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>
This commit is contained in:
		
							parent
							
								
									0a3ff7f85a
								
							
						
					
					
						commit
						663eb6cd6d
					
				@ -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
									
								
								applications/main/nfc/scenes/nfc_scene_mf_classic_data.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								applications/main/nfc/scenes/nfc_scene_mf_classic_data.c
									
									
									
									
									
										Normal file
									
								
							@ -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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -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 {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user