DerSkythe 2 лет назад
Родитель
Сommit
42bba47a60

+ 21 - 21
LICENSE

@@ -1,21 +1,21 @@
-MIT License
-
-Copyright (c) 2022 Der Skythe
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+MIT License
+
+Copyright (c) 2023 DerSkythe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 58 - 58
helpers/gui_top_buttons.c

@@ -1,59 +1,59 @@
-#include "gui_top_buttons.h"
-
-void elements_button_top_left(Canvas* canvas, const char* str) {
-    const Icon* icon = &I_ButtonUp_7x4;
-
-    const uint8_t button_height = 12;
-    const uint8_t vertical_offset = 3;
-    const uint8_t horizontal_offset = 3;
-    const uint8_t string_width = canvas_string_width(canvas, str);
-    const uint8_t icon_h_offset = 3;
-    const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
-    const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset;
-    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
-
-    const uint8_t x = 0;
-    const uint8_t y = 0 + button_height;
-
-    uint8_t line_x = x + button_width;
-    uint8_t line_y = y - button_height;
-    canvas_draw_box(canvas, x, line_y, button_width, button_height);
-    canvas_draw_line(canvas, line_x + 0, line_y, line_x + 0, y - 1);
-    canvas_draw_line(canvas, line_x + 1, line_y, line_x + 1, y - 2);
-    canvas_draw_line(canvas, line_x + 2, line_y, line_x + 2, y - 3);
-
-    canvas_invert_color(canvas);
-    canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, icon);
-    canvas_draw_str(
-        canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
-    canvas_invert_color(canvas);
-}
-
-void elements_button_top_right(Canvas* canvas, const char* str) {
-    const Icon* icon = &I_ButtonDown_7x4;
-
-    const uint8_t button_height = 12;
-    const uint8_t vertical_offset = 3;
-    const uint8_t horizontal_offset = 3;
-    const uint8_t string_width = canvas_string_width(canvas, str);
-    const uint8_t icon_h_offset = 3;
-    const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
-    const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset + 1;
-    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
-
-    const uint8_t x = canvas_width(canvas);
-    const uint8_t y = 0 + button_height;
-
-    uint8_t line_x = x - button_width;
-    uint8_t line_y = y - button_height;
-    canvas_draw_box(canvas, line_x, line_y, button_width, button_height);
-    canvas_draw_line(canvas, line_x - 1, line_y, line_x - 1, y - 1);
-    canvas_draw_line(canvas, line_x - 2, line_y, line_x - 2, y - 2);
-    canvas_draw_line(canvas, line_x - 3, line_y, line_x - 3, y - 3);
-
-    canvas_invert_color(canvas);
-    canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
-    canvas_draw_icon(
-        canvas, x - horizontal_offset - icon_get_width(icon), y - icon_v_offset, icon);
-    canvas_invert_color(canvas);
+#include "gui_top_buttons.h"
+
+void elements_button_top_left(Canvas* canvas, const char* str) {
+    const Icon* icon = &I_ButtonUp_7x4;
+
+    const uint8_t button_height = 12;
+    const uint8_t vertical_offset = 3;
+    const uint8_t horizontal_offset = 3;
+    const uint8_t string_width = canvas_string_width(canvas, str);
+    const uint8_t icon_h_offset = 3;
+    const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
+    const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset;
+    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+
+    const uint8_t x = 0;
+    const uint8_t y = 0 + button_height;
+
+    uint8_t line_x = x + button_width;
+    uint8_t line_y = y - button_height;
+    canvas_draw_box(canvas, x, line_y, button_width, button_height);
+    canvas_draw_line(canvas, line_x + 0, line_y, line_x + 0, y - 1);
+    canvas_draw_line(canvas, line_x + 1, line_y, line_x + 1, y - 2);
+    canvas_draw_line(canvas, line_x + 2, line_y, line_x + 2, y - 3);
+
+    canvas_invert_color(canvas);
+    canvas_draw_icon(canvas, x + horizontal_offset, y - icon_v_offset, icon);
+    canvas_draw_str(
+        canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
+    canvas_invert_color(canvas);
+}
+
+void elements_button_top_right(Canvas* canvas, const char* str) {
+    const Icon* icon = &I_ButtonDown_7x4;
+
+    const uint8_t button_height = 12;
+    const uint8_t vertical_offset = 3;
+    const uint8_t horizontal_offset = 3;
+    const uint8_t string_width = canvas_string_width(canvas, str);
+    const uint8_t icon_h_offset = 3;
+    const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset;
+    const uint8_t icon_v_offset = icon_get_height(icon) + vertical_offset + 1;
+    const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
+
+    const uint8_t x = canvas_width(canvas);
+    const uint8_t y = 0 + button_height;
+
+    uint8_t line_x = x - button_width;
+    uint8_t line_y = y - button_height;
+    canvas_draw_box(canvas, line_x, line_y, button_width, button_height);
+    canvas_draw_line(canvas, line_x - 1, line_y, line_x - 1, y - 1);
+    canvas_draw_line(canvas, line_x - 2, line_y, line_x - 2, y - 2);
+    canvas_draw_line(canvas, line_x - 3, line_y, line_x - 3, y - 3);
+
+    canvas_invert_color(canvas);
+    canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
+    canvas_draw_icon(
+        canvas, x - horizontal_offset - icon_get_width(icon), y - icon_v_offset, icon);
+    canvas_invert_color(canvas);
 }
 }

+ 20 - 20
helpers/gui_top_buttons.h

@@ -1,21 +1,21 @@
-#pragma once
-
-#include <subghz_bruteforcer_icons.h>
-#include <input/input.h>
-#include <gui/elements.h>
-#include <gui/icon.h>
-#include <gui/icon_animation.h>
-
-/**
- * Thanks to the author of metronome
- * @param canvas
- * @param str
- */
-void elements_button_top_left(Canvas* canvas, const char* str);
-
-/**
- * Thanks to the author of metronome
- * @param canvas
- * @param str
- */
+#pragma once
+
+#include <subghz_bruteforcer_icons.h>
+#include <input/input.h>
+#include <gui/elements.h>
+#include <gui/icon.h>
+#include <gui/icon_animation.h>
+
+/**
+ * Thanks to the author of metronome
+ * @param canvas
+ * @param str
+ */
+void elements_button_top_left(Canvas* canvas, const char* str);
+
+/**
+ * Thanks to the author of metronome
+ * @param canvas
+ * @param str
+ */
 void elements_button_top_right(Canvas* canvas, const char* str);
 void elements_button_top_right(Canvas* canvas, const char* str);

+ 49 - 49
helpers/subbrute_worker_private.h

@@ -1,50 +1,50 @@
-#pragma once
-
-#include "subbrute_worker.h"
-#include <lib/subghz/protocols/base.h>
-#include <lib/subghz/transmitter.h>
-#include <lib/subghz/receiver.h>
-#include <lib/subghz/environment.h>
-
-struct SubBruteWorker {
-    SubBruteWorkerState state;
-    volatile bool worker_running;
-    volatile bool initiated;
-    volatile bool transmit_mode;
-
-    // Current step
-    uint64_t step;
-
-    // SubGhz
-    FuriThread* thread;
-    SubGhzProtocolDecoderBase* decoder_result;
-    SubGhzEnvironment* environment;
-    SubGhzTransmitter* transmitter;
-    const char* protocol_name;
-    uint8_t tx_timeout_ms;
-    const SubGhzDevice* radio_device;
-
-    // Initiated values
-    SubBruteAttacks attack; // Attack state
-    uint32_t frequency;
-    FuriHalSubGhzPreset preset;
-    SubBruteFileProtocol file;
-    uint8_t bits;
-    uint32_t te;
-    uint8_t repeat;
-    uint8_t load_index; // Index of group to bruteforce in loaded file
-    uint64_t file_key;
-    uint64_t max_value; // Max step
-    bool two_bytes;
-
-    // Manual transmit
-    uint32_t last_time_tx_data;
-
-    // Callback for changed states
-    SubBruteWorkerCallback callback;
-    void* context;
-};
-
-int32_t subbrute_worker_thread(void* context);
-void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* flipper_format);
+#pragma once
+
+#include "subbrute_worker.h"
+#include <lib/subghz/protocols/base.h>
+#include <lib/subghz/transmitter.h>
+#include <lib/subghz/receiver.h>
+#include <lib/subghz/environment.h>
+
+struct SubBruteWorker {
+    SubBruteWorkerState state;
+    volatile bool worker_running;
+    volatile bool initiated;
+    volatile bool transmit_mode;
+
+    // Current step
+    uint64_t step;
+
+    // SubGhz
+    FuriThread* thread;
+    SubGhzProtocolDecoderBase* decoder_result;
+    SubGhzEnvironment* environment;
+    SubGhzTransmitter* transmitter;
+    const char* protocol_name;
+    uint8_t tx_timeout_ms;
+    const SubGhzDevice* radio_device;
+
+    // Initiated values
+    SubBruteAttacks attack; // Attack state
+    uint32_t frequency;
+    FuriHalSubGhzPreset preset;
+    SubBruteFileProtocol file;
+    uint8_t bits;
+    uint32_t te;
+    uint8_t repeat;
+    uint8_t load_index; // Index of group to bruteforce in loaded file
+    uint64_t file_key;
+    uint64_t max_value; // Max step
+    bool two_bytes;
+
+    // Manual transmit
+    uint32_t last_time_tx_data;
+
+    // Callback for changed states
+    SubBruteWorkerCallback callback;
+    void* context;
+};
+
+int32_t subbrute_worker_thread(void* context);
+void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* flipper_format);
 void subbrute_worker_send_callback(SubBruteWorker* instance);
 void subbrute_worker_send_callback(SubBruteWorker* instance);

+ 29 - 29
scenes/subbrute_scene.h

@@ -1,29 +1,29 @@
-#pragma once
-
-#include <gui/scene_manager.h>
-
-// Generate scene id and total number
-#define ADD_SCENE(prefix, name, id) SubBruteScene##id,
-typedef enum {
-#include "subbrute_scene_config.h"
-    SubBruteSceneNum,
-} SubBruteScene;
-#undef ADD_SCENE
-
-extern const SceneManagerHandlers subbrute_scene_handlers;
-
-// Generate scene on_enter handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
-#include "subbrute_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_event handlers declaration
-#define ADD_SCENE(prefix, name, id) \
-    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
-#include "subbrute_scene_config.h"
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers declaration
-#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
-#include "subbrute_scene_config.h"
-#undef ADD_SCENE
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) SubBruteScene##id,
+typedef enum {
+#include "subbrute_scene_config.h"
+    SubBruteSceneNum,
+} SubBruteScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers subbrute_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "subbrute_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_event handlers declaration
+#define ADD_SCENE(prefix, name, id) \
+    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
+#include "subbrute_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
+#include "subbrute_scene_config.h"
+#undef ADD_SCENE

+ 7 - 7
scenes/subbrute_scene_config.h

@@ -1,8 +1,8 @@
-ADD_SCENE(subbrute, load_file, LoadFile)
-ADD_SCENE(subbrute, load_select, LoadSelect)
-ADD_SCENE(subbrute, run_attack, RunAttack)
-ADD_SCENE(subbrute, save_name, SaveName)
-ADD_SCENE(subbrute, save_success, SaveSuccess)
-ADD_SCENE(subbrute, setup_attack, SetupAttack)
-ADD_SCENE(subbrute, setup_extra, SetupExtra)
+ADD_SCENE(subbrute, load_file, LoadFile)
+ADD_SCENE(subbrute, load_select, LoadSelect)
+ADD_SCENE(subbrute, run_attack, RunAttack)
+ADD_SCENE(subbrute, save_name, SaveName)
+ADD_SCENE(subbrute, save_success, SaveSuccess)
+ADD_SCENE(subbrute, setup_attack, SetupAttack)
+ADD_SCENE(subbrute, setup_extra, SetupExtra)
 ADD_SCENE(subbrute, start, Start)
 ADD_SCENE(subbrute, start, Start)

+ 90 - 90
scenes/subbrute_scene_load_file.c

@@ -1,91 +1,91 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-#define TAG "SubBruteSceneLoadFile"
-
-void subbrute_scene_load_file_on_enter(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = (SubBruteState*)context;
-
-    // Input events and views are managed by file_browser
-    FuriString* app_folder;
-    FuriString* load_path;
-    load_path = furi_string_alloc();
-    app_folder = furi_string_alloc_set(SUBBRUTE_PATH);
-
-    DialogsFileBrowserOptions browser_options;
-    dialog_file_browser_set_basic_options(&browser_options, SUBBRUTE_FILE_EXT, &I_sub1_10px);
-
-    SubBruteFileResult load_result = SubBruteFileResultUnknown;
-    // TODO: DELETE IT
-#ifdef SUBBRUTE_FAST_TRACK
-    bool res = true;
-    furi_string_printf(load_path, "%s", "/ext/subghz/princeton.sub");
-#else
-    bool res =
-        dialog_file_browser_show(instance->dialogs, load_path, app_folder, &browser_options);
-#endif
-#ifdef FURI_DEBUG
-    FURI_LOG_D(
-        TAG,
-        "load_path: %s, app_folder: %s",
-        furi_string_get_cstr(load_path),
-        furi_string_get_cstr(app_folder));
-#endif
-    if(res) {
-        load_result =
-            subbrute_device_load_from_file(instance->device, furi_string_get_cstr(load_path));
-        if(load_result == SubBruteFileResultOk) {
-            uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
-
-            load_result = subbrute_device_attack_set(
-                instance->device, SubBruteAttackLoadFile, extra_repeats);
-            if(load_result == SubBruteFileResultOk) {
-                if(!subbrute_worker_init_file_attack(
-                       instance->worker,
-                       instance->device->current_step,
-                       instance->device->bit_index,
-                       instance->device->key_from_file,
-                       instance->device->file_protocol_info,
-                       extra_repeats,
-                       instance->device->two_bytes)) {
-                    furi_crash("Invalid attack set!");
-                }
-                // Ready to run!
-                FURI_LOG_I(TAG, "Ready to run");
-                res = true;
-            }
-        }
-
-        if(load_result == SubBruteFileResultOk) {
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect);
-        } else {
-            FURI_LOG_E(TAG, "Returned error: %d", load_result);
-
-            FuriString* dialog_msg;
-            dialog_msg = furi_string_alloc();
-            furi_string_cat_printf(
-                dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result));
-            dialog_message_show_storage_error(instance->dialogs, furi_string_get_cstr(dialog_msg));
-            furi_string_free(dialog_msg);
-            scene_manager_search_and_switch_to_previous_scene(
-                instance->scene_manager, SubBruteSceneStart);
-        }
-    } else {
-        scene_manager_search_and_switch_to_previous_scene(
-            instance->scene_manager, SubBruteSceneStart);
-    }
-
-    furi_string_free(app_folder);
-    furi_string_free(load_path);
-}
-
-void subbrute_scene_load_file_on_exit(void* context) {
-    UNUSED(context);
-}
-
-bool subbrute_scene_load_file_on_event(void* context, SceneManagerEvent event) {
-    UNUSED(context);
-    UNUSED(event);
-    return false;
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+#define TAG "SubBruteSceneLoadFile"
+
+void subbrute_scene_load_file_on_enter(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = (SubBruteState*)context;
+
+    // Input events and views are managed by file_browser
+    FuriString* app_folder;
+    FuriString* load_path;
+    load_path = furi_string_alloc();
+    app_folder = furi_string_alloc_set(SUBBRUTE_PATH);
+
+    DialogsFileBrowserOptions browser_options;
+    dialog_file_browser_set_basic_options(&browser_options, SUBBRUTE_FILE_EXT, &I_sub1_10px);
+
+    SubBruteFileResult load_result = SubBruteFileResultUnknown;
+    // TODO: DELETE IT
+#ifdef SUBBRUTE_FAST_TRACK
+    bool res = true;
+    furi_string_printf(load_path, "%s", "/ext/subghz/princeton.sub");
+#else
+    bool res =
+        dialog_file_browser_show(instance->dialogs, load_path, app_folder, &browser_options);
+#endif
+#ifdef FURI_DEBUG
+    FURI_LOG_D(
+        TAG,
+        "load_path: %s, app_folder: %s",
+        furi_string_get_cstr(load_path),
+        furi_string_get_cstr(app_folder));
+#endif
+    if(res) {
+        load_result =
+            subbrute_device_load_from_file(instance->device, furi_string_get_cstr(load_path));
+        if(load_result == SubBruteFileResultOk) {
+            uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
+
+            load_result = subbrute_device_attack_set(
+                instance->device, SubBruteAttackLoadFile, extra_repeats);
+            if(load_result == SubBruteFileResultOk) {
+                if(!subbrute_worker_init_file_attack(
+                       instance->worker,
+                       instance->device->current_step,
+                       instance->device->bit_index,
+                       instance->device->key_from_file,
+                       instance->device->file_protocol_info,
+                       extra_repeats,
+                       instance->device->two_bytes)) {
+                    furi_crash("Invalid attack set!");
+                }
+                // Ready to run!
+                FURI_LOG_I(TAG, "Ready to run");
+                res = true;
+            }
+        }
+
+        if(load_result == SubBruteFileResultOk) {
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect);
+        } else {
+            FURI_LOG_E(TAG, "Returned error: %d", load_result);
+
+            FuriString* dialog_msg;
+            dialog_msg = furi_string_alloc();
+            furi_string_cat_printf(
+                dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result));
+            dialog_message_show_storage_error(instance->dialogs, furi_string_get_cstr(dialog_msg));
+            furi_string_free(dialog_msg);
+            scene_manager_search_and_switch_to_previous_scene(
+                instance->scene_manager, SubBruteSceneStart);
+        }
+    } else {
+        scene_manager_search_and_switch_to_previous_scene(
+            instance->scene_manager, SubBruteSceneStart);
+    }
+
+    furi_string_free(app_folder);
+    furi_string_free(load_path);
+}
+
+void subbrute_scene_load_file_on_exit(void* context) {
+    UNUSED(context);
+}
+
+bool subbrute_scene_load_file_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
 }
 }

+ 81 - 81
scenes/subbrute_scene_load_select.c

@@ -1,82 +1,82 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-#define TAG "SubBruteSceneStart"
-
-void subbrute_scene_load_select_callback(SubBruteCustomEvent event, void* context) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
-}
-
-void subbrute_scene_load_select_on_enter(void* context) {
-    furi_assert(context);
-#ifdef FURI_DEBUG
-    FURI_LOG_I(TAG, "subbrute_scene_load_select_on_enter");
-#endif
-    SubBruteState* instance = (SubBruteState*)context;
-    SubBruteMainView* view = instance->view_main;
-
-    instance->current_view = SubBruteViewMain;
-    subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
-    subbrute_main_view_set_index(
-        view, 7, true, instance->device->two_bytes, instance->device->key_from_file);
-
-    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
-}
-
-void subbrute_scene_load_select_on_exit(void* context) {
-    UNUSED(context);
-#ifdef FURI_DEBUG
-    FURI_LOG_I(TAG, "subbrute_scene_load_select_on_exit");
-#endif
-}
-
-bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event) {
-    SubBruteState* instance = (SubBruteState*)context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubBruteCustomEventTypeIndexSelected) {
-            /*#ifdef FURI_DEBUG && !SUBBRUTE_FAST_TRACK
-            view_dispatcher_stop(instance->view_dispatcher);
-            consumed = true;
-#else*/
-            instance->device->current_step = 0;
-            instance->device->bit_index = subbrute_main_view_get_index(instance->view_main);
-            instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main);
-            uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
-            instance->device->max_value = subbrute_protocol_calc_max_value(
-                instance->device->attack,
-                instance->device->bit_index,
-                instance->device->two_bytes);
-
-            if(!subbrute_worker_init_file_attack(
-                   instance->worker,
-                   instance->device->current_step,
-                   instance->device->bit_index,
-                   instance->device->key_from_file,
-                   instance->device->file_protocol_info,
-                   extra_repeats,
-                   instance->device->two_bytes)) {
-                furi_crash("Invalid attack set!");
-            }
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
-            /*#endif*/
-            consumed = true;
-        } /* else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
-            instance->device->two_bytes = true;
-        } else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
-            instance->device->two_bytes = false;
-        }*/
-    } else if(event.type == SceneManagerEventTypeBack) {
-        if(!scene_manager_search_and_switch_to_previous_scene(
-               instance->scene_manager, SubBruteSceneStart)) {
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
-        }
-        consumed = true;
-    }
-
-    return consumed;
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+#define TAG "SubBruteSceneStart"
+
+void subbrute_scene_load_select_callback(SubBruteCustomEvent event, void* context) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
+}
+
+void subbrute_scene_load_select_on_enter(void* context) {
+    furi_assert(context);
+#ifdef FURI_DEBUG
+    FURI_LOG_I(TAG, "subbrute_scene_load_select_on_enter");
+#endif
+    SubBruteState* instance = (SubBruteState*)context;
+    SubBruteMainView* view = instance->view_main;
+
+    instance->current_view = SubBruteViewMain;
+    subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance);
+    subbrute_main_view_set_index(
+        view, 7, true, instance->device->two_bytes, instance->device->key_from_file);
+
+    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
+}
+
+void subbrute_scene_load_select_on_exit(void* context) {
+    UNUSED(context);
+#ifdef FURI_DEBUG
+    FURI_LOG_I(TAG, "subbrute_scene_load_select_on_exit");
+#endif
+}
+
+bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event) {
+    SubBruteState* instance = (SubBruteState*)context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubBruteCustomEventTypeIndexSelected) {
+            /*#ifdef FURI_DEBUG && !SUBBRUTE_FAST_TRACK
+            view_dispatcher_stop(instance->view_dispatcher);
+            consumed = true;
+#else*/
+            instance->device->current_step = 0;
+            instance->device->bit_index = subbrute_main_view_get_index(instance->view_main);
+            instance->device->two_bytes = subbrute_main_view_get_two_bytes(instance->view_main);
+            uint8_t extra_repeats = subbrute_main_view_get_extra_repeats(instance->view_main);
+            instance->device->max_value = subbrute_protocol_calc_max_value(
+                instance->device->attack,
+                instance->device->bit_index,
+                instance->device->two_bytes);
+
+            if(!subbrute_worker_init_file_attack(
+                   instance->worker,
+                   instance->device->current_step,
+                   instance->device->bit_index,
+                   instance->device->key_from_file,
+                   instance->device->file_protocol_info,
+                   extra_repeats,
+                   instance->device->two_bytes)) {
+                furi_crash("Invalid attack set!");
+            }
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
+            /*#endif*/
+            consumed = true;
+        } /* else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
+            instance->device->two_bytes = true;
+        } else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
+            instance->device->two_bytes = false;
+        }*/
+    } else if(event.type == SceneManagerEventTypeBack) {
+        if(!scene_manager_search_and_switch_to_previous_scene(
+               instance->scene_manager, SubBruteSceneStart)) {
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
+        }
+        consumed = true;
+    }
+
+    return consumed;
 }
 }

+ 104 - 104
scenes/subbrute_scene_run_attack.c

@@ -1,104 +1,104 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-#define TAG "SubBruteSceneRunAttack"
-
-static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
-}
-
-static void
-    subbrute_scene_run_attack_device_state_changed(void* context, SubBruteWorkerState state) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-
-    if(state == SubBruteWorkerStateIDLE) {
-        // Can't be IDLE on this step!
-        view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError);
-    } else if(state == SubBruteWorkerStateFinished) {
-        view_dispatcher_send_custom_event(
-            instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished);
-    }
-}
-void subbrute_scene_run_attack_on_exit(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = (SubBruteState*)context;
-
-    notification_message(instance->notifications, &sequence_blink_stop);
-    subbrute_worker_stop(instance->worker);
-}
-
-void subbrute_scene_run_attack_on_enter(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = (SubBruteState*)context;
-    SubBruteAttackView* view = instance->view_attack;
-
-    instance->current_view = SubBruteViewAttack;
-    subbrute_attack_view_set_callback(view, subbrute_scene_run_attack_callback, instance);
-    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
-
-    subbrute_worker_set_callback(
-        instance->worker, subbrute_scene_run_attack_device_state_changed, instance);
-
-    if(!subbrute_worker_is_running(instance->worker)) {
-        subbrute_worker_set_step(instance->worker, instance->device->current_step);
-        if(!subbrute_worker_start(instance->worker)) {
-            view_dispatcher_send_custom_event(
-                instance->view_dispatcher, SubBruteCustomEventTypeError);
-        } else {
-            notification_message(instance->notifications, &sequence_single_vibro);
-            notification_message(instance->notifications, &sequence_blink_start_yellow);
-        }
-    }
-}
-
-bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) {
-    SubBruteState* instance = (SubBruteState*)context;
-    SubBruteAttackView* view = instance->view_attack;
-
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        uint64_t step = subbrute_worker_get_step(instance->worker);
-        instance->device->current_step = step;
-        subbrute_attack_view_set_current_step(view, step);
-
-        if(event.event == SubBruteCustomEventTypeTransmitFinished) {
-            notification_message(instance->notifications, &sequence_display_backlight_on);
-            notification_message(instance->notifications, &sequence_double_vibro);
-
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
-        } else if(
-            event.event == SubBruteCustomEventTypeTransmitNotStarted ||
-            event.event == SubBruteCustomEventTypeBackPressed) {
-            if(subbrute_worker_is_running(instance->worker)) {
-                // Notify
-                notification_message(instance->notifications, &sequence_single_vibro);
-            }
-            // Stop transmit
-            scene_manager_search_and_switch_to_previous_scene(
-                instance->scene_manager, SubBruteSceneSetupAttack);
-        } else if(event.event == SubBruteCustomEventTypeError) {
-            notification_message(instance->notifications, &sequence_error);
-
-            // Stop transmit
-            scene_manager_search_and_switch_to_previous_scene(
-                instance->scene_manager, SubBruteSceneSetupAttack);
-        } else if(event.event == SubBruteCustomEventTypeUpdateView) {
-            //subbrute_attack_view_set_current_step(view, instance->device->current_step);
-        }
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
-        uint64_t step = subbrute_worker_get_step(instance->worker);
-        instance->device->current_step = step;
-        subbrute_attack_view_set_current_step(view, step);
-
-        consumed = true;
-    }
-
-    return consumed;
-}
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+#define TAG "SubBruteSceneRunAttack"
+
+static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
+}
+
+static void
+    subbrute_scene_run_attack_device_state_changed(void* context, SubBruteWorkerState state) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+
+    if(state == SubBruteWorkerStateIDLE) {
+        // Can't be IDLE on this step!
+        view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError);
+    } else if(state == SubBruteWorkerStateFinished) {
+        view_dispatcher_send_custom_event(
+            instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished);
+    }
+}
+void subbrute_scene_run_attack_on_exit(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = (SubBruteState*)context;
+
+    notification_message(instance->notifications, &sequence_blink_stop);
+    subbrute_worker_stop(instance->worker);
+}
+
+void subbrute_scene_run_attack_on_enter(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = (SubBruteState*)context;
+    SubBruteAttackView* view = instance->view_attack;
+
+    instance->current_view = SubBruteViewAttack;
+    subbrute_attack_view_set_callback(view, subbrute_scene_run_attack_callback, instance);
+    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
+
+    subbrute_worker_set_callback(
+        instance->worker, subbrute_scene_run_attack_device_state_changed, instance);
+
+    if(!subbrute_worker_is_running(instance->worker)) {
+        subbrute_worker_set_step(instance->worker, instance->device->current_step);
+        if(!subbrute_worker_start(instance->worker)) {
+            view_dispatcher_send_custom_event(
+                instance->view_dispatcher, SubBruteCustomEventTypeError);
+        } else {
+            notification_message(instance->notifications, &sequence_single_vibro);
+            notification_message(instance->notifications, &sequence_blink_start_yellow);
+        }
+    }
+}
+
+bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) {
+    SubBruteState* instance = (SubBruteState*)context;
+    SubBruteAttackView* view = instance->view_attack;
+
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        uint64_t step = subbrute_worker_get_step(instance->worker);
+        instance->device->current_step = step;
+        subbrute_attack_view_set_current_step(view, step);
+
+        if(event.event == SubBruteCustomEventTypeTransmitFinished) {
+            notification_message(instance->notifications, &sequence_display_backlight_on);
+            notification_message(instance->notifications, &sequence_double_vibro);
+
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack);
+        } else if(
+            event.event == SubBruteCustomEventTypeTransmitNotStarted ||
+            event.event == SubBruteCustomEventTypeBackPressed) {
+            if(subbrute_worker_is_running(instance->worker)) {
+                // Notify
+                notification_message(instance->notifications, &sequence_single_vibro);
+            }
+            // Stop transmit
+            scene_manager_search_and_switch_to_previous_scene(
+                instance->scene_manager, SubBruteSceneSetupAttack);
+        } else if(event.event == SubBruteCustomEventTypeError) {
+            notification_message(instance->notifications, &sequence_error);
+
+            // Stop transmit
+            scene_manager_search_and_switch_to_previous_scene(
+                instance->scene_manager, SubBruteSceneSetupAttack);
+        } else if(event.event == SubBruteCustomEventTypeUpdateView) {
+            //subbrute_attack_view_set_current_step(view, instance->device->current_step);
+        }
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeTick) {
+        uint64_t step = subbrute_worker_get_step(instance->worker);
+        instance->device->current_step = step;
+        subbrute_attack_view_set_current_step(view, step);
+
+        consumed = true;
+    }
+
+    return consumed;
+}

+ 84 - 84
scenes/subbrute_scene_save_name.c

@@ -1,84 +1,84 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-#include <lib/toolbox/random_name.h>
-
-#define TAG "SubBruteSceneSaveFile"
-
-void subbrute_scene_save_name_on_enter(void* context) {
-    SubBruteState* instance = (SubBruteState*)context;
-
-    // Setup view
-    TextInput* text_input = instance->text_input;
-    set_random_name(instance->text_store, sizeof(instance->text_store));
-
-    text_input_set_header_text(text_input, "Name of file");
-    text_input_set_result_callback(
-        text_input,
-        subbrute_text_input_callback,
-        instance,
-        instance->text_store,
-        SUBBRUTE_MAX_LEN_NAME,
-        true);
-
-    furi_string_reset(instance->file_path);
-    furi_string_set_str(instance->file_path, SUBBRUTE_PATH);
-
-    ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
-        furi_string_get_cstr(instance->file_path), SUBBRUTE_FILE_EXT, "");
-    text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
-
-    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewTextInput);
-}
-
-bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) {
-    SubBruteState* instance = (SubBruteState*)context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeBack) {
-        scene_manager_previous_scene(instance->scene_manager);
-        return true;
-    } else if(
-        event.type == SceneManagerEventTypeCustom &&
-        event.event == SubBruteCustomEventTypeTextEditDone) {
-#ifdef FURI_DEBUG
-        FURI_LOG_D(TAG, "Saving: %s", instance->text_store);
-#endif
-        bool success = false;
-        if(strcmp(instance->text_store, "")) {
-            furi_string_reset(instance->file_path);
-            furi_string_cat_printf(
-                instance->file_path,
-                "%s/%s%s",
-                SUBBRUTE_PATH,
-                instance->text_store,
-                SUBBRUTE_FILE_EXT);
-
-            if(subbrute_device_save_file(
-                   instance->device, furi_string_get_cstr(instance->file_path))) {
-                scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveSuccess);
-                success = true;
-                consumed = true;
-            }
-        }
-
-        if(!success) {
-            dialog_message_show_storage_error(instance->dialogs, "Error during saving!");
-            consumed = scene_manager_search_and_switch_to_previous_scene(
-                instance->scene_manager, SubBruteSceneSetupAttack);
-        }
-    }
-    return consumed;
-}
-
-void subbrute_scene_save_name_on_exit(void* context) {
-    SubBruteState* instance = (SubBruteState*)context;
-
-    // Clear view
-    void* validator_context = text_input_get_validator_callback_context(instance->text_input);
-    text_input_set_validator(instance->text_input, NULL, NULL);
-    validator_is_file_free(validator_context);
-
-    text_input_reset(instance->text_input);
-
-    furi_string_reset(instance->file_path);
-}
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+#include <lib/toolbox/random_name.h>
+
+#define TAG "SubBruteSceneSaveFile"
+
+void subbrute_scene_save_name_on_enter(void* context) {
+    SubBruteState* instance = (SubBruteState*)context;
+
+    // Setup view
+    TextInput* text_input = instance->text_input;
+    set_random_name(instance->text_store, sizeof(instance->text_store));
+
+    text_input_set_header_text(text_input, "Name of file");
+    text_input_set_result_callback(
+        text_input,
+        subbrute_text_input_callback,
+        instance,
+        instance->text_store,
+        SUBBRUTE_MAX_LEN_NAME,
+        true);
+
+    furi_string_reset(instance->file_path);
+    furi_string_set_str(instance->file_path, SUBBRUTE_PATH);
+
+    ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
+        furi_string_get_cstr(instance->file_path), SUBBRUTE_FILE_EXT, "");
+    text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
+
+    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewTextInput);
+}
+
+bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) {
+    SubBruteState* instance = (SubBruteState*)context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeBack) {
+        scene_manager_previous_scene(instance->scene_manager);
+        return true;
+    } else if(
+        event.type == SceneManagerEventTypeCustom &&
+        event.event == SubBruteCustomEventTypeTextEditDone) {
+#ifdef FURI_DEBUG
+        FURI_LOG_D(TAG, "Saving: %s", instance->text_store);
+#endif
+        bool success = false;
+        if(strcmp(instance->text_store, "")) {
+            furi_string_reset(instance->file_path);
+            furi_string_cat_printf(
+                instance->file_path,
+                "%s/%s%s",
+                SUBBRUTE_PATH,
+                instance->text_store,
+                SUBBRUTE_FILE_EXT);
+
+            if(subbrute_device_save_file(
+                   instance->device, furi_string_get_cstr(instance->file_path))) {
+                scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveSuccess);
+                success = true;
+                consumed = true;
+            }
+        }
+
+        if(!success) {
+            dialog_message_show_storage_error(instance->dialogs, "Error during saving!");
+            consumed = scene_manager_search_and_switch_to_previous_scene(
+                instance->scene_manager, SubBruteSceneSetupAttack);
+        }
+    }
+    return consumed;
+}
+
+void subbrute_scene_save_name_on_exit(void* context) {
+    SubBruteState* instance = (SubBruteState*)context;
+
+    // Clear view
+    void* validator_context = text_input_get_validator_callback_context(instance->text_input);
+    text_input_set_validator(instance->text_input, NULL, NULL);
+    validator_is_file_free(validator_context);
+
+    text_input_reset(instance->text_input);
+
+    furi_string_reset(instance->file_path);
+}

+ 51 - 51
scenes/subbrute_scene_save_success.c

@@ -1,51 +1,51 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-void subbrute_scene_save_success_on_enter(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = context;
-
-    // Setup view
-    Popup* popup = instance->popup;
-    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
-    popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
-    popup_set_timeout(popup, 1500);
-    popup_set_context(popup, instance);
-    popup_set_callback(popup, subbrute_popup_closed_callback);
-    popup_enable_timeout(popup);
-    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewPopup);
-}
-
-bool subbrute_scene_save_success_on_event(void* context, SceneManagerEvent event) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-    //SubBruteMainView* view = instance->view_main;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubBruteCustomEventTypePopupClosed) {
-            if(!scene_manager_search_and_switch_to_previous_scene(
-                   instance->scene_manager, SubBruteSceneSetupAttack)) {
-                scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-void subbrute_scene_save_success_on_exit(void* context) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-
-    // Clear view
-    Popup* popup = instance->popup;
-    popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
-    popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, NULL);
-    popup_set_callback(popup, NULL);
-    popup_set_context(popup, NULL);
-    popup_set_timeout(popup, 0);
-    popup_disable_timeout(popup);
-}
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+void subbrute_scene_save_success_on_enter(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = context;
+
+    // Setup view
+    Popup* popup = instance->popup;
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
+    popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
+    popup_set_timeout(popup, 1500);
+    popup_set_context(popup, instance);
+    popup_set_callback(popup, subbrute_popup_closed_callback);
+    popup_enable_timeout(popup);
+    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewPopup);
+}
+
+bool subbrute_scene_save_success_on_event(void* context, SceneManagerEvent event) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+    //SubBruteMainView* view = instance->view_main;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubBruteCustomEventTypePopupClosed) {
+            if(!scene_manager_search_and_switch_to_previous_scene(
+                   instance->scene_manager, SubBruteSceneSetupAttack)) {
+                scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+void subbrute_scene_save_success_on_exit(void* context) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+
+    // Clear view
+    Popup* popup = instance->popup;
+    popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+    popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+    popup_set_icon(popup, 0, 0, NULL);
+    popup_set_callback(popup, NULL);
+    popup_set_context(popup, NULL);
+    popup_set_timeout(popup, 0);
+    popup_disable_timeout(popup);
+}

+ 140 - 140
scenes/subbrute_scene_setup_attack.c

@@ -1,140 +1,140 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-#define TAG "SubBruteSceneSetupAttack"
-
-static void subbrute_scene_setup_attack_callback(SubBruteCustomEvent event, void* context) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
-}
-
-static void
-    subbrute_scene_setup_attack_device_state_changed(void* context, SubBruteWorkerState state) {
-    furi_assert(context);
-
-    SubBruteState* instance = (SubBruteState*)context;
-
-    if(state == SubBruteWorkerStateIDLE) {
-        // Can't be IDLE on this step!
-        view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError);
-    }
-}
-
-void subbrute_scene_setup_attack_on_enter(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = (SubBruteState*)context;
-    SubBruteAttackView* view = instance->view_attack;
-
-    notification_message(instance->notifications, &sequence_reset_vibro);
-
-#ifdef FURI_DEBUG
-    FURI_LOG_D(TAG, "Enter Attack: %s", subbrute_protocol_name(instance->device->attack));
-#endif
-
-    subbrute_worker_set_callback(
-        instance->worker, subbrute_scene_setup_attack_device_state_changed, context);
-    if(subbrute_worker_is_running(instance->worker)) {
-        subbrute_worker_stop(instance->worker);
-        instance->device->current_step = subbrute_worker_get_step(instance->worker);
-    }
-
-    subbrute_attack_view_init_values(
-        view,
-        instance->device->attack,
-        instance->device->max_value,
-        instance->device->current_step,
-        false,
-        subbrute_worker_get_repeats(instance->worker));
-
-    instance->current_view = SubBruteViewAttack;
-    subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance);
-    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
-}
-
-void subbrute_scene_setup_attack_on_exit(void* context) {
-    furi_assert(context);
-#ifdef FURI_DEBUG
-    FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit");
-#endif
-    SubBruteState* instance = (SubBruteState*)context;
-    subbrute_worker_stop(instance->worker);
-    notification_message(instance->notifications, &sequence_blink_stop);
-    notification_message(instance->notifications, &sequence_reset_vibro);
-}
-
-bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event) {
-    SubBruteState* instance = (SubBruteState*)context;
-    SubBruteAttackView* view = instance->view_attack;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubBruteCustomEventTypeTransmitStarted) {
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack);
-        } else if(event.event == SubBruteCustomEventTypeSaveFile) {
-            subbrute_attack_view_init_values(
-                view,
-                instance->device->attack,
-                instance->device->max_value,
-                instance->device->current_step,
-                false,
-                instance->device->extra_repeats);
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveName);
-        } else if(event.event == SubBruteCustomEventTypeExtraSettings) {
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupExtra);
-        } else if(event.event == SubBruteCustomEventTypeBackPressed) {
-            subbrute_attack_view_init_values(
-                view,
-                instance->device->attack,
-                instance->device->max_value,
-                instance->device->current_step,
-                false,
-                instance->device->extra_repeats);
-            scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
-        } else if(event.event == SubBruteCustomEventTypeError) {
-            notification_message(instance->notifications, &sequence_error);
-        } else if(event.event == SubBruteCustomEventTypeTransmitCustom) {
-            // We can transmit only in not working states
-            if(subbrute_worker_can_manual_transmit(instance->worker)) {
-                // MANUAL Transmit!
-                // Blink
-                notification_message(instance->notifications, &sequence_blink_green_100);
-                subbrute_worker_transmit_current_key(
-                    instance->worker, instance->device->current_step);
-                // Stop
-                notification_message(instance->notifications, &sequence_blink_stop);
-            }
-        } else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
-            // +1
-            uint64_t step = subbrute_device_add_step(instance->device, 1);
-            subbrute_worker_set_step(instance->worker, step);
-            subbrute_attack_view_set_current_step(view, step);
-        } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) {
-            // +50
-            uint64_t step = subbrute_device_add_step(instance->device, 50);
-            subbrute_worker_set_step(instance->worker, step);
-            subbrute_attack_view_set_current_step(view, step);
-        } else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
-            // -1
-            uint64_t step = subbrute_device_add_step(instance->device, -1);
-            subbrute_worker_set_step(instance->worker, step);
-            subbrute_attack_view_set_current_step(view, step);
-        } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) {
-            // -50
-            uint64_t step = subbrute_device_add_step(instance->device, -50);
-            subbrute_worker_set_step(instance->worker, step);
-            subbrute_attack_view_set_current_step(view, step);
-        }
-
-        consumed = true;
-    } else if(event.type == SceneManagerEventTypeTick) {
-        if(subbrute_worker_is_running(instance->worker)) {
-            instance->device->current_step = subbrute_worker_get_step(instance->worker);
-        }
-        subbrute_attack_view_set_current_step(view, instance->device->current_step);
-        consumed = true;
-    }
-
-    return consumed;
-}
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+#define TAG "SubBruteSceneSetupAttack"
+
+static void subbrute_scene_setup_attack_callback(SubBruteCustomEvent event, void* context) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+    view_dispatcher_send_custom_event(instance->view_dispatcher, event);
+}
+
+static void
+    subbrute_scene_setup_attack_device_state_changed(void* context, SubBruteWorkerState state) {
+    furi_assert(context);
+
+    SubBruteState* instance = (SubBruteState*)context;
+
+    if(state == SubBruteWorkerStateIDLE) {
+        // Can't be IDLE on this step!
+        view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError);
+    }
+}
+
+void subbrute_scene_setup_attack_on_enter(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = (SubBruteState*)context;
+    SubBruteAttackView* view = instance->view_attack;
+
+    notification_message(instance->notifications, &sequence_reset_vibro);
+
+#ifdef FURI_DEBUG
+    FURI_LOG_D(TAG, "Enter Attack: %s", subbrute_protocol_name(instance->device->attack));
+#endif
+
+    subbrute_worker_set_callback(
+        instance->worker, subbrute_scene_setup_attack_device_state_changed, context);
+    if(subbrute_worker_is_running(instance->worker)) {
+        subbrute_worker_stop(instance->worker);
+        instance->device->current_step = subbrute_worker_get_step(instance->worker);
+    }
+
+    subbrute_attack_view_init_values(
+        view,
+        instance->device->attack,
+        instance->device->max_value,
+        instance->device->current_step,
+        false,
+        subbrute_worker_get_repeats(instance->worker));
+
+    instance->current_view = SubBruteViewAttack;
+    subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance);
+    view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view);
+}
+
+void subbrute_scene_setup_attack_on_exit(void* context) {
+    furi_assert(context);
+#ifdef FURI_DEBUG
+    FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit");
+#endif
+    SubBruteState* instance = (SubBruteState*)context;
+    subbrute_worker_stop(instance->worker);
+    notification_message(instance->notifications, &sequence_blink_stop);
+    notification_message(instance->notifications, &sequence_reset_vibro);
+}
+
+bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event) {
+    SubBruteState* instance = (SubBruteState*)context;
+    SubBruteAttackView* view = instance->view_attack;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubBruteCustomEventTypeTransmitStarted) {
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack);
+        } else if(event.event == SubBruteCustomEventTypeSaveFile) {
+            subbrute_attack_view_init_values(
+                view,
+                instance->device->attack,
+                instance->device->max_value,
+                instance->device->current_step,
+                false,
+                instance->device->extra_repeats);
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveName);
+        } else if(event.event == SubBruteCustomEventTypeExtraSettings) {
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupExtra);
+        } else if(event.event == SubBruteCustomEventTypeBackPressed) {
+            subbrute_attack_view_init_values(
+                view,
+                instance->device->attack,
+                instance->device->max_value,
+                instance->device->current_step,
+                false,
+                instance->device->extra_repeats);
+            scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
+        } else if(event.event == SubBruteCustomEventTypeError) {
+            notification_message(instance->notifications, &sequence_error);
+        } else if(event.event == SubBruteCustomEventTypeTransmitCustom) {
+            // We can transmit only in not working states
+            if(subbrute_worker_can_manual_transmit(instance->worker)) {
+                // MANUAL Transmit!
+                // Blink
+                notification_message(instance->notifications, &sequence_blink_green_100);
+                subbrute_worker_transmit_current_key(
+                    instance->worker, instance->device->current_step);
+                // Stop
+                notification_message(instance->notifications, &sequence_blink_stop);
+            }
+        } else if(event.event == SubBruteCustomEventTypeChangeStepUp) {
+            // +1
+            uint64_t step = subbrute_device_add_step(instance->device, 1);
+            subbrute_worker_set_step(instance->worker, step);
+            subbrute_attack_view_set_current_step(view, step);
+        } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) {
+            // +50
+            uint64_t step = subbrute_device_add_step(instance->device, 50);
+            subbrute_worker_set_step(instance->worker, step);
+            subbrute_attack_view_set_current_step(view, step);
+        } else if(event.event == SubBruteCustomEventTypeChangeStepDown) {
+            // -1
+            uint64_t step = subbrute_device_add_step(instance->device, -1);
+            subbrute_worker_set_step(instance->worker, step);
+            subbrute_attack_view_set_current_step(view, step);
+        } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) {
+            // -50
+            uint64_t step = subbrute_device_add_step(instance->device, -50);
+            subbrute_worker_set_step(instance->worker, step);
+            subbrute_attack_view_set_current_step(view, step);
+        }
+
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeTick) {
+        if(subbrute_worker_is_running(instance->worker)) {
+            instance->device->current_step = subbrute_worker_get_step(instance->worker);
+        }
+        subbrute_attack_view_set_current_step(view, instance->device->current_step);
+        consumed = true;
+    }
+
+    return consumed;
+}

+ 280 - 280
scenes/subbrute_scene_setup_extra.c

@@ -1,281 +1,281 @@
-#include "../subbrute_i.h"
-#include "subbrute_scene.h"
-
-#define TAG "SubBruteSceneLoadFile"
-
-#define MIN_TD 0
-#define MAX_TD 255
-#define MIN_REP 1
-#define MAX_REP 100
-#define MIN_TE 100
-#define MAX_TE 600
-
-enum SubBruteVarListIndex {
-    SubBruteVarListIndexTimeDelay,
-    SubBruteVarListIndexRepeat_or_OnExtra,
-    SubBruteVarListIndexTe,
-};
-
-static void setup_extra_enter_callback(void* context, uint32_t index);
-
-static void setup_extra_td_callback(VariableItem* item) {
-    furi_assert(item);
-    SubBruteState* instance = variable_item_get_context(item);
-    furi_assert(instance);
-    char buf[6];
-
-    const uint8_t index = variable_item_get_current_value_index(item);
-    uint8_t val = subbrute_worker_get_timeout(instance->worker);
-
-    if(index == 0) {
-        if(val > MIN_TD) {
-            val--;
-            subbrute_worker_set_timeout(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_TD) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    } else if(index == 2) {
-        if(val < MAX_TD) {
-            val++;
-            subbrute_worker_set_timeout(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_TD) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        }
-    } else if(index == 1) {
-        if(val == MIN_TD) {
-            val++;
-            subbrute_worker_set_timeout(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_TD) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        } else if(val == MAX_TD) {
-            val--;
-            subbrute_worker_set_timeout(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_TD) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    }
-}
-
-static void setup_extra_rep_callback(VariableItem* item) {
-    furi_assert(item);
-    SubBruteState* instance = variable_item_get_context(item);
-    furi_assert(instance);
-    char buf[6];
-
-    const uint8_t index = variable_item_get_current_value_index(item);
-    uint8_t val = subbrute_worker_get_repeats(instance->worker);
-
-    if(index == 0) {
-        if(val > MIN_REP) {
-            val--;
-            subbrute_worker_set_repeats(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_REP) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    } else if(index == 2) {
-        if(val < MAX_REP) {
-            val++;
-            subbrute_worker_set_repeats(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_REP) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        }
-    } else if(index == 1) {
-        if(val == MIN_REP) {
-            val++;
-            subbrute_worker_set_repeats(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_REP) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        } else if(val == MAX_REP) {
-            val--;
-            subbrute_worker_set_repeats(instance->worker, val);
-            snprintf(&buf[0], 5, "%d", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_REP) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    }
-}
-
-static void setup_extra_te_callback(VariableItem* item) {
-    furi_assert(item);
-    SubBruteState* instance = variable_item_get_context(item);
-    furi_assert(instance);
-    char buf[6];
-
-    const uint8_t index = variable_item_get_current_value_index(item);
-    uint32_t val = subbrute_worker_get_te(instance->worker);
-
-    if(index == 0) {
-        if(val > MIN_TE) {
-            val--;
-            subbrute_worker_set_te(instance->worker, val);
-            snprintf(&buf[0], 5, "%ld", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_TE) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    } else if(index == 2) {
-        if(val < MAX_TE) {
-            val++;
-            subbrute_worker_set_te(instance->worker, val);
-            snprintf(&buf[0], 5, "%ld", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_TE) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        }
-    } else if(index == 1) {
-        if(val == MIN_TE) {
-            val++;
-            subbrute_worker_set_te(instance->worker, val);
-            snprintf(&buf[0], 5, "%ld", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MAX_TE) {
-                variable_item_set_current_value_index(item, 2);
-            }
-        } else if(val == MAX_TE) {
-            val--;
-            subbrute_worker_set_te(instance->worker, val);
-            snprintf(&buf[0], 5, "%ld", val);
-            variable_item_set_current_value_text(item, &buf[0]);
-            variable_item_set_current_value_index(item, 1);
-            if(val == MIN_TE) {
-                variable_item_set_current_value_index(item, 0);
-            }
-        }
-    }
-}
-
-static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bool on_extra) {
-    furi_assert(instance);
-    char str[6];
-    VariableItem* item;
-    static bool extra = false;
-    if(on_extra) {
-        extra = true;
-    }
-
-    VariableItemList* var_list = instance->var_list;
-
-    variable_item_list_reset(var_list);
-
-    item = variable_item_list_add(var_list, "TimeDelay", 3, setup_extra_td_callback, instance);
-    snprintf(&str[0], 5, "%d", subbrute_worker_get_timeout(instance->worker));
-    variable_item_set_current_value_text(item, &str[0]);
-    switch(subbrute_worker_get_timeout(instance->worker)) {
-    case MIN_TD:
-        variable_item_set_current_value_index(item, 0);
-        break;
-    case MAX_TD:
-        variable_item_set_current_value_index(item, 2);
-        break;
-
-    default:
-        variable_item_set_current_value_index(item, 1);
-        break;
-    }
-
-    if(extra) {
-        item = variable_item_list_add(var_list, "Repeats", 3, setup_extra_rep_callback, instance);
-        snprintf(&str[0], 5, "%d", subbrute_worker_get_repeats(instance->worker));
-        variable_item_set_current_value_text(item, &str[0]);
-        switch(subbrute_worker_get_repeats(instance->worker)) {
-        case MIN_REP:
-            variable_item_set_current_value_index(item, 0);
-            break;
-        case MAX_REP:
-            variable_item_set_current_value_index(item, 2);
-            break;
-
-        default:
-            variable_item_set_current_value_index(item, 1);
-            break;
-        }
-        const uint32_t te = subbrute_worker_get_te(instance->worker);
-        if(te != 0) {
-            item = variable_item_list_add(var_list, "Te", 3, setup_extra_te_callback, instance);
-            snprintf(&str[0], 5, "%ld", te);
-            variable_item_set_current_value_text(item, &str[0]);
-            switch(te) {
-            case MIN_TE:
-                variable_item_set_current_value_index(item, 0);
-                break;
-            case MAX_TE:
-                variable_item_set_current_value_index(item, 2);
-                break;
-
-            default:
-                variable_item_set_current_value_index(item, 1);
-                break;
-            }
-        }
-    } else {
-        item = variable_item_list_add(var_list, "Show Extra", 0, NULL, NULL);
-    }
-
-    variable_item_list_set_enter_callback(var_list, setup_extra_enter_callback, instance);
-    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewVarList);
-}
-
-static void setup_extra_enter_callback(void* context, uint32_t index) {
-    furi_assert(context);
-    SubBruteState* instance = context;
-
-    if(index == SubBruteVarListIndexRepeat_or_OnExtra) {
-        subbrute_scene_setup_extra_init_var_list(instance, true);
-    }
-}
-
-void subbrute_scene_setup_extra_on_enter(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = context;
-
-    subbrute_scene_setup_extra_init_var_list(instance, false);
-}
-
-void subbrute_scene_setup_extra_on_exit(void* context) {
-    furi_assert(context);
-    SubBruteState* instance = context;
-
-    variable_item_list_reset(instance->var_list);
-}
-
-bool subbrute_scene_setup_extra_on_event(void* context, SceneManagerEvent event) {
-    UNUSED(context);
-    UNUSED(event);
-    return false;
+#include "../subbrute_i.h"
+#include "subbrute_scene.h"
+
+#define TAG "SubBruteSceneLoadFile"
+
+#define MIN_TD 0
+#define MAX_TD 255
+#define MIN_REP 1
+#define MAX_REP 100
+#define MIN_TE 100
+#define MAX_TE 600
+
+enum SubBruteVarListIndex {
+    SubBruteVarListIndexTimeDelay,
+    SubBruteVarListIndexRepeat_or_OnExtra,
+    SubBruteVarListIndexTe,
+};
+
+static void setup_extra_enter_callback(void* context, uint32_t index);
+
+static void setup_extra_td_callback(VariableItem* item) {
+    furi_assert(item);
+    SubBruteState* instance = variable_item_get_context(item);
+    furi_assert(instance);
+    char buf[6];
+
+    const uint8_t index = variable_item_get_current_value_index(item);
+    uint8_t val = subbrute_worker_get_timeout(instance->worker);
+
+    if(index == 0) {
+        if(val > MIN_TD) {
+            val--;
+            subbrute_worker_set_timeout(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_TD) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    } else if(index == 2) {
+        if(val < MAX_TD) {
+            val++;
+            subbrute_worker_set_timeout(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_TD) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        }
+    } else if(index == 1) {
+        if(val == MIN_TD) {
+            val++;
+            subbrute_worker_set_timeout(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_TD) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        } else if(val == MAX_TD) {
+            val--;
+            subbrute_worker_set_timeout(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_TD) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    }
+}
+
+static void setup_extra_rep_callback(VariableItem* item) {
+    furi_assert(item);
+    SubBruteState* instance = variable_item_get_context(item);
+    furi_assert(instance);
+    char buf[6];
+
+    const uint8_t index = variable_item_get_current_value_index(item);
+    uint8_t val = subbrute_worker_get_repeats(instance->worker);
+
+    if(index == 0) {
+        if(val > MIN_REP) {
+            val--;
+            subbrute_worker_set_repeats(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_REP) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    } else if(index == 2) {
+        if(val < MAX_REP) {
+            val++;
+            subbrute_worker_set_repeats(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_REP) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        }
+    } else if(index == 1) {
+        if(val == MIN_REP) {
+            val++;
+            subbrute_worker_set_repeats(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_REP) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        } else if(val == MAX_REP) {
+            val--;
+            subbrute_worker_set_repeats(instance->worker, val);
+            snprintf(&buf[0], 5, "%d", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_REP) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    }
+}
+
+static void setup_extra_te_callback(VariableItem* item) {
+    furi_assert(item);
+    SubBruteState* instance = variable_item_get_context(item);
+    furi_assert(instance);
+    char buf[6];
+
+    const uint8_t index = variable_item_get_current_value_index(item);
+    uint32_t val = subbrute_worker_get_te(instance->worker);
+
+    if(index == 0) {
+        if(val > MIN_TE) {
+            val--;
+            subbrute_worker_set_te(instance->worker, val);
+            snprintf(&buf[0], 5, "%ld", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_TE) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    } else if(index == 2) {
+        if(val < MAX_TE) {
+            val++;
+            subbrute_worker_set_te(instance->worker, val);
+            snprintf(&buf[0], 5, "%ld", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_TE) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        }
+    } else if(index == 1) {
+        if(val == MIN_TE) {
+            val++;
+            subbrute_worker_set_te(instance->worker, val);
+            snprintf(&buf[0], 5, "%ld", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MAX_TE) {
+                variable_item_set_current_value_index(item, 2);
+            }
+        } else if(val == MAX_TE) {
+            val--;
+            subbrute_worker_set_te(instance->worker, val);
+            snprintf(&buf[0], 5, "%ld", val);
+            variable_item_set_current_value_text(item, &buf[0]);
+            variable_item_set_current_value_index(item, 1);
+            if(val == MIN_TE) {
+                variable_item_set_current_value_index(item, 0);
+            }
+        }
+    }
+}
+
+static void subbrute_scene_setup_extra_init_var_list(SubBruteState* instance, bool on_extra) {
+    furi_assert(instance);
+    char str[6];
+    VariableItem* item;
+    static bool extra = false;
+    if(on_extra) {
+        extra = true;
+    }
+
+    VariableItemList* var_list = instance->var_list;
+
+    variable_item_list_reset(var_list);
+
+    item = variable_item_list_add(var_list, "TimeDelay", 3, setup_extra_td_callback, instance);
+    snprintf(&str[0], 5, "%d", subbrute_worker_get_timeout(instance->worker));
+    variable_item_set_current_value_text(item, &str[0]);
+    switch(subbrute_worker_get_timeout(instance->worker)) {
+    case MIN_TD:
+        variable_item_set_current_value_index(item, 0);
+        break;
+    case MAX_TD:
+        variable_item_set_current_value_index(item, 2);
+        break;
+
+    default:
+        variable_item_set_current_value_index(item, 1);
+        break;
+    }
+
+    if(extra) {
+        item = variable_item_list_add(var_list, "Repeats", 3, setup_extra_rep_callback, instance);
+        snprintf(&str[0], 5, "%d", subbrute_worker_get_repeats(instance->worker));
+        variable_item_set_current_value_text(item, &str[0]);
+        switch(subbrute_worker_get_repeats(instance->worker)) {
+        case MIN_REP:
+            variable_item_set_current_value_index(item, 0);
+            break;
+        case MAX_REP:
+            variable_item_set_current_value_index(item, 2);
+            break;
+
+        default:
+            variable_item_set_current_value_index(item, 1);
+            break;
+        }
+        const uint32_t te = subbrute_worker_get_te(instance->worker);
+        if(te != 0) {
+            item = variable_item_list_add(var_list, "Te", 3, setup_extra_te_callback, instance);
+            snprintf(&str[0], 5, "%ld", te);
+            variable_item_set_current_value_text(item, &str[0]);
+            switch(te) {
+            case MIN_TE:
+                variable_item_set_current_value_index(item, 0);
+                break;
+            case MAX_TE:
+                variable_item_set_current_value_index(item, 2);
+                break;
+
+            default:
+                variable_item_set_current_value_index(item, 1);
+                break;
+            }
+        }
+    } else {
+        item = variable_item_list_add(var_list, "Show Extra", 0, NULL, NULL);
+    }
+
+    variable_item_list_set_enter_callback(var_list, setup_extra_enter_callback, instance);
+    view_dispatcher_switch_to_view(instance->view_dispatcher, SubBruteViewVarList);
+}
+
+static void setup_extra_enter_callback(void* context, uint32_t index) {
+    furi_assert(context);
+    SubBruteState* instance = context;
+
+    if(index == SubBruteVarListIndexRepeat_or_OnExtra) {
+        subbrute_scene_setup_extra_init_var_list(instance, true);
+    }
+}
+
+void subbrute_scene_setup_extra_on_enter(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = context;
+
+    subbrute_scene_setup_extra_init_var_list(instance, false);
+}
+
+void subbrute_scene_setup_extra_on_exit(void* context) {
+    furi_assert(context);
+    SubBruteState* instance = context;
+
+    variable_item_list_reset(instance->var_list);
+}
+
+bool subbrute_scene_setup_extra_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
 }
 }

+ 30 - 30
scenes/subbute_scene.c

@@ -1,30 +1,30 @@
-#include "subbrute_scene.h"
-
-// Generate scene on_enter handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
-void (*const subbrute_on_enter_handlers[])(void*) = {
-#include "subbrute_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_event handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
-bool (*const subbrute_on_event_handlers[])(void* context, SceneManagerEvent event) = {
-#include "subbrute_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Generate scene on_exit handlers array
-#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
-void (*const subbrute_on_exit_handlers[])(void* context) = {
-#include "subbrute_scene_config.h"
-};
-#undef ADD_SCENE
-
-// Initialize scene handlers configuration structure
-const SceneManagerHandlers subbrute_scene_handlers = {
-    .on_enter_handlers = subbrute_on_enter_handlers,
-    .on_event_handlers = subbrute_on_event_handlers,
-    .on_exit_handlers = subbrute_on_exit_handlers,
-    .scene_num = SubBruteSceneNum,
-};
+#include "subbrute_scene.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const subbrute_on_enter_handlers[])(void*) = {
+#include "subbrute_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_event handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
+bool (*const subbrute_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+#include "subbrute_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
+void (*const subbrute_on_exit_handlers[])(void* context) = {
+#include "subbrute_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers subbrute_scene_handlers = {
+    .on_enter_handlers = subbrute_on_enter_handlers,
+    .on_event_handlers = subbrute_on_event_handlers,
+    .on_exit_handlers = subbrute_on_exit_handlers,
+    .scene_num = SubBruteSceneNum,
+};

+ 26 - 26
subbrute_custom_event.h

@@ -1,27 +1,27 @@
-#pragma once
-
-typedef enum {
-    // Reserve first 100 events for button types and indexes, starting from 0
-    SubBruteCustomEventTypeReserved = 100,
-
-    SubBruteCustomEventTypeBackPressed,
-    SubBruteCustomEventTypeIndexSelected,
-    SubBruteCustomEventTypeTransmitStarted,
-    SubBruteCustomEventTypeError,
-    SubBruteCustomEventTypeTransmitFinished,
-    SubBruteCustomEventTypeTransmitNotStarted,
-    SubBruteCustomEventTypeTransmitCustom,
-    SubBruteCustomEventTypeSaveFile,
-    SubBruteCustomEventTypeExtraSettings,
-    SubBruteCustomEventTypeUpdateView,
-    SubBruteCustomEventTypeChangeStepUp,
-    SubBruteCustomEventTypeChangeStepDown,
-    SubBruteCustomEventTypeChangeStepUpMore,
-    SubBruteCustomEventTypeChangeStepDownMore,
-
-    SubBruteCustomEventTypeMenuSelected,
-    SubBruteCustomEventTypeTextEditDone,
-    SubBruteCustomEventTypePopupClosed,
-
-    SubBruteCustomEventTypeLoadFile,
+#pragma once
+
+typedef enum {
+    // Reserve first 100 events for button types and indexes, starting from 0
+    SubBruteCustomEventTypeReserved = 100,
+
+    SubBruteCustomEventTypeBackPressed,
+    SubBruteCustomEventTypeIndexSelected,
+    SubBruteCustomEventTypeTransmitStarted,
+    SubBruteCustomEventTypeError,
+    SubBruteCustomEventTypeTransmitFinished,
+    SubBruteCustomEventTypeTransmitNotStarted,
+    SubBruteCustomEventTypeTransmitCustom,
+    SubBruteCustomEventTypeSaveFile,
+    SubBruteCustomEventTypeExtraSettings,
+    SubBruteCustomEventTypeUpdateView,
+    SubBruteCustomEventTypeChangeStepUp,
+    SubBruteCustomEventTypeChangeStepDown,
+    SubBruteCustomEventTypeChangeStepUpMore,
+    SubBruteCustomEventTypeChangeStepDownMore,
+
+    SubBruteCustomEventTypeMenuSelected,
+    SubBruteCustomEventTypeTextEditDone,
+    SubBruteCustomEventTypePopupClosed,
+
+    SubBruteCustomEventTypeLoadFile,
 } SubBruteCustomEvent;
 } SubBruteCustomEvent;