From 4d84169b293ebc4b6100af145b30b2626650ddce Mon Sep 17 00:00:00 2001 From: Manuel Weiser Date: Sat, 30 Aug 2025 10:09:22 +0200 Subject: [PATCH] feat: enhance NFC tag reading with robust error recovery and JSON optimization for fast-path detection --- src/nfc.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/src/nfc.cpp b/src/nfc.cpp index 3a7ec60..dde0012 100644 --- a/src/nfc.cpp +++ b/src/nfc.cpp @@ -1285,10 +1285,11 @@ bool quickSpoolIdCheck(String uidString) { memset(ndefData, 0, 20); for (uint8_t page = 4; page < 9; page++) { - if (!nfc.ntag2xx_ReadPage(page, ndefData + (page - 4) * 4)) { - Serial.print("Failed to read page "); - Serial.println(page); - return false; // Fall back to full read + if (!robustPageRead(page, ndefData + (page - 4) * 4)) { + Serial.print("FAST-PATH: Failed to read page "); + Serial.print(page); + Serial.println(" - falling back to full read"); + return false; // Fall back to full read if any page read fails } } @@ -1358,10 +1359,11 @@ bool quickSpoolIdCheck(String uidString) { memset(extraData, 0, 16); for (uint8_t page = 9; page < 13; page++) { - if (!nfc.ntag2xx_ReadPage(page, extraData + (page - 9) * 4)) { - Serial.print("Failed to read additional page "); - Serial.println(page); - return false; + if (!robustPageRead(page, extraData + (page - 9) * 4)) { + Serial.print("FAST-PATH: Failed to read additional page "); + Serial.print(page); + Serial.println(" - falling back to full read"); + return false; // Fall back to full read if extended read fails } } @@ -1655,10 +1657,60 @@ void writeJsonToTag(void *parameter) { vTaskDelete(NULL); } +// Ensures sm_id is always the first key in JSON for fast-path detection +String optimizeJsonForFastPath(const char* payload) { + JsonDocument inputDoc; + DeserializationError error = deserializeJson(inputDoc, payload); + + if (error) { + Serial.print("JSON optimization failed: "); + Serial.println(error.c_str()); + return String(payload); // Return original if parsing fails + } + + // Create optimized JSON with sm_id first + JsonDocument optimizedDoc; + + // Always add sm_id first (even if it's "0" for brand filaments) + if (inputDoc["sm_id"].is()) { + optimizedDoc["sm_id"] = inputDoc["sm_id"].as(); + Serial.print("Optimizing JSON: sm_id found = "); + Serial.println(inputDoc["sm_id"].as()); + } else { + optimizedDoc["sm_id"] = "0"; // Default for brand filaments + Serial.println("Optimizing JSON: No sm_id found, setting to '0'"); + } + + // Add all other keys in original order + for (JsonPair kv : inputDoc.as()) { + String key = kv.key().c_str(); + if (key != "sm_id") { // Skip sm_id as it's already added first + optimizedDoc[key] = kv.value(); + } + } + + String optimizedJson; + serializeJson(optimizedDoc, optimizedJson); + + Serial.println("JSON optimized for fast-path detection:"); + Serial.print("Original: "); + Serial.println(payload); + Serial.print("Optimized: "); + Serial.println(optimizedJson); + + inputDoc.clear(); + optimizedDoc.clear(); + + return optimizedJson; +} + void startWriteJsonToTag(const bool isSpoolTag, const char* payload) { + // Optimize JSON to ensure sm_id is first key for fast-path detection + String optimizedPayload = optimizeJsonForFastPath(payload); + NfcWriteParameterType* parameters = new NfcWriteParameterType(); parameters->tagType = isSpoolTag; - parameters->payload = strdup(payload); + parameters->payload = strdup(optimizedPayload.c_str()); // Use optimized payload // Task nicht mehrfach starten if (nfcReaderState == NFC_IDLE || nfcReaderState == NFC_READ_ERROR || nfcReaderState == NFC_READ_SUCCESS) { @@ -1762,6 +1814,11 @@ void scanRfidTask(void * parameter) { foundNfcTag(nullptr, success); + // Reset activeSpoolId immediately when no tag is detected to prevent stale autoSet + if (!success) { + activeSpoolId = ""; + } + // As long as there is still a tag on the reader, do not try to read it again if (success && nfcReaderState == NFC_IDLE) { @@ -1857,6 +1914,9 @@ void scanRfidTask(void * parameter) { { oledShowProgressBar(1, 1, "Failure", "Tag read error"); nfcReaderState = NFC_READ_ERROR; + // Reset activeSpoolId when tag reading fails to prevent autoSet + activeSpoolId = ""; + Serial.println("Tag read failed - activeSpoolId reset to prevent autoSet"); } } else @@ -1864,6 +1924,9 @@ void scanRfidTask(void * parameter) { //TBD: Show error here?! oledShowProgressBar(1, 1, "Failure", "Unkown tag type"); Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!"); + // Reset activeSpoolId when tag type is unknown to prevent autoSet + activeSpoolId = ""; + Serial.println("Unknown tag type - activeSpoolId reset to prevent autoSet"); } }