Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce NFC driver with RFAL middleware #4566

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/SConscript.prodtest
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)

FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "usb", "consumption_mask", "optiga", "haptic"]
FEATURES_WANTED = ["input", "sbu", "nfc", "sd_card", "rgb_led", "usb", "consumption_mask", "optiga", "haptic"]

CCFLAGS_MOD = ''
CPPPATH_MOD = []
Expand Down Expand Up @@ -108,6 +108,7 @@ SOURCE_PRODTEST = [
'embed/projects/prodtest/cmd/prodtest_get_cpuid.c',
'embed/projects/prodtest/cmd/prodtest_haptic.c',
'embed/projects/prodtest/cmd/prodtest_help.c',
'embed/projects/prodtest/cmd/prodtest_nfc.c',
'embed/projects/prodtest/cmd/prodtest_optiga.c',
'embed/projects/prodtest/cmd/prodtest_otp_batch.c',
'embed/projects/prodtest/cmd/prodtest_otp_variant.c',
Expand Down
104 changes: 104 additions & 0 deletions core/embed/io/nfc/inc/io/nfc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* 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/>.
*/

#ifndef TREZORHAL_NFC_H
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved
#define TREZORHAL_NFC_H

#include <trezor_bsp.h>
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved
#include <trezor_rtl.h>
#include "ndef.h"
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved

#define NFC_MAX_UID_LEN 10

typedef enum {
NFC_POLLER_TECH_A = 0x1,
NFC_POLLER_TECH_B = 0x1 << 1,
NFC_POLLER_TECH_F = 0x1 << 2,
NFC_POLLER_TECH_V = 0x1 << 3,
NFC_CARD_EMU_TECH_A = 0x1 << 4,
NFC_CARD_EMU_TECH_F = 0x1 << 5,
} nfc_tech_t;

typedef enum {
NFC_DEV_TYPE_A,
NFC_DEV_TYPE_B,
NFC_DEV_TYPE_F,
NFC_DEV_TYPE_V,
NFC_DEV_TYPE_ST25TB,
NFC_DEV_TYPE_AP2P,
NFC_DEV_TYPE_UNKNOWN,
} nfc_dev_type_t;

typedef enum {
NFC_STATE_IDLE,
NFC_STATE_ACTIVATED,
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved
} nfc_event_t;

typedef enum {
NFC_OK,
NFC_ERROR,
NFC_NOT_INITIALIZED,
NFC_SPI_BUS_ERROR,
NFC_INITIALIZATION_FAILED,
} nfc_status_t;

typedef struct {
uint8_t type;
char uid[NFC_MAX_UID_LEN];
uint8_t uid_len;
} nfc_dev_info_t;

// Initialize NFC driver including supportive RFAL middlewere
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved
nfc_status_t nfc_init();
cepetr marked this conversation as resolved.
Show resolved Hide resolved

// Deinitialize NFC drive
nfc_status_t nfc_deinit();

// 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);

// 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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we use different approach, which is polling for events and i think we should keep the same style here. So instead of this register function and nfc_feed_worker, the api would have single nfc_get_event (see i.e. ble_get_event for reference), which would internally call nfc_feed_worker. Internally, you could put the events into <util/tsqueue.h> if there is a need to store multiple events.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is bit more complex in NFC case, because optimally you want to make an user action in the middle of the rfal worker process right after device get discovered and deactivate the device at the end of the same routine. But I think i managed to refactor that in d0ecd9f by pulling out the deactivate function to nfc lib api. Thanks for double checking!

void (*cb_fn)(void));

// Activate the NFC RFAL state machine which will explore the registered
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved
// 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();

// Deactivate the NFC RFAL state machine (put in IDLE state).
nfc_status_t nfc_deactivate_stm();

// 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();

// 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
458 changes: 458 additions & 0 deletions core/embed/io/nfc/rfal/doc/Release_Notes.html

Large diffs are not rendered by default.

Loading
Loading