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

refactor(core): resolve requested changes

This commit is contained in:
kopecdav 2025-02-06 20:13:01 +01:00 committed by tychovrahe
parent 07bb8afe26
commit 83337dd266
13 changed files with 400 additions and 397 deletions

View File

@ -17,12 +17,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TREZORHAL_NFC_H
#define TREZORHAL_NFC_H
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include "ndef.h"
#pragma once
#include "trezor_types.h"
#define NFC_MAX_UID_LEN 10
@ -46,7 +44,7 @@ typedef enum {
} nfc_dev_type_t;
typedef enum {
NFC_STATE_IDLE,
NFC_NO_EVENT,
NFC_STATE_ACTIVATED,
} nfc_event_t;
@ -60,45 +58,40 @@ typedef enum {
typedef struct {
uint8_t type;
char uid[NFC_MAX_UID_LEN];
char uid[NFC_MAX_UID_LEN + 1]; // Plus one for string termination
uint8_t uid_len;
} nfc_dev_info_t;
// Initialize NFC driver including supportive RFAL middlewere
nfc_status_t nfc_init();
// Initialize NFC driver including supportive RFAL middleware
nfc_status_t nfc_init(void);
// Deinitialize NFC drive
nfc_status_t nfc_deinit();
// Deinitialize NFC driver
nfc_status_t nfc_deinit(void);
// Register NFC technology (or several) to be explored by NFC state machine
// use this function before activating the state machine with nfc_activate_stm()
nfc_status_t nfc_register_tech(nfc_tech_t tech);
nfc_status_t nfc_register_tech(const nfc_tech_t tech);
// Register event callbacks to be called with state machine, this function is
// used when user need to further interact (read/write) with the connected NFC
// device
nfc_status_t nfc_register_event_callback(nfc_event_t event_type,
void (*cb_fn)(void));
// Activate the NFC RFAL state machine which will explore the registered
// technologies State machine handles the low level NFC protocols of registered
// technologies and provide the user with the activated device information. With
// activated, user have to constantly run NFC workerwith nfc_feed_worker() to
// activly loop the state machine.
nfc_status_t nfc_activate_stm();
// Activates the NFC RFAL state machine to explore the previously registered technologies.
// The RFAL handles low-level NFC protocols and provides information about the activated device.
// This function only starts the exploration; you must regularly call nfc_get_event() to continue
// processing NFC operations.
nfc_status_t nfc_activate_stm(void);
// Deactivate the NFC RFAL state machine (put in IDLE state).
nfc_status_t nfc_deactivate_stm();
nfc_status_t nfc_deactivate_stm(void);
// Calls NFC RFAL worker which service the NFC statemachine exploring the
// registered technologies. this function has to be actively called in loop
// (main NFC poll function).
nfc_status_t nfc_feed_worker();
// Calls NFC RFAL worker to service the NFC state machine and expolore
// registered technologies. This function has to be actively called in loop
// (main NFC poll function), returns nfc event.
nfc_event_t nfc_get_event(void);
// Deactivate the currently activated NFC device and put RFAL state machine back to
// discovary state.
nfc_status_t nfc_dev_deactivate(void);
// Read the general device information of the activated NFC device.
nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info);
// Write the NDFE message with the trezor.io URI to the activated NFC device.
nfc_status_t nfc_def_write_ndef_uri();
#endif // TREZORHAL_NFC_H
// Write the NDEF message with the trezor.io URI to the activated NFC device.
nfc_status_t nfc_dev_write_ndef_uri(void);

View File

@ -0,0 +1,8 @@
RFAL middleware was imported into trezor-firmware to support a low level NFC operations of st25r3916b from
https://www.st.com/en/embedded-software/stsw-st25r-lib.html#overview (version 1.7.0)
# Local changes
1. rfalIsoDepInfo structure defined in include/rfal_isoDep.h and rfalNfcDepInfo include/rfal_nfcDep.h contains variable DSI which colide with the DSI macro in
STM32 HAL drivers. To resolve this, variale in RFAL library was refactored to DSI_ID.

View File

@ -529,7 +529,7 @@ static uint16_t card_emulation_t3t_update(uint8_t *cmdData, uint8_t *rspData) {
* @return None
*****************************************************************************
*/
void card_emulation_init(uint8_t *nfcfNfcid) {
void card_emulation_init(const uint8_t *nfcfNfcid) {
if (nfcfNfcid != NULL) {
memcpy(gNfcfNfcid, nfcfNfcid, RFAL_NFCF_NFCID2_LEN);
}

View File

@ -16,16 +16,14 @@
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef DEMO_CE_H
#define DEMO_CE_H
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>
#include <trezor_bsp.h>
/** @addtogroup X-CUBE-NFC6_Applications
* @brief Sample applications for X-NUCLEO-NFC06A1 STM32 expansion boards.
@ -74,7 +72,7 @@ extern "C" {
/** @defgroup CE_CardEmul_Exported_functions
* @{
*/
void card_emulation_init(uint8_t *nfcfNfcid);
void card_emulation_init(const uint8_t *nfcfNfcid);
uint16_t card_emulation_t3t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
uint16_t txBufLen);
uint16_t card_emulation_t4t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
@ -100,6 +98,4 @@ uint16_t card_emulation_t4t(uint8_t *rxData, uint16_t rxDataLen, uint8_t *txBuf,
}
#endif
#endif /* DEMO_CE_H */
/******************* (C) COPYRIGHT 2018 STMicroelectronics *****END OF FILE****/

View File

@ -1,12 +1,28 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <trezor_rtl.h>
#include "ndef.h"
#include <stdint.h>
#include <string.h>
// ndef_status_t create_ndef_record_uri(uint8_t *bytearray, )
ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
ndef_status_t ndef_parse_message(const uint8_t *buffer, uint16_t buffer_len,
ndef_message_t *message) {
memset(message, 0, sizeof(ndef_message_t));
@ -34,7 +50,7 @@ ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
remaining_len = message->message_total_len;
while (1) {
parse_ndef_record(buffer, remaining_len,
ndef_parse_record(buffer, remaining_len,
&(message->records[message->records_cnt]));
buffer += message->records[message->records_cnt].record_total_len;
remaining_len -= message->records[message->records_cnt].record_total_len;
@ -57,7 +73,7 @@ ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
return NDEF_OK;
}
ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
ndef_status_t ndef_parse_record(const uint8_t *buffer, uint16_t len,
ndef_record_t *rec) {
uint8_t bp = 0;
@ -119,7 +135,7 @@ ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
return NDEF_OK;
}
uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
uint16_t ndef_create_uri(const char *uri, uint8_t *buffer) {
*buffer = 0x3; // TLV header
buffer++;
@ -129,15 +145,6 @@ uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
*buffer = uri_len + 5; // uri + record header;
buffer++;
// ndef_record_header_t hdr = {
// .tnf = 0x01,
// .il = 0,
// .sr = 1,
// .cf = 0,
// .me = 1,
// .mb = 1,
// };
*buffer = 0xD1; // NDEF record Header
buffer++;
@ -158,8 +165,6 @@ uint16_t create_ndef_uri(const char *uri, uint8_t *buffer) {
buffer++;
}
// memcpy(buffer, uri, uri_len);
*buffer = 0xFE; // TLV termination
return uri_len + 7; // return buffer len

View File

@ -1,7 +1,6 @@
#include <stdint.h>
#pragma once
#ifndef NDEF_H
#define NDEF_H
#include <trezor_types.h>
#define NDEF_MAX_RECORDS 3
#define NDEF_MAX_RECORD_PAYLOAD_BYTES 50
@ -37,10 +36,9 @@ typedef struct {
ndef_record_t records[NDEF_MAX_RECORDS];
} ndef_message_t;
ndef_status_t parse_ndef_message(uint8_t *buffer, uint16_t buffer_len,
ndef_status_t ndef_parse_message(const uint8_t *buffer, uint16_t buffer_len,
ndef_message_t *message);
ndef_status_t parse_ndef_record(uint8_t *buffer, uint16_t len,
ndef_status_t ndef_parse_record(const uint8_t *buffer, uint16_t len,
ndef_record_t *rec);
uint16_t create_ndef_uri(const char *uri, uint8_t *buffer);
uint16_t ndef_create_uri(const char *uri, uint8_t *buffer);
#endif

View File

@ -1,23 +1,52 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/irq.h>
#include <sys/systick.h>
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include "../inc/io/nfc.h"
#include <sys/irq.h>
#include <sys/systick.h>
#include <rtl/strutils.h>
#include "io/nfc.h"
#include "rfal_isoDep.h"
#include "rfal_nfc.h"
#include "rfal_nfca.h"
#include "rfal_rf.h"
#include "rfal_t2t.h"
#include "rfal_utils.h"
#include "card_emulation.h"
#include "ndef.h"
#include "nfc_internal.h"
#include "rfal_platform.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 "stm32u5xx_hal.h"
#define LM_SEL_RES \
0x20U /*!<NFC-A SEL_RES configured for Type 4A Tag Platform */
#define LM_NFCID2_BYTE1 \
0x02U /*!<NFC-F SENSF_RES configured for Type 3 Tag Platform */
#define LM_SC_BYTE1 \
0x12U /*!<NFC-F System Code byte 1 */
#define LM_SC_BYTE2 \
0xFCU /*!<NFC-F System Code byte 2 */
#define LM_PAD0 \
0x00U /*!<NFC-F PAD0 */
typedef struct {
bool initialized;
@ -26,10 +55,6 @@ typedef struct {
// NFC IRQ pin callback
void (*nfc_irq_callback)(void);
// Event callbacks
void (*nfc_state_idle_cb)(void);
void (*nfc_state_activated_cb)(void);
EXTI_HandleTypeDef hEXTI;
rfalNfcDiscoverParam disc_params;
@ -54,24 +79,10 @@ typedef struct {
};
} nfc_device_header_t2t_t;
// static void parse_tag_header(uint8_t *data, uint16_t dataLen);
static char *hex2Str(unsigned char *data, size_t dataLen);
#define LM_SEL_RES \
0x20U /*!<NFC-A SEL_RES configured for Type 4A Tag Platform */
#define LM_NFCID2_BYTE1 \
0x02U /*!<NFC-F SENSF_RES configured for Type 3 Tag Platform */
#define LM_SC_BYTE1 \
0x12U /*!<NFC-F System Code byte 1 */
#define LM_SC_BYTE2 \
0xFCU /*!<NFC-F System Code byte 2 */
#define LM_PAD0 \
0x00U /*!<NFC-F PAD0 */
/* P2P communication data */
static uint8_t NFCID3[] = {0x01, 0xFE, 0x03, 0x04, 0x05,
const uint8_t NFCID3[] = {0x01, 0xFE, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0A};
static uint8_t GB[] = {0x46, 0x66, 0x6d, 0x01, 0x01, 0x11, 0x02,
const uint8_t GB[] = {0x46, 0x66, 0x6d, 0x01, 0x01, 0x11, 0x02,
0x02, 0x07, 0x80, 0x03, 0x02, 0x00, 0x03,
0x04, 0x01, 0x32, 0x07, 0x01, 0x03};
@ -80,18 +91,18 @@ static uint8_t GB[] = {0x46, 0x66, 0x6d, 0x01, 0x01, 0x11, 0x02,
* 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[] = {
const uint8_t ceNFCA_NFCID[] = {
0x1, 0x2, 0x3, 0x4}; /* =_STM, 5F 53 54 4D NFCID1 / UID (4 bytes) */
static uint8_t ceNFCA_SENS_RES[] = {0x02,
const uint8_t ceNFCA_SENS_RES[] = {0x02,
0x00}; /* SENS_RES / ATQA for 4-byte UID */
static uint8_t ceNFCA_SEL_RES = LM_SEL_RES; /* SEL_RES / SAK */
const uint8_t ceNFCA_SEL_RES = LM_SEL_RES; /* SEL_RES / SAK */
static uint8_t ceNFCF_nfcid2[] = {
const uint8_t ceNFCF_nfcid2[] = {
LM_NFCID2_BYTE1, 0xFE, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
/* NFC-F CE config */
static uint8_t ceNFCF_SC[] = {LM_SC_BYTE1, LM_SC_BYTE2};
static uint8_t ceNFCF_SENSF_RES[] = {
const uint8_t ceNFCF_SC[] = {LM_SC_BYTE1, LM_SC_BYTE2};
uint8_t ceNFCF_SENSF_RES[] = {
0x01, /* SENSF_RES */
0x02, 0xFE, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, /* NFCID2 */
@ -103,12 +114,8 @@ static uint8_t ceNFCF_SENSF_RES[] = {
static ReturnCode nfc_transcieve_blocking(uint8_t *txBuf, uint16_t txBufSize,
uint8_t **rxBuf, uint16_t **rcvLen,
uint32_t fwt);
static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev);
#define MAX_HEX_STR 4
#define MAX_HEX_STR_LENGTH 512
char hexStr[MAX_HEX_STR][MAX_HEX_STR_LENGTH];
uint8_t hexStrIdx = 0;
static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev);
nfc_status_t nfc_init() {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@ -119,35 +126,37 @@ nfc_status_t nfc_init() {
// Enable clock of relevant peripherals
// SPI + GPIO ports
SPI_INSTANCE_3_CLK_EN();
SPI_INSTANCE_3_MISO_CLK_EN();
SPI_INSTANCE_3_MOSI_CLK_EN();
SPI_INSTANCE_3_SCK_CLK_EN();
SPI_INSTANCE_3_NSS_CLK_EN();
NFC_SPI_FORCE_RESET();
NFC_SPI_RELEASE_RESET();
NFC_SPI_CLK_EN();
NFC_SPI_MISO_CLK_EN();
NFC_SPI_MOSI_CLK_EN();
NFC_SPI_SCK_CLK_EN();
NFC_SPI_NSS_CLK_EN();
// SPI peripheral pin config
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = SPI_INSTANCE_3_PIN_AF;
GPIO_InitStruct.Alternate = NFC_SPI_PIN_AF;
GPIO_InitStruct.Pin = SPI_INSTANCE_3_MISO_PIN;
HAL_GPIO_Init(SPI_INSTANCE_3_MISO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = NFC_SPI_MISO_PIN;
HAL_GPIO_Init(NFC_SPI_MISO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_INSTANCE_3_MOSI_PIN;
HAL_GPIO_Init(SPI_INSTANCE_3_MOSI_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = NFC_SPI_MOSI_PIN;
HAL_GPIO_Init(NFC_SPI_MOSI_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_INSTANCE_3_SCK_PIN;
HAL_GPIO_Init(SPI_INSTANCE_3_SCK_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = NFC_SPI_SCK_PIN;
HAL_GPIO_Init(NFC_SPI_SCK_PORT, &GPIO_InitStruct);
// NSS pin controled by software, set as classical GPIO
// NSS pin controlled by software, set as classical GPIO
GPIO_InitTypeDef GPIO_InitStruct_nss = {0};
GPIO_InitStruct_nss.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct_nss.Pull = GPIO_NOPULL;
GPIO_InitStruct_nss.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct_nss.Pin = SPI_INSTANCE_3_NSS_PIN;
HAL_GPIO_Init(SPI_INSTANCE_3_NSS_PORT, &GPIO_InitStruct_nss);
GPIO_InitStruct_nss.Pin = NFC_SPI_NSS_PIN;
HAL_GPIO_Init(NFC_SPI_NSS_PORT, &GPIO_InitStruct_nss);
// NFC IRQ pin
GPIO_InitTypeDef GPIO_InitStructure_int = {0};
@ -159,7 +168,7 @@ nfc_status_t nfc_init() {
memset(&(drv->hspi), 0, sizeof(drv->hspi));
drv->hspi.Instance = SPI_INSTANCE_3;
drv->hspi.Instance = NFC_SPI_INSTANCE;
drv->hspi.Init.Mode = SPI_MODE_MASTER;
drv->hspi.Init.BaudRatePrescaler =
SPI_BAUDRATEPRESCALER_32; // TODO: Calculate frequency precisly.
@ -204,7 +213,7 @@ nfc_status_t nfc_init() {
return NFC_OK;
}
nfc_status_t nfc_deinit() {
nfc_status_t nfc_deinit(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
if (!drv->initialized) {
@ -228,40 +237,25 @@ nfc_status_t nfc_deinit() {
HAL_SPI_DeInit(&(drv->hspi));
HAL_GPIO_DeInit(SPI_INSTANCE_3_MISO_PORT, SPI_INSTANCE_3_MISO_PIN);
HAL_GPIO_DeInit(SPI_INSTANCE_3_MOSI_PORT, SPI_INSTANCE_3_MOSI_PIN);
HAL_GPIO_DeInit(SPI_INSTANCE_3_SCK_PORT, SPI_INSTANCE_3_SCK_PIN);
HAL_GPIO_DeInit(SPI_INSTANCE_3_NSS_PORT, SPI_INSTANCE_3_NSS_PIN);
HAL_GPIO_DeInit(NFC_SPI_MISO_PORT, NFC_SPI_MISO_PIN);
HAL_GPIO_DeInit(NFC_SPI_MOSI_PORT, NFC_SPI_MOSI_PIN);
HAL_GPIO_DeInit(NFC_SPI_SCK_PORT, NFC_SPI_SCK_PIN);
HAL_GPIO_DeInit(NFC_SPI_NSS_PORT, NFC_SPI_NSS_PIN);
HAL_GPIO_DeInit(NFC_INT_PORT, NFC_INT_PIN);
drv->initialized = false;
return NFC_OK;
}
void rfal_callback(rfalNfcState st) {
nfc_status_t nfc_register_tech(const nfc_tech_t tech) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
switch (st) {
case RFAL_NFC_STATE_IDLE:
if (drv->nfc_state_idle_cb != NULL) {
drv->nfc_state_idle_cb();
}
break;
case RFAL_NFC_STATE_ACTIVATED:
if (drv->nfc_state_activated_cb != NULL) {
drv->nfc_state_activated_cb();
}
break;
default:
// State not reported
break;
if (drv->initialized == false) {
return NFC_NOT_INITIALIZED;
}
}
nfc_status_t nfc_register_tech(nfc_tech_t tech) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
drv->disc_params.devLimit = 1;
memcpy(&drv->disc_params.nfcid3, NFCID3, sizeof(NFCID3));
@ -269,11 +263,6 @@ nfc_status_t nfc_register_tech(nfc_tech_t tech) {
drv->disc_params.GBLen = sizeof(GB);
drv->disc_params.p2pNfcaPrio = true;
drv->disc_params.totalDuration = 1000U;
drv->disc_params.notifyCb = rfal_callback;
if (drv->initialized == false) {
return NFC_NOT_INITIALIZED;
}
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
return NFC_ERROR;
@ -324,34 +313,13 @@ nfc_status_t nfc_register_tech(nfc_tech_t tech) {
return NFC_OK;
}
nfc_status_t nfc_register_event_callback(nfc_event_t event_type,
void (*cb_fn)(void)) {
nfc_status_t nfc_activate_stm(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
switch (event_type) {
case NFC_STATE_IDLE:
drv->nfc_state_idle_cb = cb_fn;
break;
case NFC_STATE_ACTIVATED:
drv->nfc_state_activated_cb = cb_fn;
break;
default:
return NFC_ERROR;
if(!drv->initialized) {
return NFC_NOT_INITIALIZED;
}
return NFC_OK;
}
nfc_status_t nfc_unregister_event_callback() {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
drv->disc_params.notifyCb = NULL;
return NFC_OK;
}
nfc_status_t nfc_activate_stm() {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
ReturnCode err;
err = rfalNfcDiscover(&(drv->disc_params));
if (err != RFAL_ERR_NONE) {
@ -361,7 +329,14 @@ nfc_status_t nfc_activate_stm() {
return NFC_OK;
}
nfc_status_t nfc_deactivate_stm() {
nfc_status_t nfc_deactivate_stm(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
if(!drv->initialized) {
return NFC_OK;
}
// In case the NFC state machine is active, deactivate to idle before
// registering a new card emulation technology.
if (rfalNfcGetState() != RFAL_NFC_STATE_IDLE) {
@ -374,61 +349,60 @@ nfc_status_t nfc_deactivate_stm() {
return NFC_OK;
}
nfc_status_t nfc_feed_worker() {
nfc_event_t nfc_get_event(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
if(!drv->initialized) {
return NFC_NOT_INITIALIZED;
}
static rfalNfcDevice *nfcDevice;
rfalNfcWorker(); /* Run RFAL worker periodically */
if (rfalNfcIsDevActivated(rfalNfcGetState())) {
if(rfalNfcIsDevActivated(rfalNfcGetState())) {
rfalNfcGetActiveDevice(&nfcDevice);
// Perform immediate mandatory actions for certain technology (Placeholder)
switch (nfcDevice->type) {
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCA:
switch (nfcDevice->dev.nfca.type) {
case RFAL_NFCA_T1T:
break;
case RFAL_NFCA_T4T:
break;
case RFAL_NFCA_T4T_NFCDEP:
break;
case RFAL_NFCA_NFCDEP:
break;
default:
break;
}
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCB:
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCF:
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_NFCV:
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_ST25TB:
break;
/*******************************************************************************/
case RFAL_NFC_LISTEN_TYPE_AP2P:
case RFAL_NFC_POLL_TYPE_AP2P:
break;
/*******************************************************************************/
/*******************************************************************************/
// Card emulators need to promptly respond to the reader commands, so when
// activated rfal worker is called seveal times untill back to back
// communication with the reader is completed. This may prolong the
// run_feed_worker service time compared to standard reader mode.
// Card emulators must respond to reader commands promptly. Once activated,
// the RFAL worker is called multiple times until back-to-back communication
// with the reader finishes. This can prolong the nfc_get_event() service
// time compared to standard reader mode.
case RFAL_NFC_POLL_TYPE_NFCA:
case RFAL_NFC_POLL_TYPE_NFCF:
@ -436,59 +410,35 @@ nfc_status_t nfc_feed_worker() {
// not supported yet
} else {
nfc_card_emulator_loop(nfcDevice);
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY); // Automatically deactivate
}
break;
return NFC_NO_EVENT;
break;
break;
/*******************************************************************************/
default:
break;
}
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY);
return NFC_STATE_ACTIVATED;
}
return NFC_OK;
return NFC_NO_EVENT;
}
static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev) {
ReturnCode err = RFAL_ERR_INTERNAL;
uint8_t *rxData;
uint16_t *rcvLen;
uint8_t txBuf[150];
uint16_t txLen;
nfc_status_t nfc_dev_deactivate(void) {
do {
rfalNfcWorker();
st25r3916b_driver_t drv = g_st25r3916b_driver;
switch (rfalNfcGetState()) {
case RFAL_NFC_STATE_ACTIVATED:
err = nfc_transcieve_blocking(NULL, 0, &rxData, &rcvLen, 0);
break;
if (!drv.initialized) {
return NFC_NOT_INITIALIZED;
}
case RFAL_NFC_STATE_DATAEXCHANGE:
case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
rfalNfcDeactivate(RFAL_NFC_DEACTIVATE_DISCOVERY);
txLen = ((nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA)
? card_emulation_t4t(rxData, *rcvLen, txBuf, sizeof(txBuf))
: rfalConvBytesToBits(card_emulation_t3t(
rxData, rfalConvBitsToBytes(*rcvLen), txBuf,
sizeof(txBuf))));
err = nfc_transcieve_blocking(txBuf, txLen, &rxData, &rcvLen,
RFAL_FWT_NONE);
break;
case RFAL_NFC_STATE_START_DISCOVERY:
return;
case RFAL_NFC_STATE_LISTEN_SLEEP:
default:
break;
}
} while ((err == RFAL_ERR_NONE) || (err == RFAL_ERR_SLEEP_REQ));
return NFC_OK;
}
nfc_status_t nfc_transceive(const uint8_t *txData, uint16_t txDataLen,
@ -514,11 +464,18 @@ nfc_status_t nfc_transceive(const uint8_t *txData, uint16_t txDataLen,
return NFC_OK;
}
nfc_status_t nfc_def_write_ndef_uri() {
nfc_status_t nfc_dev_write_ndef_uri(void) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
if (!drv->initialized) {
return NFC_NOT_INITIALIZED;
}
// NDEF message
uint8_t ndef_message[128] = {0};
uint16_t buffer_len = create_ndef_uri("trezor.io/", ndef_message);
uint16_t buffer_len = ndef_create_uri("trezor.io/", ndef_message);
for (uint8_t i = 0; i < buffer_len / 4; i++) {
rfalT2TPollerWrite(4 + i, ndef_message + i * 4);
@ -564,8 +521,12 @@ nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info) {
return NFC_ERROR;
}
char *uid_str = hex2Str(nfcDevice->nfcid, nfcDevice->nfcidLen);
memcpy(dev_info->uid, uid_str, nfcDevice->nfcidLen);
if (nfcDevice->nfcidLen <= NFC_MAX_UID_LEN) {
return NFC_ERROR;
}
// Copy the hex UID in printable string
cstr_encode_hex(dev_info->uid, NFC_MAX_UID_LEN, nfcDevice->nfcid, nfcDevice->nfcidLen);
} else {
// No device activated
@ -575,58 +536,6 @@ nfc_status_t nfc_dev_read_info(nfc_dev_info_t *dev_info) {
return NFC_OK;
}
// static void parse_tag_header(uint8_t *data, uint16_t dataLen) {
// nfc_device_header_t2t_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);
// }
static ReturnCode nfc_transcieve_blocking(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;
}
static 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];
}
}
HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint8_t *rxData, uint16_t length) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@ -644,22 +553,9 @@ HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
return status;
}
uint32_t nfc_create_timer(uint16_t time) { return (systick_ms() + time); }
uint32_t nfc_create_timer(uint16_t time) { return ticks_timeout(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
// Check if the given timer has expired already
if (s_diff < 0) {
return true;
}
return false;
}
bool nfc_timer_is_expired(uint32_t timer) { return ticks_expired(timer); }
void nfc_ext_irq_set_callback(void (*cb)(void)) {
st25r3916b_driver_t *drv = &g_st25r3916b_driver;
@ -675,3 +571,58 @@ void NFC_EXTI_INTERRUPT_HANDLER(void) {
drv->nfc_irq_callback();
}
}
static void nfc_card_emulator_loop(rfalNfcDevice *nfcDev) {
ReturnCode err = RFAL_ERR_INTERNAL;
uint8_t *rxBuf;
uint16_t *rcvLen;
uint8_t txBuf[150];
uint16_t txLen;
do {
rfalNfcWorker();
switch (rfalNfcGetState()) {
case RFAL_NFC_STATE_ACTIVATED:
err = nfc_transcieve_blocking(NULL, 0, &rxBuf, &rcvLen, 0);
break;
case RFAL_NFC_STATE_DATAEXCHANGE:
case RFAL_NFC_STATE_DATAEXCHANGE_DONE:
txLen = ((nfcDev->type == RFAL_NFC_POLL_TYPE_NFCA)
? card_emulation_t4t(rxBuf, *rcvLen, txBuf, sizeof(txBuf))
: rfalConvBytesToBits(card_emulation_t3t(
rxBuf, rfalConvBitsToBytes(*rcvLen), txBuf,
sizeof(txBuf))));
err = nfc_transcieve_blocking(txBuf, txLen, &rxBuf, &rcvLen,
RFAL_FWT_NONE);
break;
case RFAL_NFC_STATE_START_DISCOVERY:
return;
case RFAL_NFC_STATE_LISTEN_SLEEP:
default:
break;
}
} while ((err == RFAL_ERR_NONE) || (err == RFAL_ERR_SLEEP_REQ));
}
static ReturnCode nfc_transcieve_blocking(uint8_t *txBuf, uint16_t txBufSize,
uint8_t **rxBuf, uint16_t **rcvLen,
uint32_t fwt) {
ReturnCode err;
err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxBuf, rcvLen, fwt);
if (err == RFAL_ERR_NONE) {
do {
rfalNfcWorker();
err = rfalNfcDataExchangeGetStatus();
} while (err == RFAL_ERR_BUSY);
}
return err;
}

View File

@ -1,9 +1,8 @@
#pragma once
#include <trezor_bsp.h>
#ifndef TREZORHAL_NFC_INTERNAL_H
#define TREZORHAL_NFC_INTERNAL_H
HAL_StatusTypeDef nfc_spi_transmit_receive(const uint8_t *txData,
uint8_t *rxData, uint16_t length);
@ -13,4 +12,3 @@ bool nfc_timer_is_expired(uint32_t timer);
void nfc_ext_irq_set_callback(void (*cb)(void));
#endif

View File

@ -20,8 +20,7 @@
*
*/
#ifndef RFAL_PLATFORM_H
#define RFAL_PLATFORM_H
#pragma once
#ifdef __cplusplus
extern "C" {
@ -34,16 +33,13 @@ extern "C" {
*/
#include <trezor_bsp.h>
#include "stm32u5xx_hal.h"
#include <trezor_types.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/systimer.h>
#include <sys/systimer.h>
#include "io/nfc.h"
#include "nfc_internal.h"
/*
@ -56,10 +52,10 @@ extern "C" {
#define ST25R3916B
// GPIO pin used for ST25R SPI SS
#define ST25R_SS_PIN SPI_INSTANCE_3_NSS_PIN
#define ST25R_SS_PIN NFC_SPI_NSS_PIN
// GPIO port used for ST25R SPI SS port
#define ST25R_SS_PORT SPI_INSTANCE_3_NSS_PORT
#define ST25R_SS_PORT NFC_SPI_NSS_PORT
// GPIO pin used for ST25R External Interrupt
#define ST25R_INT_PIN NFC_INT_PIN
@ -73,12 +69,10 @@ extern "C" {
******************************************************************************
*/
#define platformProtectST25RComm() \
NVIC_DisableIRQ(EXTI10_IRQn) // TODO: PRobably should be irq_lock instead //
// Protect the unique access to communication
// channel (disable IRQ on single thread)
NVIC_DisableIRQ(NFC_EXTI_INTERRUPT_NUM)
#define platformUnprotectST25RComm() \
NVIC_EnableIRQ(EXTI10_IRQn) // TODO: Use macro here /
NVIC_EnableIRQ(NFC_EXTI_INTERRUPT_NUM)
#define platformProtectST25RIrqStatus() \
platformProtectST25RComm() /*!< Protect unique access to IRQ status var - \
@ -292,5 +286,3 @@ extern uint8_t globalCommProtectCnt; /* Global Protection Counter provided per
#ifdef __cplusplus
}
#endif
#endif /* RFAL_PLATFORM_H */

View File

@ -160,22 +160,24 @@
#define NRF_OUT_FW_RUNNING_PORT GPIOE
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
#define SPI_INSTANCE_3 SPI3
#define SPI_INSTANCE_3_PIN_AF GPIO_AF6_SPI3
#define SPI_INSTANCE_3_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
#define SPI_INSTANCE_3_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
#define SPI_INSTANCE_3_MISO_PORT GPIOB
#define SPI_INSTANCE_3_MISO_PIN GPIO_PIN_4
#define SPI_INSTANCE_3_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define SPI_INSTANCE_3_MOSI_PORT GPIOB
#define SPI_INSTANCE_3_MOSI_PIN GPIO_PIN_5
#define SPI_INSTANCE_3_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define SPI_INSTANCE_3_SCK_PORT GPIOG
#define SPI_INSTANCE_3_SCK_PIN GPIO_PIN_9
#define SPI_INSTANCE_3_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define SPI_INSTANCE_3_NSS_PORT GPIOG
#define SPI_INSTANCE_3_NSS_PIN GPIO_PIN_12
#define SPI_INSTANCE_3_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_SPI_INSTANCE SPI3
#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
#define NFC_SPI_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
#define NFC_SPI_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
#define NFC_SPI_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET
#define NFC_SPI_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET
#define NFC_SPI_MISO_PORT GPIOB
#define NFC_SPI_MISO_PIN GPIO_PIN_4
#define NFC_SPI_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define NFC_SPI_MOSI_PORT GPIOB
#define NFC_SPI_MOSI_PIN GPIO_PIN_5
#define NFC_SPI_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define NFC_SPI_SCK_PORT GPIOG
#define NFC_SPI_SCK_PIN GPIO_PIN_9
#define NFC_SPI_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_SPI_NSS_PORT GPIOG
#define NFC_SPI_NSS_PIN GPIO_PIN_12
#define NFC_SPI_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_INT_PIN GPIO_PIN_10
#define NFC_INT_PORT GPIOG

View File

@ -160,22 +160,24 @@
#define NRF_OUT_FW_RUNNING_PORT GPIOE
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
#define SPI_INSTANCE_3 SPI3
#define SPI_INSTANCE_3_PIN_AF GPIO_AF6_SPI3
#define SPI_INSTANCE_3_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
#define SPI_INSTANCE_3_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
#define SPI_INSTANCE_3_MISO_PORT GPIOB
#define SPI_INSTANCE_3_MISO_PIN GPIO_PIN_4
#define SPI_INSTANCE_3_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define SPI_INSTANCE_3_MOSI_PORT GPIOB
#define SPI_INSTANCE_3_MOSI_PIN GPIO_PIN_5
#define SPI_INSTANCE_3_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define SPI_INSTANCE_3_SCK_PORT GPIOG
#define SPI_INSTANCE_3_SCK_PIN GPIO_PIN_9
#define SPI_INSTANCE_3_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define SPI_INSTANCE_3_NSS_PORT GPIOG
#define SPI_INSTANCE_3_NSS_PIN GPIO_PIN_12
#define SPI_INSTANCE_3_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_SPI_INSTANCE SPI3
#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
#define NFC_SPI_CLK_EN __HAL_RCC_SPI3_CLK_ENABLE
#define NFC_SPI_CLK_DIS __HAL_RCC_SPI3_CLK_DISABLE
#define NFC_SPI_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET
#define NFC_SPI_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET
#define NFC_SPI_MISO_PORT GPIOB
#define NFC_SPI_MISO_PIN GPIO_PIN_4
#define NFC_SPI_MISO_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define NFC_SPI_MOSI_PORT GPIOB
#define NFC_SPI_MOSI_PIN GPIO_PIN_5
#define NFC_SPI_MOSI_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define NFC_SPI_SCK_PORT GPIOG
#define NFC_SPI_SCK_PIN GPIO_PIN_9
#define NFC_SPI_SCK_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_SPI_NSS_PORT GPIOG
#define NFC_SPI_NSS_PIN GPIO_PIN_12
#define NFC_SPI_NSS_CLK_EN __HAL_RCC_GPIOG_CLK_ENABLE
#define NFC_INT_PIN GPIO_PIN_10
#define NFC_INT_PORT GPIOG

View File

@ -792,3 +792,48 @@ wpc-update
# Updating STWLC38...
# WPC update completed 800 ms
```
### nfc-read-card
Activate the NFC in reader mode for a given time. Read general information from firstly discovered NFC tag or exits on timeout.
Example:
```
nfc-read-card <timeout_seconds>
# NFC activated in reader mode for <timeout_seconds> seconds.
# NFC card detected.
# NFC Type A: UID: %s
OK
```
### nfc-emulate-card
Activate NFC in Card Emulator mode for given time.
Example:
```
nfc-emulate-card <timeout_seconds>
# Emulation started for <timeout_seconds>
# Emulation over
OK
```
### nfc-write-card
Activates the NFC reader for given time. Writes the NDEF URI message into the first discovered NFC tag type A or exits on timeout.
Example:
```
nfc-write_card <timeout_seconds>
# NFC reader on, put the card on the reader (timeout <timeout_seconds> s)
# Writting URI to NFC tag 7AF403
OK
```

View File

@ -25,21 +25,8 @@
#include <rtl/cli.h>
#include <sys/systick.h>
static bool nfc_dev_activated = false;
static nfc_dev_info_t dev_info = {0};
static void nfc_activated_callback() {
nfc_dev_read_info(&dev_info);
nfc_dev_activated = true;
}
static void nfc_write_tag_callback() {
nfc_dev_info_t dev_info;
nfc_dev_read_info(&dev_info);
nfc_dev_activated = true;
}
static void prodtest_nfc_read_card(cli_t* cli) {
uint32_t timeout = 0;
memset(&dev_info, 0, sizeof(dev_info));
@ -55,31 +42,41 @@ static void prodtest_nfc_read_card(cli_t* cli) {
return;
}
nfc_dev_activated = false;
nfc_status_t ret = nfc_init();
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
cli_trace(cli, "NFC activated in reader mode for %d seconds.", timeout);
cli_trace(cli, "NFC activated in reader mode for %d ms.", timeout);
}
nfc_register_tech(NFC_POLLER_TECH_A | NFC_POLLER_TECH_B | NFC_POLLER_TECH_F |
NFC_POLLER_TECH_V);
nfc_register_event_callback(NFC_STATE_ACTIVATED, nfc_activated_callback);
nfc_activate_stm();
uint32_t tick = systick_ms();
nfc_event_t nfc_event = NFC_NO_EVENT;
while (!nfc_dev_activated) { // Todo, while timeout or device found
uint32_t expire_time = ticks_timeout(timeout);
if ((systick_ms() - tick) > (timeout * 1000)) {
while (true) {
if (ticks_expired(expire_time)) {
nfc_deinit();
cli_error(cli, CLI_ERROR_TIMEOUT, "NFC timeout");
return;
}
nfc_feed_worker();
nfc_event = nfc_get_event();
if(nfc_event == NFC_STATE_ACTIVATED) {
nfc_dev_read_info(&dev_info);
nfc_dev_deactivate();
break;
}
if (cli_aborted(cli)) {
return;
}
}
cli_trace(cli, "NFC card detected.");
@ -136,16 +133,21 @@ static void prodtest_nfc_emulate_card(cli_t* cli) {
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
cli_trace(cli, "Emulation started for %d seconds", timeout);
cli_trace(cli, "Emulation started for %d ms", timeout);
}
nfc_register_tech(NFC_CARD_EMU_TECH_A);
nfc_activate_stm();
uint32_t tick = systick_ms();
uint32_t expire_time = ticks_timeout(timeout);
while (!ticks_expired(expire_time)) {
nfc_get_event();
if (cli_aborted(cli)) {
return;
}
while ((systick_ms() - tick) < (timeout * 1000)) {
nfc_feed_worker();
}
cli_trace(cli, "Emulation over");
@ -170,41 +172,52 @@ static void prodtest_nfc_write_card(cli_t* cli) {
return;
}
nfc_dev_activated = false;
nfc_status_t ret = nfc_init();
if (ret != NFC_OK) {
cli_error(cli, CLI_ERROR_FATAL, "NFC init failed");
} else {
cli_trace(cli, "NFC reader on put the card on the reader (timeout %d s)",
cli_trace(cli, "NFC reader on, put the card on the reader (timeout %d ms)",
timeout);
}
nfc_register_tech(NFC_POLLER_TECH_A);
nfc_register_event_callback(NFC_STATE_ACTIVATED, nfc_write_tag_callback);
nfc_activate_stm();
uint32_t tick = systick_ms();
nfc_event_t nfc_event = NFC_NO_EVENT;
uint32_t expire_time = ticks_timeout(timeout);
while (!nfc_dev_activated) { // Todo, while timeout or device found
while (true) {
if ((systick_ms() - tick) > timeout * 1000) {
if (ticks_expired(expire_time)) {
nfc_deinit();
cli_error(cli, CLI_ERROR_TIMEOUT, "NFC timeout");
return;
}
nfc_feed_worker();
}
nfc_event = nfc_get_event();
if (nfc_event == NFC_STATE_ACTIVATED) {
if (dev_info.type != NFC_DEV_TYPE_A) {
cli_error(cli, CLI_ERROR, "Only NFC type A cards supported");
return;
}
nfc_dev_read_info(&dev_info);
cli_trace(cli, "Writting URI to NFC tag %s", dev_info.uid);
nfc_def_write_ndef_uri();
if (dev_info.type != NFC_DEV_TYPE_A) {
cli_error(cli, CLI_ERROR, "Only NFC type A cards supported");
return;
}
cli_trace(cli, "Writting URI to NFC tag %s", dev_info.uid);
nfc_dev_write_ndef_uri();
nfc_dev_deactivate();
break;
}
if (cli_aborted(cli)) {
return;
}
}
nfc_deinit();