11#include "../subghz_i.h"
2+ #include <furi/core/memmgr.h>
3+ #include <furi/core/memmgr_heap.h>
24
35#define TAG "SubGhzDecodeRaw"
46
7+ #define SUBGHZ_DECODE_RAW_MIN_HEAP (12u * 1024u)
8+ // The decode worker allocates two large contiguous buffers (stream ~4 KB and the
9+ // pre-reserved line buffer ~4.6 KB). Require the largest free block to hold both,
10+ #define SUBGHZ_DECODE_RAW_MIN_BLOCK (9u * 1024u)
11+
512#define SAMPLES_TO_READ_PER_TICK 400
613
714static void subghz_scene_receiver_update_statusbar (void * context ) {
@@ -145,6 +152,14 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) {
145152 } while (false);
146153
147154 if (success ) {
155+ if (memmgr_get_free_heap () < SUBGHZ_DECODE_RAW_MIN_HEAP ||
156+ memmgr_heap_get_max_free_block () < SUBGHZ_DECODE_RAW_MIN_BLOCK ) {
157+ FURI_LOG_E (TAG , "Not enough memory to decode" );
158+ subghz -> decode_raw_file_worker_encoder = NULL ;
159+ furi_string_free (file_name );
160+ return false;
161+ }
162+
148163 //FURI_LOG_I(TAG, "Listening at \033[0;33m%s\033[0m.", furi_string_get_cstr(file_name));
149164
150165 subghz -> decode_raw_file_worker_encoder = subghz_file_encoder_worker_alloc ();
@@ -160,6 +175,7 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) {
160175
161176 if (!success ) {
162177 subghz_file_encoder_worker_free (subghz -> decode_raw_file_worker_encoder );
178+ subghz -> decode_raw_file_worker_encoder = NULL ;
163179 }
164180 }
165181
@@ -190,6 +206,14 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) {
190206 subghz -> scene_manager , SubGhzSceneDecodeRAW , SubGhzDecodeRawStateLoaded );
191207 subghz -> state_notifications = SubGhzNotificationStateIDLE ;
192208
209+ if (subghz -> decode_raw_file_worker_encoder ) {
210+ if (subghz_file_encoder_worker_is_running (subghz -> decode_raw_file_worker_encoder )) {
211+ subghz_file_encoder_worker_stop (subghz -> decode_raw_file_worker_encoder );
212+ }
213+ subghz_file_encoder_worker_free (subghz -> decode_raw_file_worker_encoder );
214+ subghz -> decode_raw_file_worker_encoder = NULL ;
215+ }
216+
193217 subghz_view_receiver_add_data_progress (subghz -> subghz_receiver , "Done!" );
194218 return false; // No more samples available
195219 }
@@ -269,10 +293,13 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
269293
270294 subghz_txrx_set_rx_callback (subghz -> txrx , NULL , subghz );
271295
272- if (subghz_file_encoder_worker_is_running (subghz -> decode_raw_file_worker_encoder )) {
273- subghz_file_encoder_worker_stop (subghz -> decode_raw_file_worker_encoder );
296+ if (subghz -> decode_raw_file_worker_encoder ) {
297+ if (subghz_file_encoder_worker_is_running (subghz -> decode_raw_file_worker_encoder )) {
298+ subghz_file_encoder_worker_stop (subghz -> decode_raw_file_worker_encoder );
299+ }
300+ subghz_file_encoder_worker_free (subghz -> decode_raw_file_worker_encoder );
301+ subghz -> decode_raw_file_worker_encoder = NULL ;
274302 }
275- subghz_file_encoder_worker_free (subghz -> decode_raw_file_worker_encoder );
276303
277304 subghz -> state_notifications = SubGhzNotificationStateIDLE ;
278305 scene_manager_set_scene_state (
0 commit comments