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

Implement block selection scene

TollyH 2 лет назад
Родитель
Сommit
0abe1ff4d9

+ 12 - 7
mfc_editor_app.c

@@ -81,15 +81,22 @@ void mfc_editor_app_free(MfcEditorApp* instance) {
     free(instance);
     free(instance);
 }
 }
 
 
-bool mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path, bool show_dialog) {
+MfcEditorPromptResponse mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path) {
     furi_assert(instance);
     furi_assert(instance);
     furi_assert(file_path);
     furi_assert(file_path);
-    bool result = false;
 
 
-    result = nfc_device_load(instance->nfc_device, furi_string_get_cstr(file_path));
+    MfcEditorPromptResponse result = MfcEditorPromptResponseSuccess;
 
 
-    if(!result && show_dialog) {
+    if(!nfc_device_load(instance->nfc_device, furi_string_get_cstr(file_path))) {
+        result = MfcEditorPromptResponseFailure;
         dialog_message_show_storage_error(instance->dialogs, "Cannot load\nkey file");
         dialog_message_show_storage_error(instance->dialogs, "Cannot load\nkey file");
+    } else {
+        if(nfc_device_get_protocol(instance->nfc_device) == NfcProtocolMfClassic) {
+            instance->mf_classic_data =
+                nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
+        } else {
+            result = MfcEditorPromptResponseNotMfClassic;
+        }
     }
     }
 
 
     return result;
     return result;
@@ -166,9 +173,7 @@ MfcEditorPromptResponse mfc_editor_prompt_load_file(MfcEditorApp* instance) {
 
 
         // Don't load the file if user was prompted for shadow file use but went back
         // Don't load the file if user was prompted for shadow file use but went back
         if(result == MfcEditorPromptResponseSuccess) {
         if(result == MfcEditorPromptResponseSuccess) {
-            if(!mfc_editor_load_file(instance, instance->file_path, true)) {
-                result = MfcEditorPromptResponseFailure;
-            }
+            result = mfc_editor_load_file(instance, instance->file_path);
         }
         }
     }
     }
 
 

+ 7 - 1
mfc_editor_app_i.h

@@ -46,8 +46,12 @@ struct MfcEditorApp {
     Popup* popup;
     Popup* popup;
 
 
     NfcDevice* nfc_device;
     NfcDevice* nfc_device;
+    const MfClassicData* mf_classic_data;
 
 
     FuriString* file_path;
     FuriString* file_path;
+
+    uint8_t current_sector;
+    uint8_t current_block;
 };
 };
 
 
 typedef enum {
 typedef enum {
@@ -60,6 +64,8 @@ typedef enum {
     MfcEditorPromptResponseSuccess,
     MfcEditorPromptResponseSuccess,
     MfcEditorPromptResponseFailure,
     MfcEditorPromptResponseFailure,
 
 
+    MfcEditorPromptResponseNotMfClassic,
+
     // Backed out of a prompt
     // Backed out of a prompt
     MfcEditorPromptResponseExitedFile,
     MfcEditorPromptResponseExitedFile,
     MfcEditorPromptResponseExitedShadow,
     MfcEditorPromptResponseExitedShadow,
@@ -67,4 +73,4 @@ typedef enum {
 
 
 MfcEditorPromptResponse mfc_editor_prompt_load_file(MfcEditorApp* instance);
 MfcEditorPromptResponse mfc_editor_prompt_load_file(MfcEditorApp* instance);
 
 
-bool mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path, bool show_dialog);
+MfcEditorPromptResponse mfc_editor_load_file(MfcEditorApp* instance, FuriString* file_path);

+ 108 - 0
scenes/mfc_editor_scene_block_select.c

@@ -0,0 +1,108 @@
+#include "../mfc_editor_app_i.h"
+
+enum SubmenuIndex {
+    // Reserve first indices for opening normal block
+    SubmenuIndexReserved = MF_CLASSIC_TOTAL_BLOCKS_MAX,
+
+    // Special options - Sector 0 only
+    SubmenuIndexUID,
+    SubmenuIndexManufacturerBytes,
+
+    // Special options - All sectors
+    SubmenuIndexKeyA,
+    SubmenuIndexKeyB,
+    SubmenuIndexAccessBits,
+    SubmenuIndexUserByte,
+};
+
+void mfc_editor_scene_block_select_submenu_callback(void* context, uint32_t index) {
+    MfcEditorApp* instance = context;
+    view_dispatcher_send_custom_event(instance->view_dispatcher, index);
+}
+
+void mfc_editor_scene_block_select_on_enter(void* context) {
+    MfcEditorApp* instance = context;
+
+    Submenu* submenu = instance->submenu;
+
+    char header[sizeof("Sector ") + 2];
+    snprintf(header, sizeof(header), "Sector %hhu", instance->current_sector);
+    submenu_set_header(submenu, header);
+
+    uint8_t first_block = mf_classic_get_first_block_num_of_sector(instance->current_sector);
+    uint8_t block_num = mf_classic_get_blocks_num_in_sector(instance->current_sector);
+    for(uint8_t i = 0; i < block_num; i++) {
+        uint8_t block_index = first_block + i;
+        char label[sizeof("Block ") + 3];
+        snprintf(label, sizeof(label), "Block %hhu", block_index);
+        submenu_add_item(
+            submenu, label, block_index, mfc_editor_scene_block_select_submenu_callback, instance);
+    }
+
+    if(instance->current_sector == 0) {
+        submenu_add_item(
+            submenu,
+            "UID",
+            SubmenuIndexUID,
+            mfc_editor_scene_block_select_submenu_callback,
+            instance);
+        submenu_add_item(
+            submenu,
+            "Manufacturer Bytes",
+            SubmenuIndexManufacturerBytes,
+            mfc_editor_scene_block_select_submenu_callback,
+            instance);
+    }
+
+    submenu_add_item(
+        submenu,
+        "Key A",
+        SubmenuIndexKeyA,
+        mfc_editor_scene_block_select_submenu_callback,
+        instance);
+    submenu_add_item(
+        submenu,
+        "Key B",
+        SubmenuIndexKeyB,
+        mfc_editor_scene_block_select_submenu_callback,
+        instance);
+    submenu_add_item(
+        submenu,
+        "Access Bits",
+        SubmenuIndexAccessBits,
+        mfc_editor_scene_block_select_submenu_callback,
+        instance);
+    submenu_add_item(
+        submenu,
+        "User Byte",
+        SubmenuIndexUserByte,
+        mfc_editor_scene_block_select_submenu_callback,
+        instance);
+
+    submenu_set_selected_item(
+        submenu,
+        scene_manager_get_scene_state(instance->scene_manager, MfcEditorSceneBlockSelect));
+    view_dispatcher_switch_to_view(instance->view_dispatcher, MfcEditorAppViewSubmenu);
+}
+
+bool mfc_editor_scene_block_select_on_event(void* context, SceneManagerEvent event) {
+    MfcEditorApp* instance = context;
+    bool consumed = false;
+
+    UNUSED(instance);
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        scene_manager_set_scene_state(
+            instance->scene_manager, MfcEditorSceneBlockSelect, event.event);
+        FURI_LOG_I(TAG, "Block select event %lu", event.event);
+        consumed = true;
+    }
+
+    return consumed;
+}
+
+void mfc_editor_scene_block_select_on_exit(void* context) {
+    MfcEditorApp* instance = context;
+
+    submenu_reset(instance->submenu);
+}

+ 1 - 0
scenes/mfc_editor_scene_config.h

@@ -2,3 +2,4 @@ ADD_SCENE(mfc_editor, start, Start)
 ADD_SCENE(mfc_editor, file_select, FileSelect)
 ADD_SCENE(mfc_editor, file_select, FileSelect)
 ADD_SCENE(mfc_editor, invalid_file, InvalidFile)
 ADD_SCENE(mfc_editor, invalid_file, InvalidFile)
 ADD_SCENE(mfc_editor, sector_select, SectorSelect)
 ADD_SCENE(mfc_editor, sector_select, SectorSelect)
+ADD_SCENE(mfc_editor, block_select, BlockSelect)

+ 4 - 6
scenes/mfc_editor_scene_file_select.c

@@ -12,12 +12,10 @@ void mfc_editor_scene_file_select_on_enter(void* context) {
     }
     }
 
 
     if(prompt_response == MfcEditorPromptResponseSuccess) {
     if(prompt_response == MfcEditorPromptResponseSuccess) {
-        if(nfc_device_get_protocol(instance->nfc_device) == NfcProtocolMfClassic) {
-            scene_manager_set_scene_state(instance->scene_manager, MfcEditorSceneSectorSelect, 0);
-            scene_manager_next_scene(instance->scene_manager, MfcEditorSceneSectorSelect);
-        } else {
-            scene_manager_next_scene(instance->scene_manager, MfcEditorSceneInvalidFile);
-        }
+        scene_manager_set_scene_state(instance->scene_manager, MfcEditorSceneSectorSelect, 0);
+        scene_manager_next_scene(instance->scene_manager, MfcEditorSceneSectorSelect);
+    } else if(prompt_response == MfcEditorPromptResponseNotMfClassic) {
+        scene_manager_next_scene(instance->scene_manager, MfcEditorSceneInvalidFile);
     } else {
     } else {
         scene_manager_search_and_switch_to_previous_scene(
         scene_manager_search_and_switch_to_previous_scene(
             instance->scene_manager, MfcEditorSceneStart);
             instance->scene_manager, MfcEditorSceneStart);

+ 10 - 9
scenes/mfc_editor_scene_sector_select.c

@@ -8,15 +8,13 @@ void mfc_editor_scene_sector_select_submenu_callback(void* context, uint32_t ind
 void mfc_editor_scene_sector_select_on_enter(void* context) {
 void mfc_editor_scene_sector_select_on_enter(void* context) {
     MfcEditorApp* instance = context;
     MfcEditorApp* instance = context;
 
 
-    const MfClassicData* mf_classic_data =
-        nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic);
-
     Submenu* submenu = instance->submenu;
     Submenu* submenu = instance->submenu;
     submenu_set_header(submenu, "Select sector");
     submenu_set_header(submenu, "Select sector");
 
 
-    for(int i = 0; i < mf_classic_get_total_sectors_num(mf_classic_data->type); i++) {
-        char label[sizeof("Sector ") + 20];
-        snprintf(label, sizeof(label), "Sector %i", i);
+    uint8_t sectors_num = mf_classic_get_total_sectors_num(instance->mf_classic_data->type);
+    for(uint8_t i = 0; i < sectors_num; i++) {
+        char label[sizeof("Sector ") + 2];
+        snprintf(label, sizeof(label), "Sector %hhu", i);
         submenu_add_item(
         submenu_add_item(
             submenu, label, i, mfc_editor_scene_sector_select_submenu_callback, instance);
             submenu, label, i, mfc_editor_scene_sector_select_submenu_callback, instance);
     }
     }
@@ -32,9 +30,12 @@ bool mfc_editor_scene_sector_select_on_event(void* context, SceneManagerEvent ev
     bool consumed = false;
     bool consumed = false;
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
-        FURI_LOG_I(TAG, "Opened sector %lu", event.event);
-        scene_manager_search_and_switch_to_previous_scene(
-            instance->scene_manager, MfcEditorSceneStart);
+        scene_manager_set_scene_state(
+            instance->scene_manager, MfcEditorSceneSectorSelect, event.event);
+        instance->current_sector = event.event;
+        scene_manager_set_scene_state(instance->scene_manager, MfcEditorSceneBlockSelect, 0);
+        scene_manager_next_scene(instance->scene_manager, MfcEditorSceneBlockSelect);
+        consumed = true;
     }
     }
 
 
     return consumed;
     return consumed;