From 127b7006423b8b309aec0d7a34d77206013e49d3 Mon Sep 17 00:00:00 2001 From: derskythe Date: Fri, 30 Sep 2022 18:36:56 +0400 Subject: [PATCH 01/14] Init work on rev3, but this is not working code --- .../subbrute/helpers/subbrute_worker.c | 346 ----- .../subbrute/helpers/subbrute_worker.h | 39 - .../scenes/subbrute_scene_load_file.c | 4 +- .../scenes/subbrute_scene_load_select.c | 11 +- .../scenes/subbrute_scene_run_attack.c | 174 +-- .../scenes/subbrute_scene_save_name.c | 32 +- .../scenes/subbrute_scene_save_success.c | 2 +- .../scenes/subbrute_scene_setup_attack.c | 170 +-- .../subbrute/scenes/subbrute_scene_start.c | 5 +- applications/plugins/subbrute/subbrute.c | 77 +- .../plugins/subbrute/subbrute_custom_event.h | 2 +- .../plugins/subbrute/subbrute_device.c | 1142 +++++++++-------- .../plugins/subbrute/subbrute_device.h | 102 +- .../plugins/subbrute/subbrute_device_i.h | 64 + applications/plugins/subbrute/subbrute_i.h | 26 +- .../plugins/subbrute/subbrute_protocols.c | 127 ++ .../plugins/subbrute/subbrute_protocols.h | 42 + .../plugins/subbrute/subbrute_protocols_i.h | 18 + .../subbrute/views/subbrute_attack_view.c | 3 +- .../subbrute/views/subbrute_attack_view.h | 2 +- .../subbrute/views/subbrute_main_view.c | 6 +- 21 files changed, 1022 insertions(+), 1372 deletions(-) delete mode 100644 applications/plugins/subbrute/helpers/subbrute_worker.c delete mode 100644 applications/plugins/subbrute/helpers/subbrute_worker.h create mode 100644 applications/plugins/subbrute/subbrute_device_i.h create mode 100644 applications/plugins/subbrute/subbrute_protocols.c create mode 100644 applications/plugins/subbrute/subbrute_protocols.h create mode 100644 applications/plugins/subbrute/subbrute_protocols_i.h diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c deleted file mode 100644 index 80275698e..000000000 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "subbrute_worker.h" - -#include -#include -#include -#include - -#define TAG "SubBruteWorker" - -struct SubBruteWorker { - SubGhzTxRxWorker* subghz_txrx; - volatile bool worker_running; - volatile bool worker_manual_mode; - bool is_manual_init; - bool is_continuous_worker; - - SubGhzEnvironment* environment; - SubGhzTransmitter* transmitter; - FlipperFormat* flipper_format; - - uint32_t last_time_tx_data; - - // Preset and frequency needed - FuriHalSubGhzPreset preset; - uint32_t frequency; - string_t protocol_name; - - //SubBruteWorkerCallback callback; - //void* context; -}; - -/** Taken from subghz_tx_rx_worker.c */ -#define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048 -#define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60 -#define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 -#define SUBBRUTE_TX_TIMEOUT 5 -#define SUBBRUTE_SEND_DELAY 20 - -SubBruteWorker* subbrute_worker_alloc() { - SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); - - //instance->status = SubBruteWorkerStatusIDLE; - instance->worker_running = false; - instance->worker_manual_mode = false; - - //instance->environment = subghz_environment_alloc(); - instance->transmitter = NULL; - - instance->flipper_format = flipper_format_string_alloc(); - string_init(instance->protocol_name); - - // SubGhzTxRxWorker - instance->subghz_txrx = subghz_tx_rx_worker_alloc(); - - return instance; -} - -void subbrute_worker_free(SubBruteWorker* instance) { - furi_assert(instance); - 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; - }*/ - - flipper_format_free(instance->flipper_format); - - string_clear(instance->protocol_name); - - // SubGhzTxRxWorker - subghz_tx_rx_worker_free(instance->subghz_txrx); - - free(instance); -} - -bool subbrute_worker_start( - SubBruteWorker* instance, - uint32_t frequency, - FuriHalSubGhzPreset preset, - const char* protocol_name) { - furi_assert(instance); - - if(instance->worker_manual_mode) { - FURI_LOG_W(TAG, "Invalid mode for starting worker!"); - return false; - } - - instance->frequency = frequency; - instance->preset = preset; - - string_clear(instance->protocol_name); - string_init_printf(instance->protocol_name, "%s", protocol_name); - - bool res = false; - - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(instance->preset); - - furi_hal_subghz_set_frequency_and_path(instance->frequency); - furi_hal_subghz_flush_rx(); - - //if(furi_hal_subghz_is_tx_allowed(frequency)) { - instance->frequency = frequency; - res = true; - //} - instance->worker_running = res; - -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Frequency: %d", frequency); -#endif - instance->preset = preset; - if(res) { - instance->worker_running = res = - subghz_tx_rx_worker_start(instance->subghz_txrx, frequency); - } - return res; -} - -void subbrute_worker_stop(SubBruteWorker* instance) { - furi_assert(instance); - - instance->worker_running = false; - - if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) { - subghz_tx_rx_worker_stop(instance->subghz_txrx); - } -} - -void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_continuous_worker) { - furi_assert(instance); - - instance->is_continuous_worker = is_continuous_worker; -} - -bool subbrute_worker_get_continuous_worker(SubBruteWorker* instance) { - furi_assert(instance); - - return instance->is_continuous_worker; -} - -bool subbrute_worker_is_running(SubBruteWorker* instance) { - furi_assert(instance); - - return instance->worker_running; -} - -bool subbrute_worker_can_transmit(SubBruteWorker* instance) { - furi_assert(instance); - - return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY; -} - -bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance, bool is_button_pressed) { - furi_assert(instance); - - if(is_button_pressed) { - // It's human pressed, trying to reset twice pressing - return !instance->worker_manual_mode && - (furi_get_tick() - instance->last_time_tx_data) > 500; - } else { - return !instance->worker_manual_mode; - } -} - -bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { - furi_assert(instance); - furi_assert(instance->worker_running); - - if(!subbrute_worker_can_transmit(instance)) { - FURI_LOG_E(TAG, "Too early to transmit"); - - return false; - } - instance->last_time_tx_data = furi_get_tick(); - -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "payload: %s", payload); -#endif - - while(!subghz_tx_rx_worker_write(instance->subghz_txrx, (uint8_t*)payload, strlen(payload))) { - furi_delay_ms(10); - } - - furi_hal_subghz_flush_tx(); - // Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); - // stream_clean(stream); - // stream_write_cstring(stream, payload); - // subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format); - - return true; -} - -// Init MANUAL -bool subbrute_worker_init_manual_transmit( - SubBruteWorker* instance, - uint32_t frequency, - FuriHalSubGhzPreset preset, - const char* protocol_name) { -#ifdef FURI_DEBUG - FURI_LOG_D( - TAG, - "subbrute_worker_init_manual_transmit. frequency: %d, protocol: %s", - frequency, - protocol_name); -#endif - if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance, false) || - instance->worker_running) { -#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); - } - - // Not transmit at this period - 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->frequency = frequency; - - string_clear(instance->protocol_name); - string_init_printf(instance->protocol_name, "%s", protocol_name); - - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(instance->preset); - - furi_hal_subghz_set_frequency_and_path(instance->frequency); - furi_hal_subghz_flush_rx(); - - /*if(!furi_hal_subghz_is_tx_allowed(frequency)) { - FURI_LOG_E(TAG, "Frequency: %d invalid!", frequency); - - instance->frequency = frequency; - instance->worker_manual_mode = false; - return false; - }*/ - -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Frequency: %d", frequency); -#endif - - instance->transmitter = subghz_transmitter_alloc_init( - 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); - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; - - 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; - } - - 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) { - FURI_LOG_W(TAG, "Worker was working for manual mode. Shutdown thread"); - 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_clean(stream); - stream_write_cstring(stream, payload); - - 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_load_preset(instance->preset); - instance->frequency = furi_hal_subghz_set_frequency_and_path(instance->frequency); - - furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); - - while(!furi_hal_subghz_is_async_tx_complete()) { - furi_delay_ms(SUBBRUTE_TX_TIMEOUT); - } - furi_hal_subghz_stop_async_tx(); - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; - - stream_clean(stream); - - instance->worker_manual_mode = false; - - return true; -} \ No newline at end of file diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h deleted file mode 100644 index d96fbdde2..000000000 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include - -typedef struct SubBruteWorker SubBruteWorker; -/** - * Same like SubGhzTxRxWorkerStatus in subghz_tx_rx_worker.h - * using just to not include that file - -typedef enum { - SubBruteWorkerStatusIDLE, - SubBruteWorkerStatusTx, - // SubBruteWorkerStatusRx, -} SubBruteWorkerStatus; - -//typedef void (*SubBruteWorkerCallback)(SubBruteWorkerStatus event, void* context); -*/ -SubBruteWorker* subbrute_worker_alloc(); -void subbrute_worker_free(SubBruteWorker* instance); -bool subbrute_worker_start( - SubBruteWorker* instance, - uint32_t frequency, - FuriHalSubGhzPreset preset, - const char* protocol_name); -void subbrute_worker_stop(SubBruteWorker* instance); -bool subbrute_worker_get_continuous_worker(SubBruteWorker* instance); -void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_continuous_worker); -//bool subbrute_worker_write(SubBruteWorker* instance, uint8_t* data, size_t size); -bool subbrute_worker_is_running(SubBruteWorker* instance); -bool subbrute_worker_can_transmit(SubBruteWorker* instance); -bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance, bool is_button_pressed); -bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload); -bool subbrute_worker_init_manual_transmit( - SubBruteWorker* instance, - uint32_t frequency, - FuriHalSubGhzPreset preset, - const char* protocol_name); -bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* payload); -void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance); \ No newline at end of file diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c index 05a7125e1..c2572a24c 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c @@ -1,6 +1,5 @@ #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" -#include +#include "subbrute_scene.h" #define TAG "SubBruteSceneLoadFile" @@ -40,7 +39,6 @@ void subbrute_scene_load_file_on_enter(void* context) { load_result = subbrute_device_attack_set(instance->device, SubBruteAttackLoadFile); if(load_result == SubBruteFileResultOk) { // Ready to run! - instance->device->state = SubBruteDeviceStateReady; FURI_LOG_I(TAG, "Ready to run"); res = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c index e3774e407..46021ba71 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c @@ -1,6 +1,5 @@ #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" -#include "../views/subbrute_main_view.h" +#include "subbrute_scene.h" #define TAG "SubBruteSceneStart" @@ -24,7 +23,7 @@ void subbrute_scene_load_select_on_enter(void* context) { 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->file_key); + subbrute_main_view_set_index(view, 7, true, subbrute_device_get_file_key(instance->device)); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); } @@ -42,10 +41,8 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeIndexSelected) { - instance->device->load_index = subbrute_main_view_get_index(instance->view_main); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "load_index: %d", instance->device->load_index); -#endif + subbrute_device_set_load_index( + instance->device, subbrute_main_view_get_index(instance->view_main)); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 385f43b9b..3d6bfde37 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -1,7 +1,7 @@ #include "../subbrute_i.h" +#include "subbrute_scene.h" #include "../subbrute_custom_event.h" #include "../views/subbrute_attack_view.h" -#include "../helpers/subbrute_worker.h" #define TAG "SubBruteSceneRunAttack" @@ -12,56 +12,25 @@ static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* view_dispatcher_send_custom_event(instance->view_dispatcher, event); } -//static void subbrute_scene_run_attack_worker_callback(void* context) { -// SubBruteState* instance = (SubBruteState*)context; -// -// if(instance->locked || instance->device->key_index + 1 > instance->device->max_value) { -// return; -// } -// instance->locked = true; -// -// if(subbrute_worker_can_manual_transmit(instance->worker)) { -// // Blink -// notification_message(instance->notifications, &sequence_blink_yellow_100); -// subbrute_device_create_packet_parsed(instance->device, instance->device->key_index, true); -// -//#ifdef FURI_DEBUG -// FURI_LOG_I(TAG, "subbrute_worker_manual_transmit"); -//#endif -// if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { -//#ifdef FURI_DEBUG -// FURI_LOG_I(TAG, "transmit ok"); -//#endif -// // Make payload for new iteration or exit -// if(instance->device->key_index + 1 <= instance->device->max_value) { -// instance->device->key_index++; -// } else { -// view_dispatcher_send_custom_event( -// instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); -// } -// } -// -// // Stop -// notification_message(instance->notifications, &sequence_blink_stop); -// } -// -// instance->locked = false; -// subbrute_attack_view_set_current_step(instance->view_attack, instance->device->key_index); -//} +static void + subbrute_scene_run_attack_device_state_changed(void* context, SubBruteDeviceState state) { + furi_assert(context); + SubBruteState* instance = (SubBruteState*)context; + + if(state == SubBruteDeviceStateIDLE) { + // Can't be IDLE on this step! + view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError); + } else if(state == SubBruteDeviceStateFinished) { + 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; - // SubBruteAttackState* state = (SubBruteAttackState*)scene_manager_get_scene_state( - // instance->scene_manager, SubBruteSceneRunAttack); - // furi_assert(state); - // - // furi_timer_free(state->timer); - // free(state); - if(subbrute_worker_get_continuous_worker(instance->worker)) { - subbrute_worker_stop(instance->worker); - } + subbrute_worker_stop(instance->device); notification_message(instance->notifications, &sequence_blink_stop); } @@ -70,124 +39,47 @@ void subbrute_scene_run_attack_on_enter(void* context) { furi_assert(context); SubBruteState* instance = (SubBruteState*)context; SubBruteAttackView* view = instance->view_attack; - // - // SubBruteAttackState* state = malloc(sizeof(SubBruteAttackState)); - // scene_manager_set_scene_state( - // instance->scene_manager, SubBruteSceneRunAttack, (uint32_t)state); 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_attack_view_init_values( - view, - (uint8_t)instance->device->attack, - instance->device->max_value, - instance->device->key_index, - true); + subbrute_device_set_callback( + instance->device, subbrute_scene_run_attack_device_state_changed, instance); - if(subbrute_worker_get_continuous_worker(instance->worker)) { - // Init Continuous worker with values! - if(!subbrute_worker_start( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { - FURI_LOG_W(TAG, "Worker Continuous init failed!"); - } - } else { - // Init worker with values - if(!subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { - FURI_LOG_W(TAG, "Worker init failed!"); - } - - // state->timer = furi_timer_alloc( - // subbrute_scene_run_attack_worker_callback, FuriTimerTypePeriodic, instance); - // furi_timer_start(state->timer, pdMS_TO_TICKS(100)); // 20 ms + if(!subbrute_device_is_worker_running(instance->device)) { + subbrute_worker_start(instance->device); } } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { SubBruteState* instance = (SubBruteState*)context; - // SubBruteAttackState* state = (SubBruteAttackState*)scene_manager_get_scene_state( - // instance->scene_manager, SubBruteSceneRunAttack); - // furi_assert(state); + SubBruteAttackView* view = instance->view_attack; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - SubBruteAttackView* view = instance->view_attack; + subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); - if(event.event == SubBruteCustomEventTypeTransmitNotStarted || - event.event == SubBruteCustomEventTypeTransmitFinished || - event.event == SubBruteCustomEventTypeBackPressed) { - // furi_timer_stop(state->timer); - // Stop transmit + if(event.event == SubBruteCustomEventTypeTransmitFinished) { notification_message(instance->notifications, &sequence_display_backlight_on); notification_message(instance->notifications, &sequence_single_vibro); - subbrute_attack_view_set_current_step(view, instance->device->key_index); + + scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); + } else if( + event.event == SubBruteCustomEventTypeTransmitNotStarted || + event.event == SubBruteCustomEventTypeBackPressed) { + // Stop transmit scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneSetupAttack); - consumed = true; + } else if(event.event == SubBruteCustomEventTypeError) { + notification_message(instance->notifications, &sequence_error); } else if(event.event == SubBruteCustomEventTypeUpdateView) { - subbrute_attack_view_set_current_step(view, instance->device->key_index); + //subbrute_attack_view_set_current_step(view, instance->device->key_index); } + consumed = true; } else if(event.type == SceneManagerEventTypeTick) { - if(subbrute_worker_get_continuous_worker(instance->worker)) { - if(subbrute_worker_can_transmit(instance->worker)) { - // Blink - notification_message(instance->notifications, &sequence_blink_yellow_100); - - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index, true); - - if(subbrute_worker_transmit(instance->worker, instance->device->payload)) { - // Make payload for new iteration or exit - if(instance->device->key_index + 1 > instance->device->max_value) { - // End of list - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); - } else { - instance->device->key_index++; - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); - //subbrute_attack_view_set_current_step(view, instance->device->key_index); - } - } - - // Stop - notification_message(instance->notifications, &sequence_blink_stop); - } - } else { - if(subbrute_worker_can_manual_transmit(instance->worker, false)) { - // Blink - notification_message(instance->notifications, &sequence_blink_yellow_100); - - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index, true); - - if(subbrute_worker_manual_transmit(instance->worker, instance->device->payload)) { - // Make payload for new iteration or exit - if(instance->device->key_index + 1 > instance->device->max_value) { - // End of list - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); - } else { - instance->device->key_index++; - view_dispatcher_send_custom_event( - instance->view_dispatcher, SubBruteCustomEventTypeUpdateView); - //subbrute_attack_view_set_current_step(view, instance->device->key_index); - } - } - - // Stop - notification_message(instance->notifications, &sequence_blink_stop); - } - } + subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); consumed = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c index 88a497db5..8b38ac246 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c @@ -1,35 +1,29 @@ -#include -#include -#include -#include -#include - #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" +#include "subbrute_scene.h" +#include #define TAG "SubBruteSceneSaveFile" void subbrute_scene_save_name_on_enter(void* context) { SubBruteState* instance = (SubBruteState*)context; - SubBruteDevice* device = instance->device; // Setup view TextInput* text_input = instance->text_input; - set_random_name(device->text_store, sizeof(device->text_store)); + 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, - device->text_store, + instance->text_store, SUBBRUTE_MAX_LEN_NAME, true); - string_set_str(device->load_path, SUBBRUTE_PATH); + string_set_str(instance->file_path, SUBBRUTE_PATH); ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(device->load_path), SUBBRUTE_FILE_EXT, ""); + validator_is_file_alloc_init(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); @@ -46,18 +40,14 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) { event.type == SceneManagerEventTypeCustom && event.event == SubBruteCustomEventTypeTextEditDone) { #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Saving: %s", instance->device->text_store); + FURI_LOG_D(TAG, "Saving: %s", instance->text_store); #endif bool success = false; - if(strcmp(instance->device->text_store, "")) { + if(strcmp(instance->text_store, "")) { string_cat_printf( - instance->device->load_path, - "/%s%s", - instance->device->text_store, - SUBBRUTE_FILE_EXT); + instance->file_path, "/%s%s", instance->text_store, SUBBRUTE_FILE_EXT); - if(subbrute_device_save_file( - instance->device, string_get_cstr(instance->device->load_path))) { + if(subbrute_device_save_file(instance->device, string_get_cstr(instance->file_path))) { scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveSuccess); success = true; consumed = true; @@ -83,5 +73,5 @@ void subbrute_scene_save_name_on_exit(void* context) { text_input_reset(instance->text_input); - string_reset(instance->device->load_path); + string_reset(instance->file_path); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c index f83c0c0fe..20b1a0de4 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_success.c @@ -1,5 +1,5 @@ #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" +#include "subbrute_scene.h" void subbrute_scene_save_success_on_enter(void* context) { furi_assert(context); diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index 2da28f672..b506a33d5 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -1,6 +1,5 @@ #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" -#include "../views/subbrute_attack_view.h" +#include "subbrute_scene.h" #define TAG "SubBruteSceneSetupAttack" @@ -11,28 +10,32 @@ static void subbrute_scene_setup_attack_callback(SubBruteCustomEvent event, void view_dispatcher_send_custom_event(instance->view_dispatcher, event); } +static void + subbrute_scene_setup_attack_device_state_changed(void* context, SubBruteDeviceState state) { + furi_assert(context); + + SubBruteState* instance = (SubBruteState*)context; + + if(state == SubBruteDeviceStateIDLE) { + // 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; #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Enter Attack: %d", instance->device->attack); + FURI_LOG_D(TAG, "Enter Attack: %d", subbrute_device_get_attack(instance->device)); #endif - subbrute_attack_view_init_values( - view, - instance->device->attack, - instance->device->max_value, - instance->device->key_index, - false); + subbrute_device_set_callback( + instance->device, subbrute_scene_setup_attack_device_state_changed, context); - if(!subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { - FURI_LOG_W(TAG, "Worker init failed!"); + if(subbrute_device_is_worker_running(instance->device)) { + subbrute_worker_stop(instance->device); } instance->current_view = SubBruteViewAttack; @@ -46,7 +49,7 @@ void subbrute_scene_setup_attack_on_exit(void* context) { FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit"); #endif SubBruteState* instance = (SubBruteState*)context; - subbrute_worker_manual_transmit_stop(instance->worker); + subbrute_worker_stop(instance->device); notification_message(instance->notifications, &sequence_blink_stop); } @@ -57,129 +60,60 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeTransmitStarted) { - subbrute_worker_set_continuous_worker(instance->worker, false); subbrute_attack_view_set_worker_type(view, false); scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); - } else if(event.event == SubBruteCustomEventTypeTransmitContinuousStarted) { - // Setting different type of worker - subbrute_worker_set_continuous_worker(instance->worker, true); - subbrute_attack_view_set_worker_type(view, true); - scene_manager_next_scene(instance->scene_manager, SubBruteSceneRunAttack); } else if(event.event == SubBruteCustomEventTypeSaveFile) { - subbrute_worker_manual_transmit_stop(instance->worker); - subbrute_attack_view_init_values( view, - instance->device->attack, - instance->device->max_value, - instance->device->key_index, + subbrute_device_get_attack(instance->device), + subbrute_device_get_max_value(instance->device), + subbrute_device_get_step(instance->device), false); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveName); } else if(event.event == SubBruteCustomEventTypeBackPressed) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "SubBruteCustomEventTypeBackPressed"); -#endif - instance->device->key_index = 0x00; - //subbrute_attack_view_stop_worker(view); + subbrute_device_reset_step(instance->device); subbrute_attack_view_init_values( view, - instance->device->attack, - instance->device->max_value, - instance->device->key_index, + subbrute_device_get_attack(instance->device), + subbrute_device_get_max_value(instance->device), + subbrute_device_get_step(instance->device), false); scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart); - } else if(event.event == SubBruteCustomEventTypeChangeStepUp) { - // +1 - if((instance->device->key_index + 1) - instance->device->max_value == 1) { - instance->device->key_index = 0x00; - } else { - uint64_t value = instance->device->key_index + 1; - if(value == instance->device->max_value) { - instance->device->key_index = value; - } else { - instance->device->key_index = value % instance->device->max_value; - } - } - subbrute_attack_view_set_current_step(view, instance->device->key_index); - } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) { - // +50 - uint64_t value = instance->device->key_index + 50; - if(value == instance->device->max_value) { - instance->device->key_index += value; - } else { - instance->device->key_index = value % instance->device->max_value; - } - subbrute_attack_view_set_current_step(view, instance->device->key_index); - } else if(event.event == SubBruteCustomEventTypeChangeStepDown) { - // -1 - if(instance->device->key_index - 1 == 0) { - instance->device->key_index = 0x00; - } else if(instance->device->key_index == 0) { - instance->device->key_index = instance->device->max_value; - } else { - uint64_t value = ((instance->device->key_index - 1) + instance->device->max_value); - if(value == instance->device->max_value) { - instance->device->key_index = value; - } else { - instance->device->key_index = value % instance->device->max_value; - } - } - subbrute_attack_view_set_current_step(view, instance->device->key_index); - } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) { - // -50 - uint64_t value = ((instance->device->key_index - 50) + instance->device->max_value); - if(value == instance->device->max_value) { - instance->device->key_index = value; - } else { - instance->device->key_index = value % instance->device->max_value; - } - subbrute_attack_view_set_current_step(view, instance->device->key_index); + } else if(event.event == SubBruteCustomEventTypeError) { + notification_message(instance->notifications, &sequence_error); } else if(event.event == SubBruteCustomEventTypeTransmitCustom) { - if(subbrute_worker_can_manual_transmit(instance->worker, true)) { + // We can transmit only in not working states + if(subbrute_device_can_manual_transmit(instance->device)) { + // MANUAL Transmit! // Blink notification_message(instance->notifications, &sequence_blink_green_100); - - // if(!subbrute_attack_view_is_worker_running(view)) { - // subbrute_attack_view_start_worker( - // view, - // instance->device->frequency, - // instance->device->preset, - // string_get_cstr(instance->device->protocol_name)); - // } - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index, false); - subbrute_worker_manual_transmit(instance->worker, instance->device->payload); - + subbrute_device_transmit_current_key(instance->device); // 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_attack_view_set_current_step(view, step); + } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) { + // +50 + uint64_t step = subbrute_device_add_step(instance->device, 50); + 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_attack_view_set_current_step(view, step); + } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) { + // -50 + uint64_t step = subbrute_device_add_step(instance->device, -50); + subbrute_attack_view_set_current_step(view, step); } + consumed = true; + } else if(event.type == SceneManagerEventTypeTick) { + subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); consumed = true; } - // if(event.type == SceneManagerEventTypeCustom) { - // switch(event.event) { - // case SubBruteCustomEventTypeMenuSelected: - // with_view_model( - // view, (SubBruteMainViewModel * model) { - // instance->menu_index = model->index; - // return false; - // }); - // scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadFile); - // consumed = true; - // break; - // case SubBruteCustomEventTypeLoadFile: - // with_view_model( - // view, (SubBruteMainViewModel * model) { - // instance->menu_index = model->index; - // return false; - // }); - // scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); - // consumed = true; - // break; - // } - // } - return consumed; -} \ No newline at end of file +} diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_start.c b/applications/plugins/subbrute/scenes/subbrute_scene_start.c index fe3a5d8b4..419fdc41c 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_start.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_start.c @@ -1,6 +1,5 @@ #include "../subbrute_i.h" -#include "../subbrute_custom_event.h" -#include "../views/subbrute_main_view.h" +#include "subbrute_scene.h" #define TAG "SubBruteSceneStart" @@ -24,7 +23,7 @@ void subbrute_scene_start_on_enter(void* context) { instance->current_view = SubBruteViewMain; subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance); - subbrute_main_view_set_index(view, instance->device->attack, false, NULL); + subbrute_main_view_set_index(view, subbrute_device_get_attack(instance->device), false, NULL); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); } diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index f9c6e67dc..f07febc43 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -1,55 +1,9 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "subbrute.h" #include "subbrute_i.h" #include "subbrute_custom_event.h" +#include "scenes/subbrute_scene.h" #define TAG "SubBruteApp" -static const char* subbrute_menu_names[] = { - [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz", - [SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz", - [SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz", - [SubBruteAttackNICE12bit433] = "NICE 12bit 433MHz", - [SubBruteAttackNICE12bit868] = "NICE 12bit 868MHz", - [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz", - [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz", - [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz", - [SubBruteAttackLinear10bit300] = "Linear 10bit 300MHz", - [SubBruteAttackLinear10bit310] = "Linear 10bit 310MHz", - [SubBruteAttackLoadFile] = "BF existing dump", - [SubBruteAttackTotalCount] = "Total Count", -}; - -static const char* subbrute_menu_names_small[] = { - [SubBruteAttackCAME12bit307] = "CAME 307MHz", - [SubBruteAttackCAME12bit433] = "CAME 433MHz", - [SubBruteAttackCAME12bit868] = "CAME 868MHz", - [SubBruteAttackNICE12bit433] = "NICE 433MHz", - [SubBruteAttackNICE12bit868] = "NICE 868MHz", - [SubBruteAttackChamberlain9bit300] = "Cham 300MHz", - [SubBruteAttackChamberlain9bit315] = "Cham 315MHz", - [SubBruteAttackChamberlain9bit390] = "Cham 390MHz", - [SubBruteAttackLinear10bit300] = "Linear 300MHz", - [SubBruteAttackLinear10bit310] = "Linear 310MHz", - [SubBruteAttackLoadFile] = "Existing", - [SubBruteAttackTotalCount] = "Total Count", -}; - static bool subbrute_custom_event_callback(void* context, uint32_t event) { furi_assert(context); SubBruteState* instance = context; @@ -71,6 +25,9 @@ static void subbrute_tick_event_callback(void* context) { SubBruteState* subbrute_alloc() { SubBruteState* instance = malloc(sizeof(SubBruteState)); + memset(instance->text_store, 0, sizeof(instance->text_store)); + string_init(instance->file_path); + instance->scene_manager = scene_manager_alloc(&subbrute_scene_handlers, instance); instance->view_dispatcher = view_dispatcher_alloc(); @@ -94,9 +51,6 @@ SubBruteState* subbrute_alloc() { // Devices instance->device = subbrute_device_alloc(); - // Worker - instance->worker = subbrute_worker_alloc(); - // TextInput instance->text_input = text_input_alloc(); view_dispatcher_add_view( @@ -144,17 +98,11 @@ SubBruteState* subbrute_alloc() { void subbrute_free(SubBruteState* instance) { furi_assert(instance); - // SubBruteWorker -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteDevice"); -#endif - subbrute_worker_stop(instance->worker); - subbrute_worker_free(instance->worker); - // SubBruteDevice #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free SubBruteDevice"); #endif + subbrute_worker_stop(instance->device); subbrute_device_free(instance->device); // Notifications @@ -239,6 +187,9 @@ void subbrute_free(SubBruteState* instance) { furi_record_close(RECORD_GUI); instance->gui = NULL; + string_clear(instance->file_path); + string_init(instance->file_path); + // The rest #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free instance"); @@ -277,18 +228,6 @@ void subbrute_popup_closed_callback(void* context) { instance->view_dispatcher, SubBruteCustomEventTypePopupClosed); } -const char* subbrute_get_menu_name(SubBruteAttacks index) { - furi_assert(index < SubBruteAttackTotalCount); - - return subbrute_menu_names[index]; -} - -const char* subbrute_get_small_menu_name(SubBruteAttacks index) { - furi_assert(index < SubBruteAttackTotalCount); - - return subbrute_menu_names_small[index]; -} - // ENTRYPOINT int32_t subbrute_app(void* p) { UNUSED(p); diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 800d8f5e0..8478a6750 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -10,7 +10,7 @@ typedef enum { SubBruteCustomEventTypeBackPressed, SubBruteCustomEventTypeIndexSelected, SubBruteCustomEventTypeTransmitStarted, - SubBruteCustomEventTypeTransmitContinuousStarted, + SubBruteCustomEventTypeError, SubBruteCustomEventTypeTransmitFinished, SubBruteCustomEventTypeTransmitNotStarted, SubBruteCustomEventTypeTransmitCustom, diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index d5712d96b..82dccafbb 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -1,64 +1,45 @@ #include "subbrute_device.h" -#include "subbrute_i.h" - -#include -#include -#include +#include #include -#include - -#include -#include - -#include -#include -#include #include -#include #include #define TAG "SubBruteDevice" -/** - * List of protocols - */ -static const char* protocol_came = "CAME"; -static const char* protocol_cham_code = "Cham_Code"; -static const char* protocol_linear = "Linear"; -static const char* protocol_nice_flo = "Nice FLO"; -static const char* protocol_princeton = "Princeton"; -static const char* protocol_raw = "RAW"; +#define SUBBRUTE_TX_TIMEOUT 5 +#define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 400 /** * Values to not use less memory for packet parse operations */ static const char* subbrute_key_file_start = "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d"; -static const char* subbrute_key_file_key = "%s\nKey: %s\n"; -static const char* subbrute_key_file_princeton_end = "%s\nKey: %s\nTE: %d\n"; -static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\n"; -static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\n"; - -// Why nobody set in as const in all codebase? -static const char* preset_ook270_async = "FuriHalSubGhzPresetOok270Async"; -static const char* preset_ook650_async = "FuriHalSubGhzPresetOok650Async"; -static const char* preset_2fsk_dev238_async = "FuriHalSubGhzPreset2FSKDev238Async"; -static const char* preset_2fsk_dev476_async = "FuriHalSubGhzPreset2FSKDev476Async"; -static const char* preset_msk99_97_kb_async = "FuriHalSubGhzPresetMSK99_97KbAsync"; -static const char* preset_gfs99_97_kb_async = "FuriHalSubGhzPresetGFS99_97KbAsync"; +static const char* subbrute_key_file_key = "%s\nKey: %s\nRepeat: %d\n"; +static const char* subbrute_key_file_key_with_tail = "%s\nKey: %s\nTE: %d\nRepeat: %d\n"; +static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\nRepeat: %d\n"; +static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; SubBruteDevice* subbrute_device_alloc() { SubBruteDevice* instance = malloc(sizeof(SubBruteDevice)); instance->state = SubBruteDeviceStateIDLE; instance->key_index = 0; + instance->worker_running = false; + instance->last_time_tx_data = 0; - string_init(instance->load_path); - string_init(instance->preset_name); - string_init(instance->protocol_name); + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); + furi_thread_set_stack_size(instance->thread, 2048); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, subbrute_worker_thread); + instance->context = NULL; + instance->callback = NULL; + + instance->protocol_info = NULL; instance->decoder_result = NULL; + instance->transmitter = NULL; instance->receiver = NULL; instance->environment = subghz_environment_alloc(); @@ -84,6 +65,11 @@ void subbrute_device_free(SubBruteDevice* instance) { instance->receiver = NULL; } + if(instance->transmitter != NULL) { + subghz_transmitter_free(instance->transmitter); + instance->transmitter = NULL; + } + subghz_environment_free(instance->environment); instance->environment = NULL; @@ -91,53 +77,623 @@ void subbrute_device_free(SubBruteDevice* instance) { FURI_LOG_D(TAG, "before free"); #endif - string_clear(instance->load_path); - string_clear(instance->preset_name); - string_clear(instance->protocol_name); + furi_thread_free(instance->thread); + subbrute_device_free_protocol_info(instance); free(instance); } +/** + * Entrypoint for worker + * + * @param context SubBruteWorker* + * @return 0 if ok + */ +int32_t subbrute_worker_thread(void* context) { + furi_assert(context); + SubBruteDevice* instance = (SubBruteDevice*)context; + + if(!instance->worker_running) { + FURI_LOG_W(TAG, "Worker is not set to running state!"); + return -1; + } + if(instance->state != SubBruteDeviceStateReady && + instance->state != SubBruteDeviceStateFinished) { + FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); + return -2; + } +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker start"); +#endif + + SubBruteDeviceState local_state = instance->state = SubBruteDeviceStateTx; + subbrute_device_send_callback(instance); + + FlipperFormat* flipper_format = flipper_format_string_alloc(); + + while(instance->worker_running) { + if(!subbrute_device_create_packet_parsed( + instance, flipper_format, instance->key_index, true)) { + FURI_LOG_W(TAG, "Error creating packet! BREAK"); + instance->worker_running = false; + local_state = SubBruteDeviceStateIDLE; + break; + } + subbrute_device_subghz_transmit(instance, flipper_format); + + if(instance->key_index + 1 > instance->max_value) { +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker finished to end"); +#endif + local_state = SubBruteDeviceStateFinished; + break; + } + instance->key_index++; + + furi_delay_ms(SUBBRUTE_TX_TIMEOUT); + } + + flipper_format_free(flipper_format); + + instance->worker_running = false; // Because we have error states + instance->state = local_state == SubBruteDeviceStateTx ? SubBruteDeviceStateReady : + local_state; + subbrute_device_send_callback(instance); + +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker stop"); +#endif + return 0; +} + +bool subbrute_worker_start(SubBruteDevice* instance) { + furi_assert(instance); + + if(instance->worker_running) { + FURI_LOG_W(TAG, "Worker is already running!"); + return false; + } + if(instance->state != SubBruteDeviceStateReady && + instance->state != SubBruteDeviceStateFinished) { + FURI_LOG_W(TAG, "Worker cannot start, invalid device state: %d", instance->state); + return false; + } + if(instance->protocol_info == NULL) { + FURI_LOG_W(TAG, "Worker cannot start, protocol_info is NULL!"); + return false; + } + + instance->worker_running = true; + furi_thread_start(instance->thread); + + return true; +} + +void subbrute_worker_stop(SubBruteDevice* instance) { + furi_assert(instance); + + instance->worker_running = false; + + furi_thread_join(instance->thread); + + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); +} + +SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance) { + return instance->attack; +} +bool subbrute_device_is_worker_running(SubBruteDevice* instance) { + return instance->worker_running; +} +uint64_t subbrute_device_get_step(SubBruteDevice* instance) { + return instance->key_index; +} +const char* subbrute_device_get_file_key(SubBruteDevice* instance) { + return instance->file_key; +} +uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step) { + if(!subbrute_device_can_manual_transmit(instance)) { + return instance->key_index; + } + if(step > 0) { + if((instance->key_index + step) - instance->max_value == 1) { + instance->key_index = 0x00; + } else { + uint64_t value = instance->key_index + step; + if(value == instance->max_value) { + instance->key_index = value; + } else { + instance->key_index = value % instance->max_value; + } + } + } else { + if(instance->key_index + step == 0) { + instance->key_index = 0x00; + } else if(instance->key_index == 0) { + instance->key_index = instance->max_value; + } else { + uint64_t value = ((instance->key_index - step) + instance->max_value); + if(value == instance->max_value) { + instance->key_index = value; + } else { + instance->key_index = value % instance->max_value; + } + } + } + + return instance->key_index; +} +void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index) { + instance->load_index = load_index; +} +void subbrute_device_reset_step(SubBruteDevice* instance) { + instance->key_index = 0x00; +} +void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format) { + instance->transmitter = subghz_transmitter_alloc_init( + instance->environment, subbrute_protocol_name(instance->attack)); + subghz_transmitter_deserialize(instance->transmitter, flipper_format); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(instance->protocol_info->preset); + furi_hal_subghz_set_frequency_and_path(instance->protocol_info->preset); + + furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); + + while(!furi_hal_subghz_is_async_tx_complete()) { + furi_delay_ms(SUBBRUTE_TX_TIMEOUT); + } + furi_hal_subghz_stop_async_tx(); + + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); + subghz_transmitter_free(instance->transmitter); + instance->transmitter = NULL; +} + +bool subbrute_device_transmit_current_key(SubBruteDevice* instance) { + furi_assert(instance); + + if(instance->worker_running) { + FURI_LOG_W(TAG, "Worker in running state!"); + return false; + } + if(instance->state != SubBruteDeviceStateReady && + instance->state != SubBruteDeviceStateFinished) { + FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); + return false; + } + + uint32_t ticks = furi_get_tick(); + if((ticks - instance->last_time_tx_data) < SUBBRUTE_MANUAL_TRANSMIT_INTERVAL) { +#if FURI_DEBUG + FURI_LOG_D(TAG, "Need to wait, current: %d", ticks - instance->last_time_tx_data); +#endif + return false; + } + + instance->last_time_tx_data = ticks; + FlipperFormat* flipper_format = flipper_format_string_alloc(); + + if(!subbrute_device_create_packet_parsed(instance, flipper_format, instance->key_index, true)) { + FURI_LOG_W(TAG, "Error creating packet! EXIT"); + return false; + } + subbrute_device_subghz_transmit(instance, flipper_format); + + flipper_format_free(flipper_format); + + return true; +} + +void subbrute_device_set_callback( + SubBruteDevice* instance, + SubBruteDeviceWorkerCallback callback, + void* context) { + furi_assert(instance); + + instance->callback = callback; + instance->context = context; +} + +bool subbrute_device_can_manual_transmit(SubBruteDevice* instance) { + furi_assert(instance); + + return !instance->worker_running && instance->state != SubBruteDeviceStateIDLE && + instance->state != SubBruteDeviceStateTx && + ((furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_MANUAL_TRANSMIT_INTERVAL); +} + bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_name) { furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_save_file: %s", dev_file_name); -#endif - bool result = subbrute_device_create_packet_parsed(instance, instance->key_index, false); - - if(!result) { - FURI_LOG_E(TAG, "subbrute_device_create_packet_parsed failed!"); - //subbrute_device_notification_message(instance, &sequence_error); + if(instance->state != SubBruteDeviceStateReady && + instance->state != SubBruteDeviceStateFinished) { + FURI_LOG_W(TAG, "Worker is not set to running state!"); return false; } - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* stream = buffered_file_stream_alloc(storage); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "subbrute_device_save_file: %s", dev_file_name); +#endif - result = false; + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + bool result = false; do { - if(!buffered_file_stream_open(stream, dev_file_name, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) { - buffered_file_stream_close(stream); + if(!flipper_format_file_open_always(file, dev_file_name)) { + break; + } + + if(!subbrute_device_create_packet_parsed(instance, file, instance->key_index, false)) { + FURI_LOG_E(TAG, "subbrute_device_create_packet_parsed failed!"); break; } - stream_write_cstring(stream, instance->payload); result = true; } while(false); - buffered_file_stream_close(stream); - stream_free(stream); if(!result) { - FURI_LOG_E(TAG, "stream_write_string failed!"); - //subbrute_device_notification_message(instance, &sequence_error); + FURI_LOG_E(TAG, "flipper_format_file_open_always failed!"); } + flipper_format_free(file); furi_record_close(RECORD_STORAGE); return result; } +bool subbrute_device_create_packet_parsed( + SubBruteDevice* instance, + FlipperFormat* flipper_format, + uint64_t step, + bool small) { + furi_assert(instance); + + string_t candidate; + string_init(candidate); + + if(instance->attack == SubBruteAttackLoadFile) { + if(step >= sizeof(instance->file_key)) { + return false; + } + char subbrute_payload_byte[4]; + string_set_str(candidate, instance->file_key); + snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); + string_replace_at(candidate, instance->load_index * 3, 3, subbrute_payload_byte); + //snprintf(step_payload, sizeof(step_payload), "%02X", (uint8_t)instance->file_key[step]); + } else { + //snprintf(step_payload, sizeof(step_payload), "%16X", step); + //snprintf(step_payload, sizeof(step_payload), "%016llX", step); + string_t buffer; + string_init(buffer); + string_init_printf(buffer, "%16X", step); + int j = 0; + string_set_str(candidate, " "); + for(uint8_t i = 0; i < 16; i++) { + if(string_get_char(buffer, i) != ' ') { + string_set_char(candidate, i + j, string_get_char(buffer, i)); + } else { + string_set_char(candidate, i + j, '0'); + } + if(i % 2 != 0) { + j++; + } + } + string_clear(buffer); + } + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "candidate: %s, step: %d", string_get_cstr(candidate), step); +#endif + + Stream* stream = flipper_format_get_raw_stream(flipper_format); + stream_clean(stream); + + if(small) { + if(instance->protocol_info->te) { + stream_write_format( + stream, + subbrute_key_small_with_tail, + instance->protocol_info->bits, + string_get_cstr(candidate), + instance->protocol_info->te, + instance->protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_small_no_tail, + instance->protocol_info->bits, + string_get_cstr(candidate), + instance->protocol_info->repeat); + } + } else { + if(instance->protocol_info->te) { + stream_write_format( + stream, + subbrute_key_file_key_with_tail, + instance->file_template, + string_get_cstr(candidate), + instance->protocol_info->te, + instance->protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_file_key, + instance->file_template, + string_get_cstr(candidate), + instance->protocol_info->repeat); + } + } +#ifdef FURI_DEBUG + //FURI_LOG_D(TAG, "payload: %s", instance->payload); +#endif + + string_clear(candidate); + + return true; +} + +SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBruteAttacks type) { + furi_assert(instance); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "subbrute_device_attack_set: %d", type); +#endif + subbrute_device_attack_set_default_values(instance, type); + + if(type != SubBruteAttackLoadFile) { + subbrute_device_free_protocol_info(instance); + instance->protocol_info = subbrute_protocol(type); + } + + // For non-file types we didn't set SubGhzProtocolDecoderBase + instance->receiver = subghz_receiver_alloc_init(instance->environment); + subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); + furi_hal_subghz_reset(); + + uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound; + if(type != SubBruteAttackLoadFile) { + instance->decoder_result = subghz_receiver_search_decoder_base_by_name( + instance->receiver, subbrute_protocol_file(instance->protocol_info->file)); + + if(!instance->decoder_result || + instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { + FURI_LOG_E(TAG, "Can't load SubGhzProtocolDecoderBase in phase non-file decoder set"); + } else { + protocol_check_result = SubBruteFileResultOk; + } + } else { + // And here we need to set preset enum + protocol_check_result = SubBruteFileResultOk; + } + + subghz_receiver_free(instance->receiver); + instance->receiver = NULL; + + if(protocol_check_result != SubBruteFileResultOk) { + return SubBruteFileResultProtocolNotFound; + } + + // Calc max value + if(instance->attack == SubBruteAttackLoadFile) { + instance->max_value = 0xFF; + } else { + string_t max_value_s; + string_init(max_value_s); + for(uint8_t i = 0; i < instance->protocol_info->bits; i++) { + string_cat_printf(max_value_s, "1"); + } + instance->max_value = (uint64_t)strtol(string_get_cstr(max_value_s), NULL, 2); + string_clear(max_value_s); + } + + // Now we are ready to set file template for using in the future with snprintf + // for sending attack payload + snprintf( + instance->file_template, + sizeof(instance->file_template), + subbrute_key_file_start, + instance->protocol_info->frequency, + subbrute_protocol_preset(instance->protocol_info->preset), + subbrute_protocol_file(instance->protocol_info->file), + instance->protocol_info->bits); +#ifdef FURI_DEBUG + FURI_LOG_D( + TAG, "tail: %d, file_template: %s", instance->protocol_info->te, instance->file_template); +#endif + + // Init payload + FlipperFormat* flipper_format = flipper_format_string_alloc(); + if(subbrute_device_create_packet_parsed(instance, flipper_format, instance->key_index, false)) { + instance->state = SubBruteDeviceStateReady; + subbrute_device_send_callback(instance); + } + flipper_format_free(flipper_format); + + return SubBruteFileResultOk; +} + +uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_path) { + furi_assert(instance); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "subbrute_device_load_from_file: %s", string_get_cstr(file_path)); +#endif + SubBruteFileResult result = SubBruteFileResultUnknown; + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + + string_t temp_str; + string_init(temp_str); + uint32_t temp_data32; + + instance->receiver = subghz_receiver_alloc_init(instance->environment); + subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); + furi_hal_subghz_reset(); + + do { + if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Error open file %s", string_get_cstr(file_path)); + result = SubBruteFileResultErrorOpenFile; + break; + } + if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { + FURI_LOG_E(TAG, "Missing or incorrect header"); + result = SubBruteFileResultMissingOrIncorrectHeader; + break; + } + + // Frequency + if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { + instance->protocol_info->frequency = temp_data32; + if(!furi_hal_subghz_is_tx_allowed(instance->protocol_info->frequency)) { + result = SubBruteFileResultFrequencyNotAllowed; + break; + } + } else { + FURI_LOG_E(TAG, "Missing or incorrect Frequency"); + result = SubBruteFileResultMissingOrIncorrectFrequency; + break; + } + + // Preset + if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { + FURI_LOG_E(TAG, "Preset FAIL"); + result = SubBruteFileResultPresetInvalid; + } else { + instance->protocol_info->preset = subbrute_protocol_convert_preset(temp_str); + } + + const char* protocol_file = NULL; + // Protocol + if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { + FURI_LOG_E(TAG, "Missing Protocol"); + result = SubBruteFileResultMissingProtocol; + break; + } else { + instance->protocol_info->file = subbrute_protocol_file_protocol_name(temp_str); + protocol_file = subbrute_protocol_file(instance->protocol_info->file); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Protocol: %s", protocol_file); +#endif + } + + instance->decoder_result = + subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_file); + + if(!instance->decoder_result || strcmp(protocol_file, "RAW") == 0) { + FURI_LOG_E(TAG, "RAW unsupported"); + result = SubBruteFileResultProtocolNotSupported; + break; + } + + if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { + FURI_LOG_E(TAG, "Protocol is dynamic - not supported"); + result = SubBruteFileResultDynamicProtocolNotValid; + break; + } +#ifdef FURI_DEBUG + else { + FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name); + } +#endif + + // Bit + if(!flipper_format_read_uint32(fff_data_file, "Bit", &temp_data32, 1)) { + FURI_LOG_E(TAG, "Missing or incorrect Bit"); + result = SubBruteFileResultMissingOrIncorrectBit; + break; + } else { + instance->protocol_info->bits = temp_data32; +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Bit: %d", instance->protocol_info->bits); +#endif + } + + // Key + if(!flipper_format_read_string(fff_data_file, "Key", temp_str)) { + FURI_LOG_E(TAG, "Missing or incorrect Key"); + result = SubBruteFileResultMissingOrIncorrectKey; + break; + } else { + snprintf( + instance->file_key, sizeof(instance->file_key), "%s", string_get_cstr(temp_str)); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Key: %s", instance->file_key); +#endif + } + + // TE + if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) { + FURI_LOG_E(TAG, "Missing or incorrect TE"); + //result = SubBruteFileResultMissingOrIncorrectTe; + //break; + } else { + instance->protocol_info->te = temp_data32 != 0; + } + + // Repeat + if(flipper_format_read_uint32(fff_data_file, "Repeat", &temp_data32, 1)) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Repeat: %d", temp_data32); +#endif + instance->protocol_info->repeat = (uint8_t)temp_data32; + } else { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Repeat: 3 (default)"); +#endif + instance->protocol_info->repeat = 3; + } + + result = SubBruteFileResultOk; + } while(0); + + string_clear(temp_str); + flipper_format_file_close(fff_data_file); + flipper_format_free(fff_data_file); + furi_record_close(RECORD_STORAGE); + + subghz_receiver_free(instance->receiver); + + instance->decoder_result = NULL; + instance->receiver = NULL; + + if(result == SubBruteFileResultOk) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "Loaded successfully"); +#endif + } + + return result; +} + +void subbrute_device_attack_set_default_values( + SubBruteDevice* instance, + SubBruteAttacks default_attack) { + furi_assert(instance); +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "subbrute_device_attack_set_default_values"); +#endif + instance->attack = default_attack; + instance->key_index = 0x00; + instance->load_index = 0x00; + memset(instance->file_template, 0, sizeof(instance->file_template)); + memset(instance->current_key, 0, sizeof(instance->current_key)); + + if(default_attack != SubBruteAttackLoadFile) { + memset(instance->file_key, 0, sizeof(instance->file_key)); + + instance->max_value = (uint64_t)0x00; + } +} + +void subbrute_device_send_callback(SubBruteDevice* instance) { + if(instance->callback != NULL) { + instance->callback(instance->context, instance->state); + } +} + const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { const char* result; switch(error_id) { @@ -186,470 +742,4 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { break; } return result; -} - -bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t step, bool small) { - furi_assert(instance); - - //char step_payload[32]; - //memset(step_payload, '0', sizeof(step_payload)); - memset(instance->payload, 0, sizeof(instance->payload)); - string_t candidate; - string_init(candidate); - - if(instance->attack == SubBruteAttackLoadFile) { - if(step >= sizeof(instance->file_key)) { - return false; - } - char subbrute_payload_byte[4]; - string_set_str(candidate, instance->file_key); - snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); - string_replace_at(candidate, instance->load_index * 3, 3, subbrute_payload_byte); - //snprintf(step_payload, sizeof(step_payload), "%02X", (uint8_t)instance->file_key[step]); - } else { - //snprintf(step_payload, sizeof(step_payload), "%16X", step); - //snprintf(step_payload, sizeof(step_payload), "%016llX", step); - string_t buffer; - string_init(buffer); - string_init_printf(buffer, "%16X", step); - int j = 0; - string_set_str(candidate, " "); - for(uint8_t i = 0; i < 16; i++) { - if(string_get_char(buffer, i) != ' ') { - string_set_char(candidate, i + j, string_get_char(buffer, i)); - } else { - string_set_char(candidate, i + j, '0'); - } - if(i % 2 != 0) { - j++; - } - } - string_clear(buffer); - } - -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s, step: %d", string_get_cstr(candidate), step); -#endif - - if(small) { - if(instance->has_tail) { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_small_with_tail, - instance->bit, - string_get_cstr(candidate), - instance->te); - } else { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_small_no_tail, - instance->bit, - string_get_cstr(candidate)); - } - } else { - if(instance->has_tail) { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_princeton_end, - instance->file_template, - string_get_cstr(candidate), - instance->te); - } else { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_key, - instance->file_template, - string_get_cstr(candidate)); - } - } - -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "payload: %s", instance->payload); -#endif - - string_clear(candidate); - - return true; -} - -SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBruteAttacks type) { - furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_attack_set: %d", type); -#endif - subbrute_device_attack_set_default_values(instance, type); - switch(type) { - case SubBruteAttackLoadFile: - // In this case values must be already set - // file_result = - // subbrute_device_load_from_file(instance, string_get_cstr(instance->load_path)); - // if(file_result != SubBruteFileResultOk) { - // // Failed load file so failed to set attack type - // return file_result; // RETURN - // } - break; - case SubBruteAttackCAME12bit307: - case SubBruteAttackCAME12bit433: - case SubBruteAttackCAME12bit868: - if(type == SubBruteAttackCAME12bit307) { - instance->frequency = 307800000; - } else if(type == SubBruteAttackCAME12bit433) { - instance->frequency = 433920000; - } else /* ALWAYS TRUE if(type == SubBruteAttackCAME12bit868) */ { - instance->frequency = 868350000; - } - instance->bit = 12; - string_set_str(instance->protocol_name, protocol_came); - string_set_str(instance->preset_name, preset_ook650_async); - break; - case SubBruteAttackChamberlain9bit300: - case SubBruteAttackChamberlain9bit315: - case SubBruteAttackChamberlain9bit390: - if(type == SubBruteAttackChamberlain9bit300) { - instance->frequency = 300000000; - } else if(type == SubBruteAttackChamberlain9bit315) { - instance->frequency = 315000000; - } else /* ALWAYS TRUE if(type == SubBruteAttackChamberlain9bit390) */ { - instance->frequency = 390000000; - } - instance->bit = 9; - string_set_str(instance->protocol_name, protocol_cham_code); - string_set_str(instance->preset_name, preset_ook650_async); - break; - case SubBruteAttackLinear10bit300: - instance->frequency = 300000000; - instance->bit = 10; - string_set_str(instance->protocol_name, protocol_linear); - string_set_str(instance->preset_name, preset_ook650_async); - break; - case SubBruteAttackLinear10bit310: - instance->frequency = 310000000; - instance->bit = 10; - string_set_str(instance->protocol_name, protocol_linear); - string_set_str(instance->preset_name, preset_ook650_async); - break; - case SubBruteAttackNICE12bit433: - instance->frequency = 433920000; - instance->bit = 12; - string_set_str(instance->protocol_name, protocol_nice_flo); - string_set_str(instance->preset_name, preset_ook650_async); - break; - case SubBruteAttackNICE12bit868: - instance->frequency = 868350000; - instance->bit = 12; - string_set_str(instance->protocol_name, protocol_nice_flo); - string_set_str(instance->preset_name, preset_ook650_async); - break; - default: - FURI_LOG_E(TAG, "Unknown attack type: %d", type); - return SubBruteFileResultProtocolNotFound; // RETURN - } - - /*if(!furi_hal_subghz_is_tx_allowed(instance->frequency)) { - FURI_LOG_E(TAG, "Frequency invalid: %d", instance->frequency); - return SubBruteFileResultMissingOrIncorrectFrequency; // RETURN - }*/ - - // For non-file types we didn't set SubGhzProtocolDecoderBase - instance->receiver = subghz_receiver_alloc_init(instance->environment); - subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); - furi_hal_subghz_reset(); - - uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound; - if(type != SubBruteAttackLoadFile) { - instance->decoder_result = subghz_receiver_search_decoder_base_by_name( - instance->receiver, string_get_cstr(instance->protocol_name)); - - if(!instance->decoder_result || - instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { - FURI_LOG_E(TAG, "Can't load SubGhzProtocolDecoderBase in phase non-file decoder set"); - } else { - protocol_check_result = SubBruteFileResultOk; - } - } else { - // And here we need to set preset enum - instance->preset = subbrute_device_convert_preset(string_get_cstr(instance->preset_name)); - protocol_check_result = SubBruteFileResultOk; - } - - subghz_receiver_free(instance->receiver); - instance->receiver = NULL; - - if(protocol_check_result != SubBruteFileResultOk) { - return SubBruteFileResultProtocolNotFound; - } - - instance->has_tail = - (strcmp(string_get_cstr(instance->protocol_name), protocol_princeton) == 0); - - // Calc max value - if(instance->attack == SubBruteAttackLoadFile) { - instance->max_value = 0xFF; - } else { - string_t max_value_s; - string_init(max_value_s); - for(uint8_t i = 0; i < instance->bit; i++) { - string_cat_printf(max_value_s, "1"); - } - instance->max_value = (uint64_t)strtol(string_get_cstr(max_value_s), NULL, 2); - string_clear(max_value_s); - } - - // Now we are ready to set file template for using in the future with snprintf - // for sending attack payload - snprintf( - instance->file_template, - sizeof(instance->file_template), - subbrute_key_file_start, - instance->frequency, - string_get_cstr(instance->preset_name), - string_get_cstr(instance->protocol_name), - instance->bit); -// strncat(instance->file_template, "\n", sizeof(instance->file_template)); -// strncat(instance->file_template, subbrute_key_file_key, sizeof(instance->file_template)); -// if(instance->has_tail) { -// strncat( -// instance->file_template, -// subbrute_key_file_princeton_end, -// sizeof(instance->file_template)); -// } -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "tail: %d, file_template: %s", instance->has_tail, instance->file_template); -#endif - - // Init payload - subbrute_device_create_packet_parsed(instance, instance->key_index, false); - - return SubBruteFileResultOk; -} - -uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_path) { - furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_load_from_file: %s", string_get_cstr(file_path)); -#endif - SubBruteFileResult result = SubBruteFileResultUnknown; - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - - string_t temp_str; - string_init(temp_str); - uint32_t temp_data32; - - instance->receiver = subghz_receiver_alloc_init(instance->environment); - subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); - furi_hal_subghz_reset(); - - do { - if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_path))) { - FURI_LOG_E(TAG, "Error open file %s", string_get_cstr(file_path)); - result = SubBruteFileResultErrorOpenFile; - break; - } - if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - result = SubBruteFileResultMissingOrIncorrectHeader; - break; - } - - // Frequency - if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { - instance->frequency = temp_data32; - if(!furi_hal_subghz_is_tx_allowed(instance->frequency)) { - result = SubBruteFileResultFrequencyNotAllowed; - break; - } - } else { - FURI_LOG_E(TAG, "Missing or incorrect Frequency"); - result = SubBruteFileResultMissingOrIncorrectFrequency; - break; - } - // Preset - if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { - FURI_LOG_E(TAG, "Preset FAIL"); - result = SubBruteFileResultPresetInvalid; - } else { - string_init_set_str(instance->preset_name, string_get_cstr(temp_str)); - } - - // Protocol - if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - result = SubBruteFileResultMissingProtocol; - break; - } else { - string_init_set_str(instance->protocol_name, string_get_cstr(temp_str)); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Protocol: %s", string_get_cstr(instance->protocol_name)); -#endif - } - - instance->decoder_result = subghz_receiver_search_decoder_base_by_name( - instance->receiver, string_get_cstr(instance->protocol_name)); - - if(!instance->decoder_result || - strcmp(string_get_cstr(instance->protocol_name), "RAW") == 0) { - FURI_LOG_E(TAG, "RAW unsupported"); - result = SubBruteFileResultProtocolNotSupported; - break; - } - - if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { - FURI_LOG_E(TAG, "Protocol is dynamic - not supported"); - result = SubBruteFileResultDynamicProtocolNotValid; - break; - } -#ifdef FURI_DEBUG - else { - FURI_LOG_D(TAG, "Decoder: %s", instance->decoder_result->protocol->name); - } -#endif - - // instance->decoder_result = subghz_receiver_search_decoder_base_by_name( - // instance->receiver, string_get_cstr(instance->protocol_name)); - // - // if(!instance->decoder_result) { - // FURI_LOG_E(TAG, "Protocol not found"); - // result = SubBruteFileResultProtocolNotFound; - // break; - // } - - // Bit - if(!flipper_format_read_uint32(fff_data_file, "Bit", &temp_data32, 1)) { - FURI_LOG_E(TAG, "Missing or incorrect Bit"); - result = SubBruteFileResultMissingOrIncorrectBit; - break; - } else { - instance->bit = temp_data32; -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Bit: %d", instance->bit); -#endif - } - - // Key - if(!flipper_format_read_string(fff_data_file, "Key", temp_str)) { - FURI_LOG_E(TAG, "Missing or incorrect Key"); - result = SubBruteFileResultMissingOrIncorrectKey; - break; - } else { - snprintf( - instance->file_key, sizeof(instance->file_key), "%s", string_get_cstr(temp_str)); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Key: %s", instance->file_key); -#endif - } - - // TE - if(!flipper_format_read_uint32(fff_data_file, "TE", &temp_data32, 1)) { - FURI_LOG_E(TAG, "Missing or incorrect TE"); - //result = SubBruteFileResultMissingOrIncorrectTe; - //break; - } else { - instance->te = temp_data32; - instance->has_tail = true; - } - - // Repeat - if(flipper_format_read_uint32(fff_data_file, "Repeat", &temp_data32, 1)) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Repeat: %d", temp_data32); -#endif - instance->repeat = temp_data32; - } else { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Repeat: 3 (default)"); -#endif - instance->repeat = 3; - } - - result = SubBruteFileResultOk; - } while(0); - - string_clear(temp_str); - flipper_format_file_close(fff_data_file); - flipper_format_free(fff_data_file); - furi_record_close(RECORD_STORAGE); - - subghz_receiver_free(instance->receiver); - - instance->decoder_result = NULL; - instance->receiver = NULL; - - if(result == SubBruteFileResultOk) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Loaded successfully"); -#endif - } - - return result; -} - -void subbrute_device_attack_set_default_values( - SubBruteDevice* instance, - SubBruteAttacks default_attack) { - furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_attack_set_default_values"); -#endif - instance->attack = default_attack; - instance->key_index = 0x00; - instance->load_index = 0x00; - memset(instance->file_template, 0, sizeof(instance->file_template)); - memset(instance->current_key, 0, sizeof(instance->current_key)); - memset(instance->text_store, 0, sizeof(instance->text_store)); - memset(instance->payload, 0, sizeof(instance->payload)); - - if(default_attack != SubBruteAttackLoadFile) { - memset(instance->file_key, 0, sizeof(instance->file_key)); - - instance->max_value = (uint64_t)0x00; - - string_clear(instance->protocol_name); - string_clear(instance->preset_name); - - string_clear(instance->load_path); - string_init(instance->load_path); - - string_init_set_str(instance->protocol_name, protocol_raw); - string_init_set_str(instance->preset_name, preset_ook650_async); - instance->preset = FuriHalSubGhzPresetOok650Async; - - instance->repeat = 5; - instance->te = 0; - instance->has_tail = false; - } -#ifdef FURI_DEBUG - FURI_LOG_D( - TAG, "subbrute_device_attack_set_default_values done. has_tail: %d", instance->has_tail); - //furi_delay_ms(250); -#endif -} - -FuriHalSubGhzPreset subbrute_device_convert_preset(const char* preset_name) { - string_t preset; - string_init_set_str(preset, preset_name); - FuriHalSubGhzPreset preset_value; - if(string_cmp_str(preset, preset_ook270_async) == 0) { - preset_value = FuriHalSubGhzPresetOok270Async; - } else if(string_cmp_str(preset, preset_ook650_async) == 0) { - preset_value = FuriHalSubGhzPresetOok650Async; - } else if(string_cmp_str(preset, preset_2fsk_dev238_async) == 0) { - preset_value = FuriHalSubGhzPreset2FSKDev238Async; - } else if(string_cmp_str(preset, preset_2fsk_dev476_async) == 0) { - preset_value = FuriHalSubGhzPreset2FSKDev476Async; - } else if(string_cmp_str(preset, preset_msk99_97_kb_async) == 0) { - preset_value = FuriHalSubGhzPresetMSK99_97KbAsync; - } else if(string_cmp_str(preset, preset_gfs99_97_kb_async) == 0) { - preset_value = FuriHalSubGhzPresetMSK99_97KbAsync; - } else { - preset_value = FuriHalSubGhzPresetCustom; - } - - string_clear(preset); - return preset_value; -} +} \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 46a1d2598..f2f30d401 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -1,102 +1,58 @@ #pragma once -#include -#include -#include +#include "subbrute_device_i.h" #include #include #include #include -#define SUBBRUTE_TEXT_STORE_SIZE 256 - -#define SUBBRUTE_MAX_LEN_NAME 64 -#define SUBBRUTE_PATH EXT_PATH("subghz") -#define SUBBRUTE_FILE_EXT ".sub" - -#define SUBBRUTE_PAYLOAD_SIZE 16 - -typedef enum { - SubBruteAttackCAME12bit307, - SubBruteAttackCAME12bit433, - SubBruteAttackCAME12bit868, - SubBruteAttackNICE12bit433, - SubBruteAttackNICE12bit868, - SubBruteAttackChamberlain9bit300, - SubBruteAttackChamberlain9bit315, - SubBruteAttackChamberlain9bit390, - SubBruteAttackLinear10bit300, - SubBruteAttackLinear10bit310, - SubBruteAttackLoadFile, - SubBruteAttackTotalCount, -} SubBruteAttacks; - -typedef enum { - SubBruteFileResultUnknown, - SubBruteFileResultOk, - SubBruteFileResultErrorOpenFile, - SubBruteFileResultMissingOrIncorrectHeader, - SubBruteFileResultFrequencyNotAllowed, - SubBruteFileResultMissingOrIncorrectFrequency, - SubBruteFileResultPresetInvalid, - SubBruteFileResultMissingProtocol, - SubBruteFileResultProtocolNotSupported, - SubBruteFileResultDynamicProtocolNotValid, - SubBruteFileResultProtocolNotFound, - SubBruteFileResultMissingOrIncorrectBit, - SubBruteFileResultMissingOrIncorrectKey, - SubBruteFileResultMissingOrIncorrectTe, -} SubBruteFileResult; - -typedef enum { - SubBruteDeviceStateIDLE, - SubBruteDeviceStateReady, - SubBruteDeviceStateTx, - SubBruteDeviceStateFinished, -} SubBruteDeviceState; - -typedef struct { +struct SubBruteDevice { SubBruteDeviceState state; + SubBruteProtocol* protocol_info; + volatile bool worker_running; // Current step uint64_t key_index; - string_t load_path; // Index of group to bruteforce in loaded file uint8_t load_index; + // SubGhz + FuriThread* thread; SubGhzReceiver* receiver; SubGhzProtocolDecoderBase* decoder_result; SubGhzEnvironment* environment; + SubGhzTransmitter* transmitter; // Attack state SubBruteAttacks attack; char file_template[SUBBRUTE_TEXT_STORE_SIZE]; - bool has_tail; - char payload[SUBBRUTE_TEXT_STORE_SIZE * 2]; + uint64_t max_value; // Loaded info for attack type - FuriHalSubGhzPreset preset; - string_t preset_name; - string_t protocol_name; - uint32_t frequency; - uint32_t repeat; - uint32_t bit; char current_key[SUBBRUTE_PAYLOAD_SIZE]; - uint32_t te; - char file_key[SUBBRUTE_MAX_LEN_NAME]; - char text_store[SUBBRUTE_PAYLOAD_SIZE]; -} SubBruteDevice; -SubBruteDevice* subbrute_device_alloc(); -void subbrute_device_free(SubBruteDevice* instance); -bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); -const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); -bool subbrute_device_create_packet_parsed(SubBruteDevice* context, uint64_t step, bool small); -SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); -uint8_t subbrute_device_load_from_file(SubBruteDevice* context, string_t file_path); -FuriHalSubGhzPreset subbrute_device_convert_preset(const char* preset); + // Manual transmit + uint32_t last_time_tx_data; + + // Callback for changed states + SubBruteDeviceWorkerCallback callback; + void* context; +}; + +/* + * PRIVATE METHODS + */ +void subbrute_device_free_protocol_info(SubBruteDevice* instance); +int32_t subbrute_worker_thread(void* context); void subbrute_device_attack_set_default_values( SubBruteDevice* context, - SubBruteAttacks default_attack); \ No newline at end of file + SubBruteAttacks default_attack); +bool subbrute_device_create_packet_parsed( + SubBruteDevice* instance, + FlipperFormat* flipper_format, + uint64_t step, + bool small); +void subbrute_device_send_callback(SubBruteDevice* instance); +void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_device_i.h b/applications/plugins/subbrute/subbrute_device_i.h new file mode 100644 index 000000000..02b934ba7 --- /dev/null +++ b/applications/plugins/subbrute/subbrute_device_i.h @@ -0,0 +1,64 @@ +#pragma once + +#include "subbrute_protocols.h" + +#define SUBBRUTE_TEXT_STORE_SIZE 256 + +#define SUBBRUTE_MAX_LEN_NAME 64 +#define SUBBRUTE_PATH EXT_PATH("subghz") +#define SUBBRUTE_FILE_EXT ".sub" + +#define SUBBRUTE_PAYLOAD_SIZE 16 + +typedef enum { + SubBruteFileResultUnknown, + SubBruteFileResultOk, + SubBruteFileResultErrorOpenFile, + SubBruteFileResultMissingOrIncorrectHeader, + SubBruteFileResultFrequencyNotAllowed, + SubBruteFileResultMissingOrIncorrectFrequency, + SubBruteFileResultPresetInvalid, + SubBruteFileResultMissingProtocol, + SubBruteFileResultProtocolNotSupported, + SubBruteFileResultDynamicProtocolNotValid, + SubBruteFileResultProtocolNotFound, + SubBruteFileResultMissingOrIncorrectBit, + SubBruteFileResultMissingOrIncorrectKey, + SubBruteFileResultMissingOrIncorrectTe, +} SubBruteFileResult; + +typedef enum { + SubBruteDeviceStateIDLE, + SubBruteDeviceStateReady, + SubBruteDeviceStateTx, + SubBruteDeviceStateFinished +} SubBruteDeviceState; + +typedef void (*SubBruteDeviceWorkerCallback)(void* context, SubBruteDeviceState state); +typedef struct SubBruteDevice SubBruteDevice; + +SubBruteDevice* subbrute_device_alloc(); +void subbrute_device_free(SubBruteDevice* instance); +bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); +const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); +SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); +uint8_t subbrute_device_load_from_file(SubBruteDevice* context, string_t file_path); + + +bool subbrute_device_is_worker_running(SubBruteDevice* instance); +SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance); +uint64_t subbrute_device_get_max_value(SubBruteDevice* instance); +uint64_t subbrute_device_get_step(SubBruteDevice* instance); +uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step); +void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index); +void subbrute_device_reset_step(SubBruteDevice* instance); +const char* subbrute_device_get_file_key(SubBruteDevice* instance); + +bool subbrute_worker_start(SubBruteDevice* instance); +void subbrute_worker_stop(SubBruteDevice* instance); +bool subbrute_device_transmit_current_key(SubBruteDevice* instance); +bool subbrute_device_can_manual_transmit(SubBruteDevice* instance); +void subbrute_device_set_callback( + SubBruteDevice* instance, + SubBruteDeviceWorkerCallback callback, + void* context); diff --git a/applications/plugins/subbrute/subbrute_i.h b/applications/plugins/subbrute/subbrute_i.h index 28a9a73e3..1e6498c62 100644 --- a/applications/plugins/subbrute/subbrute_i.h +++ b/applications/plugins/subbrute/subbrute_i.h @@ -4,14 +4,10 @@ #include #include -#include "lib/toolbox/path.h" #include #include #include -#include -#include - #include #include #include @@ -23,17 +19,11 @@ #include -#include -#include -#include -#include #include #include -#include "subbrute_device.h" -#include "helpers/subbrute_worker.h" #include "subbrute.h" -#include "scenes/subbrute_scene.h" +#include "subbrute_device_i.h" #include "views/subbrute_attack_view.h" #include "views/subbrute_main_view.h" @@ -60,6 +50,10 @@ struct SubBruteState { DialogsApp* dialogs; Loading* loading; + // Text store + char text_store[SUBBRUTE_MAX_LEN_NAME]; + string_t file_path; + // Views SubBruteMainView* view_main; SubBruteAttackView* view_attack; @@ -68,16 +62,10 @@ struct SubBruteState { // Scene SceneManager* scene_manager; + // SubBruteDevice SubBruteDevice* device; - SubBruteWorker* worker; - - //Menu stuff - // TODO: Do we need it? - uint8_t menu_index; }; void subbrute_show_loading_popup(void* context, bool show); void subbrute_text_input_callback(void* context); -void subbrute_popup_closed_callback(void* context); -const char* subbrute_get_menu_name(uint8_t index); -const char* subbrute_get_small_menu_name(uint8_t index); \ No newline at end of file +void subbrute_popup_closed_callback(void* context); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c new file mode 100644 index 000000000..3d857233b --- /dev/null +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -0,0 +1,127 @@ +#include "subbrute_protocols.h" + +static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { + [SubBruteAttackCAME12bit307] = + {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, + [SubBruteAttackCAME12bit433] = + {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, + [SubBruteAttackCAME12bit868] = + {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, + [SubBruteAttackNICE12bit433] = + {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, + [SubBruteAttackNICE12bit868] = + {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, + [SubBruteAttackChamberlain9bit300] = + {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, + [SubBruteAttackChamberlain9bit315] = + {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, + [SubBruteAttackChamberlain9bit390] = + {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, + [SubBruteAttackLinear10bit300] = + {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, + [SubBruteAttackLinear10bit310] = + {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, + [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}, +}; +//static const uint32_t subbrute_protocols[SubBruteAttackTotalCount][TotalProtocolFields] = { +// [SubBruteAttackCAME12bit307] = {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackCAME12bit433] = {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackCAME12bit868] = {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackNICE12bit433] = {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, +// [SubBruteAttackNICE12bit868] = {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, +// [SubBruteAttackChamberlain9bit300] = {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackChamberlain9bit315] = {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackChamberlain9bit390] = {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackLinear10bit300] = {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, +// [SubBruteAttackLinear10bit310] = {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, +// [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}, +//}; + +static const char* subbrute_protocol_names[] = { + [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz", + [SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz", + [SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz", + [SubBruteAttackNICE12bit433] = "NICE 12bit 433MHz", + [SubBruteAttackNICE12bit868] = "NICE 12bit 868MHz", + [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz", + [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz", + [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz", + [SubBruteAttackLinear10bit300] = "Linear 10bit 300MHz", + [SubBruteAttackLinear10bit310] = "Linear 10bit 310MHz", + [SubBruteAttackLoadFile] = "BF existing dump", + [SubBruteAttackTotalCount] = "Total Count", +}; + +static const char* subbrute_protocol_presets[] = { + [FuriHalSubGhzPresetIDLE] = "FuriHalSubGhzPresetIDLE", + [FuriHalSubGhzPresetOok270Async] = "FuriHalSubGhzPresetOok270Async", + [FuriHalSubGhzPresetOok650Async] = "FuriHalSubGhzPresetOok650Async", + [FuriHalSubGhzPreset2FSKDev238Async] = "FuriHalSubGhzPreset2FSKDev238Async", + [FuriHalSubGhzPreset2FSKDev476Async] = "FuriHalSubGhzPreset2FSKDev476Async", + [FuriHalSubGhzPresetMSK99_97KbAsync] = "FuriHalSubGhzPresetMSK99_97KbAsync", + [FuriHalSubGhzPresetGFSK9_99KbAsync] = "FuriHalSubGhzPresetGFSK9_99KbAsync", +}; + +static const char* subbrute_protocol_file_types[TotalFileProtocol] = { + [CAMEFileProtocol] = "CAME", + [NICEFileProtocol] = "Nice FLO", + [ChamberlainFileProtocol] = "Cham_Code", + [LinearFileProtocol] = "Linear", + [PrincetonFileProtocol] = "Princeton", + [RAWFileProtocol] = "RAW"}; + +SubBruteProtocol* subbrute_protocol_alloc(void) { + SubBruteProtocol* protocol = malloc(sizeof(SubBruteProtocol)); + protocol->frequency = subbrute_protocols[SubBruteAttackLoadFile].frequency; + protocol->repeat = subbrute_protocols[SubBruteAttackLoadFile].repeat; + protocol->preset = subbrute_protocols[SubBruteAttackLoadFile].preset; + protocol->file = subbrute_protocols[SubBruteAttackLoadFile].file; + protocol->te = subbrute_protocols[SubBruteAttackLoadFile].te; + protocol->bits = subbrute_protocols[SubBruteAttackLoadFile].bits; + + return protocol; +} + +const char* subbrute_protocol_name(SubBruteAttacks index) { + return subbrute_protocol_names[index]; +} + +SubBruteProtocol* subbrute_protocol(SubBruteAttacks index) { + SubBruteProtocol* protocol = subbrute_protocol_alloc(); + protocol->frequency = subbrute_protocols[index].frequency; + protocol->repeat = subbrute_protocols[index].repeat; + protocol->preset = subbrute_protocols[index].preset; + protocol->file = subbrute_protocols[index].file; + protocol->te = subbrute_protocols[index].te; + protocol->bits = subbrute_protocols[index].bits; + + return protocol; +} + +const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset) { + return subbrute_protocol_presets[preset]; +} + +const char* subbrute_protocol_file(SubBruteFileProtocol protocol) { + return subbrute_protocol_file_types[protocol]; +} + +FuriHalSubGhzPreset subbrute_protocol_convert_preset(string_t preset_name) { + for(size_t i = FuriHalSubGhzPresetIDLE; i +#include +#include + +//typedef enum { +// FrequencyProtocolField, +// BitsProtocolField, +// HasTeProtocolField, +// RepeatProtocolField, +// PresetProtocolField, +// FileProtocolField, +// TotalProtocolFields +//} ProtocolFields; + +typedef enum { + CAMEFileProtocol, + NICEFileProtocol, + ChamberlainFileProtocol, + LinearFileProtocol, + PrincetonFileProtocol, + RAWFileProtocol, + TotalFileProtocol, +} SubBruteFileProtocol; + +typedef struct { + uint32_t frequency; + uint8_t bits; + uint8_t te; + uint8_t repeat; + FuriHalSubGhzPreset preset; + SubBruteFileProtocol file; +} SubBruteProtocol; + +SubBruteProtocol* subbrute_protocol_alloc(void); +SubBruteProtocol* subbrute_protocol(SubBruteAttacks index); +const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset); +const char* subbrute_protocol_file(SubBruteFileProtocol protocol); +FuriHalSubGhzPreset subbrute_protocol_convert_preset(string_t preset_name); +SubBruteFileProtocol subbrute_protocol_file_protocol_name(string_t name); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_protocols_i.h b/applications/plugins/subbrute/subbrute_protocols_i.h new file mode 100644 index 000000000..b7e5f1713 --- /dev/null +++ b/applications/plugins/subbrute/subbrute_protocols_i.h @@ -0,0 +1,18 @@ +#pragma once + +typedef enum { + SubBruteAttackCAME12bit307, + SubBruteAttackCAME12bit433, + SubBruteAttackCAME12bit868, + SubBruteAttackNICE12bit433, + SubBruteAttackNICE12bit868, + SubBruteAttackChamberlain9bit300, + SubBruteAttackChamberlain9bit315, + SubBruteAttackChamberlain9bit390, + SubBruteAttackLinear10bit300, + SubBruteAttackLinear10bit310, + SubBruteAttackLoadFile, + SubBruteAttackTotalCount, +} SubBruteAttacks; + +const char* subbrute_protocol_name(SubBruteAttacks index); \ No newline at end of file diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 562c30131..d3f618f5b 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -1,5 +1,6 @@ #include "subbrute_attack_view.h" #include "../subbrute_i.h" +#include "../subbrute_protocols_i.h" #include "assets_icons.h" #include @@ -350,7 +351,7 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { char buffer[26]; const char* attack_name = NULL; - attack_name = subbrute_get_menu_name(model->index); + attack_name = subbrute_protocol_name(model->index); // Title if(model->is_attacking) { canvas_set_color(canvas, ColorBlack); diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.h b/applications/plugins/subbrute/views/subbrute_attack_view.h index 2aa9c4012..b10f8b17b 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.h +++ b/applications/plugins/subbrute/views/subbrute_attack_view.h @@ -1,12 +1,12 @@ #pragma once +#include "../subbrute_custom_event.h" #include #include "assets_icons.h" #include #include #include #include -#include "../subbrute_custom_event.h" typedef void (*SubBruteAttackViewCallback)(SubBruteCustomEvent event, void* context); typedef struct SubBruteAttackView SubBruteAttackView; diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 1159a33b3..32eeeabb7 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -1,5 +1,6 @@ #include "subbrute_main_view.h" #include "../subbrute_i.h" +#include "../subbrute_protocols_i.h" #include #include @@ -123,7 +124,6 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { uint8_t item_position = position - model->window_position; if(item_position < items_on_screen) { - const char* str = subbrute_get_menu_name(position); if(m->index == position) { canvas_draw_str_aligned( canvas, @@ -131,7 +131,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, AlignLeft, AlignCenter, - str); + subbrute_protocol_name(position)); elements_frame( canvas, 1, 1 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, 124, 15); } else { @@ -141,7 +141,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, AlignLeft, AlignCenter, - str); + subbrute_protocol_name(position)); } } } From 7ec4cb4b7aa83c086fdee342488364a0f19b26ee Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Sat, 8 Oct 2022 02:24:19 +0400 Subject: [PATCH 02/14] Fix compile errors --- applications/main/application.fam | 14 ++-- .../scenes/subbrute_scene_load_file.c | 6 +- .../scenes/subbrute_scene_load_select.c | 3 - .../scenes/subbrute_scene_save_name.c | 13 ++-- applications/plugins/subbrute/subbrute.c | 8 +-- .../plugins/subbrute/subbrute_device.c | 40 ++++++------ .../plugins/subbrute/subbrute_device.h | 55 +++++++++------- .../plugins/subbrute/subbrute_device_i.h | 64 ------------------- applications/plugins/subbrute/subbrute_i.h | 4 +- .../plugins/subbrute/subbrute_protocols.c | 15 +++-- .../plugins/subbrute/subbrute_protocols.h | 24 +++++-- .../plugins/subbrute/subbrute_protocols_i.h | 18 ------ .../subbrute/views/subbrute_attack_view.c | 15 +---- .../subbrute/views/subbrute_main_view.c | 4 +- 14 files changed, 106 insertions(+), 177 deletions(-) delete mode 100644 applications/plugins/subbrute/subbrute_device_i.h delete mode 100644 applications/plugins/subbrute/subbrute_protocols_i.h diff --git a/applications/main/application.fam b/applications/main/application.fam index a3d310093..639640b72 100644 --- a/applications/main/application.fam +++ b/applications/main/application.fam @@ -4,17 +4,17 @@ App( apptype=FlipperAppType.METAPACKAGE, provides=[ "gpio", - "ibutton", - "infrared", - "lfrfid", - "nfc", + #"ibutton", + #"infrared", + #"lfrfid", + #"nfc", "subghz", - "bad_usb", - "u2f", + #"bad_usb", + #"u2f", "fap_loader", "archive", "clock", - "unirfremix", + #"unirfremix", ], ) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c index 911dd21c4..dc26403c3 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c @@ -34,7 +34,8 @@ void subbrute_scene_load_file_on_enter(void* context) { furi_string_get_cstr(app_folder)); #endif if(res) { - load_result = subbrute_device_load_from_file(instance->device, load_path); + load_result = + subbrute_device_load_from_file(instance->device, furi_string_get_cstr(load_path)); if(load_result == SubBruteFileResultOk) { load_result = subbrute_device_attack_set(instance->device, SubBruteAttackLoadFile); if(load_result == SubBruteFileResultOk) { @@ -51,8 +52,7 @@ void subbrute_scene_load_file_on_enter(void* context) { 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)); + 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( diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c index 46021ba71..e9fafd4da 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c @@ -7,9 +7,6 @@ void subbrute_scene_load_select_callback(SubBruteCustomEvent event, void* contex furi_assert(context); SubBruteState* instance = (SubBruteState*)context; -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_scene_load_select_callback"); -#endif view_dispatcher_send_custom_event(instance->view_dispatcher, event); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c index 937bf52ae..9a010a2ba 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c @@ -1,5 +1,6 @@ #include "../subbrute_i.h" #include "subbrute_scene.h" +#include #include #define TAG "SubBruteSceneSaveFile" @@ -20,10 +21,11 @@ void subbrute_scene_save_name_on_enter(void* context) { SUBBRUTE_MAX_LEN_NAME, true); - string_set_str(instance->file_path, SUBBRUTE_PATH); + furi_string_reset(instance->file_path); + furi_string_set_str(instance->file_path, SUBBRUTE_PATH); - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(instance->file_path), SUBBRUTE_FILE_EXT, ""); + 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); @@ -44,10 +46,11 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) { #endif bool success = false; if(strcmp(instance->text_store, "")) { + furi_string_reset(instance->file_path); furi_string_cat_printf( instance->file_path, "/%s%s", instance->text_store, SUBBRUTE_FILE_EXT); - if(subbrute_device_save_file(instance->device, string_get_cstr(instance->file_path))) { + 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; @@ -73,5 +76,5 @@ void subbrute_scene_save_name_on_exit(void* context) { text_input_reset(instance->text_input); - string_reset(instance->file_path); + furi_string_reset(instance->file_path); } diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index f07febc43..200b42c3c 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -26,7 +26,7 @@ SubBruteState* subbrute_alloc() { SubBruteState* instance = malloc(sizeof(SubBruteState)); memset(instance->text_store, 0, sizeof(instance->text_store)); - string_init(instance->file_path); + instance->file_path = furi_string_alloc(); instance->scene_manager = scene_manager_alloc(&subbrute_scene_handlers, instance); instance->view_dispatcher = view_dispatcher_alloc(); @@ -187,13 +187,9 @@ void subbrute_free(SubBruteState* instance) { furi_record_close(RECORD_GUI); instance->gui = NULL; - string_clear(instance->file_path); - string_init(instance->file_path); + furi_string_free(instance->file_path); // The rest -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free instance"); -#endif free(instance); } diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 0be231cf7..311b6eba2 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -1,8 +1,10 @@ #include "subbrute_device.h" +//#include "subbrute_device.h" -#include #include -#include +#include +#include +#include #include #define TAG "SubBruteDevice" @@ -50,17 +52,11 @@ SubBruteDevice* subbrute_device_alloc() { void subbrute_device_free(SubBruteDevice* instance) { furi_assert(instance); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_free"); -#endif // I don't know how to free this instance->decoder_result = NULL; if(instance->receiver != NULL) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subghz_receiver_free"); -#endif subghz_receiver_free(instance->receiver); instance->receiver = NULL; } @@ -73,10 +69,6 @@ void subbrute_device_free(SubBruteDevice* instance) { subghz_environment_free(instance->environment); instance->environment = NULL; -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "before free"); -#endif - furi_thread_free(instance->thread); subbrute_device_free_protocol_info(instance); @@ -186,6 +178,9 @@ SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance) { bool subbrute_device_is_worker_running(SubBruteDevice* instance) { return instance->worker_running; } +uint64_t subbrute_device_get_max_value(SubBruteDevice* instance) { + return instance->max_value; +} uint64_t subbrute_device_get_step(SubBruteDevice* instance) { return instance->key_index; } @@ -267,7 +262,7 @@ bool subbrute_device_transmit_current_key(SubBruteDevice* instance) { uint32_t ticks = furi_get_tick(); if((ticks - instance->last_time_tx_data) < SUBBRUTE_MANUAL_TRANSMIT_INTERVAL) { #if FURI_DEBUG - FURI_LOG_D(TAG, "Need to wait, current: %d", ticks - instance->last_time_tx_data); + FURI_LOG_D(TAG, "Need to wait, current: %ld", ticks - instance->last_time_tx_data); #endif return false; } @@ -403,7 +398,7 @@ bool subbrute_device_create_packet_parsed( stream, subbrute_key_small_no_tail, instance->protocol_info->bits, - string_get_cstr(candidate), + furi_string_get_cstr(candidate), instance->protocol_info->repeat); } } else { @@ -420,7 +415,7 @@ bool subbrute_device_create_packet_parsed( stream, subbrute_key_file_key, instance->file_template, - string_get_cstr(candidate), + furi_string_get_cstr(candidate), instance->protocol_info->repeat); } } @@ -512,10 +507,10 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute return SubBruteFileResultOk; } -uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, FuriString* file_path) { +uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* file_path) { furi_assert(instance); #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_device_load_from_file: %s", furi_string_get_cstr(file_path)); + FURI_LOG_D(TAG, "subbrute_device_load_from_file: %s", file_path); #endif SubBruteFileResult result = SubBruteFileResultUnknown; @@ -531,8 +526,8 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, FuriString* fil furi_hal_subghz_reset(); do { - if(!flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(file_path))) { - FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(file_path)); + if(!flipper_format_file_open_existing(fff_data_file, file_path)) { + FURI_LOG_E(TAG, "Error open file %s", file_path); result = SubBruteFileResultErrorOpenFile; break; } @@ -743,4 +738,11 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { break; } return result; +} + +void subbrute_device_free_protocol_info(SubBruteDevice* instance) { + furi_assert(instance); + + free(instance->protocol_info); + instance->protocol_info = NULL; } \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 801b3f635..bdcaa11bd 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -1,6 +1,6 @@ #pragma once -#include "subbrute_device_i.h" +#include "subbrute_protocols.h" #include #include #include @@ -14,22 +14,6 @@ #define SUBBRUTE_PAYLOAD_SIZE 16 -typedef enum { - SubBruteAttackCAME12bit303, - SubBruteAttackCAME12bit307, - SubBruteAttackCAME12bit433, - SubBruteAttackCAME12bit868, - SubBruteAttackNICE12bit433, - SubBruteAttackNICE12bit868, - SubBruteAttackChamberlain9bit300, - SubBruteAttackChamberlain9bit315, - SubBruteAttackChamberlain9bit390, - SubBruteAttackLinear10bit300, - SubBruteAttackLinear10bit310, - SubBruteAttackLoadFile, - SubBruteAttackTotalCount, -} SubBruteAttacks; - typedef enum { SubBruteFileResultUnknown, SubBruteFileResultOk, @@ -45,16 +29,16 @@ typedef enum { SubBruteFileResultMissingOrIncorrectBit, SubBruteFileResultMissingOrIncorrectKey, SubBruteFileResultMissingOrIncorrectTe, - SubBruteFileResultBigBitSize, } SubBruteFileResult; typedef enum { SubBruteDeviceStateIDLE, SubBruteDeviceStateReady, SubBruteDeviceStateTx, - SubBruteDeviceStateFinished, + SubBruteDeviceStateFinished } SubBruteDeviceState; +typedef void (*SubBruteDeviceWorkerCallback)(void* context, SubBruteDeviceState state); typedef struct { SubBruteDeviceState state; SubBruteProtocol* protocol_info; @@ -88,11 +72,34 @@ typedef struct { // Callback for changed states SubBruteDeviceWorkerCallback callback; void* context; -}; +} SubBruteDevice; + +SubBruteDevice* subbrute_device_alloc(); +void subbrute_device_free(SubBruteDevice* instance); + +bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); +const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); +SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); +uint8_t subbrute_device_load_from_file(SubBruteDevice* context, const char* file_path); + +bool subbrute_device_is_worker_running(SubBruteDevice* instance); +SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance); +uint64_t subbrute_device_get_max_value(SubBruteDevice* instance); +uint64_t subbrute_device_get_step(SubBruteDevice* instance); +uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step); +void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index); +void subbrute_device_reset_step(SubBruteDevice* instance); +const char* subbrute_device_get_file_key(SubBruteDevice* instance); + +bool subbrute_worker_start(SubBruteDevice* instance); +void subbrute_worker_stop(SubBruteDevice* instance); +bool subbrute_device_transmit_current_key(SubBruteDevice* instance); +bool subbrute_device_can_manual_transmit(SubBruteDevice* instance); +void subbrute_device_set_callback( + SubBruteDevice* instance, + SubBruteDeviceWorkerCallback callback, + void* context); -/* - * PRIVATE METHODS - */ void subbrute_device_free_protocol_info(SubBruteDevice* instance); int32_t subbrute_worker_thread(void* context); void subbrute_device_attack_set_default_values( @@ -104,4 +111,4 @@ bool subbrute_device_create_packet_parsed( uint64_t step, bool small); void subbrute_device_send_callback(SubBruteDevice* instance); -void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format); \ No newline at end of file +void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format); diff --git a/applications/plugins/subbrute/subbrute_device_i.h b/applications/plugins/subbrute/subbrute_device_i.h deleted file mode 100644 index 02b934ba7..000000000 --- a/applications/plugins/subbrute/subbrute_device_i.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "subbrute_protocols.h" - -#define SUBBRUTE_TEXT_STORE_SIZE 256 - -#define SUBBRUTE_MAX_LEN_NAME 64 -#define SUBBRUTE_PATH EXT_PATH("subghz") -#define SUBBRUTE_FILE_EXT ".sub" - -#define SUBBRUTE_PAYLOAD_SIZE 16 - -typedef enum { - SubBruteFileResultUnknown, - SubBruteFileResultOk, - SubBruteFileResultErrorOpenFile, - SubBruteFileResultMissingOrIncorrectHeader, - SubBruteFileResultFrequencyNotAllowed, - SubBruteFileResultMissingOrIncorrectFrequency, - SubBruteFileResultPresetInvalid, - SubBruteFileResultMissingProtocol, - SubBruteFileResultProtocolNotSupported, - SubBruteFileResultDynamicProtocolNotValid, - SubBruteFileResultProtocolNotFound, - SubBruteFileResultMissingOrIncorrectBit, - SubBruteFileResultMissingOrIncorrectKey, - SubBruteFileResultMissingOrIncorrectTe, -} SubBruteFileResult; - -typedef enum { - SubBruteDeviceStateIDLE, - SubBruteDeviceStateReady, - SubBruteDeviceStateTx, - SubBruteDeviceStateFinished -} SubBruteDeviceState; - -typedef void (*SubBruteDeviceWorkerCallback)(void* context, SubBruteDeviceState state); -typedef struct SubBruteDevice SubBruteDevice; - -SubBruteDevice* subbrute_device_alloc(); -void subbrute_device_free(SubBruteDevice* instance); -bool subbrute_device_save_file(SubBruteDevice* instance, const char* key_name); -const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); -SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); -uint8_t subbrute_device_load_from_file(SubBruteDevice* context, string_t file_path); - - -bool subbrute_device_is_worker_running(SubBruteDevice* instance); -SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance); -uint64_t subbrute_device_get_max_value(SubBruteDevice* instance); -uint64_t subbrute_device_get_step(SubBruteDevice* instance); -uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step); -void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index); -void subbrute_device_reset_step(SubBruteDevice* instance); -const char* subbrute_device_get_file_key(SubBruteDevice* instance); - -bool subbrute_worker_start(SubBruteDevice* instance); -void subbrute_worker_stop(SubBruteDevice* instance); -bool subbrute_device_transmit_current_key(SubBruteDevice* instance); -bool subbrute_device_can_manual_transmit(SubBruteDevice* instance); -void subbrute_device_set_callback( - SubBruteDevice* instance, - SubBruteDeviceWorkerCallback callback, - void* context); diff --git a/applications/plugins/subbrute/subbrute_i.h b/applications/plugins/subbrute/subbrute_i.h index bf8ab7ebc..02f91f93d 100644 --- a/applications/plugins/subbrute/subbrute_i.h +++ b/applications/plugins/subbrute/subbrute_i.h @@ -22,7 +22,7 @@ #include #include "subbrute.h" -#include "subbrute_device_i.h" +#include "subbrute_device.h" #include "views/subbrute_attack_view.h" #include "views/subbrute_main_view.h" @@ -51,7 +51,7 @@ struct SubBruteState { // Text store char text_store[SUBBRUTE_MAX_LEN_NAME]; - string_t file_path; + FuriString* file_path; // Views SubBruteMainView* view_main; diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index 3d857233b..3bedcb23c 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -1,6 +1,8 @@ #include "subbrute_protocols.h" static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { + [SubBruteAttackCAME12bit303] = + {303875000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, [SubBruteAttackCAME12bit307] = {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, [SubBruteAttackCAME12bit433] = @@ -38,6 +40,7 @@ static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { //}; static const char* subbrute_protocol_names[] = { + [SubBruteAttackCAME12bit303] = "CAME 12bit 303MHz", [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz", [SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz", [SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz", @@ -106,9 +109,9 @@ const char* subbrute_protocol_file(SubBruteFileProtocol protocol) { return subbrute_protocol_file_types[protocol]; } -FuriHalSubGhzPreset subbrute_protocol_convert_preset(string_t preset_name) { - for(size_t i = FuriHalSubGhzPresetIDLE; i -#include #include +#include //typedef enum { // FrequencyProtocolField, @@ -25,6 +24,22 @@ typedef enum { TotalFileProtocol, } SubBruteFileProtocol; +typedef enum { + SubBruteAttackCAME12bit303, + SubBruteAttackCAME12bit307, + SubBruteAttackCAME12bit433, + SubBruteAttackCAME12bit868, + SubBruteAttackNICE12bit433, + SubBruteAttackNICE12bit868, + SubBruteAttackChamberlain9bit300, + SubBruteAttackChamberlain9bit315, + SubBruteAttackChamberlain9bit390, + SubBruteAttackLinear10bit300, + SubBruteAttackLinear10bit310, + SubBruteAttackLoadFile, + SubBruteAttackTotalCount, +} SubBruteAttacks; + typedef struct { uint32_t frequency; uint8_t bits; @@ -38,5 +53,6 @@ SubBruteProtocol* subbrute_protocol_alloc(void); SubBruteProtocol* subbrute_protocol(SubBruteAttacks index); const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset); const char* subbrute_protocol_file(SubBruteFileProtocol protocol); -FuriHalSubGhzPreset subbrute_protocol_convert_preset(string_t preset_name); -SubBruteFileProtocol subbrute_protocol_file_protocol_name(string_t name); \ No newline at end of file +FuriHalSubGhzPreset subbrute_protocol_convert_preset(FuriString* preset_name); +SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name); +const char* subbrute_protocol_name(SubBruteAttacks index); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_protocols_i.h b/applications/plugins/subbrute/subbrute_protocols_i.h deleted file mode 100644 index b7e5f1713..000000000 --- a/applications/plugins/subbrute/subbrute_protocols_i.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -typedef enum { - SubBruteAttackCAME12bit307, - SubBruteAttackCAME12bit433, - SubBruteAttackCAME12bit868, - SubBruteAttackNICE12bit433, - SubBruteAttackNICE12bit868, - SubBruteAttackChamberlain9bit300, - SubBruteAttackChamberlain9bit315, - SubBruteAttackChamberlain9bit390, - SubBruteAttackLinear10bit300, - SubBruteAttackLinear10bit310, - SubBruteAttackLoadFile, - SubBruteAttackTotalCount, -} SubBruteAttacks; - -const char* subbrute_protocol_name(SubBruteAttacks index); \ No newline at end of file diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index da333a9a2..197cf8239 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -1,6 +1,6 @@ #include "subbrute_attack_view.h" #include "../subbrute_i.h" -#include "../subbrute_protocols_i.h" +#include "../subbrute_protocols.h" #include "assets_icons.h" #include @@ -299,10 +299,6 @@ void elements_button_top_left(Canvas* canvas, const char* str) { const uint8_t y = 0; canvas_draw_box(canvas, x, y, button_width, button_height); -#ifdef FURI_DEBUG - FURI_LOG_D( - TAG, "lbox, x: %d, y: %d, width: %d, height: %d", x, y, button_width, button_height); -#endif // canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y + button_height - 0); // // canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y + button_height - 1); // canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y + button_height - 2); @@ -330,15 +326,6 @@ void elements_button_top_right(Canvas* canvas, const char* str) { const uint8_t y = 0; canvas_draw_box(canvas, x - button_width, y, button_width, button_height); -#ifdef FURI_DEBUG - FURI_LOG_D( - TAG, - "rbox, x: %d, y: %d, width: %d, height: %d", - x - button_width, - y, - button_width, - button_height); -#endif // canvas_draw_line(canvas, x - button_width - 1, y, x + button_width - 1, y + button_height - 0); // canvas_draw_line(canvas, x - button_width - 2, y, x + button_width - 2, y + button_height - 1); // canvas_draw_line(canvas, x - button_width - 3, y, x + button_width - 3, y + button_height - 2); diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index e6a19d6f0..c3f56cae2 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -1,6 +1,6 @@ #include "subbrute_main_view.h" #include "../subbrute_i.h" -#include "../subbrute_protocols_i.h" +#include "../subbrute_protocols.h" #include #include @@ -86,7 +86,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { canvas_set_font(canvas, FontPrimary); canvas_draw_box(canvas, 0, 0, canvas_width(canvas), STATUS_BAR_Y_SHIFT); canvas_invert_color(canvas); - canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz Bruteforcer"); + canvas_draw_str_aligned(canvas, 64, 3, AlignCenter, AlignTop, "Sub-GHz BruteForcer v3"); canvas_invert_color(canvas); if(m->is_select_byte) { From 1adf76d54d4ef025f743a6f1ac2d6d7921e9ee2f Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Sat, 8 Oct 2022 02:25:22 +0400 Subject: [PATCH 03/14] Revert application.fam --- applications/main/application.fam | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/applications/main/application.fam b/applications/main/application.fam index 639640b72..a3d310093 100644 --- a/applications/main/application.fam +++ b/applications/main/application.fam @@ -4,17 +4,17 @@ App( apptype=FlipperAppType.METAPACKAGE, provides=[ "gpio", - #"ibutton", - #"infrared", - #"lfrfid", - #"nfc", + "ibutton", + "infrared", + "lfrfid", + "nfc", "subghz", - #"bad_usb", - #"u2f", + "bad_usb", + "u2f", "fap_loader", "archive", "clock", - #"unirfremix", + "unirfremix", ], ) From b86f42e7fbc372cf07fffcf54aa628aed0f6cd26 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Sat, 8 Oct 2022 21:53:31 +0400 Subject: [PATCH 04/14] Changed protocol info --- .../scenes/subbrute_scene_run_attack.c | 2 - .../scenes/subbrute_scene_save_name.c | 1 - applications/plugins/subbrute/subbrute.c | 63 +---- .../plugins/subbrute/subbrute_custom_event.h | 3 - .../plugins/subbrute/subbrute_device.c | 196 +++++++++------ .../plugins/subbrute/subbrute_device.h | 3 +- applications/plugins/subbrute/subbrute_i.h | 1 - .../plugins/subbrute/subbrute_protocols.c | 226 +++++++++++++----- .../plugins/subbrute/subbrute_protocols.h | 3 +- .../subbrute/views/subbrute_attack_view.c | 20 +- .../subbrute/views/subbrute_attack_view.h | 3 - .../subbrute/views/subbrute_main_view.c | 2 +- .../subbrute/views/subbrute_main_view.h | 2 - 13 files changed, 310 insertions(+), 215 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 3d6bfde37..b37ac34f9 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -1,7 +1,5 @@ #include "../subbrute_i.h" #include "subbrute_scene.h" -#include "../subbrute_custom_event.h" -#include "../views/subbrute_attack_view.h" #define TAG "SubBruteSceneRunAttack" diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c index 9a010a2ba..f0acb30df 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c @@ -1,6 +1,5 @@ #include "../subbrute_i.h" #include "subbrute_scene.h" -#include #include #define TAG "SubBruteSceneSaveFile" diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index 200b42c3c..0e226f9e4 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -40,7 +40,7 @@ SubBruteState* subbrute_alloc() { view_dispatcher_set_navigation_event_callback( instance->view_dispatcher, subbrute_back_event_callback); view_dispatcher_set_tick_event_callback( - instance->view_dispatcher, subbrute_tick_event_callback, 10); + instance->view_dispatcher, subbrute_tick_event_callback, 100); //Dialog instance->dialogs = furi_record_open(RECORD_DIALOGS); @@ -87,8 +87,6 @@ SubBruteState* subbrute_alloc() { SubBruteViewAttack, subbrute_attack_view_get_view(instance->view_attack)); - // Loading - instance->loading = loading_alloc(); //instance->flipper_format = flipper_format_string_alloc(); //instance->environment = subghz_environment_alloc(); @@ -99,91 +97,49 @@ void subbrute_free(SubBruteState* instance) { furi_assert(instance); // SubBruteDevice -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteDevice"); -#endif subbrute_worker_stop(instance->device); subbrute_device_free(instance->device); // Notifications -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free Notifications"); -#endif notification_message(instance->notifications, &sequence_blink_stop); furi_record_close(RECORD_NOTIFICATION); instance->notifications = NULL; - // Loading -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free loading"); -#endif - loading_free(instance->loading); - // View Main -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewMain"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewMain); subbrute_main_view_free(instance->view_main); // View Attack -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewAttack"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewAttack); subbrute_attack_view_free(instance->view_attack); // TextInput -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewTextInput"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewTextInput); text_input_free(instance->text_input); // Custom Widget -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewWidget"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewWidget); widget_free(instance->widget); // Popup -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewPopup"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewPopup); popup_free(instance->popup); // ViewStack -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free SubBruteViewStack"); -#endif view_dispatcher_remove_view(instance->view_dispatcher, SubBruteViewStack); view_stack_free(instance->view_stack); //Dialog -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free RECORD_DIALOGS"); -#endif furi_record_close(RECORD_DIALOGS); instance->dialogs = NULL; // Scene manager -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free scene_manager"); -#endif scene_manager_free(instance->scene_manager); // View Dispatcher -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free view_dispatcher"); -#endif view_dispatcher_free(instance->view_dispatcher); // GUI -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "free RECORD_GUI"); -#endif furi_record_close(RECORD_GUI); instance->gui = NULL; @@ -193,23 +149,6 @@ void subbrute_free(SubBruteState* instance) { free(instance); } -void subbrute_show_loading_popup(void* context, bool show) { - TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME); - SubBruteState* instance = context; - ViewStack* view_stack = instance->view_stack; - Loading* loading = instance->loading; - - if(show) { - // Raise timer priority so that animations can play - vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1); - view_stack_add_view(view_stack, loading_get_view(loading)); - } else { - view_stack_remove_view(view_stack, loading_get_view(loading)); - // Restore default timer priority - vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY); - } -} - void subbrute_text_input_callback(void* context) { furi_assert(context); SubBruteState* instance = context; diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 8478a6750..2864f8934 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -1,8 +1,5 @@ #pragma once -#include -#include - typedef enum { // Reserve first 100 events for button types and indexes, starting from 0 SubBruteCustomEventTypeReserved = 100, diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 311b6eba2..e6292b0e9 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -40,6 +40,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->callback = NULL; instance->protocol_info = NULL; + instance->file_protocol_info = NULL; instance->decoder_result = NULL; instance->transmitter = NULL; instance->receiver = NULL; @@ -150,7 +151,8 @@ bool subbrute_worker_start(SubBruteDevice* instance) { FURI_LOG_W(TAG, "Worker cannot start, invalid device state: %d", instance->state); return false; } - if(instance->protocol_info == NULL) { + if((instance->protocol_info == NULL && instance->attack != SubBruteAttackLoadFile) || + (instance->attack == SubBruteAttackLoadFile && instance->file_protocol_info == NULL)) { FURI_LOG_W(TAG, "Worker cannot start, protocol_info is NULL!"); return false; } @@ -230,9 +232,13 @@ void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* fl instance->environment, subbrute_protocol_name(instance->attack)); subghz_transmitter_deserialize(instance->transmitter, flipper_format); furi_hal_subghz_reset(); - furi_hal_subghz_load_preset(instance->protocol_info->preset); - furi_hal_subghz_set_frequency_and_path(instance->protocol_info->preset); - + if(instance->attack == SubBruteAttackLoadFile) { + furi_hal_subghz_load_preset(instance->file_protocol_info->preset); + furi_hal_subghz_set_frequency_and_path(instance->file_protocol_info->preset); + } else { + furi_hal_subghz_load_preset(instance->protocol_info->preset); + furi_hal_subghz_set_frequency_and_path(instance->protocol_info->preset); + } furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); while(!furi_hal_subghz_is_async_tx_complete()) { @@ -348,6 +354,9 @@ bool subbrute_device_create_packet_parsed( FuriString* candidate = furi_string_alloc(); + Stream* stream = flipper_format_get_raw_stream(flipper_format); + stream_clean(stream); + if(instance->attack == SubBruteAttackLoadFile) { if(step >= sizeof(instance->file_key)) { return false; @@ -357,6 +366,42 @@ bool subbrute_device_create_packet_parsed( snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); furi_string_replace_at(candidate, instance->load_index * 3, 3, subbrute_payload_byte); //snprintf(step_payload, sizeof(step_payload), "%02X", (uint8_t)instance->file_key[step]); + + if(small) { + if(instance->file_protocol_info->te) { + stream_write_format( + stream, + subbrute_key_small_with_tail, + instance->file_protocol_info->bits, + furi_string_get_cstr(candidate), + instance->file_protocol_info->te, + instance->file_protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_small_no_tail, + instance->file_protocol_info->bits, + furi_string_get_cstr(candidate), + instance->file_protocol_info->repeat); + } + } else { + if(instance->file_protocol_info->te) { + stream_write_format( + stream, + subbrute_key_file_key_with_tail, + instance->file_template, + furi_string_get_cstr(candidate), + instance->file_protocol_info->te, + instance->file_protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_file_key, + instance->file_template, + furi_string_get_cstr(candidate), + instance->file_protocol_info->repeat); + } + } } else { //snprintf(step_payload, sizeof(step_payload), "%16X", step); //snprintf(step_payload, sizeof(step_payload), "%016llX", step); @@ -375,53 +420,50 @@ bool subbrute_device_create_packet_parsed( } } furi_string_free(buffer); - } #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif - Stream* stream = flipper_format_get_raw_stream(flipper_format); - stream_clean(stream); - - if(small) { - if(instance->protocol_info->te) { - stream_write_format( - stream, - subbrute_key_small_with_tail, - instance->protocol_info->bits, - furi_string_get_cstr(candidate), - instance->protocol_info->te, - instance->protocol_info->repeat); + if(small) { + if(instance->protocol_info->te) { + stream_write_format( + stream, + subbrute_key_small_with_tail, + instance->protocol_info->bits, + furi_string_get_cstr(candidate), + instance->protocol_info->te, + instance->protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_small_no_tail, + instance->protocol_info->bits, + furi_string_get_cstr(candidate), + instance->protocol_info->repeat); + } } else { - stream_write_format( - stream, - subbrute_key_small_no_tail, - instance->protocol_info->bits, - furi_string_get_cstr(candidate), - instance->protocol_info->repeat); + if(instance->protocol_info->te) { + stream_write_format( + stream, + subbrute_key_file_key_with_tail, + instance->file_template, + furi_string_get_cstr(candidate), + instance->protocol_info->te, + instance->protocol_info->repeat); + } else { + stream_write_format( + stream, + subbrute_key_file_key, + instance->file_template, + furi_string_get_cstr(candidate), + instance->protocol_info->repeat); + } } - } else { - if(instance->protocol_info->te) { - stream_write_format( - stream, - subbrute_key_file_key_with_tail, - instance->file_template, - furi_string_get_cstr(candidate), - instance->protocol_info->te, - instance->protocol_info->repeat); - } else { - stream_write_format( - stream, - subbrute_key_file_key, - instance->file_template, - furi_string_get_cstr(candidate), - instance->protocol_info->repeat); - } - } #ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "payload: %s", instance->payload); + //FURI_LOG_D(TAG, "payload: %s", instance->payload); #endif + } furi_string_free(candidate); @@ -471,6 +513,17 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute // Calc max value if(instance->attack == SubBruteAttackLoadFile) { instance->max_value = 0x3F; + + // Now we are ready to set file template for using in the future with snprintf + // for sending attack payload ONLY for files! + snprintf( + instance->file_template, + sizeof(instance->file_template), + subbrute_key_file_start, + instance->file_protocol_info->frequency, + subbrute_protocol_preset(instance->file_protocol_info->preset), + subbrute_protocol_file(instance->file_protocol_info->file), + instance->file_protocol_info->bits); } else { FuriString* max_value_s; max_value_s = furi_string_alloc(); @@ -479,22 +532,22 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute } instance->max_value = (uint64_t)strtol(furi_string_get_cstr(max_value_s), NULL, 2); furi_string_free(max_value_s); - } - // Now we are ready to set file template for using in the future with snprintf - // for sending attack payload - snprintf( - instance->file_template, - sizeof(instance->file_template), - subbrute_key_file_start, - instance->protocol_info->frequency, - subbrute_protocol_preset(instance->protocol_info->preset), - subbrute_protocol_file(instance->protocol_info->file), - instance->protocol_info->bits); + // Now we are ready to set file template for using in the future with snprintf + // for sending attack payload + snprintf( + instance->file_template, + sizeof(instance->file_template), + subbrute_key_file_start, + instance->protocol_info->frequency, + subbrute_protocol_preset(instance->protocol_info->preset), + subbrute_protocol_file(instance->protocol_info->file), + instance->protocol_info->bits); #ifdef FURI_DEBUG - FURI_LOG_D( - TAG, "tail: %d, file_template: %s", instance->protocol_info->te, instance->file_template); + FURI_LOG_D( + TAG, "tail: %d, file_template: %s", instance->protocol_info->te, instance->file_template); #endif + } // Init payload FlipperFormat* flipper_format = flipper_format_string_alloc(); @@ -517,6 +570,9 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); + subbrute_device_free_protocol_info(instance); + instance->file_protocol_info = malloc(sizeof(SubBruteProtocol)); + FuriString* temp_str; temp_str = furi_string_alloc(); uint32_t temp_data32; @@ -539,8 +595,8 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil // Frequency if(flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { - instance->protocol_info->frequency = temp_data32; - if(!furi_hal_subghz_is_tx_allowed(instance->protocol_info->frequency)) { + instance->file_protocol_info->frequency = temp_data32; + if(!furi_hal_subghz_is_tx_allowed(instance->file_protocol_info->frequency)) { result = SubBruteFileResultFrequencyNotAllowed; break; } @@ -555,7 +611,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil FURI_LOG_E(TAG, "Preset FAIL"); result = SubBruteFileResultPresetInvalid; } else { - instance->protocol_info->preset = subbrute_protocol_convert_preset(temp_str); + instance->file_protocol_info->preset = subbrute_protocol_convert_preset(temp_str); } const char* protocol_file = NULL; @@ -565,8 +621,8 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil result = SubBruteFileResultMissingProtocol; break; } else { - instance->protocol_info->file = subbrute_protocol_file_protocol_name(temp_str); - protocol_file = subbrute_protocol_file(instance->protocol_info->file); + instance->file_protocol_info->file = subbrute_protocol_file_protocol_name(temp_str); + protocol_file = subbrute_protocol_file(instance->file_protocol_info->file); #ifdef FURI_DEBUG FURI_LOG_D(TAG, "Protocol: %s", protocol_file); #endif @@ -598,9 +654,9 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil result = SubBruteFileResultMissingOrIncorrectBit; break; } else { - instance->protocol_info->bits = temp_data32; + instance->file_protocol_info->bits = temp_data32; #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Bit: %d", instance->protocol_info->bits); + FURI_LOG_D(TAG, "Bit: %d", instance->file_protocol_info->bits); #endif } @@ -626,7 +682,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil //result = SubBruteFileResultMissingOrIncorrectTe; //break; } else { - instance->protocol_info->te = temp_data32 != 0; + instance->file_protocol_info->te = temp_data32 != 0; } // Repeat @@ -634,12 +690,12 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil #ifdef FURI_DEBUG FURI_LOG_D(TAG, "Repeat: %ld", temp_data32); #endif - instance->protocol_info->repeat = (uint8_t)temp_data32; + instance->file_protocol_info->repeat = (uint8_t)temp_data32; } else { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "Repeat: 3 (default)"); #endif - instance->protocol_info->repeat = 3; + instance->file_protocol_info->repeat = 3; } result = SubBruteFileResultOk; @@ -659,6 +715,8 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil #ifdef FURI_DEBUG FURI_LOG_D(TAG, "Loaded successfully"); #endif + } else { + subbrute_device_free_protocol_info(instance); } return result; @@ -742,7 +800,9 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { void subbrute_device_free_protocol_info(SubBruteDevice* instance) { furi_assert(instance); - - free(instance->protocol_info); instance->protocol_info = NULL; + if(instance->file_protocol_info) { + free(instance->file_protocol_info); + } + instance->file_protocol_info = NULL; } \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index bdcaa11bd..e3b327b85 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -41,7 +41,8 @@ typedef enum { typedef void (*SubBruteDeviceWorkerCallback)(void* context, SubBruteDeviceState state); typedef struct { SubBruteDeviceState state; - SubBruteProtocol* protocol_info; + const SubBruteProtocol* protocol_info; + SubBruteProtocol* file_protocol_info; volatile bool worker_running; // Current step diff --git a/applications/plugins/subbrute/subbrute_i.h b/applications/plugins/subbrute/subbrute_i.h index 02f91f93d..b4264c0d6 100644 --- a/applications/plugins/subbrute/subbrute_i.h +++ b/applications/plugins/subbrute/subbrute_i.h @@ -47,7 +47,6 @@ struct SubBruteState { Popup* popup; Widget* widget; DialogsApp* dialogs; - Loading* loading; // Text store char text_store[SUBBRUTE_MAX_LEN_NAME]; diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index 3bedcb23c..462732937 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -1,41 +1,155 @@ #include "subbrute_protocols.h" -static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { - [SubBruteAttackCAME12bit303] = - {303875000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, - [SubBruteAttackCAME12bit307] = - {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, - [SubBruteAttackCAME12bit433] = - {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, - [SubBruteAttackCAME12bit868] = - {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, - [SubBruteAttackNICE12bit433] = - {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, - [SubBruteAttackNICE12bit868] = - {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, - [SubBruteAttackChamberlain9bit300] = - {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, - [SubBruteAttackChamberlain9bit315] = - {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, - [SubBruteAttackChamberlain9bit390] = - {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, - [SubBruteAttackLinear10bit300] = - {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, - [SubBruteAttackLinear10bit310] = - {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, - [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}, -}; -//static const uint32_t subbrute_protocols[SubBruteAttackTotalCount][TotalProtocolFields] = { -// [SubBruteAttackCAME12bit307] = {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackCAME12bit433] = {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackCAME12bit868] = {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackNICE12bit433] = {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, -// [SubBruteAttackNICE12bit868] = {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, -// [SubBruteAttackChamberlain9bit300] = {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackChamberlain9bit315] = {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackChamberlain9bit390] = {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackLinear10bit300] = {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, -// [SubBruteAttackLinear10bit310] = {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, +/** + * CAME 12bit 303MHz + */ +const SubBruteProtocol subbrute_protocol_came_12bit_303 = { + .frequency = 303875000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = CAMEFileProtocol}; + +/** + * CAME 12bit 307MHz + */ +const SubBruteProtocol subbrute_protocol_came_12bit_307 = { + .frequency = 307800000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = CAMEFileProtocol}; + +/** + * CAME 12bit 433MHz + */ +const SubBruteProtocol subbrute_protocol_came_12bit_433 = { + .frequency = 433920000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = CAMEFileProtocol}; + +/** + * CAME 12bit 868MHz + */ +const SubBruteProtocol subbrute_protocol_came_12bit_868 = { + .frequency = 868350000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = CAMEFileProtocol}; + +/** + * NICE 12bit 433MHz + */ +const SubBruteProtocol subbrute_protocol_nice_12bit_433 = { + .frequency = 433920000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = NICEFileProtocol}; + +/** + * NICE 12bit 868MHz + */ +const SubBruteProtocol subbrute_protocol_nice_12bit_868 = { + .frequency = 868350000, + .bits = 12, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = NICEFileProtocol}; + +/** + * Chamberlain 9bit 300MHz + */ +const SubBruteProtocol subbrute_protocol_chamberlain_9bit_300 = { + .frequency = 300000000, + .bits = 9, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = ChamberlainFileProtocol}; + +/** + * Chamberlain 9bit 315MHz + */ +const SubBruteProtocol subbrute_protocol_chamberlain_9bit_315 = { + .frequency = 315000000, + .bits = 9, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = ChamberlainFileProtocol}; + +/** + * Chamberlain 9bit 390MHz + */ +const SubBruteProtocol subbrute_protocol_chamberlain_9bit_390 = { + .frequency = 390000000, + .bits = 9, + .te = 0, + .repeat = 3, + .preset = FuriHalSubGhzPresetOok650Async, + .file = ChamberlainFileProtocol}; + +/** + * Linear 10bit 300MHz + */ +const SubBruteProtocol subbrute_protocol_linear_10bit_300 = { + .frequency = 300000000, + .bits = 10, + .te = 0, + .repeat = 5, + .preset = FuriHalSubGhzPresetOok650Async, + .file = LinearFileProtocol}; + +/** + * Linear 10bit 310MHz + */ +const SubBruteProtocol subbrute_protocol_linear_10bit_310 = { + .frequency = 310000000, + .bits = 10, + .te = 0, + .repeat = 5, + .preset = FuriHalSubGhzPresetOok650Async, + .file = LinearFileProtocol}; + +/** + * BF existing dump + */ +const SubBruteProtocol subbrute_protocol_load_file = + {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}; + +//static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { +// [SubBruteAttackCAME12bit303] = +// {303875000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackCAME12bit307] = +// {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackCAME12bit433] = +// {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackCAME12bit868] = +// {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, +// [SubBruteAttackNICE12bit433] = +// {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, +// [SubBruteAttackNICE12bit868] = +// {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, +// [SubBruteAttackChamberlain9bit300] = +// {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackChamberlain9bit315] = +// {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackChamberlain9bit390] = +// {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, +// [SubBruteAttackLinear10bit300] = +// {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, +// [SubBruteAttackLinear10bit310] = +// {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, // [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}, //}; @@ -65,7 +179,21 @@ static const char* subbrute_protocol_presets[] = { [FuriHalSubGhzPresetGFSK9_99KbAsync] = "FuriHalSubGhzPresetGFSK9_99KbAsync", }; -static const char* subbrute_protocol_file_types[TotalFileProtocol] = { +const SubBruteProtocol* subbrute_protocol_registry[] = { + [SubBruteAttackCAME12bit303] = &subbrute_protocol_came_12bit_303, + [SubBruteAttackCAME12bit307] = &subbrute_protocol_came_12bit_307, + [SubBruteAttackCAME12bit433] = &subbrute_protocol_came_12bit_433, + [SubBruteAttackCAME12bit868] = &subbrute_protocol_came_12bit_868, + [SubBruteAttackNICE12bit433] = &subbrute_protocol_nice_12bit_433, + [SubBruteAttackNICE12bit868] = &subbrute_protocol_nice_12bit_868, + [SubBruteAttackChamberlain9bit300] = &subbrute_protocol_chamberlain_9bit_300, + [SubBruteAttackChamberlain9bit315] = &subbrute_protocol_chamberlain_9bit_315, + [SubBruteAttackChamberlain9bit390] = &subbrute_protocol_chamberlain_9bit_390, + [SubBruteAttackLinear10bit300] = &subbrute_protocol_linear_10bit_300, + [SubBruteAttackLinear10bit310] = &subbrute_protocol_linear_10bit_310, + [SubBruteAttackLoadFile] = &subbrute_protocol_load_file}; + +static const char* subbrute_protocol_file_types[] = { [CAMEFileProtocol] = "CAME", [NICEFileProtocol] = "Nice FLO", [ChamberlainFileProtocol] = "Cham_Code", @@ -73,32 +201,12 @@ static const char* subbrute_protocol_file_types[TotalFileProtocol] = { [PrincetonFileProtocol] = "Princeton", [RAWFileProtocol] = "RAW"}; -SubBruteProtocol* subbrute_protocol_alloc(void) { - SubBruteProtocol* protocol = malloc(sizeof(SubBruteProtocol)); - protocol->frequency = subbrute_protocols[SubBruteAttackLoadFile].frequency; - protocol->repeat = subbrute_protocols[SubBruteAttackLoadFile].repeat; - protocol->preset = subbrute_protocols[SubBruteAttackLoadFile].preset; - protocol->file = subbrute_protocols[SubBruteAttackLoadFile].file; - protocol->te = subbrute_protocols[SubBruteAttackLoadFile].te; - protocol->bits = subbrute_protocols[SubBruteAttackLoadFile].bits; - - return protocol; -} - const char* subbrute_protocol_name(SubBruteAttacks index) { return subbrute_protocol_names[index]; } -SubBruteProtocol* subbrute_protocol(SubBruteAttacks index) { - SubBruteProtocol* protocol = subbrute_protocol_alloc(); - protocol->frequency = subbrute_protocols[index].frequency; - protocol->repeat = subbrute_protocols[index].repeat; - protocol->preset = subbrute_protocols[index].preset; - protocol->file = subbrute_protocols[index].file; - protocol->te = subbrute_protocols[index].te; - protocol->bits = subbrute_protocols[index].bits; - - return protocol; +const SubBruteProtocol* subbrute_protocol(SubBruteAttacks index) { + return subbrute_protocol_registry[index]; } const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset) { diff --git a/applications/plugins/subbrute/subbrute_protocols.h b/applications/plugins/subbrute/subbrute_protocols.h index 34502572c..f876ed756 100644 --- a/applications/plugins/subbrute/subbrute_protocols.h +++ b/applications/plugins/subbrute/subbrute_protocols.h @@ -49,8 +49,7 @@ typedef struct { SubBruteFileProtocol file; } SubBruteProtocol; -SubBruteProtocol* subbrute_protocol_alloc(void); -SubBruteProtocol* subbrute_protocol(SubBruteAttacks index); +const SubBruteProtocol* subbrute_protocol(SubBruteAttacks index); const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset); const char* subbrute_protocol_file(SubBruteFileProtocol protocol); FuriHalSubGhzPreset subbrute_protocol_convert_preset(FuriString* preset_name); diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 197cf8239..63328d771 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -2,11 +2,11 @@ #include "../subbrute_i.h" #include "../subbrute_protocols.h" -#include "assets_icons.h" #include #include -#include -#include +#include +#include +#include #define TAG "SubBruteAttackView" @@ -291,8 +291,8 @@ void elements_button_top_left(Canvas* canvas, const char* str) { 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->width + icon_h_offset; - const uint8_t icon_v_offset = icon->height; // + const uint8_t icon_width_with_offset = icon_get_width(icon) + icon_h_offset; + const uint8_t icon_v_offset = icon_get_height(icon); // const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset + 1; const uint8_t x = 0; @@ -318,8 +318,8 @@ void elements_button_top_right(Canvas* canvas, const char* str) { 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->width + icon_h_offset; - const uint8_t icon_v_offset = icon->height; // + vertical_offset; + 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 + 1; const uint8_t x = canvas_width(canvas); @@ -332,7 +332,7 @@ void elements_button_top_right(Canvas* canvas, const char* str) { 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->width, y + icon_v_offset, icon); + canvas_draw_icon(canvas, x - horizontal_offset - icon_get_width(icon), y + icon_v_offset, icon); canvas_invert_color(canvas); } @@ -371,8 +371,8 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { } // canvas_draw_icon_animation const uint8_t icon_h_offset = 0; - const uint8_t icon_width_with_offset = model->icon->icon->width + icon_h_offset; - const uint8_t icon_v_offset = model->icon->icon->height; // + vertical_offset; + const uint8_t icon_width_with_offset = icon_animation_get_width(model->icon) + icon_h_offset; + const uint8_t icon_v_offset = icon_animation_get_height(model->icon); // + vertical_offset; const uint8_t x = canvas_width(canvas); const uint8_t y = canvas_height(canvas); canvas_draw_icon_animation( diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.h b/applications/plugins/subbrute/views/subbrute_attack_view.h index b10f8b17b..1e25379e2 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.h +++ b/applications/plugins/subbrute/views/subbrute_attack_view.h @@ -2,11 +2,8 @@ #include "../subbrute_custom_event.h" #include -#include "assets_icons.h" #include #include -#include -#include typedef void (*SubBruteAttackViewCallback)(SubBruteCustomEvent event, void* context); typedef struct SubBruteAttackView SubBruteAttackView; diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index c3f56cae2..23095e17f 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -4,8 +4,8 @@ #include #include -#include "assets_icons.h" #include +#include #define STATUS_BAR_Y_SHIFT 14 #define TAG "SubBruteMainView" diff --git a/applications/plugins/subbrute/views/subbrute_main_view.h b/applications/plugins/subbrute/views/subbrute_main_view.h index 02eb3305a..361dbc22b 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.h +++ b/applications/plugins/subbrute/views/subbrute_main_view.h @@ -2,10 +2,8 @@ #include "../subbrute_custom_event.h" #include -#include "assets_icons.h" #include #include -#include typedef void (*SubBruteMainViewCallback)(SubBruteCustomEvent event, void* context); typedef struct SubBruteMainView SubBruteMainView; From 7643fdad7c173c8cf008f3e726010ce1bcda787e Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Sat, 8 Oct 2022 22:54:30 +0400 Subject: [PATCH 05/14] Seems we have cross-thread violation --- .../scenes/subbrute_scene_run_attack.c | 4 +-- applications/plugins/subbrute/subbrute.c | 7 +++++ .../plugins/subbrute/subbrute_device.c | 29 +++++++++++++++---- applications/plugins/subbrute/subbrute_i.h | 3 +- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index b37ac34f9..36b3e3f43 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -57,7 +57,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); + subbrute_attack_view_set_current_step(view, subbrute_get_step(instance)); if(event.event == SubBruteCustomEventTypeTransmitFinished) { notification_message(instance->notifications, &sequence_display_backlight_on); @@ -77,7 +77,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } consumed = true; } else if(event.type == SceneManagerEventTypeTick) { - subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); + subbrute_attack_view_set_current_step(view, subbrute_get_step(instance)); consumed = true; } diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index 0e226f9e4..cfb6b337f 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -163,6 +163,13 @@ void subbrute_popup_closed_callback(void* context) { instance->view_dispatcher, SubBruteCustomEventTypePopupClosed); } +uint64_t subbrute_get_step(void* context) { + furi_assert(context); + SubBruteState* instance = context; + + return subbrute_device_get_step(instance->device); +} + // ENTRYPOINT int32_t subbrute_app(void* p) { UNUSED(p); diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index e6292b0e9..fea298b8a 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -1,5 +1,4 @@ #include "subbrute_device.h" -//#include "subbrute_device.h" #include #include @@ -46,7 +45,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->receiver = NULL; instance->environment = subghz_environment_alloc(); - subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit307); + subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); return instance; } @@ -274,6 +273,23 @@ bool subbrute_device_transmit_current_key(SubBruteDevice* instance) { } instance->last_time_tx_data = ticks; + +#ifdef FURI_DEBUG + if(instance->attack == SubBruteAttackLoadFile) { + FURI_LOG_D( + TAG, + "Protocol: %d, Frequency: %ld", + instance->file_protocol_info->file, + instance->file_protocol_info->frequency); + } else { + FURI_LOG_D( + TAG, + "Protocol: %d, Frequency: %ld", + instance->protocol_info->file, + instance->protocol_info->frequency); + } +#endif + FlipperFormat* flipper_format = flipper_format_string_alloc(); if(!subbrute_device_create_packet_parsed(instance, flipper_format, instance->key_index, true)) { @@ -328,7 +344,7 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na } if(!subbrute_device_create_packet_parsed(instance, file, instance->key_index, false)) { - FURI_LOG_E(TAG, "subbrute_device_create_packet_parsed failed!"); + FURI_LOG_E(TAG, "create_packet_parsed failed!"); break; } @@ -461,7 +477,7 @@ bool subbrute_device_create_packet_parsed( } } #ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "payload: %s", instance->payload); + FURI_LOG_D(TAG, "candidate: %s", furi_string_get_cstr(candidate)); #endif } @@ -545,7 +561,10 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute instance->protocol_info->bits); #ifdef FURI_DEBUG FURI_LOG_D( - TAG, "tail: %d, file_template: %s", instance->protocol_info->te, instance->file_template); + TAG, + "tail: %d, file_template: %s", + instance->protocol_info->te, + instance->file_template); #endif } diff --git a/applications/plugins/subbrute/subbrute_i.h b/applications/plugins/subbrute/subbrute_i.h index b4264c0d6..856a0b83d 100644 --- a/applications/plugins/subbrute/subbrute_i.h +++ b/applications/plugins/subbrute/subbrute_i.h @@ -66,4 +66,5 @@ struct SubBruteState { void subbrute_show_loading_popup(void* context, bool show); void subbrute_text_input_callback(void* context); -void subbrute_popup_closed_callback(void* context); \ No newline at end of file +void subbrute_popup_closed_callback(void* context); +uint64_t subbrute_get_step(void* context); \ No newline at end of file From 500456b03dc4a227f7d3c3b1003a18ca70caafa2 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 00:35:44 +0400 Subject: [PATCH 06/14] Returned to Worker model --- .../subbrute/helpers/subbrute_worker.c | 362 +++++++++++++ .../subbrute/helpers/subbrute_worker.h | 39 ++ .../helpers/subbrute_worker_private.h | 45 ++ .../scenes/subbrute_scene_load_file.c | 11 +- .../scenes/subbrute_scene_load_select.c | 13 +- .../scenes/subbrute_scene_run_attack.c | 20 +- .../scenes/subbrute_scene_setup_attack.c | 51 +- .../subbrute/scenes/subbrute_scene_start.c | 11 +- applications/plugins/subbrute/subbrute.c | 15 +- .../plugins/subbrute/subbrute_device.c | 476 ++---------------- .../plugins/subbrute/subbrute_device.h | 47 +- applications/plugins/subbrute/subbrute_i.h | 6 +- .../plugins/subbrute/subbrute_protocols.c | 218 ++++++++ .../plugins/subbrute/subbrute_protocols.h | 31 +- .../subbrute/views/subbrute_main_view.c | 10 +- 15 files changed, 818 insertions(+), 537 deletions(-) create mode 100644 applications/plugins/subbrute/helpers/subbrute_worker.c create mode 100644 applications/plugins/subbrute/helpers/subbrute_worker.h create mode 100644 applications/plugins/subbrute/helpers/subbrute_worker_private.h diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c new file mode 100644 index 000000000..4d7e98fa4 --- /dev/null +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -0,0 +1,362 @@ +#include "subbrute_worker_private.h" +#include +#include +#include +#include + +#define TAG "SubBruteWorker" +#define SUBBRUTE_TX_TIMEOUT 5 +#define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 400 + +SubBruteWorker* subbrute_worker_alloc() { + SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); + + instance->state = SubBruteWorkerStateIDLE; + instance->key_index = 0; + instance->worker_running = false; + instance->initiated = false; + instance->last_time_tx_data = 0; + instance->load_index = 0; + + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); + furi_thread_set_stack_size(instance->thread, 2048); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, subbrute_worker_thread); + + instance->context = NULL; + instance->callback = NULL; + + instance->decoder_result = NULL; + instance->transmitter = NULL; + instance->environment = subghz_environment_alloc(); + + return instance; +} + +void subbrute_worker_free(SubBruteWorker* instance) { + furi_assert(instance); + + // I don't know how to free this + instance->decoder_result = NULL; + + if(instance->transmitter != NULL) { + subghz_transmitter_free(instance->transmitter); + instance->transmitter = NULL; + } + + subghz_environment_free(instance->environment); + instance->environment = NULL; + + furi_thread_free(instance->thread); + + free(instance); +} + +uint64_t subbrute_worker_get_step(SubBruteWorker* instance) { + return instance->key_index; +} + +bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step) { + furi_assert(instance); + if(!subbrute_worker_can_manual_transmit(instance)) { + FURI_LOG_W(TAG, "Cannot set step during running mode"); + return false; + } + + instance->key_index = step; + + return true; +} + +bool subbrute_worker_init_default_attack( + SubBruteWorker* instance, + SubBruteAttacks attack_type, + uint64_t step, + const SubBruteProtocol* protocol) { + furi_assert(instance); + + if(instance->worker_running) { + FURI_LOG_W(TAG, "Init Worker when it's running"); + subbrute_worker_stop(instance); + } + + instance->attack = attack_type; + instance->frequency = protocol->frequency; + instance->preset = protocol->preset; + instance->file = protocol->file; + instance->key_index = step; + instance->bits = protocol->bits; + instance->te = protocol->te; + instance->load_index = 0; + instance->file_key = NULL; + instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits); + + return true; +} + +bool subbrute_worker_init_file_attack( + SubBruteWorker* instance, + uint64_t step, + uint8_t load_index, + const char* file_key, + SubBruteProtocol* protocol) { + furi_assert(instance); + + if(instance->worker_running) { + FURI_LOG_W(TAG, "Init Worker when it's running"); + subbrute_worker_stop(instance); + } + + instance->attack = SubBruteAttackLoadFile; + instance->frequency = protocol->frequency; + instance->preset = protocol->preset; + instance->file = protocol->file; + instance->key_index = step; + instance->bits = protocol->bits; + instance->te = protocol->te; + instance->load_index = load_index; + instance->file_key = file_key; + instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits); + + return true; +} + +bool subbrute_worker_start(SubBruteWorker* instance) { + furi_assert(instance); + + if(!instance->initiated) { + FURI_LOG_W(TAG, "Worker not init!"); + return false; + } + + if(instance->worker_running) { + FURI_LOG_W(TAG, "Worker is already running!"); + return false; + } + if(instance->state != SubBruteWorkerStateReady && + instance->state != SubBruteWorkerStateFinished) { + FURI_LOG_W(TAG, "Worker cannot start, invalid device state: %d", instance->state); + return false; + } + + instance->worker_running = true; + furi_thread_start(instance->thread); + + return true; +} + +void subbrute_worker_stop(SubBruteWorker* instance) { + furi_assert(instance); + + instance->worker_running = false; + + furi_thread_join(instance->thread); + + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); +} + +bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step) { + furi_assert(instance); + + if(!instance->initiated) { + FURI_LOG_W(TAG, "Worker not init!"); + return false; + } + if(instance->worker_running) { + FURI_LOG_W(TAG, "Worker in running state!"); + return false; + } + if(instance->state != SubBruteWorkerStateReady && + instance->state != SubBruteWorkerStateFinished) { + FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); + return false; + } + + uint32_t ticks = furi_get_tick(); + if((ticks - instance->last_time_tx_data) < SUBBRUTE_MANUAL_TRANSMIT_INTERVAL) { +#if FURI_DEBUG + FURI_LOG_D(TAG, "Need to wait, current: %ld", ticks - instance->last_time_tx_data); +#endif + return false; + } + + instance->last_time_tx_data = ticks; + instance->key_index = step; + + bool result; + FlipperFormat* flipper_format = flipper_format_string_alloc(); + Stream* stream = flipper_format_get_raw_stream(flipper_format); + + FuriString* payload = furi_string_alloc(); + stream_clean(stream); + + if(instance->attack == SubBruteAttackLoadFile) { + payload = subbrute_protocol_file_payload( + step, + instance->bits, + instance->te, + instance->repeat, + instance->load_index, + instance->file_key); + } else { + payload = subbrute_protocol_default_payload( + step, instance->bits, instance->te, instance->repeat); + } + + size_t written = stream_write_string(stream, payload); + if(written <= 0) { + FURI_LOG_W(TAG, "Error creating packet! EXIT"); + result = false; + } else { + subbrute_worker_subghz_transmit(instance, flipper_format); + + result = true; +#if FURI_DEBUG + FURI_LOG_D(TAG, "Manual transmit done"); +#endif + } + + flipper_format_free(flipper_format); + furi_string_free(payload); + + return result; +} + +bool subbrute_worker_is_running(SubBruteWorker* instance) { + return instance->worker_running; +} + +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance) { + furi_assert(instance); + + if(!instance->initiated) { + FURI_LOG_W(TAG, "Worker not init!"); + return false; + } + + return !instance->worker_running && instance->state != SubBruteWorkerStateIDLE && + instance->state != SubBruteWorkerStateTx && + ((furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_MANUAL_TRANSMIT_INTERVAL); +} + +void subbrute_worker_set_callback( + SubBruteWorker* instance, + SubBruteWorkerCallback callback, + void* context) { + furi_assert(instance); + + instance->callback = callback; + instance->context = context; +} + +void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* flipper_format) { + instance->transmitter = subghz_transmitter_alloc_init( + instance->environment, subbrute_protocol_name(instance->attack)); + subghz_transmitter_deserialize(instance->transmitter, flipper_format); + furi_hal_subghz_reset(); + furi_hal_subghz_load_preset(instance->preset); + furi_hal_subghz_set_frequency_and_path(instance->frequency); + furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); + + while(!furi_hal_subghz_is_async_tx_complete()) { + furi_delay_ms(SUBBRUTE_TX_TIMEOUT); + } + furi_hal_subghz_stop_async_tx(); + + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); + subghz_transmitter_free(instance->transmitter); + instance->transmitter = NULL; +} + +void subbrute_worker_send_callback(SubBruteWorker* instance) { + if(instance->callback != NULL) { + instance->callback(instance->context, instance->state); + } +} + +/** + * Entrypoint for worker + * + * @param context SubBruteWorker* + * @return 0 if ok + */ +int32_t subbrute_worker_thread(void* context) { + furi_assert(context); + SubBruteWorker* instance = (SubBruteWorker*)context; + + if(!instance->worker_running) { + FURI_LOG_W(TAG, "Worker is not set to running state!"); + return -1; + } + if(instance->state != SubBruteWorkerStateReady && + instance->state != SubBruteWorkerStateFinished) { + FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); + return -2; + } +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker start"); +#endif + + SubBruteWorkerState local_state = instance->state = SubBruteWorkerStateTx; + subbrute_worker_send_callback(instance); + + FlipperFormat* flipper_format = flipper_format_string_alloc(); + Stream* stream = flipper_format_get_raw_stream(flipper_format); + + while(instance->worker_running) { + FuriString* payload = furi_string_alloc(); + stream_clean(stream); + + if(instance->attack == SubBruteAttackLoadFile) { + payload = subbrute_protocol_file_payload( + instance->key_index, + instance->bits, + instance->te, + instance->repeat, + instance->load_index, + instance->file_key); + } else { + payload = subbrute_protocol_default_payload( + instance->key_index, instance->bits, instance->te, instance->repeat); + } + + size_t written = stream_write_string(stream, payload); + if(written <= 0) { + FURI_LOG_W(TAG, "Error creating packet! BREAK"); + instance->worker_running = false; + local_state = SubBruteWorkerStateIDLE; + furi_string_free(payload); + break; + } + + subbrute_worker_subghz_transmit(instance, flipper_format); + + if(instance->key_index + 1 > instance->max_value) { +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker finished to end"); +#endif + local_state = SubBruteWorkerStateFinished; + furi_string_free(payload); + break; + } + instance->key_index++; + + furi_string_free(payload); + furi_delay_ms(SUBBRUTE_TX_TIMEOUT); + } + + flipper_format_free(flipper_format); + + instance->worker_running = false; // Because we have error states + instance->state = local_state == SubBruteWorkerStateTx ? SubBruteWorkerStateReady : + local_state; + subbrute_worker_send_callback(instance); + +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Worker stop"); +#endif + return 0; +} diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h new file mode 100644 index 000000000..3a514272b --- /dev/null +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../subbrute_protocols.h" + +typedef enum { + SubBruteWorkerStateIDLE, + SubBruteWorkerStateReady, + SubBruteWorkerStateTx, + SubBruteWorkerStateFinished +} SubBruteWorkerState; + +typedef void (*SubBruteWorkerCallback)(void* context, SubBruteWorkerState state); + +typedef struct SubBruteWorker SubBruteWorker; + +SubBruteWorker* subbrute_worker_alloc(); +void subbrute_worker_free(SubBruteWorker* instance); +uint64_t subbrute_worker_get_step(SubBruteWorker* instance); +bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step); +bool subbrute_worker_is_running(SubBruteWorker* instance); +bool subbrute_worker_init_default_attack( + SubBruteWorker* instance, + SubBruteAttacks attack_type, + uint64_t step, + const SubBruteProtocol* protocol); +bool subbrute_worker_init_file_attack( + SubBruteWorker* instance, + uint64_t step, + uint8_t load_index, + const char* file_key, + SubBruteProtocol* protocol); +bool subbrute_worker_start(SubBruteWorker* instance); +void subbrute_worker_stop(SubBruteWorker* instance); +bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t step); +bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance); +void subbrute_worker_set_callback( + SubBruteWorker* instance, + SubBruteWorkerCallback callback, + void* context); \ No newline at end of file diff --git a/applications/plugins/subbrute/helpers/subbrute_worker_private.h b/applications/plugins/subbrute/helpers/subbrute_worker_private.h new file mode 100644 index 000000000..fd55902bb --- /dev/null +++ b/applications/plugins/subbrute/helpers/subbrute_worker_private.h @@ -0,0 +1,45 @@ +#pragma once + +#include "subbrute_worker.h" +#include +#include +#include +#include + +struct SubBruteWorker { + SubBruteWorkerState state; + volatile bool worker_running; + volatile bool initiated; + + // Current step + uint64_t key_index; + + // SubGhz + FuriThread* thread; + SubGhzProtocolDecoderBase* decoder_result; + SubGhzEnvironment* environment; + SubGhzTransmitter* transmitter; + + // Initiated values + SubBruteAttacks attack; // Attack state + uint32_t frequency; + FuriHalSubGhzPreset preset; + SubBruteFileProtocol file; + uint8_t bits; + uint8_t te; + uint8_t repeat; + uint8_t load_index; // Index of group to bruteforce in loaded file + const char* file_key; + uint64_t max_value; // Max step + + // 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); \ No newline at end of file diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c index dc26403c3..84df3e4e5 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c @@ -39,6 +39,14 @@ void subbrute_scene_load_file_on_enter(void* context) { if(load_result == SubBruteFileResultOk) { load_result = subbrute_device_attack_set(instance->device, SubBruteAttackLoadFile); if(load_result == SubBruteFileResultOk) { + if(!subbrute_worker_init_file_attack( + instance->worker, + instance->device->key_index, + instance->device->load_index, + instance->device->file_key, + instance->device->file_protocol_info)) { + furi_crash("Invalid attack set!"); + } // Ready to run! FURI_LOG_I(TAG, "Ready to run"); res = true; @@ -52,7 +60,8 @@ void subbrute_scene_load_file_on_enter(void* context) { 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)); + 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( diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c index e9fafd4da..77db3f64b 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_select.c @@ -20,7 +20,7 @@ void subbrute_scene_load_select_on_enter(void* context) { instance->current_view = SubBruteViewMain; subbrute_main_view_set_callback(view, subbrute_scene_load_select_callback, instance); - subbrute_main_view_set_index(view, 7, true, subbrute_device_get_file_key(instance->device)); + subbrute_main_view_set_index(view, 7, true, instance->device->file_key); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); } @@ -38,8 +38,15 @@ bool subbrute_scene_load_select_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeIndexSelected) { - subbrute_device_set_load_index( - instance->device, subbrute_main_view_get_index(instance->view_main)); + instance->device->load_index = subbrute_main_view_get_index(instance->view_main); + if(!subbrute_worker_init_file_attack( + instance->worker, + instance->device->key_index, + instance->device->load_index, + instance->device->file_key, + instance->device->file_protocol_info)) { + furi_crash("Invalid attack set!"); + } scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 36b3e3f43..17a3d910a 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -11,15 +11,15 @@ static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* } static void - subbrute_scene_run_attack_device_state_changed(void* context, SubBruteDeviceState state) { + subbrute_scene_run_attack_device_state_changed(void* context, SubBruteWorkerState state) { furi_assert(context); SubBruteState* instance = (SubBruteState*)context; - if(state == SubBruteDeviceStateIDLE) { + if(state == SubBruteWorkerStateIDLE) { // Can't be IDLE on this step! view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError); - } else if(state == SubBruteDeviceStateFinished) { + } else if(state == SubBruteWorkerStateFinished) { view_dispatcher_send_custom_event( instance->view_dispatcher, SubBruteCustomEventTypeTransmitFinished); } @@ -28,7 +28,7 @@ void subbrute_scene_run_attack_on_exit(void* context) { furi_assert(context); SubBruteState* instance = (SubBruteState*)context; - subbrute_worker_stop(instance->device); + subbrute_worker_stop(instance->worker); notification_message(instance->notifications, &sequence_blink_stop); } @@ -42,11 +42,11 @@ void subbrute_scene_run_attack_on_enter(void* context) { subbrute_attack_view_set_callback(view, subbrute_scene_run_attack_callback, instance); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); - subbrute_device_set_callback( - instance->device, subbrute_scene_run_attack_device_state_changed, instance); + subbrute_worker_set_callback( + instance->worker, subbrute_scene_run_attack_device_state_changed, instance); - if(!subbrute_device_is_worker_running(instance->device)) { - subbrute_worker_start(instance->device); + if(!subbrute_worker_is_running(instance->worker)) { + subbrute_worker_start(instance->worker); } } @@ -57,7 +57,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - subbrute_attack_view_set_current_step(view, subbrute_get_step(instance)); + subbrute_attack_view_set_current_step(view, subbrute_worker_get_step(instance->worker)); if(event.event == SubBruteCustomEventTypeTransmitFinished) { notification_message(instance->notifications, &sequence_display_backlight_on); @@ -77,7 +77,7 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } consumed = true; } else if(event.type == SceneManagerEventTypeTick) { - subbrute_attack_view_set_current_step(view, subbrute_get_step(instance)); + subbrute_attack_view_set_current_step(view, subbrute_worker_get_step(instance->worker)); consumed = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index b506a33d5..4984b4931 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -11,12 +11,12 @@ static void subbrute_scene_setup_attack_callback(SubBruteCustomEvent event, void } static void - subbrute_scene_setup_attack_device_state_changed(void* context, SubBruteDeviceState state) { + subbrute_scene_setup_attack_device_state_changed(void* context, SubBruteWorkerState state) { furi_assert(context); SubBruteState* instance = (SubBruteState*)context; - if(state == SubBruteDeviceStateIDLE) { + if(state == SubBruteWorkerStateIDLE) { // Can't be IDLE on this step! view_dispatcher_send_custom_event(instance->view_dispatcher, SubBruteCustomEventTypeError); } @@ -28,16 +28,24 @@ void subbrute_scene_setup_attack_on_enter(void* context) { SubBruteAttackView* view = instance->view_attack; #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Enter Attack: %d", subbrute_device_get_attack(instance->device)); + FURI_LOG_D(TAG, "Enter Attack: %d", instance->device->attack); #endif - subbrute_device_set_callback( - instance->device, subbrute_scene_setup_attack_device_state_changed, context); + subbrute_worker_set_callback( + instance->worker, subbrute_scene_setup_attack_device_state_changed, context); - if(subbrute_device_is_worker_running(instance->device)) { - subbrute_worker_stop(instance->device); + if(subbrute_worker_is_running(instance->worker)) { + instance->device->key_index = subbrute_worker_get_step(instance->worker); + subbrute_worker_stop(instance->worker); } + subbrute_attack_view_init_values( + view, + instance->device->attack, + instance->device->max_value, + instance->device->key_index, + false); + 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); @@ -49,7 +57,7 @@ void subbrute_scene_setup_attack_on_exit(void* context) { FURI_LOG_D(TAG, "subbrute_scene_setup_attack_on_exit"); #endif SubBruteState* instance = (SubBruteState*)context; - subbrute_worker_stop(instance->device); + subbrute_worker_stop(instance->worker); notification_message(instance->notifications, &sequence_blink_stop); } @@ -65,53 +73,60 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } else if(event.event == SubBruteCustomEventTypeSaveFile) { subbrute_attack_view_init_values( view, - subbrute_device_get_attack(instance->device), - subbrute_device_get_max_value(instance->device), - subbrute_device_get_step(instance->device), + instance->device->attack, + instance->device->max_value, + instance->device->key_index, false); scene_manager_next_scene(instance->scene_manager, SubBruteSceneSaveName); } else if(event.event == SubBruteCustomEventTypeBackPressed) { - subbrute_device_reset_step(instance->device); subbrute_attack_view_init_values( view, - subbrute_device_get_attack(instance->device), - subbrute_device_get_max_value(instance->device), - subbrute_device_get_step(instance->device), + instance->device->attack, + instance->device->max_value, + instance->device->key_index, false); 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_device_can_manual_transmit(instance->device)) { + if(subbrute_worker_can_manual_transmit(instance->worker)) { // MANUAL Transmit! // Blink notification_message(instance->notifications, &sequence_blink_green_100); - subbrute_device_transmit_current_key(instance->device); + subbrute_worker_transmit_current_key( + instance->worker, instance->device->key_index); // 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) { - subbrute_attack_view_set_current_step(view, subbrute_device_get_step(instance->device)); + if(subbrute_worker_is_running(instance->worker)) { + instance->device->key_index = subbrute_worker_get_step(instance->worker); + } + subbrute_attack_view_set_current_step(view, instance->device->key_index); consumed = true; } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_start.c b/applications/plugins/subbrute/scenes/subbrute_scene_start.c index 38441ea30..2d7bc5134 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_start.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_start.c @@ -23,7 +23,7 @@ void subbrute_scene_start_on_enter(void* context) { instance->current_view = SubBruteViewMain; subbrute_main_view_set_callback(view, subbrute_scene_start_callback, instance); - subbrute_main_view_set_index(view, subbrute_device_get_attack(instance->device), false, NULL); + subbrute_main_view_set_index(view, instance->device->attack, false, NULL); view_dispatcher_switch_to_view(instance->view_dispatcher, instance->current_view); } @@ -46,7 +46,14 @@ bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.event == SubBruteCustomEventTypeMenuSelected) { SubBruteAttacks attack = subbrute_main_view_get_index(instance->view_main); - subbrute_device_attack_set(instance->device, attack); + if(subbrute_device_attack_set(instance->device, attack) != SubBruteFileResultOk || + !subbrute_worker_init_default_attack( + instance->worker, + attack, + instance->device->key_index, + instance->device->protocol_info)) { + furi_crash("Invalid attack set!"); + } scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index cfb6b337f..aaab3aeb1 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -51,6 +51,9 @@ SubBruteState* subbrute_alloc() { // Devices instance->device = subbrute_device_alloc(); + // SubBruteWorker + instance->worker = subbrute_worker_alloc(); + // TextInput instance->text_input = text_input_alloc(); view_dispatcher_add_view( @@ -96,8 +99,11 @@ SubBruteState* subbrute_alloc() { void subbrute_free(SubBruteState* instance) { furi_assert(instance); + // SubBruteWorker + subbrute_worker_stop(instance->worker); + subbrute_worker_free(instance->worker); + // SubBruteDevice - subbrute_worker_stop(instance->device); subbrute_device_free(instance->device); // Notifications @@ -163,13 +169,6 @@ void subbrute_popup_closed_callback(void* context) { instance->view_dispatcher, SubBruteCustomEventTypePopupClosed); } -uint64_t subbrute_get_step(void* context) { - furi_assert(context); - SubBruteState* instance = context; - - return subbrute_device_get_step(instance->device); -} - // ENTRYPOINT int32_t subbrute_app(void* p) { UNUSED(p); diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index fea298b8a..3e98c469d 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -8,40 +8,14 @@ #define TAG "SubBruteDevice" -#define SUBBRUTE_TX_TIMEOUT 5 -#define SUBBRUTE_MANUAL_TRANSMIT_INTERVAL 400 - -/** - * Values to not use less memory for packet parse operations - */ -static const char* subbrute_key_file_start = - "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d"; -static const char* subbrute_key_file_key = "%s\nKey: %s\nRepeat: %d\n"; -static const char* subbrute_key_file_key_with_tail = "%s\nKey: %s\nTE: %d\nRepeat: %d\n"; -static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\nRepeat: %d\n"; -static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; - SubBruteDevice* subbrute_device_alloc() { SubBruteDevice* instance = malloc(sizeof(SubBruteDevice)); - instance->state = SubBruteDeviceStateIDLE; instance->key_index = 0; - instance->worker_running = false; - instance->last_time_tx_data = 0; - - instance->thread = furi_thread_alloc(); - furi_thread_set_name(instance->thread, "SubBruteAttackWorker"); - furi_thread_set_stack_size(instance->thread, 2048); - furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, subbrute_worker_thread); - - instance->context = NULL; - instance->callback = NULL; instance->protocol_info = NULL; instance->file_protocol_info = NULL; instance->decoder_result = NULL; - instance->transmitter = NULL; instance->receiver = NULL; instance->environment = subghz_environment_alloc(); @@ -61,137 +35,15 @@ void subbrute_device_free(SubBruteDevice* instance) { instance->receiver = NULL; } - if(instance->transmitter != NULL) { - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; - } - subghz_environment_free(instance->environment); instance->environment = NULL; - furi_thread_free(instance->thread); subbrute_device_free_protocol_info(instance); free(instance); } -/** - * Entrypoint for worker - * - * @param context SubBruteWorker* - * @return 0 if ok - */ -int32_t subbrute_worker_thread(void* context) { - furi_assert(context); - SubBruteDevice* instance = (SubBruteDevice*)context; - - if(!instance->worker_running) { - FURI_LOG_W(TAG, "Worker is not set to running state!"); - return -1; - } - if(instance->state != SubBruteDeviceStateReady && - instance->state != SubBruteDeviceStateFinished) { - FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); - return -2; - } -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker start"); -#endif - - SubBruteDeviceState local_state = instance->state = SubBruteDeviceStateTx; - subbrute_device_send_callback(instance); - - FlipperFormat* flipper_format = flipper_format_string_alloc(); - - while(instance->worker_running) { - if(!subbrute_device_create_packet_parsed( - instance, flipper_format, instance->key_index, true)) { - FURI_LOG_W(TAG, "Error creating packet! BREAK"); - instance->worker_running = false; - local_state = SubBruteDeviceStateIDLE; - break; - } - subbrute_device_subghz_transmit(instance, flipper_format); - - if(instance->key_index + 1 > instance->max_value) { -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker finished to end"); -#endif - local_state = SubBruteDeviceStateFinished; - break; - } - instance->key_index++; - - furi_delay_ms(SUBBRUTE_TX_TIMEOUT); - } - - flipper_format_free(flipper_format); - - instance->worker_running = false; // Because we have error states - instance->state = local_state == SubBruteDeviceStateTx ? SubBruteDeviceStateReady : - local_state; - subbrute_device_send_callback(instance); - -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker stop"); -#endif - return 0; -} - -bool subbrute_worker_start(SubBruteDevice* instance) { - furi_assert(instance); - - if(instance->worker_running) { - FURI_LOG_W(TAG, "Worker is already running!"); - return false; - } - if(instance->state != SubBruteDeviceStateReady && - instance->state != SubBruteDeviceStateFinished) { - FURI_LOG_W(TAG, "Worker cannot start, invalid device state: %d", instance->state); - return false; - } - if((instance->protocol_info == NULL && instance->attack != SubBruteAttackLoadFile) || - (instance->attack == SubBruteAttackLoadFile && instance->file_protocol_info == NULL)) { - FURI_LOG_W(TAG, "Worker cannot start, protocol_info is NULL!"); - return false; - } - - instance->worker_running = true; - furi_thread_start(instance->thread); - - return true; -} - -void subbrute_worker_stop(SubBruteDevice* instance) { - furi_assert(instance); - - instance->worker_running = false; - - furi_thread_join(instance->thread); - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); -} - -SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance) { - return instance->attack; -} -bool subbrute_device_is_worker_running(SubBruteDevice* instance) { - return instance->worker_running; -} -uint64_t subbrute_device_get_max_value(SubBruteDevice* instance) { - return instance->max_value; -} -uint64_t subbrute_device_get_step(SubBruteDevice* instance) { - return instance->key_index; -} -const char* subbrute_device_get_file_key(SubBruteDevice* instance) { - return instance->file_key; -} uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step) { - if(!subbrute_device_can_manual_transmit(instance)) { - return instance->key_index; - } if(step > 0) { if((instance->key_index + step) - instance->max_value == 1) { instance->key_index = 0x00; @@ -220,122 +72,17 @@ uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step) { return instance->key_index; } -void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index) { - instance->load_index = load_index; -} -void subbrute_device_reset_step(SubBruteDevice* instance) { - instance->key_index = 0x00; -} -void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format) { - instance->transmitter = subghz_transmitter_alloc_init( - instance->environment, subbrute_protocol_name(instance->attack)); - subghz_transmitter_deserialize(instance->transmitter, flipper_format); - furi_hal_subghz_reset(); - if(instance->attack == SubBruteAttackLoadFile) { - furi_hal_subghz_load_preset(instance->file_protocol_info->preset); - furi_hal_subghz_set_frequency_and_path(instance->file_protocol_info->preset); - } else { - furi_hal_subghz_load_preset(instance->protocol_info->preset); - furi_hal_subghz_set_frequency_and_path(instance->protocol_info->preset); - } - furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter); - - while(!furi_hal_subghz_is_async_tx_complete()) { - furi_delay_ms(SUBBRUTE_TX_TIMEOUT); - } - furi_hal_subghz_stop_async_tx(); - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; -} - -bool subbrute_device_transmit_current_key(SubBruteDevice* instance) { - furi_assert(instance); - - if(instance->worker_running) { - FURI_LOG_W(TAG, "Worker in running state!"); - return false; - } - if(instance->state != SubBruteDeviceStateReady && - instance->state != SubBruteDeviceStateFinished) { - FURI_LOG_W(TAG, "Invalid state for running worker! State: %d", instance->state); - return false; - } - - uint32_t ticks = furi_get_tick(); - if((ticks - instance->last_time_tx_data) < SUBBRUTE_MANUAL_TRANSMIT_INTERVAL) { -#if FURI_DEBUG - FURI_LOG_D(TAG, "Need to wait, current: %ld", ticks - instance->last_time_tx_data); -#endif - return false; - } - - instance->last_time_tx_data = ticks; - -#ifdef FURI_DEBUG - if(instance->attack == SubBruteAttackLoadFile) { - FURI_LOG_D( - TAG, - "Protocol: %d, Frequency: %ld", - instance->file_protocol_info->file, - instance->file_protocol_info->frequency); - } else { - FURI_LOG_D( - TAG, - "Protocol: %d, Frequency: %ld", - instance->protocol_info->file, - instance->protocol_info->frequency); - } -#endif - - FlipperFormat* flipper_format = flipper_format_string_alloc(); - - if(!subbrute_device_create_packet_parsed(instance, flipper_format, instance->key_index, true)) { - FURI_LOG_W(TAG, "Error creating packet! EXIT"); - return false; - } - subbrute_device_subghz_transmit(instance, flipper_format); - - flipper_format_free(flipper_format); - - return true; -} - -void subbrute_device_set_callback( - SubBruteDevice* instance, - SubBruteDeviceWorkerCallback callback, - void* context) { - furi_assert(instance); - - instance->callback = callback; - instance->context = context; -} - -bool subbrute_device_can_manual_transmit(SubBruteDevice* instance) { - furi_assert(instance); - - return !instance->worker_running && instance->state != SubBruteDeviceStateIDLE && - instance->state != SubBruteDeviceStateTx && - ((furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_MANUAL_TRANSMIT_INTERVAL); -} bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_name) { furi_assert(instance); - if(instance->state != SubBruteDeviceStateReady && - instance->state != SubBruteDeviceStateFinished) { - FURI_LOG_W(TAG, "Worker is not set to running state!"); - return false; - } - #ifdef FURI_DEBUG FURI_LOG_D(TAG, "subbrute_device_save_file: %s", dev_file_name); #endif Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); + FuriString* file_content = furi_string_alloc(); bool result = false; do { @@ -343,7 +90,32 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na break; } - if(!subbrute_device_create_packet_parsed(instance, file, instance->key_index, false)) { + if(instance->attack == SubBruteAttackLoadFile) { + file_content = subbrute_protocol_file_generate_file( + instance->file_protocol_info->frequency, + instance->file_protocol_info->preset, + instance->file_protocol_info->file, + instance->key_index, + instance->file_protocol_info->bits, + instance->file_protocol_info->te, + instance->file_protocol_info->repeat, + instance->load_index, + instance->file_key); + } else { + file_content = subbrute_protocol_default_generate_file( + instance->protocol_info->frequency, + instance->protocol_info->preset, + instance->protocol_info->file, + instance->key_index, + instance->protocol_info->bits, + instance->protocol_info->te, + instance->protocol_info->repeat); + } + + Stream* stream = flipper_format_get_raw_stream(file); + stream_clean(stream); + size_t written = stream_write_string(stream, file_content); + if(written <= 0) { FURI_LOG_E(TAG, "create_packet_parsed failed!"); break; } @@ -352,140 +124,17 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na } while(false); if(!result) { - FURI_LOG_E(TAG, "flipper_format_file_open_always failed!"); + FURI_LOG_E(TAG, "subbrute_device_save_file failed!"); } + flipper_format_file_close(file); flipper_format_free(file); furi_record_close(RECORD_STORAGE); + furi_string_free(file_content); return result; } -bool subbrute_device_create_packet_parsed( - SubBruteDevice* instance, - FlipperFormat* flipper_format, - uint64_t step, - bool small) { - furi_assert(instance); - - FuriString* candidate = furi_string_alloc(); - - Stream* stream = flipper_format_get_raw_stream(flipper_format); - stream_clean(stream); - - if(instance->attack == SubBruteAttackLoadFile) { - if(step >= sizeof(instance->file_key)) { - return false; - } - char subbrute_payload_byte[4]; - furi_string_set_str(candidate, instance->file_key); - snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); - furi_string_replace_at(candidate, instance->load_index * 3, 3, subbrute_payload_byte); - //snprintf(step_payload, sizeof(step_payload), "%02X", (uint8_t)instance->file_key[step]); - - if(small) { - if(instance->file_protocol_info->te) { - stream_write_format( - stream, - subbrute_key_small_with_tail, - instance->file_protocol_info->bits, - furi_string_get_cstr(candidate), - instance->file_protocol_info->te, - instance->file_protocol_info->repeat); - } else { - stream_write_format( - stream, - subbrute_key_small_no_tail, - instance->file_protocol_info->bits, - furi_string_get_cstr(candidate), - instance->file_protocol_info->repeat); - } - } else { - if(instance->file_protocol_info->te) { - stream_write_format( - stream, - subbrute_key_file_key_with_tail, - instance->file_template, - furi_string_get_cstr(candidate), - instance->file_protocol_info->te, - instance->file_protocol_info->repeat); - } else { - stream_write_format( - stream, - subbrute_key_file_key, - instance->file_template, - furi_string_get_cstr(candidate), - instance->file_protocol_info->repeat); - } - } - } else { - //snprintf(step_payload, sizeof(step_payload), "%16X", step); - //snprintf(step_payload, sizeof(step_payload), "%016llX", step); - FuriString* buffer = furi_string_alloc(); - furi_string_printf(buffer, "%16llX", step); - int j = 0; - furi_string_set_str(candidate, " "); - for(uint8_t i = 0; i < 16; i++) { - if(furi_string_get_char(buffer, i) != ' ') { - furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i)); - } else { - furi_string_set_char(candidate, i + j, '0'); - } - if(i % 2 != 0) { - j++; - } - } - furi_string_free(buffer); - -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); -#endif - - if(small) { - if(instance->protocol_info->te) { - stream_write_format( - stream, - subbrute_key_small_with_tail, - instance->protocol_info->bits, - furi_string_get_cstr(candidate), - instance->protocol_info->te, - instance->protocol_info->repeat); - } else { - stream_write_format( - stream, - subbrute_key_small_no_tail, - instance->protocol_info->bits, - furi_string_get_cstr(candidate), - instance->protocol_info->repeat); - } - } else { - if(instance->protocol_info->te) { - stream_write_format( - stream, - subbrute_key_file_key_with_tail, - instance->file_template, - furi_string_get_cstr(candidate), - instance->protocol_info->te, - instance->protocol_info->repeat); - } else { - stream_write_format( - stream, - subbrute_key_file_key, - instance->file_template, - furi_string_get_cstr(candidate), - instance->protocol_info->repeat); - } - } -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s", furi_string_get_cstr(candidate)); -#endif - } - - furi_string_free(candidate); - - return true; -} - SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBruteAttacks type) { furi_assert(instance); #ifdef FURI_DEBUG @@ -513,10 +162,18 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute FURI_LOG_E(TAG, "Can't load SubGhzProtocolDecoderBase in phase non-file decoder set"); } else { protocol_check_result = SubBruteFileResultOk; + + // Calc max value + instance->max_value = + subbrute_protocol_calc_max_value(instance->attack, instance->protocol_info->bits); } } else { // And here we need to set preset enum protocol_check_result = SubBruteFileResultOk; + + // Calc max value + instance->max_value = + subbrute_protocol_calc_max_value(instance->attack, instance->file_protocol_info->bits); } subghz_receiver_free(instance->receiver); @@ -526,56 +183,6 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute return SubBruteFileResultProtocolNotFound; } - // Calc max value - if(instance->attack == SubBruteAttackLoadFile) { - instance->max_value = 0x3F; - - // Now we are ready to set file template for using in the future with snprintf - // for sending attack payload ONLY for files! - snprintf( - instance->file_template, - sizeof(instance->file_template), - subbrute_key_file_start, - instance->file_protocol_info->frequency, - subbrute_protocol_preset(instance->file_protocol_info->preset), - subbrute_protocol_file(instance->file_protocol_info->file), - instance->file_protocol_info->bits); - } else { - FuriString* max_value_s; - max_value_s = furi_string_alloc(); - for(uint8_t i = 0; i < instance->protocol_info->bits; i++) { - furi_string_cat_printf(max_value_s, "1"); - } - instance->max_value = (uint64_t)strtol(furi_string_get_cstr(max_value_s), NULL, 2); - furi_string_free(max_value_s); - - // Now we are ready to set file template for using in the future with snprintf - // for sending attack payload - snprintf( - instance->file_template, - sizeof(instance->file_template), - subbrute_key_file_start, - instance->protocol_info->frequency, - subbrute_protocol_preset(instance->protocol_info->preset), - subbrute_protocol_file(instance->protocol_info->file), - instance->protocol_info->bits); -#ifdef FURI_DEBUG - FURI_LOG_D( - TAG, - "tail: %d, file_template: %s", - instance->protocol_info->te, - instance->file_template); -#endif - } - - // Init payload - FlipperFormat* flipper_format = flipper_format_string_alloc(); - if(subbrute_device_create_packet_parsed(instance, flipper_format, instance->key_index, false)) { - instance->state = SubBruteDeviceStateReady; - subbrute_device_send_callback(instance); - } - flipper_format_free(flipper_format); - return SubBruteFileResultOk; } @@ -751,7 +358,6 @@ void subbrute_device_attack_set_default_values( instance->attack = default_attack; instance->key_index = 0x00; instance->load_index = 0x00; - memset(instance->file_template, 0, sizeof(instance->file_template)); memset(instance->current_key, 0, sizeof(instance->current_key)); if(default_attack != SubBruteAttackLoadFile) { @@ -761,12 +367,6 @@ void subbrute_device_attack_set_default_values( } } -void subbrute_device_send_callback(SubBruteDevice* instance) { - if(instance->callback != NULL) { - instance->callback(instance->context, instance->state); - } -} - const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { const char* result; switch(error_id) { diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index e3b327b85..b0f136ad2 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -31,19 +31,9 @@ typedef enum { SubBruteFileResultMissingOrIncorrectTe, } SubBruteFileResult; -typedef enum { - SubBruteDeviceStateIDLE, - SubBruteDeviceStateReady, - SubBruteDeviceStateTx, - SubBruteDeviceStateFinished -} SubBruteDeviceState; - -typedef void (*SubBruteDeviceWorkerCallback)(void* context, SubBruteDeviceState state); typedef struct { - SubBruteDeviceState state; const SubBruteProtocol* protocol_info; SubBruteProtocol* file_protocol_info; - volatile bool worker_running; // Current step uint64_t key_index; @@ -51,28 +41,17 @@ typedef struct { uint8_t load_index; // SubGhz - FuriThread* thread; SubGhzReceiver* receiver; SubGhzProtocolDecoderBase* decoder_result; SubGhzEnvironment* environment; - SubGhzTransmitter* transmitter; // Attack state SubBruteAttacks attack; - char file_template[SUBBRUTE_TEXT_STORE_SIZE]; - uint64_t max_value; // Loaded info for attack type char current_key[SUBBRUTE_PAYLOAD_SIZE]; char file_key[SUBBRUTE_MAX_LEN_NAME]; - - // Manual transmit - uint32_t last_time_tx_data; - - // Callback for changed states - SubBruteDeviceWorkerCallback callback; - void* context; } SubBruteDevice; SubBruteDevice* subbrute_device_alloc(); @@ -83,33 +62,9 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id); SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* context, SubBruteAttacks type); uint8_t subbrute_device_load_from_file(SubBruteDevice* context, const char* file_path); -bool subbrute_device_is_worker_running(SubBruteDevice* instance); -SubBruteAttacks subbrute_device_get_attack(SubBruteDevice* instance); -uint64_t subbrute_device_get_max_value(SubBruteDevice* instance); -uint64_t subbrute_device_get_step(SubBruteDevice* instance); uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step); -void subbrute_device_set_load_index(SubBruteDevice* instance, uint64_t load_index); -void subbrute_device_reset_step(SubBruteDevice* instance); -const char* subbrute_device_get_file_key(SubBruteDevice* instance); - -bool subbrute_worker_start(SubBruteDevice* instance); -void subbrute_worker_stop(SubBruteDevice* instance); -bool subbrute_device_transmit_current_key(SubBruteDevice* instance); -bool subbrute_device_can_manual_transmit(SubBruteDevice* instance); -void subbrute_device_set_callback( - SubBruteDevice* instance, - SubBruteDeviceWorkerCallback callback, - void* context); void subbrute_device_free_protocol_info(SubBruteDevice* instance); -int32_t subbrute_worker_thread(void* context); void subbrute_device_attack_set_default_values( SubBruteDevice* context, - SubBruteAttacks default_attack); -bool subbrute_device_create_packet_parsed( - SubBruteDevice* instance, - FlipperFormat* flipper_format, - uint64_t step, - bool small); -void subbrute_device_send_callback(SubBruteDevice* instance); -void subbrute_device_subghz_transmit(SubBruteDevice* instance, FlipperFormat* flipper_format); + SubBruteAttacks default_attack); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_i.h b/applications/plugins/subbrute/subbrute_i.h index 856a0b83d..edd87eb0f 100644 --- a/applications/plugins/subbrute/subbrute_i.h +++ b/applications/plugins/subbrute/subbrute_i.h @@ -23,6 +23,7 @@ #include "subbrute.h" #include "subbrute_device.h" +#include "helpers/subbrute_worker.h" #include "views/subbrute_attack_view.h" #include "views/subbrute_main_view.h" @@ -62,9 +63,10 @@ struct SubBruteState { // SubBruteDevice SubBruteDevice* device; + // SubBruteWorker + SubBruteWorker* worker; }; void subbrute_show_loading_popup(void* context, bool show); void subbrute_text_input_callback(void* context); -void subbrute_popup_closed_callback(void* context); -uint64_t subbrute_get_step(void* context); \ No newline at end of file +void subbrute_popup_closed_callback(void* context); \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index 462732937..81e00d02f 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -1,5 +1,7 @@ #include "subbrute_protocols.h" +#define TAG "SubBruteProtocols" + /** * CAME 12bit 303MHz */ @@ -201,6 +203,16 @@ static const char* subbrute_protocol_file_types[] = { [PrincetonFileProtocol] = "Princeton", [RAWFileProtocol] = "RAW"}; +/** + * Values to not use less memory for packet parse operations + */ +static const char* subbrute_key_file_start_no_tail = + "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nRepeat: %d\n"; +static const char* subbrute_key_file_start_with_tail = + "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; +static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\nRepeat: %d\n"; +static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; + const char* subbrute_protocol_name(SubBruteAttacks index) { return subbrute_protocol_names[index]; } @@ -235,4 +247,210 @@ SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name) { } return RAWFileProtocol; +} + +FuriString* + subbrute_protocol_default_payload(uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat) { + FuriString* candidate = furi_string_alloc_set_str(" "); + + FuriString* buffer = furi_string_alloc_printf("%16llX", step); + int j = 0; + for(uint8_t i = 0; i < 16; i++) { + if(furi_string_get_char(buffer, i) != ' ') { + furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i)); + } else { + furi_string_set_char(candidate, i + j, '0'); + } + if(i % 2 != 0) { + j++; + } + } + furi_string_free(buffer); + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); +#endif + FuriString* result; + + if(te) { + result = furi_string_alloc_printf( + subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat); + } else { + result = furi_string_alloc_printf( + subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); + } +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); +#endif + + furi_string_free(candidate); + + return result; +} + +FuriString* subbrute_protocol_file_payload( + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat, + uint8_t load_index, + const char* file_key) { + FuriString* candidate = furi_string_alloc(); + if(step >= sizeof(file_key)) { + return false; + } + char subbrute_payload_byte[4]; + furi_string_set_str(candidate, file_key); + snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); + furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte); + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); +#endif + FuriString* result; + + if(te) { + result = furi_string_alloc_printf( + subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat); + } else { + result = furi_string_alloc_printf( + subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); + } + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); +#endif + + furi_string_free(candidate); + + return result; +} + +FuriString* subbrute_protocol_default_generate_file( + uint32_t frequency, + FuriHalSubGhzPreset preset, + SubBruteFileProtocol file, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat) { + FuriString* candidate = furi_string_alloc_set_str(" "); + + FuriString* buffer = furi_string_alloc_printf("%16llX", step); + int j = 0; + for(uint8_t i = 0; i < 16; i++) { + if(furi_string_get_char(buffer, i) != ' ') { + furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i)); + } else { + furi_string_set_char(candidate, i + j, '0'); + } + if(i % 2 != 0) { + j++; + } + } + furi_string_free(buffer); + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); +#endif + FuriString* result; + + if(te) { + result = furi_string_alloc_printf( + subbrute_key_file_start_with_tail, + frequency, + preset, + file, + bits, + furi_string_get_cstr(candidate), + te, + repeat); + } else { + result = furi_string_alloc_printf( + subbrute_key_file_start_no_tail, + frequency, + preset, + file, + bits, + furi_string_get_cstr(candidate), + repeat); + } +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); +#endif + + furi_string_free(candidate); + + return result; +} + +FuriString* subbrute_protocol_file_generate_file( + uint32_t frequency, + FuriHalSubGhzPreset preset, + SubBruteFileProtocol file, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat, + uint8_t load_index, + const char* file_key) { + FuriString* candidate = furi_string_alloc(); + if(step >= sizeof(file_key)) { + return false; + } + char subbrute_payload_byte[4]; + furi_string_set_str(candidate, file_key); + snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); + furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte); + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); +#endif + FuriString* result; + + if(te) { + result = furi_string_alloc_printf( + subbrute_key_file_start_with_tail, + frequency, + preset, + file, + bits, + furi_string_get_cstr(candidate), + te, + repeat); + } else { + result = furi_string_alloc_printf( + subbrute_key_file_start_no_tail, + frequency, + preset, + file, + bits, + furi_string_get_cstr(candidate), + repeat); + } + +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); +#endif + + furi_string_free(candidate); + + return result; +} + +uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) { + uint64_t max_value; + if(attack_type == SubBruteAttackLoadFile) { + max_value = 0x3F; + } else { + FuriString* max_value_s; + max_value_s = furi_string_alloc(); + for(uint8_t i = 0; i < bits; i++) { + furi_string_cat_printf(max_value_s, "1"); + } + max_value = (uint64_t)strtol(furi_string_get_cstr(max_value_s), NULL, 2); + furi_string_free(max_value_s); + } + + return max_value; } \ No newline at end of file diff --git a/applications/plugins/subbrute/subbrute_protocols.h b/applications/plugins/subbrute/subbrute_protocols.h index f876ed756..747328d5b 100644 --- a/applications/plugins/subbrute/subbrute_protocols.h +++ b/applications/plugins/subbrute/subbrute_protocols.h @@ -54,4 +54,33 @@ const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset); const char* subbrute_protocol_file(SubBruteFileProtocol protocol); FuriHalSubGhzPreset subbrute_protocol_convert_preset(FuriString* preset_name); SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name); -const char* subbrute_protocol_name(SubBruteAttacks index); \ No newline at end of file +const char* subbrute_protocol_name(SubBruteAttacks index); + +FuriString* + subbrute_protocol_default_payload(uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat); +FuriString* subbrute_protocol_file_payload( + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat, + uint8_t load_index, + const char* file_key); +FuriString* subbrute_protocol_default_generate_file( + uint32_t frequency, + FuriHalSubGhzPreset preset, + SubBruteFileProtocol file, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat); +FuriString* subbrute_protocol_file_generate_file( + uint32_t frequency, + FuriHalSubGhzPreset preset, + SubBruteFileProtocol file, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat, + uint8_t load_index, + const char* file_key); +uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits); \ No newline at end of file diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 2010e9ae2..bfac24b8b 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -227,10 +227,7 @@ bool subbrute_main_view_input(InputEvent* event, void* context) { #ifdef FURI_DEBUG with_view_model( - instance->view, (SubBruteMainViewModel * model) { - index = model->index; - return false; - }); + instance->view, SubBruteMainViewModel * model, { index = model->index; }, false); FURI_LOG_I(TAG, "Index: %d", index); #endif @@ -265,10 +262,7 @@ bool subbrute_main_view_input(InputEvent* event, void* context) { #ifdef FURI_DEBUG with_view_model( - instance->view, (SubBruteMainViewModel * model) { - index = model->index; - return false; - }); + instance->view, SubBruteMainViewModel * model, { index = model->index; }, false); FURI_LOG_I(TAG, "Index: %d", index); #endif From eed8cd18241c1b3e9aa42c39875ccefbe4b65bec Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 01:44:37 +0400 Subject: [PATCH 07/14] fix problem with sending --- .../subbrute/helpers/subbrute_worker.c | 76 +++++++++++++++---- .../helpers/subbrute_worker_private.h | 3 +- .../scenes/subbrute_scene_run_attack.c | 9 ++- .../subbrute/scenes/subbrute_scene_start.c | 7 +- .../plugins/subbrute/subbrute_device.c | 34 +++++++++ .../plugins/subbrute/subbrute_protocols.c | 10 +-- 6 files changed, 118 insertions(+), 21 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 4d7e98fa4..345539eb5 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -12,7 +12,7 @@ SubBruteWorker* subbrute_worker_alloc() { SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); instance->state = SubBruteWorkerStateIDLE; - instance->key_index = 0; + instance->step = 0; instance->worker_running = false; instance->initiated = false; instance->last_time_tx_data = 0; @@ -31,6 +31,8 @@ SubBruteWorker* subbrute_worker_alloc() { instance->transmitter = NULL; instance->environment = subghz_environment_alloc(); + instance->transmit_mode = false; + return instance; } @@ -54,7 +56,7 @@ void subbrute_worker_free(SubBruteWorker* instance) { } uint64_t subbrute_worker_get_step(SubBruteWorker* instance) { - return instance->key_index; + return instance->step; } bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step) { @@ -64,7 +66,7 @@ bool subbrute_worker_set_step(SubBruteWorker* instance, uint64_t step) { return false; } - instance->key_index = step; + instance->step = step; return true; } @@ -85,13 +87,30 @@ bool subbrute_worker_init_default_attack( instance->frequency = protocol->frequency; instance->preset = protocol->preset; instance->file = protocol->file; - instance->key_index = step; + instance->step = step; instance->bits = protocol->bits; instance->te = protocol->te; + instance->repeat = protocol->repeat; instance->load_index = 0; instance->file_key = NULL; instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits); + instance->initiated = true; + instance->state = SubBruteWorkerStateReady; + subbrute_worker_send_callback(instance); +#ifdef FURI_DEBUG + FURI_LOG_I( + TAG, + "subbrute_worker_init_default_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld", + subbrute_protocol_name(instance->attack), + instance->bits, + subbrute_protocol_preset(instance->preset), + subbrute_protocol_file(instance->file), + instance->te, + instance->repeat, + instance->max_value); +#endif + return true; } @@ -112,13 +131,30 @@ bool subbrute_worker_init_file_attack( instance->frequency = protocol->frequency; instance->preset = protocol->preset; instance->file = protocol->file; - instance->key_index = step; + instance->step = step; instance->bits = protocol->bits; instance->te = protocol->te; instance->load_index = load_index; + instance->repeat = protocol->repeat; instance->file_key = file_key; instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->bits); + instance->initiated = true; + instance->state = SubBruteWorkerStateReady; + subbrute_worker_send_callback(instance); +#ifdef FURI_DEBUG + FURI_LOG_I( + TAG, + "subbrute_worker_init_file_attack: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld", + subbrute_protocol_name(instance->attack), + instance->bits, + subbrute_protocol_preset(instance->preset), + subbrute_protocol_file(instance->file), + instance->te, + instance->repeat, + instance->max_value); +#endif + return true; } @@ -183,13 +219,13 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste } instance->last_time_tx_data = ticks; - instance->key_index = step; + instance->step = step; bool result; FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); - FuriString* payload = furi_string_alloc(); + FuriString* payload = NULL; stream_clean(stream); if(instance->attack == SubBruteAttackLoadFile) { @@ -252,8 +288,16 @@ void subbrute_worker_set_callback( } void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* flipper_format) { + while(instance->transmit_mode) { + furi_delay_ms(SUBBRUTE_TX_TIMEOUT); + } + instance->transmit_mode = true; + if(instance->transmitter != NULL) { + subghz_transmitter_free(instance->transmitter); + instance->transmitter = NULL; + } instance->transmitter = subghz_transmitter_alloc_init( - instance->environment, subbrute_protocol_name(instance->attack)); + instance->environment, subbrute_protocol_file(instance->file)); subghz_transmitter_deserialize(instance->transmitter, flipper_format); furi_hal_subghz_reset(); furi_hal_subghz_load_preset(instance->preset); @@ -269,6 +313,8 @@ void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* fl furi_hal_subghz_sleep(); subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; + + instance->transmit_mode = false; } void subbrute_worker_send_callback(SubBruteWorker* instance) { @@ -307,12 +353,12 @@ int32_t subbrute_worker_thread(void* context) { Stream* stream = flipper_format_get_raw_stream(flipper_format); while(instance->worker_running) { - FuriString* payload = furi_string_alloc(); + FuriString* payload = NULL; stream_clean(stream); if(instance->attack == SubBruteAttackLoadFile) { payload = subbrute_protocol_file_payload( - instance->key_index, + instance->step, instance->bits, instance->te, instance->repeat, @@ -320,8 +366,12 @@ int32_t subbrute_worker_thread(void* context) { instance->file_key); } else { payload = subbrute_protocol_default_payload( - instance->key_index, instance->bits, instance->te, instance->repeat); + instance->step, instance->bits, instance->te, instance->repeat); } +#ifdef FURI_DEBUG + FURI_LOG_I(TAG, "Payload: %s", furi_string_get_cstr(payload)); + furi_delay_ms(SUBBRUTE_MANUAL_TRANSMIT_INTERVAL / 4); +#endif size_t written = stream_write_string(stream, payload); if(written <= 0) { @@ -334,7 +384,7 @@ int32_t subbrute_worker_thread(void* context) { subbrute_worker_subghz_transmit(instance, flipper_format); - if(instance->key_index + 1 > instance->max_value) { + if(instance->step + 1 > instance->max_value) { #ifdef FURI_DEBUG FURI_LOG_I(TAG, "Worker finished to end"); #endif @@ -342,7 +392,7 @@ int32_t subbrute_worker_thread(void* context) { furi_string_free(payload); break; } - instance->key_index++; + instance->step++; furi_string_free(payload); furi_delay_ms(SUBBRUTE_TX_TIMEOUT); diff --git a/applications/plugins/subbrute/helpers/subbrute_worker_private.h b/applications/plugins/subbrute/helpers/subbrute_worker_private.h index fd55902bb..7da16df08 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker_private.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker_private.h @@ -10,9 +10,10 @@ struct SubBruteWorker { SubBruteWorkerState state; volatile bool worker_running; volatile bool initiated; + volatile bool transmit_mode; // Current step - uint64_t key_index; + uint64_t step; // SubGhz FuriThread* thread; diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 17a3d910a..6e449e227 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -46,7 +46,10 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->worker, subbrute_scene_run_attack_device_state_changed, instance); if(!subbrute_worker_is_running(instance->worker)) { - subbrute_worker_start(instance->worker); + if(!subbrute_worker_start(instance->worker)) { + view_dispatcher_send_custom_event( + instance->view_dispatcher, SubBruteCustomEventTypeError); + } } } @@ -72,6 +75,10 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) 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->key_index); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_start.c b/applications/plugins/subbrute/scenes/subbrute_scene_start.c index 2d7bc5134..677b1ef20 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_start.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_start.c @@ -41,7 +41,12 @@ bool subbrute_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Event: %ld", event.event); + FURI_LOG_D( + TAG, + "Event: %ld, SubBruteCustomEventTypeMenuSelected: %s, SubBruteCustomEventTypeLoadFile: %s", + event.event, + event.event == SubBruteCustomEventTypeMenuSelected ? "true" : "false", + event.event == SubBruteCustomEventTypeLoadFile ? "true" : "false"); #endif if(event.event == SubBruteCustomEventTypeMenuSelected) { SubBruteAttacks attack = subbrute_main_view_get_index(instance->view_main); diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 3e98c469d..8e94c4255 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -153,6 +153,13 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute furi_hal_subghz_reset(); uint8_t protocol_check_result = SubBruteFileResultProtocolNotFound; +#ifdef FURI_DEBUG + uint8_t bits; + uint8_t te; + uint8_t repeat; + FuriHalSubGhzPreset preset; + SubBruteFileProtocol file; +#endif if(type != SubBruteAttackLoadFile) { instance->decoder_result = subghz_receiver_search_decoder_base_by_name( instance->receiver, subbrute_protocol_file(instance->protocol_info->file)); @@ -167,6 +174,13 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->protocol_info->bits); } +#ifdef FURI_DEBUG + bits = instance->protocol_info->bits; + te = instance->protocol_info->te; + repeat = instance->protocol_info->repeat; + preset = instance->protocol_info->preset; + file = instance->protocol_info->file; +#endif } else { // And here we need to set preset enum protocol_check_result = SubBruteFileResultOk; @@ -174,6 +188,13 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute // Calc max value instance->max_value = subbrute_protocol_calc_max_value(instance->attack, instance->file_protocol_info->bits); +#ifdef FURI_DEBUG + bits = instance->file_protocol_info->bits; + te = instance->file_protocol_info->te; + repeat = instance->file_protocol_info->repeat; + preset = instance->file_protocol_info->preset; + file = instance->file_protocol_info->file; +#endif } subghz_receiver_free(instance->receiver); @@ -183,6 +204,19 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute return SubBruteFileResultProtocolNotFound; } +#ifdef FURI_DEBUG + FURI_LOG_I( + TAG, + "subbrute_device_attack_set: %s, bits: %d, preset: %s, file: %s, te: %d, repeat: %d, max_value: %lld", + subbrute_protocol_name(instance->attack), + bits, + subbrute_protocol_preset(preset), + subbrute_protocol_file(file), + te, + repeat, + instance->max_value); +#endif + return SubBruteFileResultOk; } diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index 81e00d02f..512152e61 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -210,7 +210,7 @@ static const char* subbrute_key_file_start_no_tail = "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nRepeat: %d\n"; static const char* subbrute_key_file_start_with_tail = "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; -static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\nRepeat: %d\n"; +static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\n"; static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\nRepeat: %d\n"; const char* subbrute_protocol_name(SubBruteAttacks index) { @@ -268,7 +268,7 @@ FuriString* furi_string_free(buffer); #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); + //FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif FuriString* result; @@ -280,7 +280,7 @@ FuriString* subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); } #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); + //FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); #endif furi_string_free(candidate); @@ -305,7 +305,7 @@ FuriString* subbrute_protocol_file_payload( furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte); #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); + //FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif FuriString* result; @@ -318,7 +318,7 @@ FuriString* subbrute_protocol_file_payload( } #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); + //FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); #endif furi_string_free(candidate); From b65a2e9c94ab2d1bb75c7e857f45869205899e3e Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 02:52:32 +0400 Subject: [PATCH 08/14] fix send with dump file --- .../subbrute/helpers/subbrute_worker.c | 61 ++++++------ .../scenes/subbrute_scene_run_attack.c | 15 ++- .../plugins/subbrute/subbrute_device.c | 28 +++--- .../plugins/subbrute/subbrute_protocols.c | 94 +++++++++---------- .../plugins/subbrute/subbrute_protocols.h | 19 ++-- .../subbrute/views/subbrute_main_view.c | 4 +- 6 files changed, 111 insertions(+), 110 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 345539eb5..0188cfecc 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -225,11 +225,11 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); - FuriString* payload = NULL; stream_clean(stream); if(instance->attack == SubBruteAttackLoadFile) { - payload = subbrute_protocol_file_payload( + subbrute_protocol_file_payload( + stream, step, instance->bits, instance->te, @@ -237,25 +237,25 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste instance->load_index, instance->file_key); } else { - payload = subbrute_protocol_default_payload( - step, instance->bits, instance->te, instance->repeat); + subbrute_protocol_default_payload( + stream, step, instance->bits, instance->te, instance->repeat); } - size_t written = stream_write_string(stream, payload); - if(written <= 0) { - FURI_LOG_W(TAG, "Error creating packet! EXIT"); - result = false; - } else { - subbrute_worker_subghz_transmit(instance, flipper_format); + // size_t written = stream_write_string(stream, payload); + // if(written <= 0) { + // FURI_LOG_W(TAG, "Error creating packet! EXIT"); + // result = false; + // } else { + subbrute_worker_subghz_transmit(instance, flipper_format); - result = true; + result = true; #if FURI_DEBUG - FURI_LOG_D(TAG, "Manual transmit done"); + FURI_LOG_D(TAG, "Manual transmit done"); #endif - } + // } flipper_format_free(flipper_format); - furi_string_free(payload); +// furi_string_free(payload); return result; } @@ -353,11 +353,10 @@ int32_t subbrute_worker_thread(void* context) { Stream* stream = flipper_format_get_raw_stream(flipper_format); while(instance->worker_running) { - FuriString* payload = NULL; stream_clean(stream); - if(instance->attack == SubBruteAttackLoadFile) { - payload = subbrute_protocol_file_payload( + subbrute_protocol_file_payload( + stream, instance->step, instance->bits, instance->te, @@ -365,22 +364,22 @@ int32_t subbrute_worker_thread(void* context) { instance->load_index, instance->file_key); } else { - payload = subbrute_protocol_default_payload( - instance->step, instance->bits, instance->te, instance->repeat); + subbrute_protocol_default_payload( + stream, instance->step, instance->bits, instance->te, instance->repeat); } #ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Payload: %s", furi_string_get_cstr(payload)); - furi_delay_ms(SUBBRUTE_MANUAL_TRANSMIT_INTERVAL / 4); + //FURI_LOG_I(TAG, "Payload: %s", furi_string_get_cstr(payload)); + //furi_delay_ms(SUBBRUTE_MANUAL_TRANSMIT_INTERVAL / 4); #endif - size_t written = stream_write_string(stream, payload); - if(written <= 0) { - FURI_LOG_W(TAG, "Error creating packet! BREAK"); - instance->worker_running = false; - local_state = SubBruteWorkerStateIDLE; - furi_string_free(payload); - break; - } + // size_t written = stream_write_stream_write_string(stream, payload); + // if(written <= 0) { + // FURI_LOG_W(TAG, "Error creating packet! BREAK"); + // instance->worker_running = false; + // local_state = SubBruteWorkerStateIDLE; + // furi_string_free(payload); + // break; + // } subbrute_worker_subghz_transmit(instance, flipper_format); @@ -389,12 +388,12 @@ int32_t subbrute_worker_thread(void* context) { FURI_LOG_I(TAG, "Worker finished to end"); #endif local_state = SubBruteWorkerStateFinished; - furi_string_free(payload); + // furi_string_free(payload); break; } instance->step++; - furi_string_free(payload); + // furi_string_free(payload); furi_delay_ms(SUBBRUTE_TX_TIMEOUT); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 6e449e227..d6e4bad0b 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -46,9 +46,13 @@ void subbrute_scene_run_attack_on_enter(void* context) { 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->key_index); 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); } } } @@ -60,11 +64,14 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - subbrute_attack_view_set_current_step(view, subbrute_worker_get_step(instance->worker)); + uint64_t step = subbrute_worker_get_step(instance->worker); + instance->device->key_index = 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_single_vibro); + notification_message(instance->notifications, &sequence_double_vibro); + scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); } else if( @@ -84,7 +91,9 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } consumed = true; } else if(event.type == SceneManagerEventTypeTick) { - subbrute_attack_view_set_current_step(view, subbrute_worker_get_step(instance->worker)); + uint64_t step = subbrute_worker_get_step(instance->worker); + instance->device->key_index = step; + subbrute_attack_view_set_current_step(view, step); consumed = true; } diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 8e94c4255..0b23e61e2 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -19,8 +19,11 @@ SubBruteDevice* subbrute_device_alloc() { instance->receiver = NULL; instance->environment = subghz_environment_alloc(); +#ifdef FURI_DEBUG + subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); +#else subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); - +#endif return instance; } @@ -61,7 +64,7 @@ uint64_t subbrute_device_add_step(SubBruteDevice* instance, int8_t step) { } else if(instance->key_index == 0) { instance->key_index = instance->max_value; } else { - uint64_t value = ((instance->key_index - step) + instance->max_value); + uint64_t value = ((instance->key_index + step) + instance->max_value); if(value == instance->max_value) { instance->key_index = value; } else { @@ -82,16 +85,15 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); - FuriString* file_content = furi_string_alloc(); - bool result = false; do { if(!flipper_format_file_open_always(file, dev_file_name)) { break; } - + Stream* stream = flipper_format_get_raw_stream(file); if(instance->attack == SubBruteAttackLoadFile) { - file_content = subbrute_protocol_file_generate_file( + subbrute_protocol_file_generate_file( + stream, instance->file_protocol_info->frequency, instance->file_protocol_info->preset, instance->file_protocol_info->file, @@ -102,7 +104,8 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na instance->load_index, instance->file_key); } else { - file_content = subbrute_protocol_default_generate_file( + subbrute_protocol_default_generate_file( + stream, instance->protocol_info->frequency, instance->protocol_info->preset, instance->protocol_info->file, @@ -112,14 +115,6 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na instance->protocol_info->repeat); } - Stream* stream = flipper_format_get_raw_stream(file); - stream_clean(stream); - size_t written = stream_write_string(stream, file_content); - if(written <= 0) { - FURI_LOG_E(TAG, "create_packet_parsed failed!"); - break; - } - result = true; } while(false); @@ -130,7 +125,6 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na flipper_format_file_close(file); flipper_format_free(file); furi_record_close(RECORD_STORAGE); - furi_string_free(file_content); return result; } @@ -342,7 +336,7 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, const char* fil //result = SubBruteFileResultMissingOrIncorrectTe; //break; } else { - instance->file_protocol_info->te = temp_data32 != 0; + instance->file_protocol_info->te = temp_data32 != 0 ? temp_data32 : 0; } // Repeat diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index 512152e61..c4ef1c662 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -1,4 +1,5 @@ #include "subbrute_protocols.h" +#include #define TAG "SubBruteProtocols" @@ -249,8 +250,12 @@ SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name) { return RAWFileProtocol; } -FuriString* - subbrute_protocol_default_payload(uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat) { +void subbrute_protocol_default_payload( + Stream* stream, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat) { FuriString* candidate = furi_string_alloc_set_str(" "); FuriString* buffer = furi_string_alloc_printf("%16llX", step); @@ -270,25 +275,25 @@ FuriString* #ifdef FURI_DEBUG //FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif - FuriString* result; - + stream_clean(stream); if(te) { - result = furi_string_alloc_printf( - subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat); + stream_write_format( + stream, + subbrute_key_small_with_tail, + bits, + furi_string_get_cstr(candidate), + te, + repeat); } else { - result = furi_string_alloc_printf( - subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); + stream_write_format( + stream, subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); } -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); -#endif furi_string_free(candidate); - - return result; } -FuriString* subbrute_protocol_file_payload( +void subbrute_protocol_file_payload( + Stream* stream, uint64_t step, uint8_t bits, uint8_t te, @@ -296,9 +301,6 @@ FuriString* subbrute_protocol_file_payload( uint8_t load_index, const char* file_key) { FuriString* candidate = furi_string_alloc(); - if(step >= sizeof(file_key)) { - return false; - } char subbrute_payload_byte[4]; furi_string_set_str(candidate, file_key); snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); @@ -307,26 +309,26 @@ FuriString* subbrute_protocol_file_payload( #ifdef FURI_DEBUG //FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif - FuriString* result; + stream_clean(stream); if(te) { - result = furi_string_alloc_printf( - subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat); + stream_write_format( + stream, + subbrute_key_small_with_tail, + bits, + furi_string_get_cstr(candidate), + te, + repeat); } else { - result = furi_string_alloc_printf( - subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); + stream_write_format( + stream, subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat); } -#ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); -#endif - furi_string_free(candidate); - - return result; } -FuriString* subbrute_protocol_default_generate_file( +void subbrute_protocol_default_generate_file( + Stream* stream, uint32_t frequency, FuriHalSubGhzPreset preset, SubBruteFileProtocol file, @@ -353,10 +355,11 @@ FuriString* subbrute_protocol_default_generate_file( #ifdef FURI_DEBUG FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif - FuriString* result; + stream_clean(stream); if(te) { - result = furi_string_alloc_printf( + stream_write_format( + stream, subbrute_key_file_start_with_tail, frequency, preset, @@ -366,7 +369,8 @@ FuriString* subbrute_protocol_default_generate_file( te, repeat); } else { - result = furi_string_alloc_printf( + stream_write_format( + stream, subbrute_key_file_start_no_tail, frequency, preset, @@ -375,16 +379,12 @@ FuriString* subbrute_protocol_default_generate_file( furi_string_get_cstr(candidate), repeat); } -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); -#endif furi_string_free(candidate); - - return result; } -FuriString* subbrute_protocol_file_generate_file( +void subbrute_protocol_file_generate_file( + Stream* stream, uint32_t frequency, FuriHalSubGhzPreset preset, SubBruteFileProtocol file, @@ -395,9 +395,6 @@ FuriString* subbrute_protocol_file_generate_file( uint8_t load_index, const char* file_key) { FuriString* candidate = furi_string_alloc(); - if(step >= sizeof(file_key)) { - return false; - } char subbrute_payload_byte[4]; furi_string_set_str(candidate, file_key); snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step); @@ -406,10 +403,10 @@ FuriString* subbrute_protocol_file_generate_file( #ifdef FURI_DEBUG FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif - FuriString* result; - + stream_clean(stream); if(te) { - result = furi_string_alloc_printf( + stream_write_format( + stream, subbrute_key_file_start_with_tail, frequency, preset, @@ -419,7 +416,8 @@ FuriString* subbrute_protocol_file_generate_file( te, repeat); } else { - result = furi_string_alloc_printf( + stream_write_format( + stream, subbrute_key_file_start_no_tail, frequency, preset, @@ -429,13 +427,7 @@ FuriString* subbrute_protocol_file_generate_file( repeat); } -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result)); -#endif - furi_string_free(candidate); - - return result; } uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) { diff --git a/applications/plugins/subbrute/subbrute_protocols.h b/applications/plugins/subbrute/subbrute_protocols.h index 747328d5b..e0a97eef2 100644 --- a/applications/plugins/subbrute/subbrute_protocols.h +++ b/applications/plugins/subbrute/subbrute_protocols.h @@ -3,7 +3,7 @@ #include #include #include - +#include //typedef enum { // FrequencyProtocolField, // BitsProtocolField, @@ -56,16 +56,22 @@ FuriHalSubGhzPreset subbrute_protocol_convert_preset(FuriString* preset_name); SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name); const char* subbrute_protocol_name(SubBruteAttacks index); -FuriString* - subbrute_protocol_default_payload(uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat); -FuriString* subbrute_protocol_file_payload( +void subbrute_protocol_default_payload( + Stream* stream, + uint64_t step, + uint8_t bits, + uint8_t te, + uint8_t repeat); +void subbrute_protocol_file_payload( + Stream* stream, uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat, uint8_t load_index, const char* file_key); -FuriString* subbrute_protocol_default_generate_file( +void subbrute_protocol_default_generate_file( + Stream* stream, uint32_t frequency, FuriHalSubGhzPreset preset, SubBruteFileProtocol file, @@ -73,7 +79,8 @@ FuriString* subbrute_protocol_default_generate_file( uint8_t bits, uint8_t te, uint8_t repeat); -FuriString* subbrute_protocol_file_generate_file( +void subbrute_protocol_file_generate_file( + Stream* stream, uint32_t frequency, FuriHalSubGhzPreset preset, SubBruteFileProtocol file, diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index bfac24b8b..9d3486797 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -91,7 +91,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { if(m->is_select_byte) { #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "key_field: %s", m->key_field); + //FURI_LOG_D(TAG, "key_field: %s", m->key_field); #endif char msg_index[18]; snprintf(msg_index, sizeof(msg_index), "Field index : %d", m->index); @@ -118,7 +118,7 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { const uint8_t item_height = 16; #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, m->index); + //FURI_LOG_D(TAG, "window_position: %d, index: %d", model->window_position, m->index); #endif for(uint8_t position = 0; position < SubBruteAttackTotalCount; ++position) { uint8_t item_position = position - model->window_position; From 323a56e987bda3c181db9539da9993f7ecf2cb64 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 03:05:51 +0400 Subject: [PATCH 09/14] fix saving files --- applications/plugins/subbrute/application.fam | 4 ++-- .../subbrute/scenes/subbrute_scene_save_name.c | 2 +- applications/plugins/subbrute/subbrute_device.c | 3 ++- .../plugins/subbrute/subbrute_protocols.c | 16 ++++++++-------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/applications/plugins/subbrute/application.fam b/applications/plugins/subbrute/application.fam index 5e9dd9c8d..62d59a188 100644 --- a/applications/plugins/subbrute/application.fam +++ b/applications/plugins/subbrute/application.fam @@ -1,6 +1,6 @@ App( - appid="SubGHz_Bruteforcer", - name="Sub-GHz Bruteforcer", + appid="SubGHz_Bruteforcer_v3", + name="Sub-GHz Bruteforcer v3", apptype=FlipperAppType.EXTERNAL, entry_point="subbrute_app", cdefines=["APP_SUB_BRUTE"], diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c index f0acb30df..b5919ae5a 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_save_name.c @@ -47,7 +47,7 @@ bool subbrute_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(strcmp(instance->text_store, "")) { furi_string_reset(instance->file_path); furi_string_cat_printf( - instance->file_path, "/%s%s", instance->text_store, SUBBRUTE_FILE_EXT); + 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); diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 0b23e61e2..bf85e3a66 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -20,7 +20,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->environment = subghz_environment_alloc(); #ifdef FURI_DEBUG - subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); + subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); #else subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); #endif @@ -88,6 +88,7 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na bool result = false; do { if(!flipper_format_file_open_always(file, dev_file_name)) { + FURI_LOG_E(TAG, "Failed to open file: %s", dev_file_name); break; } Stream* stream = flipper_format_get_raw_stream(file); diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index c4ef1c662..b6595fefd 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -362,8 +362,8 @@ void subbrute_protocol_default_generate_file( stream, subbrute_key_file_start_with_tail, frequency, - preset, - file, + subbrute_protocol_preset(preset), + subbrute_protocol_file(file), bits, furi_string_get_cstr(candidate), te, @@ -373,8 +373,8 @@ void subbrute_protocol_default_generate_file( stream, subbrute_key_file_start_no_tail, frequency, - preset, - file, + subbrute_protocol_preset(preset), + subbrute_protocol_file(file), bits, furi_string_get_cstr(candidate), repeat); @@ -409,8 +409,8 @@ void subbrute_protocol_file_generate_file( stream, subbrute_key_file_start_with_tail, frequency, - preset, - file, + subbrute_protocol_preset(preset), + subbrute_protocol_file(file), bits, furi_string_get_cstr(candidate), te, @@ -420,8 +420,8 @@ void subbrute_protocol_file_generate_file( stream, subbrute_key_file_start_no_tail, frequency, - preset, - file, + subbrute_protocol_preset(preset), + subbrute_protocol_file(file), bits, furi_string_get_cstr(candidate), repeat); From 7ded162c94b804b8c3fc8ee210ce382a83174e50 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 03:24:44 +0400 Subject: [PATCH 10/14] add vibro on stop to in-pocket mode --- .../plugins/subbrute/scenes/subbrute_scene_run_attack.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index d6e4bad0b..e632b0cf2 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -77,6 +77,10 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) } 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); From 9c0391a88726706b17b5114938df8e22812411aa Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 04:44:23 +0400 Subject: [PATCH 11/14] minor changes --- .../subbrute/helpers/subbrute_worker.c | 9 ++++--- .../helpers/subbrute_worker_private.h | 1 + .../plugins/subbrute/subbrute_protocols.c | 26 ------------------- 3 files changed, 7 insertions(+), 29 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 0188cfecc..596240ded 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -222,6 +222,7 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste instance->step = step; bool result; + instance->protocol_name = subbrute_protocol_file(instance->file); FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); @@ -255,7 +256,7 @@ bool subbrute_worker_transmit_current_key(SubBruteWorker* instance, uint64_t ste // } flipper_format_free(flipper_format); -// furi_string_free(payload); + // furi_string_free(payload); return result; } @@ -296,8 +297,8 @@ void subbrute_worker_subghz_transmit(SubBruteWorker* instance, FlipperFormat* fl subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; } - instance->transmitter = subghz_transmitter_alloc_init( - instance->environment, subbrute_protocol_file(instance->file)); + instance->transmitter = + subghz_transmitter_alloc_init(instance->environment, instance->protocol_name); subghz_transmitter_deserialize(instance->transmitter, flipper_format); furi_hal_subghz_reset(); furi_hal_subghz_load_preset(instance->preset); @@ -349,6 +350,8 @@ int32_t subbrute_worker_thread(void* context) { SubBruteWorkerState local_state = instance->state = SubBruteWorkerStateTx; subbrute_worker_send_callback(instance); + instance->protocol_name = subbrute_protocol_file(instance->file); + FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); diff --git a/applications/plugins/subbrute/helpers/subbrute_worker_private.h b/applications/plugins/subbrute/helpers/subbrute_worker_private.h index 7da16df08..cebda8585 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker_private.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker_private.h @@ -20,6 +20,7 @@ struct SubBruteWorker { SubGhzProtocolDecoderBase* decoder_result; SubGhzEnvironment* environment; SubGhzTransmitter* transmitter; + const char* protocol_name; // Initiated values SubBruteAttacks attack; // Attack state diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index b6595fefd..c5509680b 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -130,32 +130,6 @@ const SubBruteProtocol subbrute_protocol_linear_10bit_310 = { const SubBruteProtocol subbrute_protocol_load_file = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}; -//static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = { -// [SubBruteAttackCAME12bit303] = -// {303875000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackCAME12bit307] = -// {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackCAME12bit433] = -// {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackCAME12bit868] = -// {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol}, -// [SubBruteAttackNICE12bit433] = -// {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, -// [SubBruteAttackNICE12bit868] = -// {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol}, -// [SubBruteAttackChamberlain9bit300] = -// {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackChamberlain9bit315] = -// {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackChamberlain9bit390] = -// {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol}, -// [SubBruteAttackLinear10bit300] = -// {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, -// [SubBruteAttackLinear10bit310] = -// {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol}, -// [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol}, -//}; - static const char* subbrute_protocol_names[] = { [SubBruteAttackCAME12bit303] = "CAME 12bit 303MHz", [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz", From 915229956276ded40b71734f4fbc527a7e9008b1 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 12:53:33 +0400 Subject: [PATCH 12/14] Fix max value in BF dump brute --- applications/plugins/subbrute/subbrute_device.c | 2 +- applications/plugins/subbrute/subbrute_protocols.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index bf85e3a66..8328c0492 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -20,7 +20,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->environment = subghz_environment_alloc(); #ifdef FURI_DEBUG - subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); + subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); #else subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); #endif diff --git a/applications/plugins/subbrute/subbrute_protocols.c b/applications/plugins/subbrute/subbrute_protocols.c index c5509680b..77a0bf791 100644 --- a/applications/plugins/subbrute/subbrute_protocols.c +++ b/applications/plugins/subbrute/subbrute_protocols.c @@ -281,7 +281,7 @@ void subbrute_protocol_file_payload( furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte); #ifdef FURI_DEBUG - //FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); + FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step); #endif stream_clean(stream); @@ -407,7 +407,7 @@ void subbrute_protocol_file_generate_file( uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) { uint64_t max_value; if(attack_type == SubBruteAttackLoadFile) { - max_value = 0x3F; + max_value = 0xFF; } else { FuriString* max_value_s; max_value_s = furi_string_alloc(); From 3f3ee1822a76e2c8cbc6a679a64618a0a6957aa9 Mon Sep 17 00:00:00 2001 From: DerSkythe Date: Mon, 10 Oct 2022 23:24:10 +0400 Subject: [PATCH 13/14] Update upper buttons --- .../plugins/subbrute/subbrute_device.c | 2 +- .../subbrute/views/subbrute_attack_view.c | 54 +++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 8328c0492..bf85e3a66 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -20,7 +20,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->environment = subghz_environment_alloc(); #ifdef FURI_DEBUG - subbrute_device_attack_set_default_values(instance, SubBruteAttackLoadFile); + subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); #else subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit433); #endif diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index e783d9f4c..c3412de71 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -293,56 +293,67 @@ void subbrute_attack_view_exit(void* context) { false); } +/** + * Thanks to the author of metronome + * @param canvas + * @param str + */ 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 = 9; // + 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); // - const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset + 1; + 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; + const uint8_t y = 0 + button_height; - canvas_draw_box(canvas, x, y, button_width, button_height); - // canvas_draw_line(canvas, x + button_width + 0, y, x + button_width + 0, y + button_height - 0); // - // canvas_draw_line(canvas, x + button_width + 1, y, x + button_width + 1, y + button_height - 1); - // canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y + button_height - 2); + canvas_draw_box(canvas, x, y - button_height, button_width, button_height); + canvas_draw_line(canvas, x + button_width + 0, y - button_height, x + button_width + 0, y - 1); + canvas_draw_line(canvas, x + button_width + 1, y - button_height, x + button_width + 1, y - 2); + canvas_draw_line(canvas, x + button_width + 2, y - button_height, x + button_width + 2, y - 3); canvas_invert_color(canvas); - canvas_draw_icon(canvas, x + horizontal_offset, y + icon_v_offset, icon); + 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, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str); canvas_invert_color(canvas); } +/** + * Thanks to the author of metronome + * @param canvas + * @param str + */ 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 = 9; + 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 + 1; + 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; + const uint8_t y = 0 + button_height; - canvas_draw_box(canvas, x - button_width, y, button_width, button_height); - // canvas_draw_line(canvas, x - button_width - 1, y, x + button_width - 1, y + button_height - 0); - // canvas_draw_line(canvas, x - button_width - 2, y, x + button_width - 2, y + button_height - 1); - // canvas_draw_line(canvas, x - button_width - 3, y, x + button_width - 3, y + button_height - 2); + canvas_draw_box(canvas, x - button_width, y - button_height, button_width, button_height); + canvas_draw_line(canvas, x - button_width - 1, y - button_height, x - button_width - 1, y - 1); + canvas_draw_line(canvas, x - button_width - 2, y - button_height, x - button_width - 2, y - 2); + canvas_draw_line(canvas, x - button_width - 3, y - button_height, x - button_width - 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_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); } @@ -381,7 +392,8 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { } // canvas_draw_icon_animation const uint8_t icon_h_offset = 0; - const uint8_t icon_width_with_offset = icon_animation_get_width(model->icon) + icon_h_offset; + const uint8_t icon_width_with_offset = + icon_animation_get_width(model->icon) + icon_h_offset; const uint8_t icon_v_offset = icon_animation_get_height(model->icon); // + vertical_offset; const uint8_t x = canvas_width(canvas); const uint8_t y = canvas_height(canvas); From b0c31da36a09d8305daf57df75d67336057a5fa7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:52:43 +0300 Subject: [PATCH 14/14] update name --- applications/plugins/subbrute/application.fam | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/plugins/subbrute/application.fam b/applications/plugins/subbrute/application.fam index 62d59a188..5e9dd9c8d 100644 --- a/applications/plugins/subbrute/application.fam +++ b/applications/plugins/subbrute/application.fam @@ -1,6 +1,6 @@ App( - appid="SubGHz_Bruteforcer_v3", - name="Sub-GHz Bruteforcer v3", + appid="SubGHz_Bruteforcer", + name="Sub-GHz Bruteforcer", apptype=FlipperAppType.EXTERNAL, entry_point="subbrute_app", cdefines=["APP_SUB_BRUTE"],