Skip to content

fix(readers): libnfc connection strings, double-close race, and NTP false wake#532

Merged
wizzomafizzo merged 5 commits intomainfrom
fix/libnfc-i2c-connection-string
Feb 9, 2026
Merged

fix(readers): libnfc connection strings, double-close race, and NTP false wake#532
wizzomafizzo merged 5 commits intomainfrom
fix/libnfc-i2c-connection-string

Conversation

@wizzomafizzo
Copy link
Member

@wizzomafizzo wizzomafizzo commented Feb 9, 2026

Summary

  • libnfc connection string format: libnfc driver names require underscores (pn532_i2c, pn532_uart) but ConnectionString() normalization was stripping them, producing invalid strings that libnfc cannot recognize. Extracts translation into testable toLibnfcConnStr() with full regression coverage.
  • NTP clock sync false wake detection: On MiSTer (no RTC), the system boots at epoch (1970). When NTP syncs, SleepWakeMonitor misinterprets the ~56-year wall clock jump as wake-from-sleep, triggering bulk reader reconnection. Fixed by skipping wake detection when the previous timestamp was from an unreliable clock (year < 2024).
  • libnfc double-close race: The libnfc reader had no mutex protecting polling and pnd fields. Concurrent Close() calls could double-close the C library handle, crashing the service. Fixed by adding syncutil.RWMutex protection following the pattern used by acr122pcsc and pn532 readers.

…cores

libnfc driver names require underscores (e.g. "pn532_i2c", "pn532_uart")
but ConnectionString() normalization was stripping them, producing invalid
strings like "pn532i2c:/dev/i2c-2" that libnfc cannot recognize. This
caused all PN532 I2C and UART connections via libnfc to fail with
"cannot open NFC device" after 10 retries.

Fixes connection string translation in Open(), Detect(), and both
auto-detect functions (detectSerialReaders, detectI2CReaders).
@sentry
Copy link

sentry bot commented Feb 9, 2026

Codecov Report

❌ Patch coverage is 41.50943% with 31 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/readers/libnfc/libnfc.go 38.00% 31 Missing ⚠️

📢 Thoughts on this report? Let us know!

On MiSTer (no RTC), the system boots at epoch (1970). When NTP syncs,
the wall clock jumps ~56 years. SleepWakeMonitor was interpreting this
as a wake-from-sleep event, triggering bulk reader reconnection and
causing the "keeps disconnecting" bug.

Now Check() skips wake detection when lastCheck was from an unreliable
clock (year < 2024), since the elapsed time is meaningless in that case.
The libnfc reader had no mutex protecting its polling and pnd fields.
When SleepWakeMonitor triggered reconnection, Close() could race with
the polling goroutine, causing a double-close of the C library handle
and crashing the service.

Add syncutil.RWMutex to protect shared state, following the pattern
already used by acr122pcsc and pn532 readers. Close() now nil-checks
and nil-outs the device handle under lock before closing it, preventing
the double-close race.
@wizzomafizzo wizzomafizzo changed the title fix(readers): use correct libnfc connection string format with underscores fix(readers): libnfc connection strings, double-close race, and NTP false wake Feb 9, 2026
…methods

Cover Connected, Info, Path, Close (nil device), ReaderID, and
validateWriteParameters — all pure-logic paths that don't require
the libnfc C library.
…ng Close

Capture r.pnd into a local variable under the mutex at the start of
writeTag, matching the pattern already used by the polling goroutine.
Previously, Close() could nil out r.pnd while writeTag was mid-operation,
causing a panic on the next r.pnd method call.
@wizzomafizzo wizzomafizzo merged commit 3552fed into main Feb 9, 2026
9 of 10 checks passed
@wizzomafizzo wizzomafizzo deleted the fix/libnfc-i2c-connection-string branch February 9, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant