Skip to content

fix: resolve UART disconnect/reconnection detection failures#43

Merged
wizzomafizzo merged 2 commits intomainfrom
fix/uart-disconnect-reconnection
Feb 7, 2026
Merged

fix: resolve UART disconnect/reconnection detection failures#43
wizzomafizzo merged 2 commits intomainfrom
fix/uart-disconnect-reconnection

Conversation

@wizzomafizzo
Copy link
Member

Summary

  • Detection cache: clear stale entries when no devices found; filter cached results through IgnorePaths/Blocklist (previously bypassed on cache hit)
  • Synthetic response: verify device exists before returning fake "no tags" response in receiveFrame, preventing disconnect from being masked for one poll cycle
  • Post-reset health check: add DeviceHealthChecker interface; check device health after failed hard reset on NoACK, eliminating a wasted poll cycle before disconnect is recognized
  • UART IsConnected(): add disconnected flag set on device-gone detection during I/O, so IsConnected() returns false immediately after unplug
  • Read error wrapping: wrap port.Read errors as TransportError with proper ErrorType so IsFatal() classifies them without relying on serial library error internals
  • Export IsDeviceGoneError: make it available for cross-package use

Test plan

  • make check passes (lint + tests with race detection + deadlock check)
  • New tests for cache invalidation on device disappearance
  • New tests for cache filtering with IgnorePaths and Blocklist
  • New tests for NoACK + hard reset failure leading to proper disconnect detection
  • New tests for IsDeviceGoneError export
  • Manual testing: plug/unplug PN532 UART device with zaparoo-core running

Fix multiple bugs that prevented reliable detection of PN532 UART device
disconnection and reconnection:

- Clear stale detection cache when no devices found, and filter cached
  results through IgnorePaths/Blocklist (previously bypassed on cache hit)
- Add device existence check before returning synthetic "no tags" response
  in receiveFrame, preventing disconnect masking for one poll cycle
- Add DeviceHealthChecker interface and check device health after failed
  hard reset on NoACK errors, eliminating a wasted poll cycle
- Add disconnected flag to UART transport so IsConnected() returns false
  after device-gone is detected during I/O
- Wrap port.Read errors as TransportError with proper ErrorType so
  IsFatal() can classify them without relying on serial library internals
- Export IsDeviceGoneError for cross-package use
@codecov
Copy link

codecov bot commented Feb 7, 2026

Codecov Report

❌ Patch coverage is 74.35897% with 20 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
transport.go 0.00% 8 Missing ⚠️
transport/uart/uart.go 79.41% 6 Missing and 1 partial ⚠️
detection/detector.go 83.33% 1 Missing and 2 partials ⚠️
polling/session.go 87.50% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

- UART: tests for wrapReadError (transient + device-gone), CheckHealth
  (healthy, already-disconnected, device-file-gone), IsConnected with
  disconnected flag, handleWriteError with OS-level EIO, markDisconnected,
  checkDeviceExists setting disconnected flag
- Polling: test for checkDeviceHealth with nil device
@wizzomafizzo wizzomafizzo merged commit bee5e5f into main Feb 7, 2026
12 checks passed
@wizzomafizzo wizzomafizzo deleted the fix/uart-disconnect-reconnection branch February 7, 2026 11: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