feat: enhance NFC tag reading with robust error recovery and JSON optimization for fast-path detection
This commit is contained in:
		
							
								
								
									
										81
									
								
								src/nfc.cpp
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/nfc.cpp
									
									
									
									
									
								
							| @@ -1285,10 +1285,11 @@ bool quickSpoolIdCheck(String uidString) { | |||||||
|     memset(ndefData, 0, 20); |     memset(ndefData, 0, 20); | ||||||
|      |      | ||||||
|     for (uint8_t page = 4; page < 9; page++) { |     for (uint8_t page = 4; page < 9; page++) { | ||||||
|         if (!nfc.ntag2xx_ReadPage(page, ndefData + (page - 4) * 4)) { |         if (!robustPageRead(page, ndefData + (page - 4) * 4)) { | ||||||
|             Serial.print("Failed to read page "); |             Serial.print("FAST-PATH: Failed to read page "); | ||||||
|             Serial.println(page); |             Serial.print(page); | ||||||
|             return false; // Fall back to full read |             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); |         memset(extraData, 0, 16); | ||||||
|          |          | ||||||
|         for (uint8_t page = 9; page < 13; page++) { |         for (uint8_t page = 9; page < 13; page++) { | ||||||
|             if (!nfc.ntag2xx_ReadPage(page, extraData + (page - 9) * 4)) { |             if (!robustPageRead(page, extraData + (page - 9) * 4)) { | ||||||
|                 Serial.print("Failed to read additional page "); |                 Serial.print("FAST-PATH: Failed to read additional page "); | ||||||
|                 Serial.println(page); |                 Serial.print(page); | ||||||
|                 return false; |                 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); |   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<String>()) { | ||||||
|  |         optimizedDoc["sm_id"] = inputDoc["sm_id"].as<String>(); | ||||||
|  |         Serial.print("Optimizing JSON: sm_id found = "); | ||||||
|  |         Serial.println(inputDoc["sm_id"].as<String>()); | ||||||
|  |     } 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<JsonObject>()) { | ||||||
|  |         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) { | 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(); |   NfcWriteParameterType* parameters = new NfcWriteParameterType(); | ||||||
|   parameters->tagType = isSpoolTag; |   parameters->tagType = isSpoolTag; | ||||||
|   parameters->payload = strdup(payload); |   parameters->payload = strdup(optimizedPayload.c_str()); // Use optimized payload | ||||||
|    |    | ||||||
|   // Task nicht mehrfach starten |   // Task nicht mehrfach starten | ||||||
|   if (nfcReaderState == NFC_IDLE || nfcReaderState == NFC_READ_ERROR || nfcReaderState == NFC_READ_SUCCESS) { |   if (nfcReaderState == NFC_IDLE || nfcReaderState == NFC_READ_ERROR || nfcReaderState == NFC_READ_SUCCESS) { | ||||||
| @@ -1762,6 +1814,11 @@ void scanRfidTask(void * parameter) { | |||||||
|  |  | ||||||
|       foundNfcTag(nullptr, success); |       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 |       // As long as there is still a tag on the reader, do not try to read it again | ||||||
|       if (success && nfcReaderState == NFC_IDLE) |       if (success && nfcReaderState == NFC_IDLE) | ||||||
|       { |       { | ||||||
| @@ -1857,6 +1914,9 @@ void scanRfidTask(void * parameter) { | |||||||
|           { |           { | ||||||
|             oledShowProgressBar(1, 1, "Failure", "Tag read error"); |             oledShowProgressBar(1, 1, "Failure", "Tag read error"); | ||||||
|             nfcReaderState = NFC_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 |         else | ||||||
| @@ -1864,6 +1924,9 @@ void scanRfidTask(void * parameter) { | |||||||
|           //TBD: Show error here?! |           //TBD: Show error here?! | ||||||
|           oledShowProgressBar(1, 1, "Failure", "Unkown tag type"); |           oledShowProgressBar(1, 1, "Failure", "Unkown tag type"); | ||||||
|           Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!"); |           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"); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user