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

[FL-1499] NFC App: save and load from SD card (#560)

* nfc: add save name and save success scenes
* applications: increase nfc app stack size to 4k
* nfc: move nfc device data to separate file
* nfc: add nfc device save to SD card
* nfc: add file select scene
* nfc: add saved key menu scene
* nfc: add manual SAK, ATQA, UID enter
* nfc: add manual enter
* nfc scenes: remove typedef in SubmenuIndex enu
* nfc_device: close file_worker after load data

Co-authored-by: あく <alleteam@gmail.com>
gornekich 4 лет назад
Родитель
Сommit
602c125ef5
28 измененных файлов с 812 добавлено и 48 удалено
  1. 1 1
      applications/applications.c
  2. 16 0
      applications/nfc/nfc.c
  3. 123 0
      applications/nfc/nfc_device.c
  4. 55 0
      applications/nfc/nfc_device.h
  5. 26 0
      applications/nfc/nfc_i.h
  6. 1 33
      applications/nfc/nfc_worker.h
  7. 3 3
      applications/nfc/scenes/nfc_scene_card_menu.c
  8. 2 2
      applications/nfc/scenes/nfc_scene_debug_menu.c
  9. 7 4
      applications/nfc/scenes/nfc_scene_emulate_uid.c
  10. 39 0
      applications/nfc/scenes/nfc_scene_file_select.c
  11. 7 0
      applications/nfc/scenes/nfc_scene_file_select.h
  12. 1 0
      applications/nfc/scenes/nfc_scene_read_card.c
  13. 3 0
      applications/nfc/scenes/nfc_scene_read_card_success.c
  14. 72 0
      applications/nfc/scenes/nfc_scene_save_name.c
  15. 7 0
      applications/nfc/scenes/nfc_scene_save_name.h
  16. 66 0
      applications/nfc/scenes/nfc_scene_save_success.c
  17. 7 0
      applications/nfc/scenes/nfc_scene_save_success.h
  18. 83 0
      applications/nfc/scenes/nfc_scene_saved_menu.c
  19. 7 0
      applications/nfc/scenes/nfc_scene_saved_menu.h
  20. 61 0
      applications/nfc/scenes/nfc_scene_set_atqa.c
  21. 7 0
      applications/nfc/scenes/nfc_scene_set_atqa.h
  22. 60 0
      applications/nfc/scenes/nfc_scene_set_sak.c
  23. 7 0
      applications/nfc/scenes/nfc_scene_set_sak.h
  24. 67 0
      applications/nfc/scenes/nfc_scene_set_type.c
  25. 7 0
      applications/nfc/scenes/nfc_scene_set_type.h
  26. 65 0
      applications/nfc/scenes/nfc_scene_set_uid.c
  27. 7 0
      applications/nfc/scenes/nfc_scene_set_uid.h
  28. 5 5
      applications/nfc/scenes/nfc_scene_start.c

+ 1 - 1
applications/applications.c

@@ -175,7 +175,7 @@ const FlipperApplication FLIPPER_APPS[] = {
 #endif
 #endif
 
 
 #ifdef APP_NFC
 #ifdef APP_NFC
-    {.app = nfc_task, .name = "NFC", .stack_size = 1024, .icon = A_NFC_14},
+    {.app = nfc_task, .name = "NFC", .stack_size = 4096, .icon = A_NFC_14},
 #endif
 #endif
 
 
 #ifdef APP_SUBGHZ
 #ifdef APP_SUBGHZ

+ 16 - 0
applications/nfc/nfc.c

@@ -77,6 +77,14 @@ Nfc* nfc_alloc() {
     nfc->scene_debug_read_emv = nfc_scene_debug_read_emv_alloc();
     nfc->scene_debug_read_emv = nfc_scene_debug_read_emv_alloc();
     nfc->scene_debug_read_mifare_ul = nfc_scene_debug_read_mifare_ul_alloc();
     nfc->scene_debug_read_mifare_ul = nfc_scene_debug_read_mifare_ul_alloc();
     nfc->scene_emulate_uid = nfc_scene_emulate_uid_alloc();
     nfc->scene_emulate_uid = nfc_scene_emulate_uid_alloc();
+    nfc->scene_save_name = nfc_scene_save_name_alloc();
+    nfc->scene_save_success = nfc_scene_save_success_alloc();
+    nfc->scene_file_select = nfc_scene_file_select_alloc();
+    nfc->scene_saved_menu = nfc_scene_saved_menu_alloc();
+    nfc->scene_set_type = nfc_scene_set_type_alloc();
+    nfc->scene_set_sak = nfc_scene_set_sak_alloc();
+    nfc->scene_set_atqa = nfc_scene_set_atqa_alloc();
+    nfc->scene_set_uid = nfc_scene_set_uid_alloc();
 
 
     view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_start);
     view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_start);
 
 
@@ -138,6 +146,14 @@ void nfc_free(Nfc* nfc) {
     nfc_scene_debug_read_emv_free(nfc->scene_debug_read_emv);
     nfc_scene_debug_read_emv_free(nfc->scene_debug_read_emv);
     nfc_scene_debug_read_mifare_ul_free(nfc->scene_debug_read_mifare_ul);
     nfc_scene_debug_read_mifare_ul_free(nfc->scene_debug_read_mifare_ul);
     nfc_scene_emulate_uid_free(nfc->scene_emulate_uid);
     nfc_scene_emulate_uid_free(nfc->scene_emulate_uid);
+    nfc_scene_save_name_free(nfc->scene_save_name);
+    nfc_scene_save_success_free(nfc->scene_save_success);
+    nfc_scene_file_select_free(nfc->scene_file_select);
+    nfc_scene_saved_menu_free(nfc->scene_saved_menu);
+    nfc_scene_set_type_free(nfc->scene_set_type);
+    nfc_scene_set_sak_free(nfc->scene_set_sak);
+    nfc_scene_set_atqa_free(nfc->scene_set_atqa);
+    nfc_scene_set_uid_free(nfc->scene_set_uid);
 
 
     // View Dispatcher
     // View Dispatcher
     view_dispatcher_free(nfc->nfc_common.view_dispatcher);
     view_dispatcher_free(nfc->nfc_common.view_dispatcher);

+ 123 - 0
applications/nfc/nfc_device.c

@@ -0,0 +1,123 @@
+#include "nfc_device.h"
+
+#include <file-worker.h>
+
+#define NFC_DEVICE_MAX_DATA_LEN 14
+
+static const char* nfc_app_folder = "nfc";
+static const char* nfc_app_extension = ".nfc";
+
+void nfc_device_set_name(NfcDevice* dev, const char* name) {
+    furi_assert(dev);
+
+    strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN);
+}
+
+bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
+    furi_assert(dev);
+
+    FileWorker* file_worker = file_worker_alloc(false);
+    string_t dev_file_name;
+
+    // Create nfc directory if necessary
+    if(!file_worker_mkdir(file_worker, nfc_app_folder)) {
+        return false;
+    };
+
+    // First remove nfc device file if it was saved
+    string_init_printf(dev_file_name, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
+    if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) {
+        string_clear(dev_file_name);
+        return false;
+    };
+
+    // Prepare buffer to write
+    uint8_t buff[NFC_DEVICE_MAX_DATA_LEN];
+    buff[0] = dev->data.uid_len;
+    memcpy(&buff[1], dev->data.uid, dev->data.uid_len);
+    memcpy(&buff[dev->data.uid_len + 1], dev->data.atqa, 2);
+    buff[dev->data.uid_len + 3] = dev->data.sak;
+
+    // Save nfc device
+    bool res = file_worker_open(
+        file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS);
+    string_clear(dev_file_name);
+    if(res) {
+        // Write UID length
+        if(!file_worker_write_hex(file_worker, buff, dev->data.uid_len + 4)) {
+            file_worker_close(file_worker);
+            return false;
+        }
+    }
+    file_worker_close(file_worker);
+    file_worker_free(file_worker);
+
+    return true;
+}
+
+static bool nfc_device_load_data(FileWorker* file_worker, string_t path, NfcDevice* dev) {
+    // Open key file
+    if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
+        return false;
+    }
+
+    uint8_t buff[NFC_DEVICE_MAX_DATA_LEN] = {};
+
+    // Load first byte - UID length
+    if(!file_worker_read_hex(file_worker, buff, 1)) {
+        return false;
+    }
+    // Read space
+    uint8_t space = 0;
+    if(!file_worker_read(file_worker, &space, 1)) {
+        return false;
+    }
+
+    // // Load other data
+    if(!file_worker_read_hex(file_worker, &buff[1], buff[0] + 3)) {
+        return false;
+    }
+
+    // Set loaded data
+    dev->data.uid_len = buff[0];
+    memcpy(dev->data.uid, &buff[1], dev->data.uid_len);
+    memcpy(dev->data.atqa, &buff[dev->data.uid_len + 1], 2);
+    dev->data.sak = buff[dev->data.uid_len + 3];
+    return true;
+}
+
+bool nfc_device_load(NfcDevice* dev, const char* dev_name) {
+    furi_assert(dev);
+
+    return true;
+}
+
+bool nfc_file_select(NfcDevice* dev) {
+    furi_assert(dev);
+
+    FileWorker* file_worker = file_worker_alloc(false);
+    // Input events and views are managed by file_select
+    bool res = file_worker_file_select(
+        file_worker,
+        nfc_app_folder,
+        nfc_app_extension,
+        dev->file_name,
+        sizeof(dev->file_name),
+        NULL);
+    if(res) {
+        string_t dev_str;
+
+        // Get key file path
+        string_init_printf(dev_str, "%s/%s%s", nfc_app_folder, dev->file_name, nfc_app_extension);
+
+        res = nfc_device_load_data(file_worker, dev_str, dev);
+        if(res) {
+            nfc_device_set_name(dev, dev->file_name);
+        }
+        string_clear(dev_str);
+    }
+    file_worker_close(file_worker);
+    file_worker_free(file_worker);
+
+    return res;
+}

+ 55 - 0
applications/nfc/nfc_device.h

@@ -0,0 +1,55 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define NFC_DEV_NAME_MAX_LEN 22
+#define NFC_FILE_NAME_MAX_LEN 120
+
+typedef enum {
+    NfcDeviceNfca,
+    NfcDeviceNfcb,
+    NfcDeviceNfcf,
+    NfcDeviceNfcv,
+} NfcDeviceType;
+
+typedef enum {
+    NfcDeviceProtocolUnknown,
+    NfcDeviceProtocolEMV,
+    NfcDeviceProtocolMfUltralight,
+} NfcProtocol;
+
+typedef struct {
+    uint8_t uid_len;
+    uint8_t uid[10];
+    uint8_t atqa[2];
+    uint8_t sak;
+    NfcDeviceType device;
+    NfcProtocol protocol;
+} NfcDeviceData;
+
+typedef struct {
+    NfcDeviceData nfc_data;
+    char name[32];
+    uint8_t number[8];
+} NfcEmvData;
+
+typedef struct {
+    NfcDeviceData nfc_data;
+    uint8_t man_block[12];
+    uint8_t otp[4];
+} NfcMifareUlData;
+
+typedef struct {
+    NfcDeviceData data;
+    char dev_name[NFC_DEV_NAME_MAX_LEN];
+    char file_name[NFC_FILE_NAME_MAX_LEN];
+} NfcDevice;
+
+void nfc_device_set_name(NfcDevice* dev, const char* name);
+
+bool nfc_device_save(NfcDevice* dev, const char* dev_name);
+
+bool nfc_device_load(NfcDevice* dev, const char* dev_name);
+
+bool nfc_file_select(NfcDevice* dev);

+ 26 - 0
applications/nfc/nfc_i.h

@@ -3,6 +3,7 @@
 #include "nfc.h"
 #include "nfc.h"
 #include "nfc_types.h"
 #include "nfc_types.h"
 #include "nfc_worker.h"
 #include "nfc_worker.h"
+#include "nfc_device.h"
 
 
 #include <furi.h>
 #include <furi.h>
 
 
@@ -29,6 +30,14 @@
 #include "scenes/nfc_scene_card_menu.h"
 #include "scenes/nfc_scene_card_menu.h"
 #include "scenes/nfc_scene_emulate_uid.h"
 #include "scenes/nfc_scene_emulate_uid.h"
 #include "scenes/nfc_scene_not_implemented.h"
 #include "scenes/nfc_scene_not_implemented.h"
+#include "scenes/nfc_scene_save_name.h"
+#include "scenes/nfc_scene_save_success.h"
+#include "scenes/nfc_scene_file_select.h"
+#include "scenes/nfc_scene_saved_menu.h"
+#include "scenes/nfc_scene_set_type.h"
+#include "scenes/nfc_scene_set_sak.h"
+#include "scenes/nfc_scene_set_atqa.h"
+#include "scenes/nfc_scene_set_uid.h"
 
 
 // TODO delete debug scenes
 // TODO delete debug scenes
 #include "scenes/nfc_scene_debug_menu.h"
 #include "scenes/nfc_scene_debug_menu.h"
@@ -43,6 +52,7 @@ struct Nfc {
     NfcCommon nfc_common;
     NfcCommon nfc_common;
     Gui* gui;
     Gui* gui;
     NotificationApp* notifications;
     NotificationApp* notifications;
+    NfcDevice device;
 
 
     char text_store[NFC_TEXT_STORE_SIZE + 1];
     char text_store[NFC_TEXT_STORE_SIZE + 1];
 
 
@@ -66,6 +76,14 @@ struct Nfc {
     AppScene* scene_card_menu;
     AppScene* scene_card_menu;
     AppScene* scene_not_implemented;
     AppScene* scene_not_implemented;
     AppScene* scene_emulate_uid;
     AppScene* scene_emulate_uid;
+    AppScene* scene_save_name;
+    AppScene* scene_save_success;
+    AppScene* scene_file_select;
+    AppScene* scene_saved_menu;
+    AppScene* scene_set_type;
+    AppScene* scene_set_sak;
+    AppScene* scene_set_atqa;
+    AppScene* scene_set_uid;
 
 
     // TODO delete debug scenes
     // TODO delete debug scenes
     AppScene* scene_debug_menu;
     AppScene* scene_debug_menu;
@@ -99,6 +117,14 @@ typedef enum {
     NfcSceneDebugEmulate,
     NfcSceneDebugEmulate,
     NfcSceneDebugReadEmv,
     NfcSceneDebugReadEmv,
     NfcSceneDebugReadMifareUl,
     NfcSceneDebugReadMifareUl,
+    NfcSceneSaveName,
+    NfcSceneSaveSuccess,
+    NfcSceneFileSelect,
+    NfcSceneSavedMenu,
+    NfcSceneSetType,
+    NfcSceneSetSak,
+    NfcSceneSetAtqa,
+    NfcSceneSetUid,
 } NfcScene;
 } NfcScene;
 
 
 Nfc* nfc_alloc();
 Nfc* nfc_alloc();

+ 1 - 33
applications/nfc/nfc_worker.h

@@ -1,38 +1,6 @@
 #pragma once
 #pragma once
 
 
-typedef enum {
-    NfcDeviceNfca,
-    NfcDeviceNfcb,
-    NfcDeviceNfcf,
-    NfcDeviceNfcv,
-} NfcDeviceType;
-
-typedef enum {
-    NfcDeviceProtocolUnknown,
-    NfcDeviceProtocolEMV,
-    NfcDeviceProtocolMfUltralight,
-} NfcProtocol;
-
-typedef struct {
-    uint8_t uid_len;
-    uint8_t uid[10];
-    uint8_t atqa[2];
-    uint8_t sak;
-    NfcDeviceType device;
-    NfcProtocol protocol;
-} NfcDeviceData;
-
-typedef struct {
-    NfcDeviceData nfc_data;
-    char name[32];
-    uint8_t number[8];
-} NfcEmvData;
-
-typedef struct {
-    NfcDeviceData nfc_data;
-    uint8_t man_block[12];
-    uint8_t otp[4];
-} NfcMifareUlData;
+#include "nfc_device.h"
 
 
 typedef struct {
 typedef struct {
     union {
     union {

+ 3 - 3
applications/nfc/scenes/nfc_scene_card_menu.c

@@ -5,12 +5,12 @@
 #include <gui/modules/submenu.h>
 #include <gui/modules/submenu.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
 
 
-typedef enum {
+enum SubmenuIndex {
     SubmenuIndexRunApp,
     SubmenuIndexRunApp,
     SubmenuIndexChooseScript,
     SubmenuIndexChooseScript,
     SubmenuIndexEmulate,
     SubmenuIndexEmulate,
     SubmenuIndexSave,
     SubmenuIndexSave,
-} SubmenuIndex;
+};
 
 
 void nfc_scene_card_menu_submenu_callback(void* context, uint32_t index) {
 void nfc_scene_card_menu_submenu_callback(void* context, uint32_t index) {
     Nfc* nfc = (Nfc*)context;
     Nfc* nfc = (Nfc*)context;
@@ -61,7 +61,7 @@ const bool nfc_scene_card_menu_on_event(void* context, uint32_t event) {
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
         return true;
         return true;
     } else if(event == SubmenuIndexSave) {
     } else if(event == SubmenuIndexSave) {
-        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_save_name);
         view_dispatcher_send_navigation_event(
         view_dispatcher_send_navigation_event(
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
         return true;
         return true;

+ 2 - 2
applications/nfc/scenes/nfc_scene_debug_menu.c

@@ -5,12 +5,12 @@
 #include <gui/modules/submenu.h>
 #include <gui/modules/submenu.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
 
 
-typedef enum {
+enum SubmenuIndex {
     SubmenuIndexDetect,
     SubmenuIndexDetect,
     SubmenuIndexEmulate,
     SubmenuIndexEmulate,
     SubmenuIndexReadEmv,
     SubmenuIndexReadEmv,
     SubmenuIndexReadMifareUl,
     SubmenuIndexReadMifareUl,
-} SubmenuIndex;
+};
 
 
 void nfc_scene_debug_menu_submenu_callback(void* context, uint32_t index) {
 void nfc_scene_debug_menu_submenu_callback(void* context, uint32_t index) {
     Nfc* nfc = (Nfc*)context;
     Nfc* nfc = (Nfc*)context;

+ 7 - 4
applications/nfc/scenes/nfc_scene_emulate_uid.c

@@ -9,8 +9,11 @@ const void nfc_scene_emulate_uid_on_enter(void* context) {
 
 
     // Setup view
     // Setup view
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
-    NfcDeviceData* data = &nfc->nfc_common.worker_result.nfc_detect_data;
-    if(data->uid_len == 4) {
+    NfcDeviceData* data = &nfc->device.data;
+
+    if(strcmp(nfc->device.dev_name, "")) {
+        nfc_set_text_store(nfc, "%s", nfc->device.dev_name);
+    } else if(data->uid_len == 4) {
         nfc_set_text_store(
         nfc_set_text_store(
             nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]);
             nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]);
     } else if(data->uid_len == 7) {
     } else if(data->uid_len == 7) {
@@ -31,8 +34,8 @@ const void nfc_scene_emulate_uid_on_enter(void* context) {
     popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
     popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
 
 
     // Setup and start worker
     // Setup and start worker
-    nfc_worker_set_emulation_params(
-        nfc->nfc_common.worker, &nfc->nfc_common.worker_result.nfc_detect_data);
+
+    nfc_worker_set_emulation_params(nfc->nfc_common.worker, data);
     nfc_worker_start(
     nfc_worker_start(
         nfc->nfc_common.worker, NfcWorkerStateEmulate, &nfc->nfc_common.worker_result, NULL, nfc);
         nfc->nfc_common.worker, NfcWorkerStateEmulate, &nfc->nfc_common.worker_result, NULL, nfc);
     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);

+ 39 - 0
applications/nfc/scenes/nfc_scene_file_select.c

@@ -0,0 +1,39 @@
+#include <nfc/scenes/nfc_scene_file_select.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+
+const void nfc_scene_file_select_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+    // Process file_select return
+    if(nfc_file_select(&nfc->device)) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_saved_menu);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+    } else {
+        view_dispatcher_send_back_search_scene_event(
+            nfc->nfc_common.view_dispatcher, NfcSceneStart);
+    }
+}
+
+const bool nfc_scene_file_select_on_event(void* context, uint32_t event) {
+    return false;
+}
+
+const void nfc_scene_file_select_on_exit(void* context) {
+}
+
+AppScene* nfc_scene_file_select_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneFileSelect;
+    scene->on_enter = nfc_scene_file_select_on_enter;
+    scene->on_event = nfc_scene_file_select_on_event;
+    scene->on_exit = nfc_scene_file_select_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_file_select_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_file_select.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_file_select_alloc();
+
+void nfc_scene_file_select_free(AppScene* scene);

+ 1 - 0
applications/nfc/scenes/nfc_scene_read_card.c

@@ -34,6 +34,7 @@ const bool nfc_scene_read_card_on_event(void* context, uint32_t event) {
     Nfc* nfc = (Nfc*)context;
     Nfc* nfc = (Nfc*)context;
 
 
     if(event == NfcEventDetect) {
     if(event == NfcEventDetect) {
+        nfc->device.data = nfc->nfc_common.worker_result.nfc_detect_data;
         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_read_card_success);
         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_read_card_success);
         view_dispatcher_send_navigation_event(
         view_dispatcher_send_navigation_event(
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);

+ 3 - 0
applications/nfc/scenes/nfc_scene_read_card_success.c

@@ -16,6 +16,9 @@ void nfc_scene_read_card_success_dialog_callback(DialogExResult result, void* co
 const void nfc_scene_read_card_success_on_enter(void* context) {
 const void nfc_scene_read_card_success_on_enter(void* context) {
     Nfc* nfc = (Nfc*)context;
     Nfc* nfc = (Nfc*)context;
 
 
+    // Clear device name
+    nfc_device_set_name(&nfc->device, "");
+
     // Send notification
     // Send notification
     notification_message(nfc->notifications, &sequence_success);
     notification_message(nfc->notifications, &sequence_success);
 
 

+ 72 - 0
applications/nfc/scenes/nfc_scene_save_name.c

@@ -0,0 +1,72 @@
+#include <nfc/scenes/nfc_scene_save_name.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+#include "../views/nfc_detect.h"
+
+#include <gui/view_dispatcher.h>
+
+#define SCENE_SAVE_NAME_CUSTOM_EVENT (0UL)
+
+void nfc_scene_save_name_text_input_callback(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(
+        nfc->nfc_common.view_dispatcher, SCENE_SAVE_NAME_CUSTOM_EVENT);
+}
+
+const void nfc_scene_save_name_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Setup view
+    TextInput* text_input = nfc->text_input;
+    nfc_set_text_store(nfc, "");
+    text_input_set_header_text(text_input, "Name the card");
+    text_input_set_result_callback(
+        text_input,
+        nfc_scene_save_name_text_input_callback,
+        nfc,
+        nfc->text_store,
+        sizeof(nfc->text_store));
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewTextInput);
+}
+
+const bool nfc_scene_save_name_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SCENE_SAVE_NAME_CUSTOM_EVENT) {
+        memcpy(&nfc->device.dev_name, nfc->text_store, strlen(nfc->text_store));
+        if(nfc_device_save(&nfc->device, "test")) {
+            view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_save_success);
+            view_dispatcher_send_navigation_event(
+                nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        } else {
+            view_dispatcher_send_back_search_scene_event(
+                nfc->nfc_common.view_dispatcher, NfcSceneStart);
+        }
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_save_name_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Clear view
+    text_input_set_header_text(nfc->text_input, NULL);
+}
+
+AppScene* nfc_scene_save_name_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSaveName;
+    scene->on_enter = nfc_scene_save_name_on_enter;
+    scene->on_event = nfc_scene_save_name_on_event;
+    scene->on_exit = nfc_scene_save_name_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_save_name_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_save_name.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_save_name_alloc();
+
+void nfc_scene_save_name_free(AppScene* scene);

+ 66 - 0
applications/nfc/scenes/nfc_scene_save_success.c

@@ -0,0 +1,66 @@
+#include <nfc/scenes/nfc_scene_save_success.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+
+#define SCENE_SAVE_SUCCESS_CUSTOM_EVENT (0UL)
+
+void nfc_scene_save_success_popup_callback(void* context) {
+    Nfc* nfc = (Nfc*)context;
+    view_dispatcher_send_custom_event(
+        nfc->nfc_common.view_dispatcher, SCENE_SAVE_SUCCESS_CUSTOM_EVENT);
+}
+
+const void nfc_scene_save_success_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Setup view
+    Popup* popup = nfc->popup;
+    popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
+    popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
+    popup_set_timeout(popup, 1500);
+    popup_set_context(popup, nfc);
+    popup_set_callback(popup, nfc_scene_save_success_popup_callback);
+    popup_enable_timeout(popup);
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup);
+}
+
+const bool nfc_scene_save_success_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SCENE_SAVE_SUCCESS_CUSTOM_EVENT) {
+        view_dispatcher_send_back_search_scene_event(
+            nfc->nfc_common.view_dispatcher, NfcSceneStart);
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_save_success_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Clear view
+    Popup* popup = nfc->popup;
+    popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
+    popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
+    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_callback(popup, NULL);
+    popup_set_context(popup, NULL);
+    popup_set_timeout(popup, 0);
+    popup_disable_timeout(popup);
+}
+
+AppScene* nfc_scene_save_success_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSaveSuccess;
+    scene->on_enter = nfc_scene_save_success_on_enter;
+    scene->on_event = nfc_scene_save_success_on_event;
+    scene->on_exit = nfc_scene_save_success_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_save_success_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_save_success.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_save_success_alloc();
+
+void nfc_scene_save_success_free(AppScene* scene);

+ 83 - 0
applications/nfc/scenes/nfc_scene_saved_menu.c

@@ -0,0 +1,83 @@
+#include "nfc_scene_saved_menu.h"
+#include "../nfc_i.h"
+
+#include <furi.h>
+#include <gui/modules/submenu.h>
+#include <gui/view_dispatcher.h>
+
+enum SubmenuIndex {
+    SubmenuIndexEmulate,
+    SubmenuIndexEdit,
+    SubmenuIndexDelete,
+    SubmenuIndexInfo,
+};
+
+void nfc_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+}
+
+const void nfc_scene_saved_menu_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+    Submenu* submenu = nfc->submenu;
+
+    submenu_add_item(
+        submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
+    submenu_add_item(
+        submenu, "Edit UID and name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc);
+    submenu_add_item(
+        submenu, "Delete", SubmenuIndexDelete, nfc_scene_saved_menu_submenu_callback, nfc);
+    submenu_add_item(
+        submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
+
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+}
+
+const bool nfc_scene_saved_menu_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SubmenuIndexEmulate) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_emulate_uid);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    } else if(event == SubmenuIndexEdit) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    } else if(event == SubmenuIndexDelete) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    } else if(event == SubmenuIndexInfo) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    }
+
+    return false;
+}
+
+const void nfc_scene_saved_menu_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    submenu_clean(nfc->submenu);
+}
+
+AppScene* nfc_scene_saved_menu_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSavedMenu;
+    scene->on_enter = nfc_scene_saved_menu_on_enter;
+    scene->on_event = nfc_scene_saved_menu_on_event;
+    scene->on_exit = nfc_scene_saved_menu_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_saved_menu_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_saved_menu.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_saved_menu_alloc();
+
+void nfc_scene_saved_menu_free(AppScene* scene);

+ 61 - 0
applications/nfc/scenes/nfc_scene_set_atqa.c

@@ -0,0 +1,61 @@
+#include <nfc/scenes/nfc_scene_set_atqa.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+
+#include <gui/view_dispatcher.h>
+
+#define SCENE_SET_ATQA_CUSTOM_EVENT (0UL)
+
+void nfc_scene_set_atqa_byte_input_callback(void* context, uint8_t* bytes, uint8_t bytes_count) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(
+        nfc->nfc_common.view_dispatcher, SCENE_SET_ATQA_CUSTOM_EVENT);
+}
+
+const void nfc_scene_set_atqa_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Setup view
+    ByteInput* byte_input = nfc->byte_input;
+    byte_input_set_header_text(byte_input, "Enter atqa in hex");
+    byte_input_set_result_callback(
+        byte_input, nfc_scene_set_atqa_byte_input_callback, NULL, nfc, nfc->device.data.atqa, 2);
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+}
+
+const bool nfc_scene_set_atqa_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SCENE_SET_ATQA_CUSTOM_EVENT) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_set_uid);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_set_atqa_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Clear view
+    byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);
+    byte_input_set_header_text(nfc->byte_input, "");
+}
+
+AppScene* nfc_scene_set_atqa_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSetAtqa;
+    scene->on_enter = nfc_scene_set_atqa_on_enter;
+    scene->on_event = nfc_scene_set_atqa_on_event;
+    scene->on_exit = nfc_scene_set_atqa_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_set_atqa_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_set_atqa.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_set_atqa_alloc();
+
+void nfc_scene_set_atqa_free(AppScene* scene);

+ 60 - 0
applications/nfc/scenes/nfc_scene_set_sak.c

@@ -0,0 +1,60 @@
+#include <nfc/scenes/nfc_scene_set_sak.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+
+#include <gui/view_dispatcher.h>
+
+#define SCENE_SET_SAK_CUSTOM_EVENT (0UL)
+
+void nfc_scene_set_sak_byte_input_callback(void* context, uint8_t* bytes, uint8_t bytes_count) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, SCENE_SET_SAK_CUSTOM_EVENT);
+}
+
+const void nfc_scene_set_sak_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Setup view
+    ByteInput* byte_input = nfc->byte_input;
+    byte_input_set_header_text(byte_input, "Enter SAK in hex");
+    byte_input_set_result_callback(
+        byte_input, nfc_scene_set_sak_byte_input_callback, NULL, nfc, &nfc->device.data.sak, 1);
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+}
+
+const bool nfc_scene_set_sak_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SCENE_SET_SAK_CUSTOM_EVENT) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_set_atqa);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_set_sak_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Clear view
+    byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);
+    byte_input_set_header_text(nfc->byte_input, "");
+}
+
+AppScene* nfc_scene_set_sak_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSetSak;
+    scene->on_enter = nfc_scene_set_sak_on_enter;
+    scene->on_event = nfc_scene_set_sak_on_event;
+    scene->on_exit = nfc_scene_set_sak_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_set_sak_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_set_sak.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_set_sak_alloc();
+
+void nfc_scene_set_sak_free(AppScene* scene);

+ 67 - 0
applications/nfc/scenes/nfc_scene_set_type.c

@@ -0,0 +1,67 @@
+#include "nfc_scene_set_type.h"
+#include "../nfc_i.h"
+
+#include <furi.h>
+#include <gui/modules/submenu.h>
+#include <gui/view_dispatcher.h>
+
+enum SubmenuIndex {
+    SubmenuIndexNFCA4,
+    SubmenuIndexNFCA7,
+};
+
+void nfc_scene_set_type_submenu_callback(void* context, uint32_t index) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index);
+}
+
+const void nfc_scene_set_type_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+    Submenu* submenu = nfc->submenu;
+
+    submenu_add_item(
+        submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc);
+    submenu_add_item(
+        submenu, "NFC-A 4-bytes UID", SubmenuIndexNFCA4, nfc_scene_set_type_submenu_callback, nfc);
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
+}
+
+const bool nfc_scene_set_type_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SubmenuIndexNFCA7) {
+        nfc->device.data.uid_len = 7;
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_set_sak);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    } else if(event == SubmenuIndexNFCA4) {
+        nfc->device.data.uid_len = 4;
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_set_sak);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_set_type_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    submenu_clean(nfc->submenu);
+}
+
+AppScene* nfc_scene_set_type_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSetType;
+    scene->on_enter = nfc_scene_set_type_on_enter;
+    scene->on_event = nfc_scene_set_type_on_event;
+    scene->on_exit = nfc_scene_set_type_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_set_type_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_set_type.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_set_type_alloc();
+
+void nfc_scene_set_type_free(AppScene* scene);

+ 65 - 0
applications/nfc/scenes/nfc_scene_set_uid.c

@@ -0,0 +1,65 @@
+#include <nfc/scenes/nfc_scene_set_uid.h>
+
+#include <furi.h>
+
+#include "../nfc_i.h"
+
+#include <gui/view_dispatcher.h>
+
+#define SCENE_SET_UID_CUSTOM_EVENT (0UL)
+
+void nfc_scene_set_uid_byte_input_callback(void* context, uint8_t* bytes, uint8_t bytes_count) {
+    Nfc* nfc = (Nfc*)context;
+
+    view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, SCENE_SET_UID_CUSTOM_EVENT);
+}
+
+const void nfc_scene_set_uid_on_enter(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Setup view
+    ByteInput* byte_input = nfc->byte_input;
+    byte_input_set_header_text(byte_input, "Enter uid in hex");
+    byte_input_set_result_callback(
+        byte_input,
+        nfc_scene_set_uid_byte_input_callback,
+        NULL,
+        nfc,
+        nfc->device.data.uid,
+        nfc->device.data.uid_len);
+    view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput);
+}
+
+const bool nfc_scene_set_uid_on_event(void* context, uint32_t event) {
+    Nfc* nfc = (Nfc*)context;
+
+    if(event == SCENE_SET_UID_CUSTOM_EVENT) {
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_save_name);
+        view_dispatcher_send_navigation_event(
+            nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
+        return true;
+    }
+    return false;
+}
+
+const void nfc_scene_set_uid_on_exit(void* context) {
+    Nfc* nfc = (Nfc*)context;
+
+    // Clear view
+    byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0);
+    byte_input_set_header_text(nfc->byte_input, "");
+}
+
+AppScene* nfc_scene_set_uid_alloc() {
+    AppScene* scene = furi_alloc(sizeof(AppScene));
+    scene->id = NfcSceneSetUid;
+    scene->on_enter = nfc_scene_set_uid_on_enter;
+    scene->on_event = nfc_scene_set_uid_on_event;
+    scene->on_exit = nfc_scene_set_uid_on_exit;
+
+    return scene;
+}
+
+void nfc_scene_set_uid_free(AppScene* scene) {
+    free(scene);
+}

+ 7 - 0
applications/nfc/scenes/nfc_scene_set_uid.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "app_scene.h"
+
+AppScene* nfc_scene_set_uid_alloc();
+
+void nfc_scene_set_uid_free(AppScene* scene);

+ 5 - 5
applications/nfc/scenes/nfc_scene_start.c

@@ -5,13 +5,13 @@
 #include <gui/modules/submenu.h>
 #include <gui/modules/submenu.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
 
 
-typedef enum {
+enum SubmenuIndex {
     SubmenuIndexRead,
     SubmenuIndexRead,
     SubmenuIndexRunScript,
     SubmenuIndexRunScript,
     SubmenuIndexSaved,
     SubmenuIndexSaved,
     SubmenuIndexAddManualy,
     SubmenuIndexAddManualy,
     SubmenuIndexDebug,
     SubmenuIndexDebug,
-} SubmenuIndex;
+};
 
 
 void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
 void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
     Nfc* nfc = (Nfc*)context;
     Nfc* nfc = (Nfc*)context;
@@ -34,7 +34,7 @@ const void nfc_scene_start_on_enter(void* context) {
     submenu_add_item(
     submenu_add_item(
         submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
         submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
     submenu_add_item(
     submenu_add_item(
-        submenu, "Add manualy", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
+        submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
     submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
     submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
 
 
     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu);
@@ -54,12 +54,12 @@ const bool nfc_scene_start_on_event(void* context, uint32_t event) {
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
         return true;
         return true;
     } else if(event == SubmenuIndexSaved) {
     } else if(event == SubmenuIndexSaved) {
-        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_file_select);
         view_dispatcher_send_navigation_event(
         view_dispatcher_send_navigation_event(
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
         return true;
         return true;
     } else if(event == SubmenuIndexAddManualy) {
     } else if(event == SubmenuIndexAddManualy) {
-        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented);
+        view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_set_type);
         view_dispatcher_send_navigation_event(
         view_dispatcher_send_navigation_event(
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext);
         return true;
         return true;