12 uint8_t current_block = 4;
13 uint8_t message_start_index = 0;
17 ESP_LOGE(TAG,
"Tag auth failed while attempting to read tag data");
18 return nfc::STATUS_FAILED;
20 std::vector<uint8_t> data;
24 return nfc::STATUS_FAILED;
27 ESP_LOGE(TAG,
"Failed to read block %u", current_block);
28 return nfc::STATUS_FAILED;
33 std::vector<uint8_t> buffer;
35 while (index < buffer_size) {
38 ESP_LOGE(TAG,
"Block authentication failed for %u", current_block);
39 return nfc::STATUS_FAILED;
42 std::vector<uint8_t> block_data;
44 ESP_LOGE(TAG,
"Error reading block %u", current_block);
45 return nfc::STATUS_FAILED;
47 buffer.insert(buffer.end(), block_data.begin(), block_data.end());
50 index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
58 if (buffer.begin() + message_start_index < buffer.end()) {
59 buffer.erase(buffer.begin(), buffer.begin() + message_start_index);
61 return nfc::STATUS_FAILED;
64 tag.set_ndef_message(make_unique<nfc::NdefMessage>(buffer));
66 return nfc::STATUS_OK;
98 case nfc::MIFARE_CMD_AUTH_A:
99 tx.get_message().back() = MFC_AUTHENTICATE_PARAM_KS_A;
102 case nfc::MIFARE_CMD_AUTH_B:
103 tx.get_message().back() = MFC_AUTHENTICATE_PARAM_KS_B;
110 if (key !=
nullptr) {
111 tx.get_message().back() |= MFC_AUTHENTICATE_PARAM_EMBED_KEY;
112 tx.get_message().insert(tx.get_message().end(), key, key + 6);
115 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
118 ESP_LOGE(TAG,
"Sending MFC_AUTHENTICATE_REQ failed");
119 return nfc::STATUS_FAILED;
123 ESP_LOGE(TAG,
"MFC authentication failed - block 0x%02x", block_num);
125 return nfc::STATUS_FAILED;
128 ESP_LOGV(TAG,
"MFC block %u authentication succeeded", block_num);
129 return nfc::STATUS_OK;
142 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BUFFER = {
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
144 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> TRAILER_BUFFER = {
145 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
147 auto status = nfc::STATUS_OK;
149 for (
int block = 0; block < 64; block += 4) {
155 ESP_LOGE(TAG,
"Unable to write block %u", block);
156 status = nfc::STATUS_FAILED;
160 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
161 status = nfc::STATUS_FAILED;
164 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
165 status = nfc::STATUS_FAILED;
168 ESP_LOGE(TAG,
"Unable to write block %u", block + 3);
169 status = nfc::STATUS_FAILED;
177 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> EMPTY_NDEF_MESSAGE = {
178 0x03, 0x03, 0xD0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
179 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLANK_BLOCK = {
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
181 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_1_DATA = {
182 0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
183 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_2_DATA = {
184 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
185 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> BLOCK_3_TRAILER = {
186 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
187 static constexpr std::array<uint8_t, nfc::MIFARE_CLASSIC_BLOCK_SIZE> NDEF_TRAILER = {
188 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
191 ESP_LOGE(TAG,
"Unable to authenticate block 0 for formatting");
192 return nfc::STATUS_FAILED;
195 return nfc::STATUS_FAILED;
198 return nfc::STATUS_FAILED;
201 return nfc::STATUS_FAILED;
204 ESP_LOGD(TAG,
"Sector 0 formatted with NDEF");
206 auto status = nfc::STATUS_OK;
208 for (
int block = 4; block < 64; block += 4) {
210 return nfc::STATUS_FAILED;
215 ESP_LOGE(TAG,
"Unable to write block %u", block);
216 status = nfc::STATUS_FAILED;
220 ESP_LOGE(TAG,
"Unable to write block %u", block);
221 status = nfc::STATUS_FAILED;
225 ESP_LOGE(TAG,
"Unable to write block %u", block + 1);
226 status = nfc::STATUS_FAILED;
229 ESP_LOGE(TAG,
"Unable to write block %u", block + 2);
230 status = nfc::STATUS_FAILED;
233 ESP_LOGE(TAG,
"Unable to write trailer block %u", block + 3);
234 status = nfc::STATUS_FAILED;
242 nfc::NciMessage tx(nfc::NCI_PKT_MT_DATA, {XCHG_DATA_OID, nfc::MIFARE_CMD_WRITE, block_num});
244 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
247 ESP_LOGE(TAG,
"Sending XCHG_DATA_REQ failed");
248 return nfc::STATUS_FAILED;
251 tx.set_payload({XCHG_DATA_OID});
252 tx.get_message().insert(tx.get_message().end(), data, data +
len);
255 if (this->
transceive_(tx, rx, NFCC_TAG_WRITE_TIMEOUT) != nfc::STATUS_OK) {
256 ESP_LOGE(TAG,
"MFC XCHG_DATA timed out waiting for XCHG_DATA_RSP during block write");
257 return nfc::STATUS_FAILED;
262 ESP_LOGE(TAG,
"MFC write block failed - block 0x%02x", block_num);
264 return nfc::STATUS_FAILED;
267 return nfc::STATUS_OK;
271 auto encoded =
message->encode();
273 uint32_t message_length = encoded.size();
276 encoded.insert(encoded.begin(), 0x03);
277 if (message_length < 255) {
278 encoded.insert(encoded.begin() + 1, message_length);
280 encoded.insert(encoded.begin() + 1, 0xFF);
281 encoded.insert(encoded.begin() + 2, (message_length >> 8) & 0xFF);
282 encoded.insert(encoded.begin() + 3, message_length & 0xFF);
284 encoded.push_back(0xFE);
286 encoded.resize(buffer_length, 0);
289 uint8_t current_block = 4;
291 while (index < buffer_length) {
294 return nfc::STATUS_FAILED;
300 return nfc::STATUS_FAILED;
302 index += nfc::MIFARE_CLASSIC_BLOCK_SIZE;
310 return nfc::STATUS_OK;