M5Unit-NFC 0.0.3 git rev:59f5362
Loading...
Searching...
No Matches
nfc_layer_f.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
16#ifndef M5_UNIT_NFC_NFC_LAYER_NFC_LAYER_F_HPP
17#define M5_UNIT_NFC_NFC_LAYER_NFC_LAYER_F_HPP
18
20#include "nfc/f/nfcf.hpp"
22#include <vector>
23#include <memory>
24
25namespace m5 {
26namespace unit {
27class UnitST25R3916;
28class CapST25R3916;
29} // namespace unit
30
31namespace nfc {
32
38public:
39 struct Adapter;
42
43 virtual uint16_t maximum_fifo_depth() const override;
44
50 inline bool isActive(const m5::nfc::f::PICC& picc) const
51 {
52 return _activePICC.valid() && _activePICC == picc;
53 }
60 {
61 return _activePICC;
62 }
63
66
75 bool polling(m5::nfc::f::PICC& picc, const uint16_t system_code, const m5::nfc::f::RequestCode request_code,
76 const m5::nfc::f::TimeSlot time_slot);
77
85 bool detect(m5::nfc::f::PICC& picc, const uint32_t timeout_ms = 100U);
94 inline bool detect(std::vector<m5::nfc::f::PICC>& piccs,
95 m5::nfc::f::TimeSlot time_slot = m5::nfc::f::TimeSlot::Slot16, const uint32_t timeout_ms = 500U)
96 {
97 return detect(piccs, nullptr, 0, time_slot, timeout_ms);
98 }
109 inline bool detect(std::vector<m5::nfc::f::PICC>& piccs, const uint16_t private_code,
110 m5::nfc::f::TimeSlot time_slot = m5::nfc::f::TimeSlot::Slot16, const uint32_t timeout_ms = 500U)
111 {
112 return detect(piccs, &private_code, 1, time_slot, timeout_ms);
113 }
126 bool detect(std::vector<m5::nfc::f::PICC>& piccs, const uint16_t* private_code, const uint8_t pc_size,
127 m5::nfc::f::TimeSlot time_slot = m5::nfc::f::TimeSlot::Slot16, const uint32_t timeout_ms = 500U);
128
135 bool activate(const m5::nfc::f::PICC& picc);
142 inline bool reactivate(const m5::nfc::f::PICC& picc)
143 {
144 return activate(picc);
145 }
147
150
155 bool deactivate();
156
164 bool requestService(uint16_t& key_version, const uint16_t node_code);
173 bool requestService(uint16_t key_version[], const uint16_t* node_code, const uint8_t node_num);
174
182 {
183 return _activePICC.valid() && request_response_impl(_activePICC, mode);
184 }
185
193 bool requestSystemCode(uint16_t code_list[255], uint8_t& code_num);
194
200 bool dump();
207 bool dump(const m5::nfc::f::block_t block);
209
212
219 inline bool read16(uint8_t rx[16], const m5::nfc::f::block_t block,
220 const uint16_t service_code = m5::nfc::f::service_random_read)
221 {
222 return read16(rx, &block, 1, service_code);
223 }
233 bool read16(uint8_t rx[16], const m5::nfc::f::block_t* block, const uint8_t block_num,
234 const uint16_t service_code = m5::nfc::f::service_random_read);
235
245 bool read(uint8_t* rx, uint16_t& rx_len, const m5::nfc::f::block_t sblock);
246
258 inline bool read(uint8_t* rx, uint16_t& rx_len, const m5::nfc::f::block_t* block_list, const uint8_t block_num,
259 const uint16_t* service_code, const uint8_t service_num)
260 {
261 return _activePICC.valid() &&
262 read_without_encryption_impl(rx, rx_len, block_list, block_num, service_code, service_num, _activePICC);
263 }
264
274 bool write16(const m5::nfc::f::block_t block, const uint8_t tx[16], const uint16_t tx_len);
283 bool write(const m5::nfc::f::block_t sblock, const uint8_t* tx, const uint16_t tx_len);
284
290 bool clearSPAD();
291
293
297
304 bool internalAuthenticate(const uint8_t ck[16], const uint16_t ckv, const uint8_t rc[16]);
311 bool externalAuthenticate(const uint8_t ck[16], const uint16_t ckv);
312
314 {
315 _authenticated = false;
316 }
317
325 bool readWithMAC16(uint8_t rx[16], const m5::nfc::f::block_t block);
326
336 bool writeWithMAC16(const m5::nfc::f::block_t block, const uint8_t tx[16], const uint16_t tx_len);
338
342
347 bool ndefIsValidFormat(bool& valid);
355 bool ndefRead(m5::nfc::ndef::TLV& msg);
363 bool ndefWrite(const m5::nfc::ndef::TLV& msg);
364
371 bool writeSupportNDEF(const bool enabled);
373
374protected:
375 virtual bool read(uint8_t* rx, uint16_t& rx_len, const uint16_t saddr) override;
376 virtual bool write(const uint16_t saddr, const uint8_t* tx, const uint16_t tx_len) override;
377 inline virtual uint16_t first_user_block() const override
378 {
379 return _activePICC.firstUserBlock();
380 }
381 inline virtual uint16_t last_user_block() const override
382 {
383 return _activePICC.lastUserBlock();
384 }
385 inline virtual uint16_t user_area_size() const
386 {
387 return _activePICC.userAreaSize();
388 }
389 inline virtual uint16_t unit_size_read() const override
390 {
391 return 16;
392 }
393 inline virtual uint16_t unit_size_write() const override
394 {
395 return 16;
396 }
397 inline virtual uint8_t maximum_read_blocks() const override
398 {
399 return _activePICC.maximumReadBlocks();
400 }
401 inline virtual uint8_t maximum_write_blocks() const override
402 {
403 return _activePICC.maximumWriteBlocks();
404 }
405
406 bool request_response_impl(const m5::nfc::f::PICC& picc, m5::nfc::f::standard::Mode& mode);
407 bool read_without_encryption_impl(uint8_t* rx, uint16_t& rx_len, const m5::nfc::f::block_t* block_list,
408 const uint8_t block_num, const uint16_t* service_code, const uint8_t service_num,
409 const m5::nfc::f::PICC& picc);
410 bool write_without_encryption_impl(const m5::nfc::f::PICC& picc, const m5::nfc::f::block_t* block_list,
411 const uint8_t block_num, const uint16_t* service_code, const uint8_t service_num,
412 const uint8_t* tx, const uint16_t tx_len);
413
414 bool dump_felica_lite();
415 bool dump_felica_lite_s();
416 bool dump_block(m5::nfc::f::block_t block);
417
418 bool internal_authenticate_lite_s(const uint8_t ck[16], const uint16_t ckv, const uint8_t rc[16],
419 const bool include_wcnt = false);
420 bool external_authenticate_lite_s(const uint8_t ck[16], const uint16_t ckv);
421
422protected:
423 m5::nfc::f::PICC _activePICC{};
424
425private:
426 std::unique_ptr<Adapter> _impl;
428 union {
429 uint8_t _sk[16]{};
430 struct {
431 uint8_t _sk1[8];
432 uint8_t _sk2[8];
433 };
434 };
435 uint8_t _rc[16]{};
436 bool _authenticated{};
437};
438
440// Impl for units
441struct NFCLayerF::Adapter {
442 virtual ~Adapter() = default;
443
444 virtual uint16_t max_fifo_depth() const = 0;
445 virtual bool transceive(uint8_t* rx, uint16_t& rx_len, const uint8_t* tx, const uint16_t tx_len,
446 const uint32_t timeout_ms) = 0;
447};
449
450} // namespace nfc
451} // namespace m5
452#endif
Common interface layer for each chip of the NFC-F reader.
Definition nfc_layer_f.hpp:37
bool read16(uint8_t rx[16], const m5::nfc::f::block_t block, const uint16_t service_code=m5::nfc::f::service_random_read)
Read the 1 block with service code.
Definition nfc_layer_f.hpp:219
bool ndefWrite(const m5::nfc::ndef::TLV &msg)
Write NDEF message TLV.
Definition nfc_layer_f.cpp:783
bool requestService(uint16_t &key_version, const uint16_t node_code)
Request service.
Definition nfc_layer_f.cpp:311
bool requestResponse(m5::nfc::f::standard::Mode &mode)
Request response.
Definition nfc_layer_f.hpp:181
bool read(uint8_t *rx, uint16_t &rx_len, const m5::nfc::f::block_t sblock)
Read any bytes from user area.
Definition nfc_layer_f.cpp:494
virtual uint16_t first_user_block() const override
First user block.
Definition nfc_layer_f.hpp:377
bool writeWithMAC16(const m5::nfc::f::block_t block, const uint8_t tx[16], const uint16_t tx_len)
Write the 1 block.
Definition nfc_layer_f.cpp:684
virtual uint16_t unit_size_read() const override
Unit size for read.
Definition nfc_layer_f.hpp:389
virtual uint8_t maximum_read_blocks() const override
Maximum read blocks for NFC-F.
Definition nfc_layer_f.hpp:397
bool detect(std::vector< m5::nfc::f::PICC > &piccs, m5::nfc::f::TimeSlot time_slot=m5::nfc::f::TimeSlot::Slot16, const uint32_t timeout_ms=500U)
Detect PICCs.
Definition nfc_layer_f.hpp:94
virtual uint16_t maximum_fifo_depth() const override
Maximum FIFO depth.
Definition nfc_layer_f.cpp:82
bool readWithMAC16(uint8_t rx[16], const m5::nfc::f::block_t block)
Read the 1 block.
Definition nfc_layer_f.cpp:546
bool dump()
Dump all blocks.
Definition nfc_layer_f.cpp:814
virtual uint16_t unit_size_write() const override
Unit size for write.
Definition nfc_layer_f.hpp:393
bool isActive(const m5::nfc::f::PICC &picc) const
Is the specified PICC currently active?
Definition nfc_layer_f.hpp:50
bool detect(std::vector< m5::nfc::f::PICC > &piccs, const uint16_t private_code, m5::nfc::f::TimeSlot time_slot=m5::nfc::f::TimeSlot::Slot16, const uint32_t timeout_ms=500U)
Detect PICCs matching the specified system code.
Definition nfc_layer_f.hpp:109
bool reactivate(const m5::nfc::f::PICC &picc)
Activate a specific PICC.
Definition nfc_layer_f.hpp:142
virtual uint16_t last_user_block() const override
Last user block.
Definition nfc_layer_f.hpp:381
bool detect(m5::nfc::f::PICC &picc, const uint32_t timeout_ms=100U)
Detect single PICC.
Definition nfc_layer_f.cpp:121
bool deactivate()
Deactivate PICC.
Definition nfc_layer_f.cpp:304
bool clearSPAD()
Clear SPAD_0 - 13.
Definition nfc_layer_f.cpp:739
void clearAuthenticate()
Internal authentication.
Definition nfc_layer_f.hpp:313
bool ndefRead(m5::nfc::ndef::TLV &msg)
Read NDEF Message TLV.
Definition nfc_layer_f.cpp:771
virtual uint16_t user_area_size() const
User area size (bytes)
Definition nfc_layer_f.hpp:385
bool externalAuthenticate(const uint8_t ck[16], const uint16_t ckv)
External authentication.
Definition nfc_layer_f.cpp:753
bool write(const m5::nfc::f::block_t sblock, const uint8_t *tx, const uint16_t tx_len)
Write any bytes to user area.
Definition nfc_layer_f.cpp:618
virtual uint8_t maximum_write_blocks() const override
Maximum write blocks for NFC-F.
Definition nfc_layer_f.hpp:401
bool activate(const m5::nfc::f::PICC &picc)
Activate a specific PICC.
Definition nfc_layer_f.cpp:294
bool writeSupportNDEF(const bool enabled)
Write changes for NDEF Support.
Definition nfc_layer_f.cpp:789
bool ndefIsValidFormat(bool &valid)
Is the PICC data in NDEF format?
Definition nfc_layer_f.cpp:765
bool internalAuthenticate(const uint8_t ck[16], const uint16_t ckv, const uint8_t rc[16])
Internal authentication.
Definition nfc_layer_f.cpp:745
const m5::nfc::f::PICC & activatedPICC() const
Retrieve the currently activated PICC.
Definition nfc_layer_f.hpp:59
bool polling(m5::nfc::f::PICC &picc, const uint16_t system_code, const m5::nfc::f::RequestCode request_code, const m5::nfc::f::TimeSlot time_slot)
Polling.
Definition nfc_layer_f.cpp:87
bool read(uint8_t *rx, uint16_t &rx_len, const m5::nfc::f::block_t *block_list, const uint8_t block_num, const uint16_t *service_code, const uint8_t service_num)
Read the specified block list and service codes.
Definition nfc_layer_f.hpp:258
bool requestSystemCode(uint16_t code_list[255], uint8_t &code_num)
Request system code.
Definition nfc_layer_f.cpp:397
bool write16(const m5::nfc::f::block_t block, const uint8_t tx[16], const uint16_t tx_len)
Write the 1 block.
Definition nfc_layer_f.cpp:608
Common interface for NFC layer.
Definition nfc_layer.hpp:26
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:2062
ST25R3916 Unit.
Definition unit_ST25R3916.hpp:38
Top level namespace of M5stack.
NFC related definitions.
Unit-related namespace.
Common layer for NDEF related.
Common layer for NFC related units.
NFC-F definitions.
TimeSlot
Timeslot value for Polling.
Definition nfcf.hpp:107
Mode
Mode for Standard.
Definition nfcf.hpp:236
RequestCode
Request code for Polling.
Definition nfcf.hpp:97
PICC information for NFC-F.
Definition nfcf.hpp:381
uint16_t userAreaSize() const
Total user area size.
Definition nfcf.hpp:403
uint16_t lastUserBlock() const
Gets the last user block.
Definition nfcf.hpp:413
uint8_t maximumWriteBlocks() const
Maximum number of blocks that can be write simultaneously.
Definition nfcf.hpp:429
uint16_t firstUserBlock() const
Gets the first user block.
Definition nfcf.hpp:408
uint8_t maximumReadBlocks() const
Maximum number of blocks that can be read simultaneously.
Definition nfcf.hpp:424
bool valid() const
Valid for detection?
Definition nfcf.cpp:310
Block list element.
Definition nfcf.hpp:147