14 uint8_t current_block = 4;
15 uint8_t message_start_index = 0;
19 ESP_LOGE(TAG,
"Tag auth failed while attempting to read tag data");
20 return nfc::STATUS_FAILED;
22 std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> block_data;
26 return nfc::STATUS_FAILED;
29 ESP_LOGE(TAG,
"Failed to read block %u", current_block);
30 return nfc::STATUS_FAILED;
32 if (message_length > MIFARE_CLASSIC_MAX_NDEF_SIZE) {
33 ESP_LOGE(TAG,
"NDEF message too long: %" PRIu32
" bytes", message_length);
34 return nfc::STATUS_FAILED;
39 if (!
buffer.try_init(buffer_size)) {
40 ESP_LOGE(TAG,
"Out of memory reading NDEF message of %" PRIu32
" bytes", buffer_size);
41 return nfc::STATUS_FAILED;
44 while (
buffer.size() < buffer_size) {
47 ESP_LOGE(TAG,
"Block authentication failed for %u", current_block);
48 return nfc::STATUS_FAILED;
52 ESP_LOGE(TAG,
"Error reading block %u", current_block);
53 return nfc::STATUS_FAILED;
55 for (
const uint8_t
byte : block_data) {
65 if (message_start_index >=
buffer.size()) {
66 return nfc::STATUS_FAILED;
68 tag.
set_ndef_message(make_unique<nfc::NdefMessage>(std::span<const uint8_t>(
buffer).subspan(message_start_index)));
70 return nfc::STATUS_OK;
100 uint8_t key_select = key_num;
102 case nfc::MIFARE_CMD_AUTH_A:
103 key_select = MFC_AUTHENTICATE_PARAM_KS_A;
106 case nfc::MIFARE_CMD_AUTH_B:
107 key_select = MFC_AUTHENTICATE_PARAM_KS_B;
113 if (key !=
nullptr) {
114 key_select |= MFC_AUTHENTICATE_PARAM_EMBED_KEY;
119 if (key !=
nullptr) {
120 tx.append(std::span<const uint8_t>(key, 6));
123 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
126 ESP_LOGE(TAG,
"Sending MFC_AUTHENTICATE_REQ failed");
127 return nfc::STATUS_FAILED;
131 ESP_LOGE(TAG,
"MFC authentication failed - block 0x%02x", block_num);
133 return nfc::STATUS_FAILED;
136 ESP_LOGV(TAG,
"MFC block %u authentication succeeded", block_num);
137 return nfc::STATUS_OK;
150 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BUFFER = {
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
152 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> TRAILER_BUFFER = {
153 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
155 auto status = nfc::STATUS_OK;
157 for (
int block = 0; block < 64; block += 4) {
163 ESP_LOGE(TAG,
"Unable to write block %u", block);
164 status = nfc::STATUS_FAILED;
168 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
169 status = nfc::STATUS_FAILED;
172 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
173 status = nfc::STATUS_FAILED;
176 ESP_LOGE(TAG,
"Unable to write block %u", block + 3);
177 status = nfc::STATUS_FAILED;
185 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> EMPTY_NDEF_MESSAGE = {
186 0x03, 0x03, 0xD0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
187 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BLOCK = {
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
189 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_1_DATA = {
190 0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
191 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_2_DATA = {
192 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
193 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_3_TRAILER = {
194 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
195 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> NDEF_TRAILER = {
196 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
199 ESP_LOGE(TAG,
"Unable to authenticate block 0 for formatting");
200 return nfc::STATUS_FAILED;
203 return nfc::STATUS_FAILED;
206 return nfc::STATUS_FAILED;
209 return nfc::STATUS_FAILED;
212 ESP_LOGD(TAG,
"Sector 0 formatted with NDEF");
214 auto status = nfc::STATUS_OK;
216 for (
int block = 4; block < 64; block += 4) {
218 return nfc::STATUS_FAILED;
223 ESP_LOGE(TAG,
"Unable to write block %u", block);
224 status = nfc::STATUS_FAILED;
228 ESP_LOGE(TAG,
"Unable to write block %u", block);
229 status = nfc::STATUS_FAILED;
233 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
234 status = nfc::STATUS_FAILED;
237 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
238 status = nfc::STATUS_FAILED;
241 ESP_LOGE(TAG,
"Unable to write trailer block %u", block + 3);
242 status = nfc::STATUS_FAILED;
250 nfc::NciMessage tx(nfc::NCI_PKT_MT_DATA, {XCHG_DATA_OID, nfc::MIFARE_CMD_WRITE, block_num});
251 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
255 ESP_LOGE(TAG,
"Sending XCHG_DATA_REQ failed");
256 return nfc::STATUS_FAILED;
259 tx.set_payload({XCHG_DATA_OID});
260 tx.append(std::span<const uint8_t>(data,
len));
263 if (this->
transceive_(tx, rx, NFCC_TAG_WRITE_TIMEOUT) != nfc::STATUS_OK) {
264 ESP_LOGE(TAG,
"MFC XCHG_DATA timed out waiting for XCHG_DATA_RSP during block write");
265 return nfc::STATUS_FAILED;
270 ESP_LOGE(TAG,
"MFC write block failed - block 0x%02x", block_num);
272 return nfc::STATUS_FAILED;
275 return nfc::STATUS_OK;