polling

package
v0.22.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: Apache-2.0 Imports: 7 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoTagInPoll = errors.New("no tag detected in polling cycle")

ErrNoTagInPoll indicates no tag was detected during polling (not an error condition)

Functions

This section is empty.

Types

type CardDetectionState

type CardDetectionState int

CardDetectionState represents the finite state machine for card detection

const (
	StateIdle CardDetectionState = iota
	StateTagDetected
	StateReading
	StatePostReadGrace
)

type CardState

type CardState struct {
	LastSeenTime              time.Time
	ReadStartTime             time.Time
	RemovalTimer              *time.Timer
	LastUID                   string
	LastType                  string
	TestedUID                 string
	DetectionState            CardDetectionState
	ConsecutiveStableFailures int
	Present                   bool
}

CardState tracks the state of a card on a reader

func (*CardState) CanStartRemovalTimer

func (cs *CardState) CanStartRemovalTimer() bool

CanStartRemovalTimer returns true if the state allows removal timer to run

func (*CardState) TransitionToDetected

func (cs *CardState) TransitionToDetected(timeout time.Duration, callback func())

TransitionToDetected moves to tag detected state with normal removal timeout

func (*CardState) TransitionToIdle

func (cs *CardState) TransitionToIdle()

TransitionToIdle resets to idle state

func (*CardState) TransitionToPostReadGrace

func (cs *CardState) TransitionToPostReadGrace(timeout time.Duration, callback func())

TransitionToPostReadGrace moves to post-read grace period with short timeout

func (*CardState) TransitionToReading

func (cs *CardState) TransitionToReading()

TransitionToReading moves to reading state and suspends removal timer

type Config

type Config struct {
	PollInterval       time.Duration
	CardRemovalTimeout time.Duration
	// HardwareTimeoutRetries controls how long PN532 waits for card detection
	// 0x00 = immediate return, 0x01-0xFE = retry count (~150ms each), 0xFF = infinite
	// Higher values reduce LED blinking frequency but increase detection latency
	HardwareTimeoutRetries byte
	// SleepRecovery configures automatic recovery after host sleep/wake cycles
	SleepRecovery SleepRecoveryConfig
}

Config holds polling configuration options

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default polling configuration

type DefaultRecoverer added in v0.15.0

type DefaultRecoverer struct {
	// contains filtered or unexported fields
}

DefaultRecoverer implements a tiered recovery strategy: 1. Soft reset via SAMConfiguration 2. Full reconnection via user-provided reopen function

func NewDefaultRecoverer added in v0.15.0

func NewDefaultRecoverer(
	device *pn532.Device,
	reopenFunc ReopenFunc,
	backoff time.Duration,
	maxAttempts int,
) *DefaultRecoverer

NewDefaultRecoverer creates a recoverer with tiered recovery strategy. If reopenFunc is nil, only soft reset will be attempted.

func (*DefaultRecoverer) AttemptRecovery added in v0.15.0

func (r *DefaultRecoverer) AttemptRecovery(ctx context.Context) error

AttemptRecovery implements tiered recovery: 1. Try soft reset (SAMConfiguration) - works if USB port still valid 2. If that fails and reopenFunc is provided, try full reconnection

func (*DefaultRecoverer) GetDevice added in v0.15.0

func (r *DefaultRecoverer) GetDevice() *pn532.Device

GetDevice returns the current device reference. This may return a different device after a successful reconnection.

type DeviceRecoverer added in v0.15.0

type DeviceRecoverer interface {
	// AttemptRecovery tries to recover the device connection.
	// Returns nil if recovery was successful, error otherwise.
	AttemptRecovery(ctx context.Context) error

	// GetDevice returns the current device reference (may change after reconnection)
	GetDevice() *pn532.Device
}

DeviceRecoverer handles device recovery after sleep/wake or errors

type ReopenFunc added in v0.15.0

type ReopenFunc func() (*pn532.Device, error)

ReopenFunc is a function that attempts to reopen/reconnect the device

type Session added in v0.5.0

type Session struct {
	OnSleepDetected      func()
	OnDeviceDisconnected func(err error)

	OnCardChanged  func(ctx context.Context, tag *pn532.DetectedTag) error
	OnCardDetected func(ctx context.Context, tag *pn532.DetectedTag) error
	OnCardRemoved  func()
	// contains filtered or unexported fields
}

Session handles continuous card monitoring with state machine

func NewSession added in v0.5.0

func NewSession(device *pn532.Device, config *Config) *Session

NewSession creates a new card monitoring session. If sleep recovery is enabled in config, a DefaultRecoverer is automatically created for soft reset recovery. Use SetRecoverer to provide a custom recoverer with full reconnection capability via ReopenFunc.

func (*Session) Close added in v0.5.0

func (s *Session) Close() error

Close cleans up the monitor resources

func (*Session) GetDevice added in v0.5.0

func (s *Session) GetDevice() *pn532.Device

GetDevice returns the underlying PN532 device. This may return a different device after sleep/wake recovery.

func (*Session) GetState added in v0.5.0

func (s *Session) GetState() CardState

GetState returns the current card state

func (*Session) Pause added in v0.5.0

func (s *Session) Pause()

Pause temporarily stops the polling loop This is used to coordinate with write operations

func (*Session) Resume added in v0.5.0

func (s *Session) Resume()

Resume restarts the polling loop after a pause

func (*Session) SetOnCardChanged added in v0.9.0

func (s *Session) SetOnCardChanged(callback func(context.Context, *pn532.DetectedTag) error)

SetOnCardChanged sets the callback for when the card changes. The callback receives a context that is tied to the poll cycle timeout, allowing long-running operations to be cancelled if needed.

func (*Session) SetOnCardDetected added in v0.9.0

func (s *Session) SetOnCardDetected(callback func(context.Context, *pn532.DetectedTag) error)

SetOnCardDetected sets the callback for when a card is detected. The callback receives a context that is tied to the poll cycle timeout, allowing long-running operations (like MIFARE authentication) to be cancelled if the tag is removed or the operation takes too long.

func (*Session) SetOnCardRemoved added in v0.9.0

func (s *Session) SetOnCardRemoved(callback func())

SetOnCardRemoved sets the callback for when a card is removed.

func (*Session) SetOnDeviceDisconnected added in v0.16.0

func (s *Session) SetOnDeviceDisconnected(callback func(err error))

SetOnDeviceDisconnected sets the callback for when the device is disconnected. This is called when a fatal error indicates the device is no longer available (e.g., USB unplugged). The error parameter contains the underlying cause.

func (*Session) SetOnSleepDetected added in v0.15.0

func (s *Session) SetOnSleepDetected(callback func())

SetOnSleepDetected sets the callback for when system sleep/wake is detected.

func (*Session) SetRecoverer added in v0.15.0

func (s *Session) SetRecoverer(r DeviceRecoverer)

SetRecoverer configures a custom device recoverer for sleep/wake handling. Use this to provide a recoverer with ReopenFunc for full reconnection capability beyond the default soft reset behavior.

func (*Session) Start added in v0.5.0

func (s *Session) Start(ctx context.Context) error

Start begins continuous monitoring for cards. It blocks until ctx is cancelled or an unrecoverable error occurs.

Callers must:

  1. Run Start in a dedicated goroutine.
  2. Track that goroutine (for example with a sync.WaitGroup).
  3. On shutdown, cancel the context, call Close, then wait for the goroutine.

Start returns promptly when ctx is cancelled during normal polling. During the initial hardware configuration it is bounded by startInitTimeout so a wedged transport cannot delay Start's exit indefinitely.

func (*Session) WriteToNextTag added in v0.5.0

func (s *Session) WriteToNextTag(
	sessionCtx context.Context,
	writeCtx context.Context,
	timeout time.Duration,
	writeFn func(context.Context, pn532.Tag) error,
) error

WriteToNextTag waits for the next tag detection and performs a write operation This method blocks until a tag is detected or timeout occurs sessionCtx controls session lifetime, writeCtx controls write operation lifetime

func (*Session) WriteToNextTagWithRetry added in v0.9.1

func (s *Session) WriteToNextTagWithRetry(
	sessionCtx context.Context,
	writeCtx context.Context,
	timeout time.Duration,
	maxRetries int,
	writeFn func(context.Context, pn532.Tag) error,
) error

WriteToNextTagWithRetry waits for the next tag detection and performs a write operation with automatic retry on transient errors. This is useful for handling intermittent write failures due to card placement issues or timing problems. sessionCtx controls session lifetime, writeCtx controls write operation lifetime. maxRetries specifies how many times to retry the write operation (default 3 if <= 0).

func (*Session) WriteToTag added in v0.5.0

func (s *Session) WriteToTag(
	sessionCtx context.Context,
	writeCtx context.Context,
	detectedTag *pn532.DetectedTag,
	writeFn func(context.Context, pn532.Tag) error,
) error

WriteToTag performs a thread-safe write operation to a detected tag This method pauses polling during the write to prevent interference sessionCtx controls session lifetime, writeCtx controls write operation lifetime

func (*Session) WriteToTagWithRetry added in v0.9.1

func (s *Session) WriteToTagWithRetry(
	sessionCtx context.Context,
	writeCtx context.Context,
	detectedTag *pn532.DetectedTag,
	maxRetries int,
	writeFn func(context.Context, pn532.Tag) error,
) error

WriteToTagWithRetry performs a thread-safe write operation to a detected tag with automatic retry on transient errors. This is useful for handling intermittent write failures due to card placement issues or timing problems. sessionCtx controls session lifetime, writeCtx controls write operation lifetime. maxRetries specifies how many times to retry the write operation (default 3 if <= 0).

type SleepRecoveryConfig added in v0.15.0

type SleepRecoveryConfig struct {
	// Enabled enables sleep detection and recovery attempts
	Enabled bool

	// TimeDiscontinuityThreshold is the minimum elapsed time beyond the expected
	// poll interval that indicates a sleep occurred. Default: 2 seconds
	TimeDiscontinuityThreshold time.Duration

	// MaxRecoveryAttempts is the number of recovery attempts before
	// treating as a fatal error. Default: 3
	MaxRecoveryAttempts int

	// RecoveryBackoff is the delay between recovery attempts
	RecoveryBackoff time.Duration
}

SleepRecoveryConfig configures automatic recovery after host sleep/wake

func DefaultSleepRecoveryConfig added in v0.15.0

func DefaultSleepRecoveryConfig() SleepRecoveryConfig

DefaultSleepRecoveryConfig returns sensible defaults for sleep recovery

func (SleepRecoveryConfig) DetectSleep added in v0.15.0

func (cfg SleepRecoveryConfig) DetectSleep(elapsed, pollInterval time.Duration) bool

DetectSleep checks if the elapsed time since last poll indicates a system sleep. Returns true if elapsed time exceeds (pollInterval + TimeDiscontinuityThreshold).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL