From 877a9202fd31881b728215433e981504a7c0fe1a Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 9 Oct 2022 19:45:39 +0300 Subject: [PATCH] fix decode raw bugs (blank screen, broken files) --- .../subghz/scenes/subghz_scene_decode_raw.c | 38 ++++++++----------- .../scenes/subghz_scene_receiver_info.c | 6 ++- .../subghz/scenes/subghz_scene_save_success.c | 38 +++++++++++++++---- applications/main/subghz/subghz.c | 1 + applications/main/subghz/subghz_i.h | 13 +++++++ 5 files changed, 66 insertions(+), 30 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_decode_raw.c b/applications/main/subghz/scenes/subghz_scene_decode_raw.c index 4412cc023..ccfb40820 100644 --- a/applications/main/subghz/scenes/subghz_scene_decode_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_decode_raw.c @@ -22,15 +22,6 @@ // [X] Find good value for SAMPLES_TO_READ_PER_TICK // [X] Fix: read errors (slow flash) after aborting decode read -typedef enum { - SubGhzDecodeRawStateStart, - SubGhzDecodeRawStateLoading, - SubGhzDecodeRawStateLoaded, -} SubGhzDecodeRawState; - -SubGhzDecodeRawState decode_raw_state = SubGhzDecodeRawStateStart; -SubGhzFileEncoderWorker* file_worker_encoder; - static void subghz_scene_receiver_update_statusbar(void* context) { SubGhz* subghz = context; FuriString* history_stat_str; @@ -114,8 +105,9 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) { if(success) { //FURI_LOG_I(TAG, "Listening at \033[0;33m%s\033[0m.", furi_string_get_cstr(file_name)); - file_worker_encoder = subghz_file_encoder_worker_alloc(); - if(subghz_file_encoder_worker_start(file_worker_encoder, furi_string_get_cstr(file_name))) { + subghz->decode_raw_file_worker_encoder = subghz_file_encoder_worker_alloc(); + if(subghz_file_encoder_worker_start( + subghz->decode_raw_file_worker_encoder, furi_string_get_cstr(file_name))) { //the worker needs a file in order to open and read part of the file furi_delay_ms(100); } else { @@ -123,7 +115,7 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) { } if(!success) { - subghz_file_encoder_worker_free(file_worker_encoder); + subghz_file_encoder_worker_free(subghz->decode_raw_file_worker_encoder); } } @@ -135,13 +127,14 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) { LevelDuration level_duration; for(uint32_t read = SAMPLES_TO_READ_PER_TICK; read > 0; --read) { - level_duration = subghz_file_encoder_worker_get_level_duration(file_worker_encoder); + level_duration = + subghz_file_encoder_worker_get_level_duration(subghz->decode_raw_file_worker_encoder); if(!level_duration_is_reset(level_duration)) { bool level = level_duration_get_level(level_duration); uint32_t duration = level_duration_get_duration(level_duration); subghz_receiver_decode(subghz->txrx->receiver, level, duration); } else { - decode_raw_state = SubGhzDecodeRawStateLoaded; + subghz->decode_raw_state = SubGhzDecodeRawStateLoaded; subghz->state_notifications = SubGhzNotificationStateIDLE; subghz_view_receiver_add_data_progress(subghz->subghz_receiver, "100%"); @@ -152,7 +145,8 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) { // Update progress info FuriString* progress_str; progress_str = furi_string_alloc(); - subghz_file_encoder_worker_get_text_progress(file_worker_encoder, progress_str); + subghz_file_encoder_worker_get_text_progress( + subghz->decode_raw_file_worker_encoder, progress_str); subghz_view_receiver_add_data_progress( subghz->subghz_receiver, furi_string_get_cstr(progress_str)); @@ -183,11 +177,11 @@ void subghz_scene_decode_raw_on_enter(void* context) { false); subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable); - if(decode_raw_state == SubGhzDecodeRawStateStart) { + if(subghz->decode_raw_state == SubGhzDecodeRawStateStart) { //Decode RAW to history subghz_history_reset(subghz->txrx->history); if(subghz_scene_decode_raw_start(subghz)) { - decode_raw_state = SubGhzDecodeRawStateLoading; + subghz->decode_raw_state = SubGhzDecodeRawStateLoading; subghz->state_notifications = SubGhzNotificationStateRx; } } else { @@ -216,14 +210,14 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { case SubGhzCustomEventViewReceiverBack: - decode_raw_state = SubGhzDecodeRawStateStart; + subghz->decode_raw_state = SubGhzDecodeRawStateStart; subghz->txrx->idx_menu_chosen = 0; subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); - if(subghz_file_encoder_worker_is_running(file_worker_encoder)) { - subghz_file_encoder_worker_stop(file_worker_encoder); + if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { + subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); } - subghz_file_encoder_worker_free(file_worker_encoder); + subghz_file_encoder_worker_free(subghz->decode_raw_file_worker_encoder); subghz->state_notifications = SubGhzNotificationStateIDLE; scene_manager_set_scene_state( @@ -268,7 +262,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) { break; } - switch(decode_raw_state) { + switch(subghz->decode_raw_state) { case SubGhzDecodeRawStateLoading: subghz_scene_decode_raw_next(subghz); break; diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 516e63494..3713b85c0 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -186,6 +186,10 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == SubGhzProtocolFlag_Save) { subghz_file_name_clear(subghz); + + if(subghz->in_decoder_scene) { + subghz->in_decoder_scene_skip = true; + } scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); } return true; @@ -214,7 +218,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) void subghz_scene_receiver_info_on_exit(void* context) { SubGhz* subghz = context; - if(subghz->in_decoder_scene) { + if(subghz->in_decoder_scene && !subghz->in_decoder_scene_skip) { subghz->in_decoder_scene = false; } widget_reset(subghz->widget); diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c index 3d5c16ca3..62efa5e41 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_success.c +++ b/applications/main/subghz/scenes/subghz_scene_save_success.c @@ -27,17 +27,36 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveSuccess) { - if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneReceiver)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWSave; + if(!subghz->in_decoder_scene) { if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneReadRAW)) { - subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + subghz->scene_manager, SubGhzSceneReceiver)) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWSave; if(!scene_manager_search_and_switch_to_previous_scene( - subghz->scene_manager, SubGhzSceneSaved)) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + subghz->scene_manager, SubGhzSceneReadRAW)) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneSaved)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + } } } + } else { + subghz->decode_raw_state = SubGhzDecodeRawStateStart; + subghz->txrx->idx_menu_chosen = 0; + subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); + + if(subghz_file_encoder_worker_is_running(subghz->decode_raw_file_worker_encoder)) { + subghz_file_encoder_worker_stop(subghz->decode_raw_file_worker_encoder); + } + subghz_file_encoder_worker_free(subghz->decode_raw_file_worker_encoder); + + subghz->state_notifications = SubGhzNotificationStateIDLE; + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); + if(!scene_manager_search_and_switch_to_previous_scene( + subghz->scene_manager, SubGhzSceneSaved)) { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaved); + } } return true; } @@ -48,6 +67,11 @@ bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) void subghz_scene_save_success_on_exit(void* context) { SubGhz* subghz = context; + if(subghz->in_decoder_scene) { + subghz->in_decoder_scene = false; + subghz->in_decoder_scene_skip = false; + } + // Clear view Popup* popup = subghz->popup; popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index df8110ac1..93c9b2d80 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -70,6 +70,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->gui = furi_record_open(RECORD_GUI); subghz->in_decoder_scene = false; + subghz->in_decoder_scene_skip = false; // View Dispatcher subghz->view_dispatcher = view_dispatcher_alloc(); diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 832ae8696..baf3ae82a 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -29,6 +29,8 @@ #include +#include + #include #include @@ -49,6 +51,12 @@ typedef struct { uint8_t seed[4]; } SecureData; +typedef enum { + SubGhzDecodeRawStateStart, + SubGhzDecodeRawStateLoading, + SubGhzDecodeRawStateLoaded, +} SubGhzDecodeRawState; + struct SubGhzTxRx { SubGhzWorker* worker; @@ -109,6 +117,11 @@ struct SubGhz { SubGhzLock lock; bool in_decoder_scene; + bool in_decoder_scene_skip; + + SubGhzDecodeRawState decode_raw_state; + SubGhzFileEncoderWorker* decode_raw_file_worker_encoder; + void* rpc_ctx; };