BUGFIX: Auto-Saved and Check-Saved crash the Receiver

* Process Deferred Storage after 1 second, and wait in receiver callback for save to complete.
This commit is contained in:
Leeroy
2026-09-24 21:52:41 +10:00
parent 76c8368e1c
commit 9ca0c8fed8
3 changed files with 34 additions and 2 deletions
+1
View File
@@ -172,6 +172,7 @@ ProtoPirateApp* protopirate_app_alloc() {
app->setting = subghz_setting_alloc();
app->loaded_file_path = NULL;
app->start_tx_time = 0;
app->deferred_storage_timer = NULL;
subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user"));
// Apply loaded frequency and preset, with validation
+2
View File
@@ -82,10 +82,12 @@ struct ProtoPirateApp {
View* view_about;
FuriString* file_path;
ProtoPirateReceiver* protopirate_receiver;
FuriTimer* deferred_storage_timer;
ProtoPirateTxRx* txrx;
SubGhzSetting* setting;
ProtoPirateLock lock;
FuriString* loaded_file_path;
bool deferred_storage_in_progress;
bool auto_save;
bool check_saved;
bool sound;
+31 -2
View File
@@ -9,9 +9,12 @@
#define TAG "ProtoPirateSceneRx"
#define DEFERRED_STORAGE_TIME 1000
// Forward declaration
void protopirate_scene_receiver_view_callback(ProtoPirateCustomEvent event, void* context);
static void protopirate_scene_receiver_start_rx_stack(ProtoPirateApp* app);
static void protopirate_scene_receiver_process_deferred_storage(ProtoPirateApp* app);
static void protopirate_scene_receiver_update_statusbar(void* context) {
furi_check(context);
@@ -51,6 +54,10 @@ static void protopirate_scene_receiver_callback(
FURI_LOG_I(TAG, "=== SIGNAL DECODED (%s) ===", decoder_base->protocol->name);
//If save is happening, dont attempt to add to history yet.
while(app->deferred_storage_in_progress)
furi_delay_ms(25);
uint16_t count_before = protopirate_history_get_item(app->txrx->history);
bool added =
protopirate_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset);
@@ -76,11 +83,21 @@ static void protopirate_scene_receiver_callback(
protopirate_view_receiver_set_idx_menu(app->protopirate_receiver, last_index);
uint16_t new_idx = protopirate_history_get_item(app->txrx->history) - 1;
bool start_timer = false;
if(app->auto_save) {
protopirate_history_mark_auto_save_pending(app->txrx->history, new_idx);
start_timer = true;
}
if(app->check_saved) {
protopirate_history_mark_saved_match_pending(app->txrx->history, new_idx);
start_timer = true;
}
//Restart the timer.
if(start_timer) {
furi_timer_stop(app->deferred_storage_timer);
furi_timer_start(app->deferred_storage_timer, DEFERRED_STORAGE_TIME);
}
view_dispatcher_send_custom_event(
@@ -206,11 +223,15 @@ static void protopirate_scene_receiver_process_saved_match(ProtoPirateApp* app)
}
static void protopirate_scene_receiver_process_deferred_storage(ProtoPirateApp* app) {
app->deferred_storage_in_progress = true;
if(protopirate_scene_receiver_process_auto_save(app)) {
return;
}
protopirate_scene_receiver_process_saved_match(app);
furi_timer_stop(app->deferred_storage_timer);
app->deferred_storage_in_progress = false;
}
static bool protopirate_scene_receiver_bind_rx_stack(ProtoPirateApp* app) {
@@ -271,6 +292,10 @@ static void protopirate_scene_receiver_start_rx_stack(ProtoPirateApp* app) {
FURI_LOG_I(TAG, "RX started, state: %d", app->txrx->txrx_state);
}
void deferred_storage_timer_callback(void* app) {
protopirate_scene_receiver_process_deferred_storage(app);
}
void protopirate_scene_receiver_on_enter(void* context) {
furi_check(context);
ProtoPirateApp* app = context;
@@ -314,6 +339,9 @@ void protopirate_scene_receiver_on_enter(void* context) {
protopirate_scene_receiver_update_statusbar(app);
app->deferred_storage_timer =
furi_timer_alloc(deferred_storage_timer_callback, FuriTimerTypePeriodic, app);
#ifndef REMOVE_LOGS
bool is_external =
app->txrx->radio_device ? radio_device_loader_is_external(app->txrx->radio_device) : false;
@@ -424,8 +452,6 @@ bool protopirate_scene_receiver_on_event(void* context, SceneManagerEvent event)
break;
}
} else if(event.type == SceneManagerEventTypeTick) {
protopirate_scene_receiver_process_deferred_storage(app);
if(app->txrx->hopper_state != ProtoPirateHopperStateOFF) {
if(protopirate_hopper_update(app) && protopirate_scene_receiver_bind_rx_stack(app)) {
protopirate_rx(app, app->txrx->preset->frequency);
@@ -467,6 +493,9 @@ void protopirate_scene_receiver_on_exit(void* context) {
ProtoPirateApp* app = context;
FURI_LOG_I(TAG, "=== EXITING RECEIVER SCENE ===");
furi_timer_stop(app->deferred_storage_timer);
furi_timer_free(app->deferred_storage_timer);
app->deferred_storage_timer = NULL;
const bool leaving_for_subscene =
(scene_manager_get_scene_state(app->scene_manager, ProtoPirateSceneReceiver) == 1);