ESPHome 2026.11.0-dev
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::nfc {
13
14static constexpr uint8_t MIFARE_CLASSIC_BLOCK_SIZE = 16;
15static constexpr uint8_t MIFARE_CLASSIC_LONG_TLV_SIZE = 4;
16static constexpr uint8_t MIFARE_CLASSIC_SHORT_TLV_SIZE = 2;
17static constexpr uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_LOW = 4;
18static constexpr uint8_t MIFARE_CLASSIC_BLOCKS_PER_SECT_HIGH = 16;
19static constexpr uint8_t MIFARE_CLASSIC_16BLOCK_SECT_START = 32;
20
21static constexpr uint8_t MIFARE_ULTRALIGHT_PAGE_SIZE = 4;
22static constexpr uint8_t MIFARE_ULTRALIGHT_READ_SIZE = 4;
23static constexpr uint8_t MIFARE_ULTRALIGHT_DATA_START_PAGE = 4;
24static constexpr uint8_t MIFARE_ULTRALIGHT_MAX_PAGE = 63;
25
26static constexpr uint8_t TAG_TYPE_MIFARE_CLASSIC = 0;
27static constexpr uint8_t TAG_TYPE_1 = 1;
28static constexpr uint8_t TAG_TYPE_2 = 2;
29static constexpr uint8_t TAG_TYPE_3 = 3;
30static constexpr uint8_t TAG_TYPE_4 = 4;
31static constexpr uint8_t TAG_TYPE_UNKNOWN = 99;
32
33// Mifare Commands
34static constexpr uint8_t MIFARE_CMD_AUTH_A = 0x60;
35static constexpr uint8_t MIFARE_CMD_AUTH_B = 0x61;
36static constexpr uint8_t MIFARE_CMD_HALT = 0x50;
37static constexpr uint8_t MIFARE_CMD_READ = 0x30;
38static constexpr uint8_t MIFARE_CMD_WRITE = 0xA0;
39static constexpr uint8_t MIFARE_CMD_WRITE_ULTRALIGHT = 0xA2;
40
41// Mifare Ack/Nak
42static constexpr uint8_t MIFARE_CMD_ACK = 0x0A;
43static constexpr uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_VALID = 0x00;
44static constexpr uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_VALID = 0x01;
45static constexpr uint8_t MIFARE_CMD_NAK_INVALID_XFER_BUFF_INVALID = 0x04;
46static constexpr uint8_t MIFARE_CMD_NAK_CRC_ERROR_XFER_BUFF_INVALID = 0x05;
47
48static const char *const MIFARE_CLASSIC = "Mifare Classic";
49static const char *const NFC_FORUM_TYPE_2 = "NFC Forum Type 2";
50static const char *const ERROR = "Error";
51
52static constexpr uint8_t DEFAULT_KEY[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
53static constexpr uint8_t NDEF_KEY[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
54static constexpr uint8_t MAD_KEY[6] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
55
57static constexpr size_t FORMAT_UID_BUFFER_SIZE = 30;
59char *format_uid_to(char *buffer, std::span<const uint8_t> uid);
60
62static constexpr size_t FORMAT_BYTES_BUFFER_SIZE = 192;
64char *format_bytes_to(char *buffer, std::span<const uint8_t> bytes);
65
66uint8_t guess_tag_type(uint8_t uid_length);
67int8_t get_mifare_classic_ndef_start_index(std::span<const uint8_t> data);
68bool decode_mifare_classic_tlv(std::span<const uint8_t> data, uint32_t &message_length, uint8_t &message_start_index);
71void fill_ndef_tlv(std::span<const uint8_t> message, uint32_t buffer_length, FixedVector<uint8_t> &buffer);
72
73bool mifare_classic_is_first_block(uint8_t block_num);
74bool mifare_classic_is_trailer_block(uint8_t block_num);
75
77
79 public:
80 virtual void tag_off(NfcTag &tag) {}
81 virtual void tag_on(NfcTag &tag) {}
82};
83
84class Nfcc {
85 public:
86#ifdef NFC_TAG_LISTENER_COUNT
87 void register_listener(NfcTagListener *listener) { this->tag_listeners_.push_back(listener); }
88
89 protected:
91#endif
92};
93
94} // namespace esphome::nfc
Minimal static vector - saves memory by avoiding std::vector overhead.
Definition helpers.h:286
virtual void tag_on(NfcTag &tag)
Definition nfc.h:81
virtual void tag_off(NfcTag &tag)
Definition nfc.h:80
StaticVector< NfcTagListener *, NFC_TAG_LISTENER_COUNT > tag_listeners_
Definition nfc.h:90
void register_listener(NfcTagListener *listener)
Definition nfc.h:87
const LogString * message
Definition component.cpp:35
uint32_t buffer
Definition gif.cpp:50
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:14
int8_t get_mifare_classic_ndef_start_index(const std::span< const uint8_t > data)
Definition nfc.cpp:26
uint32_t get_mifare_ultralight_buffer_size(uint32_t message_length)
Definition nfc.cpp:64
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:10
uint8_t guess_tag_type(uint8_t uid_length)
Definition nfc.cpp:18
bool mifare_classic_is_trailer_block(uint8_t block_num)
Definition nfc.cpp:112
bool decode_mifare_classic_tlv(const std::span< const uint8_t > data, uint32_t &message_length, uint8_t &message_start_index)
Definition nfc.cpp:39
uint32_t get_mifare_classic_buffer_size(uint32_t message_length)
Definition nfc.cpp:91
void fill_ndef_tlv(const std::span< const uint8_t > message, const uint32_t buffer_length, FixedVector< uint8_t > &buffer)
Fills buffer with the NDEF TLV (type, length, message, terminator) padded with zeros to buffer_length
Definition nfc.cpp:72
bool mifare_classic_is_first_block(uint8_t block_num)
Definition nfc.cpp:104
static void uint32_t