ESPHome 2026.2.1
Loading...
Searching...
No Matches
nfc.h
Go to the documentation of this file.
1#pragma once
2
4#include "esphome/core/log.h"
5#include "ndef_message.h"
6#include "ndef_record.h"
7#include "nfc_tag.h"
8
9#include <span>
10#include <vector>
11
12namespace esphome {
13namespace nfc {
14
15static const uint8_t MIFARE_CLASSIC_BLOCK_SIZE = 16;
16static const uint8_t MIFARE_CLASSIC_LONG_TLV_SIZE = 4;
17static const uint8_t MIFARE_CLASSIC_SHORT_TLV_SIZE = 2;
18static const uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW = 4;
19static const uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_HIGH = 16;
20static const uint8_t MIFARE_CLASSIC_16BLOCK_SECT_START = 32;
21
22static const uint8_t MIFARE_ULTRALIGHT_PAGE_SIZE = 4;
23static const uint8_t MIFARE_ULTRALIGHT_READ_SIZE = 4;
24static const uint8_t MIFARE_ULTRALIGHT_DATA_START_PAGE = 4;
25static const uint8_t MIFARE_ULTRALIGHT_MAX_PAGE = 63;
26
27static const uint8_t TAG_TYPE_MIFARE_CLASSIC = 0;
28static const uint8_t TAG_TYPE_1 = 1;
29static const uint8_t TAG_TYPE_2 = 2;
30static const uint8_t TAG_TYPE_3 = 3;
31static const uint8_t TAG_TYPE_4 = 4;
32static const uint8_t TAG_TYPE_UNKNOWN = 99;
33
34// Mifare Commands
35static const uint8_t MIFARE_CMD_AUTH_A = 0x60;
36static const uint8_t MIFARE_CMD_AUTH_B = 0x61;
37static const uint8_t MIFARE_CMD_HALT = 0x50;
38static const uint8_t MIFARE_CMD_READ = 0x30;
39static const uint8_t MIFARE_CMD_WRITE = 0xA0;
40static const uint8_t MIFARE_CMD_WRITE_ULTRALIGHT = 0xA2;
41
42// Mifare Ack/Nak
43static const uint8_t MIFARE_CMD_ACK = 0x0A;
44static const uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_VALID = 0x00;
45static const uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_VALID = 0x01;
46static const uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_INVALID = 0x04;
47static const uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_INVALID = 0x05;
48
49static const char *const MIFARE_CLASSIC = "Mifare Classic";
50static const char *const NFC_FORUM_TYPE_2 = "NFC Forum Type 2";
51static const char *const ERROR = "Error";
52
53static const uint8_t DEFAULT_KEY[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
54static const uint8_t NDEF_KEY[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
55static const uint8_t MAD_KEY[6] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
56
58static constexpr size_t FORMAT_UID_BUFFER_SIZE = 30;
60char *format_uid_to(char *buffer, std::span<const uint8_t> uid);
61
63static constexpr size_t FORMAT_BYTES_BUFFER_SIZE = 192;
65char *format_bytes_to(char *buffer, std::span<const uint8_t> bytes);
66
67// Remove before 2026.6.0
68ESPDEPRECATED("Use format_uid_to() with stack buffer instead. Removed in 2026.6.0", "2025.12.0")
69std::string format_uid(std::span<const uint8_t> uid);
70// Remove before 2026.6.0
71ESPDEPRECATED("Use format_bytes_to() with stack buffer instead. Removed in 2026.6.0", "2025.12.0")
72std::string format_bytes(std::span<const uint8_t> bytes);
73
74uint8_t guess_tag_type(uint8_t uid_length);
75uint8_t get_mifare_classic_ndef_start_index(std::vector<uint8_t> &data);
76bool decode_mifare_classic_tlv(std::vector<uint8_t> &data, uint32_t &message_length, uint8_t &message_start_index);
77uint32_t get_mifare_classic_buffer_size(uint32_t message_length);
78
79bool mifare_classic_is_first_block(uint8_t block_num);
80bool mifare_classic_is_trailer_block(uint8_t block_num);
81
82uint32_t get_mifare_ultralight_buffer_size(uint32_t message_length);
83
85 public:
86 virtual void tag_off(NfcTag &tag) {}
87 virtual void tag_on(NfcTag &tag) {}
88};
89
90class Nfcc {
91 public:
92 void register_listener(NfcTagListener *listener) { this->tag_listeners_.push_back(listener); }
93
94 protected:
95 std::vector<NfcTagListener *> tag_listeners_;
96};
97
98} // namespace nfc
99} // namespace esphome
virtual void tag_on(NfcTag &tag)
Definition nfc.h:87
virtual void tag_off(NfcTag &tag)
Definition nfc.h:86
std::vector< NfcTagListener * > tag_listeners_
Definition nfc.h:95
void register_listener(NfcTagListener *listener)
Definition nfc.h:92
bool decode_mifare_classic_tlv(std::vector< uint8_t > &data, uint32_t &message_length, uint8_t &message_start_index)
Definition nfc.cpp:51
char * format_bytes_to(char *buffer, std::span< const uint8_t > bytes)
Format bytes to buffer with ' ' separator (e.g., "04 11 22 33"). Returns buffer for inline use.
Definition nfc.cpp:15
uint32_t get_mifare_ultralight_buffer_size(uint32_t message_length)
Definition nfc.cpp:67
std::string format_uid(std::span< const uint8_t > uid)
Definition nfc.cpp:22
uint8_t get_mifare_classic_ndef_start_index(std::vector< uint8_t > &data)
Definition nfc.cpp:38
std::string format_bytes(std::span< const uint8_t > bytes)
Definition nfc.cpp:25
char * format_uid_to(char *buffer, std::span< const uint8_t > uid)
Format UID to buffer with '-' separator (e.g., "04-11-22-33"). Returns buffer for inline use.
Definition nfc.cpp:11
uint8_t guess_tag_type(uint8_t uid_length)
Definition nfc.cpp:30
bool mifare_classic_is_trailer_block(uint8_t block_num)
Definition nfc.cpp:95
uint32_t get_mifare_classic_buffer_size(uint32_t message_length)
Definition nfc.cpp:74
bool mifare_classic_is_first_block(uint8_t block_num)
Definition nfc.cpp:87
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
struct ESPDEPRECATED("Use std::index_sequence instead. Removed in 2026.6.0", "2025.12.0") seq
Definition automation.h:25