Skip to content

Commit 71ef24f

Browse files
committed
Fix writing NDEF messages
1 parent 4acf5e4 commit 71ef24f

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

firmware/conf.d/logger.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ logger:
3535
nfc.ndef_message: DEBUG
3636
select: INFO
3737
number: INFO
38+
pn532.mifare_ultralight: VERBOSE
39+
#TODO: What are other pn532 protocol types?
3840
"": ERROR

firmware/conf.d/pn532_rfid-solo.yaml

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -234,51 +234,69 @@ button:
234234
}
235235
then:
236236
- lambda: |-
237-
constexpr size_t json_capacity = 1024;
237+
auto message = new nfc::NdefMessage();
238238
239-
StaticJsonDocument<json_capacity> doc;
239+
//TODO: uncomment once esphome suppports messages nless than 255 bytes
240+
// URI NDEF record
241+
// esphome fails if this is more than 255 bytes
242+
//auto uri_record = std::make_unique<nfc::NdefRecordUri>();
243+
//std::string url = "https://openspool.io/tag?";
244+
//url.append("protocol=").append("openspool");
245+
//url.append("version=").append("1.0");
246+
//url.append("&color_hex=").append(id(filament_color_hex).state);
247+
//url.append("&type=").append(id(filament_type).state);
248+
//url.append("&min_temp=").append(std::to_string(static_cast<uint16_t>(id(filament_min_temp).state)));
249+
//url.append("&max_temp=").append(std::to_string(static_cast<uint16_t>(id(filament_max_temp).state)));
250+
//url.append("&brand=").append(id(filament_brand).state);
240251
241-
doc["version"] = "1.0";
242-
doc["protocol"] = "openspool";
243-
doc["color_hex"] = id(filament_color_hex).state;
244-
doc["type"] = id(filament_type).state;
245-
doc["min_temp"] = id(filament_min_temp).state;
246-
doc["max_temp"] = id(filament_max_temp).state;
247-
doc["brand"] = id(filament_brand).state;
252+
// Warn if the url is more than 255 bytes
253+
// While NFC allows messages longer than 255, you have to set the tnf_byte which esphome doesn't allow yet
254+
//if (url.length() > 255) {
255+
// ESP_LOGE("NFC", "URL longer than 255 bytes: %s", url.c_str());
256+
// return;
257+
//}
258+
//ESP_LOGD("NFC", "Adding NDEF Record URI: %s", url.c_str());
259+
//message->add_uri_record(url);
248260
249-
char json_buffer[json_capacity];
250-
size_t json_length = serializeJson(doc, json_buffer, sizeof(json_buffer));
251-
if (json_length >= json_capacity) {
252-
ESP_LOGE("rfid", "JSON serialization failed: buffer too small");
253-
return;
254-
}
261+
// Application/Json NDEF record
262+
auto json_record = std::make_unique<nfc::NdefRecord>();
263+
json_record->set_tnf(nfc::TNF_MIME_MEDIA);
264+
json_record->set_type("application/json");
255265
256-
auto message = new nfc::NdefMessage();
266+
DynamicJsonDocument doc(256); // Adjust size as needed
267+
JsonObject root = doc.to<JsonObject>();
268+
root["version"] = "1.0";
269+
root["protocol"] = "openspool";
270+
root["color_hex"] = id(filament_color_hex).state;
271+
root["type"] = id(filament_type).state;
272+
root["min_temp"] = id(filament_min_temp).state;
273+
root["max_temp"] = id(filament_max_temp).state;
274+
root["brand"] = id(filament_brand).state;
257275
258-
//Create openspool.io/tag_info uri
259-
std::string url = "https://openspool.io/tag_info?";
260-
url += "color_hex=" + std::string(id(filament_color_hex).state);
261-
url += "&type=" + std::string(id(filament_type).state);
262-
url += "&min_temp=" + std::to_string(static_cast<int>(id(filament_min_temp).state));
263-
url += "&max_temp=" + std::to_string(static_cast<int>(id(filament_max_temp).state));
264-
url += "&brand=" + std::string(id(filament_brand).state);
265-
url += "&protocol=" + std::string("openspool");
266-
url += "&version=" + std::string("1.0");
267-
ESP_LOGI("rfid", "NDEF Record URL: %s", url.c_str());
268-
message->add_uri_record(url);
269-
270-
ESP_LOGI("rfid", "JSON content to be written: %s", json_buffer);
276+
std::string json_string;
277+
serializeJson(root, json_string);
278+
if (json_string.empty()) {
279+
ESP_LOGE("rfid", "Failed to serialize JSON");
280+
return;
281+
}
282+
ESP_LOGI("rfid", "JSON content to be written: %s", json_string.c_str());
283+
json_record->set_payload(json_string);
284+
message->add_record(std::move(json_record));
271285
272-
auto tag_data_record = std::make_unique<nfc::NdefRecord>();
273-
tag_data_record->set_tnf(nfc::TNF_WELL_KNOWN);
274-
tag_data_record->set_type("application/json");
275-
tag_data_record->set_payload(std::string(json_buffer, json_length));
286+
std::vector<uint8_t> encoded_message = message->encode();
287+
size_t message_size = encoded_message.size();
288+
ESP_LOGI("rfid", "NDEF message size: %zu bytes", message_size);
276289
277-
message->add_record(std::move(tag_data_record));
290+
// TODO: make dynamic for NTAG215 (544) or NTAG216 (888)
291+
// TODO: 544 bytes is actuall 496 usable according to logs
292+
//const size_t MAX_MESSAGE_SIZE = 496;
293+
//if (message_size > MAX_MESSAGE_SIZE) {
294+
// ESP_LOGE("rfid", "Error: NDEF message size (%zu bytes) exceeds maximum allowed size (%zu bytes)", message_size, MAX_MESSAGE_SIZE);
295+
//return; // Exit the function or throw an exception, depending on your error handling strategy
296+
//}
278297
279298
id(rfid_reader_spi_0).write_mode(message);
280299
ESP_LOGI("rfid", "Writing JSON NDEF message to tag");
281-
//TODO: GPT says there is a memory leak here, yet when I use 'delete' or std::make_unique<> I get crashes
282300
- wait_until:
283301
not:
284302
pn532.is_writing:

0 commit comments

Comments
 (0)