From 127b7006423b8b309aec0d7a34d77206013e49d3 Mon Sep 17 00:00:00 2001 From: derskythe Date: Fri, 30 Sep 2022 18:36:56 +0400 Subject: [PATCH] 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)); } } }