ESPHome  2022.12.8
nfc.cpp
Go to the documentation of this file.
1 #include "nfc.h"
2 #include <cstdio>
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace nfc {
7 
8 static const char *const TAG = "nfc";
9 
10 std::string format_uid(std::vector<uint8_t> &uid) {
11  char buf[(uid.size() * 2) + uid.size() - 1];
12  int offset = 0;
13  for (size_t i = 0; i < uid.size(); i++) {
14  const char *format = "%02X";
15  if (i + 1 < uid.size())
16  format = "%02X-";
17  offset += sprintf(buf + offset, format, uid[i]);
18  }
19  return std::string(buf);
20 }
21 
22 std::string format_bytes(std::vector<uint8_t> &bytes) {
23  char buf[(bytes.size() * 2) + bytes.size() - 1];
24  int offset = 0;
25  for (size_t i = 0; i < bytes.size(); i++) {
26  const char *format = "%02X";
27  if (i + 1 < bytes.size())
28  format = "%02X ";
29  offset += sprintf(buf + offset, format, bytes[i]);
30  }
31  return std::string(buf);
32 }
33 
34 uint8_t guess_tag_type(uint8_t uid_length) {
35  if (uid_length == 4) {
36  return TAG_TYPE_MIFARE_CLASSIC;
37  } else {
38  return TAG_TYPE_2;
39  }
40 }
41 
42 uint8_t get_mifare_classic_ndef_start_index(std::vector<uint8_t> &data) {
43  for (uint8_t i = 0; i < MIFARE_CLASSIC_BLOCK_SIZE; i++) {
44  if (data[i] == 0x00) {
45  // Do nothing, skip
46  } else if (data[i] == 0x03) {
47  return i;
48  } else {
49  return -2;
50  }
51  }
52  return -1;
53 }
54 
55 bool decode_mifare_classic_tlv(std::vector<uint8_t> &data, uint32_t &message_length, uint8_t &message_start_index) {
56  uint8_t i = get_mifare_classic_ndef_start_index(data);
57  if (i < 0 || data[i] != 0x03) {
58  ESP_LOGE(TAG, "Error, Can't decode message length.");
59  return false;
60  }
61  if (data[i + 1] == 0xFF) {
62  message_length = ((0xFF & data[i + 2]) << 8) | (0xFF & data[i + 3]);
63  message_start_index = i + MIFARE_CLASSIC_LONG_TLV_SIZE;
64  } else {
65  message_length = data[i + 1];
66  message_start_index = i + MIFARE_CLASSIC_SHORT_TLV_SIZE;
67  }
68  return true;
69 }
70 
71 uint32_t get_mifare_ultralight_buffer_size(uint32_t message_length) {
72  uint32_t buffer_size = message_length + 2 + 1;
73  if (buffer_size % MIFARE_ULTRALIGHT_READ_SIZE != 0)
74  buffer_size = ((buffer_size / MIFARE_ULTRALIGHT_READ_SIZE) + 1) * MIFARE_ULTRALIGHT_READ_SIZE;
75  return buffer_size;
76 }
77 
78 uint32_t get_mifare_classic_buffer_size(uint32_t message_length) {
79  uint32_t buffer_size = message_length;
80  if (message_length < 255) {
81  buffer_size += MIFARE_CLASSIC_SHORT_TLV_SIZE + 1;
82  } else {
83  buffer_size += MIFARE_CLASSIC_LONG_TLV_SIZE + 1;
84  }
85  if (buffer_size % MIFARE_CLASSIC_BLOCK_SIZE != 0) {
86  buffer_size = ((buffer_size / MIFARE_CLASSIC_BLOCK_SIZE) + 1) * MIFARE_CLASSIC_BLOCK_SIZE;
87  }
88  return buffer_size;
89 }
90 
91 bool mifare_classic_is_first_block(uint8_t block_num) {
92  if (block_num < 128) {
93  return (block_num % 4 == 0);
94  } else {
95  return (block_num % 16 == 0);
96  }
97 }
98 
99 bool mifare_classic_is_trailer_block(uint8_t block_num) {
100  if (block_num < 128) {
101  return ((block_num + 1) % 4 == 0);
102  } else {
103  return ((block_num + 1) % 16 == 0);
104  }
105 }
106 
107 } // namespace nfc
108 } // namespace esphome
uint32_t get_mifare_classic_buffer_size(uint32_t message_length)
Definition: nfc.cpp:78
bool mifare_classic_is_trailer_block(uint8_t block_num)
Definition: nfc.cpp:99
bool decode_mifare_classic_tlv(std::vector< uint8_t > &data, uint32_t &message_length, uint8_t &message_start_index)
Definition: nfc.cpp:55
uint8_t get_mifare_classic_ndef_start_index(std::vector< uint8_t > &data)
Definition: nfc.cpp:42
std::string format_uid(std::vector< uint8_t > &uid)
Definition: nfc.cpp:10
uint8_t guess_tag_type(uint8_t uid_length)
Definition: nfc.cpp:34
bool mifare_classic_is_first_block(uint8_t block_num)
Definition: nfc.cpp:91
Definition: a4988.cpp:4
std::vector< uint8_t > bytes
Definition: sml_parser.h:12
uint32_t get_mifare_ultralight_buffer_size(uint32_t message_length)
Definition: nfc.cpp:71
std::string format_bytes(std::vector< uint8_t > &bytes)
Definition: nfc.cpp:22