diff --git a/applications/plugins/subbrute/helpers/subbrute_worker.c b/applications/plugins/subbrute/helpers/subbrute_worker.c index 22e0e7ec4fa..369ffd81c24 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 50 -#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 = 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; } @@ -117,16 +64,18 @@ void subbrute_worker_free(SubBruteWorker* instance) { instance->transmitter = NULL; } - if(instance->environment != NULL) { + /*if(instance->environment != NULL) { subghz_environment_free(instance->environment); 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) { @@ -195,6 +157,18 @@ bool subbrute_worker_can_transmit(SubBruteWorker* 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); @@ -210,14 +184,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, @@ -230,7 +210,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, false) || + instance->worker_running) { #ifdef FURI_DEBUG FURI_LOG_D(TAG, "cannot transmit"); #endif @@ -276,7 +257,6 @@ bool subbrute_worker_init_manual_transmit( FURI_LOG_I(TAG, "Frequency: %d", frequency); #endif - instance->environment = subghz_environment_alloc(); instance->transmitter = subghz_transmitter_alloc_init( instance->environment, string_get_cstr(instance->protocol_name)); @@ -310,8 +290,6 @@ void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance) { subghz_transmitter_free(instance->transmitter); instance->transmitter = NULL; } - subghz_environment_free(instance->environment); - instance->environment = NULL; instance->is_manual_init = false; } @@ -326,9 +304,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 37875fa12b8..d96fbdde2f5 100644 --- a/applications/plugins/subbrute/helpers/subbrute_worker.h +++ b/applications/plugins/subbrute/helpers/subbrute_worker.h @@ -23,13 +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 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_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 6557b4ba18d..05a7125e107 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_load_file.c @@ -45,19 +45,22 @@ void subbrute_scene_load_file_on_enter(void* context) { res = true; } } - } - if(load_result == SubBruteFileResultOk) { - scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect); - } else { - FURI_LOG_E(TAG, "Returned error: %d", load_result); + if(load_result == SubBruteFileResultOk) { + scene_manager_next_scene(instance->scene_manager, SubBruteSceneLoadSelect); + } else { + FURI_LOG_E(TAG, "Returned error: %d", load_result); - string_t dialog_msg; - string_init(dialog_msg); - string_cat_printf( - dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result)); - dialog_message_show_storage_error(instance->dialogs, string_get_cstr(dialog_msg)); - string_clear(dialog_msg); + string_t dialog_msg; + string_init(dialog_msg); + string_cat_printf( + dialog_msg, "Cannot parse\nfile: %s", subbrute_device_error_get_desc(load_result)); + dialog_message_show_storage_error(instance->dialogs, string_get_cstr(dialog_msg)); + string_clear(dialog_msg); + scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, SubBruteSceneStart); + } + } else { scene_manager_search_and_switch_to_previous_scene( instance->scene_manager, SubBruteSceneStart); } diff --git a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c index 36a9e86f97a..385f43b9b6d 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_run_attack.c @@ -3,6 +3,8 @@ #include "../views/subbrute_attack_view.h" #include "../helpers/subbrute_worker.h" +#define TAG "SubBruteSceneRunAttack" + static void subbrute_scene_run_attack_callback(SubBruteCustomEvent event, void* context) { furi_assert(context); @@ -10,10 +12,57 @@ 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); +//} + 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); + } + notification_message(instance->notifications, &sequence_blink_stop); } @@ -21,6 +70,10 @@ 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); @@ -33,47 +86,107 @@ void subbrute_scene_run_attack_on_enter(void* context) { instance->device->key_index, true); - // Start worker if not started - subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name)); + 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 + } } bool subbrute_scene_run_attack_on_event(void* context, SceneManagerEvent event) { SubBruteState* instance = (SubBruteState*)context; - SubBruteAttackView* view = instance->view_attack; + // SubBruteAttackState* state = (SubBruteAttackState*)scene_manager_get_scene_state( + // instance->scene_manager, SubBruteSceneRunAttack); + // furi_assert(state); + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { + SubBruteAttackView* view = instance->view_attack; + if(event.event == SubBruteCustomEventTypeTransmitNotStarted || event.event == SubBruteCustomEventTypeTransmitFinished || event.event == SubBruteCustomEventTypeBackPressed) { + // furi_timer_stop(state->timer); // Stop transmit - scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); + 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_search_and_switch_to_previous_scene( + instance->scene_manager, SubBruteSceneSetupAttack); consumed = true; + } 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_transmit(instance->worker)) { - // Blink - notification_message(instance->notifications, &sequence_blink_yellow_100); - - 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 - scene_manager_next_scene(instance->scene_manager, SubBruteSceneSetupAttack); - } else { - instance->device->key_index++; - subbrute_attack_view_set_current_step(view, instance->device->key_index); - subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index); + 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); - // Stop - notification_message(instance->notifications, &sequence_blink_stop); + 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 22d0a3a5f27..2da28f672a8 100644 --- a/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c +++ b/applications/plugins/subbrute/scenes/subbrute_scene_setup_attack.c @@ -27,11 +27,13 @@ void subbrute_scene_setup_attack_on_enter(void* context) { instance->device->key_index, false); - subbrute_worker_init_manual_transmit( - instance->worker, - instance->device->frequency, - instance->device->preset, - string_get_cstr(instance->device->protocol_name)); + 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!"); + } instance->current_view = SubBruteViewAttack; subbrute_attack_view_set_callback(view, subbrute_scene_setup_attack_callback, instance); @@ -55,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); + 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); @@ -94,8 +102,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepUpMore) { - // +100 - uint64_t value = instance->device->key_index + 100; + // +50 + uint64_t value = instance->device->key_index + 50; if(value == instance->device->max_value) { instance->device->key_index += value; } else { @@ -118,8 +126,8 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeChangeStepDownMore) { - // -100 - uint64_t value = ((instance->device->key_index - 100) + instance->device->max_value); + // -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 { @@ -127,7 +135,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event } subbrute_attack_view_set_current_step(view, instance->device->key_index); } else if(event.event == SubBruteCustomEventTypeTransmitCustom) { - if(subbrute_worker_can_transmit(instance->worker)) { + if(subbrute_worker_can_manual_transmit(instance->worker, true)) { // Blink notification_message(instance->notifications, &sequence_blink_green_100); @@ -139,7 +147,7 @@ bool subbrute_scene_setup_attack_on_event(void* context, SceneManagerEvent event // string_get_cstr(instance->device->protocol_name)); // } subbrute_device_create_packet_parsed( - instance->device, instance->device->key_index); + instance->device, instance->device->key_index, false); subbrute_worker_manual_transmit(instance->worker, instance->device->payload); // Stop diff --git a/applications/plugins/subbrute/subbrute.c b/applications/plugins/subbrute/subbrute.c index fb6e158824a..0393335ab1d 100644 --- a/applications/plugins/subbrute/subbrute.c +++ b/applications/plugins/subbrute/subbrute.c @@ -81,7 +81,7 @@ SubBruteState* subbrute_alloc() { view_dispatcher_set_navigation_event_callback( instance->view_dispatcher, subbrute_back_event_callback); view_dispatcher_set_tick_event_callback( - instance->view_dispatcher, subbrute_tick_event_callback, 100); + instance->view_dispatcher, subbrute_tick_event_callback, 10); //Dialog instance->dialogs = furi_record_open(RECORD_DIALOGS); @@ -142,18 +142,18 @@ SubBruteState* subbrute_alloc() { void subbrute_free(SubBruteState* instance) { furi_assert(instance); - // SubBruteDevice + // SubBruteWorker #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free SubBruteDevice"); #endif - subbrute_device_free(instance->device); + subbrute_worker_stop(instance->worker); + subbrute_worker_free(instance->worker); - // SubBruteWorker + // SubBruteDevice #ifdef FURI_DEBUG FURI_LOG_D(TAG, "free SubBruteDevice"); #endif - subbrute_worker_stop(instance->worker); - subbrute_worker_free(instance->worker); + subbrute_device_free(instance->device); // Notifications #ifdef FURI_DEBUG @@ -297,6 +297,7 @@ int32_t subbrute_app(void* p) { scene_manager_next_scene(instance->scene_manager, SubBruteSceneStart); furi_hal_power_suppress_charge_enter(); + notification_message(instance->notifications, &sequence_display_backlight_on); view_dispatcher_run(instance->view_dispatcher); furi_hal_power_suppress_charge_exit(); subbrute_free(instance); diff --git a/applications/plugins/subbrute/subbrute_custom_event.h b/applications/plugins/subbrute/subbrute_custom_event.h index 5ddab7fa1b4..800d8f5e091 100644 --- a/applications/plugins/subbrute/subbrute_custom_event.h +++ b/applications/plugins/subbrute/subbrute_custom_event.h @@ -10,11 +10,12 @@ typedef enum { SubBruteCustomEventTypeBackPressed, SubBruteCustomEventTypeIndexSelected, SubBruteCustomEventTypeTransmitStarted, + SubBruteCustomEventTypeTransmitContinuousStarted, SubBruteCustomEventTypeTransmitFinished, SubBruteCustomEventTypeTransmitNotStarted, SubBruteCustomEventTypeTransmitCustom, SubBruteCustomEventTypeSaveFile, - SubBruteCustomEventTypeSaveSuccess, + SubBruteCustomEventTypeUpdateView, SubBruteCustomEventTypeChangeStepUp, SubBruteCustomEventTypeChangeStepDown, SubBruteCustomEventTypeChangeStepUpMore, diff --git a/applications/plugins/subbrute/subbrute_device.c b/applications/plugins/subbrute/subbrute_device.c index 28b47562b9f..037a0f11be0 100644 --- a/applications/plugins/subbrute/subbrute_device.c +++ b/applications/plugins/subbrute/subbrute_device.c @@ -37,6 +37,8 @@ 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"; @@ -58,7 +60,7 @@ SubBruteDevice* subbrute_device_alloc() { instance->decoder_result = NULL; instance->receiver = NULL; - instance->environment = NULL; + instance->environment = subghz_environment_alloc(); subbrute_device_attack_set_default_values(instance, SubBruteAttackCAME12bit307); @@ -82,13 +84,8 @@ void subbrute_device_free(SubBruteDevice* instance) { instance->receiver = NULL; } - if(instance->environment != NULL) { -#ifdef FURI_DEBUG - FURI_LOG_D(TAG, "subghz_environment_free"); -#endif - subghz_environment_free(instance->environment); - instance->environment = NULL; - } + subghz_environment_free(instance->environment); + instance->environment = NULL; #ifdef FURI_DEBUG FURI_LOG_D(TAG, "before free"); @@ -107,7 +104,7 @@ bool subbrute_device_save_file(SubBruteDevice* instance, const char* dev_file_na #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); + bool result = subbrute_device_create_packet_parsed(instance, instance->key_index, false); if(!result) { FURI_LOG_E(TAG, "subbrute_device_create_packet_parsed failed!"); @@ -191,7 +188,7 @@ const char* subbrute_device_error_get_desc(SubBruteFileResult error_id) { return result; } -bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t step) { +bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t step, bool small) { furi_assert(instance); //char step_payload[32]; @@ -234,21 +231,40 @@ bool subbrute_device_create_packet_parsed(SubBruteDevice* instance, uint64_t ste FURI_LOG_D(TAG, "candidate: %s, step: %d", string_get_cstr(candidate), step); #endif - if(instance->has_tail) { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_princeton_end, - instance->file_template, - string_get_cstr(candidate), - instance->te); + 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 { - snprintf( - instance->payload, - sizeof(instance->payload), - subbrute_key_file_key, - instance->file_template, - string_get_cstr(candidate)); + 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 @@ -337,7 +353,6 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute } // For non-file types we didn't set SubGhzProtocolDecoderBase - instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -359,10 +374,8 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute protocol_check_result = SubBruteFileResultOk; } - subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->receiver = NULL; - instance->environment = NULL; if(protocol_check_result != SubBruteFileResultOk) { return SubBruteFileResultProtocolNotFound; @@ -407,7 +420,7 @@ SubBruteFileResult subbrute_device_attack_set(SubBruteDevice* instance, SubBrute #endif // Init payload - subbrute_device_create_packet_parsed(instance, instance->key_index); + subbrute_device_create_packet_parsed(instance, instance->key_index, false); return SubBruteFileResultOk; } @@ -426,7 +439,6 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p string_init(temp_str); uint32_t temp_data32; - instance->environment = subghz_environment_alloc(); instance->receiver = subghz_receiver_alloc_init(instance->environment); subghz_receiver_set_filter(instance->receiver, SubGhzProtocolFlag_Decodable); furi_hal_subghz_reset(); @@ -561,12 +573,10 @@ uint8_t subbrute_device_load_from_file(SubBruteDevice* instance, string_t file_p flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); - subghz_environment_free(instance->environment); subghz_receiver_free(instance->receiver); instance->decoder_result = NULL; instance->receiver = NULL; - instance->environment = NULL; if(result == SubBruteFileResultOk) { #ifdef FURI_DEBUG diff --git a/applications/plugins/subbrute/subbrute_device.h b/applications/plugins/subbrute/subbrute_device.h index 625c53d2aac..008e022a8e8 100644 --- a/applications/plugins/subbrute/subbrute_device.h +++ b/applications/plugins/subbrute/subbrute_device.h @@ -92,7 +92,7 @@ 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 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); diff --git a/applications/plugins/subbrute/views/subbrute_attack_view.c b/applications/plugins/subbrute/views/subbrute_attack_view.c index 4f43f786d62..12c849b43d1 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; } @@ -198,7 +220,7 @@ View* subbrute_attack_view_get_view(SubBruteAttackView* instance) { void subbrute_attack_view_set_current_step(SubBruteAttackView* instance, uint64_t current_step) { furi_assert(instance); #ifdef FURI_DEBUG - FURI_LOG_D(TAG, "Set step: %d", current_step); + //FURI_LOG_D(TAG, "Set step: %d", current_step); #endif with_view_model( instance->view, (SubBruteAttackViewModel * model) { @@ -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 e72d69d4ca1..2aa9c401230 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, diff --git a/applications/plugins/subbrute/views/subbrute_main_view.c b/applications/plugins/subbrute/views/subbrute_main_view.c index 141e3ce2728..8d8bf477e2b 100644 --- a/applications/plugins/subbrute/views/subbrute_main_view.c +++ b/applications/plugins/subbrute/views/subbrute_main_view.c @@ -127,9 +127,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { if(m->index == position) { canvas_draw_str_aligned( canvas, - 64, + 4, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignCenter, + AlignLeft, AlignCenter, str); elements_frame( @@ -137,9 +137,9 @@ void subbrute_main_view_draw(Canvas* canvas, SubBruteMainViewModel* model) { } else { canvas_draw_str_aligned( canvas, - 64, + 4, 9 + (item_position * item_height) + STATUS_BAR_Y_SHIFT, - AlignCenter, + AlignLeft, AlignCenter, str); }