From 5309bfae4101e5675bcf961adcd11f8cfb0f5efb Mon Sep 17 00:00:00 2001 From: gornekich <44112859+gornekich@users.noreply.github.com> Date: Wed, 31 Mar 2021 20:47:32 +0300 Subject: [PATCH] [FL-1061] iButton save and load from sd card (#394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SD App: fix queue adresses * sd-filesystem: fix making path on file select event * ibutton: add key reading from sd card * ibutton: save ibutton key to sd card * ibutton: add deleting keys from sd card * ibutton: remove KeyStore from application * ibutton: make directory if necessary on key save Co-authored-by: DrZlo13 Co-authored-by: あく --- applications/applications.c | 2 +- applications/gui/modules/file_select.c | 12 ++-- applications/ibutton/helpers/key-store.cpp | 69 ------------------- applications/ibutton/helpers/key-store.h | 29 -------- applications/ibutton/ibutton-app.cpp | 32 +++++---- applications/ibutton/ibutton-app.h | 22 +++--- applications/ibutton/ibutton-key.cpp | 23 ------- applications/ibutton/ibutton-key.h | 13 ---- .../scene/ibutton-scene-delete-confirm.cpp | 17 +++-- .../scene/ibutton-scene-delete-success.cpp | 2 +- .../ibutton/scene/ibutton-scene-save-name.cpp | 24 +++++-- .../ibutton/scene/ibutton-scene-saved.cpp | 62 ----------------- .../ibutton/scene/ibutton-scene-saved.h | 12 ---- .../ibutton/scene/ibutton-scene-start.cpp | 38 +++++++++- applications/sd-filesystem/sd-filesystem.c | 31 +++++++-- 15 files changed, 132 insertions(+), 256 deletions(-) delete mode 100644 applications/ibutton/helpers/key-store.cpp delete mode 100644 applications/ibutton/helpers/key-store.h delete mode 100644 applications/ibutton/scene/ibutton-scene-saved.cpp delete mode 100644 applications/ibutton/scene/ibutton-scene-saved.h diff --git a/applications/applications.c b/applications/applications.c index 30285779..9a9b4e50 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -177,7 +177,7 @@ const FlipperApplication FLIPPER_APPS[] = { #endif #ifdef BUILD_IBUTTON - {.app = app_ibutton, .name = "iButton", .stack_size = 1024, .icon = A_iButton_14}, + {.app = app_ibutton, .name = "iButton", .stack_size = 4096, .icon = A_iButton_14}, #endif #ifdef BUILD_GPIO_DEMO diff --git a/applications/gui/modules/file_select.c b/applications/gui/modules/file_select.c index 55c18174..1b565297 100644 --- a/applications/gui/modules/file_select.c +++ b/applications/gui/modules/file_select.c @@ -96,6 +96,9 @@ static bool file_select_input_callback(InputEvent* event, void* context) { return true; }); consumed = true; + if(!file_select_fill_strings(file_select)) { + file_select->callback(false, file_select->context); + } } else if(event->key == InputKeyDown) { with_view_model( file_select->view, (FileSelectModel * model) { @@ -121,6 +124,9 @@ static bool file_select_input_callback(InputEvent* event, void* context) { return true; }); consumed = true; + if(!file_select_fill_strings(file_select)) { + file_select->callback(false, file_select->context); + } } else if(event->key == InputKeyOk) { if(file_select->callback != NULL) { const char* result; @@ -138,10 +144,6 @@ static bool file_select_input_callback(InputEvent* event, void* context) { } consumed = true; } - - if(!file_select_fill_strings(file_select)) { - file_select->callback(false, file_select->context); - } } return consumed; @@ -207,6 +209,8 @@ void file_select_set_api(FileSelect* file_select, FS_Api* fs_api) { } void file_select_set_callback(FileSelect* file_select, FileSelectCallback callback, void* context) { + file_select->context = context; + file_select->callback = callback; } void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension) { diff --git a/applications/ibutton/helpers/key-store.cpp b/applications/ibutton/helpers/key-store.cpp deleted file mode 100644 index ea33bb37..00000000 --- a/applications/ibutton/helpers/key-store.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "key-store.h" -#include - -uint16_t KeyStore::get_key_count() { - return store.size(); -} - -uint8_t KeyStore::add_key() { - store.push_back(iButtonKey()); - return get_key_count() - 1; -} - -void KeyStore::set_key_type(uint8_t index, iButtonKeyType type) { - iButtonKey* key = get_key(index); - key->set_type(type); -} - -void KeyStore::set_key_name(uint8_t index, char* name) { - iButtonKey* key = get_key(index); - char* orphan = strdup(name); - key->set_name(orphan); -} - -void KeyStore::set_key_data(uint8_t index, uint8_t* data, uint8_t data_size) { - iButtonKey* key = get_key(index); - key->set_data(data, data_size); -} - -iButtonKeyType KeyStore::get_key_type(uint8_t index) { - iButtonKey* key = get_key(index); - return key->get_key_type(); -} - -const char* KeyStore::get_key_name(uint8_t index) { - iButtonKey* key = get_key(index); - return key->get_name(); -} - -uint8_t* KeyStore::get_key_data(uint8_t index) { - iButtonKey* key = get_key(index); - return key->get_data(); -} - -void KeyStore::remove_key(uint8_t index) { - furi_check(index >= 0); - furi_check(index < get_key_count()); - auto item = std::next(store.begin(), index); - store.erase(item); -} - -KeyStore::KeyStore() { - store.push_back(iButtonKey( - iButtonKeyType::KeyDallas, "Dallas_1", 0x01, 0x41, 0xCE, 0x67, 0x0F, 0x00, 0x00, 0xB6)); - store.push_back(iButtonKey( - iButtonKeyType::KeyDallas, "Dallas_2", 0x01, 0xFD, 0x0E, 0x84, 0x01, 0x00, 0x00, 0xDB)); - store.push_back(iButtonKey( - iButtonKeyType::KeyCyfral, "Cyfral_1", 0xA6, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - store.push_back(iButtonKey( - iButtonKeyType::KeyMetakom, "Metakom_1", 0xB1, 0x2E, 0x47, 0xB2, 0x00, 0x00, 0x00, 0x00)); -} - -KeyStore::~KeyStore() { -} - -iButtonKey* KeyStore::get_key(uint8_t index) { - furi_check(index >= 0); - furi_check(index < get_key_count()); - return &(*std::next(store.begin(), index)); -} diff --git a/applications/ibutton/helpers/key-store.h b/applications/ibutton/helpers/key-store.h deleted file mode 100644 index 8033d4d9..00000000 --- a/applications/ibutton/helpers/key-store.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include -#include -#include "key-info.h" -#include "../ibutton-key.h" - -class KeyStore { -public: - uint16_t get_key_count(); - - uint8_t add_key(); - - void set_key_type(uint8_t index, iButtonKeyType type); - void set_key_name(uint8_t index, char* name); - void set_key_data(uint8_t index, uint8_t* data, uint8_t data_size); - - iButtonKeyType get_key_type(uint8_t index); - const char* get_key_name(uint8_t index); - uint8_t* get_key_data(uint8_t index); - - void remove_key(uint8_t index); - - KeyStore(); - ~KeyStore(); - -private: - std::list store; - iButtonKey* get_key(uint8_t index); -}; \ No newline at end of file diff --git a/applications/ibutton/ibutton-app.cpp b/applications/ibutton/ibutton-app.cpp index 74758280..fef1942f 100644 --- a/applications/ibutton/ibutton-app.cpp +++ b/applications/ibutton/ibutton-app.cpp @@ -28,12 +28,16 @@ iButtonApp::iButtonApp() { api_hal_power_insomnia_enter(); key_worker = new KeyWorker(&ibutton_gpio); + sd_ex_api = static_cast(furi_record_open("sdcard-ex")); + fs_api = static_cast(furi_record_open("sdcard")); // we need random srand(DWT->CYCCNT); } iButtonApp::~iButtonApp() { + furi_record_close("sdcard-ex"); + furi_record_close("sdcard"); api_hal_power_insomnia_exit(); } @@ -107,6 +111,22 @@ iButtonKey* iButtonApp::get_key() { return &key; } +SdCard_Api* iButtonApp::get_sd_ex_api() { + return sd_ex_api; +} + +FS_Api* iButtonApp::get_fs_api() { + return fs_api; +} + +char* iButtonApp::get_file_name() { + return file_name; +} + +uint8_t iButtonApp::get_file_name_size() { + return file_name_size; +} + void iButtonApp::notify_init() { // TODO open record const GpioPin* vibro_record = &vibro_gpio; @@ -193,18 +213,6 @@ uint8_t iButtonApp::get_text_store_size() { return text_store_size; } -KeyStore* iButtonApp::get_key_store() { - return &store; -} - -uint8_t iButtonApp::get_stored_key_index() { - return key_index; -} - -void iButtonApp::set_stored_key_index(uint8_t _index) { - key_index = _index; -} - void iButtonApp::generate_random_name(char* name, uint8_t max_name_size) { const uint8_t prefix_size = 9; const char* prefix[prefix_size] = { diff --git a/applications/ibutton/ibutton-app.h b/applications/ibutton/ibutton-app.h index 6b32ea5e..142473b9 100644 --- a/applications/ibutton/ibutton-app.h +++ b/applications/ibutton/ibutton-app.h @@ -12,7 +12,6 @@ #include "scene/ibutton-scene-readed-key-menu.h" #include "scene/ibutton-scene-write.h" #include "scene/ibutton-scene-write-success.h" -#include "scene/ibutton-scene-saved.h" #include "scene/ibutton-scene-saved-key-menu.h" #include "scene/ibutton-scene-delete-confirm.h" #include "scene/ibutton-scene-delete-success.h" @@ -23,9 +22,11 @@ #include "scene/ibutton-scene-add-type.h" #include "scene/ibutton-scene-add-value.h" -#include "helpers/key-store.h" #include "helpers/key-worker.h" +#include +#include + #include "one_wire_master.h" #include "maxim_crc.h" #include "ibutton-key.h" @@ -48,7 +49,6 @@ public: SceneWrite, SceneWriteSuccess, SceneEmulate, - SceneSavedList, SceneSavedKeyMenu, SceneDeleteConfirm, SceneDeleteSuccess, @@ -88,9 +88,10 @@ public: char* get_text_store(); uint8_t get_text_store_size(); - KeyStore* get_key_store(); - uint8_t get_stored_key_index(); - void set_stored_key_index(uint8_t index); + SdCard_Api* get_sd_ex_api(); + FS_Api* get_fs_api(); + char* get_file_name(); + uint8_t get_file_name_size(); void generate_random_name(char* name, uint8_t max_name_size); @@ -109,7 +110,6 @@ private: {Scene::SceneWrite, new iButtonSceneWrite()}, {Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()}, {Scene::SceneEmulate, new iButtonSceneEmulate()}, - {Scene::SceneSavedList, new iButtonSceneSavedList()}, {Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()}, {Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()}, {Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()}, @@ -123,12 +123,14 @@ private: KeyWorker* key_worker; iButtonKey key; - uint8_t key_index = 0; + + SdCard_Api* sd_ex_api; + FS_Api* fs_api; + static const uint8_t file_name_size = 100; + char file_name[file_name_size]; static const uint8_t text_store_size = 128; char text_store[text_store_size + 1]; - KeyStore store; - void notify_init(); }; \ No newline at end of file diff --git a/applications/ibutton/ibutton-key.cpp b/applications/ibutton/ibutton-key.cpp index 16a2aa07..a32b5003 100644 --- a/applications/ibutton/ibutton-key.cpp +++ b/applications/ibutton/ibutton-key.cpp @@ -51,28 +51,5 @@ iButtonKeyType iButtonKey::get_key_type() { return type; } -iButtonKey::iButtonKey( - iButtonKeyType _type, - const char* _name, - uint8_t d0, - uint8_t d1, - uint8_t d2, - uint8_t d3, - uint8_t d4, - uint8_t d5, - uint8_t d6, - uint8_t d7) { - type = _type; - name = _name; - data[0] = d0; - data[1] = d1; - data[2] = d2; - data[3] = d3; - data[4] = d4; - data[5] = d5; - data[6] = d6; - data[7] = d7; -} - iButtonKey::iButtonKey() { } diff --git a/applications/ibutton/ibutton-key.h b/applications/ibutton/ibutton-key.h index aa693180..7a1533dc 100644 --- a/applications/ibutton/ibutton-key.h +++ b/applications/ibutton/ibutton-key.h @@ -16,19 +16,6 @@ public: void set_type(iButtonKeyType key_type); iButtonKeyType get_key_type(); - // temporary constructor for KeyStore mockup - iButtonKey( - iButtonKeyType type, - const char* name, - uint8_t d0, - uint8_t d1, - uint8_t d2, - uint8_t d3, - uint8_t d4, - uint8_t d5, - uint8_t d6, - uint8_t d7); - iButtonKey(); private: diff --git a/applications/ibutton/scene/ibutton-scene-delete-confirm.cpp b/applications/ibutton/scene/ibutton-scene-delete-confirm.cpp index c9f71d25..84ba94b5 100644 --- a/applications/ibutton/scene/ibutton-scene-delete-confirm.cpp +++ b/applications/ibutton/scene/ibutton-scene-delete-confirm.cpp @@ -55,10 +55,19 @@ bool iButtonSceneDeleteConfirm::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeDialogResult) { if(event->payload.dialog_result == DialogExResultRight) { - KeyStore* store = app->get_key_store(); - store->remove_key(app->get_stored_key_index()); - - app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteSuccess); + iButtonKey* key = app->get_key(); + string_t key_file_name; + string_init_set_str(key_file_name, "ibutton/"); + string_cat_str(key_file_name, key->get_name()); + bool res = + (app->get_fs_api()->common.remove(string_get_cstr(key_file_name)) == FSE_OK); + string_clear(key_file_name); + if(res) { + app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteSuccess); + } else { + // TODO error file path + // app->switch_to_next_scene(iButtonApp::Scene::SceneDeleteFail); + } } else { app->switch_to_previous_scene(); } diff --git a/applications/ibutton/scene/ibutton-scene-delete-success.cpp b/applications/ibutton/scene/ibutton-scene-delete-success.cpp index 1127b8f0..e0471daf 100644 --- a/applications/ibutton/scene/ibutton-scene-delete-success.cpp +++ b/applications/ibutton/scene/ibutton-scene-delete-success.cpp @@ -25,7 +25,7 @@ bool iButtonSceneDeleteSuccess::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; if(event->type == iButtonEvent::Type::EventTypeBack) { - app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneSavedList}); + app->search_and_switch_to_previous_scene({iButtonApp::Scene::SceneStart}); consumed = true; } diff --git a/applications/ibutton/scene/ibutton-scene-save-name.cpp b/applications/ibutton/scene/ibutton-scene-save-name.cpp index 7243ba5d..e84cf2f2 100644 --- a/applications/ibutton/scene/ibutton-scene-save-name.cpp +++ b/applications/ibutton/scene/ibutton-scene-save-name.cpp @@ -4,6 +4,7 @@ #include "../ibutton-event.h" #include "../ibutton-key.h" #include +#include void iButtonSceneSaveName::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); @@ -28,14 +29,23 @@ bool iButtonSceneSaveName::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; if(event->type == iButtonEvent::Type::EventTypeTextEditResult) { - KeyStore* store = app->get_key_store(); - uint8_t key_index = store->add_key(); iButtonKey* key = app->get_key(); - - store->set_key_type(key_index, key->get_key_type()); - store->set_key_name(key_index, app->get_text_store()); - store->set_key_data(key_index, key->get_data(), key->get_size()); - + File key_file; + string_t key_file_name; + string_init_set_str(key_file_name, "ibutton/"); + string_cat_str(key_file_name, app->get_text_store()); + uint8_t key_data[IBUTTON_KEY_SIZE + 1]; + key_data[0] = static_cast(key->get_key_type()); + memcpy(key_data + 1, key->get_data(), IBUTTON_KEY_SIZE); + // Create ibutton directory if necessary + app->get_fs_api()->common.mkdir("ibutton"); + bool res = app->get_fs_api()->file.open( + &key_file, string_get_cstr(key_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS); + if(res) { + res = app->get_fs_api()->file.write(&key_file, key_data, IBUTTON_KEY_SIZE + 1); + res = app->get_fs_api()->file.close(&key_file); + } + string_clear(key_file_name); app->switch_to_next_scene(iButtonApp::Scene::SceneSaveSuccess); consumed = true; } diff --git a/applications/ibutton/scene/ibutton-scene-saved.cpp b/applications/ibutton/scene/ibutton-scene-saved.cpp deleted file mode 100644 index d73755fc..00000000 --- a/applications/ibutton/scene/ibutton-scene-saved.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "ibutton-scene-saved.h" -#include "../ibutton-app.h" -#include "../ibutton-view-manager.h" -#include "../ibutton-event.h" -#include - -void iButtonSceneSavedList::on_enter(iButtonApp* app) { - iButtonAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &iButtonSceneSavedList::submenu_callback); - - KeyStore* store = app->get_key_store(); - - if(store->get_key_count() > 0) { - for(uint8_t i = 0; i < store->get_key_count(); i++) { - submenu_add_item(submenu, store->get_key_name(i), i, callback, app); - } - } else { - submenu_add_item(submenu, "Empty", 0, NULL, NULL); - } - - view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); -} - -bool iButtonSceneSavedList::on_event(iButtonApp* app, iButtonEvent* event) { - bool consumed = false; - - if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { - uint8_t key_index = event->payload.menu_index; - - // store data - iButtonKey* stored_key_data = app->get_key(); - KeyStore* store = app->get_key_store(); - - app->set_stored_key_index(key_index); - stored_key_data->set_name(store->get_key_name(key_index)); - stored_key_data->set_type(store->get_key_type(key_index)); - stored_key_data->set_data(store->get_key_data(key_index), stored_key_data->get_size()); - - app->switch_to_next_scene(iButtonApp::Scene::SceneSavedKeyMenu); - consumed = true; - } - - return consumed; -} - -void iButtonSceneSavedList::on_exit(iButtonApp* app) { - iButtonAppViewManager* view = app->get_view_manager(); - Submenu* submenu = view->get_submenu(); - - submenu_clean(submenu); -} - -void iButtonSceneSavedList::submenu_callback(void* context, uint32_t index) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton-scene-saved.h b/applications/ibutton/scene/ibutton-scene-saved.h deleted file mode 100644 index 99a996cd..00000000 --- a/applications/ibutton/scene/ibutton-scene-saved.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "ibutton-scene-generic.h" - -class iButtonSceneSavedList : public iButtonScene { -public: - void on_enter(iButtonApp* app) final; - bool on_event(iButtonApp* app, iButtonEvent* event) final; - void on_exit(iButtonApp* app) final; - -private: - void submenu_callback(void* context, uint32_t index); -}; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton-scene-start.cpp b/applications/ibutton/scene/ibutton-scene-start.cpp index 6944dc14..45f4bc38 100644 --- a/applications/ibutton/scene/ibutton-scene-start.cpp +++ b/applications/ibutton/scene/ibutton-scene-start.cpp @@ -3,6 +3,7 @@ #include "../ibutton-view-manager.h" #include "../ibutton-event.h" #include +#include typedef enum { SubmenuIndexRead, @@ -30,9 +31,40 @@ bool iButtonSceneStart::on_event(iButtonApp* app, iButtonEvent* event) { case SubmenuIndexRead: app->switch_to_next_scene(iButtonApp::Scene::SceneRead); break; - case SubmenuIndexSaved: - app->switch_to_next_scene(iButtonApp::Scene::SceneSavedList); - break; + case SubmenuIndexSaved: { + bool res = app->get_sd_ex_api()->file_select( + app->get_sd_ex_api()->context, + "ibutton", + "*", + app->get_file_name(), + app->get_file_name_size()); + if(res) { + string_t key_str; + string_init_set_str(key_str, "ibutton/"); + string_cat_str(key_str, app->get_file_name()); + File key_file; + uint8_t key_data[IBUTTON_KEY_SIZE + 1] = {}; + // Read data from file + // TODO handle false return + res = app->get_fs_api()->file.open( + &key_file, string_get_cstr(key_str), FSAM_READ, FSOM_OPEN_EXISTING); + res = app->get_fs_api()->file.read(&key_file, key_data, IBUTTON_KEY_SIZE + 1); + res = app->get_fs_api()->file.close(&key_file); + string_clear(key_str); + // Set key + iButtonKeyType key_type = static_cast(key_data[0]); + if(key_type > iButtonKeyType::KeyMetakom) { + app->switch_to_next_scene(iButtonApp::Scene::SceneStart); + } + app->get_key()->set_name(app->get_file_name()); + app->get_key()->set_type(key_type); + app->get_key()->set_data(key_data + 1, IBUTTON_KEY_SIZE); + app->switch_to_next_scene(iButtonApp::Scene::SceneSavedKeyMenu); + } else { + // TODO add error scene + app->switch_to_next_scene(iButtonApp::Scene::SceneStart); + } + }; break; case SubmenuIndexAdd: app->switch_to_next_scene(iButtonApp::Scene::SceneAddType); break; diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c index 6f96c094..a1dbd0c8 100644 --- a/applications/sd-filesystem/sd-filesystem.c +++ b/applications/sd-filesystem/sd-filesystem.c @@ -325,7 +325,7 @@ bool app_sd_make_path(const char* path) { if(*path) { char* file_path = strdup(path); - + // Make parent directories for(char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) { *p = '\0'; SDError result = f_mkdir(file_path); @@ -339,6 +339,14 @@ bool app_sd_make_path(const char* path) { } *p = '/'; } + // Make origin directory + SDError result = f_mkdir(file_path); + if(result != SD_OK) { + if(result != SD_EXIST) { + free(file_path); + return false; + } + } free(file_path); } @@ -393,7 +401,7 @@ bool sd_api_file_select( SdAppFileSelectResultEvent event; while(1) { osStatus_t event_status = - osMessageQueueGet(sd_app->event_queue, &event, NULL, osWaitForever); + osMessageQueueGet(return_event_queue, &event, NULL, osWaitForever); if(event_status == osOK) { retval = event.result; break; @@ -697,7 +705,7 @@ int32_t sd_filesystem(void* p) { case SdAppStateFileSelect: { SdAppFileSelectResultEvent retval = {.result = true}; furi_check( - osMessageQueuePut(event.result_receiver, &retval, 0, osWaitForever) == + osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == osOK); app_reset_state(sd_app); }; break; @@ -712,7 +720,7 @@ int32_t sd_filesystem(void* p) { case SdAppStateFileSelect: { SdAppFileSelectResultEvent retval = {.result = false}; furi_check( - osMessageQueuePut(event.result_receiver, &retval, 0, osWaitForever) == + osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == osOK); app_reset_state(sd_app); }; break; @@ -799,8 +807,12 @@ int32_t sd_filesystem(void* p) { break; case SdAppEventTypeFileSelect: if(!app_sd_make_path(event.payload.file_select_data.path)) { + SdAppFileSelectResultEvent retval = {.result = false}; + furi_check( + osMessageQueuePut(sd_app->result_receiver, &retval, 0, osWaitForever) == + osOK); + app_reset_state(sd_app); } - if(try_to_alloc_view_holder(sd_app, gui)) { sd_app->result_receiver = event.result_receiver; FileSelect* file_select = alloc_and_attach_file_select(sd_app); @@ -814,8 +826,15 @@ int32_t sd_filesystem(void* p) { event.payload.file_select_data.result, event.payload.file_select_data.result_size); if(!file_select_init(file_select)) { + SdAppFileSelectResultEvent retval = {.result = false}; + furi_check( + osMessageQueuePut( + sd_app->result_receiver, &retval, 0, osWaitForever) == osOK); + app_reset_state(sd_app); + } else { + sd_app->sd_app_state = SdAppStateFileSelect; + view_holder_start(sd_app->view_holder); } - sd_app->sd_app_state = SdAppStateFileSelect; } else { SdAppFileSelectResultEvent retval = {.result = false}; furi_check(