13 uint8_t current_block = 4;
14 uint8_t message_start_index = 0;
15 uint32_t message_length = 0;
18 ESP_LOGE(TAG,
"Tag auth failed while attempting to read tag data");
19 return nfc::STATUS_FAILED;
21 std::vector<uint8_t> data;
25 return nfc::STATUS_FAILED;
28 ESP_LOGE(TAG,
"Failed to read block %u", current_block);
29 return nfc::STATUS_FAILED;
34 std::vector<uint8_t> buffer;
36 while (index < buffer_size) {
39 ESP_LOGE(TAG,
"Block authentication failed for %u", current_block);
40 return nfc::STATUS_FAILED;
43 std::vector<uint8_t> block_data;
45 ESP_LOGE(TAG,
"Error reading block %u", current_block);
46 return nfc::STATUS_FAILED;
48 buffer.insert(buffer.end(), block_data.begin(), block_data.end());
51 index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
59 if (buffer.begin() + message_start_index < buffer.end()) {
60 buffer.erase(buffer.begin(), buffer.begin() + message_start_index);
62 return nfc::STATUS_FAILED;
67 return nfc::STATUS_OK;
99 case nfc::MIFARE_CMD_AUTH_A:
100 tx.get_message().back() = MFC_AUTHENTICATE_PARAM_KS_A;
103 case nfc::MIFARE_CMD_AUTH_B:
104 tx.get_message().back() = MFC_AUTHENTICATE_PARAM_KS_B;
111 if (key !=
nullptr) {
112 tx.get_message().back() |= MFC_AUTHENTICATE_PARAM_EMBED_KEY;
113 tx.get_message().insert(tx.get_message().end(), key, key + 6);
116 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
119 ESP_LOGE(TAG,
"Sending MFC_AUTHENTICATE_REQ failed");
120 return nfc::STATUS_FAILED;
124 ESP_LOGE(TAG,
"MFC authentication failed - block 0x%02x", block_num);
126 return nfc::STATUS_FAILED;
129 ESP_LOGV(TAG,
"MFC block %u authentication succeeded", block_num);
130 return nfc::STATUS_OK;
143 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BUFFER = {
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
145 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> TRAILER_BUFFER = {
146 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
148 auto status = nfc::STATUS_OK;
150 for (
int block = 0; block < 64; block += 4) {
156 ESP_LOGE(TAG,
"Unable to write block %u", block);
157 status = nfc::STATUS_FAILED;
161 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
162 status = nfc::STATUS_FAILED;
165 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
166 status = nfc::STATUS_FAILED;
169 ESP_LOGE(TAG,
"Unable to write block %u", block + 3);
170 status = nfc::STATUS_FAILED;
178 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> EMPTY_NDEF_MESSAGE = {
179 0x03, 0x03, 0xD0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
180 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BLOCK = {
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
182 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_1_DATA = {
183 0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
184 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_2_DATA = {
185 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
186 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_3_TRAILER = {
187 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
188 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> NDEF_TRAILER = {
189 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
192 ESP_LOGE(TAG,
"Unable to authenticate block 0 for formatting");
193 return nfc::STATUS_FAILED;
196 return nfc::STATUS_FAILED;
199 return nfc::STATUS_FAILED;
202 return nfc::STATUS_FAILED;
205 ESP_LOGD(TAG,
"Sector 0 formatted with NDEF");
207 auto status = nfc::STATUS_OK;
209 for (
int block = 4; block < 64; block += 4) {
211 return nfc::STATUS_FAILED;
216 ESP_LOGE(TAG,
"Unable to write block %u", block);
217 status = nfc::STATUS_FAILED;
221 ESP_LOGE(TAG,
"Unable to write block %u", block);
222 status = nfc::STATUS_FAILED;
226 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
227 status = nfc::STATUS_FAILED;
230 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
231 status = nfc::STATUS_FAILED;
234 ESP_LOGE(TAG,
"Unable to write trailer block %u", block + 3);
235 status = nfc::STATUS_FAILED;
243 nfc::NciMessage tx(nfc::NCI_PKT_MT_DATA, {XCHG_DATA_OID, nfc::MIFARE_CMD_WRITE, block_num});
245 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
248 ESP_LOGE(TAG,
"Sending XCHG_DATA_REQ failed");
249 return nfc::STATUS_FAILED;
252 tx.set_payload({XCHG_DATA_OID});
253 tx.get_message().insert(tx.get_message().end(), data, data +
len);
256 if (this->
transceive_(tx, rx, NFCC_TAG_WRITE_TIMEOUT) != nfc::STATUS_OK) {
257 ESP_LOGE(TAG,
"MFC XCHG_DATA timed out waiting for XCHG_DATA_RSP during block write");
258 return nfc::STATUS_FAILED;
263 ESP_LOGE(TAG,
"MFC write block failed - block 0x%02x", block_num);
265 return nfc::STATUS_FAILED;
268 return nfc::STATUS_OK;
272 auto encoded =
message->encode();
274 uint32_t message_length = encoded.size();
277 encoded.insert(encoded.begin(), 0x03);
278 if (message_length < 255) {
279 encoded.insert(encoded.begin() + 1, message_length);
281 encoded.insert(encoded.begin() + 1, 0xFF);
282 encoded.insert(encoded.begin() + 2, (message_length >> 8) & 0xFF);
283 encoded.insert(encoded.begin() + 3, message_length & 0xFF);
285 encoded.push_back(0xFE);
287 encoded.resize(buffer_length, 0);
290 uint8_t current_block = 4;
292 while (index < buffer_length) {
295 return nfc::STATUS_FAILED;
301 return nfc::STATUS_FAILED;
303 index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
311 return nfc::STATUS_OK;