M5Unit-NFC 0.1.2 git rev:63c4caa
Loading...
Searching...
No Matches
nfc_layer_a.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
17#ifndef M5_UNIT_NFC_NFC_LAYER_NFC_LAYER_A_HPP
18#define M5_UNIT_NFC_NFC_LAYER_NFC_LAYER_A_HPP
19
21#include "nfc/a/nfca.hpp"
22#include "nfc/isoDEP/isoDEP.hpp"
24#include "nfc/ndef/ndef.hpp"
25#include <vector>
26#include <memory>
27
28namespace m5 {
29
30namespace unit {
31class UnitMFRC522; // M5Unit-RFID
32class UnitWS1850S; // M5Unit-RFID
33class UnitST25R3916;
34class CapST25R3916;
35} // namespace unit
36
37namespace nfc {
38
44public:
45 struct Adapter;
47 explicit NFCLayerA(m5::unit::UnitMFRC522& u); // The implementation of this function is located in M5Unit-RFID
49 explicit NFCLayerA(m5::unit::UnitWS1850S& u); // The implementation of this function is located in M5Unit-RFID
54 virtual ~NFCLayerA();
55
58
67 virtual bool transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
68 const uint32_t timeout_ms) override;
69 // virtual bool transmit(const uint8_t* tx, const uint16_t tx_len, const uint32_t timeout_ms) override;
70 // virtual bool receive(uint8_t* rx, uint16_t& rx_len, const uint32_t timeout_ms) override;
75 virtual m5::nfc::NFCForumTag supportsNFCTag() const override;
80 virtual file_system_feature_t supportsFilesystem() const override;
85 virtual m5::nfc::isodep::IsoDEP* isoDEP() override
86 {
87 return &_isoDEP;
88 }
93 virtual uint16_t maximum_fifo_depth() const override;
95
101 inline bool isActive(const m5::nfc::a::PICC& picc) const
102 {
103 return _activePICC.valid() && _activePICC == picc;
104 }
111 {
112 return _activePICC;
113 }
119 {
120 return _cfg;
121 }
127 void config(const m5::nfc::a::config_t& cfg);
128
131
137 bool request(uint16_t& atqa);
144 bool wakeup(uint16_t& atqa);
145
155 bool detect(m5::nfc::a::PICC& picc, const uint32_t timeout_ms = 100U);
165 bool detect(std::vector<m5::nfc::a::PICC>& piccs, const uint32_t timeout_ms = 1000U);
175 bool select(m5::nfc::a::PICC& picc);
184 bool activate(const m5::nfc::a::PICC& picc, const bool force_rats = false);
192 bool reactivate(const m5::nfc::a::PICC& picc, const bool force_rats = false);
204 inline bool reactivate()
205 {
206 return reactivate(_activePICC);
207 }
209
212
218 bool deactivate();
219
231 bool identify(m5::nfc::a::PICC& picc);
232
240 bool read4(uint8_t rx[4], const uint8_t addr);
248 bool read16(uint8_t rx[16], const uint8_t addr);
259 bool read(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr,
260 const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY);
271 bool read(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr, const m5::nfc::a::mifare::plus::AESKey& key);
272
284 bool write4(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len, const bool safety = true);
296 bool write16(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len, const bool safety = true);
308 bool write(const uint8_t saddr, const uint8_t* tx, const uint16_t tx_len,
309 const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY);
320 bool write(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len,
322
329 bool dump(const m5::nfc::a::mifare::classic::Key& mkey = m5::nfc::a::mifare::classic::DEFAULT_KEY);
337 bool dump(const uint8_t block);
339
343
350 const uint8_t block, const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY);
358 const uint8_t block, const m5::nfc::a::mifare::classic::Key& key = m5::nfc::a::mifare::classic::DEFAULT_KEY);
359
389 bool mifareClassicReadAccessCondition(uint8_t& c123, const uint8_t block);
401 bool mifareClassicWriteAccessCondition(const uint8_t block, const uint8_t c123,
404
413 bool mifareClassicIsValueBlock(bool& is_value_block, const uint8_t block);
421 bool mifareClassicReadValueBlock(int32_t& value, const uint8_t block);
429 bool mifareClassicWriteValueBlock(const uint8_t block, const int32_t value);
441 bool mifareClassicDecrementValueBlock(const uint8_t block, const uint32_t delta, const bool transfer = true);
453 bool mifareClassicIncrementValueBlock(const uint8_t block, const uint32_t delta, const bool transfer = true);
461 bool mifareClassicTransferValueBlock(const uint8_t block);
469 bool mifareClassicRestoreValueBlock(const uint8_t block);
471
475
485
489
494 bool mifareUltralightCAuthenticate(const uint8_t key[16]);
496
500
514 const m5::nfc::a::mifare::plus::AESKey& card_config_key = m5::nfc::a::mifare::plus::DEFAULT_KEY,
515 const m5::nfc::a::mifare::plus::AESKey& card_master_key = m5::nfc::a::mifare::plus::DEFAULT_KEY,
516 const m5::nfc::a::mifare::plus::AESKey& l2_switch_key = m5::nfc::a::mifare::plus::DEFAULT_KEY,
517 const m5::nfc::a::mifare::plus::AESKey& l3_switch_key = m5::nfc::a::mifare::plus::DEFAULT_KEY,
518 const m5::nfc::a::mifare::plus::AESKey& aes_sector_key = m5::nfc::a::mifare::plus::DEFAULT_FF_KEY,
519 const m5::nfc::a::mifare::classic::Key& key_a = m5::nfc::a::mifare::classic::DEFAULT_KEY,
520 const m5::nfc::a::mifare::classic::Key& key_b = m5::nfc::a::mifare::classic::DEFAULT_KEY);
529 const m5::nfc::a::mifare::plus::AESKey& sl2_switch_key = m5::nfc::a::mifare::plus::DEFAULT_KEY);
538 const m5::nfc::a::mifare::plus::AESKey& l3_switch_key = m5::nfc::a::mifare::plus::DEFAULT_KEY);
539
541
545
550 bool ndefIsValidFormat(bool& valid);
561 bool ndefPrepareDesfire(const uint32_t max_ndef_size);
569 bool ndefRead(m5::nfc::ndef::TLV& msg);
577 bool ndefRead(std::vector<m5::nfc::ndef::TLV>& tlvs,
578 const m5::nfc::ndef::TagBits tagBits = m5::nfc::ndef::tagBitsAll);
587 bool ndefWrite(const m5::nfc::ndef::TLV& msg);
597 bool ndefWrite(const std::vector<m5::nfc::ndef::TLV>& tlvs);
599
600protected:
601 virtual bool read(uint8_t* rx, uint16_t& rx_len, const uint16_t saddr) override;
602 virtual bool write(const uint16_t saddr, const uint8_t* tx, const uint16_t tx_len) override;
603 inline virtual uint16_t first_user_block() const override
604 {
605 return _activePICC.firstUserBlock();
606 }
607 inline virtual uint16_t last_user_block() const override
608 {
609 return _activePICC.lastUserBlock();
610 }
611 inline virtual uint16_t user_area_size() const override
612 {
613 return _activePICC.userAreaSize();
614 }
615 inline virtual uint16_t unit_size_read() const override
616 {
617 return _activePICC.supportsNFC() ? (_activePICC.isMifareUltralight() ? 16 : 4) : 16;
618 }
619 inline virtual uint16_t unit_size_write() const override
620 {
621 return (_activePICC.supportsNFC()) ? 4 : 16;
622 }
623
624 bool identify_picc(m5::nfc::a::PICC& picc);
625 m5::nfc::a::Type identify_picc_st25ta();
626 uint8_t identify_plus_sl03();
627
628 bool read_using_fast(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr);
629 bool read_using_read16(uint8_t* rx, uint16_t& rx_len, const uint8_t saddr,
631 bool write_using_write4(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len);
632 bool write_using_write16(const uint8_t addr, const uint8_t* tx, const uint16_t tx_len,
634
635 bool nfca_request_ats(m5::nfc::a::ATS& ats, const uint8_t fsdi = 5, const uint8_t cid = 0);
636 bool nfca_deselect();
637
638 bool mifare_get_version_L3(uint8_t ver[8]);
639 bool mifare_get_version_L4_raw(uint8_t* ver, uint16_t& ver_len);
640 bool mifare_get_version_L4_wrapped(uint8_t* ver, uint16_t& ver_len);
641
642 bool mifare_plus_authenticateAES(const uint16_t key_no, const m5::nfc::a::mifare::plus::AESKey& key);
643 bool mifare_plus_authenticateAES_L3(const uint16_t key_no, const m5::nfc::a::mifare::plus::AESKey& key);
644 bool mifare_plus_read_plain_nomac(const uint16_t block, const uint8_t count, std::vector<uint8_t>& out);
645 bool mifare_plus_read_plain_mac(const uint16_t block, const uint8_t count, std::vector<uint8_t>& out);
646 bool mifare_plus_read_mac_l4(const uint16_t block, const uint8_t count, std::vector<uint8_t>& out,
647 const bool plain);
648 bool mifare_plus_write_mac_l4(const uint16_t block, const uint8_t* data, const uint16_t data_len, const bool plain);
649
650 bool mifare_classic_value_block(const m5::nfc::a::Command cmd, const uint8_t block, const uint32_t arg = 0);
651
652 bool mifare_ultralightC_authenticate1(uint8_t ek[8]);
653 bool mifare_ultralightC_authenticate2(uint8_t rx_ek[8], const uint8_t tx_ek[16]);
654
655 bool ntag_read_page(uint8_t* rx, uint16_t& rx_len, const uint8_t spage, const uint8_t epage);
656 bool ntag_write_page(const uint8_t page, const uint8_t tx[4]); // NTAG,UL,ULC
657
658 bool dump_sector_structure(const m5::nfc::a::PICC& picc, const m5::nfc::a::mifare::classic::Key& key);
659 bool dump_sector(const uint8_t sector);
660 bool dump_sector_mifare_plus_sl3(const uint8_t sector);
661 bool dump_page_structure(const uint16_t maxPage);
662 bool dump_page(const uint8_t page, const uint16_t maxPage);
663 bool dump_mifare_plus_sl3(const m5::nfc::a::mifare::plus::AESKey& key);
664 bool dump_desfire();
665 bool dump_desfire_light();
666 bool dump_st25ta();
667
668 static bool push_back_picc(std::vector<m5::nfc::a::PICC>& v, const m5::nfc::a::PICC& picc);
669
670protected:
671 m5::nfc::a::PICC _activePICC{};
675
676private:
677 bool mifare_plus_transceive_raw(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len);
678
679 // Session state for MIFARE Plus
680 struct MifarePlusSession {
681 bool authenticated{};
682 uint16_t key_no{};
683 uint16_t r_ctr{};
684 uint16_t w_ctr{};
685 uint8_t frame_num{};
686 std::array<uint8_t, 4> ti{};
687 std::array<uint8_t, 16> kenc{};
688 std::array<uint8_t, 16> kmac{};
689 };
690
691 MifarePlusSession _mfp_session{};
692 std::unique_ptr<Adapter> _impl;
693};
694
696// Impl for units
697struct NFCLayerA::Adapter {
698 virtual ~Adapter() = default;
699
700 virtual uint16_t max_fifo_depth() const = 0;
701
702 virtual bool transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
703 const uint32_t timeout_ms) = 0;
704
705 virtual bool request(uint16_t& atqa) = 0;
706 virtual bool wakeup(uint16_t& atqa) = 0;
707
708 virtual bool select(m5::nfc::a::PICC& picc) = 0;
709 virtual bool activate(const m5::nfc::a::PICC& picc) = 0;
710 virtual bool hlt() = 0;
711
712 virtual bool nfca_read_block(uint8_t rx[16], const uint8_t addr) = 0;
713 virtual bool nfca_write_block(const uint8_t addr, const uint8_t tx[16]) = 0;
714 virtual bool mifare_classic_authenticate(const bool auth_a, const m5::nfc::a::PICC& picc, const uint8_t block,
715 const m5::nfc::a::mifare::classic::Key& key) = 0;
716 virtual bool mifare_classic_value_block(const m5::nfc::a::Command cmd, const uint8_t block,
717 const uint32_t arg = 0) = 0;
718};
720
721} // namespace nfc
722} // namespace m5
723
724#endif
Common interface layer for each chip of the NFC-A reader.
Definition nfc_layer_a.hpp:43
bool dump(const m5::nfc::a::mifare::classic::Key &mkey=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Dump all blocks/files.
Definition nfc_layer_a.cpp:920
bool mifareClassicTransferValueBlock(const uint8_t block)
Transfer inner buffer value to block.
Definition nfc_layer_a.cpp:1118
bool request(uint16_t &atqa)
Send REQA to discover a PICC in IDLE.
Definition nfc_layer_a.cpp:202
virtual uint16_t first_user_block() const override
First user block.
Definition nfc_layer_a.hpp:603
bool mifareClassicReadValueBlock(int32_t &value, const uint8_t block)
Read the specific block as the value block.
Definition nfc_layer_a.cpp:1064
bool mifareClassicIsValueBlock(bool &is_value_block, const uint8_t block)
Is specific block the value block?
Definition nfc_layer_a.cpp:1032
bool detect(m5::nfc::a::PICC &picc, const uint32_t timeout_ms=100U)
Detect single idle PICC.
Definition nfc_layer_a.cpp:214
NFCLayerA(m5::unit::UnitMFRC522 &u)
Constructor with UnitMFRC522 (M5Unit-RFID)
bool mifarePlusUpgradeSecurityLevel2(const m5::nfc::a::mifare::plus::AESKey &sl2_switch_key=m5::nfc::a::mifare::plus::DEFAULT_KEY)
Upgrade security level to SL2 (AES over CRYPTO1)
Definition nfc_layer_a.cpp:1326
bool mifarePlusUpgradeSecurityLevel1(const m5::nfc::a::mifare::plus::AESKey &card_config_key=m5::nfc::a::mifare::plus::DEFAULT_KEY, const m5::nfc::a::mifare::plus::AESKey &card_master_key=m5::nfc::a::mifare::plus::DEFAULT_KEY, const m5::nfc::a::mifare::plus::AESKey &l2_switch_key=m5::nfc::a::mifare::plus::DEFAULT_KEY, const m5::nfc::a::mifare::plus::AESKey &l3_switch_key=m5::nfc::a::mifare::plus::DEFAULT_KEY, const m5::nfc::a::mifare::plus::AESKey &aes_sector_key=m5::nfc::a::mifare::plus::DEFAULT_FF_KEY, const m5::nfc::a::mifare::classic::Key &key_a=m5::nfc::a::mifare::classic::DEFAULT_KEY, const m5::nfc::a::mifare::classic::Key &key_b=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Upgrade security level to SL1 (Classic compatibility mode)
Definition nfc_layer_a.cpp:1236
bool write(const uint8_t saddr, const uint8_t *tx, const uint16_t tx_len, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Write any bytes to user area.
Definition nfc_layer_a.cpp:760
bool isActive(const m5::nfc::a::PICC &picc) const
Is the specified PICC currently active?
Definition nfc_layer_a.hpp:101
virtual uint16_t last_user_block() const override
Last user block.
Definition nfc_layer_a.hpp:607
virtual file_system_feature_t supportsFilesystem() const override
Supported file system features.
Definition nfc_layer_a.cpp:197
bool activate(const m5::nfc::a::PICC &picc, const bool force_rats=false)
Activate a specific PICC (anti-collision against the given PICC)
Definition nfc_layer_a.cpp:284
bool mifareUltralightCAuthenticate(const uint8_t key[16])
Authentication for MIFARE UltralightC.
Definition nfc_layer_a.cpp:1158
bool mifareUltralightChangeFormatToNDEF()
Write change to NFC Type-2 (NDEF) format for MIFARE Ultralight/C.
Definition nfc_layer_a.cpp:1128
bool ndefPrepareDesfire(const uint32_t max_ndef_size)
Prepare NDEF files on MIFARE DESFire (EV1/EV2/EV3)
Definition nfc_layer_a.cpp:1376
bool mifareClassicWriteValueBlock(const uint8_t block, const int32_t value)
Write the specific block as the value block.
Definition nfc_layer_a.cpp:1091
bool ndefIsValidFormat(bool &valid)
Is the PICC data in NDEF format?
Definition nfc_layer_a.cpp:1362
bool select(m5::nfc::a::PICC &picc)
Select a PICC (anti-collision + SELECT cascade to ACTIVE)
Definition nfc_layer_a.cpp:269
virtual m5::nfc::isodep::IsoDEP * isoDEP() override
Get ISO-DEP context.
Definition nfc_layer_a.hpp:85
bool read16(uint8_t rx[16], const uint8_t addr)
Read the 1 block / 4 page (16 bytes)
Definition nfc_layer_a.cpp:534
NFCLayerA(m5::unit::UnitWS1850S &u)
Constructor with UnitWS1850S (M5Unit-RFID)
bool mifareClassicDecrementValueBlock(const uint8_t block, const uint32_t delta, const bool transfer=true)
Decrement value of the value block.
Definition nfc_layer_a.cpp:1102
const m5::nfc::a::PICC & activatedPICC() const
Retrieve the currently activated PICC.
Definition nfc_layer_a.hpp:110
bool ndefRead(m5::nfc::ndef::TLV &msg)
Read NDEF Message TLV.
Definition nfc_layer_a.cpp:1384
bool write4(const uint8_t addr, const uint8_t *tx, const uint16_t tx_len, const bool safety=true)
Write the 1 page (4 bytes)
Definition nfc_layer_a.cpp:712
bool reactivate()
Reactivate the previously selected PICC.
Definition nfc_layer_a.hpp:204
virtual uint16_t unit_size_read() const override
Unit size for read.
Definition nfc_layer_a.hpp:615
bool identify(m5::nfc::a::PICC &picc)
Identify the specified PICC type.
Definition nfc_layer_a.cpp:341
m5::nfc::a::config_t config() const
Get the NFC-A activation configuration.
Definition nfc_layer_a.hpp:118
bool read4(uint8_t rx[4], const uint8_t addr)
Read the 1 page.
Definition nfc_layer_a.cpp:516
bool mifareClassicAuthenticateB(const uint8_t block, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Authentication by KeyB for MIFARE classic.
Definition nfc_layer_a.cpp:965
bool deactivate()
Send HLTA to the currently selected PICC (deactivate)
Definition nfc_layer_a.cpp:326
bool mifareClassicWriteAccessCondition(const uint8_t block, const uint8_t c123, const m5::nfc::a::mifare::classic::Key &akey, const m5::nfc::a::mifare::classic::Key &bkey)
Write the specific block access conditions.
Definition nfc_layer_a.cpp:996
virtual m5::nfc::NFCForumTag supportsNFCTag() const override
Supported NFC Forum tag type.
Definition nfc_layer_a.cpp:192
bool ndefPrepareDesfireLight()
Prepare NDEF files on MIFARE DESFire Light.
Definition nfc_layer_a.cpp:1368
bool mifareClassicAuthenticateA(const uint8_t block, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Authentication by KeyA for MIFARE classic.
Definition nfc_layer_a.cpp:960
bool ndefWrite(const m5::nfc::ndef::TLV &msg)
Write NDEF message.
Definition nfc_layer_a.cpp:1401
virtual uint16_t unit_size_write() const override
Unit size for write.
Definition nfc_layer_a.hpp:619
bool mifarePlusUpgradeSecurityLevel3(const m5::nfc::a::mifare::plus::AESKey &l3_switch_key=m5::nfc::a::mifare::plus::DEFAULT_KEY)
Upgrade security level to SL3 (AES)
Definition nfc_layer_a.cpp:1344
virtual uint16_t maximum_fifo_depth() const override
Maximum FIFO depth in bytes.
Definition nfc_layer_a.cpp:187
bool mifareClassicReadAccessCondition(uint8_t &c123, const uint8_t block)
Read the specific block access conditions.
Definition nfc_layer_a.cpp:970
virtual uint16_t user_area_size() const override
User area size (bytes)
Definition nfc_layer_a.hpp:611
bool mifareClassicRestoreValueBlock(const uint8_t block)
Restore block value to inner buffer.
Definition nfc_layer_a.cpp:1123
bool read(uint8_t *rx, uint16_t &rx_len, const uint8_t saddr, const m5::nfc::a::mifare::classic::Key &key=m5::nfc::a::mifare::classic::DEFAULT_KEY)
Read any bytes from user area.
Definition nfc_layer_a.cpp:542
bool wakeup(uint16_t &atqa)
Send WUPA to wake a PICC from IDLE or HALT.
Definition nfc_layer_a.cpp:207
bool write16(const uint8_t addr, const uint8_t *tx, const uint16_t tx_len, const bool safety=true)
Write the 1 block / 4 page (16 bytes)
Definition nfc_layer_a.cpp:728
virtual bool transceive(uint8_t *rx, uint16_t &rx_len, const uint8_t *tx, const uint16_t tx_len, const uint32_t timeout_ms) override
Transceive (NFC-A)
Definition nfc_layer_a.cpp:181
bool mifareClassicIncrementValueBlock(const uint8_t block, const uint32_t delta, const bool transfer=true)
Increment value of the value block.
Definition nfc_layer_a.cpp:1110
Common interface for NFC layer.
Definition nfc_layer.hpp:26
ISO Data Exchange Protocol.
Definition isoDEP.hpp:240
NDEF operations layer.
Definition ndef_layer.hpp:35
NDEF TLV container.
Definition ndef_tlv.hpp:27
ST25R3916 unit in CapCC1101 (SPI)
Definition unit_ST25R3916.hpp:2150
ST25R3916 Unit.
Definition unit_ST25R3916.hpp:39
ISO Data Exchange Protocol.
std::array< uint8_t, 16 > AESKey
MIFARE Plus SL2/3 Key (AES)
Definition mifare.hpp:278
std::array< uint8_t, 6 > Key
MIFARE classic Key.
Definition mifare.hpp:50
Top level namespace of M5Stack.
NFC related definitions.
Unit-related namespace.
NFC-V definitions.
NDEF related.
uint8_t TagBits
TLV(Tag,Length,Value) tag bit group for type2/5.
Definition ndef.hpp:56
Common layer for NDEF related.
uint8_t file_system_feature_t
Alias for file_system_feature_t.
Definition nfc.hpp:62
NFCForumTag
NFC Forum Tag Type.
Definition nfc.hpp:39
Common layer for NFC related units.
NFC-A definitions.
Command
ISO-14443-3/4,MIFARE,NTAG commands.
Definition nfca.hpp:684
Type
Type of the PICC.
Definition nfca.hpp:31
Answer to request.
Definition nfca.hpp:394
PICC for NFC-A.
Definition nfca.hpp:481
uint16_t userAreaSize() const
Total user area size.
Definition nfca.hpp:604
bool supportsNFC() const
Supports NFC?
Definition nfca.hpp:633
uint16_t lastUserBlock() const
Total size.
Definition nfca.hpp:619
bool valid() const
Valid?
Definition nfca.hpp:502
uint16_t firstUserBlock() const
Gets the first user block/page address.
Definition nfca.hpp:615
bool isMifareUltralight() const
Is MIFARE Ultralight series?
Definition nfca.hpp:539
NFC-A activation configuration (RATS parameters)
Definition nfca.hpp:732