-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NFC: Add support for Gen4 "ultimate card" in Magic app (#2238)
* NFC: gen4 gtu detect in magic app * NFC: more support for GTU card * NFC: Fix Gen1 in Magic * Allow double UIDs for MFClassic on GTU cards * NFC: Small magic app tweaks * nfc magic: notify card event on wiping * nfc magic: fix power consumption * nfc magic: disable i2c writing and fix wipe loop * NfcMagic: correct formatting in printf * NfcMagic: correct formatting in printf, proper version * nfc_magic: rework card found notification and gen4 wiping Co-authored-by: あく <[email protected]>
- Loading branch information
1 parent
77bb997
commit 490447b
Showing
30 changed files
with
1,345 additions
and
150 deletions.
There are no files selected for viewing
175 changes: 175 additions & 0 deletions
175
applications/external/nfc_magic/lib/magic/classic_gen1.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
#include "classic_gen1.h" | ||
|
||
#include <furi_hal_nfc.h> | ||
|
||
#define TAG "Magic" | ||
|
||
#define MAGIC_CMD_WUPA (0x40) | ||
#define MAGIC_CMD_WIPE (0x41) | ||
#define MAGIC_CMD_ACCESS (0x43) | ||
|
||
#define MAGIC_MIFARE_READ_CMD (0x30) | ||
#define MAGIC_MIFARE_WRITE_CMD (0xA0) | ||
|
||
#define MAGIC_ACK (0x0A) | ||
|
||
#define MAGIC_BUFFER_SIZE (32) | ||
|
||
bool magic_gen1_wupa() { | ||
bool magic_activated = false; | ||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint16_t rx_len = 0; | ||
FuriHalNfcReturn ret = 0; | ||
|
||
do { | ||
// Start communication | ||
tx_data[0] = MAGIC_CMD_WUPA; | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
7, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, | ||
furi_hal_nfc_ll_ms2fc(20)); | ||
if(ret != FuriHalNfcReturnIncompleteByte) break; | ||
if(rx_len != 4) break; | ||
if(rx_data[0] != MAGIC_ACK) break; | ||
magic_activated = true; | ||
} while(false); | ||
|
||
return magic_activated; | ||
} | ||
|
||
bool magic_gen1_data_access_cmd() { | ||
bool write_cmd_success = false; | ||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint16_t rx_len = 0; | ||
FuriHalNfcReturn ret = 0; | ||
|
||
do { | ||
tx_data[0] = MAGIC_CMD_ACCESS; | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
8, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, | ||
furi_hal_nfc_ll_ms2fc(20)); | ||
if(ret != FuriHalNfcReturnIncompleteByte) break; | ||
if(rx_len != 4) break; | ||
if(rx_data[0] != MAGIC_ACK) break; | ||
|
||
write_cmd_success = true; | ||
} while(false); | ||
|
||
return write_cmd_success; | ||
} | ||
|
||
bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) { | ||
furi_assert(data); | ||
|
||
bool read_success = false; | ||
|
||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint16_t rx_len = 0; | ||
FuriHalNfcReturn ret = 0; | ||
|
||
do { | ||
tx_data[0] = MAGIC_MIFARE_READ_CMD; | ||
tx_data[1] = block_num; | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
2 * 8, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON, | ||
furi_hal_nfc_ll_ms2fc(20)); | ||
|
||
if(ret != FuriHalNfcReturnOk) break; | ||
if(rx_len != 16 * 8) break; | ||
memcpy(data->value, rx_data, sizeof(data->value)); | ||
read_success = true; | ||
} while(false); | ||
|
||
return read_success; | ||
} | ||
|
||
bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) { | ||
furi_assert(data); | ||
|
||
bool write_success = false; | ||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint16_t rx_len = 0; | ||
FuriHalNfcReturn ret = 0; | ||
|
||
do { | ||
tx_data[0] = MAGIC_MIFARE_WRITE_CMD; | ||
tx_data[1] = block_num; | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
2 * 8, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, | ||
furi_hal_nfc_ll_ms2fc(20)); | ||
if(ret != FuriHalNfcReturnIncompleteByte) break; | ||
if(rx_len != 4) break; | ||
if(rx_data[0] != MAGIC_ACK) break; | ||
|
||
memcpy(tx_data, data->value, sizeof(data->value)); | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
16 * 8, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, | ||
furi_hal_nfc_ll_ms2fc(20)); | ||
if(ret != FuriHalNfcReturnIncompleteByte) break; | ||
if(rx_len != 4) break; | ||
if(rx_data[0] != MAGIC_ACK) break; | ||
|
||
write_success = true; | ||
} while(false); | ||
|
||
return write_success; | ||
} | ||
|
||
bool magic_gen1_wipe() { | ||
bool wipe_success = false; | ||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {}; | ||
uint16_t rx_len = 0; | ||
FuriHalNfcReturn ret = 0; | ||
|
||
do { | ||
tx_data[0] = MAGIC_CMD_WIPE; | ||
ret = furi_hal_nfc_ll_txrx_bits( | ||
tx_data, | ||
8, | ||
rx_data, | ||
sizeof(rx_data), | ||
&rx_len, | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | | ||
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP, | ||
furi_hal_nfc_ll_ms2fc(2000)); | ||
|
||
if(ret != FuriHalNfcReturnIncompleteByte) break; | ||
if(rx_len != 4) break; | ||
if(rx_data[0] != MAGIC_ACK) break; | ||
|
||
wipe_success = true; | ||
} while(false); | ||
|
||
return wipe_success; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#pragma once | ||
|
||
#include <lib/nfc/protocols/mifare_classic.h> | ||
|
||
bool magic_gen1_wupa(); | ||
|
||
bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data); | ||
|
||
bool magic_gen1_data_access_cmd(); | ||
|
||
bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data); | ||
|
||
bool magic_gen1_wipe(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "common.h" | ||
|
||
#include <furi_hal_nfc.h> | ||
|
||
#define REQA (0x26) | ||
#define CL1_PREFIX (0x93) | ||
#define SELECT (0x70) | ||
|
||
#define MAGIC_BUFFER_SIZE (32) | ||
|
||
bool magic_activate() { | ||
FuriHalNfcReturn ret = 0; | ||
|
||
// Setup nfc poller | ||
furi_hal_nfc_exit_sleep(); | ||
furi_hal_nfc_ll_txrx_on(); | ||
furi_hal_nfc_ll_poll(); | ||
ret = furi_hal_nfc_ll_set_mode( | ||
FuriHalNfcModePollNfca, FuriHalNfcBitrate106, FuriHalNfcBitrate106); | ||
if(ret != FuriHalNfcReturnOk) return false; | ||
|
||
furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER); | ||
furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER); | ||
furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc); | ||
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCA); | ||
|
||
return true; | ||
} | ||
|
||
void magic_deactivate() { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_sleep(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
typedef enum { | ||
MagicTypeClassicGen1, | ||
MagicTypeClassicDirectWrite, | ||
MagicTypeClassicAPDU, | ||
MagicTypeUltralightGen1, | ||
MagicTypeUltralightDirectWrite, | ||
MagicTypeUltralightC_Gen1, | ||
MagicTypeUltralightC_DirectWrite, | ||
MagicTypeGen4, | ||
} MagicType; | ||
|
||
bool magic_activate(); | ||
|
||
void magic_deactivate(); |
Oops, something went wrong.
490447b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YAY!!!