@@ -25,6 +25,7 @@ import (
2525 "context"
2626 "errors"
2727 "fmt"
28+ "runtime"
2829 "strings"
2930 "time"
3031)
@@ -245,6 +246,16 @@ func (t *NTAGTag) ReadNDEF() (*NDEFMessage, error) {
245246
246247 data , err := t .readNDEFDataWithFastRead (header , totalBytes )
247248 if err != nil {
249+ // CRITICAL: Clear transport state after failed InCommunicateThru operation
250+ // This prevents firmware lockup when switching to InDataExchange protocol
251+ fallbackReason := "FastRead failed"
252+ if runtime .GOOS == "windows" && t .isUARTTransport () {
253+ fallbackReason = "FastRead failed (Windows UART has size limits to prevent PN532 firmware lockup)"
254+ }
255+ debugf ("NTAG %s, clearing transport state before fallback: %v" , fallbackReason , err )
256+ if clearErr := t .device .ClearTransportState (); clearErr != nil {
257+ debugf ("NTAG transport state clearing failed: %v" , clearErr )
258+ }
248259 return t .readNDEFBlockByBlock ()
249260 }
250261
@@ -339,6 +350,49 @@ func (t *NTAGTag) ensureTagTypeDetected() error {
339350 return nil
340351}
341352
353+ // getMaxFastReadPages returns the maximum number of pages to read in a single FastRead operation
354+ // This is platform-specific to avoid PN532 firmware lockups with large InCommunicateThru payloads
355+ func (t * NTAGTag ) getMaxFastReadPages () uint8 {
356+ // Check if user has explicitly configured a limit
357+ if t .device .config .MaxFastReadPages > 0 {
358+ // Bounds check to prevent integer overflow and ensure reasonable limits
359+ switch {
360+ case t .device .config .MaxFastReadPages > 255 :
361+ debugf ("NTAG MaxFastReadPages %d exceeds uint8 limit, capping to 255" , t .device .config .MaxFastReadPages )
362+ return 255
363+ default :
364+ // #nosec G115 - bounds checked above
365+ return uint8 (t .device .config .MaxFastReadPages )
366+ }
367+ }
368+
369+ // Apply platform-specific defaults
370+ if runtime .GOOS == "windows" {
371+ // Check if using UART transport which is most prone to the firmware lockup
372+ if t .isUARTTransport () {
373+ // 16 pages = 64 bytes - safe limit that avoids PN532 firmware lockups on Windows UART
374+ // Based on research showing InCommunicateThru becomes unreliable beyond 64 bytes
375+ debugf ("NTAG applying Windows UART FastRead limit: 16 pages (64 bytes) to prevent firmware lockup" )
376+ debugf ("NTAG tip: set config.MaxFastReadPages to override this Windows-specific safety limit" )
377+ return 16
378+ }
379+ debugf ("NTAG Windows detected but non-UART transport, using default FastRead limits" )
380+ }
381+
382+ // Default: no limit (use original behavior)
383+ return 60
384+ }
385+
386+ // isUARTTransport checks if the current transport is UART-based
387+ func (t * NTAGTag ) isUARTTransport () bool {
388+ // Check if transport has UART capability
389+ if checker , ok := t .device .transport .(TransportCapabilityChecker ); ok {
390+ return checker .HasCapability (CapabilityUART )
391+ }
392+ // Fallback: assume it might be UART to be safe
393+ return true
394+ }
395+
342396func (t * NTAGTag ) readNDEFDataWithFastRead (_ * ndefHeader , totalBytes int ) ([]byte , error ) {
343397 if t .fastReadSupported != nil && ! * t .fastReadSupported {
344398 debugf ("NTAG FastRead disabled - using block-by-block fallback" )
@@ -348,7 +402,7 @@ func (t *NTAGTag) readNDEFDataWithFastRead(_ *ndefHeader, totalBytes int) ([]byt
348402 debugf ("NTAG attempting FastRead for NDEF data (%d bytes)" , totalBytes )
349403 readRange := t .calculateReadRange (totalBytes )
350404
351- maxPagesPerRead := uint8 ( 60 )
405+ maxPagesPerRead := t . getMaxFastReadPages ( )
352406
353407 if readRange .endPage - readRange .startPage + 1 <= maxPagesPerRead {
354408 debugf ("NTAG using single FastRead for pages %d-%d" , readRange .startPage , readRange .endPage )
0 commit comments