Browse Source

Fix Read Tag diagnostic rejecting SAK 0x04 NTAG tags

  The read_tag.py diagnostic script only accepted SAK 0x00 for NTAG,
  showing "Unsupported tag type" for chips reporting SAK 0x04 (MIFARE
  Ultralight family). The daemon already handled both values — the
  diagnostic was missed. Now accepts both 0x00 and 0x04.
maziggy 2 months ago
parent
commit
e237d3ba28
2 changed files with 9 additions and 3 deletions
  1. 1 0
      CHANGELOG.md
  2. 8 3
      spoolbuddy/scripts/read_tag.py

+ 1 - 0
CHANGELOG.md

@@ -22,6 +22,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **SpoolBuddy System Tab** — Added a "System" tab to SpoolBuddy Settings showing live OS stats from the Raspberry Pi: CPU temperature, core count, load average, memory usage, disk usage, OS distro/kernel/architecture, Python version, and system uptime. Stats are collected by the daemon every heartbeat (10s) using stdlib-only reads from `/proc` and `/sys` — no additional dependencies required. Usage bars turn amber at 70% and red at 90%; CPU temperature is color-coded green/amber/red.
 - **SpoolBuddy System Tab** — Added a "System" tab to SpoolBuddy Settings showing live OS stats from the Raspberry Pi: CPU temperature, core count, load average, memory usage, disk usage, OS distro/kernel/architecture, Python version, and system uptime. Stats are collected by the daemon every heartbeat (10s) using stdlib-only reads from `/proc` and `/sys` — no additional dependencies required. Usage bars turn amber at 70% and red at 90%; CPU temperature is color-coded green/amber/red.
 
 
 ### Fixed
 ### Fixed
+- **SpoolBuddy Read Tag Diagnostic Rejects SAK 0x04 Tags** — The "Read Tag" diagnostic script only accepted SAK `0x00` for NTAG, but some NTAG chips (MIFARE Ultralight family) report SAK `0x04`. The daemon already handled both values — the diagnostic script was missed. Now accepts SAK `0x00` and `0x04` for NTAG reads.
 - **Delete Tag Leaves Stale Tag Type** — The "Delete Tag" button in the spool edit modal only cleared `tag_uid` but left `tray_uuid`, `tag_type`, and `data_origin` intact. All tag-related fields are now cleared together.
 - **Delete Tag Leaves Stale Tag Type** — The "Delete Tag" button in the spool edit modal only cleared `tag_uid` but left `tray_uuid`, `tag_type`, and `data_origin` intact. All tag-related fields are now cleared together.
 - **SpoolBuddy NFC Write Fails on NTAG Tags** — Multiple issues prevented writing to NTAG 213/215/216 tags. (1) Some chips report SAK `0x04` (MIFARE Ultralight family) instead of `0x00` during anticollision — both `0x00` and `0x04` are now accepted. (2) TX CRC was disabled for NTAG commands but the spec requires it — enabled for both WRITE and READ. (3) The PN5180 state machine needed IDLE→TRANSCEIVE resets (not just `set_transceive_mode()`) and Crypto1 cleared before NTAG operations. (4) The 4-bit WRITE ACK cannot be captured by the PN5180 (SOF detected but no RX_IRQ) — removed per-page ACK checking. (5) Post-write read-back verification also failed (second READ command gets no response from the PN5180) — removed verification since the tag reliably ACKs each write.
 - **SpoolBuddy NFC Write Fails on NTAG Tags** — Multiple issues prevented writing to NTAG 213/215/216 tags. (1) Some chips report SAK `0x04` (MIFARE Ultralight family) instead of `0x00` during anticollision — both `0x00` and `0x04` are now accepted. (2) TX CRC was disabled for NTAG commands but the spec requires it — enabled for both WRITE and READ. (3) The PN5180 state machine needed IDLE→TRANSCEIVE resets (not just `set_transceive_mode()`) and Crypto1 cleared before NTAG operations. (4) The 4-bit WRITE ACK cannot be captured by the PN5180 (SOF detected but no RX_IRQ) — removed per-page ACK checking. (5) Post-write read-back verification also failed (second READ command gets no response from the PN5180) — removed verification since the tag reliably ACKs each write.
 - **Database Connection Pool Exhaustion on Large Printer Farms** — Users with 100+ printers connected simultaneously experienced `QueuePool limit of size 10 overflow 20 reached, connection timed out` errors. Increased the SQLAlchemy connection pool from 30 total (10 base + 20 overflow) to 220 (20 base + 200 overflow), and raised the SQLite busy_timeout from 5 to 15 seconds to reduce write contention under heavy concurrent MQTT updates.
 - **Database Connection Pool Exhaustion on Large Printer Farms** — Users with 100+ printers connected simultaneously experienced `QueuePool limit of size 10 overflow 20 reached, connection timed out` errors. Increased the SQLAlchemy connection pool from 30 total (10 base + 20 overflow) to 220 (20 base + 200 overflow), and raised the SQLite busy_timeout from 5 to 15 seconds to reduce write contention under heavy concurrent MQTT updates.

+ 8 - 3
spoolbuddy/scripts/read_tag.py

@@ -614,7 +614,12 @@ def main():
             sys.exit(1)
             sys.exit(1)
 
 
         uid, sak = result
         uid, sak = result
-        tag_types = {0x00: "NTAG", 0x08: "MIFARE Classic 1K", 0x18: "MIFARE Classic 4K"}
+        tag_types = {
+            0x00: "NTAG",
+            0x04: "NTAG (MIFARE Ultralight)",
+            0x08: "MIFARE Classic 1K",
+            0x18: "MIFARE Classic 4K",
+        }
         print(f"    UID : {uid.hex().upper()}")
         print(f"    UID : {uid.hex().upper()}")
         print(f"    SAK : 0x{sak:02X} ({tag_types.get(sak, 'Unknown')})")
         print(f"    SAK : 0x{sak:02X} ({tag_types.get(sak, 'Unknown')})")
 
 
@@ -640,8 +645,8 @@ def main():
                 raw += blocks[block_num]
                 raw += blocks[block_num]
             print(f"\n    Raw payload ({len(raw)} bytes): {raw.hex().upper()}")
             print(f"\n    Raw payload ({len(raw)} bytes): {raw.hex().upper()}")
 
 
-        elif sak == 0x00:
-            # NTAG — SpoolEase / OpenPrintTag
+        elif sak in (0x00, 0x04):
+            # NTAG / MIFARE Ultralight family — SpoolEase / OpenPrintTag
             print("[4] Reading NTAG data (pages 4-20)...")
             print("[4] Reading NTAG data (pages 4-20)...")
             ntag_data = nfc.read_ntag(uid)
             ntag_data = nfc.read_ntag(uid)