1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-22 12:32:02 +00:00

feat(core): Redo nfc library API, add NDEF parser

This commit is contained in:
kopecdav 2025-01-29 21:36:28 +01:00 committed by tychovrahe
parent 14dc82a06f
commit 94ddccffae
5 changed files with 659 additions and 118 deletions

View File

@ -23,6 +23,18 @@
#include <trezor_bsp.h>
#include <trezor_rtl.h>
typedef enum {
NFC_CARD_EMU_TECH_A,
NFC_CARD_EMU_TECH_V,
} nfc_card_emul_tech_t;
typedef enum {
NFC_POLLER_TECH_A,
NFC_POLLER_TECH_B,
NFC_POLLER_TECH_F,
NFC_POLLER_TECH_V,
} nfc_poller_tech_t;
typedef enum {
NFC_OK,
NFC_ERROR,
@ -35,6 +47,10 @@ nfc_status_t nfc_init();
nfc_status_t nfc_deinit();
void nfc_poll_type_A();
nfc_status_t nfc_register_card_emu(nfc_card_emul_tech_t tech);
nfc_status_t nfc_register_poller(nfc_poller_tech_t tech);
nfc_status_t nfc_run_worker();
#endif // TREZORHAL_NFC_H

View File

@ -0,0 +1,92 @@
#include <stdint.h>
#include <string.h>
#include "ndef.h"
// ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len ,ndef_message_t *message){
// memset(message, 0, sizeof(ndef_message_t));
// uint16_t offset = 0;
// uint16_t remainin_len = buffer_len
// while(1){
// ndef_record_t record;
// parse_ndef_record(buffer + offset, remainin_len , &record);
// offset += record.payload_length;
// message->records_cnt++;
// if(message->records_cnt >= NDEF_MAX_RECORDS){
// break; // Max records reached
// }
// }
// return NDEF_OK;
// }
ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len, ndef_record_t *rec){
uint8_t bp = 0;
// Check if there is enough items to cover first part of the header revelaing record length
if(len < 3){
return NDEF_ERROR; // Not enough data to parse
}
// Look at first byte, parse header
memcpy(&(rec->header), buffer, 1);
bp++;
if(rec->header.tnf == 0x00 || rec->header.tnf > 0x06){
return NDEF_ERROR; // Empty or non-existing record
}
rec->type_length = buffer[bp++];
if(rec->header.sr){
rec->payload_length = buffer[bp++];
}else{
memcpy(&(rec->payload_length), buffer + bp, 4);
bp += 4;
}
if(rec->header.il){
rec->id_length = buffer[bp++];
}else{
// ID length ommited
rec->id_length = 0;
}
if(rec->type_length > 0){
memcpy(&(rec->type), buffer + bp, rec->type_length);
bp += rec->type_length;
}else{
// Type length ommited
rec->type = 0;
}
if(rec->id_length > 0){
memcpy(&(rec->id), buffer + bp, rec->id_length);
bp += rec->id_length;
}else{
// ID length ommited
rec->id = 0;
}
if(rec->payload_length > 0){
memcpy(rec->payload, buffer + bp, rec->payload_length);
bp += rec->payload_length;
}else{
// Payload length ommited;
}
rec->record_total_len = bp;
return NDEF_OK;
}

View File

@ -0,0 +1,38 @@
#define NDEF_MAX_RECORDS 3
#define NDEF_MAX_RECORD_PAYLOAD_BYTES 50
typedef enum{
NDEF_OK = 0,
NDEF_ERROR = 1,
} ndef_status_t;
typedef struct{
uint8_t tnf : 3;
uint8_t il : 1;
uint8_t sr : 1;
uint8_t cf : 1;
uint8_t me : 1;
uint8_t mb : 1;
}ndef_record_header_t;
typedef struct{
ndef_record_header_t header;
uint8_t type_length;
uint32_t payload_length;
uint8_t id_length;
uint8_t type;
uint8_t id;
uint8_t payload[NDEF_MAX_RECORD_PAYLOAD_BYTES];
uint16_t record_total_len;
}ndef_record_t;
typedef struct{
uint8_t records_cnt;
ndef_record_t records[NDEF_MAX_RECORDS];
} ndef_message_t;
// ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len ,ndef_message_t *message);
ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len, ndef_record_t *rec);

View File

@ -7,13 +7,27 @@
#include "../inc/io/nfc.h"
#include "nfc_internal.h"
#include "rfal_platform.h"
#include "ndef.h"
#include "../rfal/include/rfal_isoDep.h"
#include "../rfal/include/rfal_nfc.h"
#include "../rfal/include/rfal_nfca.h"
#include "../rfal/include/rfal_rf.h"
#include "../rfal/include/rfal_t2t.h"
#include "../rfal/include/rfal_utils.h"
#include "prodtest_common.h"
#include "stm32u5xx_hal.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
typedef struct {
bool initialized;
// SPI driver
@ -21,12 +35,219 @@ typedef struct {
// NFC IRQ pin callback
void (*nfc_irq_callback)(void);
EXTI_HandleTypeDef hEXTI;
rfalNfcDiscoverParam disc_params;
} st25r3916b_driver_t;
static st25r3916b_driver_t g_st25r3916b_driver = {
.initialized = false,
};
static void parse_tag_header(uint8_t *data, uint16_t dataLen);
/* Definition of possible states the demo state machine could have */
#define DEMO_ST_CE_NOTINIT 0 /*!< Demo State: Not initialized */
#define DEMO_ST_CE_START_DISCOVERY 1 /*!< Demo State: Start Discovery */
#define DEMO_ST_CE_DISCOVERY 2 /*!< Demo State: Discovery */
#define DEMO_ST_CE_TAG_OPERATION 3 /*!< Demo State: Discovery */
/* Definition of possible states the demo state machine could have */
#define DEMO_ST_NOTINIT 0 /*!< Demo State: Not initialized */
#define DEMO_ST_START_DISCOVERY 1 /*!< Demo State: Start Discovery */
#define DEMO_ST_DISCOVERY 2 /*!< Demo State: Discovery */
#define DEMO_NFCV_BLOCK_LEN 4 /*!< NFCV Block len */
#define DEMO_NFCV_USE_SELECT_MODE \
false /*!< NFCV demonstrate select mode */
/*
******************************************************************************
* GLOBAL DEFINES
******************************************************************************
*/
/* Definition of possible states the demo state machine could have */
#define DEMO_ST_NOTINIT 0 /*!< Demo State: Not initialized | Stopped */
#define DEMO_ST_START_DISCOVERY 1 /*!< Demo State: Start Discovery */
#define DEMO_ST_DISCOVERY 2 /*!< Demo State: Discovery */
#define DEMO_NFCV_BLOCK_LEN 4 /*!< NFCV Block len */
#define DEMO_NFCV_USE_SELECT_MODE \
false /*!< NFCV demonstrate select mode */
#define DEMO_NFCV_WRITE_TAG false /*!< NFCV demonstrate Write Single Block */
/* Definition of various Listen Mode constants */
#if defined(DEMO_LISTEN_MODE_TARGET)
#define DEMO_LM_SEL_RES \
0x40U /*!<NFC-A SEL_RES configured for the NFC-DEP protocol */
#define DEMO_LM_NFCID2_BYTE1 \
0x01U /*!<NFC-F SENSF_RES configured for the NFC-DEP protocol */
#define DEMO_LM_SC_BYTE1 \
0xFFU /*!<NFC-F System Code byte 1 */
#define DEMO_LM_SC_BYTE2 \
0xFFU /*!<NFC-F System Code byte 2 */
#define DEMO_LM_PAD0 \
0xFFU /*!<NFC-F PAD0 */
#else
#define DEMO_LM_SEL_RES \
0x20U /*!<NFC-A SEL_RES configured for Type 4A Tag Platform */
#define DEMO_LM_NFCID2_BYTE1 \
0x02U /*!<NFC-F SENSF_RES configured for Type 3 Tag Platform */
#define DEMO_LM_SC_BYTE1 \
0x12U /*!<NFC-F System Code byte 1 */
#define DEMO_LM_SC_BYTE2 \
0xFCU /*!<NFC-F System Code byte 2 */
#define DEMO_LM_PAD0 \
0x00U /*!<NFC-F PAD0 */
#endif
/*
******************************************************************************
* GLOBAL MACROS
******************************************************************************
*/
/*
******************************************************************************
* LOCAL VARIABLES
******************************************************************************
*/
/* P2P communication data */
static uint8_t NFCID3[] = {0x01, 0xFE, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0A};
static uint8_t GB[] = {0x46, 0x66, 0x6d, 0x01, 0x01, 0x11, 0x02,
0x02, 0x07, 0x80, 0x03, 0x02, 0x00, 0x03,
0x04, 0x01, 0x32, 0x07, 0x01, 0x03};
/* APDUs communication data */
#if RFAL_FEATURE_ISO_DEP_POLL
static uint8_t ndefSelectApp[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76,
0x00, 0x00, 0x85, 0x01, 0x01, 0x00};
static uint8_t ccSelectFile[] = {0x00, 0xA4, 0x00, 0x0C, 0x02, 0xE1, 0x03};
static uint8_t readBinary[] = {0x00, 0xB0, 0x00, 0x00, 0x0F};
/* For a Payment application a Select PPSE would be needed:
ppseSelectApp[] = { 0x00, 0xA4, 0x04, 0x00, 0x0E, 0x32, 0x50, 0x41, 0x59,
0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00 } */
#endif /* RFAL_FEATURE_ISO_DEP_POLL */
#if RFAL_FEATURE_NFC_DEP
/* P2P communication data */
static uint8_t ndefLLCPSYMM[] = {0x00, 0x00};
static uint8_t ndefInit[] = {0x05, 0x20, 0x06, 0x0F, 0x75, 0x72, 0x6E,
0x3A, 0x6E, 0x66, 0x63, 0x3A, 0x73, 0x6E,
0x3A, 0x73, 0x6E, 0x65, 0x70, 0x02, 0x02,
0x07, 0x80, 0x05, 0x01, 0x02};
static uint8_t ndefUriSTcom[] = {
0x13, 0x20, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x19, 0xc1, 0x01, 0x00,
0x00, 0x00, 0x12, 0x55, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
0x77, 0x77, 0x77, 0x2e, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d};
#endif /* RFAL_FEATURE_NFC_DEP */
#if RFAL_SUPPORT_CE && RFAL_FEATURE_LISTEN_MODE
#if RFAL_SUPPORT_MODE_LISTEN_NFCA
/* NFC-A CE config */
/* 4-byte UIDs with first byte 0x08 would need random number for the subsequent
* 3 bytes. 4-byte UIDs with first byte 0x*F are Fixed number, not unique, use
* for this demo 7-byte UIDs need a manufacturer ID and need to assure
* uniqueness of the rest.*/
static uint8_t ceNFCA_NFCID[] = {
0x5F, 'S', 'T', 'M'}; /* =_STM, 5F 53 54 4D NFCID1 / UID (4 bytes) */
static uint8_t ceNFCA_SENS_RES[] = {0x02,
0x00}; /* SENS_RES / ATQA for 4-byte UID */
static uint8_t ceNFCA_SEL_RES = DEMO_LM_SEL_RES; /* SEL_RES / SAK */
#endif /* RFAL_SUPPORT_MODE_LISTEN_NFCA */
static uint8_t ceNFCF_nfcid2[] = {
DEMO_LM_NFCID2_BYTE1, 0xFE, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
#if RFAL_SUPPORT_MODE_LISTEN_NFCF
/* NFC-F CE config */
static uint8_t ceNFCF_SC[] = {DEMO_LM_SC_BYTE1, DEMO_LM_SC_BYTE2};
static uint8_t ceNFCF_SENSF_RES[] = {
0x01, /* SENSF_RES */
0x02, 0xFE, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, /* NFCID2 */
DEMO_LM_PAD0, DEMO_LM_PAD0, 0x00, 0x00, 0x00,
0x7F, 0x7F, 0x00, /* PAD0, PAD1, MRTIcheck, MRTIupdate, PAD2
*/
0x00, 0x00}; /* RD */
#endif /* RFAL_SUPPORT_MODE_LISTEN_NFCF */
#endif /* RFAL_SUPPORT_CE && RFAL_FEATURE_LISTEN_MODE */
/*
******************************************************************************
* LOCAL VARIABLES
******************************************************************************
*/
// static void demoNotif(rfalNfcState st);
// static bool demoInit();
// static void demoCycle();
// static void demoP2P(rfalNfcDevice *nfcDev);
// static void demoAPDU(void);
// static void demoNfcv(rfalNfcvListenDevice *nfcvDev);
// static void demoNfcf(rfalNfcfListenDevice *nfcfDev);
// static void demoT2t(void);
// static void demoCE(rfalNfcDevice *nfcDev);
ReturnCode demoTransceiveBlocking(uint8_t *txBuf, uint16_t txBufSize,
uint8_t **rxBuf, uint16_t **rcvLen,
uint32_t fwt);
#define MAX_HEX_STR 4
#define MAX_HEX_STR_LENGTH 512
char hexStr[MAX_HEX_STR][MAX_HEX_STR_LENGTH];
uint8_t hexStrIdx = 0;
char *hex2Str(unsigned char *data, size_t dataLen) {
{
unsigned char *pin = data;
const char *hex = "0123456789ABCDEF";
char *pout = hexStr[hexStrIdx];
uint8_t i = 0;
uint8_t idx = hexStrIdx;
if (dataLen == 0) {
pout[0] = 0;
} else {
for (; i < dataLen - 1; ++i) {
*pout++ = hex[(*pin >> 4) & 0xF];
*pout++ = hex[(*pin++) & 0xF];
}
*pout++ = hex[(*pin >> 4) & 0xF];
*pout++ = hex[(*pin) & 0xF];
*pout = 0;
}
hexStrIdx++;
hexStrIdx %= MAX_HEX_STR;
return hexStr[idx];
}
}
typedef struct{
uint8_t UID[7];
uint8_t BCC[1];
uint8_t SYSTEM_AREA[2];
union{
uint8_t CC[4];
struct{
uint8_t CC_MAGIC_NUMBER;
uint8_t CC_VERSION;
uint8_t CC_SIZE;
uint8_t CC_ACCESS_CONDITION;
};
};
} type2_header_t;
nfc_status_t nfc_init() {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@ -84,7 +305,7 @@ nfc_status_t nfc_init() {
drv->hspi.Init.Direction = SPI_DIRECTION_2LINES;
drv->hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
drv->hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
drv->hspi.Init.NSS = SPI_NSS_SOFT; // For rfal lib purpose, use software NSS
drv->hspi.Init.NSS = SPI_NSS_SOFT; // For RFAL lib purpose, use software NSS
drv->hspi.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
drv->hspi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
@ -106,9 +327,14 @@ nfc_status_t nfc_init() {
return false;
}
ReturnCode ret_code = rfalInitialize();
if (ret_code != RFAL_ERR_NONE) {
return NFC_INITIALIZATION_FAILED;
ReturnCode ret;
ret = rfalNfcInitialize();
// Set default discovery parameters
rfalNfcDefaultDiscParams(&drv->disc_params);
if (ret != RFAL_ERR_NONE) {
return NFC_ERROR;
}
drv->initialized = true;
@ -123,6 +349,12 @@ nfc_status_t nfc_deinit() {
return NFC_OK;
}
// Deactivate rfal STM.
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_IDLE);
while (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
rfalNfcWorker();
}
HAL_EXTI_ClearConfigLine(&drv->hEXTI);
NVIC_DisableIRQ(NFC_EXTI_INTERRUPT_NUM);
@ -145,6 +377,271 @@ nfc_status_t nfc_deinit() {
return NFC_OK;
}
nfc_status_t nfc_register_card_emu(nfc_card_emul_tech_t tech) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
// In case the NFC state machine is active, deactivate to idle before
// registering a new card emulation technology.
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_IDLE);
do {
rfalNfcWorker();
} while (rfalNfcGetState() != RFAL_NFC_STATE_IDLE);
}
drv->disc_params.devLimit = 1;
memcpy(&drv->disc_params.nfcid3, NFCID3, sizeof(NFCID3));
memcpy(&drv->disc_params.GB, GB, sizeof(GB));
drv->disc_params.GBLen = sizeof(GB);
drv->disc_params.p2pNfcaPrio = true;
drv->disc_params.totalDuration = 1000U;
switch (tech) {
case NFC_CARD_EMU_TECH_A:
memcpy(drv->disc_params.lmConfigPA.SENS_RES, ceNFCA_SENS_RES,
RFAL_LM_SENS_RES_LEN); /* Set SENS_RES / ATQA */
memcpy(drv->disc_params.lmConfigPA.nfcid, ceNFCA_NFCID,
RFAL_LM_NFCID_LEN_04); /* Set NFCID / UID */
drv->disc_params.lmConfigPA.nfcidLen =
RFAL_LM_NFCID_LEN_04; /* Set NFCID length to 4 bytes */
drv->disc_params.lmConfigPA.SEL_RES =
ceNFCA_SEL_RES; /* Set SEL_RES / SAK */
drv->disc_params.techs2Find |= RFAL_NFC_LISTEN_TECH_A;
break;
case NFC_CARD_EMU_TECH_V:
drv->disc_params.techs2Find |= RFAL_NFC_POLL_TECH_V;
break;
default:
return NFC_ERROR;
}
return NFC_OK;
}
nfc_status_t nfc_register_poller(nfc_poller_tech_t tech) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
// In case the NFC state machine is active, deactivate to idle before
// registering a new card emulation technology.
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_IDLE);
do {
rfalNfcWorker();
} while (rfalNfcGetState() != RFAL_NFC_STATE_IDLE);
}
drv->disc_params.devLimit = 1;
memcpy(&drv->disc_params.nfcid3, NFCID3, sizeof(NFCID3));
memcpy(&drv->disc_params.GB, GB, sizeof(GB));
drv->disc_params.GBLen = sizeof(GB);
drv->disc_params.p2pNfcaPrio = true;
drv->disc_params.totalDuration = 1000U;
switch (tech) {
case NFC_POLLER_TECH_A:
drv->disc_params.techs2Find |= RFAL_NFC_POLL_TECH_A;
break;
case NFC_POLLER_TECH_B:
drv->disc_params.techs2Find |= RFAL_NFC_POLL_TECH_B;
break;
case NFC_POLLER_TECH_F:
drv->disc_params.techs2Find |= RFAL_NFC_POLL_TECH_F;
break;
case NFC_POLLER_TECH_V:
drv->disc_params.techs2Find |= RFAL_NFC_POLL_TECH_V;
break;
default:
return NFC_ERROR;
}
ReturnCode err;
err = rfalNfcDiscover(&drv->disc_params);
if (err != RFAL_ERR_NONE) {
return NFC_ERROR;
}
return NFC_OK;
}
nfc_status_t nfc_run_worker() {
static rfalNfcDevice *nfcDevice;
rfalNfcWorker(); /* Run RFAL worker periodically */
if (rfalNfcIsDevActivated(rfalNfcGetState())) {
rfalNfcGetActiveDevice(&nfcDevice);
switch (nfcDevice->type) {
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCA:
switch (nfcDevice->dev.nfca.type) {
case RFAL_NFCA_T1T:
vcp_println("ISO14443A/Topaz (NFC-A T1T) TAG found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
case RFAL_NFCA_T4T:
vcp_println("NFCA Passive ISO-DEP device found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
case RFAL_NFCA_T4T_NFCDEP:
case RFAL_NFCA_NFCDEP:
break;
default:
vcp_println("ISO14443A/NFC-A card found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
ReturnCode err;
uint16_t rcvLen;
uint8_t blockNum = 0;
uint8_t rxBuf[16];
vcp_println("Tag ID len: %d", nfcDevice->nfcidLen);
// Read first 16 bytes (1st block)
err = rfalT2TPollerRead(0, rxBuf, sizeof(rxBuf), &rcvLen);
parse_tag_header(rxBuf, sizeof(rxBuf));
uint8_t memory_area_data[160] = {0};
for (uint8_t i = 0; i < 10; i++) {
err = rfalT2TPollerRead(4+i*4, memory_area_data+i*16, 16 , &rcvLen);
}
ndef_record_t record;
parse_ndef_record(memory_area_data+2, 160, &record);
vcp_println("Record payload: %s", record.payload);
break;
}
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCB:
vcp_println("NFC TYPE B card found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCF:
vcp_println("NFC TYPE F card found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCV:
vcp_println("NFC TYPE V card found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_ST25TB:
vcp_println("ST25TB card found. UID: %s\r\n",
hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen));
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_AP2P:
case RFAL_NFC_POLL_TYPE_AP2P:
break;
/*******************************************************************************/
case RFAL_NFC_POLL_TYPE_NFCA:
break;
case RFAL_NFC_POLL_TYPE_NFCF:
break;
/*******************************************************************************/
default:
break;
}
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY);
}
return NFC_OK;
}
static void parse_tag_header(uint8_t *data, uint16_t dataLen){
type2_header_t hdr;
memcpy(hdr.UID, data, 3);
hdr.BCC[0] = data[3];
memcpy(hdr.UID + 3, data+4, 4);
memcpy(hdr.SYSTEM_AREA, data+8, 2);
memcpy(hdr.CC, data+12, 4);
vcp_println("UID: %s", hex2Str(hdr.UID, sizeof(hdr.UID)));
vcp_println("BCC: %s (%s)", hex2Str(hdr.BCC, sizeof(hdr.BCC)), (0x88 == (hdr.UID[0] ^ hdr.UID[1] ^ hdr.UID[2] ^ hdr.BCC[0]))? " CHECKSUM PASSED" : "CHECKSUM FAILED");
vcp_println("SYSTEM_AREA: %s", hex2Str(hdr.SYSTEM_AREA, sizeof(hdr.SYSTEM_AREA)));
vcp_println("CC: %s", hex2Str(hdr.CC, sizeof(hdr.CC)));
vcp_println(" -> CC_MAGIC_NUMBER: %02X", hdr.CC_MAGIC_NUMBER);
vcp_println(" -> CC_VERSION: %02X", hdr.CC_VERSION);
vcp_println(" -> CC_SIZE: %02X (%d bytes)", hdr.CC_SIZE, hdr.CC_SIZE*8);
vcp_println(" -> CC_ACCESS_CONDITION: %02X", hdr.CC_ACCESS_CONDITION);
}
/*!
*****************************************************************************
* \brief Demo Blocking Transceive
*
* Helper function to send data in a blocking manner via the rfalNfc module
*
* \warning A protocol transceive handles long timeouts (several seconds),
* transmission errors and retransmissions which may lead to a long period of
* time where the MCU/CPU is blocked in this method.
* This is a demo implementation, for a non-blocking usage example please
* refer to the Examples available with RFAL
*
* \param[in] txBuf : data to be transmitted
* \param[in] txBufSize : size of the data to be transmited
* \param[out] rxData : location where the received data has been placed
* \param[out] rcvLen : number of data bytes received
* \param[in] fwt : FWT to be used (only for RF frame interface,
* otherwise use RFAL_FWT_NONE)
*
* \return RFAL_ERR_PARAM : Invalid parameters
* \return RFAL_ERR_TIMEOUT : Timeout error
* \return RFAL_ERR_FRAMING : Framing error detected
* \return RFAL_ERR_PROTO : Protocol error detected
* \return RFAL_ERR_NONE : No error, activation successful
*
*****************************************************************************
*/
ReturnCode demoTransceiveBlocking(uint8_t *txBuf, uint16_t txBufSize,
uint8_t **rxData, uint16_t **rcvLen,
uint32_t fwt) {
ReturnCode err;
err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxData, rcvLen, fwt);
if (err == RFAL_ERR_NONE) {
do {
rfalNfcWorker();
err = rfalNfcDataExchangeGetStatus();
} while (err == RFAL_ERR_BUSY);
}
return err;
}
HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint8_t *rxData, uint16_t length) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@ -165,12 +662,11 @@ HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint32_t nfc_create_timer(uint16_t time) { return (systick_ms() + time); }
bool nfc_timer_is_expired(uint32_t timer) {
uint32_t u_diff;
int32_t s_diff;
u_diff = (timer - systick_ms()); // Calculate the diff between the timers
s_diff = u_diff; // Convert the diff to a signed var
u_diff = (timer - systick_ms()); // Calculate the diff between the timers
s_diff = u_diff; // Convert the diff to a signed var
// Check if the given timer has expired already
if (s_diff < 0) {
@ -194,113 +690,3 @@ void NFC_EXTI_INTERRUPT_HANDLER(void) {
drv->nfc_irq_callback();
}
}
#define EXAMPLE_NFCA_DEVICES 10
void nfc_poll_type_A() {
/*
******************************************************************************
* GLOBAL FUNCTIONS
******************************************************************************
*/
ReturnCode err;
rfalNfcaSensRes sensRes;
rfalNfcaSelRes selRes;
rfalNfcaListenDevice nfcaDevList[EXAMPLE_NFCA_DEVICES];
uint8_t devCnt;
uint8_t devIt;
rfalInitialize();
for (;;) {
rfalFieldOff(); /* Turn the Field Off */
platformDelay(500);
rfalNfcaPollerInitialize(); /* Initialize RFAL for NFC-A */
rfalFieldOnAndStartGT(); /* Turns the Field On and starts GT timer */
/*******************************************************************************/
/* Perform NFC-A Technology detection */
err = rfalNfcaPollerTechnologyDetection(
RFAL_COMPLIANCE_MODE_NFC, &sensRes); /* Poll for nearby NFC-A devices */
if (err == RFAL_ERR_NONE) /* NFC-A type card found */
{
return;
/*******************************************************************************/
/* Perform NFC-A Collision Resolution */
err = rfalNfcaPollerFullCollisionResolution(
RFAL_COMPLIANCE_MODE_NFC, EXAMPLE_NFCA_DEVICES, nfcaDevList,
&devCnt); /* Perform collision avoidance */
if ((err == RFAL_ERR_NONE) && (devCnt > 0)) {
platformLog("NFC-A device(s) found %d\r\n", devCnt);
devIt = 0; /* Use the first device on the list */
/*******************************************************************************/
/* Check if desired device is in Sleep */
if (nfcaDevList[devIt].isSleep) {
err = rfalNfcaPollerCheckPresence(RFAL_14443A_SHORTFRAME_CMD_WUPA,
&sensRes); /* Wake up all cards */
if (err != RFAL_ERR_NONE) {
continue;
}
err = rfalNfcaPollerSelect(nfcaDevList[devIt].nfcId1,
nfcaDevList[devIt].nfcId1Len,
&selRes); /* Select specific device */
if (err != RFAL_ERR_NONE) {
continue;
}
}
/*******************************************************************************/
/* Perform protocol specific activation */
switch (nfcaDevList[devIt].type) {
case RFAL_NFCA_T1T:
/* No further activation needed for a T1T (RID already
* performed)*/
platformLog(
"NFC-A T1T device found \r\n"); /* NFC-A T1T device fained in:
t1tRidRes.uid */
/* Following communications shall be performed using:
* - Non blocking: rfalStartTransceive() +
* rfalGetTransceiveState()
* - Blocking: rfalTransceiveBlockingTx() +
* rfalTransceiveBlockingRx() or rfalTransceiveBlockingTxRx() */
break;
case RFAL_NFCA_T2T:
/* No specific activation needed for a T2T */
platformLog(
"NFC-A T2T device found \r\n"); /* NFC-A T2T device found,
NFCID/UID is contained in:
nfcaDev.nfcid */
/* Following communications shall be perforound,
NFCID/UID is contmed using:
* - Non blocking: rfalStartTransceive() +
* rfalGetTransceiveState()
* - Blocking: rfalTransceiveBlockingTx() +
* rfalTransceiveBlockingRx() or rfalTransceiveBlockingTxRx() */
break;
case RFAL_NFCA_T4T:
platformLog(
"NFC-A T4T (ISO-DEP) device found \r\n"); /* NFC-A T4T device
found, NFCID/UID
is contained in:
nfcaDev.nfcid */
/* Activation should continue using
* rfalIsoDepPollAHandleActivation(), see exampleRfalPoller.c */
break;
case RFAL_NFCA_T4T_NFCDEP: /* Device supports T4T and NFC-DEP */
case RFAL_NFCA_NFCDEP: /* Device supports NFC-DEP */
platformLog(
"NFC-A P2P (NFC-DEP) device found \r\n"); /* NFC-A P2P device
found, NFCID/UID
is contained in:
nfcaDev.nfcid */
/* Activation should continue using
* rfalNfcDepInitiatorHandleActivation(), see exampleRfalPoller.c
*/
break;
}
rfalNfcaPollerSleep(); /* Put device to sleep / HLTA (useless as the
field will be turned off anyhow) */
}
}
}
}

View File

@ -93,10 +93,19 @@ def configure(
if "nfc" in features_wanted:
sources += ["embed/io/nfc/st25r3916b/nfc.c"]
sources += ["embed/io/nfc/st25r3916b/ndef.c"]
sources += ["embed/io/nfc/rfal/source/st25r3916/rfal_rfst25r3916.c"]
sources += ["embed/io/nfc/rfal/source/rfal_analogConfig.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfc.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfca.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfcb.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfcf.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfcv.c"]
sources += ["embed/io/nfc/rfal/source/rfal_isoDep.c"]
sources += ["embed/io/nfc/rfal/source/rfal_nfcDep.c"]
sources += ["embed/io/nfc/rfal/source/rfal_st25tb.c"]
sources += ["embed/io/nfc/rfal/source/rfal_t1t.c"]
sources += ["embed/io/nfc/rfal/source/rfal_t2t.c"]
sources += ["embed/io/nfc/rfal/source/rfal_iso15693_2.c"]
sources += ["embed/io/nfc/rfal/source/rfal_crc.c"]
sources += ["embed/io/nfc/rfal/source/st25r3916/st25r3916.c"]