From a58807c57a16d4b34882b2b14a2763d6074f7355 Mon Sep 17 00:00:00 2001 From: derskythe Date: Mon, 26 Sep 2022 20:14:33 +0400 Subject: [PATCH] Add SubGhzTxRxWorker for later use --- .../subbrute/helpers/subbrute_worker.c | 125 +++++++----------- .../subbrute/helpers/subbrute_worker.h | 11 +- .../scenes/subbrute_scene_run_attack.c | 104 ++++++++++----- .../scenes/subbrute_scene_setup_attack.c | 16 ++- .../plugins/subbrute/subbrute_custom_event.h | 1 + .../subbrute/views/subbrute_attack_view.c | 58 +++++--- .../subbrute/views/subbrute_attack_view.h | 2 +- 7 files changed, 180 insertions(+), 137 deletions(-) diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 0b8441df5..e12d7c9f6 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.c +++ b/applications/plugins/subbrute/helpers/subbrute_worker.c @@ -3,14 +3,16 @@ #include #include #include +#include #define TAG "SubBruteWorker" struct SubBruteWorker { -// FuriThread* thread; + SubGhzTxRxWorker* subghz_txrx; volatile bool worker_running; volatile bool worker_manual_mode; bool is_manual_init; + bool is_continuous_worker; SubGhzEnvironment* environment; SubGhzTransmitter* transmitter; @@ -31,80 +33,25 @@ struct SubBruteWorker { #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 10 -#define SUBBRUTE_SEND_DELAY 260 - -/** - * Entrypoint for worker - * - * @param context SubBruteWorker* - * @return 0 if ok - */ -int32_t subbrute_worker_thread(void* context) { - furi_assert(context); - SubBruteWorker* instance = (SubBruteWorker*)context; - - if(!instance->worker_running) { - FURI_LOG_W(TAG, "Worker is not set to running state!"); - return -1; - } -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker start"); -#endif - - instance->environment = subghz_environment_alloc(); - 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(instance->frequency); - - furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_write(&gpio_cc1101_g0, true); - - // Set ready to transmit value - instance->last_time_tx_data = furi_get_tick() - SUBBRUTE_SEND_DELAY; - - while(instance->worker_running) { - // Transmit - if(!furi_hal_subghz_tx()) { - FURI_LOG_E(TAG, "Cannot transmit!"); - break; - } - furi_delay_ms(SUBBRUTE_TX_TIMEOUT); - } - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - - subghz_transmitter_free(instance->transmitter); - instance->transmitter = NULL; - subghz_environment_free(instance->environment); - instance->environment = NULL; - -#ifdef FURI_DEBUG - FURI_LOG_I(TAG, "Worker stop"); -#endif - return 0; -} +#define SUBBRUTE_TX_TIMEOUT 5 +#define SUBBRUTE_SEND_DELAY 20 SubBruteWorker* subbrute_worker_alloc() { SubBruteWorker* instance = malloc(sizeof(SubBruteWorker)); -// 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->status = SubBruteWorkerStatusIDLE; instance->worker_running = false; instance->worker_manual_mode = false; + instance->environment = NULL; + 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; } @@ -122,11 +69,13 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->environment = NULL; } -// furi_thread_free(instance->thread); flipper_format_free(instance->flipper_format); string_clear(instance->protocol_name); + // SubGhzTxRxWorker + subghz_tx_rx_worker_free(instance->subghz_txrx); + free(instance); } @@ -138,6 +87,7 @@ bool subbrute_worker_start( furi_assert(instance); if(instance->worker_manual_mode) { + FURI_LOG_W(TAG, "Invalid mode for starting worker!"); return false; } @@ -166,9 +116,10 @@ bool subbrute_worker_start( FURI_LOG_I(TAG, "Frequency: %d", frequency); #endif instance->preset = preset; - -// furi_thread_start(instance->thread); - + if(res) { + instance->worker_running = res = + subghz_tx_rx_worker_start(instance->subghz_txrx, frequency); + } return res; } @@ -177,10 +128,21 @@ void subbrute_worker_stop(SubBruteWorker* instance) { instance->worker_running = false; -// furi_thread_join(instance->thread); + if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) { + subghz_tx_rx_worker_stop(instance->subghz_txrx); + } +} - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); +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) { @@ -216,14 +178,20 @@ bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) { //FURI_LOG_D(TAG, "payload: %s", payload); #endif - 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); + 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, @@ -236,7 +204,8 @@ bool subbrute_worker_init_manual_transmit( frequency, protocol_name); #endif - if(instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) { + if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance) || + instance->worker_running) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "cannot transmit"); #endif @@ -332,9 +301,7 @@ bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* paylo return false; } if(instance->worker_running) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subbrute_worker_stop"); -#endif + FURI_LOG_W(TAG, "Worker was working for manual mode. Shutdown thread"); subbrute_worker_stop(instance); } if(!instance->is_manual_init) { diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.h b/applications/plugins/subbrute/helpers/subbrute_worker.h index be22b69ee..3338657d1 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -23,14 +23,17 @@ bool subbrute_worker_start( 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 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_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_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index af174dd27..5f5ba3e27 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -59,6 +59,10 @@ void subbrute_scene_run_attack_on_exit(void* context) { // furi_timer_free(state->timer); // free(state); + if(subbrute_worker_get_continuous_worker(instance->worker)) { + subbrute_worker_stop(instance->worker); + } + notification_message(instance->notifications, &sequence_blink_stop); } @@ -82,18 +86,29 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->device->key_index, true); - // 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!"); - } + 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 + // state->timer = furi_timer_alloc( + // subbrute_scene_run_attack_worker_callback, FuriTimerTypePeriodic, instance); + // furi_timer_start(state->timer, pdMS_TO_TICKS(100)); // 20 ms + } } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { @@ -116,33 +131,60 @@ bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; - } else if (event.event == SubBruteCustomEventTypeUpdateView) { + } else if(event.event == SubBruteCustomEventTypeUpdateView) { subbrute_attack_view_set_current_step(view, instance->device->key_index); } } else if(event.type == SceneManagerEventTypeTick) { - if(subbrute_worker_can_manual_transmit(instance->worker)) { - // Blink - notification_message(instance->notifications, &sequence_blink_yellow_100); + 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); + 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); + 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); + // Stop + notification_message(instance->notifications, &sequence_blink_stop); + } + } else { + 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); + + 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); + } } consumed = true; diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c index e2186ce49..c645a899a 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -28,10 +28,10 @@ void subbrute_scene_setup_attack_on_enter(void* context) { false); if(!subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name))) { + instance->worker, + instance->device->frequency, + instance->device->preset, + string_get_cstr(instance->device->protocol_name))) { FURI_LOG_W(TAG, "Worker init failed!"); } @@ -57,7 +57,13 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubBruteCustomEventTypeTransmitStarted) { - subbrute_device_create_packet_parsed(instance->device, instance->device->key_index, false); + 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); diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 8be1a4469..800d8f5e0 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -10,6 +10,7 @@ typedef enum { SubBruteCustomEventTypeBackPressed, SubBruteCustomEventTypeIndexSelected, SubBruteCustomEventTypeTransmitStarted, + SubBruteCustomEventTypeTransmitContinuousStarted, SubBruteCustomEventTypeTransmitFinished, SubBruteCustomEventTypeTransmitNotStarted, SubBruteCustomEventTypeTransmitCustom, diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 97eca6a66..12c849b43 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.c +++ b/applications/plugins/subbrute/views/subbrute_attack_view.c @@ -20,6 +20,7 @@ typedef struct { uint64_t max_value; uint64_t current_step; bool is_attacking; + bool is_continuous_worker; IconAnimation* icon; } SubBruteAttackViewModel; @@ -47,6 +48,7 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = false; + model->is_continuous_worker = false; return true; }); return true; @@ -67,25 +69,45 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { // } if(!is_attacking) { - if((event->type == InputTypeShort || event->type == InputTypeRepeat) && - event->key == InputKeyOk) { + if(event->type == InputTypeShort && event->key == InputKeyOk) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "InputKey: %d OK", event->key); #endif with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = true; + model->is_continuous_worker = false; icon_animation_stop(model->icon); icon_animation_start(model->icon); return true; }); instance->callback(SubBruteCustomEventTypeTransmitStarted, instance->context); - // } else if(event->key == InputKeyBack) { - // if(previous_scene == SubBruteSceneLoadFile) { - // instance->callback(SubBruteCustomEventTypeLoadFile, instance->context); - // } else { - // instance->callback(SubBruteCustomEventTypeBackPressed, instance->context); - // } + /*if(event->type == InputTypeRepeat && event->key == InputKeyOk) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "InputKey: %d OK. SubBruteCustomEventTypeTransmitContinuousStarted", event->key); +#endif + with_view_model( + instance->view, (SubBruteAttackViewModel * model) { + model->is_attacking = true; + model->is_continuous_worker = true; + icon_animation_stop(model->icon); + icon_animation_start(model->icon); + return true; + }); + instance->callback(SubBruteCustomEventTypeTransmitContinuousStarted, instance->context); + } else if(event->type == InputTypeShort && event->key == InputKeyOk) { +#ifdef FURI_DEBUG + FURI_LOG_D(TAG, "InputKey: %d OK", event->key); +#endif + with_view_model( + instance->view, (SubBruteAttackViewModel * model) { + model->is_attacking = true; + model->is_continuous_worker = false; + icon_animation_stop(model->icon); + icon_animation_start(model->icon); + return true; + }); + instance->callback(SubBruteCustomEventTypeTransmitStarted, instance->context);*/ } else if(event->key == InputKeyUp) { instance->callback(SubBruteCustomEventTypeSaveFile, instance->context); } else if(event->key == InputKeyDown) { @@ -131,6 +153,7 @@ bool subbrute_attack_view_input(InputEvent* event, void* context) { with_view_model( instance->view, (SubBruteAttackViewModel * model) { model->is_attacking = false; + model->is_continuous_worker = false; icon_animation_stop(model->icon); icon_animation_start(model->icon); return true; @@ -161,7 +184,6 @@ SubBruteAttackView* subbrute_attack_view_alloc() { view_set_enter_callback(instance->view, subbrute_attack_view_enter); view_set_exit_callback(instance->view, subbrute_attack_view_exit); - return instance; } @@ -207,17 +229,13 @@ void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_ }); } -uint64_t subbrute_attack_view_get_current_step(SubBruteAttackView* instance) { - uint64_t current_step; +void subbrute_attack_view_set_worker_type(SubBruteAttackView* instance, bool is_continuous_worker) { + furi_assert(instance); with_view_model( instance->view, (SubBruteAttackViewModel * model) { - current_step = model->current_step; - return false; + model->is_continuous_worker = is_continuous_worker; + return true; }); -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Get step: %d", current_step); -#endif - return current_step; } // We need to call init every time, because not every time we calls enter @@ -356,6 +374,9 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_button_top_left(canvas, "Save"); elements_button_top_right(canvas, "Resend"); } else { + if (model->is_continuous_worker) { + canvas_invert_color(canvas); + } // canvas_draw_icon_animation const uint8_t icon_h_offset = 0; const uint8_t icon_width_with_offset = model->icon->icon->width + icon_h_offset; @@ -370,5 +391,8 @@ void subbrute_attack_view_draw(Canvas* canvas, void* context) { elements_progress_bar(canvas, 8, 37, 110, progress_value > 1 ? 1 : progress_value); elements_button_center(canvas, "Stop"); + if (model->is_continuous_worker) { + canvas_invert_color(canvas); + } } } diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.h b/applications/plugins/subbrute/views/subbrute_attack_view.h index e72d69d4c..2aa9c4012 100644 --- a/applications/plugins/subbrute/views/subbrute_attack_view.h +++ b/applications/plugins/subbrute/views/subbrute_attack_view.h @@ -19,7 +19,7 @@ SubBruteAttackView* subbrute_attack_view_alloc(); void subbrute_attack_view_free(SubBruteAttackView* instance); View* subbrute_attack_view_get_view(SubBruteAttackView* instance); void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step); -uint64_t subbrute_attack_view_get_current_step(SubBruteAttackView* instance); +void subbrute_attack_view_set_worker_type(SubBruteAttackView* instance, bool is_continuous_worker); void subbrute_attack_view_init_values( SubBruteAttackView* instance, uint8_t index,