Просмотр исходного кода

Copy changes from unleashed, increment version to v0.4.0

0xchocolate 2 лет назад
Родитель
Сommit
c359f82f16
57 измененных файлов с 2612 добавлено и 1292 удалено
  1. 1 2
      application.fam
  2. 0 0
      assets/DolphinCommon_56x48.png
  3. BIN
      assets/KeyBackspaceSelected_16x9.png
  4. BIN
      assets/KeyBackspace_16x9.png
  5. BIN
      assets/KeyKeyboardSelected_10x11.png
  6. BIN
      assets/KeyKeyboard_10x11.png
  7. BIN
      assets/KeySaveSelected_24x11.png
  8. BIN
      assets/KeySave_24x11.png
  9. BIN
      assets/Text_10x10.png
  10. BIN
      assets/WarningDolphin_45x42.png
  11. 17 6
      file/sequential_file.c
  12. 11 2
      file/sequential_file.h
  13. 33 19
      scenes/wifi_marauder_scene_console_output.c
  14. 13 6
      scenes/wifi_marauder_scene_log_viewer.c
  15. 27 7
      scenes/wifi_marauder_scene_script_confirm_delete.c
  16. 76 48
      scenes/wifi_marauder_scene_script_edit.c
  17. 67 27
      scenes/wifi_marauder_scene_script_edit_list.c
  18. 53 29
      scenes/wifi_marauder_scene_script_options.c
  19. 20 8
      scenes/wifi_marauder_scene_script_select.c
  20. 27 14
      scenes/wifi_marauder_scene_script_settings.c
  21. 128 43
      scenes/wifi_marauder_scene_script_stage_add.c
  22. 58 34
      scenes/wifi_marauder_scene_script_stage_edit.c
  23. 76 38
      scenes/wifi_marauder_scene_sniffpmkid_options.c
  24. 7 10
      scenes/wifi_marauder_scene_start.c
  25. 13 13
      scenes/wifi_marauder_scene_text_input.c
  26. 102 78
      scenes/wifi_marauder_scene_user_input.c
  27. 220 343
      script/cJSON.c
  28. 133 105
      script/cJSON.h
  29. 12 11
      script/menu/wifi_marauder_script_stage_menu.c
  30. 4 2
      script/menu/wifi_marauder_script_stage_menu.h
  31. 2 3
      script/menu/wifi_marauder_script_stage_menu_beaconap.c
  32. 6 9
      script/menu/wifi_marauder_script_stage_menu_beaconlist.c
  33. 2 3
      script/menu/wifi_marauder_script_stage_menu_deauth.c
  34. 2 3
      script/menu/wifi_marauder_script_stage_menu_delay.c
  35. 4 5
      script/menu/wifi_marauder_script_stage_menu_exec.c
  36. 2 3
      script/menu/wifi_marauder_script_stage_menu_probe.c
  37. 9 8
      script/menu/wifi_marauder_script_stage_menu_scan.c
  38. 12 14
      script/menu/wifi_marauder_script_stage_menu_select.c
  39. 2 3
      script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c
  40. 2 3
      script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c
  41. 2 3
      script/menu/wifi_marauder_script_stage_menu_sniffesp.c
  42. 11 12
      script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c
  43. 2 3
      script/menu/wifi_marauder_script_stage_menu_sniffpwn.c
  44. 2 3
      script/menu/wifi_marauder_script_stage_menu_sniffraw.c
  45. 339 241
      script/wifi_marauder_script.c
  46. 16 8
      script/wifi_marauder_script.h
  47. 139 94
      script/wifi_marauder_script_executor.c
  48. 2 2
      script/wifi_marauder_script_executor.h
  49. 18 15
      script/wifi_marauder_script_worker.c
  50. 6 4
      script/wifi_marauder_script_worker.h
  51. 19 4
      wifi_marauder_app.c
  52. 1 1
      wifi_marauder_app.h
  53. 3 3
      wifi_marauder_app_i.h
  54. 750 0
      wifi_marauder_text_input.c
  55. 83 0
      wifi_marauder_text_input.h
  56. 57 0
      wifi_marauder_validators.c
  57. 21 0
      wifi_marauder_validators.h

+ 1 - 2
application.fam

@@ -3,11 +3,10 @@ App(
     name="[ESP32] WiFi Marauder",
     apptype=FlipperAppType.EXTERNAL,
     entry_point="wifi_marauder_app",
-    cdefines=["APP_WIFI_MARAUDER"],
     requires=["gui"],
     stack_size=4 * 1024,
     order=90,
     fap_icon="wifi_10px.png",
-    fap_icon_assets="icons",
     fap_category="GPIO",
+    fap_icon_assets="assets",
 )

+ 0 - 0
icons/DolphinCommon_56x48.png → assets/DolphinCommon_56x48.png


BIN
assets/KeyBackspaceSelected_16x9.png


BIN
assets/KeyBackspace_16x9.png


BIN
assets/KeyKeyboardSelected_10x11.png


BIN
assets/KeyKeyboard_10x11.png


BIN
assets/KeySaveSelected_24x11.png


BIN
assets/KeySave_24x11.png


BIN
assets/Text_10x10.png


BIN
assets/WarningDolphin_45x42.png


+ 17 - 6
file/sequential_file.c

@@ -1,7 +1,11 @@
 #include "sequential_file.h"
 
-char* sequential_file_resolve_path(Storage* storage, const char* dir, const char* prefix, const char* extension) {
-    if (storage == NULL || dir == NULL || prefix == NULL || extension == NULL) {
+char* sequential_file_resolve_path(
+    Storage* storage,
+    const char* dir,
+    const char* prefix,
+    const char* extension) {
+    if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) {
         return NULL;
     }
 
@@ -9,7 +13,9 @@ char* sequential_file_resolve_path(Storage* storage, const char* dir, const char
     int file_index = 0;
 
     do {
-        if (snprintf(file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) < 0) {
+        if(snprintf(
+               file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) <
+           0) {
             return NULL;
         }
         file_index++;
@@ -18,13 +24,18 @@ char* sequential_file_resolve_path(Storage* storage, const char* dir, const char
     return strdup(file_path);
 }
 
-bool sequential_file_open(Storage* storage, File* file, const char* dir, const char* prefix, const char* extension) {
-    if (storage == NULL || file == NULL || dir == NULL || prefix == NULL || extension == NULL) {
+bool sequential_file_open(
+    Storage* storage,
+    File* file,
+    const char* dir,
+    const char* prefix,
+    const char* extension) {
+    if(storage == NULL || file == NULL || dir == NULL || prefix == NULL || extension == NULL) {
         return false;
     }
 
     char* file_path = sequential_file_resolve_path(storage, dir, prefix, extension);
-    if (file_path == NULL) {
+    if(file_path == NULL) {
         return false;
     }
 

+ 11 - 2
file/sequential_file.h

@@ -2,5 +2,14 @@
 
 #include <storage/storage.h>
 
-char* sequential_file_resolve_path(Storage* storage, const char* dir, const char* prefix, const char* extension);
-bool sequential_file_open(Storage* storage, File* file, const char* dir, const char* prefix, const char* extension);
+char* sequential_file_resolve_path(
+    Storage* storage,
+    const char* dir,
+    const char* prefix,
+    const char* extension);
+bool sequential_file_open(
+    Storage* storage,
+    File* file,
+    const char* dir,
+    const char* prefix,
+    const char* extension);

+ 33 - 19
scenes/wifi_marauder_scene_console_output.c

@@ -2,27 +2,31 @@
 
 char* _wifi_marauder_get_prefix_from_cmd(const char* command) {
     int end = strcspn(command, " ");
-    char* prefix = (char*) malloc(sizeof(char) * (end + 1));
+    char* prefix = (char*)malloc(sizeof(char) * (end + 1));
     strncpy(prefix, command, end);
     prefix[end] = '\0';
     return prefix;
 }
 
 bool _wifi_marauder_is_save_pcaps_enabled(WifiMarauderApp* app) {
-    if (!app->ok_to_save_pcaps) {
+    if(!app->ok_to_save_pcaps) {
         return false;
     }
     // If it is a script that contains a sniff function
-    if (app->script != NULL) {
+    if(app->script != NULL) {
         return wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffRaw) ||
-               wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon) ||
-               wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth) ||
+               wifi_marauder_script_has_stage(
+                   app->script, WifiMarauderScriptStageTypeSniffBeacon) ||
+               wifi_marauder_script_has_stage(
+                   app->script, WifiMarauderScriptStageTypeSniffDeauth) ||
                wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffEsp) ||
-               wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid) ||
+               wifi_marauder_script_has_stage(
+                   app->script, WifiMarauderScriptStageTypeSniffPmkid) ||
                wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPwn);
     }
     // If it is a sniff function
-    return app->is_command && app->selected_tx_string && strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;
+    return app->is_command && app->selected_tx_string &&
+           strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;
 }
 
 void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
@@ -97,21 +101,30 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
 
     // Register callbacks to receive data
-    wifi_marauder_uart_set_handle_rx_data_cb(app->uart, wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
-    wifi_marauder_uart_set_handle_rx_data_cb(app->lp_uart, wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
-    
+    wifi_marauder_uart_set_handle_rx_data_cb(
+        app->uart,
+        wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
+    wifi_marauder_uart_set_handle_rx_data_cb(
+        app->lp_uart,
+        wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
+
     // Get ready to send command
     if((app->is_command && app->selected_tx_string) || app->script) {
-        const char* prefix = strlen(app->selected_tx_string) > 0 ?
-                             _wifi_marauder_get_prefix_from_cmd(app->selected_tx_string) : // Function name
-                             app->script->name;                                            // Script name
+        const char* prefix =
+            strlen(app->selected_tx_string) > 0 ?
+                _wifi_marauder_get_prefix_from_cmd(app->selected_tx_string) : // Function name
+                app->script->name; // Script name
 
         // Create files *before* sending command
         // (it takes time to iterate through the directory)
         if(app->ok_to_save_logs) {
-            strcpy(app->log_file_path, sequential_file_resolve_path(app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log"));
-            if (app->log_file_path != NULL) {
-                if (storage_file_open(app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+            strcpy(
+                app->log_file_path,
+                sequential_file_resolve_path(
+                    app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log"));
+            if(app->log_file_path != NULL) {
+                if(storage_file_open(
+                       app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
                     app->is_writing_log = true;
                 } else {
                     dialog_message_show_storage_error(app->dialogs, "Cannot open log file");
@@ -122,8 +135,9 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
         }
 
         // If it is a sniff function or script, open the pcap file for recording
-        if (_wifi_marauder_is_save_pcaps_enabled(app)) {
-            if (sequential_file_open(app->storage, app->capture_file, MARAUDER_APP_FOLDER_PCAPS, prefix, "pcap")) {
+        if(_wifi_marauder_is_save_pcaps_enabled(app)) {
+            if(sequential_file_open(
+                   app->storage, app->capture_file, MARAUDER_APP_FOLDER_PCAPS, prefix, "pcap")) {
                 app->is_writing_pcap = true;
             } else {
                 dialog_message_show_storage_error(app->dialogs, "Cannot open pcap file");
@@ -131,7 +145,7 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
         }
 
         // Send command with newline '\n'
-        if (app->selected_tx_string) {
+        if(app->selected_tx_string) {
             wifi_marauder_uart_tx(
                 (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
             wifi_marauder_uart_tx((uint8_t*)("\n"), 1);

+ 13 - 6
scenes/wifi_marauder_scene_log_viewer.c

@@ -112,18 +112,23 @@ void wifi_marauder_scene_log_viewer_on_enter(void* context) {
     app->open_log_file_page = 0;
     app->open_log_file_num_pages = 0;
     bool saved_logs_exist = false;
-    if (!app->has_saved_logs_this_session && furi_string_empty(app->text_box_store)) {
+    if(!app->has_saved_logs_this_session && furi_string_empty(app->text_box_store)) {
         // no commands sent yet this session, find last saved log
-        if (storage_dir_open(app->log_file, MARAUDER_APP_FOLDER_LOGS)) {
+        if(storage_dir_open(app->log_file, MARAUDER_APP_FOLDER_LOGS)) {
             char name[70];
             char lastname[70];
-            while (storage_dir_read(app->log_file, NULL, name, sizeof(name))) {
+            while(storage_dir_read(app->log_file, NULL, name, sizeof(name))) {
                 // keep reading directory until last file is reached
                 strlcpy(lastname, name, sizeof(lastname));
                 saved_logs_exist = true;
             }
-            if (saved_logs_exist) {
-                snprintf(app->log_file_path, sizeof(app->log_file_path), "%s/%s", MARAUDER_APP_FOLDER_LOGS, lastname);
+            if(saved_logs_exist) {
+                snprintf(
+                    app->log_file_path,
+                    sizeof(app->log_file_path),
+                    "%s/%s",
+                    MARAUDER_APP_FOLDER_LOGS,
+                    lastname);
             }
         }
         storage_dir_close(app->log_file);
@@ -143,8 +148,10 @@ bool wifi_marauder_scene_log_viewer_on_event(void* context, SceneManagerEvent ev
             // Browse
             FuriString* predefined_filepath = furi_string_alloc_set_str(MARAUDER_APP_FOLDER_LOGS);
             FuriString* selected_filepath = furi_string_alloc();
+            DialogsFileBrowserOptions browser_options;
+            dialog_file_browser_set_basic_options(&browser_options, ".log", &I_Text_10x10);
             if(dialog_file_browser_show(
-                   app->dialogs, selected_filepath, predefined_filepath, NULL)) {
+                   app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
                 strncpy(
                     app->log_file_path,
                     furi_string_get_cstr(selected_filepath),

+ 27 - 7
scenes/wifi_marauder_scene_script_confirm_delete.c

@@ -13,14 +13,29 @@ void wifi_marauder_scene_script_confirm_delete_widget_callback(
 void wifi_marauder_scene_script_confirm_delete_on_enter(void* context) {
     WifiMarauderApp* app = context;
 
-    widget_add_button_element(app->widget, GuiButtonTypeLeft, "No", wifi_marauder_scene_script_confirm_delete_widget_callback, app);
-    widget_add_button_element(app->widget, GuiButtonTypeRight, "Yes", wifi_marauder_scene_script_confirm_delete_widget_callback, app);
+    widget_add_button_element(
+        app->widget,
+        GuiButtonTypeLeft,
+        "No",
+        wifi_marauder_scene_script_confirm_delete_widget_callback,
+        app);
+    widget_add_button_element(
+        app->widget,
+        GuiButtonTypeRight,
+        "Yes",
+        wifi_marauder_scene_script_confirm_delete_widget_callback,
+        app);
 
-    widget_add_string_element(app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Are you sure?");
+    widget_add_string_element(
+        app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Are you sure?");
     widget_add_text_box_element(
         app->widget,
-        0, 12, 128, 38,
-        AlignCenter, AlignCenter,
+        0,
+        12,
+        128,
+        38,
+        AlignCenter,
+        AlignCenter,
         "The script will be\npermanently deleted",
         false);
 
@@ -35,9 +50,14 @@ bool wifi_marauder_scene_script_confirm_delete_on_event(void* context, SceneMana
         // get which button press: "Yes" or "No"
         if(event.event == GuiButtonTypeRight) {
             // Yes
-            if (app->script != NULL) {
+            if(app->script != NULL) {
                 char script_path[256];
-                snprintf(script_path, sizeof(script_path), "%s/%s.json", MARAUDER_APP_FOLDER_SCRIPTS, app->script->name);
+                snprintf(
+                    script_path,
+                    sizeof(script_path),
+                    "%s/%s.json",
+                    MARAUDER_APP_FOLDER_SCRIPTS,
+                    app->script->name);
                 storage_simply_remove(app->storage, script_path);
                 wifi_marauder_script_free(app->script);
                 app->script = NULL;

+ 76 - 48
scenes/wifi_marauder_scene_script_edit.c

@@ -5,13 +5,13 @@ static void wifi_marauder_scene_script_edit_callback(void* context, uint32_t ind
     WifiMarauderScriptStage* current_stage = app->script->first_stage;
     uint32_t stage_index = 0;
 
-    while (current_stage != NULL && stage_index < index) {
+    while(current_stage != NULL && stage_index < index) {
         current_stage = current_stage->next_stage;
         stage_index++;
     }
     app->script_edit_selected_stage = current_stage;
 
-    if (app->script_edit_selected_stage != NULL) {
+    if(app->script_edit_selected_stage != NULL) {
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index);
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEdit);
     }
@@ -31,57 +31,85 @@ void wifi_marauder_scene_script_edit_on_enter(void* context) {
 
     WifiMarauderScriptStage* current_stage = script->first_stage;
     int stage_index = 0;
-    while (current_stage != NULL) {
-        switch (current_stage->type) {
-            case WifiMarauderScriptStageTypeScan:
-                submenu_add_item(submenu, "Scan", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSelect:
-                submenu_add_item(submenu, "Select", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeDeauth:
-                submenu_add_item(submenu, "Deauth", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeProbe:
-                submenu_add_item(submenu, "Probe", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffRaw:
-                submenu_add_item(submenu, "Sniff raw", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffBeacon:
-                submenu_add_item(submenu, "Sniff beacon", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffDeauth:
-                submenu_add_item(submenu, "Sniff deauth", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffEsp:
-                submenu_add_item(submenu, "Sniff esp", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffPmkid:
-                submenu_add_item(submenu, "Sniff PMKID", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeSniffPwn:
-                submenu_add_item(submenu, "Sniff pwn", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeBeaconList:
-                submenu_add_item(submenu, "Beacon list", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeBeaconAp:
-                submenu_add_item(submenu, "Beacon AP", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeExec:
-                submenu_add_item(submenu, "Custom command", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
-            case WifiMarauderScriptStageTypeDelay:
-                submenu_add_item(submenu, "Delay", stage_index, wifi_marauder_scene_script_edit_callback, app);
-                break;
+    while(current_stage != NULL) {
+        switch(current_stage->type) {
+        case WifiMarauderScriptStageTypeScan:
+            submenu_add_item(
+                submenu, "Scan", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeSelect:
+            submenu_add_item(
+                submenu, "Select", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeDeauth:
+            submenu_add_item(
+                submenu, "Deauth", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeProbe:
+            submenu_add_item(
+                submenu, "Probe", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeSniffRaw:
+            submenu_add_item(
+                submenu, "Sniff raw", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeSniffBeacon:
+            submenu_add_item(
+                submenu,
+                "Sniff beacon",
+                stage_index,
+                wifi_marauder_scene_script_edit_callback,
+                app);
+            break;
+        case WifiMarauderScriptStageTypeSniffDeauth:
+            submenu_add_item(
+                submenu,
+                "Sniff deauth",
+                stage_index,
+                wifi_marauder_scene_script_edit_callback,
+                app);
+            break;
+        case WifiMarauderScriptStageTypeSniffEsp:
+            submenu_add_item(
+                submenu, "Sniff esp", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeSniffPmkid:
+            submenu_add_item(
+                submenu, "Sniff PMKID", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeSniffPwn:
+            submenu_add_item(
+                submenu, "Sniff pwn", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeBeaconList:
+            submenu_add_item(
+                submenu, "Beacon list", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeBeaconAp:
+            submenu_add_item(
+                submenu, "Beacon AP", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
+        case WifiMarauderScriptStageTypeExec:
+            submenu_add_item(
+                submenu,
+                "Custom command",
+                stage_index,
+                wifi_marauder_scene_script_edit_callback,
+                app);
+            break;
+        case WifiMarauderScriptStageTypeDelay:
+            submenu_add_item(
+                submenu, "Delay", stage_index, wifi_marauder_scene_script_edit_callback, app);
+            break;
         }
         current_stage = current_stage->next_stage;
         stage_index++;
     }
 
-    submenu_add_item(submenu, "[+] ADD STAGE", stage_index++, wifi_marauder_scene_script_edit_add_callback, app);
-    submenu_set_selected_item(submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
+    submenu_add_item(
+        submenu, "[+] ADD STAGE", stage_index++, wifi_marauder_scene_script_edit_add_callback, app);
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 

+ 67 - 27
scenes/wifi_marauder_scene_script_edit_list.c

@@ -1,18 +1,20 @@
 #include "../wifi_marauder_app_i.h"
 
-static void wifi_marauder_scene_script_stage_edit_list_add_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_edit_list_add_callback(void* context, uint32_t index) {
     WifiMarauderApp* app = context;
 
     // Creates new item
-    WifiMarauderScriptStageListItem* new_item = (WifiMarauderScriptStageListItem*) malloc(sizeof(WifiMarauderScriptStageListItem));
+    WifiMarauderScriptStageListItem* new_item =
+        (WifiMarauderScriptStageListItem*)malloc(sizeof(WifiMarauderScriptStageListItem));
     new_item->value = malloc(64);
     new_item->next_item = NULL;
-    
-    if (app->script_stage_edit_first_item == NULL) {
+
+    if(app->script_stage_edit_first_item == NULL) {
         app->script_stage_edit_first_item = new_item;
     } else {
         WifiMarauderScriptStageListItem* last_item = app->script_stage_edit_first_item;
-        while (last_item->next_item != NULL) {
+        while(last_item->next_item != NULL) {
             last_item = last_item->next_item;
         }
         last_item->next_item = new_item;
@@ -26,7 +28,7 @@ static void wifi_marauder_scene_script_stage_edit_list_add_callback(void* contex
 
 static void wifi_marauder_scene_script_stage_edit_list_deallocate_items(WifiMarauderApp* app) {
     WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         WifiMarauderScriptStageListItem* next_item = current_item->next_item;
         free(current_item->value);
         free(current_item);
@@ -40,20 +42,21 @@ static void wifi_marauder_scene_script_stage_edit_list_save_strings(WifiMarauder
     int array_size = 0;
 
     // Calculates the required array size
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         array_size++;
         current_item = current_item->next_item;
     }
 
     // Reallocate the array of strings if necessary
-    if (*app->script_stage_edit_string_count_reference < array_size) {
-        *app->script_stage_edit_strings_reference = realloc(*app->script_stage_edit_strings_reference, array_size * sizeof(char*));
+    if(*app->script_stage_edit_string_count_reference < array_size) {
+        *app->script_stage_edit_strings_reference =
+            realloc(*app->script_stage_edit_strings_reference, array_size * sizeof(char*));
     }
 
     // Fills the array of strings
     current_item = app->script_stage_edit_first_item;
     int i = 0;
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         char* current_str = malloc(strlen(current_item->value) + 1);
         strncpy(current_str, current_item->value, strlen(current_item->value) + 1);
         (*app->script_stage_edit_strings_reference)[i] = current_str;
@@ -69,20 +72,21 @@ static void wifi_marauder_scene_script_stage_edit_list_save_numbers(WifiMarauder
     int array_size = 0;
 
     // Calculates the required array size
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         array_size++;
         current_item = current_item->next_item;
     }
 
     // Reallocate the array of integers if necessary
-    if (*app->script_stage_edit_number_count_reference < array_size) {
-        *app->script_stage_edit_numbers_reference = realloc(*app->script_stage_edit_numbers_reference, array_size * sizeof(int));
+    if(*app->script_stage_edit_number_count_reference < array_size) {
+        *app->script_stage_edit_numbers_reference =
+            realloc(*app->script_stage_edit_numbers_reference, array_size * sizeof(int));
     }
 
     // Fills the array of integers
     current_item = app->script_stage_edit_first_item;
     int i = 0;
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         (*app->script_stage_edit_numbers_reference)[i] = atoi(current_item->value);
         current_item = current_item->next_item;
         i++;
@@ -91,15 +95,18 @@ static void wifi_marauder_scene_script_stage_edit_list_save_numbers(WifiMarauder
     *app->script_stage_edit_number_count_reference = array_size;
 }
 
-static void wifi_marauder_scene_script_stage_edit_list_save_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_edit_list_save_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    if (app->script_stage_edit_strings_reference != NULL && app->script_stage_edit_string_count_reference != NULL) {
+    if(app->script_stage_edit_strings_reference != NULL &&
+       app->script_stage_edit_string_count_reference != NULL) {
         wifi_marauder_scene_script_stage_edit_list_save_strings(app);
     }
 
-    if (app->script_stage_edit_numbers_reference != NULL && app->script_stage_edit_number_count_reference != NULL) {
+    if(app->script_stage_edit_numbers_reference != NULL &&
+       app->script_stage_edit_number_count_reference != NULL) {
         wifi_marauder_scene_script_stage_edit_list_save_numbers(app);
     }
 
@@ -107,16 +114,32 @@ static void wifi_marauder_scene_script_stage_edit_list_save_callback(void* conte
     scene_manager_previous_scene(app->scene_manager);
 }
 
-static void wifi_marauder_scene_script_stage_edit_list_clear_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_edit_list_clear_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
     wifi_marauder_scene_script_stage_edit_list_deallocate_items(app);
 
     submenu_reset(app->submenu);
-    submenu_add_item(app->submenu, "[+] ADD ITEM", 99, wifi_marauder_scene_script_stage_edit_list_add_callback, app);
-    submenu_add_item(app->submenu, "[*] SAVE ITEMS", 99, wifi_marauder_scene_script_stage_edit_list_save_callback, app);
-    submenu_add_item(app->submenu, "[-] CLEAR LIST", 99, wifi_marauder_scene_script_stage_edit_list_clear_callback, app);
+    submenu_add_item(
+        app->submenu,
+        "[+] ADD ITEM",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_add_callback,
+        app);
+    submenu_add_item(
+        app->submenu,
+        "[*] SAVE ITEMS",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_save_callback,
+        app);
+    submenu_add_item(
+        app->submenu,
+        "[-] CLEAR LIST",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_clear_callback,
+        app);
 }
 
 void wifi_marauder_scene_script_stage_edit_list_on_enter(void* context) {
@@ -124,15 +147,32 @@ void wifi_marauder_scene_script_stage_edit_list_on_enter(void* context) {
     int item_index = 0;
     WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
 
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         submenu_add_item(app->submenu, current_item->value, item_index++, NULL, app);
         current_item = current_item->next_item;
     }
-    submenu_add_item(app->submenu, "[+] ADD ITEM", 99, wifi_marauder_scene_script_stage_edit_list_add_callback, app);
-    submenu_add_item(app->submenu, "[*] SAVE ITEMS", 99, wifi_marauder_scene_script_stage_edit_list_save_callback, app);
-    submenu_add_item(app->submenu, "[-] CLEAR LIST", 99, wifi_marauder_scene_script_stage_edit_list_clear_callback, app);
-
-    submenu_set_selected_item(app->submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList));
+    submenu_add_item(
+        app->submenu,
+        "[+] ADD ITEM",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_add_callback,
+        app);
+    submenu_add_item(
+        app->submenu,
+        "[*] SAVE ITEMS",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_save_callback,
+        app);
+    submenu_add_item(
+        app->submenu,
+        "[-] CLEAR LIST",
+        99,
+        wifi_marauder_scene_script_stage_edit_list_clear_callback,
+        app);
+
+    submenu_set_selected_item(
+        app->submenu,
+        scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 

+ 53 - 29
scenes/wifi_marauder_scene_script_options.c

@@ -8,9 +8,14 @@ enum SubmenuIndex {
     SubmenuIndexDelete
 };
 
-void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) {   
+void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) {
     char script_path[256];
-    snprintf(script_path, sizeof(script_path), "%s/%s.json", MARAUDER_APP_FOLDER_SCRIPTS, app->script->name);
+    snprintf(
+        script_path,
+        sizeof(script_path),
+        "%s/%s.json",
+        MARAUDER_APP_FOLDER_SCRIPTS,
+        app->script->name);
     wifi_marauder_script_save_json(app->storage, script_path, app->script);
 
     DialogMessage* message = dialog_message_alloc();
@@ -24,26 +29,26 @@ void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) {
 static void wifi_marauder_scene_script_options_callback(void* context, uint32_t index) {
     WifiMarauderApp* app = context;
 
-    switch (index) {
-        case SubmenuIndexRun:
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
-            break;
-        case SubmenuIndexSettings:
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSettings);
-            break;
-        case SubmenuIndexEditStages:
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptEdit);
-            break;
-        case SubmenuIndexSave:
-            wifi_marauder_scene_script_options_save_script(app);
-            break;
-        case SubmenuIndexDelete:
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptConfirmDelete);
-            break;
+    switch(index) {
+    case SubmenuIndexRun:
+        scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
+        break;
+    case SubmenuIndexSettings:
+        scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSettings);
+        break;
+    case SubmenuIndexEditStages:
+        scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptEdit);
+        break;
+    case SubmenuIndexSave:
+        wifi_marauder_scene_script_options_save_script(app);
+        break;
+    case SubmenuIndexDelete:
+        scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptConfirmDelete);
+        break;
     }
 }
 
@@ -51,7 +56,7 @@ void wifi_marauder_scene_script_options_on_enter(void* context) {
     WifiMarauderApp* app = context;
 
     // If returning after confirming script deletion
-    if (app->script == NULL) {
+    if(app->script == NULL) {
         scene_manager_previous_scene(app->scene_manager);
         return;
     }
@@ -59,13 +64,32 @@ void wifi_marauder_scene_script_options_on_enter(void* context) {
     Submenu* submenu = app->submenu;
 
     submenu_set_header(submenu, app->script->name);
-    submenu_add_item(submenu, "[>] RUN", SubmenuIndexRun, wifi_marauder_scene_script_options_callback, app);
-    submenu_add_item(submenu, "[S] SETTINGS", SubmenuIndexSettings, wifi_marauder_scene_script_options_callback, app);
-    submenu_add_item(submenu, "[+] EDIT STAGES", SubmenuIndexEditStages, wifi_marauder_scene_script_options_callback, app);
-    submenu_add_item(submenu, "[*] SAVE", SubmenuIndexSave, wifi_marauder_scene_script_options_callback, app);
-    submenu_add_item(submenu, "[X] DELETE", SubmenuIndexDelete, wifi_marauder_scene_script_options_callback, app);
+    submenu_add_item(
+        submenu, "[>] RUN", SubmenuIndexRun, wifi_marauder_scene_script_options_callback, app);
+    submenu_add_item(
+        submenu,
+        "[S] SETTINGS",
+        SubmenuIndexSettings,
+        wifi_marauder_scene_script_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] EDIT STAGES",
+        SubmenuIndexEditStages,
+        wifi_marauder_scene_script_options_callback,
+        app);
+    submenu_add_item(
+        submenu, "[*] SAVE", SubmenuIndexSave, wifi_marauder_scene_script_options_callback, app);
+    submenu_add_item(
+        submenu,
+        "[X] DELETE",
+        SubmenuIndexDelete,
+        wifi_marauder_scene_script_options_callback,
+        app);
 
-    submenu_set_selected_item(submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions));
+    submenu_set_selected_item(
+        submenu,
+        scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 

+ 20 - 8
scenes/wifi_marauder_scene_script_select.c

@@ -4,10 +4,15 @@ static void wifi_marauder_scene_script_select_callback(void* context, uint32_t i
     WifiMarauderApp* app = context;
 
     char script_path[256];
-    snprintf(script_path, sizeof(script_path), "%s/%s.json", MARAUDER_APP_FOLDER_SCRIPTS, furi_string_get_cstr(app->script_list[index]));
+    snprintf(
+        script_path,
+        sizeof(script_path),
+        "%s/%s.json",
+        MARAUDER_APP_FOLDER_SCRIPTS,
+        furi_string_get_cstr(app->script_list[index]));
 
     app->script = wifi_marauder_script_parse_json(app->storage, script_path);
-    if (app->script) {
+    if(app->script) {
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index);
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptOptions);
     }
@@ -36,7 +41,7 @@ void wifi_marauder_scene_script_select_on_enter(void* context) {
         while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
             app->script_list_count++;
         }
-        if (app->script_list_count > 0) {
+        if(app->script_list_count > 0) {
             submenu_set_header(submenu, "Select a script:");
             app->script_list = malloc(app->script_list_count * sizeof(FuriString*));
             storage_dir_close(dir_scripts);
@@ -46,18 +51,25 @@ void wifi_marauder_scene_script_select_on_enter(void* context) {
             while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
                 app->script_list[script_index] = furi_string_alloc();
                 path_extract_filename_no_ext(file_path, app->script_list[script_index]);
-                submenu_add_item(submenu, furi_string_get_cstr(app->script_list[script_index]), script_index, wifi_marauder_scene_script_select_callback, app);
+                submenu_add_item(
+                    submenu,
+                    furi_string_get_cstr(app->script_list[script_index]),
+                    script_index,
+                    wifi_marauder_scene_script_select_callback,
+                    app);
                 script_index++;
             }
         } else {
             submenu_set_header(submenu, "No script found");
         }
-        submenu_add_item(submenu, "[+] ADD SCRIPT", 99, wifi_marauder_scene_script_select_add_callback, app);
+        submenu_add_item(
+            submenu, "[+] ADD SCRIPT", 99, wifi_marauder_scene_script_select_add_callback, app);
         storage_dir_close(dir_scripts);
     }
     storage_file_free(dir_scripts);
 
-    submenu_set_selected_item(submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect));
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 
@@ -71,8 +83,8 @@ void wifi_marauder_scene_script_select_on_exit(void* context) {
     WifiMarauderApp* app = context;
     submenu_reset(app->submenu);
 
-    for (int i = 0; i < app->script_list_count; i++) {
+    for(int i = 0; i < app->script_list_count; i++) {
         furi_string_free(app->script_list[i]);
     }
-    free(app->script_list);   
+    free(app->script_list);
 }

+ 27 - 14
scenes/wifi_marauder_scene_script_settings.c

@@ -11,7 +11,7 @@ const char* option_values[3] = {"No", "Yes", "Default"};
 static void wifi_marauder_scene_script_settings_enter_callback(void* context, uint32_t index) {
     WifiMarauderApp* app = context;
     // Accept script repeat value
-    if (index == ScriptSettingsOptionRepeat) {
+    if(index == ScriptSettingsOptionRepeat) {
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings, index);
         app->user_input_type = WifiMarauderUserInputTypeNumber;
         app->user_input_number_reference = &app->script->repeat;
@@ -25,22 +25,23 @@ static void wifi_marauder_scene_script_settings_change_callback(VariableItem* it
     uint8_t current_option = variable_item_list_get_selected_item_index(app->var_item_list);
     uint8_t option_value_index = variable_item_get_current_value_index(item);
 
-    switch (current_option) {
-        case ScriptSettingsOptionSavePcap:
-            variable_item_set_current_value_text(item, option_values[option_value_index]);
-            app->script->save_pcap = option_value_index;
-            break;
-        case ScriptSettingsOptionEnableLed:
-            variable_item_set_current_value_text(item, option_values[option_value_index]);
-            app->script->enable_led = option_value_index;
-            break;
+    switch(current_option) {
+    case ScriptSettingsOptionSavePcap:
+        variable_item_set_current_value_text(item, option_values[option_value_index]);
+        app->script->save_pcap = option_value_index;
+        break;
+    case ScriptSettingsOptionEnableLed:
+        variable_item_set_current_value_text(item, option_values[option_value_index]);
+        app->script->enable_led = option_value_index;
+        break;
     }
 }
 
 void wifi_marauder_scene_script_settings_on_enter(void* context) {
     WifiMarauderApp* app = context;
     VariableItemList* var_item_list = app->var_item_list;
-    variable_item_list_set_enter_callback(app->var_item_list, wifi_marauder_scene_script_settings_enter_callback, app);
+    variable_item_list_set_enter_callback(
+        app->var_item_list, wifi_marauder_scene_script_settings_enter_callback, app);
 
     // Script repeat option
     VariableItem* repeat_item = variable_item_list_add(app->var_item_list, "Repeat", 1, NULL, app);
@@ -49,16 +50,28 @@ void wifi_marauder_scene_script_settings_on_enter(void* context) {
     variable_item_set_current_value_text(repeat_item, repeat_str);
 
     // Save PCAP option
-    VariableItem* save_pcap_item = variable_item_list_add(app->var_item_list, "Save PCAP", 3, wifi_marauder_scene_script_settings_change_callback, app);
+    VariableItem* save_pcap_item = variable_item_list_add(
+        app->var_item_list,
+        "Save PCAP",
+        3,
+        wifi_marauder_scene_script_settings_change_callback,
+        app);
     variable_item_set_current_value_index(save_pcap_item, app->script->save_pcap);
     variable_item_set_current_value_text(save_pcap_item, option_values[app->script->save_pcap]);
 
     // Enable board LED option
-    VariableItem* enable_led_item = variable_item_list_add(app->var_item_list, "Enable LED", 3, wifi_marauder_scene_script_settings_change_callback, app);
+    VariableItem* enable_led_item = variable_item_list_add(
+        app->var_item_list,
+        "Enable LED",
+        3,
+        wifi_marauder_scene_script_settings_change_callback,
+        app);
     variable_item_set_current_value_index(enable_led_item, app->script->enable_led);
     variable_item_set_current_value_text(enable_led_item, option_values[app->script->enable_led]);
 
-    variable_item_list_set_selected_item(var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings));
+    variable_item_list_set_selected_item(
+        var_item_list,
+        scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
 }
 

+ 128 - 43
scenes/wifi_marauder_scene_script_stage_add.c

@@ -5,7 +5,8 @@ static void wifi_marauder_scene_script_stage_add_scan_callback(void* context, ui
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageScan* stage = (WifiMarauderScriptStageScan*) malloc(sizeof(WifiMarauderScriptStageScan));
+    WifiMarauderScriptStageScan* stage =
+        (WifiMarauderScriptStageScan*)malloc(sizeof(WifiMarauderScriptStageScan));
     stage->type = WifiMarauderScriptScanTypeAp;
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN;
 
@@ -18,10 +19,11 @@ static void wifi_marauder_scene_script_stage_add_select_callback(void* context,
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSelect* stage = (WifiMarauderScriptStageSelect*) malloc(sizeof(WifiMarauderScriptStageSelect));
+    WifiMarauderScriptStageSelect* stage =
+        (WifiMarauderScriptStageSelect*)malloc(sizeof(WifiMarauderScriptStageSelect));
     stage->type = WifiMarauderScriptSelectTypeAp;
     stage->filter = strdup("all");
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSelect, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
@@ -31,9 +33,10 @@ static void wifi_marauder_scene_script_stage_add_deauth_callback(void* context,
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageDeauth* stage = (WifiMarauderScriptStageDeauth*) malloc(sizeof(WifiMarauderScriptStageDeauth));
+    WifiMarauderScriptStageDeauth* stage =
+        (WifiMarauderScriptStageDeauth*)malloc(sizeof(WifiMarauderScriptStageDeauth));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDeauth, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
@@ -43,9 +46,10 @@ static void wifi_marauder_scene_script_stage_add_probe_callback(void* context, u
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageProbe* stage = (WifiMarauderScriptStageProbe*) malloc(sizeof(WifiMarauderScriptStageProbe));
+    WifiMarauderScriptStageProbe* stage =
+        (WifiMarauderScriptStageProbe*)malloc(sizeof(WifiMarauderScriptStageProbe));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeProbe, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
@@ -55,33 +59,38 @@ static void wifi_marauder_scene_script_stage_add_sniffraw_callback(void* context
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffRaw* stage = (WifiMarauderScriptStageSniffRaw*) malloc(sizeof(WifiMarauderScriptStageSniffRaw));
+    WifiMarauderScriptStageSniffRaw* stage =
+        (WifiMarauderScriptStageSniffRaw*)malloc(sizeof(WifiMarauderScriptStageSniffRaw));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffRaw, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
 
 // Sniff Beacon
-static void wifi_marauder_scene_script_stage_add_sniffbeacon_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_add_sniffbeacon_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffBeacon* stage = (WifiMarauderScriptStageSniffBeacon*) malloc(sizeof(WifiMarauderScriptStageSniffBeacon));
+    WifiMarauderScriptStageSniffBeacon* stage =
+        (WifiMarauderScriptStageSniffBeacon*)malloc(sizeof(WifiMarauderScriptStageSniffBeacon));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
 
 // Sniff Deauth
-static void wifi_marauder_scene_script_stage_add_sniffdeauth_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_add_sniffdeauth_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffDeauth* stage = (WifiMarauderScriptStageSniffDeauth*) malloc(sizeof(WifiMarauderScriptStageSniffDeauth));
+    WifiMarauderScriptStageSniffDeauth* stage =
+        (WifiMarauderScriptStageSniffDeauth*)malloc(sizeof(WifiMarauderScriptStageSniffDeauth));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
@@ -91,23 +100,26 @@ static void wifi_marauder_scene_script_stage_add_sniffesp_callback(void* context
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffEsp* stage = (WifiMarauderScriptStageSniffEsp*) malloc(sizeof(WifiMarauderScriptStageSniffEsp));
+    WifiMarauderScriptStageSniffEsp* stage =
+        (WifiMarauderScriptStageSniffEsp*)malloc(sizeof(WifiMarauderScriptStageSniffEsp));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffEsp, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
 
 // Sniff PMKID
-static void wifi_marauder_scene_script_stage_add_sniffpmkid_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_add_sniffpmkid_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffPmkid* stage = (WifiMarauderScriptStageSniffPmkid*) malloc(sizeof(WifiMarauderScriptStageSniffPmkid));
+    WifiMarauderScriptStageSniffPmkid* stage =
+        (WifiMarauderScriptStageSniffPmkid*)malloc(sizeof(WifiMarauderScriptStageSniffPmkid));
     stage->channel = 0;
     stage->force_deauth = WifiMarauderScriptBooleanTrue;
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
@@ -117,19 +129,22 @@ static void wifi_marauder_scene_script_stage_add_sniffpwn_callback(void* context
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageSniffPwn* stage = (WifiMarauderScriptStageSniffPwn*) malloc(sizeof(WifiMarauderScriptStageSniffPwn));
+    WifiMarauderScriptStageSniffPwn* stage =
+        (WifiMarauderScriptStageSniffPwn*)malloc(sizeof(WifiMarauderScriptStageSniffPwn));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
-    
+
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPwn, stage);
     scene_manager_previous_scene(app->scene_manager);
 }
 
 // Beacon list
-static void wifi_marauder_scene_script_stage_add_beaconlist_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_add_beaconlist_callback(void* context, uint32_t index) {
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageBeaconList* stage = (WifiMarauderScriptStageBeaconList*) malloc(sizeof(WifiMarauderScriptStageBeaconList));
+    WifiMarauderScriptStageBeaconList* stage =
+        (WifiMarauderScriptStageBeaconList*)malloc(sizeof(WifiMarauderScriptStageBeaconList));
     stage->ssids = NULL;
     stage->ssid_count = 0;
     stage->random_ssids = 0;
@@ -144,7 +159,8 @@ static void wifi_marauder_scene_script_stage_add_beaconap_callback(void* context
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageBeaconAp* stage = (WifiMarauderScriptStageBeaconAp*) malloc(sizeof(WifiMarauderScriptStageBeaconAp));
+    WifiMarauderScriptStageBeaconAp* stage =
+        (WifiMarauderScriptStageBeaconAp*)malloc(sizeof(WifiMarauderScriptStageBeaconAp));
     stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
 
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconAp, stage);
@@ -156,7 +172,8 @@ static void wifi_marauder_scene_script_stage_add_exec_callback(void* context, ui
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageExec* stage = (WifiMarauderScriptStageExec*) malloc(sizeof(WifiMarauderScriptStageExec));
+    WifiMarauderScriptStageExec* stage =
+        (WifiMarauderScriptStageExec*)malloc(sizeof(WifiMarauderScriptStageExec));
     stage->command = NULL;
 
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeExec, stage);
@@ -168,7 +185,8 @@ static void wifi_marauder_scene_script_stage_add_delay_callback(void* context, u
     UNUSED(index);
     WifiMarauderApp* app = context;
 
-    WifiMarauderScriptStageDelay* stage = (WifiMarauderScriptStageDelay*) malloc(sizeof(WifiMarauderScriptStageDelay));
+    WifiMarauderScriptStageDelay* stage =
+        (WifiMarauderScriptStageDelay*)malloc(sizeof(WifiMarauderScriptStageDelay));
     stage->timeout = 0;
 
     wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDelay, stage);
@@ -181,22 +199,89 @@ void wifi_marauder_scene_script_stage_add_on_enter(void* context) {
     submenu_set_header(submenu, "Add stage");
 
     int menu_index = 0;
-    submenu_add_item(submenu, "[+] Scan", menu_index++, wifi_marauder_scene_script_stage_add_scan_callback, app);
-    submenu_add_item(submenu, "[+] Select", menu_index++, wifi_marauder_scene_script_stage_add_select_callback, app);
-    submenu_add_item(submenu, "[+] Deauth", menu_index++, wifi_marauder_scene_script_stage_add_deauth_callback, app);
-    submenu_add_item(submenu, "[+] Probe", menu_index++, wifi_marauder_scene_script_stage_add_probe_callback, app);
-    submenu_add_item(submenu, "[+] Sniff RAW", menu_index++, wifi_marauder_scene_script_stage_add_sniffraw_callback, app);
-    submenu_add_item(submenu, "[+] Sniff Beacon", menu_index++, wifi_marauder_scene_script_stage_add_sniffbeacon_callback, app);
-    submenu_add_item(submenu, "[+] Sniff Deauth", menu_index++, wifi_marauder_scene_script_stage_add_sniffdeauth_callback, app);
-    submenu_add_item(submenu, "[+] Sniff Esp", menu_index++, wifi_marauder_scene_script_stage_add_sniffesp_callback, app);
-    submenu_add_item(submenu, "[+] Sniff PMKID", menu_index++, wifi_marauder_scene_script_stage_add_sniffpmkid_callback, app);
-    submenu_add_item(submenu, "[+] Sniff Pwnagotchi", menu_index++, wifi_marauder_scene_script_stage_add_sniffpwn_callback, app);
-    submenu_add_item(submenu, "[+] Beacon List", menu_index++, wifi_marauder_scene_script_stage_add_beaconlist_callback, app);
-    submenu_add_item(submenu, "[+] Beacon AP", menu_index++, wifi_marauder_scene_script_stage_add_beaconap_callback, app);
-    submenu_add_item(submenu, "[+] Custom command", menu_index++, wifi_marauder_scene_script_stage_add_exec_callback, app);
-    submenu_add_item(submenu, "[+] Delay", menu_index++, wifi_marauder_scene_script_stage_add_delay_callback, app);
-
-    submenu_set_selected_item(submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
+    submenu_add_item(
+        submenu, "[+] Scan", menu_index++, wifi_marauder_scene_script_stage_add_scan_callback, app);
+    submenu_add_item(
+        submenu,
+        "[+] Select",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_select_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Deauth",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_deauth_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Probe",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_probe_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff RAW",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffraw_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff Beacon",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffbeacon_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff Deauth",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffdeauth_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff Esp",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffesp_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff PMKID",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffpmkid_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Sniff Pwnagotchi",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_sniffpwn_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Beacon List",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_beaconlist_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Beacon AP",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_beaconap_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Custom command",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_exec_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "[+] Delay",
+        menu_index++,
+        wifi_marauder_scene_script_stage_add_delay_callback,
+        app);
+
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 

+ 58 - 34
scenes/wifi_marauder_scene_script_stage_edit.c

@@ -1,9 +1,12 @@
 #include "../wifi_marauder_app_i.h"
 
-void wifi_marauder_scene_script_stage_edit_create_list_strings(WifiMarauderApp* app, char** strings, int string_count) {
+void wifi_marauder_scene_script_stage_edit_create_list_strings(
+    WifiMarauderApp* app,
+    char** strings,
+    int string_count) {
     // Deallocates the existing list
     WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         WifiMarauderScriptStageListItem* next_item = current_item->next_item;
         free(current_item->value);
         free(current_item);
@@ -13,12 +16,12 @@ void wifi_marauder_scene_script_stage_edit_create_list_strings(WifiMarauderApp*
     // Create a new list with numbers
     WifiMarauderScriptStageListItem* first_item = NULL;
     WifiMarauderScriptStageListItem* previous_item = NULL;
-    for (int i = 0; i < string_count; i++) {        
+    for(int i = 0; i < string_count; i++) {
         WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
         item->value = strdup(strings[i]);
         item->next_item = NULL;
 
-        if (previous_item == NULL) {
+        if(previous_item == NULL) {
             first_item = item;
         } else {
             previous_item->next_item = item;
@@ -29,10 +32,13 @@ void wifi_marauder_scene_script_stage_edit_create_list_strings(WifiMarauderApp*
     app->script_stage_edit_first_item = first_item;
 }
 
-void wifi_marauder_scene_script_stage_edit_create_list_numbers(WifiMarauderApp* app, int* numbers, int number_count) {
+void wifi_marauder_scene_script_stage_edit_create_list_numbers(
+    WifiMarauderApp* app,
+    int* numbers,
+    int number_count) {
     // Deallocates the existing list
     WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
-    while (current_item != NULL) {
+    while(current_item != NULL) {
         WifiMarauderScriptStageListItem* next_item = current_item->next_item;
         free(current_item->value);
         free(current_item);
@@ -42,15 +48,15 @@ void wifi_marauder_scene_script_stage_edit_create_list_numbers(WifiMarauderApp*
     // Create a new list with numbers
     WifiMarauderScriptStageListItem* first_item = NULL;
     WifiMarauderScriptStageListItem* previous_item = NULL;
-    for (int i = 0; i < number_count; i++) {
+    for(int i = 0; i < number_count; i++) {
         char number_str[32];
         snprintf(number_str, sizeof(number_str), "%d", numbers[i]);
-        
+
         WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
         item->value = strdup(number_str);
         item->next_item = NULL;
 
-        if (previous_item == NULL) {
+        if(previous_item == NULL) {
             first_item = item;
         } else {
             previous_item->next_item = item;
@@ -61,37 +67,40 @@ void wifi_marauder_scene_script_stage_edit_create_list_numbers(WifiMarauderApp*
     app->script_stage_edit_first_item = first_item;
 }
 
-static void wifi_marauder_scene_script_stage_edit_list_enter_callback(void* context, uint32_t index) {
+static void
+    wifi_marauder_scene_script_stage_edit_list_enter_callback(void* context, uint32_t index) {
     WifiMarauderApp* app = context;
     const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[index];
 
     // Fixed delete item
-    if (index == app->script_stage_menu->num_items) {
-        uint32_t deleted_stage_index = scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit);
-        if (deleted_stage_index > 0) {
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, deleted_stage_index - 1);
+    if(index == app->script_stage_menu->num_items) {
+        uint32_t deleted_stage_index =
+            scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit);
+        if(deleted_stage_index > 0) {
+            scene_manager_set_scene_state(
+                app->scene_manager, WifiMarauderSceneScriptEdit, deleted_stage_index - 1);
         }
         WifiMarauderScriptStage* previous_stage = NULL;
         WifiMarauderScriptStage* current_stage = app->script->first_stage;
         uint32_t current_stage_index = 0;
 
-        while (current_stage != NULL && current_stage_index < deleted_stage_index) {
+        while(current_stage != NULL && current_stage_index < deleted_stage_index) {
             previous_stage = current_stage;
             current_stage = current_stage->next_stage;
             current_stage_index++;
         }
 
         // Delete the stage
-        if (current_stage != NULL) {
-            if (previous_stage != NULL) {
-                if (current_stage->next_stage != NULL) {
+        if(current_stage != NULL) {
+            if(previous_stage != NULL) {
+                if(current_stage->next_stage != NULL) {
                     previous_stage->next_stage = current_stage->next_stage;
                 } else {
                     previous_stage->next_stage = NULL;
                     app->script->last_stage = previous_stage;
                 }
             } else {
-                if (current_stage->next_stage != NULL) {
+                if(current_stage->next_stage != NULL) {
                     app->script->first_stage = current_stage->next_stage;
                 } else {
                     app->script->first_stage = NULL;
@@ -105,31 +114,37 @@ static void wifi_marauder_scene_script_stage_edit_list_enter_callback(void* cont
         return;
     }
 
-    if (menu_item->select_callback == NULL) {
+    if(menu_item->select_callback == NULL) {
         return;
     }
-    if (menu_item->type == WifiMarauderScriptMenuItemTypeNumber) {
+    if(menu_item->type == WifiMarauderScriptMenuItemTypeNumber) {
         // Accepts user number input, assigning the value to the reference passed as a parameter
         menu_item->select_callback(app);
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
         app->user_input_type = WifiMarauderUserInputTypeNumber;
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
-    } else if (menu_item->type == WifiMarauderScriptMenuItemTypeString) {
+    } else if(menu_item->type == WifiMarauderScriptMenuItemTypeString) {
         // Accepts user string input, assigning the value to the reference passed as a parameter
         menu_item->select_callback(app);
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
         app->user_input_type = WifiMarauderUserInputTypeString;
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
-    } else if (menu_item->type == WifiMarauderScriptMenuItemTypeListString) {
+    } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListString) {
         // Accepts the strings that compose the list
         menu_item->select_callback(app);
-        wifi_marauder_scene_script_stage_edit_create_list_strings(app, *app->script_stage_edit_strings_reference, *app->script_stage_edit_string_count_reference);
+        wifi_marauder_scene_script_stage_edit_create_list_strings(
+            app,
+            *app->script_stage_edit_strings_reference,
+            *app->script_stage_edit_string_count_reference);
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
-    } else if (menu_item->type == WifiMarauderScriptMenuItemTypeListNumber) {
+    } else if(menu_item->type == WifiMarauderScriptMenuItemTypeListNumber) {
         // Accepts the numbers that compose the list
         menu_item->select_callback(app);
-        wifi_marauder_scene_script_stage_edit_create_list_numbers(app, *app->script_stage_edit_numbers_reference, *app->script_stage_edit_number_count_reference);
+        wifi_marauder_scene_script_stage_edit_create_list_numbers(
+            app,
+            *app->script_stage_edit_numbers_reference,
+            *app->script_stage_edit_number_count_reference);
         scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
     }
@@ -139,21 +154,28 @@ void wifi_marauder_scene_script_stage_edit_on_enter(void* context) {
     WifiMarauderApp* app = context;
     VariableItemList* var_item_list = app->var_item_list;
 
-    variable_item_list_set_enter_callback(app->var_item_list, wifi_marauder_scene_script_stage_edit_list_enter_callback, app);
-    app->script_stage_menu = wifi_marauder_script_stage_menu_create(app->script_edit_selected_stage->type);
+    variable_item_list_set_enter_callback(
+        app->var_item_list, wifi_marauder_scene_script_stage_edit_list_enter_callback, app);
+    app->script_stage_menu =
+        wifi_marauder_script_stage_menu_create(app->script_edit_selected_stage->type);
 
-    if (app->script_stage_menu->items != NULL) {
-        for (uint32_t i = 0; i < app->script_stage_menu->num_items; i++) {
+    if(app->script_stage_menu->items != NULL) {
+        for(uint32_t i = 0; i < app->script_stage_menu->num_items; i++) {
             WifiMarauderScriptMenuItem* stage_item = &app->script_stage_menu->items[i];
 
             // Changes the list item to handle it in callbacks
-            VariableItem* list_item = variable_item_list_add(app->var_item_list, stage_item->name, stage_item->num_options, stage_item->change_callback, app);
+            VariableItem* list_item = variable_item_list_add(
+                app->var_item_list,
+                stage_item->name,
+                stage_item->num_options,
+                stage_item->change_callback,
+                app);
 
             variable_item_list_set_selected_item(app->var_item_list, i);
-            if (stage_item->setup_callback != NULL) {
+            if(stage_item->setup_callback != NULL) {
                 stage_item->setup_callback(list_item);
             }
-            if (stage_item->change_callback != NULL) {
+            if(stage_item->change_callback != NULL) {
                 stage_item->change_callback(list_item);
             }
         }
@@ -161,7 +183,9 @@ void wifi_marauder_scene_script_stage_edit_on_enter(void* context) {
 
     variable_item_list_add(app->var_item_list, "[-] DELETE STAGE", 0, NULL, app);
 
-    variable_item_list_set_selected_item(var_item_list, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit));
+    variable_item_list_set_selected_item(
+        var_item_list,
+        scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
 }
 

+ 76 - 38
scenes/wifi_marauder_scene_sniffpmkid_options.c

@@ -13,37 +13,43 @@ static void wifi_marauder_scene_sniffpmkid_options_callback(void* context, uint3
     WifiMarauderApp* app = context;
 
     app->is_custom_tx_string = false; // this will be set if needed by text input
-    switch (index) {
-        case SubmenuIndexPassive:
-            app->selected_tx_string = "sniffpmkid";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
-            break;
-        case SubmenuIndexActive:
-            app->selected_tx_string = "sniffpmkid -d";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
-            break;
-        case SubmenuIndexTargetedPassive:
-            app->selected_tx_string = "sniffpmkid -l";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
-            break;
-        case SubmenuIndexTargetedActive:
-            app->selected_tx_string = "sniffpmkid -d -l";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
-            break;
-        case SubmenuIndexChannelPassive:
-            app->selected_tx_string = "sniffpmkid -c";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
-            break;
-        case SubmenuIndexChannelActive:
-            app->selected_tx_string = "sniffpmkid -d -c";
-            scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
-            scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
-            break;
+    switch(index) {
+    case SubmenuIndexPassive:
+        app->selected_tx_string = "sniffpmkid";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
+        break;
+    case SubmenuIndexActive:
+        app->selected_tx_string = "sniffpmkid -d";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
+        break;
+    case SubmenuIndexTargetedPassive:
+        app->selected_tx_string = "sniffpmkid -l";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
+        break;
+    case SubmenuIndexTargetedActive:
+        app->selected_tx_string = "sniffpmkid -d -l";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
+        break;
+    case SubmenuIndexChannelPassive:
+        app->selected_tx_string = "sniffpmkid -c";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
+        break;
+    case SubmenuIndexChannelActive:
+        app->selected_tx_string = "sniffpmkid -d -c";
+        scene_manager_set_scene_state(
+            app->scene_manager, WifiMarauderSceneSniffPmkidOptions, index);
+        scene_manager_next_scene(app->scene_manager, WifiMarauderSceneTextInput);
+        break;
     }
 }
 
@@ -53,14 +59,46 @@ void wifi_marauder_scene_sniffpmkid_options_on_enter(void* context) {
     Submenu* submenu = app->submenu;
 
     submenu_set_header(submenu, "Sniff PMKID");
-    submenu_add_item(submenu, "Passive", SubmenuIndexPassive, wifi_marauder_scene_sniffpmkid_options_callback, app);
-    submenu_add_item(submenu, "Active (Force Deauth)", SubmenuIndexActive, wifi_marauder_scene_sniffpmkid_options_callback, app);
-    submenu_add_item(submenu, "Targeted Passive (List)", SubmenuIndexTargetedPassive, wifi_marauder_scene_sniffpmkid_options_callback, app);
-    submenu_add_item(submenu, "Targeted Active (List)", SubmenuIndexTargetedActive, wifi_marauder_scene_sniffpmkid_options_callback, app);
-    submenu_add_item(submenu, "On Channel # - Passive", SubmenuIndexChannelPassive, wifi_marauder_scene_sniffpmkid_options_callback, app);
-    submenu_add_item(submenu, "On Channel # - Active", SubmenuIndexChannelActive, wifi_marauder_scene_sniffpmkid_options_callback, app);
+    submenu_add_item(
+        submenu,
+        "Passive",
+        SubmenuIndexPassive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "Active (Force Deauth)",
+        SubmenuIndexActive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "Targeted Passive (List)",
+        SubmenuIndexTargetedPassive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "Targeted Active (List)",
+        SubmenuIndexTargetedActive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "On Channel # - Passive",
+        SubmenuIndexChannelPassive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "On Channel # - Active",
+        SubmenuIndexChannelActive,
+        wifi_marauder_scene_sniffpmkid_options_callback,
+        app);
 
-    submenu_set_selected_item(submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions));
+    submenu_set_selected_item(
+        submenu,
+        scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneSniffPmkidOptions));
     view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
 }
 

+ 7 - 10
scenes/wifi_marauder_scene_start.c

@@ -97,13 +97,7 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = {
      NO_ARGS,
      FOCUS_CONSOLE_END,
      SHOW_STOPSCAN_TIP},
-    {"Signal Monitor",
-     {""},
-     1,
-     {"sigmon"},
-     NO_ARGS,
-     FOCUS_CONSOLE_END,
-     SHOW_STOPSCAN_TIP},
+    {"Signal Monitor", {""}, 1, {"sigmon"}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP},
     {"Channel",
      {"get", "set"},
      2,
@@ -161,15 +155,18 @@ static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uin
         return;
     }
 
-    if (app->selected_tx_string && strncmp("sniffpmkid", app->selected_tx_string, strlen("sniffpmkid")) == 0) {
+    if(app->selected_tx_string &&
+       strncmp("sniffpmkid", app->selected_tx_string, strlen("sniffpmkid")) == 0) {
         // sniffpmkid submenu
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartSniffPmkidOptions);
+        view_dispatcher_send_custom_event(
+            app->view_dispatcher, WifiMarauderEventStartSniffPmkidOptions);
         return;
     }
 
     // Select automation script
     if(index == NUM_MENU_ITEMS - 2) {
-        view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartScriptSelect);
+        view_dispatcher_send_custom_event(
+            app->view_dispatcher, WifiMarauderEventStartScriptSelect);
         return;
     }
 

+ 13 - 13
scenes/wifi_marauder_scene_text_input.c

@@ -44,24 +44,24 @@ void wifi_marauder_scene_text_input_on_enter(void* context) {
     }
 
     // Setup view
-    TextInput* text_input = app->text_input;
+    WIFI_TextInput* text_input = app->text_input;
     // Add help message to header
     if(app->special_case_input_step == 1) {
-        text_input_set_header_text(text_input, "Enter source MAC");
+        wifi_text_input_set_header_text(text_input, "Enter source MAC");
     } else if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) {
-        text_input_set_header_text(text_input, "Enter # SSIDs to generate");
+        wifi_text_input_set_header_text(text_input, "Enter # SSIDs to generate");
     } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) {
-        text_input_set_header_text(text_input, "Enter SSID name to add");
+        wifi_text_input_set_header_text(text_input, "Enter SSID name to add");
     } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) {
-        text_input_set_header_text(text_input, "Remove target from SSID list");
+        wifi_text_input_set_header_text(text_input, "Remove target from SSID list");
     } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) {
-        text_input_set_header_text(text_input, "Add target from AP list");
+        wifi_text_input_set_header_text(text_input, "Add target from AP list");
     } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) {
-        text_input_set_header_text(text_input, "Add target from SSID list");
+        wifi_text_input_set_header_text(text_input, "Add target from SSID list");
     } else {
-        text_input_set_header_text(text_input, "Add command arguments");
+        wifi_text_input_set_header_text(text_input, "Add command arguments");
     }
-    text_input_set_result_callback(
+    wifi_text_input_set_result_callback(
         text_input,
         wifi_marauder_scene_text_input_callback,
         app,
@@ -84,7 +84,7 @@ bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent ev
             consumed = true;
         } else if(event.event == WifiMarauderEventSaveSourceMac) {
             if(12 != strlen(app->text_input_store)) {
-                text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
+                wifi_text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
             } else {
                 snprintf(
                     app->special_case_input_src_addr,
@@ -106,12 +106,12 @@ bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent ev
                 // Advance scene to input destination MAC, clear text input
                 app->special_case_input_step = 2;
                 bzero(app->text_input_store, WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE);
-                text_input_set_header_text(app->text_input, "Enter destination MAC");
+                wifi_text_input_set_header_text(app->text_input, "Enter destination MAC");
             }
             consumed = true;
         } else if(event.event == WifiMarauderEventSaveDestinationMac) {
             if(12 != strlen(app->text_input_store)) {
-                text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
+                wifi_text_input_set_header_text(app->text_input, "MAC must be 12 hex chars!");
             } else {
                 snprintf(
                     app->special_case_input_dst_addr,
@@ -150,5 +150,5 @@ bool wifi_marauder_scene_text_input_on_event(void* context, SceneManagerEvent ev
 void wifi_marauder_scene_text_input_on_exit(void* context) {
     WifiMarauderApp* app = context;
 
-    text_input_reset(app->text_input);
+    wifi_text_input_reset(app->text_input);
 }

+ 102 - 78
scenes/wifi_marauder_scene_user_input.c

@@ -1,9 +1,12 @@
 #include "../wifi_marauder_app_i.h"
 
-bool wifi_marauder_scene_user_input_validator_number_callback(const char* text, FuriString* error, void* context) {
+bool wifi_marauder_scene_user_input_validator_number_callback(
+    const char* text,
+    FuriString* error,
+    void* context) {
     UNUSED(context);
-    for (int i = 0; text[i] != '\0'; i++) {
-        if (text[i] < '0' || text[i] > '9') {
+    for(int i = 0; text[i] != '\0'; i++) {
+        if(text[i] < '0' || text[i] > '9') {
             furi_string_printf(error, "This is not\na valid\nnumber!");
             return false;
         }
@@ -11,9 +14,12 @@ bool wifi_marauder_scene_user_input_validator_number_callback(const char* text,
     return true;
 }
 
-bool wifi_marauder_scene_user_input_validator_file_callback(const char* text, FuriString* error, void* context) {
+bool wifi_marauder_scene_user_input_validator_file_callback(
+    const char* text,
+    FuriString* error,
+    void* context) {
     UNUSED(context);
-    if (strlen(text) == 0) {
+    if(strlen(text) == 0) {
         furi_string_printf(error, "File name\ncannot be\nblank!");
         return false;
     }
@@ -26,50 +32,63 @@ void wifi_marauder_scene_user_input_ok_callback(void* context) {
     File* file = NULL;
     char* file_path = NULL;
 
-    switch (app->user_input_type) {
-        // Writes the string value of the reference
-        case WifiMarauderUserInputTypeString:
-            if (app->user_input_string_reference != NULL) {
-                strncpy(*app->user_input_string_reference, app->text_input_store, strlen(app->text_input_store) + 1);
-                app->user_input_string_reference = NULL;
-            }
-            break;
-        // Writes the numerical value of the reference
-        case WifiMarauderUserInputTypeNumber:
-            if (app->user_input_number_reference != NULL) {
-                *app->user_input_number_reference = atoi(app->text_input_store);
-                app->user_input_number_reference = NULL;
-            }
-            break;
-        // Creates a file with the name entered by the user, if it does not exist
-        case WifiMarauderUserInputTypeFileName:
-            file = storage_file_alloc(app->storage);
-            // Use application directory if not specified
-            if (app->user_input_file_dir == NULL) {
-                app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER);
-            }
-            if (app->user_input_file_extension != NULL) {
-                size_t file_path_len = strlen(app->user_input_file_dir) + strlen(app->text_input_store) + strlen(app->user_input_file_extension) + 3;
-                file_path = (char*)malloc(file_path_len);
-                snprintf(file_path, file_path_len, "%s/%s.%s", app->user_input_file_dir, app->text_input_store, app->user_input_file_extension);
-            } else {
-                size_t file_path_len = strlen(app->user_input_file_dir) + strlen(app->text_input_store) + 2;
-                file_path = (char*)malloc(file_path_len);
-                snprintf(file_path, file_path_len, "%s/%s", app->user_input_file_dir, app->text_input_store);
-            }
-            if (storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_NEW)) {
-                storage_file_close(file);
-            }
-            // Free memory
-            free(app->user_input_file_dir);
-            app->user_input_file_dir = NULL;
-            free(app->user_input_file_extension);
-            app->user_input_file_extension = NULL;
-            free(file_path);
-            storage_file_free(file);
-            break;
-        default:
-            break;
+    switch(app->user_input_type) {
+    // Writes the string value of the reference
+    case WifiMarauderUserInputTypeString:
+        if(app->user_input_string_reference != NULL) {
+            strncpy(
+                *app->user_input_string_reference,
+                app->text_input_store,
+                strlen(app->text_input_store) + 1);
+            app->user_input_string_reference = NULL;
+        }
+        break;
+    // Writes the numerical value of the reference
+    case WifiMarauderUserInputTypeNumber:
+        if(app->user_input_number_reference != NULL) {
+            *app->user_input_number_reference = atoi(app->text_input_store);
+            app->user_input_number_reference = NULL;
+        }
+        break;
+    // Creates a file with the name entered by the user, if it does not exist
+    case WifiMarauderUserInputTypeFileName:
+        file = storage_file_alloc(app->storage);
+        // Use application directory if not specified
+        if(app->user_input_file_dir == NULL) {
+            app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER);
+        }
+        if(app->user_input_file_extension != NULL) {
+            size_t file_path_len = strlen(app->user_input_file_dir) +
+                                   strlen(app->text_input_store) +
+                                   strlen(app->user_input_file_extension) + 3;
+            file_path = (char*)malloc(file_path_len);
+            snprintf(
+                file_path,
+                file_path_len,
+                "%s/%s.%s",
+                app->user_input_file_dir,
+                app->text_input_store,
+                app->user_input_file_extension);
+        } else {
+            size_t file_path_len =
+                strlen(app->user_input_file_dir) + strlen(app->text_input_store) + 2;
+            file_path = (char*)malloc(file_path_len);
+            snprintf(
+                file_path, file_path_len, "%s/%s", app->user_input_file_dir, app->text_input_store);
+        }
+        if(storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_NEW)) {
+            storage_file_close(file);
+        }
+        // Free memory
+        free(app->user_input_file_dir);
+        app->user_input_file_dir = NULL;
+        free(app->user_input_file_extension);
+        app->user_input_file_extension = NULL;
+        free(file_path);
+        storage_file_free(file);
+        break;
+    default:
+        break;
     }
 
     scene_manager_previous_scene(app->scene_manager);
@@ -78,36 +97,41 @@ void wifi_marauder_scene_user_input_ok_callback(void* context) {
 void wifi_marauder_scene_user_input_on_enter(void* context) {
     WifiMarauderApp* app = context;
 
-    switch (app->user_input_type) {
-        // Loads the string value of the reference
-        case WifiMarauderUserInputTypeString:
-            text_input_set_header_text(app->text_input, "Enter value:");
-            text_input_set_validator(app->text_input, NULL, app);
-            if (app->user_input_string_reference != NULL) {
-                strncpy(app->text_input_store, *app->user_input_string_reference, strlen(*app->user_input_string_reference) + 1);
-            }
-            break;
-        // Loads the numerical value of the reference
-        case WifiMarauderUserInputTypeNumber:
-            text_input_set_header_text(app->text_input, "Enter a valid number:");
-            text_input_set_validator(app->text_input, wifi_marauder_scene_user_input_validator_number_callback, app);
-            if (app->user_input_number_reference != NULL) {
-                char number_str[32];
-                snprintf(number_str, sizeof(number_str), "%d", *app->user_input_number_reference);
-                strncpy(app->text_input_store, number_str, strlen(number_str) + 1);
-            }
-            break;
-        // File name
-        case WifiMarauderUserInputTypeFileName:
-            text_input_set_header_text(app->text_input, "Enter file name:");
-            text_input_set_validator(app->text_input, wifi_marauder_scene_user_input_validator_file_callback, app);
-            break;
-        default:
-            scene_manager_previous_scene(app->scene_manager);
-            return;
+    switch(app->user_input_type) {
+    // Loads the string value of the reference
+    case WifiMarauderUserInputTypeString:
+        wifi_text_input_set_header_text(app->text_input, "Enter value:");
+        wifi_text_input_set_validator(app->text_input, NULL, app);
+        if(app->user_input_string_reference != NULL) {
+            strncpy(
+                app->text_input_store,
+                *app->user_input_string_reference,
+                strlen(*app->user_input_string_reference) + 1);
+        }
+        break;
+    // Loads the numerical value of the reference
+    case WifiMarauderUserInputTypeNumber:
+        wifi_text_input_set_header_text(app->text_input, "Enter a valid number:");
+        wifi_text_input_set_validator(
+            app->text_input, wifi_marauder_scene_user_input_validator_number_callback, app);
+        if(app->user_input_number_reference != NULL) {
+            char number_str[32];
+            snprintf(number_str, sizeof(number_str), "%d", *app->user_input_number_reference);
+            strncpy(app->text_input_store, number_str, strlen(number_str) + 1);
+        }
+        break;
+    // File name
+    case WifiMarauderUserInputTypeFileName:
+        wifi_text_input_set_header_text(app->text_input, "Enter file name:");
+        wifi_text_input_set_validator(
+            app->text_input, wifi_marauder_scene_user_input_validator_file_callback, app);
+        break;
+    default:
+        scene_manager_previous_scene(app->scene_manager);
+        return;
     }
 
-    text_input_set_result_callback(
+    wifi_text_input_set_result_callback(
         app->text_input,
         wifi_marauder_scene_user_input_ok_callback,
         app,
@@ -127,5 +151,5 @@ bool wifi_marauder_scene_user_input_on_event(void* context, SceneManagerEvent ev
 void wifi_marauder_scene_user_input_on_exit(void* context) {
     WifiMarauderApp* app = context;
     memset(app->text_input_store, 0, sizeof(app->text_input_store));
-    text_input_reset(app->text_input);
+    wifi_text_input_reset(app->text_input);
 }

Разница между файлами не показана из-за своего большого размера
+ 220 - 343
script/cJSON.c


+ 133 - 105
script/cJSON.h

@@ -24,11 +24,11 @@
 #define cJSON__h
 
 #ifdef __cplusplus
-extern "C"
-{
+extern "C" {
 #endif
 
-#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
+#if !defined(__WINDOWS__) && \
+    (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
 #define __WINDOWS__
 #endif
 
@@ -56,23 +56,25 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
 #define CJSON_STDCALL __stdcall
 
 /* export symbols by default, this is necessary for copy pasting the C and header file */
-#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
+#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && \
+    !defined(CJSON_EXPORT_SYMBOLS)
 #define CJSON_EXPORT_SYMBOLS
 #endif
 
 #if defined(CJSON_HIDE_SYMBOLS)
-#define CJSON_PUBLIC(type)   type CJSON_STDCALL
+#define CJSON_PUBLIC(type) type CJSON_STDCALL
 #elif defined(CJSON_EXPORT_SYMBOLS)
-#define CJSON_PUBLIC(type)   __declspec(dllexport) type CJSON_STDCALL
+#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
 #elif defined(CJSON_IMPORT_SYMBOLS)
-#define CJSON_PUBLIC(type)   __declspec(dllimport) type CJSON_STDCALL
+#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
 #endif
 #else /* !__WINDOWS__ */
 #define CJSON_CDECL
 #define CJSON_STDCALL
 
-#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
-#define CJSON_PUBLIC(type)   __attribute__((visibility("default"))) type
+#if(defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && \
+    defined(CJSON_API_VISIBILITY)
+#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
 #else
 #define CJSON_PUBLIC(type) type
 #endif
@@ -87,46 +89,44 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
 
 /* cJSON Types: */
 #define cJSON_Invalid (0)
-#define cJSON_False  (1 << 0)
-#define cJSON_True   (1 << 1)
-#define cJSON_NULL   (1 << 2)
+#define cJSON_False (1 << 0)
+#define cJSON_True (1 << 1)
+#define cJSON_NULL (1 << 2)
 #define cJSON_Number (1 << 3)
 #define cJSON_String (1 << 4)
-#define cJSON_Array  (1 << 5)
+#define cJSON_Array (1 << 5)
 #define cJSON_Object (1 << 6)
-#define cJSON_Raw    (1 << 7) /* raw json */
+#define cJSON_Raw (1 << 7) /* raw json */
 
 #define cJSON_IsReference 256
 #define cJSON_StringIsConst 512
 
 /* The cJSON structure: */
-typedef struct cJSON
-{
+typedef struct cJSON {
     /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
-    struct cJSON *next;
-    struct cJSON *prev;
+    struct cJSON* next;
+    struct cJSON* prev;
     /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
-    struct cJSON *child;
+    struct cJSON* child;
 
     /* The type of the item, as above. */
     int type;
 
     /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
-    char *valuestring;
+    char* valuestring;
     /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
     int valueint;
     /* The item's number, if type==cJSON_Number */
     double valuedouble;
 
     /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
-    char *string;
+    char* string;
 } cJSON;
 
-typedef struct cJSON_Hooks
-{
-      /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
-      void *(CJSON_CDECL *malloc_fn)(size_t sz);
-      void (CJSON_CDECL *free_fn)(void *ptr);
+typedef struct cJSON_Hooks {
+    /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
+    void*(CJSON_CDECL* malloc_fn)(size_t sz);
+    void(CJSON_CDECL* free_fn)(void* ptr);
 } cJSON_Hooks;
 
 typedef int cJSON_bool;
@@ -145,146 +145,174 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
 
 /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
 /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
-CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
-CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
+CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value);
+CJSON_PUBLIC(cJSON*) cJSON_ParseWithLength(const char* value, size_t buffer_length);
 /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
 /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
-CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
-CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
+CJSON_PUBLIC(cJSON*)
+cJSON_ParseWithOpts(
+    const char* value,
+    const char** return_parse_end,
+    cJSON_bool require_null_terminated);
+CJSON_PUBLIC(cJSON*)
+cJSON_ParseWithLengthOpts(
+    const char* value,
+    size_t buffer_length,
+    const char** return_parse_end,
+    cJSON_bool require_null_terminated);
 
 /* Render a cJSON entity to text for transfer/storage. */
-CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
+CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item);
 /* Render a cJSON entity to text for transfer/storage without any formatting. */
-CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
+CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item);
 /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
-CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
+CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt);
 /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
 /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
-CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format);
 /* Delete a cJSON entity and all subentities. */
-CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
+CJSON_PUBLIC(void) cJSON_Delete(cJSON* item);
 
 /* Returns the number of items in an array (or object). */
-CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
+CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array);
 /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
-CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
+CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index);
 /* Get item "string" from object. Case insensitive. */
-CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
-CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
-CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
+CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string);
+CJSON_PUBLIC(cJSON*)
+cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string);
+CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string);
 /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
-CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
+CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void);
 
 /* Check item type and return its value */
-CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
-CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
+CJSON_PUBLIC(char*) cJSON_GetStringValue(const cJSON* const item);
+CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON* const item);
 
 /* These functions check the type of an item */
-CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
-CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item);
 
 /* These calls create a cJSON item of the appropriate type. */
-CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
-CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
-CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
-CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
-CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
-CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
+CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void);
+CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void);
+CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void);
+CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean);
+CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num);
+CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string);
 /* raw json */
-CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
-CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
-CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
+CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw);
+CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void);
+CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void);
 
 /* Create a string where valuestring references a string so
  * it will not be freed by cJSON_Delete */
-CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
+CJSON_PUBLIC(cJSON*) cJSON_CreateStringReference(const char* string);
 /* Create an object/array that only references it's elements so
  * they will not be freed by cJSON_Delete */
-CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
-CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
+CJSON_PUBLIC(cJSON*) cJSON_CreateObjectReference(const cJSON* child);
+CJSON_PUBLIC(cJSON*) cJSON_CreateArrayReference(const cJSON* child);
 
 /* These utilities create an Array of count items.
  * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
-CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
-CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
-CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
-CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
+CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count);
+CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count);
+CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count);
+CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char* const* strings, int count);
 
 /* Append item to the specified array/object. */
-CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
-CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
+CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON* array, cJSON* item);
+CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item);
 /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
  * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
  * writing to `item->string` */
-CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
+CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item);
 /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
-CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
-CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
+CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item);
 
 /* Remove/Detach items from Arrays/Objects. */
-CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
-CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
-CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
-CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
-CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
-CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
-CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
+CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item);
+CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which);
+CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string);
+CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string);
 
 /* Update array items. */
-CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
-CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
-CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
-CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
-CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_InsertItemInArray(
+    cJSON* array,
+    int which,
+    cJSON* newitem); /* Shifts pre-existing items to the right. */
+CJSON_PUBLIC(cJSON_bool)
+cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement);
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem);
 
 /* Duplicate a cJSON item */
-CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
+CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse);
 /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
  * need to be released. With recurse!=0, it will duplicate any children connected to the item.
  * The item->next and ->prev pointers are always zero on return from Duplicate. */
 /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
  * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
-CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
+CJSON_PUBLIC(cJSON_bool)
+cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive);
 
 /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
  * The input pointer json cannot point to a read-only address area, such as a string constant, 
  * but should point to a readable and writable address area. */
-CJSON_PUBLIC(void) cJSON_Minify(char *json);
+CJSON_PUBLIC(void) cJSON_Minify(char* json);
 
 /* Helper functions for creating and adding items to an object at the same time.
  * They return the added item or NULL on failure. */
-CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
-CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
-CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
-CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
-CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
-CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
-CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
-CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
-CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON* const object, const char* const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON* const object, const char* const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON* const object, const char* const name);
+CJSON_PUBLIC(cJSON*)
+cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean);
+CJSON_PUBLIC(cJSON*)
+cJSON_AddNumberToObject(cJSON* const object, const char* const name, const double number);
+CJSON_PUBLIC(cJSON*)
+cJSON_AddStringToObject(cJSON* const object, const char* const name, const char* const string);
+CJSON_PUBLIC(cJSON*)
+cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw);
+CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON* const object, const char* const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON* const object, const char* const name);
 
 /* When assigning an integer value, it needs to be propagated to valuedouble too. */
-#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
+#define cJSON_SetIntValue(object, number) \
+    ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
 /* helper for the cJSON_SetNumberValue macro */
-CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
-#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number);
+#define cJSON_SetNumberValue(object, number) \
+    ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
 /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
-CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
+CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON* object, const char* valuestring);
 
 /* Macro for iterating over an array or object */
-#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
+#define cJSON_ArrayForEach(element, array)                                  \
+    for(element = (array != NULL) ? (array)->child : NULL; element != NULL; \
+        element = element->next)
 
 /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
-CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
-CJSON_PUBLIC(void) cJSON_free(void *object);
+CJSON_PUBLIC(void*) cJSON_malloc(size_t size);
+CJSON_PUBLIC(void) cJSON_free(void* object);
 
 #ifdef __cplusplus
 }

+ 12 - 11
script/menu/wifi_marauder_script_stage_menu.c

@@ -1,27 +1,28 @@
 #include "wifi_marauder_script_stage_menu.h"
 
-WifiMarauderScriptStageMenu* wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type) {
+WifiMarauderScriptStageMenu*
+    wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type) {
     WifiMarauderScriptStageMenu* script_stage_menu = malloc(sizeof(WifiMarauderScriptStageMenu));
 
-    switch (stage_type) {
-        #define ADD_STAGE(name, id) \
-            case WifiMarauderScriptStageType##id: \
-                wifi_marauder_script_stage_menu_##name##_load(script_stage_menu); \
-                break;
+    switch(stage_type) {
+#define ADD_STAGE(name, id)                                               \
+    case WifiMarauderScriptStageType##id:                                 \
+        wifi_marauder_script_stage_menu_##name##_load(script_stage_menu); \
+        break;
 
-        #include "wifi_marauder_script_stage_menu_config.h"
-        #undef ADD_STAGE
+#include "wifi_marauder_script_stage_menu_config.h"
+#undef ADD_STAGE
     }
     return script_stage_menu;
 }
 
 void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* stage_menu) {
-    if (stage_menu == NULL) {
+    if(stage_menu == NULL) {
         return;
     }
-    for (uint32_t i = 0; i < stage_menu->num_items; i++) {
+    for(uint32_t i = 0; i < stage_menu->num_items; i++) {
         WifiMarauderScriptMenuItem* item = &(stage_menu->items[i]);
-        for (int j = 0; j < item->num_options; j++) {
+        for(int j = 0; j < item->num_options; j++) {
             free(item->options[j]);
         }
         free(item->name);

+ 4 - 2
script/menu/wifi_marauder_script_stage_menu.h

@@ -32,9 +32,11 @@ typedef struct WifiMarauderScriptStageMenu {
     uint32_t num_items;
 } WifiMarauderScriptStageMenu;
 
-#define ADD_STAGE(name, id) void wifi_marauder_script_stage_menu_##name##_load(WifiMarauderScriptStageMenu*);
+#define ADD_STAGE(name, id) \
+    void wifi_marauder_script_stage_menu_##name##_load(WifiMarauderScriptStageMenu*);
 #include "wifi_marauder_script_stage_menu_config.h"
 #undef ADD_STAGE
 
-WifiMarauderScriptStageMenu* wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type);
+WifiMarauderScriptStageMenu*
+    wifi_marauder_script_stage_menu_create(WifiMarauderScriptStageType stage_type);
 void wifi_marauder_script_stage_menu_free(WifiMarauderScriptStageMenu* list);

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_beaconap.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_beaconap_load(WifiMarauderScriptStageMenu*
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = "Timeout",
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_beaconap_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_beaconap_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_beaconap_stage_timeout_select_callback};
 }

+ 6 - 9
script/menu/wifi_marauder_script_stage_menu_beaconlist.c

@@ -39,24 +39,21 @@ void wifi_marauder_script_stage_menu_beaconlist_load(WifiMarauderScriptStageMenu
     stage_menu->num_items = 3;
     stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("SSIDs"),
         .type = WifiMarauderScriptMenuItemTypeListString,
         .num_options = 1,
-        .select_callback = wifi_marauder_beaconlist_stage_ssids_select_callback
-    };
-    stage_menu->items[1] = (WifiMarauderScriptMenuItem) {
+        .select_callback = wifi_marauder_beaconlist_stage_ssids_select_callback};
+    stage_menu->items[1] = (WifiMarauderScriptMenuItem){
         .name = strdup("Generate random"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_beaconlist_stage_random_ssids_setup_callback,
-        .select_callback = wifi_marauder_beaconlist_stage_random_ssids_select_callback
-    };
-    stage_menu->items[2] = (WifiMarauderScriptMenuItem) {
+        .select_callback = wifi_marauder_beaconlist_stage_random_ssids_select_callback};
+    stage_menu->items[2] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_beaconlist_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_beaconlist_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_beaconlist_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_deauth.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_deauth_load(WifiMarauderScriptStageMenu* st
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_deauth_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_deauth_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_deauth_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_delay.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_delay_load(WifiMarauderScriptStageMenu* sta
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_delay_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_delay_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_delay_stage_timeout_select_callback};
 }

+ 4 - 5
script/menu/wifi_marauder_script_stage_menu_exec.c

@@ -3,7 +3,7 @@
 void wifi_marauder_exec_stage_filter_setup_callback(VariableItem* item) {
     WifiMarauderApp* app = variable_item_get_context(item);
     WifiMarauderScriptStageExec* stage = app->script_edit_selected_stage->stage;
-    if (stage->command != NULL) {
+    if(stage->command != NULL) {
         variable_item_set_current_value_text(item, stage->command);
     }
 }
@@ -11,7 +11,7 @@ void wifi_marauder_exec_stage_filter_setup_callback(VariableItem* item) {
 void wifi_marauder_exec_stage_filter_select_callback(void* context) {
     WifiMarauderApp* app = context;
     WifiMarauderScriptStageExec* stage_select = app->script_edit_selected_stage->stage;
-    if (stage_select->command == NULL) {
+    if(stage_select->command == NULL) {
         stage_select->command = malloc(128);
     }
     app->user_input_string_reference = &stage_select->command;
@@ -21,11 +21,10 @@ void wifi_marauder_script_stage_menu_exec_load(WifiMarauderScriptStageMenu* stag
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Command"),
         .type = WifiMarauderScriptMenuItemTypeString,
         .num_options = 1,
         .setup_callback = wifi_marauder_exec_stage_filter_setup_callback,
-        .select_callback = wifi_marauder_exec_stage_filter_select_callback
-    };
+        .select_callback = wifi_marauder_exec_stage_filter_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_probe.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_probe_load(WifiMarauderScriptStageMenu* sta
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_probe_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_probe_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_probe_stage_timeout_select_callback};
 }

+ 9 - 8
script/menu/wifi_marauder_script_stage_menu_scan.c

@@ -11,7 +11,8 @@ void wifi_marauder_scan_stage_type_change_callback(VariableItem* item) {
 
     // Get menu item
     uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
-    const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[current_stage_index];
+    const WifiMarauderScriptMenuItem* menu_item =
+        &app->script_stage_menu->items[current_stage_index];
 
     // Defines the text of the selected option
     uint8_t option_index = variable_item_get_current_value_index(item);
@@ -25,7 +26,7 @@ void wifi_marauder_scan_stage_type_change_callback(VariableItem* item) {
 void wifi_marauder_scan_stage_channel_setup_callback(VariableItem* item) {
     WifiMarauderApp* app = variable_item_get_context(item);
     WifiMarauderScriptStageScan* stage = app->script_edit_selected_stage->stage;
-    if (stage->channel >= 0 && stage->channel < 12) {
+    if(stage->channel >= 0 && stage->channel < 12) {
         variable_item_set_current_value_index(item, stage->channel);
     } else {
         variable_item_set_current_value_index(item, 0);
@@ -37,7 +38,8 @@ void wifi_marauder_scan_stage_channel_change_callback(VariableItem* item) {
 
     // Get menu item
     uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
-    const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[current_stage_index];
+    const WifiMarauderScriptMenuItem* menu_item =
+        &app->script_stage_menu->items[current_stage_index];
 
     // Defines the text of the selected option
     uint8_t option_index = variable_item_get_current_value_index(item);
@@ -66,7 +68,7 @@ void wifi_marauder_script_stage_menu_scan_load(WifiMarauderScriptStageMenu* stag
     stage_menu->num_items = 3;
     stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Type"),
         .type = WifiMarauderScriptMenuItemTypeOptionsString,
         .num_options = 2,
@@ -74,7 +76,7 @@ void wifi_marauder_script_stage_menu_scan_load(WifiMarauderScriptStageMenu* stag
         .setup_callback = wifi_marauder_scan_stage_type_setup_callback,
         .change_callback = wifi_marauder_scan_stage_type_change_callback,
     };
-    stage_menu->items[1] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[1] = (WifiMarauderScriptMenuItem){
         .name = strdup("Channel"),
         .type = WifiMarauderScriptMenuItemTypeOptionsNumber,
         .num_options = 12,
@@ -82,11 +84,10 @@ void wifi_marauder_script_stage_menu_scan_load(WifiMarauderScriptStageMenu* stag
         .setup_callback = wifi_marauder_scan_stage_channel_setup_callback,
         .change_callback = wifi_marauder_scan_stage_channel_change_callback,
     };
-    stage_menu->items[2] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[2] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_scan_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_scan_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_scan_stage_timeout_select_callback};
 }

+ 12 - 14
script/menu/wifi_marauder_script_stage_menu_select.c

@@ -11,7 +11,8 @@ void wifi_marauder_select_stage_type_change_callback(VariableItem* item) {
 
     // Get menu item
     uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
-    const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[current_stage_index];
+    const WifiMarauderScriptMenuItem* menu_item =
+        &app->script_stage_menu->items[current_stage_index];
 
     // Defines the text of the selected option
     uint8_t option_index = variable_item_get_current_value_index(item);
@@ -26,7 +27,7 @@ void wifi_marauder_select_stage_filter_setup_callback(VariableItem* item) {
     WifiMarauderApp* app = variable_item_get_context(item);
     WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
 
-    if (stage->filter != NULL) {
+    if(stage->filter != NULL) {
         variable_item_set_current_value_index(item, 0);
         variable_item_set_current_value_text(item, stage->filter);
     } else {
@@ -39,13 +40,13 @@ void wifi_marauder_select_stage_filter_change_callback(VariableItem* item) {
     WifiMarauderScriptStageSelect* stage = app->script_edit_selected_stage->stage;
 
     // Clears the filter if you change the option. Flipper input box does not accept blank text
-    if (variable_item_get_current_value_index(item) == 1) {
+    if(variable_item_get_current_value_index(item) == 1) {
         stage->filter = NULL;
         variable_item_set_current_value_index(item, 0);
         variable_item_set_values_count(item, 1);
     }
 
-    if (stage->filter != NULL) {
+    if(stage->filter != NULL) {
         variable_item_set_current_value_text(item, stage->filter);
     } else {
         variable_item_set_current_value_text(item, "");
@@ -55,7 +56,7 @@ void wifi_marauder_select_stage_filter_change_callback(VariableItem* item) {
 void wifi_marauder_select_stage_filter_select_callback(void* context) {
     WifiMarauderApp* app = context;
     WifiMarauderScriptStageSelect* stage_select = app->script_edit_selected_stage->stage;
-    if (stage_select->filter == NULL) {
+    if(stage_select->filter == NULL) {
         stage_select->filter = malloc(128);
     }
     app->user_input_string_reference = &stage_select->filter;
@@ -72,26 +73,23 @@ void wifi_marauder_script_stage_menu_select_load(WifiMarauderScriptStageMenu* st
     stage_menu->num_items = 3;
     stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Type"),
         .type = WifiMarauderScriptMenuItemTypeOptionsString,
         .num_options = 2,
         .options = {"ap", "station"},
         .setup_callback = wifi_marauder_select_stage_type_setup_callback,
-        .change_callback = wifi_marauder_select_stage_type_change_callback
-    };
-    stage_menu->items[1] = (WifiMarauderScriptMenuItem) {
+        .change_callback = wifi_marauder_select_stage_type_change_callback};
+    stage_menu->items[1] = (WifiMarauderScriptMenuItem){
         .name = strdup("Filter"),
         .type = WifiMarauderScriptMenuItemTypeString,
         .num_options = 2,
         .setup_callback = wifi_marauder_select_stage_filter_setup_callback,
         .change_callback = wifi_marauder_select_stage_filter_change_callback,
-        .select_callback = wifi_marauder_select_stage_filter_select_callback
-    };
-    stage_menu->items[2] = (WifiMarauderScriptMenuItem) {
+        .select_callback = wifi_marauder_select_stage_filter_select_callback};
+    stage_menu->items[2] = (WifiMarauderScriptMenuItem){
         .name = strdup("Indexes"),
         .type = WifiMarauderScriptMenuItemTypeListNumber,
         .num_options = 1,
-        .select_callback = wifi_marauder_select_stage_indexes_select_callback
-    };
+        .select_callback = wifi_marauder_select_stage_indexes_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_sniffbeacon.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_sniffbeacon_load(WifiMarauderScriptStageMen
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffbeacon_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffbeacon_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffbeacon_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_sniffdeauth.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_sniffdeauth_load(WifiMarauderScriptStageMen
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffdeauth_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffdeauth_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffdeauth_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_sniffesp.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_sniffesp_load(WifiMarauderScriptStageMenu*
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffesp_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffesp_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffesp_stage_timeout_select_callback};
 }

+ 11 - 12
script/menu/wifi_marauder_script_stage_menu_sniffpmkid.c

@@ -11,7 +11,8 @@ static void wifi_marauder_sniffpmkid_stage_force_deauth_change_callback(Variable
 
     // Get menu item
     uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
-    const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[current_stage_index];
+    const WifiMarauderScriptMenuItem* menu_item =
+        &app->script_stage_menu->items[current_stage_index];
 
     // Defines the text of the selected option
     uint8_t option_index = variable_item_get_current_value_index(item);
@@ -25,7 +26,7 @@ static void wifi_marauder_sniffpmkid_stage_force_deauth_change_callback(Variable
 static void wifi_marauder_sniffpmkid_stage_channel_setup_callback(VariableItem* item) {
     WifiMarauderApp* app = variable_item_get_context(item);
     WifiMarauderScriptStageSniffPmkid* stage = app->script_edit_selected_stage->stage;
-    if (stage->channel >= 0 && stage->channel < 12) {
+    if(stage->channel >= 0 && stage->channel < 12) {
         variable_item_set_current_value_index(item, stage->channel);
     } else {
         variable_item_set_current_value_index(item, 0);
@@ -37,7 +38,8 @@ static void wifi_marauder_sniffpmkid_stage_channel_change_callback(VariableItem*
 
     // Get menu item
     uint8_t current_stage_index = variable_item_list_get_selected_item_index(app->var_item_list);
-    const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[current_stage_index];
+    const WifiMarauderScriptMenuItem* menu_item =
+        &app->script_stage_menu->items[current_stage_index];
 
     // Defines the text of the selected option
     uint8_t option_index = variable_item_get_current_value_index(item);
@@ -66,27 +68,24 @@ void wifi_marauder_script_stage_menu_sniffpmkid_load(WifiMarauderScriptStageMenu
     stage_menu->num_items = 3;
     stage_menu->items = malloc(3 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Force deauth"),
         .type = WifiMarauderScriptMenuItemTypeOptionsString,
         .num_options = 2,
         .options = {"no", "yes"},
         .setup_callback = wifi_marauder_sniffpmkid_stage_force_deauth_setup_callback,
-        .change_callback = wifi_marauder_sniffpmkid_stage_force_deauth_change_callback
-    };
-    stage_menu->items[1] = (WifiMarauderScriptMenuItem) {
+        .change_callback = wifi_marauder_sniffpmkid_stage_force_deauth_change_callback};
+    stage_menu->items[1] = (WifiMarauderScriptMenuItem){
         .name = strdup("Channel"),
         .type = WifiMarauderScriptMenuItemTypeOptionsNumber,
         .num_options = 12,
         .options = {"none", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"},
         .setup_callback = wifi_marauder_sniffpmkid_stage_channel_setup_callback,
-        .change_callback = wifi_marauder_sniffpmkid_stage_channel_change_callback
-    };
-    stage_menu->items[2] = (WifiMarauderScriptMenuItem) {
+        .change_callback = wifi_marauder_sniffpmkid_stage_channel_change_callback};
+    stage_menu->items[2] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffpmkid_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffpmkid_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffpmkid_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_sniffpwn.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_sniffpwn_load(WifiMarauderScriptStageMenu*
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffpwn_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffpwn_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffpwn_stage_timeout_select_callback};
 }

+ 2 - 3
script/menu/wifi_marauder_script_stage_menu_sniffraw.c

@@ -18,11 +18,10 @@ void wifi_marauder_script_stage_menu_sniffraw_load(WifiMarauderScriptStageMenu*
     stage_menu->num_items = 1;
     stage_menu->items = malloc(1 * sizeof(WifiMarauderScriptMenuItem));
 
-    stage_menu->items[0] = (WifiMarauderScriptMenuItem) {
+    stage_menu->items[0] = (WifiMarauderScriptMenuItem){
         .name = strdup("Timeout"),
         .type = WifiMarauderScriptMenuItemTypeNumber,
         .num_options = 1,
         .setup_callback = wifi_marauder_sniffraw_stage_timeout_setup_callback,
-        .select_callback = wifi_marauder_sniffraw_stage_timeout_select_callback
-    };
+        .select_callback = wifi_marauder_sniffraw_stage_timeout_select_callback};
 }

Разница между файлами не показана из-за своего большого размера
+ 339 - 241
script/wifi_marauder_script.c


+ 16 - 8
script/wifi_marauder_script.h

@@ -152,7 +152,7 @@ typedef enum {
 typedef struct WifiMarauderScriptStage {
     WifiMarauderScriptStageType type;
     void* stage;
-    struct WifiMarauderScriptStage *next_stage;
+    struct WifiMarauderScriptStage* next_stage;
 } WifiMarauderScriptStage;
 
 typedef struct WifiMarauderScriptStageScan {
@@ -205,7 +205,7 @@ typedef struct WifiMarauderScriptStageSniffPwn {
 } WifiMarauderScriptStageSniffPwn;
 
 typedef struct WifiMarauderScriptStageBeaconList {
-    char **ssids;
+    char** ssids;
     int ssid_count;
     int random_ssids;
     int timeout;
@@ -227,8 +227,8 @@ typedef struct WifiMarauderScriptStageDelay {
 typedef struct WifiMarauderScript {
     char* name;
     char* description;
-    WifiMarauderScriptStage *first_stage;
-    WifiMarauderScriptStage *last_stage;
+    WifiMarauderScriptStage* first_stage;
+    WifiMarauderScriptStage* last_stage;
     WifiMarauderScriptBoolean enable_led;
     WifiMarauderScriptBoolean save_pcap;
     int repeat;
@@ -243,7 +243,15 @@ WifiMarauderScript* wifi_marauder_script_alloc();
 WifiMarauderScript* wifi_marauder_script_create(const char* script_name);
 WifiMarauderScript* wifi_marauder_script_parse_raw(const char* script_raw);
 WifiMarauderScript* wifi_marauder_script_parse_json(Storage* storage, const char* file_path);
-void wifi_marauder_script_save_json(Storage* storage, const char* file_path, WifiMarauderScript* script);
-void wifi_marauder_script_add_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type, void* stage_data);
-bool wifi_marauder_script_has_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type);
-void wifi_marauder_script_free(WifiMarauderScript *script);
+void wifi_marauder_script_save_json(
+    Storage* storage,
+    const char* file_path,
+    WifiMarauderScript* script);
+void wifi_marauder_script_add_stage(
+    WifiMarauderScript* script,
+    WifiMarauderScriptStageType stage_type,
+    void* stage_data);
+bool wifi_marauder_script_has_stage(
+    WifiMarauderScript* script,
+    WifiMarauderScriptStageType stage_type);
+void wifi_marauder_script_free(WifiMarauderScript* script);

+ 139 - 94
script/wifi_marauder_script_executor.c

@@ -2,8 +2,7 @@
 #include "wifi_marauder_script_executor.h"
 
 void _wifi_marauder_script_delay(WifiMarauderScriptWorker* worker, uint32_t delay_secs) {
-    for (uint32_t i=0; i<delay_secs && worker->is_running; i++)
-        furi_delay_ms(1000);
+    for(uint32_t i = 0; i < delay_secs && worker->is_running; i++) furi_delay_ms(1000);
 }
 
 void _send_stop() {
@@ -22,14 +21,16 @@ void _send_channel_select(int channel) {
     wifi_marauder_uart_tx((uint8_t*)(command), strlen(command));
 }
 
-void _wifi_marauder_script_execute_scan(WifiMarauderScriptStageScan* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_scan(
+    WifiMarauderScriptStageScan* stage,
+    WifiMarauderScriptWorker* worker) {
     char command[15];
     // Set channel
-    if (stage->channel > 0) {
+    if(stage->channel > 0) {
         _send_channel_select(stage->channel);
     }
     // Start scan
-    if (stage->type == WifiMarauderScriptScanTypeAp) {
+    if(stage->type == WifiMarauderScriptScanTypeAp) {
         snprintf(command, sizeof(command), "scanap\n");
     } else {
         snprintf(command, sizeof(command), "scansta\n");
@@ -41,95 +42,112 @@ void _wifi_marauder_script_execute_scan(WifiMarauderScriptStageScan* stage, Wifi
 
 void _wifi_marauder_script_execute_select(WifiMarauderScriptStageSelect* stage) {
     const char* select_type = NULL;
-    switch (stage->type) {
-        case WifiMarauderScriptSelectTypeAp:
-            select_type = "-a";
-            break;
-        case WifiMarauderScriptSelectTypeStation:
-            select_type = "-c";
-            break;
-        case WifiMarauderScriptSelectTypeSsid:
-            select_type = "-s";
-            break;
-        default:
-            return;  // invalid stage
+    switch(stage->type) {
+    case WifiMarauderScriptSelectTypeAp:
+        select_type = "-a";
+        break;
+    case WifiMarauderScriptSelectTypeStation:
+        select_type = "-c";
+        break;
+    case WifiMarauderScriptSelectTypeSsid:
+        select_type = "-s";
+        break;
+    default:
+        return; // invalid stage
     }
 
     char command[256];
     size_t command_length = 0;
 
-    if (stage->indexes != NULL && stage->index_count > 0) {
+    if(stage->indexes != NULL && stage->index_count > 0) {
         command_length = snprintf(command, sizeof(command), "select %s ", select_type);
 
-        for (int i = 0; i < stage->index_count; i++) {
+        for(int i = 0; i < stage->index_count; i++) {
             int index = stage->indexes[i];
-            command_length += snprintf(command + command_length, sizeof(command) - command_length, "%d, ", index);
+            command_length += snprintf(
+                command + command_length, sizeof(command) - command_length, "%d, ", index);
         }
 
         // Remove the trailing comma and space
         command_length -= 2;
         command[command_length] = '\n';
         command_length++;
-    } else if (stage->filter == NULL || strcmp(stage->filter, "all") == 0) {
+    } else if(stage->filter == NULL || strcmp(stage->filter, "all") == 0) {
         command_length = snprintf(command, sizeof(command), "select %s all\n", select_type);
     } else {
-        command_length = snprintf(command, sizeof(command), "select %s -f \"%s\"\n", select_type, stage->filter);
+        command_length = snprintf(
+            command, sizeof(command), "select %s -f \"%s\"\n", select_type, stage->filter);
     }
 
     wifi_marauder_uart_tx((uint8_t*)command, command_length);
 }
 
-void _wifi_marauder_script_execute_deauth(WifiMarauderScriptStageDeauth* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_deauth(
+    WifiMarauderScriptStageDeauth* stage,
+    WifiMarauderScriptWorker* worker) {
     const char attack_command[] = "attack -t deauth\n";
     wifi_marauder_uart_tx((uint8_t*)(attack_command), strlen(attack_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_probe(WifiMarauderScriptStageProbe* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_probe(
+    WifiMarauderScriptStageProbe* stage,
+    WifiMarauderScriptWorker* worker) {
     const char attack_command[] = "attack -t probe\n";
     wifi_marauder_uart_tx((uint8_t*)(attack_command), strlen(attack_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_raw(WifiMarauderScriptStageSniffRaw* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_raw(
+    WifiMarauderScriptStageSniffRaw* stage,
+    WifiMarauderScriptWorker* worker) {
     const char sniff_command[] = "sniffraw\n";
     wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_beacon(WifiMarauderScriptStageSniffBeacon* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_beacon(
+    WifiMarauderScriptStageSniffBeacon* stage,
+    WifiMarauderScriptWorker* worker) {
     const char sniff_command[] = "sniffbeacon\n";
     wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_deauth(WifiMarauderScriptStageSniffDeauth* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_deauth(
+    WifiMarauderScriptStageSniffDeauth* stage,
+    WifiMarauderScriptWorker* worker) {
     const char sniff_command[] = "sniffdeauth\n";
     wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_esp(WifiMarauderScriptStageSniffEsp* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_esp(
+    WifiMarauderScriptStageSniffEsp* stage,
+    WifiMarauderScriptWorker* worker) {
     const char sniff_command[] = "sniffesp\n";
     wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_pmkid(WifiMarauderScriptStageSniffPmkid* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_pmkid(
+    WifiMarauderScriptStageSniffPmkid* stage,
+    WifiMarauderScriptWorker* worker) {
     char attack_command[50] = "sniffpmkid";
     int len = strlen(attack_command);
-    
-    if (stage->channel > 0) {
-        len += snprintf(attack_command + len, sizeof(attack_command) - len, " -c %d", stage->channel);
+
+    if(stage->channel > 0) {
+        len +=
+            snprintf(attack_command + len, sizeof(attack_command) - len, " -c %d", stage->channel);
     }
 
-    if (stage->force_deauth) {
+    if(stage->force_deauth) {
         len += snprintf(attack_command + len, sizeof(attack_command) - len, " -d");
     }
 
@@ -140,29 +158,37 @@ void _wifi_marauder_script_execute_sniff_pmkid(WifiMarauderScriptStageSniffPmkid
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_sniff_pwn(WifiMarauderScriptStageSniffPwn* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_sniff_pwn(
+    WifiMarauderScriptStageSniffPwn* stage,
+    WifiMarauderScriptWorker* worker) {
     const char sniff_command[] = "sniffpwn\n";
     wifi_marauder_uart_tx((uint8_t*)sniff_command, strlen(sniff_command));
     _wifi_marauder_script_delay(worker, stage->timeout);
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_beacon_list(WifiMarauderScriptStageBeaconList* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_beacon_list(
+    WifiMarauderScriptStageBeaconList* stage,
+    WifiMarauderScriptWorker* worker) {
     const char clearlist_command[] = "clearlist -s\n";
     wifi_marauder_uart_tx((uint8_t*)(clearlist_command), strlen(clearlist_command));
 
     char command[100];
-    char *ssid;
+    char* ssid;
 
-    for (int i = 0; i < stage->ssid_count; i++) {
+    for(int i = 0; i < stage->ssid_count; i++) {
         ssid = stage->ssids[i];
         snprintf(command, sizeof(command), "ssid -a -n \"%s\"", ssid);
         wifi_marauder_uart_tx((uint8_t*)(command), strlen(command));
         _send_line_break();
     }
-    if (stage->random_ssids > 0) {
+    if(stage->random_ssids > 0) {
         char add_random_command[50];
-        snprintf(add_random_command, sizeof(add_random_command), "ssid -a -r -g %d\n", stage->random_ssids);
+        snprintf(
+            add_random_command,
+            sizeof(add_random_command),
+            "ssid -a -r -g %d\n",
+            stage->random_ssids);
         wifi_marauder_uart_tx((uint8_t*)add_random_command, strlen(add_random_command));
     }
     const char attack_command[] = "attack -t beacon -l\n";
@@ -171,7 +197,9 @@ void _wifi_marauder_script_execute_beacon_list(WifiMarauderScriptStageBeaconList
     _send_stop();
 }
 
-void _wifi_marauder_script_execute_beacon_ap(WifiMarauderScriptStageBeaconAp* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_beacon_ap(
+    WifiMarauderScriptStageBeaconAp* stage,
+    WifiMarauderScriptWorker* worker) {
     const char command[] = "attack -t beacon -a\n";
     wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
     _wifi_marauder_script_delay(worker, stage->timeout);
@@ -179,84 +207,101 @@ void _wifi_marauder_script_execute_beacon_ap(WifiMarauderScriptStageBeaconAp* st
 }
 
 void _wifi_marauder_script_execute_exec(WifiMarauderScriptStageExec* stage) {
-    if (stage->command != NULL) {
+    if(stage->command != NULL) {
         wifi_marauder_uart_tx((uint8_t*)stage->command, strlen(stage->command));
     }
 }
 
-void _wifi_marauder_script_execute_delay(WifiMarauderScriptStageDelay* stage, WifiMarauderScriptWorker* worker) {
+void _wifi_marauder_script_execute_delay(
+    WifiMarauderScriptStageDelay* stage,
+    WifiMarauderScriptWorker* worker) {
     _wifi_marauder_script_delay(worker, stage->timeout);
 }
 
-void wifi_marauder_script_execute_start(void *context) {
+void wifi_marauder_script_execute_start(void* context) {
     furi_assert(context);
     WifiMarauderScriptWorker* worker = context;
     WifiMarauderScript* script = worker->script;
     char command[100];
 
     // Enables or disables the LED according to script settings
-    if (script->enable_led != WifiMarauderScriptBooleanUndefined) {
-        snprintf(command, sizeof(command), "settings -s EnableLED %s", script->enable_led ? "enable" : "disable");
+    if(script->enable_led != WifiMarauderScriptBooleanUndefined) {
+        snprintf(
+            command,
+            sizeof(command),
+            "settings -s EnableLED %s",
+            script->enable_led ? "enable" : "disable");
         wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
         _send_line_break();
     }
 
     // Enables or disables PCAP saving according to script settings
-    if (script->save_pcap != WifiMarauderScriptBooleanUndefined) {
-        snprintf(command, sizeof(command), "settings -s SavePCAP %s", script->save_pcap ? "enable" : "disable");
+    if(script->save_pcap != WifiMarauderScriptBooleanUndefined) {
+        snprintf(
+            command,
+            sizeof(command),
+            "settings -s SavePCAP %s",
+            script->save_pcap ? "enable" : "disable");
         wifi_marauder_uart_tx((uint8_t*)command, strlen(command));
         _send_line_break();
     }
 }
 
-
-void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void *context) {
+void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context) {
     furi_assert(context);
     WifiMarauderScriptWorker* worker = context;
-    void *stage_data = stage->stage;
-
-    switch (stage->type) {
-        case WifiMarauderScriptStageTypeScan:
-            _wifi_marauder_script_execute_scan((WifiMarauderScriptStageScan*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSelect:
-            _wifi_marauder_script_execute_select((WifiMarauderScriptStageSelect*)stage_data);
-            break;
-        case WifiMarauderScriptStageTypeDeauth:
-            _wifi_marauder_script_execute_deauth((WifiMarauderScriptStageDeauth*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeProbe:
-            _wifi_marauder_script_execute_probe((WifiMarauderScriptStageProbe*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffRaw:
-            _wifi_marauder_script_execute_sniff_raw((WifiMarauderScriptStageSniffRaw*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffBeacon:
-            _wifi_marauder_script_execute_sniff_beacon((WifiMarauderScriptStageSniffBeacon*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffDeauth:
-            _wifi_marauder_script_execute_sniff_deauth((WifiMarauderScriptStageSniffDeauth*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffEsp:
-            _wifi_marauder_script_execute_sniff_esp((WifiMarauderScriptStageSniffEsp*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffPmkid:
-            _wifi_marauder_script_execute_sniff_pmkid((WifiMarauderScriptStageSniffPmkid*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeSniffPwn:
-            _wifi_marauder_script_execute_sniff_pwn((WifiMarauderScriptStageSniffPwn*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeBeaconList:
-            _wifi_marauder_script_execute_beacon_list((WifiMarauderScriptStageBeaconList*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeBeaconAp:
-            _wifi_marauder_script_execute_beacon_ap((WifiMarauderScriptStageBeaconAp*)stage_data, worker);
-            break;
-        case WifiMarauderScriptStageTypeExec:
-            _wifi_marauder_script_execute_exec((WifiMarauderScriptStageExec*)stage_data);
-            break;
-        case WifiMarauderScriptStageTypeDelay:
-            _wifi_marauder_script_execute_delay((WifiMarauderScriptStageDelay*)stage_data, worker);
-            break;
+    void* stage_data = stage->stage;
+
+    switch(stage->type) {
+    case WifiMarauderScriptStageTypeScan:
+        _wifi_marauder_script_execute_scan((WifiMarauderScriptStageScan*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSelect:
+        _wifi_marauder_script_execute_select((WifiMarauderScriptStageSelect*)stage_data);
+        break;
+    case WifiMarauderScriptStageTypeDeauth:
+        _wifi_marauder_script_execute_deauth((WifiMarauderScriptStageDeauth*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeProbe:
+        _wifi_marauder_script_execute_probe((WifiMarauderScriptStageProbe*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffRaw:
+        _wifi_marauder_script_execute_sniff_raw(
+            (WifiMarauderScriptStageSniffRaw*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffBeacon:
+        _wifi_marauder_script_execute_sniff_beacon(
+            (WifiMarauderScriptStageSniffBeacon*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffDeauth:
+        _wifi_marauder_script_execute_sniff_deauth(
+            (WifiMarauderScriptStageSniffDeauth*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffEsp:
+        _wifi_marauder_script_execute_sniff_esp(
+            (WifiMarauderScriptStageSniffEsp*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffPmkid:
+        _wifi_marauder_script_execute_sniff_pmkid(
+            (WifiMarauderScriptStageSniffPmkid*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeSniffPwn:
+        _wifi_marauder_script_execute_sniff_pwn(
+            (WifiMarauderScriptStageSniffPwn*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeBeaconList:
+        _wifi_marauder_script_execute_beacon_list(
+            (WifiMarauderScriptStageBeaconList*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeBeaconAp:
+        _wifi_marauder_script_execute_beacon_ap(
+            (WifiMarauderScriptStageBeaconAp*)stage_data, worker);
+        break;
+    case WifiMarauderScriptStageTypeExec:
+        _wifi_marauder_script_execute_exec((WifiMarauderScriptStageExec*)stage_data);
+        break;
+    case WifiMarauderScriptStageTypeDelay:
+        _wifi_marauder_script_execute_delay((WifiMarauderScriptStageDelay*)stage_data, worker);
+        break;
     }
 }

+ 2 - 2
script/wifi_marauder_script_executor.h

@@ -2,5 +2,5 @@
 
 #include "wifi_marauder_script.h"
 
-void wifi_marauder_script_execute_start(void *context);
-void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void *context);
+void wifi_marauder_script_execute_start(void* context);
+void wifi_marauder_script_execute_stage(WifiMarauderScriptStage* stage, void* context);

+ 18 - 15
script/wifi_marauder_script_worker.c

@@ -3,7 +3,7 @@
 
 WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc() {
     WifiMarauderScriptWorker* worker = malloc(sizeof(WifiMarauderScriptWorker));
-    if (worker == NULL) {
+    if(worker == NULL) {
         return NULL;
     }
     worker->callback_start = NULL;
@@ -15,25 +15,25 @@ WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc() {
 
 int32_t _wifi_marauder_script_worker_task(void* worker) {
     WifiMarauderScriptWorker* script_worker = worker;
-    WifiMarauderScript *script = script_worker->script;
-    if (script == NULL) {
+    WifiMarauderScript* script = script_worker->script;
+    if(script == NULL) {
         return WifiMarauderScriptWorkerStatusInvalidScript;
     }
 
     // Setup
     script_worker->callback_start(script_worker->context);
-    if (!script_worker->is_running) {
+    if(!script_worker->is_running) {
         return WifiMarauderScriptWorkerStatusForceExit;
     }
 
     // Stages
-    for (int i = 0; i < script->repeat; i++) {
-        WifiMarauderScriptStage *current_stage = script->first_stage;
-        while (current_stage != NULL && script_worker->is_running) {
+    for(int i = 0; i < script->repeat; i++) {
+        WifiMarauderScriptStage* current_stage = script->first_stage;
+        while(current_stage != NULL && script_worker->is_running) {
             script_worker->callback_stage(current_stage, script_worker->context);
             current_stage = current_stage->next_stage;
         }
-        if (!script_worker->is_running) {
+        if(!script_worker->is_running) {
             return WifiMarauderScriptWorkerStatusForceExit;
         }
     }
@@ -42,8 +42,10 @@ int32_t _wifi_marauder_script_worker_task(void* worker) {
     return WifiMarauderScriptWorkerStatusSuccess;
 }
 
-bool wifi_marauder_script_worker_start(WifiMarauderScriptWorker* instance, WifiMarauderScript* script) {
-    if (!instance || !script) {
+bool wifi_marauder_script_worker_start(
+    WifiMarauderScriptWorker* instance,
+    WifiMarauderScript* script) {
+    if(!instance || !script) {
         return false;
     }
     instance->callback_start = wifi_marauder_script_execute_start;
@@ -51,17 +53,18 @@ bool wifi_marauder_script_worker_start(WifiMarauderScriptWorker* instance, WifiM
     instance->script = script;
     instance->context = instance;
     instance->is_running = true;
-    instance->worker_thread = furi_thread_alloc_ex("WifiMarauderScriptWorker", 1024, _wifi_marauder_script_worker_task, instance);
-    if (!instance->worker_thread) {
+    instance->worker_thread = furi_thread_alloc_ex(
+        "WifiMarauderScriptWorker", 1024, _wifi_marauder_script_worker_task, instance);
+    if(!instance->worker_thread) {
         return false;
     }
     furi_thread_start(instance->worker_thread);
     return true;
 }
 
-void wifi_marauder_script_worker_free(WifiMarauderScriptWorker *worker) {
-    if (worker != NULL) {
-        if (worker->worker_thread != NULL) {
+void wifi_marauder_script_worker_free(WifiMarauderScriptWorker* worker) {
+    if(worker != NULL) {
+        if(worker->worker_thread != NULL) {
             worker->is_running = false;
             furi_thread_join(worker->worker_thread);
             furi_thread_free(worker->worker_thread);

+ 6 - 4
script/wifi_marauder_script_worker.h

@@ -9,11 +9,11 @@ typedef enum {
 } WifiMarauderScriptWorkerStatus;
 
 typedef struct WifiMarauderScriptWorker {
-    WifiMarauderScript *script;
-    FuriThread *worker_thread;
+    WifiMarauderScript* script;
+    FuriThread* worker_thread;
     void (*callback_start)(void*);
     void (*callback_stage)(WifiMarauderScriptStage*, void*);
-    void *context;
+    void* context;
     bool is_running;
 } WifiMarauderScriptWorker;
 
@@ -31,7 +31,9 @@ WifiMarauderScriptWorker* wifi_marauder_script_worker_alloc();
  * @param script Script to be executed
  * @return True if the worker was successfully started, false otherwise.
  */
-bool wifi_marauder_script_worker_start(WifiMarauderScriptWorker* instance, WifiMarauderScript* script);
+bool wifi_marauder_script_worker_start(
+    WifiMarauderScriptWorker* instance,
+    WifiMarauderScript* script);
 
 /**
  * @brief Frees the memory used by the instance of WifiMarauderScriptWorker.

+ 19 - 4
wifi_marauder_app.c

@@ -64,9 +64,11 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
     app->text_box_store = furi_string_alloc();
     furi_string_reserve(app->text_box_store, WIFI_MARAUDER_TEXT_BOX_STORE_SIZE);
 
-    app->text_input = text_input_alloc();
+    app->text_input = wifi_text_input_alloc();
     view_dispatcher_add_view(
-        app->view_dispatcher, WifiMarauderAppViewTextInput, text_input_get_view(app->text_input));
+        app->view_dispatcher,
+        WifiMarauderAppViewTextInput,
+        wifi_text_input_get_view(app->text_input));
 
     app->widget = widget_alloc();
     view_dispatcher_add_view(
@@ -81,7 +83,8 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
 
     // Submenu
     app->submenu = submenu_alloc();
-    view_dispatcher_add_view(app->view_dispatcher, WifiMarauderAppViewSubmenu, submenu_get_view(app->submenu));
+    view_dispatcher_add_view(
+        app->view_dispatcher, WifiMarauderAppViewSubmenu, submenu_get_view(app->submenu));
 
     scene_manager_next_scene(app->scene_manager, WifiMarauderSceneStart);
 
@@ -145,7 +148,7 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
     widget_free(app->widget);
     text_box_free(app->text_box);
     furi_string_free(app->text_box_store);
-    text_input_free(app->text_input);
+    wifi_text_input_free(app->text_input);
     submenu_free(app->submenu);
     variable_item_list_free(app->var_item_list);
     storage_file_free(app->capture_file);
@@ -170,6 +173,14 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
 
 int32_t wifi_marauder_app(void* p) {
     UNUSED(p);
+
+    uint8_t attempts = 0;
+    while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+        furi_hal_power_enable_otg();
+        furi_delay_ms(10);
+    }
+    furi_delay_ms(200);
+
     WifiMarauderApp* wifi_marauder_app = wifi_marauder_app_alloc();
 
     wifi_marauder_make_app_folder(wifi_marauder_app);
@@ -182,5 +193,9 @@ int32_t wifi_marauder_app(void* p) {
 
     wifi_marauder_app_free(wifi_marauder_app);
 
+    if(furi_hal_power_is_otg_enabled()) {
+        furi_hal_power_disable_otg();
+    }
+
     return 0;
 }

+ 1 - 1
wifi_marauder_app.h

@@ -4,7 +4,7 @@
 extern "C" {
 #endif
 
-#define WIFI_MARAUDER_APP_VERSION "v0.3.6"
+#define WIFI_MARAUDER_APP_VERSION "v0.4.0"
 
 typedef struct WifiMarauderApp WifiMarauderApp;
 

+ 3 - 3
wifi_marauder_app_i.h

@@ -16,10 +16,10 @@
 #include <gui/view_dispatcher.h>
 #include <gui/scene_manager.h>
 #include <gui/modules/text_box.h>
-#include <gui/modules/text_input.h>
 #include <gui/modules/submenu.h>
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/widget.h>
+#include "wifi_marauder_text_input.h"
 
 #include <ESP32_WiFi_Marauder_icons.h>
 #include <storage/storage.h>
@@ -32,7 +32,7 @@
 #define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512)
 
 #define MARAUDER_APP_FOLDER_USER "apps_data/marauder"
-#define MARAUDER_APP_FOLDER ANY_PATH(MARAUDER_APP_FOLDER_USER)
+#define MARAUDER_APP_FOLDER EXT_PATH(MARAUDER_APP_FOLDER_USER)
 #define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps"
 #define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs"
 #define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps"
@@ -57,7 +57,7 @@ struct WifiMarauderApp {
     FuriString* text_box_store;
     size_t text_box_store_strlen;
     TextBox* text_box;
-    TextInput* text_input;
+    WIFI_TextInput* text_input;
     Storage* storage;
     File* capture_file;
     File* log_file;

+ 750 - 0
wifi_marauder_text_input.c

@@ -0,0 +1,750 @@
+#include "wifi_marauder_text_input.h"
+#include <gui/elements.h>
+#include "ESP32_WiFi_Marauder_icons.h"
+#include "wifi_marauder_app_i.h"
+#include <furi.h>
+
+struct WIFI_TextInput {
+    View* view;
+    FuriTimer* timer;
+};
+
+typedef struct {
+    const char text;
+    const uint8_t x;
+    const uint8_t y;
+} WIFI_TextInputKey;
+
+typedef struct {
+    const WIFI_TextInputKey* rows[3];
+    const uint8_t keyboard_index;
+} Keyboard;
+
+typedef struct {
+    const char* header;
+    char* text_buffer;
+    size_t text_buffer_size;
+    size_t minimum_length;
+    bool clear_default_text;
+
+    bool cursor_select;
+    size_t cursor_pos;
+
+    WIFI_TextInputCallback callback;
+    void* callback_context;
+
+    uint8_t selected_row;
+    uint8_t selected_column;
+    uint8_t selected_keyboard;
+
+    WIFI_TextInputValidatorCallback validator_callback;
+    void* validator_callback_context;
+    FuriString* validator_text;
+    bool validator_message_visible;
+} WIFI_TextInputModel;
+
+static const uint8_t keyboard_origin_x = 1;
+static const uint8_t keyboard_origin_y = 29;
+static const uint8_t keyboard_row_count = 3;
+static const uint8_t keyboard_count = 2;
+
+#define ENTER_KEY '\r'
+#define BACKSPACE_KEY '\b'
+#define SWITCH_KEYBOARD_KEY 0xfe
+
+static const WIFI_TextInputKey keyboard_keys_row_1[] = {
+    {'q', 1, 8},
+    {'w', 10, 8},
+    {'e', 19, 8},
+    {'r', 28, 8},
+    {'t', 37, 8},
+    {'y', 46, 8},
+    {'u', 55, 8},
+    {'i', 64, 8},
+    {'o', 73, 8},
+    {'p', 82, 8},
+    {'0', 91, 8},
+    {'1', 100, 8},
+    {'2', 110, 8},
+    {'3', 120, 8},
+};
+
+static const WIFI_TextInputKey keyboard_keys_row_2[] = {
+    {'a', 1, 20},
+    {'s', 10, 20},
+    {'d', 19, 20},
+    {'f', 28, 20},
+    {'g', 37, 20},
+    {'h', 46, 20},
+    {'j', 55, 20},
+    {'k', 64, 20},
+    {'l', 73, 20},
+    {BACKSPACE_KEY, 82, 12},
+    {'4', 100, 20},
+    {'5', 110, 20},
+    {'6', 120, 20},
+};
+
+static const WIFI_TextInputKey keyboard_keys_row_3[] = {
+    {SWITCH_KEYBOARD_KEY, 1, 23},
+    {'z', 13, 32},
+    {'x', 21, 32},
+    {'c', 28, 32},
+    {'v', 36, 32},
+    {'b', 44, 32},
+    {'n', 52, 32},
+    {'m', 59, 32},
+    {'_', 67, 32},
+    {ENTER_KEY, 74, 23},
+    {'7', 100, 32},
+    {'8', 110, 32},
+    {'9', 120, 32},
+};
+
+static const WIFI_TextInputKey symbol_keyboard_keys_row_1[] = {
+    {'!', 2, 8},
+    {'@', 12, 8},
+    {'#', 22, 8},
+    {'$', 32, 8},
+    {'%', 42, 8},
+    {'^', 52, 8},
+    {'&', 62, 8},
+    {'(', 71, 8},
+    {')', 81, 8},
+    {'0', 91, 8},
+    {'1', 100, 8},
+    {'2', 110, 8},
+    {'3', 120, 8},
+};
+
+static const WIFI_TextInputKey symbol_keyboard_keys_row_2[] = {
+    {'~', 2, 20},
+    {'+', 12, 20},
+    {'-', 22, 20},
+    {'=', 32, 20},
+    {'[', 42, 20},
+    {']', 52, 20},
+    {'{', 62, 20},
+    {'}', 72, 20},
+    {BACKSPACE_KEY, 82, 12},
+    {'4', 100, 20},
+    {'5', 110, 20},
+    {'6', 120, 20},
+};
+
+static const WIFI_TextInputKey symbol_keyboard_keys_row_3[] = {
+    {SWITCH_KEYBOARD_KEY, 1, 23},
+    {'.', 15, 32},
+    {',', 29, 32},
+    {';', 41, 32},
+    {'`', 53, 32},
+    {'\'', 65, 32},
+    {ENTER_KEY, 74, 23},
+    {'7', 100, 32},
+    {'8', 110, 32},
+    {'9', 120, 32},
+};
+
+static const Keyboard keyboard = {
+    .rows =
+        {
+            keyboard_keys_row_1,
+            keyboard_keys_row_2,
+            keyboard_keys_row_3,
+        },
+    .keyboard_index = 0,
+};
+
+static const Keyboard symbol_keyboard = {
+    .rows =
+        {
+            symbol_keyboard_keys_row_1,
+            symbol_keyboard_keys_row_2,
+            symbol_keyboard_keys_row_3,
+        },
+    .keyboard_index = 1,
+};
+
+static const Keyboard* keyboards[] = {
+    &keyboard,
+    &symbol_keyboard,
+};
+
+static void switch_keyboard(WIFI_TextInputModel* model) {
+    model->selected_keyboard = (model->selected_keyboard + 1) % keyboard_count;
+}
+
+static uint8_t get_row_size(const Keyboard* keyboard, uint8_t row_index) {
+    uint8_t row_size = 0;
+    if(keyboard == &symbol_keyboard) {
+        switch(row_index + 1) {
+        case 1:
+            row_size = COUNT_OF(symbol_keyboard_keys_row_1);
+            break;
+        case 2:
+            row_size = COUNT_OF(symbol_keyboard_keys_row_2);
+            break;
+        case 3:
+            row_size = COUNT_OF(symbol_keyboard_keys_row_3);
+            break;
+        default:
+            furi_crash(NULL);
+        }
+    } else {
+        switch(row_index + 1) {
+        case 1:
+            row_size = COUNT_OF(keyboard_keys_row_1);
+            break;
+        case 2:
+            row_size = COUNT_OF(keyboard_keys_row_2);
+            break;
+        case 3:
+            row_size = COUNT_OF(keyboard_keys_row_3);
+            break;
+        default:
+            furi_crash(NULL);
+        }
+    }
+
+    return row_size;
+}
+
+static const WIFI_TextInputKey* get_row(const Keyboard* keyboard, uint8_t row_index) {
+    const WIFI_TextInputKey* row = NULL;
+    if(row_index < 3) {
+        row = keyboard->rows[row_index];
+    } else {
+        furi_crash(NULL);
+    }
+
+    return row;
+}
+
+static char get_selected_char(WIFI_TextInputModel* model) {
+    return get_row(
+               keyboards[model->selected_keyboard], model->selected_row)[model->selected_column]
+        .text;
+}
+
+static bool char_is_lowercase(char letter) {
+    return (letter >= 0x61 && letter <= 0x7A);
+}
+
+static char char_to_uppercase(const char letter) {
+    if(letter == '_') {
+        return 0x20;
+    } else if(char_is_lowercase(letter)) {
+        return (letter - 0x20);
+    } else {
+        return letter;
+    }
+}
+
+static void wifi_text_input_backspace_cb(WIFI_TextInputModel* model) {
+    if(model->clear_default_text) {
+        model->text_buffer[0] = 0;
+        model->cursor_pos = 0;
+    } else if(model->cursor_pos > 0) {
+        char* move = model->text_buffer + model->cursor_pos;
+        memmove(move - 1, move, strlen(move) + 1);
+        model->cursor_pos--;
+    }
+}
+
+static void wifi_text_input_view_draw_callback(Canvas* canvas, void* _model) {
+    WIFI_TextInputModel* model = _model;
+    uint8_t text_length = model->text_buffer ? strlen(model->text_buffer) : 0;
+    uint8_t needed_string_width = canvas_width(canvas) - 8;
+    uint8_t start_pos = 4;
+
+    model->cursor_pos = model->cursor_pos > text_length ? text_length : model->cursor_pos;
+    size_t cursor_pos = model->cursor_pos;
+
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+
+    canvas_draw_str(canvas, 2, 8, model->header);
+    elements_slightly_rounded_frame(canvas, 1, 12, 126, 15);
+
+    char buf[model->text_buffer_size + 1];
+    if(model->text_buffer) {
+        strlcpy(buf, model->text_buffer, sizeof(buf));
+    }
+    char* str = buf;
+
+    if(model->clear_default_text) {
+        elements_slightly_rounded_box(
+            canvas, start_pos - 1, 14, canvas_string_width(canvas, str) + 2, 10);
+        canvas_set_color(canvas, ColorWhite);
+    } else {
+        char* move = str + cursor_pos;
+        memmove(move + 1, move, strlen(move) + 1);
+        str[cursor_pos] = '|';
+    }
+
+    if(cursor_pos > 0 && canvas_string_width(canvas, str) > needed_string_width) {
+        canvas_draw_str(canvas, start_pos, 22, "...");
+        start_pos += 6;
+        needed_string_width -= 8;
+        for(uint32_t off = 0;
+            strlen(str) && canvas_string_width(canvas, str) > needed_string_width &&
+            off < cursor_pos;
+            off++) {
+            str++;
+        }
+    }
+
+    if(canvas_string_width(canvas, str) > needed_string_width) {
+        needed_string_width -= 4;
+        size_t len = strlen(str);
+        while(len && canvas_string_width(canvas, str) > needed_string_width) {
+            str[len--] = '\0';
+        }
+        //strcat(str, "..."); // TODO - find replacement
+    }
+
+    canvas_draw_str(canvas, start_pos, 22, str);
+
+    canvas_set_font(canvas, FontKeyboard);
+
+    for(uint8_t row = 0; row < keyboard_row_count; row++) {
+        const uint8_t column_count = get_row_size(keyboards[model->selected_keyboard], row);
+        const WIFI_TextInputKey* keys = get_row(keyboards[model->selected_keyboard], row);
+
+        for(size_t column = 0; column < column_count; column++) {
+            bool selected = !model->cursor_select && model->selected_row == row &&
+                            model->selected_column == column;
+            const Icon* icon = NULL;
+            if(keys[column].text == ENTER_KEY) {
+                icon = selected ? &I_KeySaveSelected_24x11 : &I_KeySave_24x11;
+            } else if(keys[column].text == SWITCH_KEYBOARD_KEY) {
+                icon = selected ? &I_KeyKeyboardSelected_10x11 : &I_KeyKeyboard_10x11;
+            } else if(keys[column].text == BACKSPACE_KEY) {
+                icon = selected ? &I_KeyBackspaceSelected_16x9 : &I_KeyBackspace_16x9;
+            }
+            canvas_set_color(canvas, ColorBlack);
+            if(icon != NULL) {
+                canvas_draw_icon(
+                    canvas,
+                    keyboard_origin_x + keys[column].x,
+                    keyboard_origin_y + keys[column].y,
+                    icon);
+            } else {
+                if(selected) {
+                    canvas_draw_box(
+                        canvas,
+                        keyboard_origin_x + keys[column].x - 1,
+                        keyboard_origin_y + keys[column].y - 8,
+                        7,
+                        10);
+                    canvas_set_color(canvas, ColorWhite);
+                }
+
+                if(model->clear_default_text || text_length == 0) {
+                    canvas_draw_glyph(
+                        canvas,
+                        keyboard_origin_x + keys[column].x,
+                        keyboard_origin_y + keys[column].y,
+                        char_to_uppercase(keys[column].text));
+                } else {
+                    canvas_draw_glyph(
+                        canvas,
+                        keyboard_origin_x + keys[column].x,
+                        keyboard_origin_y + keys[column].y,
+                        keys[column].text);
+                }
+            }
+        }
+    }
+    if(model->validator_message_visible) {
+        canvas_set_font(canvas, FontSecondary);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_box(canvas, 8, 10, 110, 48);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42);
+        canvas_draw_rframe(canvas, 8, 8, 112, 50, 3);
+        canvas_draw_rframe(canvas, 9, 9, 110, 48, 2);
+        elements_multiline_text(canvas, 62, 20, furi_string_get_cstr(model->validator_text));
+        canvas_set_font(canvas, FontKeyboard);
+    }
+}
+
+static void
+    wifi_text_input_handle_up(WIFI_TextInput* wifi_text_input, WIFI_TextInputModel* model) {
+    UNUSED(wifi_text_input);
+    if(model->selected_row > 0) {
+        model->selected_row--;
+        if(model->selected_row == 0 &&
+           model->selected_column >
+               get_row_size(keyboards[model->selected_keyboard], model->selected_row) - 6) {
+            model->selected_column = model->selected_column + 1;
+        }
+        if(model->selected_row == 1 &&
+           model->selected_keyboard == symbol_keyboard.keyboard_index) {
+            if(model->selected_column > 5)
+                model->selected_column += 2;
+            else if(model->selected_column > 1)
+                model->selected_column += 1;
+        }
+    } else {
+        model->cursor_select = true;
+        model->clear_default_text = false;
+    }
+}
+
+static void
+    wifi_text_input_handle_down(WIFI_TextInput* wifi_text_input, WIFI_TextInputModel* model) {
+    UNUSED(wifi_text_input);
+    if(model->cursor_select) {
+        model->cursor_select = false;
+    } else if(model->selected_row < keyboard_row_count - 1) {
+        model->selected_row++;
+        if(model->selected_row == 1 &&
+           model->selected_column >
+               get_row_size(keyboards[model->selected_keyboard], model->selected_row) - 4) {
+            model->selected_column = model->selected_column - 1;
+        }
+        if(model->selected_row == 2 &&
+           model->selected_keyboard == symbol_keyboard.keyboard_index) {
+            if(model->selected_column > 7)
+                model->selected_column -= 2;
+            else if(model->selected_column > 1)
+                model->selected_column -= 1;
+        }
+    }
+}
+
+static void
+    wifi_text_input_handle_left(WIFI_TextInput* wifi_text_input, WIFI_TextInputModel* model) {
+    UNUSED(wifi_text_input);
+    if(model->cursor_select) {
+        if(model->cursor_pos > 0) {
+            model->cursor_pos = CLAMP(model->cursor_pos - 1, strlen(model->text_buffer), 0u);
+        }
+    } else if(model->selected_column > 0) {
+        model->selected_column--;
+    } else {
+        model->selected_column =
+            get_row_size(keyboards[model->selected_keyboard], model->selected_row) - 1;
+    }
+}
+
+static void
+    wifi_text_input_handle_right(WIFI_TextInput* wifi_text_input, WIFI_TextInputModel* model) {
+    UNUSED(wifi_text_input);
+    if(model->cursor_select) {
+        model->cursor_pos = CLAMP(model->cursor_pos + 1, strlen(model->text_buffer), 0u);
+    } else if(
+        model->selected_column <
+        get_row_size(keyboards[model->selected_keyboard], model->selected_row) - 1) {
+        model->selected_column++;
+    } else {
+        model->selected_column = 0;
+    }
+}
+
+static void wifi_text_input_handle_ok(
+    WIFI_TextInput* wifi_text_input,
+    WIFI_TextInputModel* model,
+    InputType type) {
+    if(model->cursor_select) return;
+    bool shift = type == InputTypeLong;
+    bool repeat = type == InputTypeRepeat;
+    char selected = get_selected_char(model);
+    size_t text_length = strlen(model->text_buffer);
+
+    if(selected == ENTER_KEY) {
+        if(model->validator_callback &&
+           (!model->validator_callback(
+               model->text_buffer, model->validator_text, model->validator_callback_context))) {
+            model->validator_message_visible = true;
+            furi_timer_start(wifi_text_input->timer, furi_kernel_get_tick_frequency() * 4);
+        } else if(model->callback != 0 && text_length >= model->minimum_length) {
+            model->callback(model->callback_context);
+        }
+    } else if(selected == SWITCH_KEYBOARD_KEY) {
+        switch_keyboard(model);
+    } else {
+        if(selected == BACKSPACE_KEY) {
+            wifi_text_input_backspace_cb(model);
+        } else if(!repeat) {
+            if(model->clear_default_text) {
+                text_length = 0;
+            }
+            if(text_length < (model->text_buffer_size - 1)) {
+                if(shift != (text_length == 0)) {
+                    selected = char_to_uppercase(selected);
+                }
+                if(model->clear_default_text) {
+                    model->text_buffer[0] = selected;
+                    model->text_buffer[1] = '\0';
+                    model->cursor_pos = 1;
+                } else {
+                    char* move = model->text_buffer + model->cursor_pos;
+                    memmove(move + 1, move, strlen(move) + 1);
+                    model->text_buffer[model->cursor_pos] = selected;
+                    model->cursor_pos++;
+                }
+            }
+        }
+        model->clear_default_text = false;
+    }
+}
+
+static bool wifi_text_input_view_input_callback(InputEvent* event, void* context) {
+    WIFI_TextInput* wifi_text_input = context;
+    furi_assert(wifi_text_input);
+
+    bool consumed = false;
+
+    // Acquire model
+    WIFI_TextInputModel* model = view_get_model(wifi_text_input->view);
+
+    if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
+       model->validator_message_visible) {
+        model->validator_message_visible = false;
+        consumed = true;
+    } else if(event->type == InputTypeShort) {
+        consumed = true;
+        switch(event->key) {
+        case InputKeyUp:
+            wifi_text_input_handle_up(wifi_text_input, model);
+            break;
+        case InputKeyDown:
+            wifi_text_input_handle_down(wifi_text_input, model);
+            break;
+        case InputKeyLeft:
+            wifi_text_input_handle_left(wifi_text_input, model);
+            break;
+        case InputKeyRight:
+            wifi_text_input_handle_right(wifi_text_input, model);
+            break;
+        case InputKeyOk:
+            wifi_text_input_handle_ok(wifi_text_input, model, event->type);
+            break;
+        default:
+            consumed = false;
+            break;
+        }
+    } else if(event->type == InputTypeLong) {
+        consumed = true;
+        switch(event->key) {
+        case InputKeyUp:
+            wifi_text_input_handle_up(wifi_text_input, model);
+            break;
+        case InputKeyDown:
+            wifi_text_input_handle_down(wifi_text_input, model);
+            break;
+        case InputKeyLeft:
+            wifi_text_input_handle_left(wifi_text_input, model);
+            break;
+        case InputKeyRight:
+            wifi_text_input_handle_right(wifi_text_input, model);
+            break;
+        case InputKeyOk:
+            wifi_text_input_handle_ok(wifi_text_input, model, event->type);
+            break;
+        case InputKeyBack:
+            wifi_text_input_backspace_cb(model);
+            break;
+        default:
+            consumed = false;
+            break;
+        }
+    } else if(event->type == InputTypeRepeat) {
+        consumed = true;
+        switch(event->key) {
+        case InputKeyUp:
+            wifi_text_input_handle_up(wifi_text_input, model);
+            break;
+        case InputKeyDown:
+            wifi_text_input_handle_down(wifi_text_input, model);
+            break;
+        case InputKeyLeft:
+            wifi_text_input_handle_left(wifi_text_input, model);
+            break;
+        case InputKeyRight:
+            wifi_text_input_handle_right(wifi_text_input, model);
+            break;
+        case InputKeyOk:
+            wifi_text_input_handle_ok(wifi_text_input, model, event->type);
+            break;
+        case InputKeyBack:
+            wifi_text_input_backspace_cb(model);
+            break;
+        default:
+            consumed = false;
+            break;
+        }
+    }
+
+    // Commit model
+    view_commit_model(wifi_text_input->view, consumed);
+
+    return consumed;
+}
+
+void wifi_text_input_timer_callback(void* context) {
+    furi_assert(context);
+    WIFI_TextInput* wifi_text_input = context;
+
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        { model->validator_message_visible = false; },
+        true);
+}
+
+WIFI_TextInput* wifi_text_input_alloc() {
+    WIFI_TextInput* wifi_text_input = malloc(sizeof(WIFI_TextInput));
+    wifi_text_input->view = view_alloc();
+    view_set_context(wifi_text_input->view, wifi_text_input);
+    view_allocate_model(wifi_text_input->view, ViewModelTypeLocking, sizeof(WIFI_TextInputModel));
+    view_set_draw_callback(wifi_text_input->view, wifi_text_input_view_draw_callback);
+    view_set_input_callback(wifi_text_input->view, wifi_text_input_view_input_callback);
+
+    wifi_text_input->timer =
+        furi_timer_alloc(wifi_text_input_timer_callback, FuriTimerTypeOnce, wifi_text_input);
+
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        {
+            model->validator_text = furi_string_alloc();
+            model->minimum_length = 1;
+            model->cursor_pos = 0;
+            model->cursor_select = false;
+        },
+        false);
+
+    wifi_text_input_reset(wifi_text_input);
+
+    return wifi_text_input;
+}
+
+void wifi_text_input_free(WIFI_TextInput* wifi_text_input) {
+    furi_assert(wifi_text_input);
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        { furi_string_free(model->validator_text); },
+        false);
+
+    // Send stop command
+    furi_timer_stop(wifi_text_input->timer);
+    // Release allocated memory
+    furi_timer_free(wifi_text_input->timer);
+
+    view_free(wifi_text_input->view);
+
+    free(wifi_text_input);
+}
+
+void wifi_text_input_reset(WIFI_TextInput* wifi_text_input) {
+    furi_assert(wifi_text_input);
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        {
+            model->header = "";
+            model->selected_row = 0;
+            model->selected_column = 0;
+            model->selected_keyboard = 0;
+            model->minimum_length = 1;
+            model->clear_default_text = false;
+            model->cursor_pos = 0;
+            model->cursor_select = false;
+            model->text_buffer = NULL;
+            model->text_buffer_size = 0;
+            model->callback = NULL;
+            model->callback_context = NULL;
+            model->validator_callback = NULL;
+            model->validator_callback_context = NULL;
+            furi_string_reset(model->validator_text);
+            model->validator_message_visible = false;
+        },
+        true);
+}
+
+View* wifi_text_input_get_view(WIFI_TextInput* wifi_text_input) {
+    furi_assert(wifi_text_input);
+    return wifi_text_input->view;
+}
+
+void wifi_text_input_set_result_callback(
+    WIFI_TextInput* wifi_text_input,
+    WIFI_TextInputCallback callback,
+    void* callback_context,
+    char* text_buffer,
+    size_t text_buffer_size,
+    bool clear_default_text) {
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        {
+            model->callback = callback;
+            model->callback_context = callback_context;
+            model->text_buffer = text_buffer;
+            model->text_buffer_size = text_buffer_size;
+            model->clear_default_text = clear_default_text;
+            model->cursor_select = false;
+            if(text_buffer && text_buffer[0] != '\0') {
+                model->cursor_pos = strlen(text_buffer);
+                // Set focus on Save
+                model->selected_row = 2;
+                model->selected_column = 9;
+                model->selected_keyboard = 0;
+            } else {
+                model->cursor_pos = 0;
+            }
+        },
+        true);
+}
+
+void wifi_text_input_set_minimum_length(WIFI_TextInput* wifi_text_input, size_t minimum_length) {
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        { model->minimum_length = minimum_length; },
+        true);
+}
+
+void wifi_text_input_set_validator(
+    WIFI_TextInput* wifi_text_input,
+    WIFI_TextInputValidatorCallback callback,
+    void* callback_context) {
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        {
+            model->validator_callback = callback;
+            model->validator_callback_context = callback_context;
+        },
+        true);
+}
+
+WIFI_TextInputValidatorCallback
+    wifi_text_input_get_validator_callback(WIFI_TextInput* wifi_text_input) {
+    WIFI_TextInputValidatorCallback validator_callback = NULL;
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        { validator_callback = model->validator_callback; },
+        false);
+    return validator_callback;
+}
+
+void* wifi_text_input_get_validator_callback_context(WIFI_TextInput* wifi_text_input) {
+    void* validator_callback_context = NULL;
+    with_view_model(
+        wifi_text_input->view,
+        WIFI_TextInputModel * model,
+        { validator_callback_context = model->validator_callback_context; },
+        false);
+    return validator_callback_context;
+}
+
+void wifi_text_input_set_header_text(WIFI_TextInput* wifi_text_input, const char* text) {
+    with_view_model(
+        wifi_text_input->view, WIFI_TextInputModel * model, { model->header = text; }, true);
+}

+ 83 - 0
wifi_marauder_text_input.h

@@ -0,0 +1,83 @@
+#pragma once
+
+#include <gui/view.h>
+#include "wifi_marauder_validators.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Text input anonymous structure */
+typedef struct WIFI_TextInput WIFI_TextInput;
+typedef void (*WIFI_TextInputCallback)(void* context);
+typedef bool (*WIFI_TextInputValidatorCallback)(const char* text, FuriString* error, void* context);
+
+/** Allocate and initialize text input 
+ * 
+ * This text input is used to enter string
+ *
+ * @return     WIFI_TextInput instance
+ */
+WIFI_TextInput* wifi_text_input_alloc();
+
+/** Deinitialize and free text input
+ *
+ * @param      text_input  WIFI_TextInput instance
+ */
+void wifi_text_input_free(WIFI_TextInput* text_input);
+
+/** Clean text input view Note: this function does not free memory
+ *
+ * @param      text_input  Text input instance
+ */
+void wifi_text_input_reset(WIFI_TextInput* text_input);
+
+/** Get text input view
+ *
+ * @param      text_input  WIFI_TextInput instance
+ *
+ * @return     View instance that can be used for embedding
+ */
+View* wifi_text_input_get_view(WIFI_TextInput* text_input);
+
+/** Set text input result callback
+ *
+ * @param      text_input          WIFI_TextInput instance
+ * @param      callback            callback fn
+ * @param      callback_context    callback context
+ * @param      text_buffer         pointer to YOUR text buffer, that we going
+ *                                 to modify
+ * @param      text_buffer_size    YOUR text buffer size in bytes. Max string
+ *                                 length will be text_buffer_size-1.
+ * @param      clear_default_text  clear text from text_buffer on first OK
+ *                                 event
+ */
+void wifi_text_input_set_result_callback(
+    WIFI_TextInput* text_input,
+    WIFI_TextInputCallback callback,
+    void* callback_context,
+    char* text_buffer,
+    size_t text_buffer_size,
+    bool clear_default_text);
+
+void wifi_text_input_set_validator(
+    WIFI_TextInput* text_input,
+    WIFI_TextInputValidatorCallback callback,
+    void* callback_context);
+
+void wifi_text_input_set_minimum_length(WIFI_TextInput* text_input, size_t minimum_length);
+
+WIFI_TextInputValidatorCallback wifi_text_input_get_validator_callback(WIFI_TextInput* text_input);
+
+void* wifi_text_input_get_validator_callback_context(WIFI_TextInput* text_input);
+
+/** Set text input header text
+ *
+ * @param      text_input  WIFI_TextInput instance
+ * @param      text        text to be shown
+ */
+void wifi_text_input_set_header_text(WIFI_TextInput* text_input, const char* text);
+
+#ifdef __cplusplus
+}
+#endif

+ 57 - 0
wifi_marauder_validators.c

@@ -0,0 +1,57 @@
+#include <furi.h>
+#include "wifi_marauder_validators.h"
+#include <storage/storage.h>
+
+struct ValidatorIsFile {
+    char* app_path_folder;
+    const char* app_extension;
+    char* current_name;
+};
+
+bool validator_is_file_callback(const char* text, FuriString* error, void* context) {
+    furi_assert(context);
+    ValidatorIsFile* instance = context;
+
+    if(instance->current_name != NULL) {
+        if(strcmp(instance->current_name, text) == 0) {
+            return true;
+        }
+    }
+
+    bool ret = true;
+    FuriString* path = furi_string_alloc_printf(
+        "%s/%s%s", instance->app_path_folder, text, instance->app_extension);
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    if(storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK) {
+        ret = false;
+        furi_string_printf(error, "This name\nexists!\nChoose\nanother one.");
+    } else {
+        ret = true;
+    }
+    furi_string_free(path);
+    furi_record_close(RECORD_STORAGE);
+
+    return ret;
+}
+
+ValidatorIsFile* validator_is_file_alloc_init(
+    const char* app_path_folder,
+    const char* app_extension,
+    const char* current_name) {
+    ValidatorIsFile* instance = malloc(sizeof(ValidatorIsFile));
+
+    instance->app_path_folder = strdup(app_path_folder);
+    instance->app_extension = app_extension;
+    if(current_name != NULL) {
+        instance->current_name = strdup(current_name);
+    }
+
+    return instance;
+}
+
+void validator_is_file_free(ValidatorIsFile* instance) {
+    furi_assert(instance);
+    free(instance->app_path_folder);
+    free(instance->current_name);
+    free(instance);
+}

+ 21 - 0
wifi_marauder_validators.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <core/common_defines.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct ValidatorIsFile ValidatorIsFile;
+
+ValidatorIsFile* validator_is_file_alloc_init(
+    const char* app_path_folder,
+    const char* app_extension,
+    const char* current_name);
+
+void validator_is_file_free(ValidatorIsFile* instance);
+
+bool validator_is_file_callback(const char* text, FuriString* error, void* context);
+
+#ifdef __cplusplus
+}
+#endif

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