zigbee

package
v0.657.0 Latest Latest
Warning

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

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

Documentation

Overview

Package zigbee decodes Zigbee Network Layer (NWK) frames — the layer that sits on top of IEEE 802.15.4 MAC frames in the Zigbee stack. Pure offline parser; no transport, no hardware.

Wrap-vs-native judgement: Zigbee NWK is a public Zigbee Alliance specification (Zigbee Pro 2015 R21+). The walker is bit-level decoding over a documented Frame Control + address + optional fields layout. Wrapping a FAP for this would add an SD-card install step + a firmware-fork dependency for a pure parser. Native delivers offline analysis — operators decode the IEEE 802.15.4 MAC frame with ieee802154_decode, then dispatch the MAC payload here for NWK-layer fields.

Pairs with the existing ieee802154_decode — chain the two for full Zigbee frame analysis.

What this package covers:

  • NWK Frame Control (16 bits): frame type (Data / NWK Command / Reserved / Inter-PAN), protocol version (R22 = 0x2), discover route (0/1/2), multicast / security / source route / destination IEEE / source IEEE flags
  • 16-bit destination + source NWK addresses
  • Radius (hop limit) + sequence number
  • Optional 64-bit destination + source IEEE addresses (when the corresponding presence flag is set)
  • Multicast control byte (when multicast flag is set)
  • Source route subframe (when source-route flag is set): relay count + relay index + relay list
  • Auxiliary Security Header (when security flag is set): security control + frame counter + source address + key sequence number — surfaced as hex; decryption needs the network key out-of-band
  • NWK payload — surfaced as hex; APS (Application Support Sublayer) and ZCL (Zigbee Cluster Library) dissection is deferred to follow-on Specs

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

  • NWK Command frame body decoding (Route Request / Response / Leave / Rejoin / Link Status / Network Status / End Device Timeout) — separate Spec when a caller materialises
  • APS / ZDO / ZCL — higher-layer protocols
  • Decryption (needs the network key)
  • MIC validation (needs key + frame-counter context)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APSFrame added in v0.222.0

type APSFrame struct {
	FrameControl APSFrameControl `json:"frame_control"`
	// DestinationEndpoint is the 1-byte destination endpoint
	// (Data / Ack frames only; absent for Group delivery mode
	// where the group address replaces it).
	DestinationEndpoint *int `json:"destination_endpoint,omitempty"`
	// GroupAddress is the 2-byte group address (present only
	// when DeliveryMode = Group on Data/Ack frames).
	GroupAddress    string `json:"group_address,omitempty"`
	GroupAddressRaw int    `json:"group_address_raw,omitempty"`
	// ClusterID is the 2-byte cluster identifier (Data/Ack only).
	ClusterID    string `json:"cluster_id,omitempty"`
	ClusterIDRaw int    `json:"cluster_id_raw,omitempty"`
	// ProfileID is the 2-byte profile identifier (Data/Ack only).
	ProfileID    string `json:"profile_id,omitempty"`
	ProfileIDRaw int    `json:"profile_id_raw,omitempty"`
	// SourceEndpoint is the 1-byte source endpoint (Data/Ack
	// only).
	SourceEndpoint *int `json:"source_endpoint,omitempty"`
	// APSCounter is the 1-byte APS sequence counter.
	APSCounter int `json:"aps_counter"`
	// ExtendedHeaderHex is the raw extended header bytes when
	// the flag is set. Walking it (fragmentation control / block
	// number / ack bitfield) is deferred to a follow-on Spec.
	ExtendedHeaderHex string `json:"extended_header_hex,omitempty"`
	// AuxSecurityHeaderHex is the raw APS aux security header
	// when the Security flag is set. Same shape as the NWK
	// security header (1-byte security control + 4-byte frame
	// counter + optional 8-byte source IEEE + optional 1-byte
	// key sequence number).
	AuxSecurityHeaderHex string `json:"aux_security_header_hex,omitempty"`
	// PayloadHex is the APS payload after all headers.
	PayloadHex string `json:"payload_hex,omitempty"`
	// ProfileName is the recognised Zigbee profile (HA, ZLL,
	// SE, ZDP, Green Power, etc.) when ProfileID is in the
	// well-known set.
	ProfileName string `json:"profile_name,omitempty"`
}

APSFrame is the top-level decoded APS frame.

func DecodeAPS added in v0.222.0

func DecodeAPS(hexBlob string) (APSFrame, error)

DecodeAPS parses a hex-encoded Zigbee APS frame. Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeAPSBytes added in v0.222.0

func DecodeAPSBytes(b []byte) (APSFrame, error)

DecodeAPSBytes is the byte-slice variant of DecodeAPS.

type APSFrameControl added in v0.222.0

type APSFrameControl struct {
	Raw int `json:"raw"`
	// FrameType (bits 1..0).
	FrameType     int    `json:"frame_type"`
	FrameTypeName string `json:"frame_type_name"`
	// DeliveryMode (bits 3..2).
	DeliveryMode     int    `json:"delivery_mode"`
	DeliveryModeName string `json:"delivery_mode_name"`
	// AckFormat (bit 4) — only meaningful for Acknowledge frames
	// (0 = APS data ACK, 1 = APS command ACK).
	AckFormat bool `json:"ack_format"`
	// Security (bit 5) — APS auxiliary security header present.
	Security bool `json:"security"`
	// AckRequest (bit 6) — sender wants an APS-level ACK.
	AckRequest bool `json:"ack_request"`
	// ExtendedHeader (bit 7) — APS extended header present.
	ExtendedHeader bool `json:"extended_header_present"`
}

APSFrameControl is the decoded 8-bit APS Frame Control byte.

type APSFrameType added in v0.222.0

type APSFrameType int

APSFrameType is the 2-bit frame type field.

const (
	APSFrameTypeData        APSFrameType = 0
	APSFrameTypeCommand     APSFrameType = 1
	APSFrameTypeAcknowledge APSFrameType = 2
	APSFrameTypeInterPAN    APSFrameType = 3
)

func (APSFrameType) String added in v0.222.0

func (t APSFrameType) String() string

type AttributeValue added in v0.229.0

type AttributeValue struct {
	// DataType is the 1-byte type tag.
	DataType    int    `json:"data_type"`
	DataTypeHex string `json:"data_type_hex"`
	// TypeName is the canonical name from ZCL §2.5.2.
	TypeName string `json:"type_name"`
	// Value is the decoded value in the most natural Go type
	// for the underlying data — int64 for numeric, float64 for
	// float, bool for boolean, string for char string, etc.
	// nil for "no data" / "null" types.
	Value any `json:"value,omitempty"`
	// RawHex is the operator-facing hex rendering of the value
	// bytes (excluding the type tag). Empty for types with no
	// data (null, no-data).
	RawHex string `json:"raw_hex,omitempty"`
	// Length is the byte length of the value (excluding the
	// type tag).
	Length int `json:"length"`
}

AttributeValue is one decoded ZCL attribute value.

func DecodeAttribute added in v0.229.0

func DecodeAttribute(hexBlob string) (AttributeValue, int, error)

DecodeAttribute parses a hex-encoded ZCL attribute (type tag + value bytes) into a structured AttributeValue. Returns the decoded value + the number of bytes consumed (so callers walking a multi-attribute payload can advance the offset). Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeAttributeBytes added in v0.229.0

func DecodeAttributeBytes(b []byte) (AttributeValue, int, error)

DecodeAttributeBytes is the byte-slice variant of DecodeAttribute.

type DeliveryMode added in v0.222.0

type DeliveryMode int

DeliveryMode is the 2-bit delivery-mode field.

const (
	DeliveryModeUnicast   DeliveryMode = 0
	DeliveryModeIndirect  DeliveryMode = 1
	DeliveryModeBroadcast DeliveryMode = 2
	DeliveryModeGroup     DeliveryMode = 3
)

func (DeliveryMode) String added in v0.222.0

func (d DeliveryMode) String() string

type DiscoverRoute

type DiscoverRoute int

DiscoverRoute is the 2-bit discover-route field.

const (
	DiscoverRouteSuppress DiscoverRoute = 0
	DiscoverRouteEnable   DiscoverRoute = 1
	DiscoverRouteReserved DiscoverRoute = 2
)

func (DiscoverRoute) String

func (d DiscoverRoute) String() string

type Frame

type Frame struct {
	FrameControl FrameControl `json:"frame_control"`
	// DestinationAddress is the 16-bit short address of the
	// destination node (or broadcast 0xFFFF / 0xFFFD / 0xFFFC /
	// 0xFFFB for documented broadcast classes).
	DestinationAddress    string `json:"destination_address"`
	DestinationAddressRaw int    `json:"destination_address_raw"`
	// SourceAddress is the 16-bit short address of the source.
	SourceAddress    string `json:"source_address"`
	SourceAddressRaw int    `json:"source_address_raw"`
	// Radius is the hop limit (decremented at each forwarding hop).
	Radius int `json:"radius"`
	// SequenceNumber is the NWK-layer sequence number.
	SequenceNumber int `json:"sequence_number"`
	// DestinationIEEEHex / SourceIEEEHex are populated when the
	// respective presence flag is set. Stored little-endian on
	// wire, rendered big-endian to match the form printed on
	// device labels.
	DestinationIEEEHex string `json:"destination_ieee,omitempty"`
	SourceIEEEHex      string `json:"source_ieee,omitempty"`
	// MulticastControl is populated when the multicast flag is
	// set. The byte encodes mode + non-member radius + max
	// non-member radius.
	MulticastControl *MulticastControl `json:"multicast_control,omitempty"`
	// SourceRouteHex is the raw source-route subframe when the
	// flag is set (relay count + relay index + relay list).
	SourceRouteHex string `json:"source_route_hex,omitempty"`
	// AuxSecurityHeaderHex is the raw security header when the
	// flag is set. Walking it (security level / key identifier /
	// frame counter) is deferred to a follow-on Spec.
	AuxSecurityHeaderHex string `json:"aux_security_header_hex,omitempty"`
	// PayloadHex is the NWK payload after all headers.
	PayloadHex string `json:"payload_hex,omitempty"`
	// BroadcastClass names the well-known broadcast destination
	// when applicable.
	BroadcastClass string `json:"broadcast_class,omitempty"`
}

Frame is the top-level decoded NWK frame.

func Decode

func Decode(hexBlob string) (Frame, error)

Decode parses a hex-encoded Zigbee NWK frame. Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeBytes

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

DecodeBytes is the byte-slice variant of Decode.

type FrameControl

type FrameControl struct {
	Raw int `json:"raw"`
	// Frame Type (bits 1..0).
	FrameType     int    `json:"frame_type"`
	FrameTypeName string `json:"frame_type_name"`
	// Protocol Version (bits 5..2) — Zigbee Pro R22 uses 2.
	ProtocolVersion int `json:"protocol_version"`
	// Discover Route (bits 7..6).
	DiscoverRoute     int    `json:"discover_route"`
	DiscoverRouteName string `json:"discover_route_name"`
	// Bit 8: Multicast (when set, multicast control byte follows
	// the addressing fields).
	Multicast bool `json:"multicast"`
	// Bit 9: Security (auxiliary security header present).
	Security bool `json:"security"`
	// Bit 10: Source Route (source route subframe present).
	SourceRoute bool `json:"source_route"`
	// Bit 11: Destination IEEE Address present (8 bytes after
	// source NWK address).
	DestinationIEEE bool `json:"destination_ieee_present"`
	// Bit 12: Source IEEE Address present.
	SourceIEEE bool `json:"source_ieee_present"`
}

FrameControl is the decoded 16-bit NWK Frame Control field.

type MulticastControl

type MulticastControl struct {
	Raw                int    `json:"raw"`
	Mode               int    `json:"mode"`
	ModeName           string `json:"mode_name"`
	NonMemberRadius    int    `json:"non_member_radius"`
	MaxNonMemberRadius int    `json:"max_non_member_radius"`
}

MulticastControl is the decoded multicast control byte (present when the Multicast flag is set in Frame Control).

bits 0..1: Multicast Mode (0 = non-member, 1 = member)
bits 2..4: Non-Member Radius (3 bits)
bits 5..7: Max Non-Member Radius (3 bits)

type NWKFrameType

type NWKFrameType int

NWKFrameType is the 2-bit frame type field.

const (
	NWKFrameTypeData     NWKFrameType = 0
	NWKFrameTypeCommand  NWKFrameType = 1
	NWKFrameTypeReserved NWKFrameType = 2
	NWKFrameTypeInterPAN NWKFrameType = 3
)

func (NWKFrameType) String

func (t NWKFrameType) String() string

type ZCLFrame added in v0.225.0

type ZCLFrame struct {
	FrameControl ZCLFrameControl `json:"frame_control"`
	// ManufacturerCode is populated when the Manufacturer
	// Specific flag is set (2 bytes after the frame control).
	ManufacturerCode    string `json:"manufacturer_code,omitempty"`
	ManufacturerCodeRaw int    `json:"manufacturer_code_raw,omitempty"`
	// TransactionSequenceNumber is the 1-byte sequence number
	// (links request → response across the ZCL exchange).
	TransactionSequenceNumber int `json:"transaction_sequence_number"`
	// CommandID is the 1-byte command identifier.
	CommandID    int    `json:"command_id"`
	CommandIDHex string `json:"command_id_hex"`
	// CommandName is the canonical command name from the
	// profile-wide table (when FrameType=Profile-wide and the
	// command is documented). Empty for cluster-specific
	// commands (those need the cluster ID for context, which
	// lives in the APS layer).
	CommandName string `json:"command_name,omitempty"`
	// PayloadHex is the command payload bytes (uppercase hex).
	PayloadHex string `json:"payload_hex,omitempty"`
}

ZCLFrame is the top-level decoded ZCL frame.

func DecodeZCL added in v0.225.0

func DecodeZCL(hexBlob string) (ZCLFrame, error)

DecodeZCL parses a hex-encoded ZCL frame. Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeZCLBytes added in v0.225.0

func DecodeZCLBytes(b []byte) (ZCLFrame, error)

DecodeZCLBytes is the byte-slice variant of DecodeZCL.

type ZCLFrameControl added in v0.225.0

type ZCLFrameControl struct {
	Raw int `json:"raw"`
	// FrameType (bits 1..0).
	FrameType     int    `json:"frame_type"`
	FrameTypeName string `json:"frame_type_name"`
	// ManufacturerSpecific (bit 2) — when set, a 2-byte
	// manufacturer code follows the frame control.
	ManufacturerSpecific bool `json:"manufacturer_specific"`
	// Direction (bit 3) — 0 = client→server, 1 = server→client.
	// The "server" is typically the endpoint hosting the cluster
	// attributes; the "client" is the one issuing commands.
	Direction     int    `json:"direction"`
	DirectionName string `json:"direction_name"`
	// DisableDefaultResponse (bit 4) — when set, the recipient
	// suppresses the automatic Default Response that would
	// otherwise be sent for unrecognised / errored commands.
	DisableDefaultResponse bool `json:"disable_default_response"`
}

ZCLFrameControl is the decoded 8-bit ZCL Frame Control byte.

type ZCLFrameType added in v0.225.0

type ZCLFrameType int

ZCLFrameType is the 2-bit frame-type field at bits 1..0 of the ZCL frame control byte.

const (
	// ZCLFrameTypeProfileWide — profile-wide commands (Read
	// Attributes / Report Attributes / Default Response / etc.).
	// These commands apply to any cluster.
	ZCLFrameTypeProfileWide ZCLFrameType = 0
	// ZCLFrameTypeClusterSpecific — commands defined by the
	// specific cluster (On/Off has Toggle / On / Off; Level
	// Control has Move To Level; etc.).
	ZCLFrameTypeClusterSpecific ZCLFrameType = 1
)

func (ZCLFrameType) String added in v0.225.0

func (t ZCLFrameType) String() string

Jump to

Keyboard shortcuts

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