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

Display Mifare Classic data in NFC app (#2389)

* Add data display for Mifare Classic cards.
* Clean up log statements and data display.

Co-authored-by: あく <alleteam@gmail.com>
Liam Hays 2 лет назад
Родитель
Сommit
663eb6cd6d

+ 1 - 0
applications/main/nfc/scenes/nfc_scene_config.h

@@ -29,6 +29,7 @@ ADD_SCENE(nfc, mf_desfire_menu, MfDesfireMenu)
 ADD_SCENE(nfc, mf_desfire_data, MfDesfireData)
 ADD_SCENE(nfc, mf_desfire_data, MfDesfireData)
 ADD_SCENE(nfc, mf_desfire_app, MfDesfireApp)
 ADD_SCENE(nfc, mf_desfire_app, MfDesfireApp)
 ADD_SCENE(nfc, mf_classic_read_success, MfClassicReadSuccess)
 ADD_SCENE(nfc, mf_classic_read_success, MfClassicReadSuccess)
+ADD_SCENE(nfc, mf_classic_data, MfClassicData)
 ADD_SCENE(nfc, mf_classic_menu, MfClassicMenu)
 ADD_SCENE(nfc, mf_classic_menu, MfClassicMenu)
 ADD_SCENE(nfc, mf_classic_emulate, MfClassicEmulate)
 ADD_SCENE(nfc, mf_classic_emulate, MfClassicEmulate)
 ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys)
 ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys)

+ 106 - 0
applications/main/nfc/scenes/nfc_scene_mf_classic_data.c

@@ -0,0 +1,106 @@
+#include "../nfc_i.h"
+
+void nfc_scene_mf_classic_data_on_enter(void* context) {
+    Nfc* nfc = context;
+    MfClassicType type = nfc->dev->dev_data.mf_classic_data.type;
+    MfClassicData* data = &nfc->dev->dev_data.mf_classic_data;
+    TextBox* text_box = nfc->text_box;
+
+    text_box_set_font(text_box, TextBoxFontHex);
+
+    int card_blocks = 0;
+    if(type == MfClassicType1k) {
+        card_blocks = MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4;
+    } else if(type == MfClassicType4k) {
+        // 16 sectors of 4 blocks each plus 8 sectors of 16 blocks each
+        card_blocks = MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4 + 8 * 16;
+    } else if(type == MfClassicTypeMini) {
+        card_blocks = MF_MINI_TOTAL_SECTORS_NUM * 4;
+    }
+
+    int bytes_written = 0;
+    for(int block_num = 0; block_num < card_blocks; block_num++) {
+        bool is_sec_trailer = mf_classic_is_sector_trailer(block_num);
+        if(is_sec_trailer) {
+            uint8_t sector_num = mf_classic_get_sector_by_block(block_num);
+            MfClassicSectorTrailer* sec_tr =
+                mf_classic_get_sector_trailer_by_sector(data, sector_num);
+            // Key A
+            for(size_t i = 0; i < sizeof(sec_tr->key_a); i += 2) {
+                if((bytes_written % 8 == 0) && (bytes_written != 0)) {
+                    furi_string_push_back(nfc->text_box_store, '\n');
+                }
+                if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) {
+                    furi_string_cat_printf(
+                        nfc->text_box_store, "%02X%02X ", sec_tr->key_a[i], sec_tr->key_a[i + 1]);
+                } else {
+                    furi_string_cat_printf(nfc->text_box_store, "???? ");
+                }
+                bytes_written += 2;
+            }
+            // Access bytes
+            for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i += 2) {
+                if((bytes_written % 8 == 0) && (bytes_written != 0)) {
+                    furi_string_push_back(nfc->text_box_store, '\n');
+                }
+                if(mf_classic_is_block_read(data, block_num)) {
+                    furi_string_cat_printf(
+                        nfc->text_box_store,
+                        "%02X%02X ",
+                        sec_tr->access_bits[i],
+                        sec_tr->access_bits[i + 1]);
+                } else {
+                    furi_string_cat_printf(nfc->text_box_store, "???? ");
+                }
+                bytes_written += 2;
+            }
+            // Key B
+            for(size_t i = 0; i < sizeof(sec_tr->key_b); i += 2) {
+                if((bytes_written % 8 == 0) && (bytes_written != 0)) {
+                    furi_string_push_back(nfc->text_box_store, '\n');
+                }
+                if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) {
+                    furi_string_cat_printf(
+                        nfc->text_box_store, "%02X%02X ", sec_tr->key_b[i], sec_tr->key_b[i + 1]);
+                } else {
+                    furi_string_cat_printf(nfc->text_box_store, "???? ");
+                }
+                bytes_written += 2;
+            }
+        } else {
+            // Write data block
+            for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i += 2) {
+                if((bytes_written % 8 == 0) && (bytes_written != 0)) {
+                    furi_string_push_back(nfc->text_box_store, '\n');
+                }
+                if(mf_classic_is_block_read(data, block_num)) {
+                    furi_string_cat_printf(
+                        nfc->text_box_store,
+                        "%02X%02X ",
+                        data->block[block_num].value[i],
+                        data->block[block_num].value[i + 1]);
+                } else {
+                    furi_string_cat_printf(nfc->text_box_store, "???? ");
+                }
+                bytes_written += 2;
+            }
+        }
+    }
+    text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store));
+
+    view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
+}
+
+bool nfc_scene_mf_classic_data_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    return false;
+}
+
+void nfc_scene_mf_classic_data_on_exit(void* context) {
+    Nfc* nfc = context;
+
+    // Clean view
+    text_box_reset(nfc->text_box);
+    furi_string_reset(nfc->text_box_store);
+}

+ 5 - 1
applications/main/nfc/scenes/nfc_scene_nfc_data_info.c

@@ -14,7 +14,8 @@ void nfc_scene_nfc_data_info_on_enter(void* context) {
     NfcDeviceData* dev_data = &nfc->dev->dev_data;
     NfcDeviceData* dev_data = &nfc->dev->dev_data;
     NfcProtocol protocol = dev_data->protocol;
     NfcProtocol protocol = dev_data->protocol;
     uint8_t text_scroll_height = 0;
     uint8_t text_scroll_height = 0;
-    if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl)) {
+    if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl) ||
+       (protocol == NfcDeviceProtocolMifareClassic)) {
         widget_add_button_element(
         widget_add_button_element(
             widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc);
             widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc);
         text_scroll_height = 52;
         text_scroll_height = 52;
@@ -136,6 +137,9 @@ bool nfc_scene_nfc_data_info_on_event(void* context, SceneManagerEvent event) {
             } else if(protocol == NfcDeviceProtocolMifareUl) {
             } else if(protocol == NfcDeviceProtocolMifareUl) {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightData);
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightData);
                 consumed = true;
                 consumed = true;
+            } else if(protocol == NfcDeviceProtocolMifareClassic) {
+                scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicData);
+                consumed = true;
             }
             }
         }
         }
     }
     }

+ 2 - 0
applications/main/nfc/scenes/nfc_scene_saved_menu.c

@@ -150,6 +150,8 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
                 application_info_present = nfc_supported_card_verify_and_parse(dev_data);
                 application_info_present = nfc_supported_card_verify_and_parse(dev_data);
             }
             }
 
 
+            FURI_LOG_I("nfc", "application_info_present: %d", application_info_present);
+
             if(application_info_present) {
             if(application_info_present) {
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
                 scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
             } else {
             } else {