RFC: NTAG I2C support (#1227)
* nfc: Add NTAG I2C (Plus) 1K/2K read support * nfc: Add rudimentary NTAG I2C emulation * nfc: Closer NTAG I2C emulation plus debug logging * nfc: Fix NTAG I2C sector select emulation * nfc: Add security for NTAG I2C * nfc: Send NAK correctly for MFUL reads * nfc: Better emulate NTAG I2C SECTOR_SELECT behavior * nfc: Fix non-I2C Ultralight read Per datasheet, max sector for SECTOR_SELECT is 0xfe, so 0xff is OK as uninit value * nfc: Only read sig for NTAG if supported Attempting to read signature breaks immediate call to sector select on NTAG I2C original for some reason, so don't read signature if the command is not supported Co-authored-by: gornekich <n.gorbadey@gmail.com>
This commit is contained in:
parent
4b45746b8e
commit
0d5d4c8688
@ -35,6 +35,14 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) {
|
|||||||
return "NTAG215";
|
return "NTAG215";
|
||||||
} else if(type == MfUltralightTypeNTAG216) {
|
} else if(type == MfUltralightTypeNTAG216) {
|
||||||
return "NTAG216";
|
return "NTAG216";
|
||||||
|
} else if(type == MfUltralightTypeNTAGI2C1K) {
|
||||||
|
return "NTAG I2C 1K";
|
||||||
|
} else if(type == MfUltralightTypeNTAGI2C2K) {
|
||||||
|
return "NTAG I2C 2K";
|
||||||
|
} else if(type == MfUltralightTypeNTAGI2CPlus1K) {
|
||||||
|
return "NTAG I2C Plus 1K";
|
||||||
|
} else if(type == MfUltralightTypeNTAGI2CPlus2K) {
|
||||||
|
return "NTAG I2C Plus 2K";
|
||||||
} else if(type == MfUltralightTypeUL11 && full_name) {
|
} else if(type == MfUltralightTypeUL11 && full_name) {
|
||||||
return "Mifare Ultralight 11";
|
return "Mifare Ultralight 11";
|
||||||
} else if(type == MfUltralightTypeUL21 && full_name) {
|
} else if(type == MfUltralightTypeUL21 && full_name) {
|
||||||
|
@ -315,6 +315,11 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
|
|||||||
MfUltralightEmulator emulator = {};
|
MfUltralightEmulator emulator = {};
|
||||||
mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data);
|
mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data);
|
||||||
while(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) {
|
while(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) {
|
||||||
|
emulator.auth_success = false;
|
||||||
|
if(emulator.data.type >= MfUltralightTypeNTAGI2C1K) {
|
||||||
|
// Sector index needs to be reset
|
||||||
|
emulator.curr_sector = 0;
|
||||||
|
}
|
||||||
furi_hal_nfc_emulate_nfca(
|
furi_hal_nfc_emulate_nfca(
|
||||||
nfc_data->uid,
|
nfc_data->uid,
|
||||||
nfc_data->uid_len,
|
nfc_data->uid_len,
|
||||||
|
3
firmware/targets/f7/furi_hal/furi_hal_nfc.c
Executable file → Normal file
3
firmware/targets/f7/furi_hal/furi_hal_nfc.c
Executable file → Normal file
@ -1,3 +1,4 @@
|
|||||||
|
#include <limits.h>
|
||||||
#include "furi_hal_nfc.h"
|
#include "furi_hal_nfc.h"
|
||||||
#include <st25r3916.h>
|
#include <st25r3916.h>
|
||||||
#include <st25r3916_irq.h>
|
#include <st25r3916_irq.h>
|
||||||
@ -337,6 +338,8 @@ bool furi_hal_nfc_emulate_nfca(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(buff_tx_len) {
|
if(buff_tx_len) {
|
||||||
|
if(buff_tx_len == UINT16_MAX) buff_tx_len = 0;
|
||||||
|
|
||||||
ReturnCode ret = rfalTransceiveBitsBlockingTx(
|
ReturnCode ret = rfalTransceiveBitsBlockingTx(
|
||||||
buff_tx,
|
buff_tx,
|
||||||
buff_tx_len,
|
buff_tx_len,
|
||||||
|
@ -36,6 +36,10 @@ extern "C" {
|
|||||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
|
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
|
||||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE)
|
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE)
|
||||||
|
|
||||||
|
#define FURI_HAL_NFC_TX_RAW_RX_DEFAULT \
|
||||||
|
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_REMV | \
|
||||||
|
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FuriHalNfcTxRxTypeDefault,
|
FuriHalNfcTxRxTypeDefault,
|
||||||
FuriHalNfcTxRxTypeRxNoCrc,
|
FuriHalNfcTxRxTypeRxNoCrc,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include <furi_hal_nfc.h>
|
#include <furi_hal_nfc.h>
|
||||||
|
|
||||||
#define MF_UL_MAX_DUMP_SIZE 1024
|
// Largest tag is NTAG I2C Plus 2K, both data sectors plus SRAM
|
||||||
|
#define MF_UL_MAX_DUMP_SIZE ((238 + 256 + 16) * 4)
|
||||||
|
|
||||||
#define MF_UL_TEARING_FLAG_DEFAULT (0xBD)
|
#define MF_UL_TEARING_FLAG_DEFAULT (0xBD)
|
||||||
|
|
||||||
@ -11,6 +12,7 @@
|
|||||||
#define MF_UL_READ_CMD (0x30)
|
#define MF_UL_READ_CMD (0x30)
|
||||||
#define MF_UL_FAST_READ_CMD (0x3A)
|
#define MF_UL_FAST_READ_CMD (0x3A)
|
||||||
#define MF_UL_WRITE (0xA2)
|
#define MF_UL_WRITE (0xA2)
|
||||||
|
#define MF_UL_FAST_WRITE (0xA6)
|
||||||
#define MF_UL_COMP_WRITE (0xA0)
|
#define MF_UL_COMP_WRITE (0xA0)
|
||||||
#define MF_UL_READ_CNT (0x39)
|
#define MF_UL_READ_CNT (0x39)
|
||||||
#define MF_UL_INC_CNT (0xA5)
|
#define MF_UL_INC_CNT (0xA5)
|
||||||
@ -18,6 +20,7 @@
|
|||||||
#define MF_UL_READ_SIG (0x3C)
|
#define MF_UL_READ_SIG (0x3C)
|
||||||
#define MF_UL_CHECK_TEARING (0x3E)
|
#define MF_UL_CHECK_TEARING (0x3E)
|
||||||
#define MF_UL_READ_VCSL (0x4B)
|
#define MF_UL_READ_VCSL (0x4B)
|
||||||
|
#define MF_UL_SECTOR_SELECT (0xC2)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MfUltralightTypeUnknown,
|
MfUltralightTypeUnknown,
|
||||||
@ -26,6 +29,10 @@ typedef enum {
|
|||||||
MfUltralightTypeNTAG213,
|
MfUltralightTypeNTAG213,
|
||||||
MfUltralightTypeNTAG215,
|
MfUltralightTypeNTAG215,
|
||||||
MfUltralightTypeNTAG216,
|
MfUltralightTypeNTAG216,
|
||||||
|
MfUltralightTypeNTAGI2C1K,
|
||||||
|
MfUltralightTypeNTAGI2C2K,
|
||||||
|
MfUltralightTypeNTAGI2CPlus1K,
|
||||||
|
MfUltralightTypeNTAGI2CPlus2K,
|
||||||
|
|
||||||
// Keep last for number of types calculation
|
// Keep last for number of types calculation
|
||||||
MfUltralightTypeNum,
|
MfUltralightTypeNum,
|
||||||
@ -71,11 +78,12 @@ typedef struct {
|
|||||||
} MfUltralightAuth;
|
} MfUltralightAuth;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pages_to_read;
|
uint16_t pages_to_read;
|
||||||
uint8_t pages_read;
|
int16_t pages_read;
|
||||||
bool support_fast_read;
|
bool support_fast_read;
|
||||||
bool support_tearing_flags;
|
bool support_tearing_flags;
|
||||||
bool support_counters;
|
bool support_counters;
|
||||||
|
bool support_signature;
|
||||||
} MfUltralightReader;
|
} MfUltralightReader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -85,6 +93,10 @@ typedef struct {
|
|||||||
bool comp_write_cmd_started;
|
bool comp_write_cmd_started;
|
||||||
uint8_t comp_write_page_addr;
|
uint8_t comp_write_page_addr;
|
||||||
MfUltralightAuth* auth_data;
|
MfUltralightAuth* auth_data;
|
||||||
|
bool auth_success;
|
||||||
|
uint8_t curr_sector;
|
||||||
|
bool sector_select_cmd_started;
|
||||||
|
bool ntag_i2c_plus_sector3_lockout;
|
||||||
} MfUltralightEmulator;
|
} MfUltralightEmulator;
|
||||||
|
|
||||||
bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
|
bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
|
||||||
|
Loading…
Reference in New Issue
Block a user