NFC: add MIFARE MINI support (#2307)
* NFC: add MIFARE MINI support * Move new value to end of enum * nfc: added missing unit test Co-authored-by: gornekich <n.gorbadey@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									4dc4d34d04
								
							
						
					
					
						commit
						eee5c35400
					
				| @ -466,6 +466,10 @@ static void mf_classic_generator_test(uint8_t uid_len, MfClassicType type) { | ||||
|     nfc_device_free(nfc_keys); | ||||
| } | ||||
| 
 | ||||
| MU_TEST(mf_mini_file_test) { | ||||
|     mf_classic_generator_test(4, MfClassicTypeMini); | ||||
| } | ||||
| 
 | ||||
| MU_TEST(mf_classic_1k_4b_file_test) { | ||||
|     mf_classic_generator_test(4, MfClassicType1k); | ||||
| } | ||||
| @ -486,6 +490,7 @@ MU_TEST_SUITE(nfc) { | ||||
|     nfc_test_alloc(); | ||||
| 
 | ||||
|     MU_RUN_TEST(nfca_file_test); | ||||
|     MU_RUN_TEST(mf_mini_file_test); | ||||
|     MU_RUN_TEST(mf_classic_1k_4b_file_test); | ||||
|     MU_RUN_TEST(mf_classic_4k_4b_file_test); | ||||
|     MU_RUN_TEST(mf_classic_1k_7b_file_test); | ||||
|  | ||||
| @ -352,11 +352,27 @@ void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType | ||||
|         } | ||||
|         // Set SAK to 08
 | ||||
|         data->nfc_data.sak = 0x08; | ||||
|     } else if(type == MfClassicTypeMini) { | ||||
|         // Set every block to 0xFF
 | ||||
|         for(uint16_t i = 1; i < MF_MINI_TOTAL_SECTORS_NUM * 4; i += 1) { | ||||
|             if(mf_classic_is_sector_trailer(i)) { | ||||
|                 nfc_generate_mf_classic_sector_trailer(mfc, i); | ||||
|             } else { | ||||
|                 memset(&mfc->block[i].value, 0xFF, 16); | ||||
|             } | ||||
|             mf_classic_set_block_read(mfc, i, &mfc->block[i]); | ||||
|         } | ||||
|         // Set SAK to 09
 | ||||
|         data->nfc_data.sak = 0x09; | ||||
|     } | ||||
| 
 | ||||
|     mfc->type = type; | ||||
| } | ||||
| 
 | ||||
| static void nfc_generate_mf_mini(NfcDeviceData* data) { | ||||
|     nfc_generate_mf_classic(data, 4, MfClassicTypeMini); | ||||
| } | ||||
| 
 | ||||
| static void nfc_generate_mf_classic_1k_4b_uid(NfcDeviceData* data) { | ||||
|     nfc_generate_mf_classic(data, 4, MfClassicType1k); | ||||
| } | ||||
| @ -438,6 +454,11 @@ static const NfcGenerator ntag_i2c_plus_2k_generator = { | ||||
|     .generator_func = nfc_generate_ntag_i2c_plus_2k, | ||||
| }; | ||||
| 
 | ||||
| static const NfcGenerator mifare_mini_generator = { | ||||
|     .name = "Mifare Mini", | ||||
|     .generator_func = nfc_generate_mf_mini, | ||||
| }; | ||||
| 
 | ||||
| static const NfcGenerator mifare_classic_1k_4b_uid_generator = { | ||||
|     .name = "Mifare Classic 1k 4byte UID", | ||||
|     .generator_func = nfc_generate_mf_classic_1k_4b_uid, | ||||
| @ -472,6 +493,7 @@ const NfcGenerator* const nfc_generators[] = { | ||||
|     &ntag_i2c_2k_generator, | ||||
|     &ntag_i2c_plus_1k_generator, | ||||
|     &ntag_i2c_plus_2k_generator, | ||||
|     &mifare_mini_generator, | ||||
|     &mifare_classic_1k_4b_uid_generator, | ||||
|     &mifare_classic_1k_7b_uid_generator, | ||||
|     &mifare_classic_4k_4b_uid_generator, | ||||
|  | ||||
| @ -745,7 +745,10 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* | ||||
|     do { | ||||
|         if(!flipper_format_write_comment_cstr(file, "Mifare Classic specific data")) break; | ||||
| 
 | ||||
|         if(data->type == MfClassicType1k) { | ||||
|         if(data->type == MfClassicTypeMini) { | ||||
|             if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break; | ||||
|             blocks = 20; | ||||
|         } else if(data->type == MfClassicType1k) { | ||||
|             if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break; | ||||
|             blocks = 64; | ||||
|         } else if(data->type == MfClassicType4k) { | ||||
| @ -843,7 +846,10 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* | ||||
|     do { | ||||
|         // Read Mifare Classic type
 | ||||
|         if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; | ||||
|         if(!furi_string_cmp(temp_str, "1K")) { | ||||
|         if(!furi_string_cmp(temp_str, "MINI")) { | ||||
|             data->type = MfClassicTypeMini; | ||||
|             data_blocks = 20; | ||||
|         } else if(!furi_string_cmp(temp_str, "1K")) { | ||||
|             data->type = MfClassicType1k; | ||||
|             data_blocks = 64; | ||||
|         } else if(!furi_string_cmp(temp_str, "4K")) { | ||||
| @ -918,7 +924,9 @@ static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { | ||||
|         if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; | ||||
|         if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version)) | ||||
|             break; | ||||
|         if(data->type == MfClassicType1k) { | ||||
|         if(data->type == MfClassicTypeMini) { | ||||
|             if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break; | ||||
|         } else if(data->type == MfClassicType1k) { | ||||
|             if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break; | ||||
|         } else if(data->type == MfClassicType4k) { | ||||
|             if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break; | ||||
| @ -968,7 +976,9 @@ bool nfc_device_load_key_cache(NfcDevice* dev) { | ||||
|         if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break; | ||||
|         if(version != nfc_keys_file_version) break; | ||||
|         if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; | ||||
|         if(!furi_string_cmp(temp_str, "1K")) { | ||||
|         if(!furi_string_cmp(temp_str, "MINI")) { | ||||
|             data->type = MfClassicTypeMini; | ||||
|         } else if(!furi_string_cmp(temp_str, "1K")) { | ||||
|             data->type = MfClassicType1k; | ||||
|         } else if(!furi_string_cmp(temp_str, "4K")) { | ||||
|             data->type = MfClassicType4k; | ||||
|  | ||||
| @ -55,7 +55,9 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) { | ||||
| } | ||||
| 
 | ||||
| const char* nfc_mf_classic_type(MfClassicType type) { | ||||
|     if(type == MfClassicType1k) { | ||||
|     if(type == MfClassicTypeMini) { | ||||
|         return "Mifare Mini 0.3K"; | ||||
|     } else if(type == MfClassicType1k) { | ||||
|         return "Mifare Classic 1K"; | ||||
|     } else if(type == MfClassicType4k) { | ||||
|         return "Mifare Classic 4K"; | ||||
|  | ||||
| @ -13,7 +13,9 @@ | ||||
| #define MF_CLASSIC_WRITE_BLOCK_CMD (0xA0) | ||||
| 
 | ||||
| const char* mf_classic_get_type_str(MfClassicType type) { | ||||
|     if(type == MfClassicType1k) { | ||||
|     if(type == MfClassicTypeMini) { | ||||
|         return "MIFARE Mini 0.3K"; | ||||
|     } else if(type == MfClassicType1k) { | ||||
|         return "MIFARE Classic 1K"; | ||||
|     } else if(type == MfClassicType4k) { | ||||
|         return "MIFARE Classic 4K"; | ||||
| @ -73,7 +75,9 @@ MfClassicSectorTrailer* | ||||
| } | ||||
| 
 | ||||
| uint8_t mf_classic_get_total_sectors_num(MfClassicType type) { | ||||
|     if(type == MfClassicType1k) { | ||||
|     if(type == MfClassicTypeMini) { | ||||
|         return MF_MINI_TOTAL_SECTORS_NUM; | ||||
|     } else if(type == MfClassicType1k) { | ||||
|         return MF_CLASSIC_1K_TOTAL_SECTORS_NUM; | ||||
|     } else if(type == MfClassicType4k) { | ||||
|         return MF_CLASSIC_4K_TOTAL_SECTORS_NUM; | ||||
| @ -83,7 +87,9 @@ uint8_t mf_classic_get_total_sectors_num(MfClassicType type) { | ||||
| } | ||||
| 
 | ||||
| uint16_t mf_classic_get_total_block_num(MfClassicType type) { | ||||
|     if(type == MfClassicType1k) { | ||||
|     if(type == MfClassicTypeMini) { | ||||
|         return 20; | ||||
|     } else if(type == MfClassicType1k) { | ||||
|         return 64; | ||||
|     } else if(type == MfClassicType4k) { | ||||
|         return 256; | ||||
| @ -363,8 +369,12 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { | ||||
| 
 | ||||
| MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { | ||||
|     UNUSED(ATQA1); | ||||
|     if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) { | ||||
|         return MfClassicType1k; | ||||
|     if((ATQA0 == 0x44 || ATQA0 == 0x04)) { | ||||
|         if((SAK == 0x08 || SAK == 0x88)) { | ||||
|             return MfClassicType1k; | ||||
|         } else if(SAK == 0x09) { | ||||
|             return MfClassicTypeMini; | ||||
|         } | ||||
|     } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) { | ||||
|         //skylanders support
 | ||||
|         return MfClassicType1k; | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| 
 | ||||
| #define MF_CLASSIC_BLOCK_SIZE (16) | ||||
| #define MF_CLASSIC_TOTAL_BLOCKS_MAX (256) | ||||
| #define MF_MINI_TOTAL_SECTORS_NUM (5) | ||||
| #define MF_CLASSIC_1K_TOTAL_SECTORS_NUM (16) | ||||
| #define MF_CLASSIC_4K_TOTAL_SECTORS_NUM (40) | ||||
| 
 | ||||
| @ -20,6 +21,7 @@ | ||||
| typedef enum { | ||||
|     MfClassicType1k, | ||||
|     MfClassicType4k, | ||||
|     MfClassicTypeMini, | ||||
| } MfClassicType; | ||||
| 
 | ||||
| typedef enum { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Giacomo Ferretti
						Giacomo Ferretti