pn532

package module
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2025 License: Apache-2.0 Imports: 17 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 (
	TNFEmpty        = 0x00
	TNFWellKnown    = 0x01
	TNFMediaType    = 0x02
	TNFAbsoluteURI  = 0x03
	TNFExternalType = 0x04
	TNFUnknown      = 0x05
	TNFUnchanged    = 0x06
	TNFReserved     = 0x07
)

TNF (Type Name Format) values

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")
	ErrWriteVerificationFailed = errors.New("write verification failed: data mismatch")

	// 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 (
	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 Debugf added in v0.10.0

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

Debugf prints debug information only when debug mode is enabled This eliminates the performance overhead of fmt.Printf in production

func Debugln added in v0.10.0

func Debugln(args ...any)

Debugln prints debug information only when debug mode is enabled This eliminates the performance overhead of fmt.Printf in production

func HasTrace added in v0.9.0

func HasTrace(err error) bool

HasTrace checks if an error contains trace data

func IsCommandNotSupported added in v0.8.0

func IsCommandNotSupported(err error) bool

IsCommandNotSupported checks if an error indicates a command is not supported

func IsPN532AuthenticationError added in v0.8.0

func IsPN532AuthenticationError(err error) bool

IsPN532AuthenticationError checks if an error is a PN532 authentication failure

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 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 with proper configuration for InAutoPoll results. This method automatically sets FromInAutoPoll=true and 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() string

DebugInfo returns detailed debug information about the tag

func (*BaseTag) DebugInfoWithNDEF

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

DebugInfoWithNDEF returns detailed debug information about the tag with NDEF support

func (*BaseTag) IsMIFARE4K

func (t *BaseTag) IsMIFARE4K() bool

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

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(*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 {
	// 8-byte aligned fields first (largest to smallest)
	DetectedAt time.Time // 24 bytes (time.Time contains wall, ext, loc)
	UID        string    // 16 bytes (string header: pointer + length)
	Type       TagType   // 16 bytes (string header: pointer + length)
	UIDBytes   []byte    // 24 bytes (slice header: pointer + len + cap)
	ATQ        []byte    // 24 bytes (slice header: pointer + len + cap)
	TargetData []byte    // 24 bytes (slice header: pointer + len + cap) - Full target response data (needed for FeliCa)
	// 1-byte fields grouped together to minimize padding
	SAK            byte // 1 byte
	TargetNumber   byte // 1 byte
	FromInAutoPoll bool // 1 byte - indicates this tag was detected via InAutoPoll (skip InSelect)

}

DetectedTag represents a tag that was detected by the reader Field ordering optimized for memory alignment to reduce struct size from 120 to 112 bytes

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(path string, opts ...ConnectOption) (*Device, error)

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) DetectTag

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

DetectTag detects a single tag in the field with context support

func (*Device) DetectTags

func (d *Device) DetectTags(ctx context.Context, maxTags, baudRate byte) ([]*DetectedTag, error)

DetectTags detects multiple tags in the field with context support Uses polling strategy system with InListPassiveTarget as the preferred default

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) InAutoPoll

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

InAutoPoll polls for targets with context support

func (*Device) InListPassiveTarget added in v0.9.0

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

InListPassiveTarget detects passive targets using InListPassiveTarget command

func (*Device) InListPassiveTargetWithTimeout added in v0.9.0

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

InListPassiveTargetWithTimeout detects passive targets using InListPassiveTarget command 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, targetNumber byte) error

InRelease releases the selected target(s) with context support

func (*Device) InSelect

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

InSelect selects the specified target with context support

func (*Device) Init

func (d *Device) Init() error

Init initializes the PN532 device

func (*Device) InitContext

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

InitContext initializes the PN532 device with context support

func (*Device) InitiatorListPassiveTargets

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

InitiatorListPassiveTargets detects passive targets 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) SelectTag added in v0.9.0

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

SelectTag selects the specified detected tag for communication. This is a convenience wrapper around InSelect that uses the tag's stored target number.

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) 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(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(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 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() 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) AuthenticateContext added in v0.5.0

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

AuthenticateContext performs authentication with context support

func (*MIFARETag) AuthenticateRobust

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

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

func (*MIFARETag) AuthenticateRobustContext added in v0.5.0

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

AuthenticateRobustContext performs robust authentication with context support

func (*MIFARETag) DebugInfo

func (t *MIFARETag) DebugInfo() 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) 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) ReadNDEFRobust added in v0.8.0

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

ReadNDEFRobust 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) 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 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) 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) 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) 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(cmd byte, data []byte) ([]byte, error)

SendCommand implements Transport interface

func (*MockTransport) SendCommandWithContext added in v0.5.0

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

SendCommandWithContext 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) SetPowerMode added in v0.9.0

func (m *MockTransport) SetPowerMode(mode PN532PowerMode)

SetPowerMode sets the power mode for testing

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 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() string

DebugInfo returns detailed debug information about the NTAG tag

func (*NTAGTag) DetectType

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

DetectType attempts to detect the NTAG variant using GET_VERSION command with fallback

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) 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() (*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) 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) PwdAuth

func (t *NTAGTag) PwdAuth(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) 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) ReadNDEFRobust added in v0.8.0

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

ReadNDEFRobust 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) 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 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() 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 and waits for response
	SendCommand(cmd byte, args []byte) ([]byte, error)

	// SendCommandWithContext sends a command to the PN532 with context support
	SendCommandWithContext(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