Просмотр исходного кода

SubGhz: loading/saving files from any folder below the parent (#1142)

Co-authored-by: あく <alleteam@gmail.com>
Skorpionm 3 лет назад
Родитель
Сommit
0ff9f43eab

+ 1 - 1
applications/subghz/scenes/subghz_scene_delete.c

@@ -49,7 +49,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) {
     SubGhz* subghz = context;
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubGhzCustomEventSceneDelete) {
-            strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
+            strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME);
             if(subghz_delete_file(subghz)) {
                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
             } else {

+ 8 - 3
applications/subghz/scenes/subghz_scene_delete_raw.c

@@ -21,8 +21,13 @@ void subghz_scene_delete_raw_on_enter(void* context) {
     string_init(frequency_str);
     string_init(modulation_str);
 
-    char delete_str[256];
-    snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", subghz->file_name);
+    char delete_str[SUBGHZ_MAX_LEN_NAME + 16];
+    string_t file_name;
+    string_init(file_name);
+    path_extract_filename_no_ext(subghz->file_path, file_name);
+    snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(file_name));
+    string_clear(file_name);
+
     widget_add_text_box_element(
         subghz->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false);
 
@@ -56,7 +61,7 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) {
     SubGhz* subghz = context;
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubGhzCustomEventSceneDeleteRAW) {
-            strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
+            strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME);
             if(subghz_delete_file(subghz)) {
                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
             } else {

+ 1 - 1
applications/subghz/scenes/subghz_scene_more_raw.c

@@ -45,7 +45,7 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) {
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW);
             return true;
         } else if(event.event == SubmenuIndexEdit) {
-            memset(subghz->file_name_tmp, 0, sizeof(subghz->file_name_tmp));
+            memset(subghz->file_path_tmp, 0, sizeof(subghz->file_path_tmp));
             scene_manager_set_scene_state(
                 subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit);
             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);

+ 18 - 10
applications/subghz/scenes/subghz_scene_read_raw.c

@@ -23,8 +23,7 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
             break;
         }
 
-        path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str);
-        strncpy(subghz->file_name, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
+        strncpy(subghz->file_path, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
 
         ret = true;
     } while(false);
@@ -66,19 +65,23 @@ void subghz_scene_read_raw_callback_end_tx(void* context) {
 
 void subghz_scene_read_raw_on_enter(void* context) {
     SubGhz* subghz = context;
+    string_t file_name;
+    string_init(file_name);
 
     switch(subghz->txrx->rx_key_state) {
     case SubGhzRxKeyStateBack:
         subghz_read_raw_set_status(subghz->subghz_read_raw, SubGhzReadRAWStatusIDLE, "");
         break;
     case SubGhzRxKeyStateRAWLoad:
+        path_extract_filename_no_ext(subghz->file_path, file_name);
         subghz_read_raw_set_status(
-            subghz->subghz_read_raw, SubGhzReadRAWStatusLoadKeyTX, subghz->file_name);
+            subghz->subghz_read_raw, SubGhzReadRAWStatusLoadKeyTX, string_get_cstr(file_name));
         subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
         break;
     case SubGhzRxKeyStateRAWSave:
+        path_extract_filename_no_ext(subghz->file_path, file_name);
         subghz_read_raw_set_status(
-            subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, subghz->file_name);
+            subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, string_get_cstr(file_name));
         subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
         break;
     default:
@@ -86,14 +89,14 @@ void subghz_scene_read_raw_on_enter(void* context) {
         subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
         break;
     }
-
+    string_clear(file_name);
     subghz_scene_read_raw_update_statusbar(subghz);
 
     //set callback view raw
     subghz_read_raw_set_callback(subghz->subghz_read_raw, subghz_scene_read_raw_callback, subghz);
 
-    subghz->txrx->decoder_result =
-        subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, "RAW");
+    subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
+        subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME);
     furi_assert(subghz->txrx->decoder_result);
 
     //set filter RAW feed
@@ -230,10 +233,15 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
             };
             subghz_protocol_raw_save_to_file_stop(
                 (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result);
-            subghz_protocol_raw_gen_fff_data(
-                subghz->txrx->fff_data, SUBGHZ_APP_FOLDER, RAW_FILE_NAME);
-            subghz->state_notifications = SubGhzNotificationStateIDLE;
 
+            string_t temp_str;
+            string_init(temp_str);
+            string_printf(
+                temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION);
+            subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str));
+            string_clear(temp_str);
+
+            subghz->state_notifications = SubGhzNotificationStateIDLE;
             subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
 
             return true;

+ 33 - 17
applications/subghz/scenes/subghz_scene_save_name.c

@@ -4,6 +4,8 @@
 #include <lib/subghz/protocols/raw.h>
 #include <gui/modules/validators.h>
 
+#define MAX_TEXT_INPUT_LEN 22
+
 void subghz_scene_save_name_text_input_callback(void* context) {
     furi_assert(context);
     SubGhz* subghz = context;
@@ -17,50 +19,65 @@ void subghz_scene_save_name_on_enter(void* context) {
     TextInput* text_input = subghz->text_input;
     bool dev_name_empty = false;
 
-    if(!strcmp(subghz->file_name, "")) {
-        set_random_name(subghz->file_name, sizeof(subghz->file_name));
+    string_t file_name;
+    string_init(file_name);
+
+    if(!strcmp(subghz->file_path, "")) {
+        char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0};
+        set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME);
+        string_set(file_name, file_name_buf);
+        strncpy(subghz->file_dir, SUBGHZ_APP_FOLDER, SUBGHZ_MAX_LEN_NAME);
         //highlighting the entire filename by default
         dev_name_empty = true;
     } else {
-        strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
+        strncpy(subghz->file_path_tmp, subghz->file_path, SUBGHZ_MAX_LEN_NAME);
+        path_extract_dirname(subghz->file_path, file_name);
+        strncpy(subghz->file_dir, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME);
+        path_extract_filename_no_ext(subghz->file_path, file_name);
         if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
            SubGhzCustomEventManagerNoSet) {
             subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME);
+            path_extract_filename_no_ext(subghz->file_path, file_name);
             if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) ==
                SubGhzCustomEventManagerSetRAW) {
                 dev_name_empty = true;
             }
         }
     }
-
+    strncpy(subghz->file_path, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME);
     text_input_set_header_text(text_input, "Name signal");
     text_input_set_result_callback(
         text_input,
         subghz_scene_save_name_text_input_callback,
         subghz,
-        subghz->file_name,
-        SUBGHZ_MAX_LEN_NAME + 1, // buffer size
+        subghz->file_path,
+        MAX_TEXT_INPUT_LEN, // buffer size
         dev_name_empty);
 
-    ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
-        SUBGHZ_APP_FOLDER,
-        SUBGHZ_APP_EXTENSION,
-        (dev_name_empty) ? (NULL) : (subghz->file_name_tmp));
+    ValidatorIsFile* validator_is_file =
+        validator_is_file_alloc_init(subghz->file_dir, SUBGHZ_APP_EXTENSION, NULL);
     text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
 
+    string_clear(file_name);
+
     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTextInput);
 }
 
 bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
     SubGhz* subghz = context;
     if(event.type == SceneManagerEventTypeBack) {
-        strncpy(subghz->file_name, subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME);
+        strncpy(subghz->file_path, subghz->file_path_tmp, SUBGHZ_MAX_LEN_NAME);
         scene_manager_previous_scene(subghz->scene_manager);
         return true;
     } else if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubGhzCustomEventSceneSaveName) {
-            if(strcmp(subghz->file_name, "")) {
-                if(strcmp(subghz->file_name_tmp, "")) {
+            if(strcmp(subghz->file_path, "")) {
+                string_t temp_str;
+                string_init_printf(
+                    temp_str, "%s/%s%s", subghz->file_dir, subghz->file_path, SUBGHZ_APP_EXTENSION);
+                strncpy(subghz->file_path, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
+                string_clear(temp_str);
+                if(strcmp(subghz->file_path_tmp, "")) {
                     if(!subghz_rename_file(subghz)) {
                         return false;
                     }
@@ -68,7 +85,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
                     if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) !=
                        SubGhzCustomEventManagerNoSet) {
                         subghz_save_protocol_to_file(
-                            subghz, subghz->txrx->fff_data, subghz->file_name);
+                            subghz, subghz->txrx->fff_data, subghz->file_path);
                         scene_manager_set_scene_state(
                             subghz->scene_manager,
                             SubGhzSceneSetType,
@@ -78,14 +95,13 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
                             subghz,
                             subghz_history_get_raw_data(
                                 subghz->txrx->history, subghz->txrx->idx_menu_chosen),
-                            subghz->file_name);
+                            subghz->file_path);
                     }
                 }
 
                 if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
                    SubGhzCustomEventManagerNoSet) {
-                    subghz_protocol_raw_gen_fff_data(
-                        subghz->txrx->fff_data, SUBGHZ_APP_FOLDER, subghz->file_name);
+                    subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, subghz->file_path);
                     scene_manager_set_scene_state(
                         subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);
                 } else {

+ 3 - 7
applications/subghz/subghz.c

@@ -242,8 +242,8 @@ void subghz_free(SubGhz* subghz) {
     subghz->notifications = NULL;
 
     // About birds
-    furi_assert(subghz->file_name[SUBGHZ_MAX_LEN_NAME] == 0);
-    furi_assert(subghz->file_name_tmp[SUBGHZ_MAX_LEN_NAME] == 0);
+    furi_assert(subghz->file_path[SUBGHZ_MAX_LEN_NAME] == 0);
+    furi_assert(subghz->file_path_tmp[SUBGHZ_MAX_LEN_NAME] == 0);
 
     // The rest
     free(subghz);
@@ -260,12 +260,8 @@ int32_t subghz_app(void* p) {
     // Check argument and run corresponding scene
     if(p) {
         if(subghz_key_load(subghz, p)) {
-            string_t filename;
-            string_init(filename);
+            strncpy(subghz->file_path, p, SUBGHZ_MAX_LEN_NAME);
 
-            path_extract_filename_no_ext(p, filename);
-            strncpy(subghz->file_name, string_get_cstr(filename), SUBGHZ_MAX_LEN_NAME);
-            string_clear(filename);
             if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) {
                 //Load Raw TX
                 subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;

+ 50 - 57
applications/subghz/subghz_i.c

@@ -13,7 +13,6 @@
 #include <flipper_format/flipper_format_i.h>
 #include <lib/toolbox/stream/stream.h>
 #include <lib/subghz/protocols/raw.h>
-#include <lib/toolbox/path.h>
 
 #define TAG "SubGhz"
 
@@ -190,8 +189,8 @@ void subghz_tx_stop(SubGhz* subghz) {
 
     //if protocol dynamic then we save the last upload
     if((subghz->txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) &&
-       (strcmp(subghz->file_name, ""))) {
-        subghz_save_protocol_to_file(subghz, subghz->txrx->fff_data, subghz->file_name);
+       (strcmp(subghz->file_path, ""))) {
+        subghz_save_protocol_to_file(subghz, subghz->txrx->fff_data, subghz->file_path);
     }
     subghz_idle(subghz);
     notification_message(subghz->notifications, &sequence_reset_red);
@@ -277,17 +276,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
         }
         if(!strcmp(string_get_cstr(temp_str), "RAW")) {
             //if RAW
-            string_t file_name;
-            string_init(file_name);
-            string_t path;
-            string_init(path);
-            path_extract_filename_no_ext(file_path, file_name);
-            path_extract_dirname(file_path, path);
-            subghz_protocol_raw_gen_fff_data(
-                subghz->txrx->fff_data, string_get_cstr(path), string_get_cstr(file_name));
-            string_clear(path);
-            string_clear(file_name);
-
+            subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, file_path);
         } else {
             stream_copy_full(
                 flipper_format_get_raw_stream(fff_data_file),
@@ -334,19 +323,41 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
 
     Storage* storage = furi_record_open("storage");
     string_t temp_str;
+    string_t file_name;
+    string_t file_path;
+
     string_init(temp_str);
+    string_init(file_name);
+    string_init(file_path);
+
     bool res = false;
 
-    if(strcmp(subghz->file_name, "")) {
+    if(strcmp(subghz->file_path, "")) {
         //get the name of the next free file
+        path_extract_filename_no_ext(subghz->file_path, file_name);
+        path_extract_dirname(subghz->file_path, file_path);
+
         storage_get_next_filename(
-            storage, SUBGHZ_RAW_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION, temp_str, max_len);
+            storage,
+            string_get_cstr(file_path),
+            string_get_cstr(file_name),
+            SUBGHZ_APP_EXTENSION,
+            file_name,
+            max_len);
 
-        strncpy(subghz->file_name, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
+        string_printf(
+            temp_str,
+            "%s/%s%s",
+            string_get_cstr(file_path),
+            string_get_cstr(file_name),
+            SUBGHZ_APP_EXTENSION);
+        strncpy(subghz->file_path, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
         res = true;
     }
 
     string_clear(temp_str);
+    string_clear(file_path);
+    string_clear(file_name);
     furi_record_close("storage");
 
     return res;
@@ -355,44 +366,40 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
 bool subghz_save_protocol_to_file(
     SubGhz* subghz,
     FlipperFormat* flipper_format,
-    const char* dev_name) {
+    const char* dev_file_name) {
     furi_assert(subghz);
     furi_assert(flipper_format);
-    furi_assert(dev_name);
+    furi_assert(dev_file_name);
 
     Storage* storage = furi_record_open("storage");
     Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format);
 
-    string_t dev_file_name;
-    string_init(dev_file_name);
     bool saved = false;
+    string_t file_dir;
+    string_init(file_dir);
 
+    path_extract_dirname(dev_file_name, file_dir);
     do {
         //removing additional fields
         flipper_format_delete_key(flipper_format, "Repeat");
         flipper_format_delete_key(flipper_format, "Manufacture");
 
         // Create subghz folder directory if necessary
-        if(!storage_simply_mkdir(storage, SUBGHZ_APP_FOLDER)) {
+        if(!storage_simply_mkdir(storage, string_get_cstr(file_dir))) {
             dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder");
             break;
         }
 
-        // First remove subghz device file if it was saved
-        string_printf(dev_file_name, "%s/%s%s", SUBGHZ_APP_FOLDER, dev_name, SUBGHZ_APP_EXTENSION);
-
-        if(!storage_simply_remove(storage, string_get_cstr(dev_file_name))) {
+        if(!storage_simply_remove(storage, dev_file_name)) {
             break;
         }
         //ToDo check Write
         stream_seek(flipper_format_stream, 0, StreamOffsetFromStart);
-        stream_save_to_file(
-            flipper_format_stream, storage, string_get_cstr(dev_file_name), FSOM_CREATE_ALWAYS);
+        stream_save_to_file(flipper_format_stream, storage, dev_file_name, FSOM_CREATE_ALWAYS);
 
         saved = true;
     } while(0);
-
-    string_clear(dev_file_name);
+    string_clear(file_dir);
     furi_record_close("storage");
     return saved;
 }
@@ -400,26 +407,26 @@ bool subghz_save_protocol_to_file(
 bool subghz_load_protocol_from_file(SubGhz* subghz) {
     furi_assert(subghz);
 
-    string_t file_name;
-    string_init(file_name);
+    string_t file_path;
+    string_init(file_path);
 
     // Input events and views are managed by file_select
     bool res = dialog_file_select_show(
         subghz->dialogs,
         SUBGHZ_APP_FOLDER,
         SUBGHZ_APP_EXTENSION,
-        subghz->file_name,
-        sizeof(subghz->file_name),
+        subghz->file_path,
+        sizeof(subghz->file_path),
         NULL);
 
     if(res) {
         string_printf(
-            file_name, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION);
-
-        res = subghz_key_load(subghz, string_get_cstr(file_name));
+            file_path, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_path, SUBGHZ_APP_EXTENSION);
+        strncpy(subghz->file_path, string_get_cstr(file_path), SUBGHZ_MAX_LEN_NAME);
+        res = subghz_key_load(subghz, subghz->file_path);
     }
 
-    string_clear(file_name);
+    string_clear(file_path);
 
     return res;
 }
@@ -427,29 +434,18 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) {
 bool subghz_rename_file(SubGhz* subghz) {
     furi_assert(subghz);
     bool ret = true;
-    string_t old_path;
-    string_t new_path;
 
     Storage* storage = furi_record_open("storage");
 
-    string_init_printf(
-        old_path, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_name_tmp, SUBGHZ_APP_EXTENSION);
-
-    string_init_printf(
-        new_path, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION);
-
-    if(string_cmp(old_path, new_path) != 0) {
+    if(strcmp(subghz->file_path_tmp, subghz->file_path)) {
         FS_Error fs_result =
-            storage_common_rename(storage, string_get_cstr(old_path), string_get_cstr(new_path));
+            storage_common_rename(storage, subghz->file_path_tmp, subghz->file_path);
 
         if(fs_result != FSE_OK) {
             dialog_message_show_storage_error(subghz->dialogs, "Cannot rename\n file/directory");
             ret = false;
         }
     }
-
-    string_clear(old_path);
-    string_clear(new_path);
     furi_record_close("storage");
 
     return ret;
@@ -459,10 +455,7 @@ bool subghz_delete_file(SubGhz* subghz) {
     furi_assert(subghz);
 
     Storage* storage = furi_record_open("storage");
-    string_t file_path;
-    string_init_printf(
-        file_path, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_name_tmp, SUBGHZ_APP_EXTENSION);
-    bool result = storage_simply_remove(storage, string_get_cstr(file_path));
+    bool result = storage_simply_remove(storage, subghz->file_path_tmp);
     furi_record_close("storage");
 
     subghz_file_name_clear(subghz);
@@ -472,8 +465,8 @@ bool subghz_delete_file(SubGhz* subghz) {
 
 void subghz_file_name_clear(SubGhz* subghz) {
     furi_assert(subghz);
-    memset(subghz->file_name, 0, sizeof(subghz->file_name));
-    memset(subghz->file_name_tmp, 0, sizeof(subghz->file_name_tmp));
+    memset(subghz->file_path, 0, sizeof(subghz->file_path));
+    memset(subghz->file_path_tmp, 0, sizeof(subghz->file_path_tmp));
 }
 
 uint32_t subghz_random_serial(void) {

+ 7 - 4
applications/subghz/subghz_i.h

@@ -33,8 +33,9 @@
 #include "subghz_setting.h"
 
 #include <gui/modules/variable_item_list.h>
+#include <lib/toolbox/path.h>
 
-#define SUBGHZ_MAX_LEN_NAME 128
+#define SUBGHZ_MAX_LEN_NAME 250
 
 /** SubGhzNotification state */
 typedef enum {
@@ -117,8 +118,10 @@ struct SubGhz {
     TextInput* text_input;
     Widget* widget;
     DialogsApp* dialogs;
-    char file_name[SUBGHZ_MAX_LEN_NAME + 1];
-    char file_name_tmp[SUBGHZ_MAX_LEN_NAME + 1];
+    char file_path[SUBGHZ_MAX_LEN_NAME + 1];
+    char file_path_tmp[SUBGHZ_MAX_LEN_NAME + 1];
+    //ToDo you can get rid of it, you need to refactor text input to return the path to the folder
+    char file_dir[SUBGHZ_MAX_LEN_NAME + 1];
     SubGhzNotificationState state_notifications;
 
     SubGhzViewReceiver* subghz_receiver;
@@ -164,7 +167,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len);
 bool subghz_save_protocol_to_file(
     SubGhz* subghz,
     FlipperFormat* flipper_format,
-    const char* dev_name);
+    const char* dev_file_name);
 bool subghz_load_protocol_from_file(SubGhz* subghz);
 bool subghz_rename_file(SubGhz* subghz);
 bool subghz_delete_file(SubGhz* subghz);

+ 2 - 10
lib/subghz/protocols/raw.c

@@ -293,27 +293,19 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in
     return instance->is_runing;
 }
 
-void subghz_protocol_raw_gen_fff_data(
-    FlipperFormat* flipper_format,
-    const char* path,
-    const char* file_name) {
-    string_t temp_str;
-    string_init(temp_str);
+void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path) {
     do {
         stream_clean(flipper_format_get_raw_stream(flipper_format));
         if(!flipper_format_write_string_cstr(flipper_format, "Protocol", "RAW")) {
             FURI_LOG_E(TAG, "Unable to add Protocol");
             break;
         }
-        string_printf(temp_str, "%s/%s%s", path, file_name, SUBGHZ_APP_EXTENSION);
 
-        if(!flipper_format_write_string_cstr(
-               flipper_format, "File_name", string_get_cstr(temp_str))) {
+        if(!flipper_format_write_string_cstr(flipper_format, "File_name", file_path)) {
             FURI_LOG_E(TAG, "Unable to add File_name");
             break;
         }
     } while(false);
-    string_clear(temp_str);
 }
 
 bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipper_format) {

+ 2 - 6
lib/subghz/protocols/raw.h

@@ -113,13 +113,9 @@ void subghz_protocol_raw_file_encoder_worker_set_callback_end(
 /**
  * File generation for RAW work.
  * @param flipper_format Pointer to a FlipperFormat instance
- * @param path File path
- * @param file_name File name
+ * @param file_path File path
  */
-void subghz_protocol_raw_gen_fff_data(
-    FlipperFormat* flipper_format,
-    const char* path,
-    const char* file_name);
+void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path);
 
 /**
  * Deserialize and generating an upload to send.