refactor worker moved it to SubBruteState

This commit is contained in:
DerSkythe 2022-09-26 01:07:16 +04:00
parent ba5f590dab
commit 23f6ea2e05
9 changed files with 132 additions and 152 deletions

View file

@ -10,6 +10,7 @@ struct SubBruteWorker {
FuriThread* thread; FuriThread* thread;
volatile bool worker_running; volatile bool worker_running;
volatile bool worker_manual_mode; volatile bool worker_manual_mode;
bool is_manual_init;
SubGhzEnvironment* environment; SubGhzEnvironment* environment;
SubGhzTransmitter* transmitter; SubGhzTransmitter* transmitter;
@ -30,7 +31,7 @@ struct SubBruteWorker {
#define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048 #define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048
#define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60 #define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60
#define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 #define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40
#define SUBBRUTE_TX_TIMEOUT 200 #define SUBBRUTE_TX_TIMEOUT 50
#define SUBBRUTE_SEND_DELAY 260 #define SUBBRUTE_SEND_DELAY 260
/** /**
@ -115,6 +116,16 @@ void subbrute_worker_free(SubBruteWorker* instance) {
furi_assert(instance); furi_assert(instance);
furi_assert(!instance->worker_running); furi_assert(!instance->worker_running);
if(instance->transmitter != NULL) {
subghz_transmitter_free(instance->transmitter);
instance->transmitter = NULL;
}
if(instance->environment != NULL) {
subghz_environment_free(instance->environment);
instance->environment = NULL;
}
furi_thread_free(instance->thread); furi_thread_free(instance->thread);
flipper_format_free(instance->flipper_format); flipper_format_free(instance->flipper_format);
@ -130,7 +141,7 @@ bool subbrute_worker_start(
const char* protocol_name) { const char* protocol_name) {
furi_assert(instance); furi_assert(instance);
if (instance->worker_manual_mode) { if(instance->worker_manual_mode) {
return false; return false;
} }
@ -211,29 +222,39 @@ bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) {
return true; return true;
} }
bool subbrute_worker_single_transmit(SubBruteWorker* instance, bool subbrute_worker_init_manual_transmit(
SubBruteWorker* instance,
uint32_t frequency, uint32_t frequency,
FuriHalSubGhzPreset preset, FuriHalSubGhzPreset preset,
const char* protocol_name, const char* protocol_name) {
const char* payload) { #ifdef FURI_DEBUG
furi_assert(instance); FURI_LOG_D(
TAG,
if (instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) { "subbrute_worker_init_manual_transmit. frequency: %d, protocol: %s",
frequency,
protocol_name);
#endif
if(instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) {
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D(TAG, "cannot transmit"); FURI_LOG_D(TAG, "cannot transmit");
#endif #endif
return false; return false;
} }
if (instance->worker_running) { if(instance->worker_running) {
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_worker_stop"); FURI_LOG_D(TAG, "subbrute_worker_stop");
#endif #endif
subbrute_worker_stop(instance); subbrute_worker_stop(instance);
} }
instance->last_time_tx_data = furi_get_tick(); // Not transmit at this period
instance->worker_manual_mode = true; instance->worker_manual_mode = true;
if(instance->is_manual_init) {
FURI_LOG_E(TAG, "Trying to setup without normally shutdown prev transmit session!");
subbrute_worker_manual_transmit_stop(instance);
}
instance->preset = preset; instance->preset = preset;
instance->frequency = frequency; instance->frequency = frequency;
@ -248,6 +269,8 @@ bool subbrute_worker_single_transmit(SubBruteWorker* instance,
furi_hal_subghz_flush_rx(); furi_hal_subghz_flush_rx();
if(!furi_hal_subghz_is_tx_allowed(frequency)) { if(!furi_hal_subghz_is_tx_allowed(frequency)) {
FURI_LOG_E(TAG, "Frequency: %d invalid!", frequency);
instance->frequency = frequency; instance->frequency = frequency;
instance->worker_manual_mode = false; instance->worker_manual_mode = false;
return false; return false;
@ -261,30 +284,81 @@ bool subbrute_worker_single_transmit(SubBruteWorker* instance,
instance->transmitter = subghz_transmitter_alloc_init( instance->transmitter = subghz_transmitter_alloc_init(
instance->environment, string_get_cstr(instance->protocol_name)); instance->environment, string_get_cstr(instance->protocol_name));
furi_hal_subghz_reset();
furi_hal_subghz_load_preset(instance->preset);
instance->frequency = furi_hal_subghz_set_frequency_and_path(frequency);
instance->worker_manual_mode = false;
instance->is_manual_init = true;
return true;
}
void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_worker_manual_transmit_stop");
#endif
if(!instance->is_manual_init) {
return;
}
furi_hal_subghz_idle();
furi_hal_subghz_sleep();
if(instance->transmitter != NULL) {
subghz_transmitter_free(instance->transmitter);
instance->transmitter = NULL;
}
subghz_environment_free(instance->environment);
instance->environment = NULL;
instance->is_manual_init = false;
}
bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* payload) {
furi_assert(instance);
if(instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "cannot transmit");
#endif
return false;
}
if(instance->worker_running) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_worker_stop");
#endif
subbrute_worker_stop(instance);
}
if(!instance->is_manual_init) {
FURI_LOG_E(TAG, "Manually transmit doesn't set!");
return false;
}
instance->last_time_tx_data = furi_get_tick();
instance->worker_manual_mode = true;
Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); Stream* stream = flipper_format_get_raw_stream(instance->flipper_format);
stream_clean(stream); stream_clean(stream);
stream_write_cstring(stream, payload); stream_write_cstring(stream, payload);
subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format);
instance->transmitter = subghz_transmitter_alloc_init(
instance->environment, string_get_cstr(instance->protocol_name));
subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format);
furi_hal_subghz_reset(); furi_hal_subghz_reset();
furi_hal_subghz_load_preset(instance->preset); furi_hal_subghz_load_preset(instance->preset);
frequency = furi_hal_subghz_set_frequency_and_path(frequency); instance->frequency = furi_hal_subghz_set_frequency_and_path(instance->frequency);
furi_hal_power_suppress_charge_enter();
furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter);
while(!furi_hal_subghz_is_async_tx_complete()) { while(!furi_hal_subghz_is_async_tx_complete()) {
furi_delay_ms(SUBBRUTE_SEND_DELAY); furi_delay_ms(SUBBRUTE_TX_TIMEOUT);
} }
furi_hal_subghz_stop_async_tx(); furi_hal_subghz_stop_async_tx();
furi_hal_subghz_sleep(); furi_hal_subghz_sleep();
furi_hal_power_suppress_charge_exit();
subghz_transmitter_free(instance->transmitter); subghz_transmitter_free(instance->transmitter);
instance->transmitter = NULL; instance->transmitter = NULL;
subghz_environment_free(instance->environment);
instance->environment = NULL;
instance->worker_manual_mode = false; instance->worker_manual_mode = false;

View file

@ -27,8 +27,9 @@ void subbrute_worker_stop(SubBruteWorker* instance);
bool subbrute_worker_is_running(SubBruteWorker* instance); bool subbrute_worker_is_running(SubBruteWorker* instance);
bool subbrute_worker_can_transmit(SubBruteWorker* instance); bool subbrute_worker_can_transmit(SubBruteWorker* instance);
bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload); bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload);
bool subbrute_worker_single_transmit(SubBruteWorker* instance, bool subbrute_worker_init_manual_transmit(SubBruteWorker* instance,
uint32_t frequency, uint32_t frequency,
FuriHalSubGhzPreset preset, FuriHalSubGhzPreset preset,
const char* protocol_name, const char* protocol_name);
const char* payload); bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* payload);
void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance);

View file

@ -1,6 +1,7 @@
#include "../subbrute_i.h" #include "../subbrute_i.h"
#include "../subbrute_custom_event.h" #include "../subbrute_custom_event.h"
#include "../views/subbrute_attack_view.h" #include "../views/subbrute_attack_view.h"
#include "../helpers/subbrute_worker.h"
static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) { static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) {
furi_assert(context); furi_assert(context);
@ -33,11 +34,11 @@ void subbrute_scene_run_attack_on_enter(void* context) {
true); true);
// Start worker if not started // Start worker if not started
/*subbrute_attack_view_start_worker( subbrute_worker_init_manual_transmit(
view, instance->worker,
instance->device->frequency, instance->device->frequency,
instance->device->preset, instance->device->preset,
string_get_cstr(instance->device->protocol_name));*/ string_get_cstr(instance->device->protocol_name));
} }
bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) {
@ -54,16 +55,11 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event)
consumed = true; consumed = true;
} }
} else if(event.type == SceneManagerEventTypeTick) { } else if(event.type == SceneManagerEventTypeTick) {
if(subbrute_attack_view_can_send(view)) { if(subbrute_worker_can_transmit(instance->worker)) {
// Blink // Blink
notification_message(instance->notifications, &sequence_blink_yellow_100); notification_message(instance->notifications, &sequence_blink_yellow_100);
if(subbrute_attack_view_single_transmit( if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) {
view,
instance->device->frequency,
instance->device->preset,
string_get_cstr(instance->device->protocol_name),
instance->device->payload)) {
// Make payload for new iteration or exit // Make payload for new iteration or exit
if(instance->device->key_index + 1 > instance->device->max_value) { if(instance->device->key_index + 1 > instance->device->max_value) {
// End of list // End of list

View file

@ -27,7 +27,11 @@ void subbrute_scene_setup_attack_on_enter(void* context) {
instance->device->key_index, instance->device->key_index,
false); false);
subbrute_attack_view_stop_worker(view); subbrute_worker_init_manual_transmit(
instance->worker,
instance->device->frequency,
instance->device->preset,
string_get_cstr(instance->device->protocol_name));
instance->current_view = SubBruteViewAttack; instance->current_view = SubBruteViewAttack;
subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance); subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance);
@ -40,6 +44,7 @@ void subbrute_scene_setup_attack_on_exit(void* context) {
FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit"); FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit");
#endif #endif
SubBruteState* instance = (SubBruteState*)context; SubBruteState* instance = (SubBruteState*)context;
subbrute_worker_manual_transmit_stop(instance->worker);
notification_message(instance->notifications, &sequence_blink_stop); notification_message(instance->notifications, &sequence_blink_stop);
} }
@ -52,7 +57,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
if(event.event == SubBruteCustomEventTypeTransmitStarted) { if(event.event == SubBruteCustomEventTypeTransmitStarted) {
scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack);
} else if(event.event == SubBruteCustomEventTypeSaveFile) { } else if(event.event == SubBruteCustomEventTypeSaveFile) {
//subbrute_attack_view_stop_worker(view); subbrute_worker_manual_transmit_stop(instance->worker);
subbrute_attack_view_init_values( subbrute_attack_view_init_values(
view, view,
@ -97,7 +102,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
instance->device->max_value; instance->device->max_value;
subbrute_attack_view_set_current_step(view, instance->device->key_index); subbrute_attack_view_set_current_step(view, instance->device->key_index);
} else if(event.event == SubBruteCustomEventTypeTransmitCustom) { } else if(event.event == SubBruteCustomEventTypeTransmitCustom) {
if(subbrute_attack_view_can_send(view)) { if(subbrute_worker_can_transmit(instance->worker)) {
// Blink // Blink
notification_message(instance->notifications, &sequence_blink_green_100); notification_message(instance->notifications, &sequence_blink_green_100);
@ -110,12 +115,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event
// } // }
subbrute_device_create_packet_parsed( subbrute_device_create_packet_parsed(
instance->device, instance->device->key_index); instance->device, instance->device->key_index);
subbrute_attack_view_single_transmit( subbrute_worker_manual_transmit(instance->worker, instance->device->payload);
view,
instance->device->frequency,
instance->device->preset,
string_get_cstr(instance->device->protocol_name),
instance->device->payload);
// Stop // Stop
notification_message(instance->notifications, &sequence_blink_stop); notification_message(instance->notifications, &sequence_blink_stop);

View file

@ -92,6 +92,9 @@ SubBruteState* subbrute_alloc() {
// Devices // Devices
instance->device = subbrute_device_alloc(); instance->device = subbrute_device_alloc();
// Worker
instance->worker = subbrute_worker_alloc();
// TextInput // TextInput
instance->text_input = text_input_alloc(); instance->text_input = text_input_alloc();
view_dispatcher_add_view( view_dispatcher_add_view(
@ -145,6 +148,13 @@ void subbrute_free(SubBruteState* instance) {
#endif #endif
subbrute_device_free(instance->device); subbrute_device_free(instance->device);
// SubBruteWorker
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "free SubBruteDevice");
#endif
subbrute_worker_stop(instance->worker);
subbrute_worker_free(instance->worker);
// Notifications // Notifications
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D(TAG, "free Notifications"); FURI_LOG_D(TAG, "free Notifications");
@ -280,31 +290,16 @@ const char* subbrute_get_small_menu_name(SubBruteAttacks index) {
// ENTRYPOINT // ENTRYPOINT
int32_t subbrute_app(void* p) { int32_t subbrute_app(void* p) {
UNUSED(p); UNUSED(p);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_app");
#endif
SubBruteState* instance = subbrute_alloc(); SubBruteState* instance = subbrute_alloc();
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "Starting subbrute_alloc done");
#endif
view_dispatcher_attach_to_gui( view_dispatcher_attach_to_gui(
instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen); instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart); scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "scene_manager_next_scene set");
#endif
furi_hal_power_suppress_charge_enter(); furi_hal_power_suppress_charge_enter();
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "view_dispatcher_run");
#endif
view_dispatcher_run(instance->view_dispatcher); view_dispatcher_run(instance->view_dispatcher);
furi_hal_power_suppress_charge_exit(); furi_hal_power_suppress_charge_exit();
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "before subbrute_free");
#endif
subbrute_free(instance); subbrute_free(instance);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "return 0");
#endif
return 0; return 0;
} }

View file

@ -31,6 +31,7 @@
#include <notification/notification_messages.h> #include <notification/notification_messages.h>
#include "subbrute_device.h" #include "subbrute_device.h"
#include "helpers/subbrute_worker.h"
#include "subbrute.h" #include "subbrute.h"
#include "scenes/subbrute_scene.h" #include "scenes/subbrute_scene.h"
#include "views/subbrute_attack_view.h" #include "views/subbrute_attack_view.h"
@ -68,6 +69,7 @@ struct SubBruteState {
SceneManager* scene_manager; SceneManager* scene_manager;
SubBruteDevice* device; SubBruteDevice* device;
SubBruteWorker* worker;
//Menu stuff //Menu stuff
// TODO: Do we need it? // TODO: Do we need it?

View file

@ -1,6 +1,5 @@
#include "subbrute_attack_view.h" #include "subbrute_attack_view.h"
#include "../subbrute_i.h" #include "../subbrute_i.h"
#include "../helpers/subbrute_worker.h"
#include "assets_icons.h" #include "assets_icons.h"
#include <input/input.h> #include <input/input.h>
@ -14,7 +13,6 @@ struct SubBruteAttackView {
View* view; View* view;
SubBruteAttackViewCallback callback; SubBruteAttackViewCallback callback;
void* context; void* context;
SubBruteWorker* worker;
}; };
typedef struct { typedef struct {
@ -89,14 +87,8 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) {
// instance->callback(SubBruteCustomEventTypeBackPressed, instance->context); // instance->callback(SubBruteCustomEventTypeBackPressed, instance->context);
// } // }
} else if(event->key == InputKeyUp) { } else if(event->key == InputKeyUp) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "InputKey: %d UP", event->key);
#endif
instance->callback(SubBruteCustomEventTypeSaveFile, instance->context); instance->callback(SubBruteCustomEventTypeSaveFile, instance->context);
} else if(event->key == InputKeyDown) { } else if(event->key == InputKeyDown) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "InputKey: %d DOWN", event->key);
#endif
instance->callback(SubBruteCustomEventTypeTransmitCustom, instance->context); instance->callback(SubBruteCustomEventTypeTransmitCustom, instance->context);
} else if(event->type == InputTypeShort) { } else if(event->type == InputTypeShort) {
if(event->key == InputKeyLeft) { if(event->key == InputKeyLeft) {
@ -169,7 +161,6 @@ SubBruteAttackView* subbrute_attack_view_alloc() {
view_set_enter_callback(instance->view, subbrute_attack_view_enter); view_set_enter_callback(instance->view, subbrute_attack_view_enter);
view_set_exit_callback(instance->view, subbrute_attack_view_exit); view_set_exit_callback(instance->view, subbrute_attack_view_exit);
instance->worker = subbrute_worker_alloc();
return instance; return instance;
} }
@ -188,7 +179,6 @@ void subbrute_attack_view_free(SubBruteAttackView* instance) {
#ifdef FURI_DEBUG #ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_attack_view_free"); FURI_LOG_D(TAG, "subbrute_attack_view_free");
#endif #endif
subbrute_worker_free(instance->worker);
with_view_model( with_view_model(
instance->view, (SubBruteAttackViewModel * model) { instance->view, (SubBruteAttackViewModel * model) {
@ -257,60 +247,6 @@ void subbrute_attack_view_init_values(
}); });
} }
void subbrute_attack_view_stop_worker(SubBruteAttackView* instance) {
furi_assert(instance);
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_attack_view_stop_worker");
#endif
subbrute_worker_stop(instance->worker);
}
bool subbrute_attack_view_can_send(SubBruteAttackView* instance) {
furi_assert(instance);
return subbrute_worker_can_transmit(instance->worker);
}
void subbrute_attack_view_start_worker(
SubBruteAttackView* instance,
uint32_t frequency,
FuriHalSubGhzPreset preset,
const char* protocol_name) {
furi_assert(instance);
#ifdef FURI_DEBUG
FURI_LOG_D(
TAG,
"start_worker. frequency: %d, preset: %d, protocol_name: %s",
frequency,
preset,
protocol_name);
#endif
if(!subbrute_worker_is_running(instance->worker)) {
subbrute_worker_start(instance->worker, frequency, preset, protocol_name);
}
}
bool subbrute_attack_view_transmit(SubBruteAttackView* instance, const char* payload) {
furi_assert(instance);
return subbrute_worker_transmit(instance->worker, payload);
}
bool subbrute_attack_view_single_transmit(
SubBruteAttackView* instance,
uint32_t frequency,
FuriHalSubGhzPreset preset,
const char* protocol_name,
const char* payload) {
return subbrute_worker_single_transmit(
instance->worker, frequency, preset, protocol_name, payload);
}
bool subbrute_attack_view_is_worker_running(SubBruteAttackView* instance) {
furi_assert(instance);
return subbrute_worker_is_running(instance->worker);
}
void subbrute_attack_view_exit(void* context) { void subbrute_attack_view_exit(void* context) {
furi_assert(context); furi_assert(context);
SubBruteAttackView* instance = context; SubBruteAttackView* instance = context;
@ -322,13 +258,6 @@ void subbrute_attack_view_exit(void* context) {
icon_animation_stop(model->icon); icon_animation_stop(model->icon);
return false; return false;
}); });
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "subbrute_worker_stop");
furi_delay_ms(150);
#endif
// Just stop, make free in free method
subbrute_worker_stop(instance->worker);
} }
void elements_button_top_left(Canvas* canvas, const char* str) { void elements_button_top_left(Canvas* canvas, const char* str) {

View file

@ -26,18 +26,3 @@ void subbrute_attack_view_init_values(
uint64_t max_value, uint64_t max_value,
uint64_t current_step, uint64_t current_step,
bool is_attacking); bool is_attacking);
void subbrute_attack_view_stop_worker(SubBruteAttackView* instance);
bool subbrute_attack_view_can_send(SubBruteAttackView* instance);
void subbrute_attack_view_start_worker(
SubBruteAttackView* instance,
uint32_t frequency,
FuriHalSubGhzPreset preset,
const char* protocol_name);
bool subbrute_attack_view_transmit(SubBruteAttackView* instance, const char* payload);
bool subbrute_attack_view_single_transmit(
SubBruteAttackView* instance,
uint32_t frequency,
FuriHalSubGhzPreset preset,
const char* protocol_name,
const char* payload);
bool subbrute_attack_view_is_worker_running(SubBruteAttackView* instance);

View file

@ -18,14 +18,12 @@ void subbrute_main_view_set_callback(
SubBruteMainView* subbrute_main_view_alloc(); SubBruteMainView* subbrute_main_view_alloc();
void subbrute_main_view_free(SubBruteMainView* instance); void subbrute_main_view_free(SubBruteMainView* instance);
View* subbrute_main_view_get_view(SubBruteMainView* instance); View* subbrute_main_view_get_view(SubBruteMainView* instance);
void subbrute_main_view_set_index( void subbrute_main_view_set_index(
SubBruteMainView* instance, SubBruteMainView* instance,
uint8_t idx, uint8_t idx,
bool is_select_byte, bool is_select_byte,
const char* key_field); const char* key_field);
uint8_t subbrute_main_view_get_index(SubBruteMainView* instance); uint8_t subbrute_main_view_get_index(SubBruteMainView* instance);
void subbrute_attack_view_enter(void* context); void subbrute_attack_view_enter(void* context);
void subbrute_attack_view_exit(void* context); void subbrute_attack_view_exit(void* context);
bool subbrute_attack_view_input(InputEvent* event, void* context); bool subbrute_attack_view_input(InputEvent* event, void* context);