pn532

package module
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: 18 Imported by: 1

README

go-pn532

Go library for PN532 NFC readers. Supports UART/I2C/SPI transports and NTAG21X/MIFARE Classic/FeliCa tags with NDEF support.

Documentation

Index

Constants

View Source
const (
	WakeupHSU     byte = 0x01 // Wake-up by High Speed UART
	WakeupSPI     byte = 0x02 // Wake-up by SPI
	WakeupI2C     byte = 0x04 // Wake-up by I2C
	WakeupGPIOP32 byte = 0x08 // Wake-up by GPIO P32
	WakeupGPIOP34 byte = 0x10 // Wake-up by GPIO P34
	WakeupRF      byte = 0x20 // Wake-up by RF field
	WakeupINT1    byte = 0x80 // Wake-up by GPIO P72/INT1
)

PowerDownWakeupFlags provides constants for PowerDown wake-up sources

View Source
const (
	DiagnoseCommunicationTest = 0x00
	DiagnoseROMTest           = 0x01
	DiagnoseRAMTest           = 0x02
	// 0x03 is not used
	DiagnosePollingTest     = 0x04
	DiagnoseEchoBackTest    = 0x05
	DiagnoseAttentionTest   = 0x06
	DiagnoseSelfAntennaTest = 0x07
)

DiagnoseTestNumber constants

View Source
const (
	MIFAREKeyA = 0x00
	MIFAREKeyB = 0x01
)

Key types

View Source
const (
	AuthTypeOpen    = 0x0001
	AuthTypeWPA     = 0x0002
	AuthTypeWPAPSK  = 0x0004
	AuthTypeWPA2    = 0x0008
	AuthTypeWPA2PSK = 0x0020

	EncryptTypeNone = 0x0001
	EncryptTypeWEP  = 0x0002
	EncryptTypeTKIP = 0x0004
	EncryptTypeAES  = 0x0008
)

WiFi authentication and encryption types

View Source
const (
	TLVTypeNull          = 0x00 // NULL TLV - padding byte, no length field
	TLVTypeLockControl   = 0x01 // Lock Control TLV - defines lock bit positions
	TLVTypeMemoryControl = 0x02 // Memory Control TLV - defines reserved memory
	TLVTypeNDEF          = 0x03 // NDEF Message TLV - contains NDEF data
	TLVTypeTerminator    = 0xFE // Terminator TLV - end of data area, no length field
)

TLV type constants per NFC Forum Type 2 Tag specification

View Source
const (
	TNFEmpty        = 0x00
	TNFWellKnown    = 0x01
	TNFMediaType    = 0x02
	TNFAbsoluteURI  = 0x03
	TNFExternalType = 0x04
	TNFUnknown      = 0x05
	TNFUnchanged    = 0x06
	TNFReserved     = 0x07
)

TNF (Type Name Format) values

View Source
const (
	// DefaultConnectionRetries is the number of attempts to connect to a device.
	DefaultConnectionRetries = 3
	// ConnectionInitialBackoff is the initial delay between connection attempts.
	// Industry standard is 100ms baseline for NFC operations.
	ConnectionInitialBackoff = 100 * time.Millisecond
	// ConnectionMaxBackoff is the maximum delay between connection attempts.
	ConnectionMaxBackoff = 500 * time.Millisecond
	// ConnectionBackoffMultiplier is the exponential backoff multiplier.
	ConnectionBackoffMultiplier = 2.0
	// ConnectionJitter is the random jitter factor (0.0-1.0) to prevent thundering herd.
	ConnectionJitter = 0.1
	// ConnectionRetryTimeout is the overall timeout for all connection attempts.
	ConnectionRetryTimeout = 10 * time.Second
)

Connection retry constants control device connection behavior.

View Source
const (
	// DefaultPassiveActivationRetries controls InListPassiveTarget internal retries.
	// Each retry is approximately 100ms per PN532 datasheet.
	// 0x0A (10) provides ~1 second timeout before giving up.
	DefaultPassiveActivationRetries byte = 0x0A

	// DefaultPollingRetries controls MxRtyATR for polling loops.
	// 0x20 (32) provides approximately 4.8 seconds (32 * 150ms per retry).
	DefaultPollingRetries byte = 0x20
)

PN532 hardware retry constants (MxRty parameters) control the PN532 chip's internal retry behavior for RF operations.

View Source
const (
	// NTAGBlockReadRetries is the number of attempts for block read operations.
	NTAGBlockReadRetries = 3
	// NTAGFallbackRetries is the number of attempts when using InCommunicateThru fallback.
	NTAGFallbackRetries = 3
	// NTAGTimeoutRetryDelay is the delay before retrying after a timeout error.
	NTAGTimeoutRetryDelay = 100 * time.Millisecond
)

Tag operation retry constants control NTAG read/write retry behavior.

View Source
const (
	// NDEFMaxRetries is the number of attempts for NDEF operations.
	NDEFMaxRetries = 3
	// NDEFRetryDelay1 is the delay before the first retry (after initial attempt).
	NDEFRetryDelay1 = 100 * time.Millisecond
	// NDEFRetryDelay2 is the delay before the second retry.
	NDEFRetryDelay2 = 200 * time.Millisecond
	// NDEFRetryDelay3 is the delay before the third retry.
	NDEFRetryDelay3 = 400 * time.Millisecond
)

NDEF operation retry constants control NDEF read/write retry behavior. Uses 2x exponential backoff: 100ms → 200ms → 400ms.

View Source
const (
	// TransportACKRetries is the number of attempts to receive ACK from PN532.
	TransportACKRetries = 3
	// TransportDrainRetries is the number of attempts to drain stale data from buffer.
	TransportDrainRetries = 3
	// TransportWakeupRetries is the number of attempts to wake the PN532 from sleep.
	TransportWakeupRetries = 3
	// TransportI2CFrameRetries is the number of attempts for I2C frame reception.
	// I2C needs more retries due to clock stretching and bus arbitration.
	TransportI2CFrameRetries = 5
)

Transport retry constants control low-level transport communication.

View Source
const (
	// UARTWakeupDelay1 is the initial wakeup delay.
	UARTWakeupDelay1 = 10 * time.Millisecond
	// UARTWakeupDelay2 is the second wakeup delay (deeper sleep).
	UARTWakeupDelay2 = 50 * time.Millisecond
	// UARTWakeupDelay3 is the final wakeup delay (deepest sleep).
	UARTWakeupDelay3 = 100 * time.Millisecond
)

UART wakeup delays use progressive timing to handle different sleep states.

View Source
const (
	// TransportACKDelay1 is the initial ACK wait delay.
	TransportACKDelay1 = 50 * time.Millisecond
	// TransportACKDelay2 is the second ACK wait delay.
	TransportACKDelay2 = 100 * time.Millisecond
	// TransportACKDelay3 is the final ACK wait delay.
	TransportACKDelay3 = 200 * time.Millisecond

	// TransportACKTimeout is the maximum time to wait for an ACK response.
	// ACKs should arrive quickly - this timeout catches device lockups fast.
	// Note: This caps the per-retry ACK wait; total time = ACKTimeout * ACKRetries.
	TransportACKTimeout = 500 * time.Millisecond
)

Transport ACK delays for I2C and SPI use progressive timing.

Variables

View Source
var (
	ErrNoTagDetected  = errors.New("no tag detected")
	ErrTimeout        = errors.New("operation timeout")
	ErrInvalidTag     = errors.New("invalid tag type")
	ErrNotImplemented = errors.New("not implemented")
)

Device errors

View Source
var (
	// Transport errors - potentially retryable
	ErrTransportTimeout  = errors.New("transport timeout")
	ErrTransportWrite    = errors.New("transport write failed")
	ErrTransportRead     = errors.New("transport read failed")
	ErrTransportClosed   = errors.New("transport is closed")
	ErrTransportNotReady = errors.New("transport not ready")

	// Communication errors - potentially retryable
	ErrCommunicationFailed = errors.New("communication failed")
	ErrNoACK               = errors.New("no ACK received")
	ErrNACKReceived        = errors.New("NACK received")
	ErrFrameCorrupted      = errors.New("frame corrupted")
	ErrChecksumMismatch    = errors.New("checksum mismatch")

	// Device errors - generally not retryable
	ErrDeviceNotFound      = errors.New("device not found")
	ErrDeviceNotSupported  = errors.New("device not supported")
	ErrCommandFailed       = errors.New("command execution failed")
	ErrInvalidResponse     = errors.New("invalid response format")
	ErrCommandNotSupported = errors.New("command not supported by device")

	// Tag errors - generally not retryable
	ErrTagNotFound             = errors.New("tag not found")
	ErrTagAuthFailed           = errors.New("tag authentication failed")
	ErrTagReadFailed           = errors.New("tag read failed")
	ErrTagWriteFailed          = errors.New("tag write failed")
	ErrTagUnsupported          = errors.New("tag type not supported")
	ErrTagEmptyData            = errors.New("tag detected but returned empty data")
	ErrTagDataCorrupt          = errors.New("tag data appears corrupted")
	ErrTagUnreliable           = errors.New("tag readings are inconsistent")
	ErrTagIncompatible         = errors.New("tag is incompatible with NDEF formatting")
	ErrWriteVerificationFailed = errors.New("write verification failed: data mismatch")

	// Tag protocol-level classifications. These categorise the underlying
	// PN532 error code so callers can branch on the cause of a failure via
	// errors.Is without parsing raw error codes. They are typically chained
	// alongside a higher-level sentinel (e.g. ErrTagIncompatible) so the
	// error chain carries both "what operation failed" and "why".
	ErrTagTimeout      = errors.New("tag timeout")              // PN532 0x01
	ErrTagDataMismatch = errors.New("tag data format mismatch") // PN532 0x13
	ErrTagInvalidState = errors.New("tag in invalid state")     // PN532 0x27

	// Data errors - not retryable
	ErrInvalidParameter = errors.New("invalid parameter")
	ErrDataTooLarge     = errors.New("data too large")
	ErrInvalidFormat    = errors.New("invalid data format")
)

Error categories for better error handling and retry logic

View Source
var (
	// Security constants for memory protection
	MaxNDEFMessageSize = 8192 // Maximum NDEF message size (8KB)
	MaxNDEFRecordCount = 255  // Maximum records per message
	MaxNDEFPayloadSize = 4096 // Maximum payload size per record
	MaxNDEFTypeLength  = 255  // Maximum type field length
	MaxNDEFIDLength    = 255  // Maximum ID field length

	// Error for security violations
	ErrSecurityViolation = errors.New("security violation: data exceeds safety limits")

	// ErrNoNDEF is returned when no NDEF record is found.
	ErrNoNDEF = errors.New("no NDEF record found")
	// ErrInvalidNDEF is returned when the NDEF format is invalid.
	ErrInvalidNDEF = errors.New("invalid NDEF format")
)
View Source
var (
	ErrTLVDataTooShort    = errors.New("TLV data too short")
	ErrTLVInvalidLength   = errors.New("TLV invalid length format")
	ErrTLVNDEFNotFound    = errors.New("NDEF TLV not found")
	ErrTLVTerminatorFirst = errors.New("terminator TLV before NDEF")
)

TLV parsing errors

View Source
var (
	ErrInvalidTLV           = errors.New("invalid TLV structure")
	ErrInvalidRecordHeader  = errors.New("invalid NDEF record header")
	ErrInvalidTNF           = errors.New("invalid TNF value")
	ErrInvalidTypeLength    = errors.New("invalid TYPE length")
	ErrInvalidPayloadLength = errors.New("invalid PAYLOAD length")
	ErrInvalidIDLength      = errors.New("invalid ID length")
	ErrIncompleteRecord     = errors.New("incomplete NDEF record")
	ErrInvalidMBME          = errors.New("invalid MB/ME flags")
	ErrInvalidChunking      = errors.New("invalid chunking")
	ErrTooManyRecords       = errors.New("too many NDEF records")
)

NDEF validation errors

Functions

func BuildNDEFMessageEx

func BuildNDEFMessageEx(records []NDEFRecord) ([]byte, error)

BuildNDEFMessageEx creates NDEF data from multiple records

func BuildVCardRecord

func BuildVCardRecord(contact *VCardContact) (*ndef.Record, error)

BuildVCardRecord creates an NDEF record with vCard data

func BuildWiFiRecord

func BuildWiFiRecord(cred WiFiCredential) (*ndef.Record, error)

BuildWiFiRecord creates an NDEF record with WiFi credentials

func CloseSessionLog added in v0.17.0

func CloseSessionLog() error

CloseSessionLog closes the current session log file.

func Debugf added in v0.10.0

func Debugf(format string, args ...any)

Debugf prints debug information. Always writes to session log file (if initialized) with timestamp. Only prints to console when debug mode is enabled.

func Debugln added in v0.10.0

func Debugln(args ...any)

Debugln prints debug information. Always writes to session log file (if initialized) with timestamp. Only prints to console when debug mode is enabled.

func ExtractNDEFFromTLV added in v0.14.0

func ExtractNDEFFromTLV(data []byte) ([]byte, error)

ExtractNDEFFromTLV extracts the NDEF payload from TLV-encoded data. This is a convenience function that combines ScanForNDEFTLV with payload extraction.

func GetClaimedSizeFromCC added in v0.13.0

func GetClaimedSizeFromCC(ccData []byte) int

GetClaimedSizeFromCC returns the claimed memory size from the CC size field

func GetSessionLogPath added in v0.17.0

func GetSessionLogPath() string

GetSessionLogPath returns the current session log file path.

func HasTrace added in v0.9.0

func HasTrace(err error) bool

HasTrace checks if an error contains trace data

func InitSessionLog added in v0.17.0

func InitSessionLog() (string, error)

InitSessionLog creates a new session log file in the current directory. Returns the log file path for display to the user.

func IsCommandNotSupported added in v0.8.0

func IsCommandNotSupported(err error) bool

IsCommandNotSupported checks if an error indicates a command is not supported

func IsDeviceGoneError added in v0.20.3

func IsDeviceGoneError(err error) bool

IsDeviceGoneError checks for OS-level errors indicating device disconnection. These errors occur when a USB device is unplugged during I/O operations.

func IsFatal added in v0.15.0

func IsFatal(err error) bool

IsFatal returns true if the error indicates the device/connection is gone and polling should stop entirely. This is distinct from IsRetryable which indicates whether a single operation can be retried.

func IsGenuineNXP added in v0.13.0

func IsGenuineNXP(uid []byte) bool

IsGenuineNXP returns true if the UID indicates a genuine NXP chip. Clone tags typically have non-0x04 first bytes.

func IsPN532AuthenticationError added in v0.8.0

func IsPN532AuthenticationError(err error) bool

IsPN532AuthenticationError checks if an error is a PN532 authentication failure

func IsPN532RFError added in v0.17.0

func IsPN532RFError(err error) bool

IsPN532RFError checks if an error is a PN532 RF communication error. These errors are transient and common during card sliding.

func IsPN532TimeoutError added in v0.8.0

func IsPN532TimeoutError(err error) bool

IsPN532TimeoutError checks if an error is a PN532 timeout

func IsRetryable

func IsRetryable(err error) bool

IsRetryable returns true if the error is potentially retryable

func RetryWithConfig

func RetryWithConfig(ctx context.Context, config *RetryConfig, retryFunc RetryableFunc) error

RetryWithConfig executes a function with retry logic

func SetDebugEnabled

func SetDebugEnabled(enabled bool)

SetDebugEnabled allows programmatic control of debug logging Useful for testing or application-controlled debug modes

func TLVDebugInfo added in v0.14.0

func TLVDebugInfo(data []byte) string

TLVDebugInfo returns a human-readable description of TLV blocks in the data. Useful for debugging tag contents.

func ValidateNDEFMessage

func ValidateNDEFMessage(data []byte) error

ValidateNDEFMessage validates a complete NDEF message including TLV wrapper

func WriteNDEFWithRetry added in v0.9.1

func WriteNDEFWithRetry(ctx context.Context, writeFunc WriteNDEFFunc, maxRetries int, tagType string) error

WriteNDEFWithRetry wraps NDEF write operations with retry logic. This addresses intermittent write failures due to card placement issues or timing problems. The entire write operation is retried on failure (operation-level retry).

Types

type AccessControlConfig

type AccessControlConfig struct {
	Protection       bool  // false = write protection, true = read/write protection
	ConfigLock       bool  // lock configuration pages
	AuthFailureLimit uint8 // limit failed authentication attempts (0 = disabled, 1-7 = limit)
}

AccessControlConfig holds the access control settings for NTAG tags

type Address

type Address struct {
	Street     string
	City       string
	State      string
	PostalCode string
	Country    string
}

Address represents a physical address

type AutoPollResult

type AutoPollResult struct {
	TargetData []byte
	Type       AutoPollTarget
}

AutoPollResult contains the result of an InAutoPoll operation.

func (*AutoPollResult) ToDetectedTag

func (a *AutoPollResult) ToDetectedTag() *DetectedTag

ToDetectedTag converts an AutoPollResult to a DetectedTag. Handles UID extraction and tag type mapping.

type AutoPollTarget

type AutoPollTarget byte

AutoPollTarget defines the target type for InAutoPoll.

const (
	// AutoPollGeneric106kbps is the generic passive mode for ISO14443-4A, Mifare, DEP.
	AutoPollGeneric106kbps AutoPollTarget = 0x00
	// AutoPollGeneric212kbps is the generic passive mode for FeliCa, DEP.
	AutoPollGeneric212kbps AutoPollTarget = 0x01
	// AutoPollGeneric424kbps is the generic passive mode for FeliCa, DEP.
	AutoPollGeneric424kbps AutoPollTarget = 0x02

	// AutoPollISO14443B is for ISO14443-4B specific passive mode.
	AutoPollISO14443B AutoPollTarget = 0x03
	// AutoPollJewel is for Innovision Jewel tags.
	AutoPollJewel AutoPollTarget = 0x04
	// AutoPollMifare is for Mifare tags.
	AutoPollMifare AutoPollTarget = 0x10
	// AutoPollFeliCa212 is for FeliCa at 212 kbps.
	AutoPollFeliCa212 AutoPollTarget = 0x11
	// AutoPollFeliCa424 is for FeliCa at 424 kbps.
	AutoPollFeliCa424 AutoPollTarget = 0x12
	// AutoPollISO14443A is for ISO14443-4A.
	AutoPollISO14443A AutoPollTarget = 0x20
	// AutoPollISO14443B4 is for ISO14443-4B.
	AutoPollISO14443B4 AutoPollTarget = 0x23
)

type BaseTag

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

BaseTag provides common tag functionality

func (*BaseTag) DebugInfo

func (t *BaseTag) DebugInfo(_ context.Context) string

DebugInfo returns detailed debug information about the tag

func (*BaseTag) DebugInfoWithNDEF

func (t *BaseTag) DebugInfoWithNDEF(ctx context.Context, ndefReader interface {
	ReadNDEF(context.Context) (*NDEFMessage, error)
},
) string

DebugInfoWithNDEF returns detailed debug information about the tag with NDEF support

func (*BaseTag) IsGenuine added in v0.13.0

func (t *BaseTag) IsGenuine() bool

IsGenuine returns true if the chip appears to be from a known manufacturer. Returns false for unknown/clone chips.

func (*BaseTag) IsMIFARE4K

func (t *BaseTag) IsMIFARE4K() bool

IsMIFARE4K returns true if this is a MIFARE Classic 4K card

func (*BaseTag) Manufacturer added in v0.13.0

func (t *BaseTag) Manufacturer() Manufacturer

Manufacturer returns the chip manufacturer identified from the UID.

func (*BaseTag) ReadBlock

func (*BaseTag) ReadBlock(_ context.Context, _ uint8) ([]byte, error)

ReadBlock provides a default implementation that returns an error Specific tag types should override this method

func (*BaseTag) ReadNDEF

func (*BaseTag) ReadNDEF(_ context.Context) (*NDEFMessage, error)

ReadNDEF provides a default implementation that returns an error Specific tag types should override this method

func (*BaseTag) ReadText

func (t *BaseTag) ReadText(ctx context.Context) (string, error)

ReadText reads the first text record from the tag's NDEF data This is a convenience method that handles the common case of reading simple text

func (*BaseTag) Summary

func (t *BaseTag) Summary() string

Summary returns a brief summary of the tag

func (*BaseTag) Type

func (t *BaseTag) Type() TagType

Type returns the tag type

func (*BaseTag) UID

func (t *BaseTag) UID() string

UID returns the tag's unique identifier as hex string

func (*BaseTag) UIDBytes

func (t *BaseTag) UIDBytes() []byte

UIDBytes returns the tag's unique identifier as bytes

func (*BaseTag) WriteBlock

func (*BaseTag) WriteBlock(_ context.Context, _ uint8, _ []byte) error

WriteBlock provides a default implementation that returns an error Specific tag types should override this method

func (*BaseTag) WriteNDEF

func (*BaseTag) WriteNDEF(_ context.Context, _ *NDEFMessage) error

WriteNDEF provides a default implementation that returns an error Specific tag types should override this method

func (*BaseTag) WriteText

func (t *BaseTag) WriteText(ctx context.Context, text string) error

WriteText writes a simple text record to the tag This is a convenience method that handles the common case of writing simple text

type ConnectOption

type ConnectOption func(*connectConfig) error

ConnectOption represents a functional option for ConnectDevice

func WithAutoDetection

func WithAutoDetection() ConnectOption

WithAutoDetection enables automatic device detection instead of using a specific path

func WithConnectTimeout

func WithConnectTimeout(timeout time.Duration) ConnectOption

WithConnectTimeout sets the device connection timeout

func WithConnectionRetries added in v0.5.0

func WithConnectionRetries(maxAttempts int) ConnectOption

WithConnectionRetries sets the number of connection retry attempts

func WithDeviceDetector added in v0.5.0

func WithDeviceDetector(
	detector func(context.Context, *detection.Options) ([]detection.DeviceInfo, error),
) ConnectOption

WithDeviceDetector sets a custom device detector function for auto-detection

func WithDeviceOptions

func WithDeviceOptions(opts ...Option) ConnectOption

WithDeviceOptions adds device-level options

func WithTransportFactory

func WithTransportFactory(factory TransportFactory) ConnectOption

WithTransportFactory sets the transport factory function

func WithTransportFromDeviceFactory

func WithTransportFromDeviceFactory(factory TransportFromDeviceFactory) ConnectOption

WithTransportFromDeviceFactory sets the transport from device factory function

type DetectedTag

type DetectedTag struct {
	DetectedAt time.Time // When the tag was detected
	UID        string    // UID as hex string
	Type       TagType   // Tag type
	UIDBytes   []byte    // UID as raw bytes
	ATQ        []byte    // Answer to Request bytes
	TargetData []byte    // Full target response data (needed for FeliCa)
	SAK        byte      // Select Acknowledge byte
}

DetectedTag represents a tag that was detected by the reader

func (*DetectedTag) IsGenuine added in v0.13.0

func (t *DetectedTag) IsGenuine() bool

IsGenuine returns true if the chip appears to be from a known manufacturer. Returns false for unknown/clone chips.

func (*DetectedTag) Manufacturer added in v0.13.0

func (t *DetectedTag) Manufacturer() Manufacturer

Manufacturer returns the chip manufacturer identified from the UID.

type Device

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

Device represents a PN532 NFC reader device

Thread Safety: Device is NOT thread-safe. All methods must be called from a single goroutine or protected with external synchronization. The underlying transport may have its own concurrency limitations. For concurrent access, wrap the Device with a mutex or use separate Device instances with separate transports.

func ConnectDevice

func ConnectDevice(ctx context.Context, path string, opts ...ConnectOption) (*Device, error)

ConnectDevice creates and initializes a PN532 device from a path or via auto-detection. It handles transport creation, device initialization, and optional validation setup.

The pn532 package does not bundle a default transport — callers must wire up whichever transports they want to link (uart, i2c, spi, or a custom one) and pass the corresponding factory option. This keeps consumers that only need one transport from pulling in the others (and their dependencies).

For an explicit device path, pass WithTransportFactory with a function that returns the right Transport for the given path string:

import (
    pn532 "github.com/ZaparooProject/go-pn532"
    "github.com/ZaparooProject/go-pn532/transport/uart"
)

newTransport := func(path string) (pn532.Transport, error) {
    return uart.New(path)
}
device, err := pn532.ConnectDevice(ctx, "/dev/ttyUSB0",
    pn532.WithTransportFactory(newTransport))

For auto-detection, register the detectors you care about via blank import and pass WithAutoDetection together with WithTransportFromDeviceFactory:

import (
    pn532 "github.com/ZaparooProject/go-pn532"
    "github.com/ZaparooProject/go-pn532/detection"
    _ "github.com/ZaparooProject/go-pn532/detection/uart"
    "github.com/ZaparooProject/go-pn532/transport/uart"
)

newFromDevice := func(info detection.DeviceInfo) (pn532.Transport, error) {
    return uart.New(info.Path)
}
device, err := pn532.ConnectDevice(ctx, "",
    pn532.WithAutoDetection(),
    pn532.WithTransportFromDeviceFactory(newFromDevice))

See cmd/reader/main.go for a complete example that supports all three transports.

func New

func New(transport Transport, opts ...Option) (*Device, error)

New creates a new PN532 device with the given transport

func (*Device) ClearTransportState added in v0.8.1

func (d *Device) ClearTransportState() error

ClearTransportState clears corrupted transport state to prevent firmware lockup This is critical when switching between InCommunicateThru and InDataExchange operations after frame reception failures

func (*Device) Close

func (d *Device) Close() error

Close closes the device connection

func (*Device) CreateTag

func (d *Device) CreateTag(detected *DetectedTag) (Tag, error)

CreateTag creates a Tag instance based on the detected tag

func (*Device) CycleRFField added in v0.17.0

func (d *Device) CycleRFField(ctx context.Context) error

CycleRFField turns the RF field off and back on to reset PN532 state. This clears stuck conditions after authentication failures. Timing: 50ms off, 50ms on, 50ms settle (per docs/hardware-mifare-clone-research.md)

func (*Device) DetectTag

func (d *Device) DetectTag(ctx context.Context) (*DetectedTag, error)

DetectTag detects a single tag in the field with context support

func (*Device) Diagnose

func (d *Device) Diagnose(ctx context.Context, testNumber byte, data []byte) (*DiagnoseResult, error)

Diagnose performs a self-diagnosis test with context support

func (*Device) GetFirmwareVersion

func (d *Device) GetFirmwareVersion(ctx context.Context) (*FirmwareVersion, error)

GetFirmwareVersion returns the PN532 firmware version

func (*Device) GetGeneralStatus

func (d *Device) GetGeneralStatus(ctx context.Context) (*GeneralStatus, error)

GetGeneralStatus returns the PN532 general status with context support

func (*Device) HardReset added in v0.17.0

func (d *Device) HardReset(ctx context.Context) error

HardReset performs a "nuclear" recovery by closing and reopening the transport connection, then reinitializing the PN532. This is the last resort when the PN532 enters a complete firmware lockup (stops ACKing any commands).

This recovery is more disruptive than Reset() but handles cases where the PN532 firmware is completely unresponsive. It requires the transport to implement the Reconnecter interface.

Returns an error if the transport doesn't support reconnection or if recovery fails.

func (*Device) InAutoPoll

func (d *Device) InAutoPoll(
	ctx context.Context, pollCount, pollPeriod byte, targetTypes []AutoPollTarget,
) (*AutoPollResult, error)

InAutoPoll polls for a single target with context support

func (*Device) InDeselect added in v0.17.0

func (d *Device) InDeselect(ctx context.Context) error

InDeselect deselects all targets while keeping target information in PN532 memory. Unlike InRelease, this allows InSelect to re-select the target later. For MIFARE cards, this sends HLTA which puts the tag in HALT state. Use InSelect after InDeselect to wake up HALTed tags with WUPA.

func (*Device) InListPassiveTarget added in v0.9.0

func (d *Device) InListPassiveTarget(ctx context.Context, brTy byte) (*DetectedTag, error)

InListPassiveTarget detects a single passive target using InListPassiveTarget command

func (*Device) InListPassiveTargetWithTimeout added in v0.9.0

func (d *Device) InListPassiveTargetWithTimeout(
	ctx context.Context, brTy, mxRtyATR byte,
) (*DetectedTag, error)

InListPassiveTargetWithTimeout detects a single passive target with timeout support. The mxRtyATR parameter controls the maximum retry count for target detection: - 0x00: Try once, no retry - 0x01-0xFE: Retry count (each retry is ~150ms according to PN532 datasheet) - 0xFF: Retry infinitely (blocking mode - use with caution)

For continuous polling with card removal detection, use low values (0x01-0x10) to ensure the command returns quickly when no card is present.

func (*Device) InRelease

func (d *Device) InRelease(ctx context.Context) error

InRelease releases all selected targets with context support

func (*Device) InSelect

func (d *Device) InSelect(ctx context.Context) error

InSelect selects target 1 for communication with context support

func (*Device) Init

func (d *Device) Init(ctx context.Context) error

Init initializes the PN532 device with context support

func (*Device) InitiatorListPassiveTargets

func (d *Device) InitiatorListPassiveTargets(
	ctx context.Context, tagType TagType, uid []byte,
) (*DetectedTag, error)

InitiatorListPassiveTargets detects a passive target with optional filtering This is a compatibility method for the PN532 InListPassiveTarget command

func (*Device) IsAutoPollSupported

func (d *Device) IsAutoPollSupported() bool

IsAutoPollSupported returns true if the transport supports native InAutoPoll

func (*Device) PowerDown

func (d *Device) PowerDown(ctx context.Context, wakeupEnable, irqEnable byte) error

PowerDown puts the PN532 into power down mode with context support

func (*Device) Reset added in v0.9.0

func (d *Device) Reset(ctx context.Context) error

Reset reinitializes the device connection after a power loss, sleep/wake cycle, or communication failure. This clears internal state and re-runs the initialization sequence (GetFirmwareVersion + SAMConfiguration).

Use this when:

  • Host device wakes from sleep
  • PN532 module was power cycled
  • Communication becomes unreliable

If Reset fails, consider closing and reopening the transport entirely.

func (*Device) SAMConfiguration

func (d *Device) SAMConfiguration(ctx context.Context, mode SAMMode, timeout, irq byte) error

SAMConfiguration configures the SAM with context support

func (*Device) SendDataExchange

func (d *Device) SendDataExchange(ctx context.Context, data []byte) ([]byte, error)

SendDataExchange sends a data exchange command with context support

func (*Device) SendDataExchangeWithRetry added in v0.15.1

func (d *Device) SendDataExchangeWithRetry(ctx context.Context, data []byte) ([]byte, error)

SendDataExchangeWithRetry sends a data exchange command with automatic retry on RF errors. RF errors (timeout, CRC, parity, framing) indicate transient communication failures that commonly occur during card sliding into a reader slot. A small delay between retries allows the RF field to stabilize.

Configuration:

  • 3 attempts total (1 initial + 2 retries)
  • 15ms delay between retries (allows RF stabilization)
  • Retries on timeout (0x01) and RF errors (CRC, parity, framing, etc.)

func (*Device) SendRawCommand

func (d *Device) SendRawCommand(ctx context.Context, data []byte) ([]byte, error)

SendRawCommand sends a raw command with context support

func (*Device) SetPassiveActivationRetries added in v0.8.0

func (d *Device) SetPassiveActivationRetries(ctx context.Context, maxRetries byte) error

SetPassiveActivationRetries configures the maximum number of retries for passive activation to prevent infinite waiting that can cause the PN532 to lock up. A finite number like 10 (0x0A) is recommended instead of 0xFF (infinite) to avoid stuck states requiring power cycling.

func (*Device) SetPollingRetries added in v0.8.0

func (d *Device) SetPollingRetries(ctx context.Context, mxRtyATR byte) error

SetPollingRetries configures the MxRtyATR parameter for passive target detection retries. This controls how many times the PN532 will retry detecting a passive target before giving up. Each retry is approximately 150ms according to the PN532 datasheet.

Parameters:

  • mxRtyATR: Number of retries (0x00 = immediate, 0x01-0xFE = retry count, 0xFF = infinite)

Common values:

  • 0x00: Immediate return (no retries)
  • 0x10: ~2.4 seconds (16 retries)
  • 0x20: ~4.8 seconds (32 retries)
  • 0xFF: Infinite retries (use with caution)

func (*Device) SetRetryConfig

func (d *Device) SetRetryConfig(config *RetryConfig)

SetRetryConfig updates the retry configuration

func (*Device) SetTimeout

func (d *Device) SetTimeout(timeout time.Duration) error

SetTimeout sets the default timeout for operations

func (*Device) SimplePoll added in v0.4.0

func (d *Device) SimplePoll(ctx context.Context, interval time.Duration) (*DetectedTag, error)

SimplePoll performs straightforward polling with InListPassiveTarget on a regular schedule This is a simplified alternative to WaitForTag that removes complex error handling and strategy selection, providing predictable poll-poll-poll behavior at regular intervals.

func (*Device) Transport

func (d *Device) Transport() Transport

Transport returns the underlying transport

func (*Device) WaitForTag

func (d *Device) WaitForTag(ctx context.Context) (*DetectedTag, error)

type DeviceConfig

type DeviceConfig struct {
	// RetryConfig configures retry behavior for transport operations
	RetryConfig *RetryConfig
	// Timeout is the default timeout for operations
	Timeout time.Duration
	// MaxFastReadPages limits the number of pages in a single FastRead operation
	// Set to 0 to use platform-specific defaults (16 pages on Windows UART, unlimited elsewhere)
	// This helps avoid PN532 firmware lockups with large InCommunicateThru payloads
	MaxFastReadPages int
}

DeviceConfig contains configuration options for the Device

func DefaultDeviceConfig

func DefaultDeviceConfig() *DeviceConfig

DefaultDeviceConfig returns default device configuration

type DeviceHealthChecker added in v0.20.3

type DeviceHealthChecker interface {
	// CheckHealth returns nil if the device appears present, or an error
	// (typically with ErrorTypePermanent) if the device is gone.
	CheckHealth() error
}

DeviceHealthChecker is optionally implemented by transports that can verify the underlying device is still physically present. Used by the polling layer to quickly detect disconnection after a failed recovery attempt, without waiting for the next I/O cycle.

type DiagnoseResult

type DiagnoseResult struct {
	Data       []byte
	TestNumber byte
	Success    bool
}

DiagnoseResult contains the result of a diagnose test

type ErrorType

type ErrorType int

ErrorType represents the category of error for retry logic

const (
	// ErrorTypeTransient indicates a potentially retryable error
	ErrorTypeTransient ErrorType = iota
	// ErrorTypePermanent indicates a non-retryable error
	ErrorTypePermanent
	// ErrorTypeTimeout indicates a timeout error (special handling)
	ErrorTypeTimeout
)

type FeliCaTag

type FeliCaTag struct {
	BaseTag
	// contains filtered or unexported fields
}

FeliCaTag represents a FeliCa NFC tag implementing the Tag interface Field ordering optimized for memory alignment to reduce struct size from 96 to 80 bytes

func NewFeliCaTag

func NewFeliCaTag(device *Device, targetData []byte) (*FeliCaTag, error)

NewFeliCaTag creates a new FeliCa tag instance from polling response data targetData should contain the FeliCa polling response (POL_RES)

func (*FeliCaTag) DebugInfo

func (f *FeliCaTag) DebugInfo(ctx context.Context) string

DebugInfo returns detailed debug information about the FeliCa tag

func (*FeliCaTag) GetIDm

func (f *FeliCaTag) GetIDm() []byte

GetIDm returns the Manufacture ID (IDm) of the FeliCa tag

func (*FeliCaTag) GetPMm

func (f *FeliCaTag) GetPMm() []byte

GetPMm returns the Manufacture Parameter (PMm) of the FeliCa tag

func (*FeliCaTag) GetServiceCode

func (f *FeliCaTag) GetServiceCode() uint16

GetServiceCode returns the current service code

func (*FeliCaTag) GetSystemCode

func (f *FeliCaTag) GetSystemCode() uint16

GetSystemCode returns the current system code

func (*FeliCaTag) Polling

func (f *FeliCaTag) Polling(ctx context.Context, systemCode uint16) error

Polling performs a FeliCa polling operation to detect and initialize the tag This is a FeliCa-specific operation for card detection and system code discovery

func (*FeliCaTag) ReadBlock

func (f *FeliCaTag) ReadBlock(ctx context.Context, block uint8) ([]byte, error)

ReadBlock reads a single block from the FeliCa tag For FeliCa, block numbers are 16-bit, but we use uint8 for interface compatibility TODO: Consider extending interface for 16-bit block addressing

func (*FeliCaTag) ReadBlockExtended

func (f *FeliCaTag) ReadBlockExtended(ctx context.Context, block uint16) ([]byte, error)

ReadBlockExtended reads a single block using 16-bit block addressing

func (*FeliCaTag) ReadNDEF

func (f *FeliCaTag) ReadNDEF(ctx context.Context) (*NDEFMessage, error)

ReadNDEF reads NDEF data from the FeliCa tag Uses system code 0x12FC and service code 0x000B for NFC Forum Type 3 compliance

func (*FeliCaTag) RequestService

func (f *FeliCaTag) RequestService(ctx context.Context, serviceCodes []uint16) ([]byte, error)

RequestService requests service information from the FeliCa tag This is used to check if specific service codes are available

func (*FeliCaTag) SetServiceCode

func (f *FeliCaTag) SetServiceCode(serviceCode uint16)

SetServiceCode sets the service code for operations

func (*FeliCaTag) SetSystemCode

func (f *FeliCaTag) SetSystemCode(systemCode uint16)

SetSystemCode sets the system code for operations

func (*FeliCaTag) WriteBlock

func (f *FeliCaTag) WriteBlock(ctx context.Context, block uint8, data []byte) error

WriteBlock writes a single block to the FeliCa tag For FeliCa, block numbers are 16-bit, but we use uint8 for interface compatibility

func (*FeliCaTag) WriteBlockExtended

func (f *FeliCaTag) WriteBlockExtended(ctx context.Context, block uint16, data []byte) error

WriteBlockExtended writes a single block using 16-bit block addressing

func (*FeliCaTag) WriteNDEF

func (f *FeliCaTag) WriteNDEF(ctx context.Context, message *NDEFMessage) error

WriteNDEF writes NDEF data to the FeliCa tag Uses system code 0x12FC and service code 0x0009 for NFC Forum Type 3 compliance

func (*FeliCaTag) WriteText

func (f *FeliCaTag) WriteText(ctx context.Context, text string) error

WriteText writes a simple text record to the FeliCa tag

type FirmwareVersion

type FirmwareVersion struct {
	Version          string
	SupportIso14443a bool
	SupportIso14443b bool
	SupportIso18092  bool
}

FirmwareVersion contains PN532 firmware information

type GeneralStatus

type GeneralStatus struct {
	LastError    byte
	FieldPresent bool
	Targets      byte
}

GeneralStatus contains PN532 general status information

type IsRetryableFunc added in v0.8.0

type IsRetryableFunc func(error) bool

IsRetryableFunc defines a function that determines if an error is retryable

type MIFAREConfig added in v0.4.0

type MIFAREConfig struct {
	RetryConfig   *RetryConfig  // Retry backoff configuration
	HardwareDelay time.Duration // Hardware timing delays (reinitialization, tag processing)
}

MIFAREConfig holds all configurable timing parameters for MIFARE operations

func DefaultMIFAREConfig added in v0.4.0

func DefaultMIFAREConfig() *MIFAREConfig

DefaultMIFAREConfig returns production-safe MIFARE configuration These values are optimized based on real-world testing and provide a good balance between speed and reliability for most hardware setups.

type MIFARETag

type MIFARETag struct {
	BaseTag
	// contains filtered or unexported fields
}

MIFARETag represents a MIFARE Classic tag

func NewMIFARETag

func NewMIFARETag(device *Device, uid []byte, sak byte) *MIFARETag

NewMIFARETag creates a new MIFARE tag instance

func (*MIFARETag) AnalyzeLastError

func (*MIFARETag) AnalyzeLastError(err error) string

AnalyzeLastError provides detailed error analysis based on research findings

func (*MIFARETag) Authenticate

func (t *MIFARETag) Authenticate(ctx context.Context, sector uint8, keyType byte, key []byte) error

Authenticate authenticates a sector on the MIFARE tag

func (*MIFARETag) AuthenticateWithRetry added in v0.17.0

func (t *MIFARETag) AuthenticateWithRetry(ctx context.Context, sector uint8, keyType byte, key []byte) error

AuthenticateWithRetry performs robust authentication with retry logic and Chinese clone support This is the recommended method for authenticating with unreliable tags

func (*MIFARETag) DebugInfo

func (t *MIFARETag) DebugInfo(ctx context.Context) string

DebugInfo returns detailed debug information about the MIFARE tag

func (*MIFARETag) FormatForNDEF added in v0.7.0

func (t *MIFARETag) FormatForNDEF(ctx context.Context) error

FormatForNDEF formats a blank MIFARE Classic tag for NDEF data storage. This process takes approximately 2 seconds and sets up: - Sector 0 with MAD (MIFARE Application Directory) structure - Remaining sectors with NDEF keys and access control bits

The tag must be in factory state (using factory keys) before calling this method. After formatting, the tag will be ready for NDEF data storage using standard NDEF read/write operations.

Returns an error if formatting fails at any step.

func (*MIFARETag) GetDevice

func (t *MIFARETag) GetDevice() *Device

GetDevice returns the underlying PN532 device for direct access

func (*MIFARETag) GetTimingVariance

func (t *MIFARETag) GetTimingVariance() time.Duration

GetTimingVariance returns the timing variance for hardware issue detection

func (*MIFARETag) IsAuthenticated added in v0.17.0

func (t *MIFARETag) IsAuthenticated() bool

IsAuthenticated returns true if TryAuthenticate succeeded. Unauthenticated tags can still be used for UID-only operations.

func (*MIFARETag) IsNDEFFormatted added in v0.7.0

func (t *MIFARETag) IsNDEFFormatted(ctx context.Context) bool

IsNDEFFormatted checks if the tag is NDEF formatted by attempting to authenticate with the MAD key on sector 0. This is a fast check that takes approximately 60ms compared to 550ms for a full NDEF read attempt on a blank tag.

Returns true if the tag appears to be NDEF formatted, false otherwise. This method checks sector 0 with the MAD key as per MIFARE Application Directory standards rather than sector 1 with the NDEF key.

func (*MIFARETag) IsTimingUnstable

func (t *MIFARETag) IsTimingUnstable() bool

IsTimingUnstable checks if timing variance indicates hardware issues

func (*MIFARETag) ReadBlock

func (t *MIFARETag) ReadBlock(ctx context.Context, block uint8) ([]byte, error)

ReadBlock reads a block from the MIFARE tag

func (*MIFARETag) ReadBlockAuto

func (t *MIFARETag) ReadBlockAuto(ctx context.Context, block uint8) ([]byte, error)

ReadBlockAuto reads a block with automatic authentication using the key provider

func (*MIFARETag) ReadBlockDirect

func (t *MIFARETag) ReadBlockDirect(ctx context.Context, block uint8) ([]byte, error)

ReadBlockDirect reads a block directly without authentication (for clone tags).

func (*MIFARETag) ReadNDEF

func (t *MIFARETag) ReadNDEF(ctx context.Context) (*NDEFMessage, error)

ReadNDEF reads NDEF data from the MIFARE tag using bulk sector reads

func (*MIFARETag) ReadNDEFWithRetry added in v0.17.0

func (t *MIFARETag) ReadNDEFWithRetry(ctx context.Context) (*NDEFMessage, error)

ReadNDEFWithRetry reads NDEF data with retry logic to handle intermittent empty data issues This addresses the "empty valid tag" problem where tags are detected but return no data

func (*MIFARETag) ResetAuthState

func (t *MIFARETag) ResetAuthState(ctx context.Context) error

ResetAuthState resets the PN532's internal authentication state This can help when previous failed authentication attempts have polluted the state

func (*MIFARETag) SetConfig added in v0.4.0

func (t *MIFARETag) SetConfig(config *MIFAREConfig)

SetConfig allows runtime configuration of MIFARE behavior for testing

func (*MIFARETag) SetRetryConfig added in v0.4.0

func (t *MIFARETag) SetRetryConfig(config *RetryConfig)

SetRetryConfig allows runtime configuration of retry behavior for testing

func (*MIFARETag) TryAuthenticate added in v0.17.0

func (t *MIFARETag) TryAuthenticate(ctx context.Context) error

TryAuthenticate attempts to authenticate to sector 1 using NDEF key first, then falling back to common keys (factory default, etc.). Returns nil if any key works, error otherwise. Use this when initializing or checking if a tag can be read.

func (*MIFARETag) WriteBlock

func (t *MIFARETag) WriteBlock(ctx context.Context, block uint8, data []byte) error

WriteBlock writes a block to the MIFARE tag

func (*MIFARETag) WriteBlockAuto

func (t *MIFARETag) WriteBlockAuto(ctx context.Context, block uint8, data []byte) error

WriteBlockAuto writes a block with automatic authentication using the key provider

func (*MIFARETag) WriteBlockAutoAlternative added in v0.7.0

func (t *MIFARETag) WriteBlockAutoAlternative(ctx context.Context, block uint8, data []byte) error

WriteBlockAutoAlternative writes a block with automatic sector authentication. It handles authentication caching and tries both Key A and Key B as needed.

func (*MIFARETag) WriteBlockDirect

func (t *MIFARETag) WriteBlockDirect(ctx context.Context, block uint8, data []byte) error

WriteBlockDirect writes a block directly without authentication (for clone tags)

func (*MIFARETag) WriteNDEF

func (t *MIFARETag) WriteNDEF(ctx context.Context, message *NDEFMessage) error

WriteNDEF writes NDEF data to the MIFARE tag with final verification

func (*MIFARETag) WriteNDEFAlternative added in v0.7.0

func (t *MIFARETag) WriteNDEFAlternative(ctx context.Context, message *NDEFMessage) error

WriteNDEFAlternative provides an optimized NDEF writing implementation for tags formatted with FormatForNDEF. This method skips some validation steps and uses pre-known sector layouts for improved performance.

WARNING: This method is optimized for specific use cases where performance is critical. It assumes the tag was formatted using FormatForNDEF and may not work correctly with tags formatted by other applications.

Use the standard WriteNDEF method for general compatibility.

func (*MIFARETag) WriteText

func (t *MIFARETag) WriteText(ctx context.Context, text string) error

WriteText writes a simple text record to the MIFARE tag

type Manufacturer added in v0.13.0

type Manufacturer string

Manufacturer represents the chip manufacturer identified from the UID. The first byte of a 7-byte UID contains the manufacturer code per ISO/IEC 7816-6.

const (
	// ManufacturerNXP is NXP Semiconductors (0x04) - maker of genuine NTAG chips.
	ManufacturerNXP Manufacturer = "NXP"
	// ManufacturerST is STMicroelectronics (0x02) - maker of ST25TN chips.
	ManufacturerST Manufacturer = "STMicroelectronics"
	// ManufacturerInfineon is Infineon Technologies (0x05) - maker of MIFARE-compatible chips.
	ManufacturerInfineon Manufacturer = "Infineon"
	// ManufacturerTI is Texas Instruments (0x07).
	ManufacturerTI Manufacturer = "Texas Instruments"
	// ManufacturerFudan is Fudan Microelectronics (0x1D) - Chinese manufacturer
	// of NTAG-compatible clone chips like FM11NT021.
	ManufacturerFudan Manufacturer = "Fudan Microelectronics"
	// ManufacturerUnknown indicates an unrecognized manufacturer code.
	// This typically indicates a clone or counterfeit chip.
	ManufacturerUnknown Manufacturer = "Unknown"
)

func GetManufacturer added in v0.13.0

func GetManufacturer(uid []byte) Manufacturer

GetManufacturer returns the chip manufacturer based on the UID's first byte. For 7-byte UIDs (NTAG, ST25TN, etc.), the first byte is the manufacturer code. For 4-byte UIDs (MIFARE Classic), manufacturer detection is less reliable.

type MockTransport added in v0.4.0

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

MockTransport provides a mock implementation of Transport for testing

func NewMockTransport added in v0.4.0

func NewMockTransport() *MockTransport

NewMockTransport creates a new mock transport

func (*MockTransport) CheckHealth added in v0.20.3

func (m *MockTransport) CheckHealth() error

CheckHealth implements DeviceHealthChecker for testing

func (*MockTransport) ClearError added in v0.4.0

func (m *MockTransport) ClearError(cmd byte)

ClearError removes error injection for a command

func (*MockTransport) Close added in v0.4.0

func (m *MockTransport) Close() error

Close implements Transport interface

func (*MockTransport) DeselectTarget added in v0.9.0

func (m *MockTransport) DeselectTarget()

DeselectTarget clears the target selection

func (*MockTransport) DisableRFField added in v0.9.0

func (m *MockTransport) DisableRFField()

DisableRFField turns off the RF field for testing (also deselects target)

func (*MockTransport) EnableRFField added in v0.9.0

func (m *MockTransport) EnableRFField()

EnableRFField turns on the RF field for testing

func (*MockTransport) GetCallCount added in v0.4.0

func (m *MockTransport) GetCallCount(cmd byte) int

GetCallCount returns how many times a command was called

func (*MockTransport) GetState added in v0.9.0

func (m *MockTransport) GetState() (powerMode PN532PowerMode, rfFieldOn, targetSelected bool)

GetState returns the current PN532 state (for test assertions)

func (*MockTransport) HasCapability added in v0.17.0

func (*MockTransport) HasCapability(capability TransportCapability) bool

HasCapability implements TransportCapabilityChecker

func (*MockTransport) IsConnected added in v0.4.0

func (m *MockTransport) IsConnected() bool

IsConnected implements Transport interface

func (*MockTransport) QueueResponse added in v0.10.0

func (m *MockTransport) QueueResponse(cmd byte, response []byte)

QueueResponse adds a response to the queue for a specific command. Queued responses are returned in FIFO order for sequential calls to the same command. Once the queue is empty, SetResponse fallback is used.

func (*MockTransport) QueueResponses added in v0.10.0

func (m *MockTransport) QueueResponses(cmd byte, responses ...[]byte)

QueueResponses adds multiple responses to the queue for a specific command.

func (*MockTransport) Reconnect added in v0.17.0

func (m *MockTransport) Reconnect() error

Reconnect implements the Reconnecter interface for testing HardReset

func (*MockTransport) Reset added in v0.4.0

func (m *MockTransport) Reset()

Reset clears all call counts and resets state

func (*MockTransport) SelectTarget added in v0.9.0

func (m *MockTransport) SelectTarget()

SelectTarget simulates a target being selected (as if InListPassiveTarget succeeded)

func (*MockTransport) SendCommand added in v0.4.0

func (m *MockTransport) SendCommand(ctx context.Context, cmd byte, data []byte) ([]byte, error)

SendCommand implements Transport interface with context support

func (*MockTransport) SetDelay added in v0.4.0

func (m *MockTransport) SetDelay(delay time.Duration)

SetDelay configures a delay to simulate hardware response time

func (*MockTransport) SetError added in v0.4.0

func (m *MockTransport) SetError(cmd byte, err error)

SetError configures an error to be returned for a specific command

func (*MockTransport) SetHealthError added in v0.20.3

func (m *MockTransport) SetHealthError(err error)

SetHealthError configures an error to be returned by CheckHealth()

func (*MockTransport) SetPowerMode added in v0.9.0

func (m *MockTransport) SetPowerMode(mode PN532PowerMode)

SetPowerMode sets the power mode for testing

func (*MockTransport) SetReconnectError added in v0.17.0

func (m *MockTransport) SetReconnectError(err error)

SetReconnectError configures an error to be returned by Reconnect()

func (*MockTransport) SetResponse added in v0.4.0

func (m *MockTransport) SetResponse(cmd byte, response []byte)

SetResponse configures a response for a specific command

func (*MockTransport) SetTimeout added in v0.4.0

func (m *MockTransport) SetTimeout(timeout time.Duration) error

SetTimeout implements Transport interface

func (*MockTransport) Type added in v0.4.0

func (*MockTransport) Type() TransportType

Type implements Transport interface

type NDEFLocation added in v0.14.0

type NDEFLocation struct {
	// Offset is the byte offset where NDEF payload data starts (after TLV header)
	Offset int
	// Length is the length of the NDEF payload in bytes
	Length int
	// HeaderSize is the size of the TLV header (2 for short format, 4 for long format)
	HeaderSize int
}

NDEFLocation represents the location and size of NDEF data within TLV structure

func ScanForNDEFTLV added in v0.14.0

func ScanForNDEFTLV(data []byte) (*NDEFLocation, error)

ScanForNDEFTLV scans through TLV blocks to find the NDEF Message TLV (0x03). It properly skips NULL (0x00), Lock Control (0x01), Memory Control (0x02), and other proprietary TLVs per NFC Forum Type 2 Tag specification.

Returns the location of the NDEF data or an error if not found.

type NDEFMessage

type NDEFMessage struct {
	Records []NDEFRecord
}

NDEFMessage represents an NDEF message

func ParseNDEFMessage

func ParseNDEFMessage(data []byte) (*NDEFMessage, error)

ParseNDEFMessage parses a complete NDEF message using go-ndef

type NDEFRecord

type NDEFRecord struct {
	WiFi    *WiFiCredential
	VCard   *VCardContact
	Text    string
	URI     string
	Type    NDEFRecordType
	Payload []byte
}

NDEFRecord represents a single NDEF record

type NDEFRecordType

type NDEFRecordType string

NDEFRecordType represents the type of an NDEF record

const (
	// NDEFTypeText represents a text record type
	NDEFTypeText NDEFRecordType = "text"
	// NDEFTypeURI represents a URI record type
	NDEFTypeURI NDEFRecordType = "uri"
	// NDEFTypeSmartPoster represents a smart poster record type
	NDEFTypeSmartPoster NDEFRecordType = "smartposter"
)
const (
	// NDEFTypeWiFi represents a WiFi credential record
	NDEFTypeWiFi NDEFRecordType = "wifi"
	// NDEFTypeVCard represents a vCard contact record
	NDEFTypeVCard NDEFRecordType = "vcard"
	// NDEFTypeBluetooth represents a Bluetooth pairing record
	NDEFTypeBluetooth NDEFRecordType = "bluetooth"
)

Extended NDEF record types

type NTAGTag

type NTAGTag struct {
	BaseTag
	// contains filtered or unexported fields
}

NTAGTag represents an NTAG21X tag

func NewNTAGTag

func NewNTAGTag(device *Device, uid []byte, sak byte) *NTAGTag

NewNTAGTag creates a new NTAG tag instance

func (*NTAGTag) DebugInfo

func (t *NTAGTag) DebugInfo(ctx context.Context) string

DebugInfo returns detailed debug information about the NTAG tag

func (*NTAGTag) DetectType

func (t *NTAGTag) DetectType(ctx context.Context) error

DetectType detects the NTAG variant using the Capability Container (CC).

This function uses CC-based detection exclusively, avoiding the GET_VERSION command which uses InCommunicateThru (0x42). InCommunicateThru doesn't maintain the PN532's target selection state, causing subsequent InDataExchange calls to fail with timeout error 0x01 on readers with marginal RF connections.

CC-based detection accurately identifies NTAG213/215/216 from the size field in the capability container, which is sufficient for NDEF operations.

func (*NTAGTag) DisablePasswordProtection

func (t *NTAGTag) DisablePasswordProtection(ctx context.Context) error

DisablePasswordProtection disables password protection by setting AUTH0 to 0xFF

func (*NTAGTag) FastRead

func (t *NTAGTag) FastRead(ctx context.Context, startAddr, endAddr uint8) ([]byte, error)

FastRead performs a fast read operation on NTAG tags It reads multiple blocks from startAddr to endAddr (inclusive)

func (*NTAGTag) GetCachedCapabilityContainer added in v0.19.0

func (t *NTAGTag) GetCachedCapabilityContainer() []byte

GetCachedCapabilityContainer returns the CC bytes cached during DetectType. Returns nil if DetectType has not been called yet. The returned slice is a copy to prevent modification of internal state.

func (*NTAGTag) GetCachedUserDataPage added in v0.20.0

func (t *NTAGTag) GetCachedUserDataPage() []byte

GetCachedUserDataPage returns the first user data page (page 4) cached during DetectType. This is useful for detecting special token types like Amiibo (byte 0 = 0xA5). Returns nil if DetectType has not been called yet or if page 4 read failed. The returned slice is a copy to prevent modification of internal state.

func (*NTAGTag) GetConfigPage

func (t *NTAGTag) GetConfigPage() uint8

GetConfigPage returns the configuration page address for the tag type

func (*NTAGTag) GetPasswordPage

func (t *NTAGTag) GetPasswordPage() uint8

GetPasswordPage returns the password page address for the tag type

func (*NTAGTag) GetTotalPages

func (t *NTAGTag) GetTotalPages() uint8

GetTotalPages returns the total number of pages for the tag type

func (*NTAGTag) GetUserMemoryRange

func (t *NTAGTag) GetUserMemoryRange() (start, end uint8)

GetUserMemoryRange returns the start and end pages for user memory based on tag type.

func (*NTAGTag) GetVersion

func (t *NTAGTag) GetVersion(ctx context.Context) (*NTAGVersion, error)

GetVersion retrieves version information from the NTAG tag using proper GET_VERSION command This implementation uses SendRawCommand (like FastRead) for better compatibility across PN532 variants

func (*NTAGTag) HasNDEF added in v0.17.0

func (t *NTAGTag) HasNDEF() bool

HasNDEF returns true if the tag has a valid NDEF capability container. Non-NDEF tags (Amiibo, Lego Dimensions, etc.) return false but are still valid for UID reading and raw data access via ReadBlock/ReadAll.

func (*NTAGTag) LockPage

func (t *NTAGTag) LockPage(ctx context.Context, page uint8) error

LockPage permanently locks a page from writing (irreversible!) This uses the static lock bytes for pages 0-15 or dynamic lock bytes for higher pages

func (*NTAGTag) MakeReadOnly added in v0.21.0

func (t *NTAGTag) MakeReadOnly(ctx context.Context) error

MakeReadOnly permanently locks ALL user memory pages, making the tag read-only. This is IRREVERSIBLE. After calling this method, no data can be written to the tag. It sets all bits in the static lock bytes (pages 3-15) and dynamic lock bytes (pages 16+), then sets the CC access byte to read-only (0x0F).

The CC access byte is written last so that a partial failure (e.g., RF error during dynamic lock write) does not misleadingly mark the tag as read-only when the hardware lock bits are not fully set.

func (*NTAGTag) ProbeActualMemorySize added in v0.13.0

func (t *NTAGTag) ProbeActualMemorySize(ctx context.Context, claimedBytes int) (lastPage uint8, userMemory int)

ProbeActualMemorySize probes the tag to find its actual memory size. This is useful for clone tags that lie about their capacity in the CC. The claimedBytes parameter (from CC) is used to set a reasonable upper bound to avoid reading wildly out-of-range pages which can corrupt tag state. Returns the last readable page number and total user memory in bytes.

func (*NTAGTag) PwdAuth

func (t *NTAGTag) PwdAuth(ctx context.Context, password []byte) ([]byte, error)

PwdAuth performs password authentication on the NTAG tag password must be exactly 4 bytes (32-bit) Returns the 2-byte PACK (Password ACKnowledge) on success

func (*NTAGTag) ReadBlock

func (t *NTAGTag) ReadBlock(ctx context.Context, block uint8) ([]byte, error)

ReadBlock reads a block from the NTAG tag.

func (*NTAGTag) ReadCapabilityContainer added in v0.13.0

func (t *NTAGTag) ReadCapabilityContainer(ctx context.Context) ([]byte, error)

ReadCapabilityContainer reads the CC (page 3) and returns it

func (*NTAGTag) ReadNDEF

func (t *NTAGTag) ReadNDEF(ctx context.Context) (*NDEFMessage, error)

ReadNDEF reads NDEF data from the NTAG tag using FastRead for optimal performance

func (*NTAGTag) ReadNDEFWithRetry added in v0.17.0

func (t *NTAGTag) ReadNDEFWithRetry(ctx context.Context) (*NDEFMessage, error)

ReadNDEFWithRetry reads NDEF data with retry logic to handle intermittent empty data issues This addresses the "empty valid tag" problem where tags are detected but return no data

func (*NTAGTag) SetAccessControl

func (t *NTAGTag) SetAccessControl(ctx context.Context, config AccessControlConfig) error

SetAccessControl configures the access control settings

func (*NTAGTag) SetPasswordProtection

func (t *NTAGTag) SetPasswordProtection(ctx context.Context, password, pack []byte, auth0 uint8) error

SetPasswordProtection enables password protection on the tag password must be exactly 4 bytes, pack must be exactly 2 bytes auth0 defines from which page password protection starts (0x00 = disable, 0xFF = only config area)

func (*NTAGTag) WriteBlock

func (t *NTAGTag) WriteBlock(ctx context.Context, block uint8, data []byte) error

WriteBlock writes a block to the NTAG tag

func (*NTAGTag) WriteNDEF

func (t *NTAGTag) WriteNDEF(ctx context.Context, message *NDEFMessage) error

WriteNDEF writes NDEF data to the NTAG tag with final verification

func (*NTAGTag) WriteText

func (t *NTAGTag) WriteText(ctx context.Context, text string) error

WriteText writes a simple text record to the NTAG tag

type NTAGType

type NTAGType uint8

NTAGType represents different NTAG variants

const (
	// NTAGTypeUnknown represents an unknown NTAG type.
	NTAGTypeUnknown NTAGType = iota
	// NTAGType213 represents an NTAG213 chip.
	NTAGType213
	// NTAGType215 represents an NTAG215 chip.
	NTAGType215
	// NTAGType216 represents an NTAG216 chip.
	NTAGType216
)

type NTAGVersion

type NTAGVersion struct {
	FixedHeader    uint8 // Should be 0x00
	VendorID       uint8 // 0x04 = NXP Semiconductors
	ProductType    uint8 // 0x04 = NTAG
	ProductSubtype uint8 // 0x02 = 50 pF
	MajorVersion   uint8 // Major product version
	MinorVersion   uint8 // Minor product version
	StorageSize    uint8 // Storage size (encoded)
	ProtocolType   uint8 // 0x03 = ISO/IEC 14443-3
}

NTAGVersion holds the version information from GET_VERSION command

func (*NTAGVersion) GetNTAGType

func (v *NTAGVersion) GetNTAGType() NTAGType

GetNTAGType determines the NTAG variant from version information

func (*NTAGVersion) GetStorageSize

func (v *NTAGVersion) GetStorageSize() int

GetStorageSize calculates the actual storage size from the encoded value

type Option

type Option func(*Device) error

Option is a functional option for configuring a Device

type PN532Error added in v0.8.0

type PN532Error struct {
	Command   string
	Context   string
	BytesSent int
	ErrorCode byte
	Target    byte
}

PN532Error wraps PN532 device errors with error code context. This provides detailed information for debugging protocol-level failures.

func NewPN532Error added in v0.8.0

func NewPN532Error(errorCode byte, command, context string) *PN532Error

NewPN532Error creates a PN532 error with the specified error code and context

func NewPN532ErrorWithDetails added in v0.9.1

func NewPN532ErrorWithDetails(errorCode byte, command string, bytesSent int, target byte) *PN532Error

NewPN532ErrorWithDetails creates a PN532 error with full debugging context. Use this for protocol-level errors where knowing bytes sent and target helps debugging.

func (*PN532Error) Error added in v0.8.0

func (e *PN532Error) Error() string

func (*PN532Error) IsAuthenticationError added in v0.8.0

func (e *PN532Error) IsAuthenticationError() bool

IsAuthenticationError returns true if the error is authentication-related

func (*PN532Error) IsCommandNotSupported added in v0.8.0

func (e *PN532Error) IsCommandNotSupported() bool

IsCommandNotSupported returns true if the error indicates the command is not supported

func (*PN532Error) IsRFError added in v0.17.0

func (e *PN532Error) IsRFError() bool

IsRFError returns true if the error is RF communication related. These errors are typically transient and worth retrying, especially during card sliding where RF communication may be unstable until the card settles.

func (*PN532Error) IsTimeoutError added in v0.8.0

func (e *PN532Error) IsTimeoutError() bool

IsTimeoutError returns true if the error is timeout-related

type PN532PowerMode added in v0.9.0

type PN532PowerMode int

PN532PowerMode represents the power mode state of the PN532

const (
	// PN532PowerModeNormal is the normal operating mode
	PN532PowerModeNormal PN532PowerMode = iota
	// PN532PowerModeSleep is the sleep mode (low power)
	PN532PowerModeSleep
	// PN532PowerModePowerDown is the power down mode (lowest power)
	PN532PowerModePowerDown
)

type ReadNDEFFunc added in v0.8.0

type ReadNDEFFunc func() (*NDEFMessage, error)

ReadNDEFFunc defines a function that reads NDEF data from a tag

type Reconnecter added in v0.17.0

type Reconnecter interface {
	// Reconnect closes and reopens the underlying connection.
	// This is a last-resort recovery mechanism for firmware lockups.
	Reconnect() error
}

Reconnecter is implemented by transports that support reconnecting without recreating the transport instance. This is used for "nuclear" recovery when the PN532 firmware enters a complete lockup state (no ACKs to any commands).

type RetryConfig

type RetryConfig struct {
	// MaxAttempts is the maximum number of attempts (0 = no retry)
	MaxAttempts int
	// InitialBackoff is the initial backoff duration
	InitialBackoff time.Duration
	// MaxBackoff is the maximum backoff duration
	MaxBackoff time.Duration
	// BackoffMultiplier is the factor by which the backoff increases
	BackoffMultiplier float64
	// Jitter adds randomness to backoff to avoid thundering herd
	Jitter float64
	// RetryTimeout is the overall timeout for all retry attempts
	RetryTimeout time.Duration
}

RetryConfig configures retry behavior

func DefaultRetryConfig

func DefaultRetryConfig() *RetryConfig

DefaultRetryConfig returns a default retry configuration

type RetryableFunc

type RetryableFunc func() error

RetryableFunc is a function that can be retried

type SAMMode

type SAMMode byte

SAMMode represents the SAM configuration mode

const (
	// SAMModeNormal - normal mode (default)
	SAMModeNormal SAMMode = 0x01
	// SAMModeVirtualCard - Virtual Card mode
	SAMModeVirtualCard SAMMode = 0x02
	// SAMModeWiredCard - Wired Card mode
	SAMModeWiredCard SAMMode = 0x03
	// SAMModeDualCard - Dual Card mode
	SAMModeDualCard SAMMode = 0x04

	// SAMNormal is an alias for SAMModeNormal for backward compatibility
	SAMNormal = SAMModeNormal
)

type Tag

type Tag interface {
	// Type returns the tag type
	Type() TagType

	// UID returns the tag's unique identifier as hex string
	UID() string

	// UIDBytes returns the tag's unique identifier as bytes
	UIDBytes() []byte

	// ReadBlock reads a block of data from the tag
	ReadBlock(ctx context.Context, block uint8) ([]byte, error)

	// WriteBlock writes a block of data to the tag
	WriteBlock(ctx context.Context, block uint8, data []byte) error

	// ReadNDEF reads NDEF data from the tag
	ReadNDEF(ctx context.Context) (*NDEFMessage, error)

	// WriteNDEF writes NDEF data to the tag
	WriteNDEF(ctx context.Context, message *NDEFMessage) error

	// ReadText reads the first text record from the tag's NDEF data
	ReadText(ctx context.Context) (string, error)

	// WriteText writes a simple text record to the tag
	WriteText(ctx context.Context, text string) error

	// DebugInfo returns detailed debug information about the tag
	DebugInfo(ctx context.Context) string

	// Summary returns a brief summary of the tag
	Summary() string
}

Tag represents an NFC tag interface

type TagType

type TagType string

TagType represents the type of NFC tag

const (
	// TagTypeNTAG represents NTAG tag types.
	TagTypeNTAG TagType = "NTAG"
	// TagTypeMIFARE represents MIFARE tag types.
	TagTypeMIFARE TagType = "MIFARE"
	// TagTypeFeliCa represents FeliCa tag types.
	TagTypeFeliCa TagType = "FELICA"
	// TagTypeUnknown represents unknown tag types.
	TagTypeUnknown TagType = "UNKNOWN"
	// TagTypeAny represents any tag type (for detection)
	TagTypeAny TagType = "ANY"
)

type TraceBuffer added in v0.9.0

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

TraceBuffer collects trace entries during a command operation. It uses a fixed-size circular buffer to limit memory usage.

func NewTraceBuffer added in v0.9.0

func NewTraceBuffer(transport, port string, maxSize int) *TraceBuffer

NewTraceBuffer creates a new trace buffer with the specified capacity

func (*TraceBuffer) Clear added in v0.9.0

func (tb *TraceBuffer) Clear()

Clear resets the trace buffer

func (*TraceBuffer) RecordRX added in v0.9.0

func (tb *TraceBuffer) RecordRX(data []byte, note string)

RecordRX records data received from the PN532

func (*TraceBuffer) RecordTX added in v0.9.0

func (tb *TraceBuffer) RecordTX(data []byte, note string)

RecordTX records a transmission to the PN532

func (*TraceBuffer) RecordTimeout added in v0.9.0

func (tb *TraceBuffer) RecordTimeout(note string)

RecordTimeout records a timeout event

func (*TraceBuffer) WrapError added in v0.9.0

func (tb *TraceBuffer) WrapError(err error) error

WrapError wraps an error with the collected trace data. Returns nil if err is nil.

type TraceDirection added in v0.9.0

type TraceDirection string

TraceDirection indicates the direction of wire data

const (
	// TraceTX indicates data sent to the PN532
	TraceTX TraceDirection = "TX"
	// TraceRX indicates data received from the PN532
	TraceRX TraceDirection = "RX"
)

type TraceEntry added in v0.9.0

type TraceEntry struct {
	Timestamp time.Time
	Direction TraceDirection
	Note      string
	Data      []byte
}

TraceEntry represents a single wire-level operation

func (TraceEntry) String added in v0.9.0

func (e TraceEntry) String() string

String formats a trace entry for display

type TraceableError added in v0.9.0

type TraceableError struct {
	Err       error
	Transport string
	Port      string
	Trace     []TraceEntry
}

TraceableError wraps an error with wire-level trace data for debugging. Consumer applications can use errors.As() to extract trace information:

var te *pn532.TraceableError
if errors.As(err, &te) {
    log.Printf("Wire trace:\n%s", te.FormatTrace())
}

func GetTrace added in v0.9.0

func GetTrace(err error) *TraceableError

GetTrace extracts trace data from an error, returning nil if not present

func (*TraceableError) Error added in v0.9.0

func (e *TraceableError) Error() string

Error implements the error interface

func (*TraceableError) FormatTrace added in v0.9.0

func (e *TraceableError) FormatTrace() string

FormatTrace returns a human-readable formatted trace log

func (*TraceableError) Unwrap added in v0.9.0

func (e *TraceableError) Unwrap() error

Unwrap returns the underlying error for errors.Is/As compatibility

type Transport

type Transport interface {
	// SendCommand sends a command to the PN532 with context support
	SendCommand(ctx context.Context, cmd byte, args []byte) ([]byte, error)

	// Close closes the transport connection
	Close() error

	// SetTimeout sets the read timeout for the transport
	SetTimeout(timeout time.Duration) error

	// IsConnected returns true if the transport is connected
	IsConnected() bool

	// Type returns the transport type
	Type() TransportType
}

Transport defines the interface for communication with PN532 devices. This can be implemented by UART, I2C, or SPI backends.

type TransportCapability

type TransportCapability string

TransportCapability represents specific capabilities or behaviors of a transport

const (
	// CapabilityRequiresInSelect indicates the transport requires explicit InSelect
	CapabilityRequiresInSelect TransportCapability = "requires_in_select"

	// CapabilityAutoPollNative indicates the transport supports native InAutoPoll
	// with full command set and reliable operation (e.g., UART, I2C, SPI)
	CapabilityAutoPollNative TransportCapability = "autopoll_native"

	// CapabilityUART indicates the transport uses UART communication
	// UART transport is prone to PN532 firmware lockups with large InCommunicateThru payloads
	CapabilityUART TransportCapability = "uart"
)

type TransportCapabilityChecker

type TransportCapabilityChecker interface {
	// HasCapability returns true if the transport has the specified capability
	HasCapability(capability TransportCapability) bool
}

TransportCapabilityChecker defines an interface for querying transport capabilities This provides a clean, type-safe alternative to reflection-based mode detection

type TransportError

type TransportError struct {
	Err       error     // Underlying error
	Op        string    // Operation that failed
	Port      string    // Port or device identifier
	Type      ErrorType // Error category
	Retryable bool      // Whether the error is retryable
}

TransportError wraps transport-level errors with additional context

func NewChecksumMismatchError

func NewChecksumMismatchError(op, port string) *TransportError

NewChecksumMismatchError creates a checksum mismatch error (transient)

func NewDataTooLargeError

func NewDataTooLargeError(op, port string) *TransportError

NewDataTooLargeError creates a data too large error (permanent)

func NewFrameCorruptedError

func NewFrameCorruptedError(op, port string) *TransportError

NewFrameCorruptedError creates a frame corruption error

func NewInvalidResponseError

func NewInvalidResponseError(op, port string) *TransportError

NewInvalidResponseError creates an invalid response error (permanent)

func NewNACKReceivedError

func NewNACKReceivedError(op, port string) *TransportError

NewNACKReceivedError creates a "NACK received" error (transient)

func NewNoACKError

func NewNoACKError(op, port string) *TransportError

NewNoACKError creates a "no ACK received" error (timeout)

func NewTimeoutError

func NewTimeoutError(op, port string) *TransportError

NewTimeoutError creates a timeout error for transport operations

func NewTransportError

func NewTransportError(op, port string, err error, errType ErrorType) *TransportError

NewTransportError creates a standard transport error with consistent formatting

func NewTransportNotReadyError

func NewTransportNotReadyError(op, port string) *TransportError

NewTransportNotReadyError creates a transport not ready error (timeout)

func NewTransportReadError

func NewTransportReadError(op, port string) *TransportError

NewTransportReadError creates a read error (transient)

func NewTransportWriteError

func NewTransportWriteError(op, port string) *TransportError

NewTransportWriteError creates a write error (transient)

func (*TransportError) Error

func (e *TransportError) Error() string

func (*TransportError) Unwrap

func (e *TransportError) Unwrap() error

type TransportFactory

type TransportFactory func(path string) (Transport, error)

TransportFactory is a function type for creating transports

type TransportFromDeviceFactory

type TransportFromDeviceFactory func(device detection.DeviceInfo) (Transport, error)

TransportFromDeviceFactory is a function type for creating transports from detected devices

type TransportType

type TransportType string

TransportType represents the type of transport

const (
	// TransportUART represents UART/serial transport.
	TransportUART TransportType = "uart"
	// TransportI2C represents I2C bus transport.
	TransportI2C TransportType = "i2c"
	// TransportSPI represents SPI bus transport.
	TransportSPI TransportType = "spi"
	// TransportMock represents a mock transport for testing
	TransportMock TransportType = "mock"
)

type VCardContact

type VCardContact struct {
	Version        string
	FormattedName  string
	FirstName      string
	LastName       string
	Organization   string
	Title          string
	PhoneNumbers   map[string]string // Type -> Number
	EmailAddresses map[string]string // Type -> Email
	Addresses      map[string]Address
	URL            string
	Note           string
}

VCardContact represents contact information

type WiFiCredential

type WiFiCredential struct {
	SSID           string
	NetworkKey     string
	MACAddress     string // Optional
	AuthType       uint16
	EncryptionType uint16
	Hidden         bool // Hidden SSID
}

WiFiCredential represents WiFi network credentials

type WriteNDEFFunc added in v0.9.1

type WriteNDEFFunc func(ctx context.Context) error

WriteNDEFFunc defines a function that writes NDEF data to a tag

Directories

Path Synopsis
cmd
reader command
i2c
spi
internal
syncutil
Package syncutil provides mutex types that can optionally use deadlock detection.
Package syncutil provides mutex types that can optionally use deadlock detection.
testing
Package testing provides test utilities including a wire-level PN532 simulator.
Package testing provides test utilities including a wire-level PN532 simulator.
pkg
transport
i2c
Package i2c provides I2C transport implementation for PN532
Package i2c provides I2C transport implementation for PN532
spi
Package spi provides SPI transport implementation for PN532
Package spi provides SPI transport implementation for PN532

Jump to

Keyboard shortcuts

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