diff --git a/esp32_marauder/Display.cpp b/esp32_marauder/Display.cpp index 4559ad5..d2ff431 100644 --- a/esp32_marauder/Display.cpp +++ b/esp32_marauder/Display.cpp @@ -144,6 +144,33 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) return false; }*/ +void Display::drawFrame() +{ + tft.drawRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, TFT_BLACK); +} + +void Display::tftDrawRedOnOffButton() { + tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, TFT_RED); + tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, TFT_DARKGREY); + drawFrame(); + tft.setTextColor(TFT_WHITE); + tft.setTextSize(2); + tft.setTextDatum(MC_DATUM); + tft.drawString("ON", GREENBUTTON_X + (GREENBUTTON_W / 2), GREENBUTTON_Y + (GREENBUTTON_H / 2)); + this->SwitchOn = false; +} + +void Display::tftDrawGreenOnOffButton() { + tft.fillRect(GREENBUTTON_X, GREENBUTTON_Y, GREENBUTTON_W, GREENBUTTON_H, TFT_GREEN); + tft.fillRect(REDBUTTON_X, REDBUTTON_Y, REDBUTTON_W, REDBUTTON_H, TFT_DARKGREY); + drawFrame(); + tft.setTextColor(TFT_WHITE); + tft.setTextSize(2); + tft.setTextDatum(MC_DATUM); + tft.drawString("OFF", REDBUTTON_X + (REDBUTTON_W / 2) + 1, REDBUTTON_Y + (REDBUTTON_H / 2)); + this->SwitchOn = true; +} + void Display::tftDrawGraphObjects(byte x_scale) { //draw the graph objects diff --git a/esp32_marauder/Display.h b/esp32_marauder/Display.h index d02963b..9692342 100644 --- a/esp32_marauder/Display.h +++ b/esp32_marauder/Display.h @@ -69,6 +69,23 @@ #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 @@ -90,6 +107,7 @@ PROGMEM static lv_obj_t *kb; class Display { private: + bool SwitchOn = false; bool run_setup = true; @@ -100,6 +118,8 @@ class Display boolean change_colour = 1; boolean selected = 1; + void drawFrame(); + //void addNodes(Menu* menu, String name, Menu* child, std::function callable); //void changeMenu(Menu* menu); //void showMenuList(Menu* menu, int layer); @@ -150,6 +170,8 @@ class Display //void initLVGL(); //void deinitLVGL(); //void joinWiFiGFX(); + void tftDrawRedOnOffButton(); + void tftDrawGreenOnOffButton(); void tftDrawGraphObjects(byte x_scale); void tftDrawEapolColorKey(); void tftDrawColorKey(); diff --git a/esp32_marauder/MenuFunctions.cpp b/esp32_marauder/MenuFunctions.cpp index 5416136..f3c8587 100644 --- a/esp32_marauder/MenuFunctions.cpp +++ b/esp32_marauder/MenuFunctions.cpp @@ -155,6 +155,90 @@ void MenuFunctions::writeBadUSB(){ lv_keyboard_set_cursor_manage(kb, true); } +// Event handler for settings drop down menus +void setting_dropdown_cb(lv_obj_t * obj, lv_event_t event) { + //lv_event_code_t code = lv_event_get_code(event); + //lv_obj_t * obj = lv_event_get_target(event); + //lv_obj_t * list1 = lv_obj_get_parent(lv_obj_get_parent(obj)); + //if(event == LV_EVENT_CLICKED) { + // LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(list1, obj)); + //} +} + +void settings_list_cb(lv_obj_t * btn, lv_event_t event) { + extern Settings settings_obj; + extern MenuFunctions menu_function_obj; + + String btn_text = lv_list_get_btn_text(btn); + String display_string = ""; + + if (event == LV_EVENT_CLICKED) { + if (btn_text == "Exit") { + Serial.println("Exiting..."); + lv_obj_del_async(lv_obj_get_parent(lv_obj_get_parent(btn))); + + printf("LV_EVENT_CANCEL\n"); + Serial.println("Potato"); + //menu_function_obj.deinitLVGL(); + //wifi_scan_obj.StartScan(WIFI_SCAN_OFF); + //display_obj.exit_draw = true; // set everything back to normal + } + else { + // Build base obj to host buttons + Serial.println("Creating base object..."); + lv_obj_t * obj; + obj = lv_obj_create(lv_scr_act(), NULL); + lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES); + + lv_obj_t * exit_btn; + + lv_obj_t * label; + + // Build the generic Exit button + exit_btn = lv_btn_create(obj, NULL); + lv_obj_set_event_cb(exit_btn, settings_list_cb); + lv_label_set_text(label, "Exit"); + //lv_obj_center(label); + + label = lv_label_create(exit_btn, NULL); + + // Create the type specific device + if (settings_obj.getSettingType(btn_text) == "bool") { + lv_obj_t * sw = lv_switch_create(obj, NULL); + lv_obj_align(sw, NULL, LV_ALIGN_CENTER, 0, 0); + } + } + } + + /* + if (event == LV_EVENT_VALUE_CHANGED) { + if (lv_btn_get_state(btn) == LV_BTN_STATE_CHECKED_RELEASED) { + //Serial.print("Toggle on: "); + //Serial.println(btn_text); + for (int i = 0; i < access_points->size(); i++) { + if (access_points->get(i).essid == btn_text) { + Serial.println("Adding AP: " + (String)access_points->get(i).essid); + AccessPoint ap = access_points->get(i); + ap.selected = true; + access_points->set(i, ap); + } + } + } + else { + //Serial.print("Toggle off: "); + //Serial.println(btn_text); + for (int i = 0; i < access_points->size(); i++) { + if (access_points->get(i).essid == btn_text) { + Serial.println("Removing AP: " + (String)access_points->get(i).essid); + AccessPoint ap = access_points->get(i); + ap.selected = false; + access_points->set(i, ap); + } + } + } + }*/ +} + void MenuFunctions::displaySettingsGFX(){ extern Settings settings_obj; @@ -173,6 +257,8 @@ void MenuFunctions::displaySettingsGFX(){ lv_obj_t * label; + lv_obj_t * sw; + list_btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, "Exit"); lv_obj_set_event_cb(list_btn, ap_list_cb); @@ -181,9 +267,30 @@ void MenuFunctions::displaySettingsGFX(){ json["Settings"][i]["name"].as().toCharArray(buf, json["Settings"][i]["name"].as().length() + 1); list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, buf); - lv_btn_set_checkable(list_btn, true); - lv_obj_set_event_cb(list_btn, ap_list_cb); + lv_btn_set_checkable(list_btn, false); + lv_obj_set_event_cb(list_btn, settings_list_cb); + //lv_list_add_text(list1, buf); + + // Create the dropdown menu + /*lv_obj_t * dd = lv_dropdown_create(list1, NULL); + lv_dropdown_set_options(dd, "Apple\n" + "Banana\n" + "Orange\n" + "Cherry\n" + "Grape\n" + "Raspberry\n" + "Melon\n" + "Orange\n" + "Lemon\n" + "Nuts"); + + //lv_obj_align(dd, LV_ALIGN_IN_RIGHT_MID, 0, 20); + lv_obj_align(dd, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0); + lv_obj_set_width(dd, LV_HOR_RES / 3); + lv_obj_set_event_cb(dd, setting_dropdown_cb); + //lv_obj_add_event_cb(dd, setting_dropdown_cb, LV_EVENT_ALL, NULL);*/ + //if (access_points->get(i).selected) // lv_btn_toggle(list_btn); @@ -191,9 +298,6 @@ void MenuFunctions::displaySettingsGFX(){ //lv_obj_set_event_cb(btn1, ap_list_cb); //lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); //lv_btn_set_checkable(btn1, true); - - //label = lv_label_create(btn1, NULL); - //lv_label_set_text(label, buf); } } @@ -234,56 +338,7 @@ void MenuFunctions::addAPGFX(){ } } -void settings_list_cb(lv_obj_t * btn, lv_event_t event) { - extern Settings settings_obj; - extern MenuFunctions menu_function_obj; - String btn_text = lv_list_get_btn_text(btn); - String display_string = ""; - - if (event == LV_EVENT_CLICKED) { - if (btn_text != "Exit") { - //lv_list_focus_btn(lv_obj_get_parent(lv_obj_get_parent(btn)), btn); - } - else { - Serial.println("Exiting..."); - lv_obj_del_async(lv_obj_get_parent(lv_obj_get_parent(btn))); - - printf("LV_EVENT_CANCEL\n"); - menu_function_obj.deinitLVGL(); - wifi_scan_obj.StartScan(WIFI_SCAN_OFF); - display_obj.exit_draw = true; // set everything back to normal - } - } - - /* - if (event == LV_EVENT_VALUE_CHANGED) { - if (lv_btn_get_state(btn) == LV_BTN_STATE_CHECKED_RELEASED) { - //Serial.print("Toggle on: "); - //Serial.println(btn_text); - for (int i = 0; i < access_points->size(); i++) { - if (access_points->get(i).essid == btn_text) { - Serial.println("Adding AP: " + (String)access_points->get(i).essid); - AccessPoint ap = access_points->get(i); - ap.selected = true; - access_points->set(i, ap); - } - } - } - else { - //Serial.print("Toggle off: "); - //Serial.println(btn_text); - for (int i = 0; i < access_points->size(); i++) { - if (access_points->get(i).essid == btn_text) { - Serial.println("Removing AP: " + (String)access_points->get(i).essid); - AccessPoint ap = access_points->get(i); - ap.selected = false; - access_points->set(i, ap); - } - } - } - }*/ -} void ap_list_cb(lv_obj_t * btn, lv_event_t event) { extern LinkedList* access_points; @@ -1141,6 +1196,22 @@ void MenuFunctions::orientDisplay() changeMenu(current_menu); } +void MenuFunctions::runBoolSetting(String key) { + Serial.println("Building bool setting screen..."); + display_obj.tftDrawRedOnOffButton(); + //display_obj.tftDrawGreenOnOffButton(); +} + +void MenuFunctions::callSetting(String key) { + specSettingMenu.name = key; + + String setting_type = settings_obj.getSettingType(key); + + if (setting_type == "bool") { + this->runBoolSetting(key); + } +} + // Function to build the menus void MenuFunctions::RunSetup() @@ -1163,6 +1234,8 @@ void MenuFunctions::RunSetup() confirmMenu.list = new LinkedList(); espUpdateMenu.list = new LinkedList(); updateMenu.list = new LinkedList(); + settingsMenu.list = new LinkedList(); + specSettingMenu.list = new LinkedList(); infoMenu.list = new LinkedList(); // WiFi menu stuff @@ -1193,6 +1266,7 @@ void MenuFunctions::RunSetup() espUpdateMenu.name = " ESP8266 Update "; updateMenu.name = " Update Firmware "; infoMenu.name = " Device Info "; + settingsMenu.name = " Settings "; bluetoothMenu.name = " Bluetooth "; wifiSnifferMenu.name = " WiFi Sniffers "; wifiAttackMenu.name = " WiFi Attacks "; @@ -1481,11 +1555,33 @@ void MenuFunctions::RunSetup() changeMenu(&infoMenu); wifi_scan_obj.RunInfo(); }); - addNodes(&deviceMenu, "Settings", TFT_NAVY, NULL, KEYBOARD_ICO, [this](){ + addNodes(&deviceMenu, "Settings", TFT_NAVY, NULL, KEYBOARD_ICO, [this]() { + changeMenu(&settingsMenu); + }); + /*addNodes(&deviceMenu, "Settings", TFT_NAVY, NULL, KEYBOARD_ICO, [this](){ display_obj.clearScreen(); wifi_scan_obj.currentScanMode = LV_ADD_SSID; wifi_scan_obj.StartScan(LV_ADD_SSID, TFT_RED); displaySettingsGFX(); + });*/ + + // Settings menu + // Device menu + settingsMenu.parentMenu = &deviceMenu; + addNodes(&settingsMenu, "Back", TFT_LIGHTGREY, NULL, 0, [this]() { + changeMenu(settingsMenu.parentMenu); + }); + for (int i = 0; i < settings_obj.getNumberSettings(); i++) { + addNodes(&settingsMenu, settings_obj.setting_index_to_name(i), TFT_LIGHTGREY, NULL, 0, [this, i]() { + changeMenu(&specSettingMenu); + this->callSetting(settings_obj.setting_index_to_name(i)); + }); + } + + // Specific setting menu + specSettingMenu.parentMenu = &settingsMenu; + addNodes(&specSettingMenu, "Back", TFT_LIGHTGREY, NULL, 0, [this]() { + changeMenu(specSettingMenu.parentMenu); }); // Select update diff --git a/esp32_marauder/MenuFunctions.h b/esp32_marauder/MenuFunctions.h index 3f779fa..c7efbf2 100644 --- a/esp32_marauder/MenuFunctions.h +++ b/esp32_marauder/MenuFunctions.h @@ -93,6 +93,7 @@ PROGMEM static void write_bad_usb_keyboard_event_cb(lv_obj_t * keyboard, lv_even 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 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 @@ -145,6 +146,8 @@ class MenuFunctions Menu confirmMenu; Menu espUpdateMenu; Menu updateMenu; + Menu settingsMenu; + Menu specSettingMenu; Menu infoMenu; // WiFi menu stuff @@ -176,6 +179,8 @@ class MenuFunctions void battery(bool initial = false); void battery2(bool initial = false); void showMenuList(Menu* menu, int layer); + void callSetting(String key); + void runBoolSetting(String ley); public: MenuFunctions(); diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index b2bbe93..ad96891 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -152,11 +152,15 @@ void WiFiScan::RunSetup() { ssids = new LinkedList(); access_points = new LinkedList(); + 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(); + + this->initWiFi(1); } int WiFiScan::clearAPs() { @@ -258,10 +262,26 @@ void WiFiScan::joinWiFi(String ssid, String password) 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->set_channel = settings_obj.loadSetting("Channel"); + this->changeChannel(); + + this->force_pmkid = settings_obj.loadSetting("Force PMKID"); + this->force_probe = settings_obj.loadSetting("Force Probe"); + this->save_pcap = settings_obj.loadSetting("Save PCAP"); + this->channel_hop_delay = settings_obj.loadSetting("Channel Hop Delay"); + Serial.println(F("Initialization complete")); + } +} + // Function to prepare to run a specific scan void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color) { - //Serial.println("Starting Scan..."); + this->initWiFi(scan_mode); if (scan_mode == WIFI_SCAN_OFF) StopScan(scan_mode); else if (scan_mode == WIFI_SCAN_PROBE) @@ -1137,6 +1157,7 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) Serial.println("BT Controller Status: " + (String)esp_bt_controller_get_status()); */ 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) @@ -2693,7 +2714,7 @@ void WiFiScan::main(uint32_t currentTime) (currentScanMode == WIFI_SCAN_DEAUTH) || (currentScanMode == WIFI_SCAN_ALL)) { - if (currentTime - initTime >= 1000) + if (currentTime - initTime >= this->channel_hop_delay * 1000) { initTime = millis(); channelHop(); diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index 45d0069..25f6272 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -21,6 +21,7 @@ #include "Buffer.h" #include "BatteryInterface.h" #include "TemperatureInterface.h" +#include "settings.h" #include "Assets.h" //#include "MenuFunctions.h" @@ -60,6 +61,7 @@ extern SDInterface sd_obj; extern Buffer buffer_obj; extern BatteryInterface battery_obj; extern TemperatureInterface temp_obj; +extern Settings settings_obj; 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); @@ -79,6 +81,12 @@ struct AccessPoint { class WiFiScan { private: + // Settings + int channel_hop_delay = 1; + bool force_pmkid = false; + bool force_probe = false; + bool save_pcap = false; + int x_pos; //position along the graph x axis float y_pos_x; //current graph y axis position of X value float y_pos_x_old = 120; //old y axis position of X value @@ -100,6 +108,7 @@ class WiFiScan uint32_t initTime = 0; bool run_setup = true; + void initWiFi(uint8_t scan_mode); int bluetoothScanTime = 5; int packets_sent = 0; const wifi_promiscuous_filter_t filt = {.filter_mask=WIFI_PROMIS_FILTER_MASK_MGMT | WIFI_PROMIS_FILTER_MASK_DATA}; diff --git a/esp32_marauder/esp32_marauder.ino b/esp32_marauder/esp32_marauder.ino index db81d22..5816ed7 100644 --- a/esp32_marauder/esp32_marauder.ino +++ b/esp32_marauder/esp32_marauder.ino @@ -77,6 +77,8 @@ void setup() //Serial.begin(115200); + Serial.println("\n\nHello, World!\n"); + Serial.println("ESP-IDF version is: " + String(esp_get_idf_version())); display_obj.RunSetup(); diff --git a/esp32_marauder/settings.cpp b/esp32_marauder/settings.cpp index 4655408..5550214 100644 --- a/esp32_marauder/settings.cpp +++ b/esp32_marauder/settings.cpp @@ -119,6 +119,39 @@ uint8_t Settings::loadSetting(String key) { return 0; } +String Settings::setting_index_to_name(int i) { + DynamicJsonDocument json(1024); // ArduinoJson v6 + + if (deserializeJson(json, this->json_settings_string)) { + Serial.println("\nCould not parse json"); + } + + return json["Settings"][i]["name"]; +} + +int Settings::getNumberSettings() { + DynamicJsonDocument json(1024); // ArduinoJson v6 + + if (deserializeJson(json, this->json_settings_string)) { + Serial.println("\nCould not parse json"); + } + + return json["Settings"].size(); +} + +String Settings::getSettingType(String key) { + DynamicJsonDocument json(1024); // ArduinoJson v6 + + if (deserializeJson(json, this->json_settings_string)) { + Serial.println("\nCould not parse json"); + } + + for (int i = 0; i < json["Settings"].size(); i++) { + if (json["Settings"][i]["name"].as() == key) + return json["Settings"][i]["type"]; + } +} + void Settings::printJsonSettings(String json_string) { DynamicJsonDocument json(1024); // ArduinoJson v6 @@ -151,14 +184,32 @@ bool Settings::createDefaultSettings(fs::FS &fs) { jsonBuffer["Settings"][0]["name"] = "Channel"; jsonBuffer["Settings"][0]["type"] = "uint8_t"; jsonBuffer["Settings"][0]["value"] = 11; + jsonBuffer["Settings"][0]["range"]["min"] = 1; + jsonBuffer["Settings"][0]["range"]["max"] = 14; - jsonBuffer["Settings"][1]["name"] = "Force PMKID"; - jsonBuffer["Settings"][1]["type"] = "bool"; - jsonBuffer["Settings"][1]["value"] = true; + jsonBuffer["Settings"][1]["name"] = "Channel Hop Delay"; + jsonBuffer["Settings"][1]["type"] = "int"; + jsonBuffer["Settings"][1]["value"] = 1; + jsonBuffer["Settings"][1]["range"]["min"] = 1; + jsonBuffer["Settings"][1]["range"]["max"] = 10; - jsonBuffer["Settings"][2]["name"] = "Save PCAP"; + jsonBuffer["Settings"][2]["name"] = "Force PMKID"; jsonBuffer["Settings"][2]["type"] = "bool"; jsonBuffer["Settings"][2]["value"] = true; + jsonBuffer["Settings"][2]["range"]["min"] = false; + jsonBuffer["Settings"][2]["range"]["max"] = true; + + jsonBuffer["Settings"][3]["name"] = "Force Probe"; + jsonBuffer["Settings"][3]["type"] = "bool"; + jsonBuffer["Settings"][3]["value"] = true; + jsonBuffer["Settings"][3]["range"]["min"] = false; + jsonBuffer["Settings"][3]["range"]["max"] = true; + + jsonBuffer["Settings"][4]["name"] = "Save PCAP"; + jsonBuffer["Settings"][4]["type"] = "bool"; + jsonBuffer["Settings"][4]["value"] = true; + jsonBuffer["Settings"][4]["range"]["min"] = false; + jsonBuffer["Settings"][4]["range"]["max"] = true; //jsonBuffer.printTo(settingsFile); if (serializeJson(jsonBuffer, settingsFile) == 0) { diff --git a/esp32_marauder/settings.h b/esp32_marauder/settings.h index 19f71a9..fa7f4d6 100644 --- a/esp32_marauder/settings.h +++ b/esp32_marauder/settings.h @@ -25,6 +25,10 @@ class Settings { template T loadSetting(String name); + String getSettingType(String key); + String setting_index_to_name(int i); + int getNumberSettings(); + //template<> //int loadSetting(String key);