diff --git a/CHANGELOG.md b/CHANGELOG.md index ee842651e..846dc1ec4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,9 +65,10 @@ - Also added `BLE_ID` command, same as `BT_ID` - Main Menu: Refined CoverFlow menu style (#379 by @956MB) - NFC: + - Support MIFARE DESFire Transaction MAC file type, fixes reading some EV2+ cards (by @Willy-JL) + - Improvements and fixes for NDEF parsing on MIFARE Classic (by @Willy-JL) - OFW: Added naming for DESFire cards + fix MF3ICD40 cards unable to be read (by @Demae) - OFW: FeliCa Protocol Expose Read Block API and Allow Specifying Service (by @zinongli) - - OFW: Support DESFire Transaction MAC file type, fixes reading some EV2+ cards (by @Willy-JL) - OFW: Enable MFUL sync poller to be provided with passwords (by @GMMan) - UL: Power: Moved Charge Cap to Power Settings as Charge Limit option (by @Dmitry422) - Infrared: @@ -84,13 +85,13 @@ ### Fixed: - Asset Packs: Fix level-up animations not being themed (by @Willy-JL) - About: Fix missing Prev. button when invoked from Device Info keybind (by @Willy-JL) +- GUI: Fix widget text scroll with 256+ lines (by @Willy-JL) - Sub-GHz: - UL: Fix Hollarm protocol with more verification (by @xMasterX) - UL: Fix GangQi protocol (by @DoberBit and @mishamyte) - UL: Came Atomo button hold simulation with full cycle to allow proper pairing with receiver (by @xMasterX) - OFW: NFC: ST25TB poller mode check (by @RebornedBrain) - OFW: RFID: Fix Detection Conflict Between Securakey and Noralsy Format (by @zinongli) -- OFW: GUI: Fix widget text scroll with 256+ lines (by @Willy-JL) - Furi: - OFW: EventLoop unsubscribe fix (by @gsurkov & @portasynthinca3) - OFW: Various bug fixes and improvements (by @skotopes) diff --git a/applications/main/nfc/plugins/supported_cards/ndef.c b/applications/main/nfc/plugins/supported_cards/ndef.c index fb2c4da48..53b9c1bd2 100644 --- a/applications/main/nfc/plugins/supported_cards/ndef.c +++ b/applications/main/nfc/plugins/supported_cards/ndef.c @@ -181,30 +181,34 @@ static bool ndef_get(Ndef* ndef, size_t pos, size_t len, void* buf) { // So the first 93 (31*3) data blocks correspond to 128 real blocks. // Last 128 blocks are 8 sectors: 15 data blocks, 1 sector trailer. // So the last 120 (8*15) data blocks correspond to 128 real blocks. - div_t small_sector_data_blocks = div(pos, MF_CLASSIC_BLOCK_SIZE); + const size_t real_block_data_offset = pos % MF_CLASSIC_BLOCK_SIZE; + size_t small_sector_data_blocks = pos / MF_CLASSIC_BLOCK_SIZE; size_t large_sector_data_blocks = 0; - if(small_sector_data_blocks.quot > 93) { - large_sector_data_blocks = small_sector_data_blocks.quot - 93; - small_sector_data_blocks.quot = 93; + if(small_sector_data_blocks > 93) { + large_sector_data_blocks = small_sector_data_blocks - 93; + small_sector_data_blocks = 93; } - div_t small_sectors = div(small_sector_data_blocks.quot, 3); - size_t real_block = small_sectors.quot * 4 + small_sectors.rem; - if(small_sectors.quot >= 16) { + const size_t small_sector_block_offset = small_sector_data_blocks % 3; + const size_t small_sectors = small_sector_data_blocks / 3; + size_t real_block = small_sectors * 4 + small_sector_block_offset; + if(small_sectors >= 16) { real_block += 4; // Skip MAD2 } if(large_sector_data_blocks) { - div_t large_sectors = div(large_sector_data_blocks, 15); - real_block += large_sectors.quot * 16 + large_sectors.rem; + const size_t large_sector_block_offset = large_sector_data_blocks % 15; + const size_t large_sectors = large_sector_data_blocks / 15; + real_block += large_sectors * 16 + large_sector_block_offset; } - const uint8_t* cur = &ndef->mfc.blocks[real_block].data[small_sector_data_blocks.rem]; + const uint8_t* cur = &ndef->mfc.blocks[real_block].data[real_block_data_offset]; while(len) { size_t sector_trailer = mf_classic_get_sector_trailer_num_by_block(real_block); const uint8_t* end = &ndef->mfc.blocks[sector_trailer].data[0]; - size_t chunk_len = MIN((size_t)(end - cur), len); + const size_t chunk_len = MIN((size_t)(end - cur), len); memcpy(buf, cur, chunk_len); + buf += chunk_len; len -= chunk_len; if(len) { @@ -582,7 +586,7 @@ bool ndef_parse_record( NdefTnf tnf, const char* type, uint8_t type_len) { - FURI_LOG_D(TAG, "payload type: %.*s len: %hu", type_len, type, len); + FURI_LOG_D(TAG, "payload type: %.*s len: %hu pos: %zu", type_len, type, len, pos); if(!len) { furi_string_cat(ndef->output, "Empty\n"); return true; @@ -887,13 +891,13 @@ static bool ndef_mfc_parse(const NfcDevice* device, FuriString* parsed_data) { for(uint8_t mad = 0; mad < COUNT_OF(mads); mad++) { const size_t block = mads[mad].block; const size_t sector = mf_classic_get_sector_by_block(block); - if(sector_count <= sector) break; // Skip this MAD if not present + if(sector_count <= sector) continue; // Skip this MAD if not present // Check MAD key const MfClassicSectorTrailer* sector_trailer = mf_classic_get_sector_trailer_by_sector(data, sector); const uint64_t sector_key_a = bit_lib_bytes_to_num_be( sector_trailer->key_a.data, COUNT_OF(sector_trailer->key_a.data)); - if(sector_key_a != mad_key) return false; + if(sector_key_a != mad_key) continue; // Find NDEF AIDs for(uint8_t aid_index = 0; aid_index < mads[mad].aid_count; aid_index++) { const uint8_t* aid = &data->block[block].data[2 + aid_index * AID_SIZE]; @@ -917,7 +921,7 @@ static bool ndef_mfc_parse(const NfcDevice* device, FuriString* parsed_data) { data_size = 93 + (sector_count - 32) * 15; } else { data_size = sector_count * 3; - if(sector_count >= 16) { + if(sector_count > 16) { data_size -= 3; // Skip MAD2 } } diff --git a/lib/nfc/helpers/nfc_data_generator.c b/lib/nfc/helpers/nfc_data_generator.c index 7914c1f7f..2143f0f5f 100644 --- a/lib/nfc/helpers/nfc_data_generator.c +++ b/lib/nfc/helpers/nfc_data_generator.c @@ -392,37 +392,15 @@ static void nfc_generate_mf_classic(NfcDevice* nfc_device, uint8_t uid_len, MfCl mf_classic_set_block_read(mfc_data, 0, &mfc_data->block[0]); + // Set every block to 0x00 uint16_t block_num = mf_classic_get_total_block_num(type); - if(type == MfClassicType4k) { - // Set every block to 0x00 - for(uint16_t i = 1; i < block_num; i++) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc_data, i); - } else { - memset(&mfc_data->block[i].data, 0x00, 16); - } - mf_classic_set_block_read(mfc_data, i, &mfc_data->block[i]); - } - } else if(type == MfClassicType1k) { - // Set every block to 0x00 - for(uint16_t i = 1; i < block_num; i++) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc_data, i); - } else { - memset(&mfc_data->block[i].data, 0x00, 16); - } - mf_classic_set_block_read(mfc_data, i, &mfc_data->block[i]); - } - } else if(type == MfClassicTypeMini) { - // Set every block to 0x00 - for(uint16_t i = 1; i < block_num; i++) { - if(mf_classic_is_sector_trailer(i)) { - nfc_generate_mf_classic_sector_trailer(mfc_data, i); - } else { - memset(&mfc_data->block[i].data, 0x00, 16); - } - mf_classic_set_block_read(mfc_data, i, &mfc_data->block[i]); + for(uint16_t i = 1; i < block_num; i++) { + if(mf_classic_is_sector_trailer(i)) { + nfc_generate_mf_classic_sector_trailer(mfc_data, i); + } else { + memset(&mfc_data->block[i].data, 0x00, MF_CLASSIC_BLOCK_SIZE); } + mf_classic_set_block_read(mfc_data, i, &mfc_data->block[i]); } nfc_generate_mf_classic_block_0( diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 38229da0d..79862dbd8 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -983,7 +983,7 @@ Function,+,dir_walk_read,DirWalkResult,"DirWalk*, FuriString*, FileInfo*" Function,+,dir_walk_set_filter_cb,void,"DirWalk*, DirWalkFilterCb, void*" Function,+,dir_walk_set_recurse_filter,void,"DirWalk*, const char**, size_t" Function,+,dir_walk_set_recursive,void,"DirWalk*, _Bool" -Function,+,div,div_t,"int, int" +Function,-,div,div_t,"int, int" Function,+,dolphin_deed,void,DolphinDeed Function,+,dolphin_deed_get_app,DolphinApp,DolphinDeed Function,+,dolphin_deed_get_app_limit,uint8_t,DolphinApp