ndef

package
v0.366.0 Latest Latest
Warning

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

Go to latest
Published: May 30, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package ndef decodes NFC Data Exchange Format messages — the payload format every NDEF-formatted NFC tag stores. Pure offline parser; no transport, no hardware.

Wrap-vs-native judgement: NDEF is a fully open NFC Forum specification (NDEF 1.0). The walker is a recursive descent over record headers + payloads with a well-known type catalog (URI prefix table, Text language code, Smart Poster nesting). Wrapping a FAP for this would add an SD-card install step + a firmware-fork dependency for a pure parser. We implement natively so operators can paste an NFC dump (or just the NDEF bytes pulled out of one) and decode every record without the tag present.

What this package covers:

  • NDEF message walker (multi-record messages, chunked records reassembled, short and long record headers, ID-length present / absent)
  • Header bit decode (MB / ME / CF / SR / IL flags + TNF)
  • Well-known type decoders: URI (with the 36-entry NFC Forum prefix table), Text (UTF-8 / UTF-16 with language code), Smart Poster (recursive nested message)
  • MIME-type pass-through (TNF=2) with MIME-type field + raw payload
  • External-type pass-through (TNF=4) with vendor:name field
  • raw payload
  • Empty / Absolute URI / Unknown / Unchanged record kinds

What this package does NOT cover (deliberately out of scope):

  • Tag-format wrappers (NTAG header / Type 2 TLV / Type 4 CC-file walker) — operators bring the bare NDEF bytes; wrapper parsing is a separate concern
  • Signature record (TNF=1 Sig) crypto verification — public keys live out-of-band
  • Re-encode — happy to add if a caller materialises

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Message

type Message struct {
	// Records is the list of decoded records in order.
	Records []Record `json:"records"`
	// Count is len(Records).
	Count int `json:"count"`
	// Warnings collects non-fatal observations (chunk
	// re-assembly notes, unrecognised well-known types, etc.).
	Warnings []string `json:"warnings,omitempty"`
}

Message is the top-level parsed NDEF message.

func Decode

func Decode(hexBlob string) (Message, error)

Decode parses a hex-encoded NDEF message. Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeBytes

func DecodeBytes(b []byte) (Message, error)

DecodeBytes is the byte-slice variant for callers that already have raw NDEF bytes (e.g. from a tag-format walker).

type Record

type Record struct {
	// Header is the raw header byte for callers that want bit-
	// level access.
	Header int `json:"header"`
	// MB / ME / CF / SR / IL are the documented header flags.
	MessageBegin bool `json:"message_begin"`
	MessageEnd   bool `json:"message_end"`
	ChunkFlag    bool `json:"chunk_flag"`
	ShortRecord  bool `json:"short_record"`
	IDLength     bool `json:"id_length_present"`
	// TNF is the 3-bit Type Name Format field as an enumerated
	// int (0-7) — see TNF constants.
	TNF     int    `json:"tnf"`
	TNFName string `json:"tnf_name"`
	// Type is the bytes from the Type field. Rendered as UTF-8
	// when valid (well-known types use ASCII like "U", "T",
	// "Sp").
	Type string `json:"type"`
	// TypeHex is the operator-facing hex rendering — useful when
	// the type bytes aren't ASCII.
	TypeHex string `json:"type_hex,omitempty"`
	// ID is the bytes from the ID field. Empty when IL=0.
	ID string `json:"id,omitempty"`
	// Payload is the raw payload bytes as hex.
	PayloadHex string `json:"payload_hex"`
	// Decoded is the per-type field decode. Populated for
	// well-known types (URI / Text / Smart Poster) and MIME /
	// External / Absolute URI. nil for Empty / Unknown /
	// Unchanged.
	Decoded map[string]any `json:"decoded,omitempty"`
}

Record is one decoded NDEF record.

type TNF

type TNF int

TNF is the 3-bit Type Name Format field in the record header.

const (
	// TNFEmpty — record carries no type / id / payload.
	TNFEmpty TNF = 0
	// TNFWellKnown — type is from the NFC Forum well-known set
	// (URI / Text / Smart Poster / Handover / etc.).
	TNFWellKnown TNF = 1
	// TNFMIME — type is a media-type per RFC 2046 ("text/plain",
	// "application/json", etc.).
	TNFMIME TNF = 2
	// TNFAbsoluteURI — type field is the full URI (rare).
	TNFAbsoluteURI TNF = 3
	// TNFExternal — type is a vendor:name external type.
	TNFExternal TNF = 4
	// TNFUnknown — payload semantics are unknown.
	TNFUnknown TNF = 5
	// TNFUnchanged — middle/last chunk of a chunked record.
	TNFUnchanged TNF = 6
	// TNFReserved — reserved by the spec.
	TNFReserved TNF = 7
)

func (TNF) String

func (t TNF) String() string

Jump to

Keyboard shortcuts

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