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: あく <alleteam@gmail.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
#include "gen4.h"
|
||||
|
||||
#include <furi_hal_nfc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TAG "Magic"
|
||||
|
||||
#define MAGIC_CMD_PREFIX (0xCF)
|
||||
|
||||
#define MAGIC_CMD_GET_CFG (0xC6)
|
||||
#define MAGIC_CMD_WRITE (0xCD)
|
||||
#define MAGIC_CMD_READ (0xCE)
|
||||
#define MAGIC_CMD_SET_CFG (0xF0)
|
||||
#define MAGIC_CMD_FUSE_CFG (0xF1)
|
||||
#define MAGIC_CMD_SET_PWD (0xFE)
|
||||
|
||||
#define MAGIC_BUFFER_SIZE (40)
|
||||
|
||||
const uint8_t MAGIC_DEFAULT_CONFIG[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x78, 0x00, 0x91, 0x02, 0xDA, 0xBC, 0x19, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x00, 0x08, 0x00
|
||||
};
|
||||
|
||||
const uint8_t MAGIC_DEFAULT_BLOCK0[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const uint8_t MAGIC_EMPTY_BLOCK[16] = { 0 };
|
||||
|
||||
const uint8_t MAGIC_DEFAULT_SECTOR_TRAILER[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
static bool magic_gen4_is_block_num_trailer(uint8_t n) {
|
||||
n++;
|
||||
if (n < 32 * 4) {
|
||||
return (n % 4 == 0);
|
||||
}
|
||||
|
||||
return (n % 16 == 0);
|
||||
}
|
||||
|
||||
bool magic_gen4_get_cfg(uint32_t pwd, uint8_t* config) {
|
||||
bool is_valid_config_len = 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_PREFIX;
|
||||
tx_data[1] = (uint8_t)(pwd >> 24);
|
||||
tx_data[2] = (uint8_t)(pwd >> 16);
|
||||
tx_data[3] = (uint8_t)(pwd >> 8);
|
||||
tx_data[4] = (uint8_t)pwd;
|
||||
tx_data[5] = MAGIC_CMD_GET_CFG;
|
||||
ret = furi_hal_nfc_ll_txrx(
|
||||
tx_data,
|
||||
6,
|
||||
rx_data,
|
||||
sizeof(rx_data),
|
||||
&rx_len,
|
||||
FURI_HAL_NFC_TXRX_DEFAULT,
|
||||
furi_hal_nfc_ll_ms2fc(20));
|
||||
if(ret != FuriHalNfcReturnOk) break;
|
||||
if(rx_len != 30 && rx_len != 32) break;
|
||||
memcpy(config, rx_data, rx_len);
|
||||
is_valid_config_len = true;
|
||||
} while(false);
|
||||
|
||||
return is_valid_config_len;
|
||||
}
|
||||
|
||||
bool magic_gen4_set_cfg(uint32_t pwd, const uint8_t* config, uint8_t config_length, bool fuse) {
|
||||
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 {
|
||||
// Start communication
|
||||
tx_data[0] = MAGIC_CMD_PREFIX;
|
||||
tx_data[1] = (uint8_t)(pwd >> 24);
|
||||
tx_data[2] = (uint8_t)(pwd >> 16);
|
||||
tx_data[3] = (uint8_t)(pwd >> 8);
|
||||
tx_data[4] = (uint8_t)pwd;
|
||||
tx_data[5] = fuse ? MAGIC_CMD_FUSE_CFG : MAGIC_CMD_SET_CFG;
|
||||
memcpy(tx_data + 6, config, config_length);
|
||||
ret = furi_hal_nfc_ll_txrx(
|
||||
tx_data,
|
||||
6 + config_length,
|
||||
rx_data,
|
||||
sizeof(rx_data),
|
||||
&rx_len,
|
||||
FURI_HAL_NFC_TXRX_DEFAULT,
|
||||
furi_hal_nfc_ll_ms2fc(20));
|
||||
if(ret != FuriHalNfcReturnOk) break;
|
||||
if(rx_len != 2) break;
|
||||
write_success = true;
|
||||
} while(false);
|
||||
|
||||
return write_success;
|
||||
}
|
||||
|
||||
bool magic_gen4_set_pwd(uint32_t old_pwd, uint32_t new_pwd) {
|
||||
bool change_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 {
|
||||
// Start communication
|
||||
tx_data[0] = MAGIC_CMD_PREFIX;
|
||||
tx_data[1] = (uint8_t)(old_pwd >> 24);
|
||||
tx_data[2] = (uint8_t)(old_pwd >> 16);
|
||||
tx_data[3] = (uint8_t)(old_pwd >> 8);
|
||||
tx_data[4] = (uint8_t)old_pwd;
|
||||
tx_data[5] = MAGIC_CMD_SET_PWD;
|
||||
tx_data[6] = (uint8_t)(new_pwd >> 24);
|
||||
tx_data[7] = (uint8_t)(new_pwd >> 16);
|
||||
tx_data[8] = (uint8_t)(new_pwd >> 8);
|
||||
tx_data[9] = (uint8_t)new_pwd;
|
||||
ret = furi_hal_nfc_ll_txrx(
|
||||
tx_data,
|
||||
10,
|
||||
rx_data,
|
||||
sizeof(rx_data),
|
||||
&rx_len,
|
||||
FURI_HAL_NFC_TXRX_DEFAULT,
|
||||
furi_hal_nfc_ll_ms2fc(20));
|
||||
FURI_LOG_I(TAG, "ret %d, len %d", ret, rx_len);
|
||||
if(ret != FuriHalNfcReturnOk) break;
|
||||
if(rx_len != 2) break;
|
||||
change_success = true;
|
||||
} while(false);
|
||||
|
||||
return change_success;
|
||||
}
|
||||
|
||||
bool magic_gen4_write_blk(uint32_t pwd, uint8_t block_num, const uint8_t* 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 {
|
||||
// Start communication
|
||||
tx_data[0] = MAGIC_CMD_PREFIX;
|
||||
tx_data[1] = (uint8_t)(pwd >> 24);
|
||||
tx_data[2] = (uint8_t)(pwd >> 16);
|
||||
tx_data[3] = (uint8_t)(pwd >> 8);
|
||||
tx_data[4] = (uint8_t)pwd;
|
||||
tx_data[5] = MAGIC_CMD_WRITE;
|
||||
tx_data[6] = block_num;
|
||||
memcpy(tx_data + 7, data, 16);
|
||||
ret = furi_hal_nfc_ll_txrx(
|
||||
tx_data,
|
||||
23,
|
||||
rx_data,
|
||||
sizeof(rx_data),
|
||||
&rx_len,
|
||||
FURI_HAL_NFC_TXRX_DEFAULT,
|
||||
furi_hal_nfc_ll_ms2fc(200));
|
||||
if(ret != FuriHalNfcReturnOk) break;
|
||||
if(rx_len != 2) break;
|
||||
write_success = true;
|
||||
} while(false);
|
||||
|
||||
return write_success;
|
||||
}
|
||||
|
||||
bool magic_gen4_wipe(uint32_t pwd) {
|
||||
if(!magic_gen4_set_cfg(pwd, MAGIC_DEFAULT_CONFIG, sizeof(MAGIC_DEFAULT_CONFIG), false)) {
|
||||
FURI_LOG_E(TAG, "Set config failed");
|
||||
return false;
|
||||
}
|
||||
if(!magic_gen4_write_blk(pwd, 0, MAGIC_DEFAULT_BLOCK0)) {
|
||||
FURI_LOG_E(TAG, "Block 0 write failed");
|
||||
return false;
|
||||
}
|
||||
for(size_t i = 1; i < 64; i++) {
|
||||
const uint8_t* block = magic_gen4_is_block_num_trailer(i) ? MAGIC_DEFAULT_SECTOR_TRAILER : MAGIC_EMPTY_BLOCK;
|
||||
if(!magic_gen4_write_blk(pwd, i, block)) {
|
||||
FURI_LOG_E(TAG, "Block %d write failed", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for(size_t i = 65; i < 256; i++) {
|
||||
if(!magic_gen4_write_blk(pwd, i, MAGIC_EMPTY_BLOCK)) {
|
||||
FURI_LOG_E(TAG, "Block %d write failed", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <lib/nfc/protocols/mifare_classic.h>
|
||||
|
||||
#define MAGIC_GEN4_DEFAULT_PWD 0x00000000
|
||||
#define MAGIC_GEN4_CONFIG_LEN 32
|
||||
|
||||
#define NFCID1_SINGLE_SIZE 4
|
||||
#define NFCID1_DOUBLE_SIZE 7
|
||||
#define NFCID1_TRIPLE_SIZE 10
|
||||
|
||||
typedef enum {
|
||||
MagicGen4UIDLengthSingle = 0x00,
|
||||
MagicGen4UIDLengthDouble = 0x01,
|
||||
MagicGen4UIDLengthTriple = 0x02
|
||||
} MagicGen4UIDLength;
|
||||
|
||||
typedef enum {
|
||||
MagicGen4UltralightModeUL_EV1 = 0x00,
|
||||
MagicGen4UltralightModeNTAG = 0x01,
|
||||
MagicGen4UltralightModeUL_C = 0x02,
|
||||
MagicGen4UltralightModeUL = 0x03
|
||||
} MagicGen4UltralightMode;
|
||||
|
||||
typedef enum {
|
||||
// for writing original (shadow) data
|
||||
MagicGen4ShadowModePreWrite = 0x00,
|
||||
// written data can be read once before restored to original
|
||||
MagicGen4ShadowModeRestore = 0x01,
|
||||
// written data is discarded
|
||||
MagicGen4ShadowModeIgnore = 0x02,
|
||||
// apparently for UL?
|
||||
MagicGen4ShadowModeHighSpeedIgnore = 0x03
|
||||
} MagicGen4ShadowMode;
|
||||
|
||||
bool magic_gen4_get_cfg(uint32_t pwd, uint8_t* config);
|
||||
|
||||
bool magic_gen4_set_cfg(uint32_t pwd, const uint8_t* config, uint8_t config_length, bool fuse);
|
||||
|
||||
bool magic_gen4_set_pwd(uint32_t old_pwd, uint32_t new_pwd);
|
||||
|
||||
bool magic_gen4_read_blk(uint32_t pwd, uint8_t block_num, uint8_t* data);
|
||||
|
||||
bool magic_gen4_write_blk(uint32_t pwd, uint8_t block_num, const uint8_t* data);
|
||||
|
||||
bool magic_gen4_wipe(uint32_t pwd);
|
||||
|
||||
void magic_gen4_deactivate();
|
||||
+7
-45
@@ -1,4 +1,4 @@
|
||||
#include "magic.h"
|
||||
#include "classic_gen1.h"
|
||||
|
||||
#include <furi_hal_nfc.h>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#define MAGIC_BUFFER_SIZE (32)
|
||||
|
||||
bool magic_wupa() {
|
||||
bool magic_gen1_wupa() {
|
||||
bool magic_activated = false;
|
||||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
|
||||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
|
||||
@@ -23,19 +23,6 @@ bool magic_wupa() {
|
||||
FuriHalNfcReturn ret = 0;
|
||||
|
||||
do {
|
||||
// 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) break;
|
||||
|
||||
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);
|
||||
|
||||
// Start communication
|
||||
tx_data[0] = MAGIC_CMD_WUPA;
|
||||
ret = furi_hal_nfc_ll_txrx_bits(
|
||||
@@ -53,15 +40,10 @@ bool magic_wupa() {
|
||||
magic_activated = true;
|
||||
} while(false);
|
||||
|
||||
if(!magic_activated) {
|
||||
furi_hal_nfc_ll_txrx_off();
|
||||
furi_hal_nfc_start_sleep();
|
||||
}
|
||||
|
||||
return magic_activated;
|
||||
}
|
||||
|
||||
bool magic_data_access_cmd() {
|
||||
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] = {};
|
||||
@@ -86,15 +68,10 @@ bool magic_data_access_cmd() {
|
||||
write_cmd_success = true;
|
||||
} while(false);
|
||||
|
||||
if(!write_cmd_success) {
|
||||
furi_hal_nfc_ll_txrx_off();
|
||||
furi_hal_nfc_start_sleep();
|
||||
}
|
||||
|
||||
return write_cmd_success;
|
||||
}
|
||||
|
||||
bool magic_read_block(uint8_t block_num, MfClassicBlock* data) {
|
||||
bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) {
|
||||
furi_assert(data);
|
||||
|
||||
bool read_success = false;
|
||||
@@ -122,15 +99,10 @@ bool magic_read_block(uint8_t block_num, MfClassicBlock* data) {
|
||||
read_success = true;
|
||||
} while(false);
|
||||
|
||||
if(!read_success) {
|
||||
furi_hal_nfc_ll_txrx_off();
|
||||
furi_hal_nfc_start_sleep();
|
||||
}
|
||||
|
||||
return read_success;
|
||||
}
|
||||
|
||||
bool magic_write_blk(uint8_t block_num, MfClassicBlock* data) {
|
||||
bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) {
|
||||
furi_assert(data);
|
||||
|
||||
bool write_success = false;
|
||||
@@ -170,15 +142,10 @@ bool magic_write_blk(uint8_t block_num, MfClassicBlock* data) {
|
||||
write_success = true;
|
||||
} while(false);
|
||||
|
||||
if(!write_success) {
|
||||
furi_hal_nfc_ll_txrx_off();
|
||||
furi_hal_nfc_start_sleep();
|
||||
}
|
||||
|
||||
return write_success;
|
||||
}
|
||||
|
||||
bool magic_wipe() {
|
||||
bool magic_gen1_wipe() {
|
||||
bool wipe_success = false;
|
||||
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
|
||||
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
|
||||
@@ -205,9 +172,4 @@ bool magic_wipe() {
|
||||
} while(false);
|
||||
|
||||
return wipe_success;
|
||||
}
|
||||
|
||||
void magic_deactivate() {
|
||||
furi_hal_nfc_ll_txrx_off();
|
||||
furi_hal_nfc_sleep();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <lib/nfc/protocols/mifare_classic.h>
|
||||
|
||||
bool magic_wupa();
|
||||
|
||||
bool magic_read_block(uint8_t block_num, MfClassicBlock* data);
|
||||
|
||||
bool magic_data_access_cmd();
|
||||
|
||||
bool magic_write_blk(uint8_t block_num, MfClassicBlock* data);
|
||||
|
||||
bool magic_wipe();
|
||||
|
||||
void magic_deactivate();
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "types.h"
|
||||
|
||||
const char* nfc_magic_type(MagicType type) {
|
||||
if(type == MagicTypeClassicGen1) {
|
||||
return "Classic Gen 1A/B";
|
||||
} else if(type == MagicTypeClassicDirectWrite) {
|
||||
return "Classic DirectWrite";
|
||||
} else if(type == MagicTypeClassicAPDU) {
|
||||
return "Classic APDU";
|
||||
} else if(type == MagicTypeUltralightGen1) {
|
||||
return "Ultralight Gen 1";
|
||||
} else if(type == MagicTypeUltralightDirectWrite) {
|
||||
return "Ultralight DirectWrite";
|
||||
} else if(type == MagicTypeUltralightC_Gen1) {
|
||||
return "Ultralight-C Gen 1";
|
||||
} else if(type == MagicTypeUltralightC_DirectWrite) {
|
||||
return "Ultralight-C DirectWrite";
|
||||
} else if(type == MagicTypeGen4) {
|
||||
return "Gen 4 GTU";
|
||||
} else {
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
const char* nfc_magic_type(MagicType type);
|
||||
Reference in New Issue
Block a user