Help us shape the future of Go! Take the 2026 Go Developer Survey

node

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 68 Imported by: 0

Documentation

Overview

Package node is the facade over the bridge's bring-up: one Config, one New, Node.Start / Node.Stop / Node.Run, and an Aggregator the host adds its bridged endpoints to (ADR 0018 decision 5).

It mirrors matter.js ServerNode (packages/node/src/node/ServerNode.ts: 107-127 create, :274-309 the root endpoint composition) and Node (Node.ts:114-132 start, :183-186 run, :193 stop): a node is configured by behaviour ids — `network`, `commissioning`, `productDescription`, `basicInformation` — and its root carries the system servers without the host composing them.

What the facade performs is the reference daemon's bring-up (examples/reference-bridge/main.go:84-497 at b4ea1f96^), in the order bridge/bridge.go's package doc lists the ports, with every port wired:

  • New: the stores (schemas applied on Config.Store.DB), the group state, the endpoint assembler, bridge.New, the device-type validation mode, AttachACLLister, AttachGroupMessaging, AttachAuxiliaryACL, AttachDiagnosticEvents, the root servers (RootClusters) and AttachRootClusters, the Aggregator servers and AttachAggregatorClusters, then the security wiring — AttachSessionLookup, AttachAckTracker, AttachSubscriptionManager, AttachSessionRegistry, AttachCaseHandlerProvider, AttachSubscriptionStore, AttachOperationalResolver, AttachCaseInitiatorProvider — the commissioning window (AttachCommissioningWindow, with the PASE provider attached while a window is open), the fabric hooks and the event-number persistence; with Config.OTAProvider the OTA provider and AttachBDXResponder; with Config.CommissionerControl the CommissionerControl server on the Aggregator.
  • Start: bridge.Start, the DiagnosticLogs provider, StartUp and BootReason, the operational-time keeper, both PartsList providers, the stored fabrics' CASE identities, ReestablishFormerSubscriptions, the OTA requestor, AnnounceFabric for each fabric, and the node's own commissioning window when no fabric exists; the OTA provider's ACL entry once a fabric exists (and after each CommissioningComplete).

The citations of examples/reference-bridge files and lines in this package name the daemon as it stood before it moved onto the facade (commit 30fe7f1; brief R): the code they cite is the facade's now.

A host that assembles its own topology — its own endpoint.Assembler over its own device model — hands the bridge its Snapshotter through Config.Topology and gets no Aggregator; everything else stays the facade's, the group state included (Config.Groups, Node.Groups). Its operator surface reads Node.Sessions and Node.Subscriptions, and removes a fabric without a commissioner through Node.RemoveFabric (issue #87).

Left to the configuration on purpose: a nil Config.Advertiser publishes nothing, a nil Config.OTA mounts no OTA requestor, a nil Config.OTAProvider no OTA provider, a nil Config.CommissionerControl no CommissionerControl server. Left to the host: GeneralDiagnostics' TestEventTrigger enable key, the PowerSource endpoints of PowerSourceConfiguration, and the bridge's observer hooks (SetOnReassembled, SetOnFabricAdded) — reachable through Node.Root and Node.Bridge. The fabric, commissioning-complete and window events reach the host through Config.Observers, chained after the facade's own handlers; a host that set the cluster hooks the facade wires (OperationalCredentials SetOnFabricRemoved / SetOnFabricUpdated, GeneralCommissioning SetOnCommissioningComplete, the window's SetTransitionHook) would replace the facade's wiring. A window with credentials other than the configured ones is Node.OpenBasicWindow.

Index

Constants

View Source
const (
	// MaxDiscriminator is the largest 12-bit discriminator
	// ([setup.MaxDiscriminator]).
	MaxDiscriminator = setup.MaxDiscriminator
	// PBKDFIterationsMin and PBKDFIterationsMax bound
	// [Commissioning].PBKDFIterations ([spake2.IterationsMin],
	// [spake2.IterationsMax]).
	PBKDFIterationsMin = spake2.IterationsMin
	PBKDFIterationsMax = spake2.IterationsMax
	// PBKDFSaltMin and PBKDFSaltMax bound the length of
	// [Commissioning].Salt in bytes ([spake2.PBKDFMinSaltSize],
	// [spake2.PBKDFMaxSaltSize]).
	PBKDFSaltMin = spake2.PBKDFMinSaltSize
	PBKDFSaltMax = spake2.PBKDFMaxSaltSize
)

The commissioning bounds Config.Validate and Node.OpenBasicWindow check, for a host that validates its own configuration before New.

View Source
const (
	RegulatoryIndoor        = mattercore.RegulatoryIndoor
	RegulatoryOutdoor       = mattercore.RegulatoryOutdoor
	RegulatoryIndoorOutdoor = mattercore.RegulatoryIndoorOutdoor
)

The RegulatoryLocationTypeEnum values Commissioning.LocationCapability takes (mattercore.RegulatoryIndoor, …).

View Source
const DefaultProbeInterval = bridge.DefaultProbeInterval

DefaultProbeInterval is the probe cadence a zero Health.Interval selects (bridge.DefaultProbeInterval, 30 s).

View Source
const DefaultReannounceInterval = 30 * time.Minute

DefaultReannounceInterval is the re-announce cadence a zero Network.ReannounceInterval selects: 30 minutes, under half the 75-minute TTL Apple's mDNSResponder caches the records for, so a cache sees the records again before they expire.

View Source
const Scope = "node"

Scope is the one endpoint.Snapshot scope the Aggregator assembles under. A node has one partition; the assembler garbage-collects persisted endpoint numbers per scope.

Variables

View Source
var (
	// ErrNoStableKey: an endpoint whose Spec has no StableKey cannot keep
	// its endpoint number and is refused.
	ErrNoStableKey = errors.New("node: endpoint without a StableKey")
	// ErrDuplicateKey: an endpoint with the key of one already added.
	ErrDuplicateKey = errors.New("node: an endpoint with this StableKey is already added")
	// ErrUnknownKey: no endpoint with this key is added.
	ErrUnknownKey = errors.New("node: no endpoint with this StableKey")
	// ErrKeyMismatch: a replacement whose StableKey is not the key of the
	// endpoint it replaces.
	ErrKeyMismatch = errors.New("node: the replacement has another StableKey")
)

Aggregator errors.

View Source
var (
	// ErrAdministratorWindowOpen refuses the node's own window while an
	// administrator's window is open ([Node.OpenBasicWindow],
	// CommissioningWindow().OpenOwnWindow).
	ErrAdministratorWindowOpen = bridge.ErrAdministratorWindowOpen
	// ErrCommissioningBlocked is wrapped by every window open refused
	// while [Node.SetCommissioningBlocked] holds an error.
	ErrCommissioningBlocked = bridge.ErrCommissioningBlocked
	// ErrCommissioningWindowAlreadyOpen refuses a second window while one
	// is open.
	ErrCommissioningWindowAlreadyOpen = bridge.ErrCommissioningWindowAlreadyOpen
	// ErrCommissioningWindowNotConfigured is the window's answer when no
	// passcode is configured.
	ErrCommissioningWindowNotConfigured = bridge.ErrCommissioningWindowNotConfigured
)

The commissioning-window errors a host compares with errors.Is. They are the bridge's values, not copies: errors.Is(err, node.ErrX) and errors.Is(err, bridge.ErrX) answer alike.

View Source
var ErrInvalidConfig = errors.New("node: invalid configuration")

ErrInvalidConfig wraps every Config.Validate failure.

View Source
var ErrInvalidWindowCredentials = errors.New("node: invalid window credentials")

ErrInvalidWindowCredentials wraps every Node.OpenBasicWindow credential failure.

View Source
var ErrStopped = errors.New("node: stopped")

ErrStopped is returned by Node.Start after Node.Stop: a node is not restarted; a host builds a new one on the same store.

Functions

func SoftwareVersionFromString added in v0.9.1

func SoftwareVersionFromString(version string) uint32

SoftwareVersionFromString maps a version string such as "1.4.2" to the BasicInformation SoftwareVersion number, for BasicInformation.SoftwareVersion (mattercore.SoftwareVersionFromString: the major, minor and patch components packed, floored at 1).

func ValidateSetupPIN added in v0.9.1

func ValidateSetupPIN(pin uint32) error

ValidateSetupPIN reports whether pin is a usable setup passcode: within 1..99999998 and not on the trivially-guessable list (setup.IsValidSetupPIN) — the check Config.Validate applies to Commissioning.Passcode. The error wraps ErrInvalidConfig.

Types

type Advertiser added in v0.10.0

type Advertiser = mdns.Advertiser

Advertiser is the type of Config.Advertiser: what publishes the node over DNS-SD (mdns.Advertiser). An owned name for the seam; the two names are one type, so a value of either is the other.

type Aggregator

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

Aggregator is the Aggregator endpoint's set of bridged endpoints — matter.js `server.add(aggregator)` and `aggregator.add(endpoint)` (examples/device-bridge-onoff/src/BridgedDevicesNode.ts:77-78). It keeps the set in insertion order and produces the endpoint.Snapshot the assembler consumes (ADR 0018 decision 4): one scope, Scope. Before Node.Start an Add or Remove only changes the set (Start's assembly is the first); after it, each one reassembles the running bridge.

Call Aggregator.MarkComplete once the host has added every device it knows about; before that, numbers of stored endpoints are retained. The snapshots carry ModelComplete false until then and true afterwards, when a stored endpoint absent from the set is garbage-collected (endpoint.Snapshot.ModelComplete, BD-Matter-EndpointGC-ModelCompleteGate). Start does not mark the set complete.

A device.Device it holds (or a generated type around one) is bound to the node while it is held: it takes the node's clock, runs its `…Async` callbacks on its own goroutine, and answers device.Device.EndpointNumber, SetReachable and Rename through the node. Remove, Replace and Node.Stop unbind it, waiting for its queued callbacks.

func (*Aggregator) Add

func (a *Aggregator) Add(ctx context.Context, ep Endpoint) error

Add adds ep under the Aggregator — matter.js `aggregator.add(endpoint)` (endpoint/Endpoint.ts:755-770) — and binds a device to the node; a running node reassembles. A device another node holds is refused (device.ErrAddedElsewhere).

func (*Aggregator) Endpoints

func (a *Aggregator) Endpoints() []Endpoint

Endpoints returns the set, in insertion order.

func (*Aggregator) IncreaseConfigurationVersion

func (a *Aggregator) IncreaseConfigurationVersion(key device.SourceKey) error

IncreaseConfigurationVersion raises the ConfigurationVersion of the bridged endpoint with key (and the node's, as the bridge does) and persists both, so the version never decreases across a restart — the daemon's configChange (main.go:299-313 at b4ea1f96^).

func (*Aggregator) IncreaseConfigurationVersions added in v0.8.6

func (a *Aggregator) IncreaseConfigurationVersions(keys ...device.SourceKey) error

IncreaseConfigurationVersions raises, as one change of the node, the ConfigurationVersion of the bridged endpoints with keys — each physical device once — and the node's own once, after them, and persists every version raised in one pass. With no key it raises the node's alone. An unknown key fails with ErrUnknownKey before anything is raised. Mirrors matter.js BasicInformationServer.increaseConfigurationVersion(change) (BasicInformationServer.ts:132-138: the change first, one increment afterwards) with the bridged devices raised under the shared context (BridgedDeviceBasicInformationServer.ts:72-90); the bridge's IncreaseNodeConfigurationVersionWith does the raising.

func (*Aggregator) MarkComplete

func (a *Aggregator) MarkComplete()

MarkComplete declares the set authoritative: every later snapshot is model-complete, so stored endpoints absent from it are garbage-collected. Call it once the host has added every device it knows about; before that, numbers of stored endpoints are retained. On a running node it reassembles at once; a failure is logged and the next Add, Remove or Reassemble retries.

func (*Aggregator) Remove

func (a *Aggregator) Remove(ctx context.Context, key device.SourceKey) error

Remove drops the endpoint with key; a running node reassembles. Once the set is complete (Aggregator.MarkComplete) the assembler releases the endpoint's number then, as matter.js erases a deleted endpoint's storage (ServerEndpointInitializer.ts eraseDescendant, cited at endpoint.Snapshot.ModelComplete); a re-add gets a fresh number.

func (*Aggregator) Replace added in v0.10.0

func (a *Aggregator) Replace(ctx context.Context, key device.SourceKey, ep Endpoint) error

Replace puts ep in the place of the endpoint with key: ep must carry the same StableKey (ErrKeyMismatch), so it keeps the endpoint number the endpoint store holds for the key, and the running node reassembles once — the Aggregator's PartsList unchanged, the endpoint's Descriptor (device types, server list) the one change a controller sees. The old endpoint is unbound after the reassembly. It mirrors matter.js replacing a part: `close()` keeps the endpoint's number reservation (endpoint/Endpoint.ts:1024-1032, ServerEndpointInitializer.ts:67-69, where `delete()` would erase it, endpoint/Endpoint.ts:987-992) and the new endpoint with the same id is assigned it (ServerEndpointInitializer.ts:34-42).

type Attestation

type Attestation struct {
	// Files names a vendor chain on disk; [New] loads it into Chain and
	// CertificationDeclaration, which it excludes. Files that name
	// nothing keep the CSA test chain; a chain that does not load fails
	// New.
	Files *AttestationFiles
	// BlockCommissioningOnError keeps a node whose Files do not load
	// running: it serves the test chain, refuses every commissioning
	// ([Node.SetCommissioningBlocked] with the load error) and reports the
	// error in [Node.AttestationError]. Controllers already paired keep
	// working — attestation is checked only while a controller
	// commissions. It needs Files.
	BlockCommissioningOnError bool
	// Chain is the DAC, its key and the PAI; nil is the CSA test chain. A
	// host with a chain of its own (an HSM-held key, say) sets it here.
	Chain *AttestationChain
	// CertificationDeclaration is the CMS-signed CD; nil is the CSA test
	// CD for the vendor and product.
	CertificationDeclaration []byte
}

Attestation is the device attestation material.

type AttestationChain added in v0.10.0

type AttestationChain = attestation.Chain

AttestationChain is the type of Attestation.Chain: the DAC, its key and the PAI (attestation.Chain).

type AttestationFiles added in v0.9.1

type AttestationFiles = attestation.ChainFiles

AttestationFiles names a vendor attestation chain on disk (attestation.ChainFiles): the Device Attestation Certificate, its private key, the Product Attestation Intermediate and the Certification Declaration. Each file may be PEM or DER, the key PKCS#8 or SEC1.

type BasicInformation

type BasicInformation struct {
	VendorName   string
	ProductName  string
	ProductLabel string
	NodeLabel    string // mandatory
	SerialNumber string
	// UniqueID pins BasicInformation.UniqueID (quality F, Matter
	// §11.1.5.13) to a value the host persisted itself; at most 32 UTF-8
	// bytes. Empty, the facade pins it: the first boot of a store derives
	// one (mattercore.DeriveUniqueID over the vendor, product, NodeLabel
	// and SerialNumber) and keeps it under store.SettingUniqueID, every
	// later boot serves the stored value — matter.js creates uniqueId
	// once when the state has none and persists it
	// (BasicInformationServer.ts:89-91), so a later edit to NodeLabel does
	// not re-identify the node under a controller's cache. A boot with
	// bootid rotation enabled serves a per-boot value and pins nothing, so
	// the next boot without rotation serves the value pinned before it.
	// Leave the field empty unless the host owns the node's identity: a
	// value here replaces the facade's pin, silently.
	UniqueID              string
	HardwareVersion       uint16
	HardwareVersionString string
	SoftwareVersion       uint32
	SoftwareVersionString string
}

BasicInformation is the root BasicInformation the daemon configures (examples/reference-bridge/wiring.go:105-116 at b4ea1f96^, buildRootClusters), plus ProductLabel from matter.js's example (BridgedDevicesNode.ts:29-65).

type BootID added in v0.9.1

type BootID struct {
	// RotateUniqueIDs enables the rotation; [New] enables it before it
	// derives the root's UniqueID.
	RotateUniqueIDs bool
}

BootID is the per-boot UniqueID rotation of package bootid, a development aid: with RotateUniqueIDs every UniqueID the module derives — the root's BasicInformation UniqueID and every bridged endpoint's — mixes in a salt drawn once per process, so a controller sees a new bridge on every start (bootid.EnableRotation). Rotation is process-wide and stays on for the life of the process, for every node in it; a boot under rotation pins nothing in the store, so the next boot without it serves the UniqueID pinned before. Never set it in production: Apple Home and Google Home recognise a bridge's accessories by their UniqueIDs across restarts.

type BridgeTopology added in v0.10.0

type BridgeTopology struct {
	// Aggregator is the Aggregator's endpoint number; 0 before the node
	// assembled its endpoints.
	Aggregator uint16
	// Devices are the bridged devices, by endpoint number.
	Devices []BridgedDevice
}

BridgeTopology is the host's view of the node's bridge: the Aggregator's endpoint number and the bridged devices under it, each with its endpoint number — what Node.Topology returns.

type BridgedDevice added in v0.10.0

type BridgedDevice struct {
	// Key is the device's stable key ([device.Options].StableKey).
	Key device.SourceKey
	// Endpoint is its endpoint number.
	Endpoint uint16
	// DeviceType is its device type id.
	DeviceType uint16
	// Name is the NodeLabel it serves: a controller's or the host's
	// rename, else its Name.
	Name string
	// Reachable is its Reachable as a controller reads it now.
	Reachable bool
	// Added is what the host added to the Aggregator under Key (a
	// device.Device, the generated type around one, or any [Endpoint]);
	// nil for a part and for an endpoint of a host's own [Snapshotter].
	Added Endpoint
	// Parts are its parts, by endpoint number.
	Parts []BridgedDevice
}

BridgedDevice is one bridged device of a BridgeTopology, or a part of one.

type CapabilityMinimaStruct added in v0.10.0

type CapabilityMinimaStruct = mattercore.CapabilityMinimaStruct

CapabilityMinimaStruct is the type of Config.CapabilityMinima: the BasicInformation CapabilityMinima (mattercore.CapabilityMinimaStruct).

type Client added in v0.4.0

type Client struct {
	// Enabled builds the client stack; the zero value runs the node
	// without one ([Node.Peers] is nil, a node Binding entry is dropped).
	Enabled bool
	// Listen is the client socket's bind address; empty is an ephemeral
	// port on every address ("[::]:0", "0.0.0.0:0" with
	// Network.PreferIPv4). The client stack initiates from its own socket:
	// an initiator's source port is free, and the peer answers the source
	// it saw.
	Listen string
	// Names is the DNS-SD cache the peers' operational records are looked
	// up in; nil opens one on the mDNS groups (discovery.Open), which the
	// node closes on Stop. A Names the host supplies stays the host's.
	Names *discovery.Names
	// contains filtered or unexported fields
}

Client is the node's client stack: what a server node needs to reach other nodes of its fabrics — the peers its Binding entries direct. matter.js gives every ServerNode its peers (`node.peers`, the PeerSet BindingManager.ts:333 and :600 use); here the stack is opt-in.

type CommissionerControlConfig added in v0.4.0

type CommissionerControlConfig struct {
	// Approver approves requests. Required.
	Approver CommissioningApprover
	// Commissioner commissions an approved client's node. Required.
	Commissioner ReverseCommissioner
	// SupportedDeviceCategories is the attribute; a fabric-synchronising
	// bridge states FabricSynchronization.
	SupportedDeviceCategories commctrldef.SupportedDeviceCategoryBitmap
	// ApprovalTimeout and ApprovalValidity are
	// mattercore.CommissionerControlConfig's.
	ApprovalTimeout, ApprovalValidity time.Duration
}

CommissionerControlConfig mounts the CommissionerControl server (0x0751) on the Aggregator endpoint, where the Aggregator device type lists it under FabricSynchronization (device/aggregator_gen.go) and connectedhomeip's fabric-sync bridge serves it (kAggregatorEndpointId, examples/fabric-sync/bridge/CommissionerControlDelegate.h:30 at the harness pin). The two ports are the host's: the approval, and the commissioner that commissions an approved client's node — the node itself has none (ADR 0020: node does not import controller/); a host fills Commissioner with controller/commissioner.

type Commissioning

type Commissioning struct {
	// Passcode is the setup passcode; it must pass setup.IsValidSetupPIN.
	Passcode uint32
	// Discriminator is the 12-bit commissioning discriminator.
	Discriminator uint16
	// PBKDFIterations is the SPAKE2+ PBKDF2 iteration count, within
	// [spake2.IterationsMin, spake2.IterationsMax].
	PBKDFIterations int
	// Salt is the SPAKE2+ salt, spake2.PBKDFMinSaltSize to
	// spake2.PBKDFMaxSaltSize bytes.
	Salt []byte
	// LocationCapability is GeneralCommissioning's LocationCapability
	// (Matter §11.10.5.3), the regulatory locations the node supports and
	// SetRegulatoryConfig admits (GeneralCommissioningServer.ts:172-191):
	// mattercore.RegulatoryIndoor (the zero value, the facade's default),
	// RegulatoryOutdoor or RegulatoryIndoorOutdoor.
	LocationCapability uint8
}

Commissioning is matter.js `commissioning` (CommissioningServer.ts: 370-380: passcode, discriminator) plus the SPAKE2+ PBKDF parameters the daemon configures (main.go:91-92 at b4ea1f96^).

func NewCommissioningCredentials added in v0.9.1

func NewCommissioningCredentials() (Commissioning, error)

NewCommissioningCredentials draws a fresh commissioning secret: a random passcode from the valid set (bridge.RandomPasscode, never on the trivially-guessable list), a random 12-bit discriminator (bridge.RandomDiscriminator), a random salt of PBKDFSaltMax bytes (bridge.RandomSalt) and PBKDFIterationsMin PBKDF iterations — values Config.Validate accepts. LocationCapability is left at its zero value (RegulatoryIndoor). A host that has no configured secret uses it for Config.Commissioning, or copies its fields into the WindowCredentials of one Node.OpenBasicWindow; it persists the result itself when the node's own window must keep its pairing code across restarts.

func (Commissioning) WindowCredentials added in v0.9.1

func (c Commissioning) WindowCredentials(timeout time.Duration) WindowCredentials

WindowCredentials are c's secret as the credentials of one Node.OpenBasicWindow window that stays open for timeout (0 is the node's own window default) — a fresh window secret is NewCommissioningCredentials().WindowCredentials(timeout).

type CommissioningApprover added in v0.10.0

type CommissioningApprover = mattercore.CommissioningApprover

CommissioningApprover is the type of CommissionerControlConfig.Approver: the host's decision on a commissioning request (mattercore.CommissioningApprover).

type CommissioningWindow added in v0.9.1

type CommissioningWindow = bridge.CommissioningWindow

CommissioningWindow is the commissioning window Node.CommissioningWindow returns (bridge.CommissioningWindow).

type Config

type Config struct {
	// Network mirrors matter.js `network` (NetworkServer.ts:202-222).
	Network Network
	// Commissioning mirrors matter.js `commissioning`
	// (CommissioningServer.ts:400-410).
	Commissioning Commissioning
	// ProductDescription mirrors matter.js `productDescription`
	// (ProductDescriptionServer.ts:70-90): the identity the commissionable
	// advertisement carries.
	ProductDescription ProductDescription
	// BasicInformation mirrors matter.js `basicInformation`
	// (examples/device-bridge-onoff/src/BridgedDevicesNode.ts:29-65).
	BasicInformation BasicInformation
	// Store is where the node keeps its fabrics, credentials, ACL, groups,
	// subscriptions, settings and endpoint numbers.
	Store Store
	// Advertiser publishes the node over DNS-SD. nil is the node's own:
	// mdns.Zeroconf with the subtype responder, configured by
	// [Network].MDNS, or mdns.NewNoop() with [MDNS].Disabled. [Node.Stop]
	// closes it, the host's as the node's.
	Advertiser Advertiser
	// DeviceTypeValidation is the bridge's device-type judgement mode
	// (bridge.SetDeviceTypeValidation); the zero value is matter.js's
	// warn mode.
	DeviceTypeValidation DeviceTypeValidationMode
	// Attestation is the device attestation material; the zero value is
	// the CSA test chain and test Certification Declaration for the
	// configured vendor and product (attestation.BuildTestChain,
	// attestation.BuildTestCertificationDeclaration) — pairable with every
	// commissioner's test PAA, and not shippable.
	Attestation Attestation
	// OTA mounts the OTA Software Update Requestor on the root when set;
	// nil leaves it out (and the OtaRequestor device type with it).
	OTA *OtaConfig
	// OTAProvider serves OTA images: the OTA Software Update Provider on an
	// endpoint of device type OtaProvider beside the Aggregator, its images
	// over BDX (ADR 0021). nil, or no ImageSource, mounts none. With
	// Topology set the node builds the provider ([Node.OTAProvider]) and
	// the host mounts it.
	OTAProvider *OTAProviderConfig
	// CommissionerControl mounts the CommissionerControl server on the
	// Aggregator (ADR 0020 stage 6); nil mounts none. The reference daemon
	// mounts none.
	CommissionerControl *CommissionerControlConfig
	// FixedLabels is the root FixedLabel list; nil serves an empty list.
	FixedLabels []fixedlabeldef.LabelStruct
	// Locales are the root LocalizationConfiguration's SupportedLocales,
	// the first of them its ActiveLocale; nil is en-US alone. matter.js
	// detects the active locale and lists it alone when the host states
	// neither (LocalizationConfigurationServer.ts:14-21 initialize); a host
	// states its own, as the reference daemon does (en-US, de-DE).
	Locales []string
	// Groups, when set, is the group state the node runs on, for a host
	// whose own assembler ([Config].Topology) mounts the stack's Groups and
	// ScenesManagement servers over it (endpoint.Config.Groups): one
	// manager serves the endpoints' servers, the bridge's group-message
	// routing and the root's GroupKeyManagement and Groupcast, as matter.js
	// has one GroupKeyManagementServer the GroupsServers of every endpoint
	// write (GroupsServer.ts). The facade loads it (groups.Manager.Load)
	// and attaches it; nil builds one over the credential store, which
	// [Node.Groups] returns for a host that binds its assembler after New.
	// An advanced seam (docs/guides/advanced-seams.md): a host with the
	// facade's own assembler leaves it nil.
	Groups *Groups
	// Topology, when set, is the host's own topology — a host that
	// assembles its endpoints itself (its own endpoint.Assembler over its
	// own device model, one endpoint.Snapshot per scope, its own label and
	// scene persistence) hands the bridge its Snapshotter here, as the
	// reference daemon did before the facade (main.go:188 at b4ea1f96^, bridge.New's
	// first argument). The facade then builds no assembler and no
	// [Aggregator] ([Node.Aggregator] is nil); the root and Aggregator
	// endpoints' servers, the PartsList providers and every port stay the
	// facade's. nil is the facade's [Aggregator] under one scope.
	Topology Snapshotter
	// EndpointPersistence, when set, replaces the facade's own scene and
	// bridged-NodeLabel persistence ([NewEndpointPersistence] over the
	// node's store) in the facade's assembler and [Aggregator], for a host
	// that keeps that state itself; [Node.Persistence] returns it. nil is
	// the facade's own.
	EndpointPersistence EndpointPersistence
	// AggregatorServers are mounted on the Aggregator endpoint after
	// Identify, Descriptor, FixedLabel and UserLabel — an Actions server,
	// say (the daemon's buildAggregatorClusters extra, wiring.go:330-345 at b4ea1f96^).
	AggregatorServers []contract.ClusterServer
	// SupportedFabrics is OperationalCredentials' SupportedFabrics, the
	// number of fabrics the node admits (Matter §11.18.4.4: 1 to 254); 0
	// is 5, the facade's value before it was configurable. matter.js
	// defaults it to 254 when unset (OperationalCredentialsServer.ts:
	// 84-88 initialize), which cluster/core does too; the facade keeps 5.
	SupportedFabrics uint8
	// DisableTimeSynchronization leaves the TimeSynchronization cluster
	// (0x0038) off the root; the zero value mounts it, as the facade
	// always did. RootNode carries it under an optional conformance
	// (device/root_node_gen.go, generated from the snapshot).
	// Without it GeneralDiagnostics has no UTC clock: TimeSnapshot
	// answers SystemTimeMs alone and PosixTimeMs null, as matter.js
	// GeneralDiagnosticsServer.timeSnapshot does without a
	// TimeSynchronizationBehavior (GeneralDiagnosticsServer.ts:168-182).
	DisableTimeSynchronization bool
	// GeneralDiagnosticsFeatures selects the root GeneralDiagnostics'
	// features (mattercore.NewGeneralDiagnosticsWith); nil keeps
	// matter.js's default selection, DataModelTest
	// (GeneralDiagnosticsServer.ts:51-52). Without DataModelTest a
	// MaxPathsPerInvoke above one fails [Node.Start]
	// (mattercore.GeneralDiagnostics.CheckDataModelTest).
	GeneralDiagnosticsFeatures *GeneralDiagnosticsFeatures
	// MaxPathsPerInvoke is the most commands one InvokeRequest may carry:
	// the root BasicInformation advertises it, the PASE and CASE session
	// parameters carry it and the invoke path refuses a larger batch with
	// InvalidAction. 0 is im.DefaultMaxPathsPerInvoke (10), matter.js's
	// DEFAULT_MAX_PATHS_PER_INVOKE. Mirrors matter.js
	// basicInformation.maxPathsPerInvoke, which InteractionServer.ts:198
	// enforces.
	MaxPathsPerInvoke uint16
	// CapabilityMinima is the root BasicInformation's CapabilityMinima:
	// a zero field takes matter.js's default (the Matter floor of 3 for
	// CaseSessionsPerFabric and SubscriptionsPerFabric, 20 for the four
	// revision-6 fields, BasicInformationServer.ts initialize), a value
	// the host sets wins (CapabilityMinimaTest.ts "caller-provided values
	// win").
	CapabilityMinima CapabilityMinimaStruct
	// Client is the node's client stack ([Client]): the socket, exchanges
	// and peers its Binding entries reach other nodes through. The zero
	// value runs without one.
	Client Client
	// BootID selects the development rotation of UniqueIDs ([BootID]); the
	// zero value keeps every UniqueID stable across restarts.
	BootID BootID
	// Health runs the node's health probe ([Health], [Node.Health]); the
	// zero value runs none.
	Health Health
	// Observers are the host's callbacks on fabric and commissioning
	// events, each chained after the facade's own handler (observers.go);
	// the zero value observes nothing.
	Observers Observers
	// Logger is the node's logger; nil is slog.Default().
	Logger *slog.Logger
	// Clock is the node's time source; nil is [clock.System]. The node
	// hands it to the bridge (every device-side interval: the ack pump,
	// MRP, subscriptions' timers, the commissioning window, PASE lockout),
	// the session table, the subscription engine, the PASE and CASE
	// providers, the operational resolver, an advertiser that takes a
	// clock ([mdns.Zeroconf]), the group sender, the root's cluster
	// servers, OTA, the store's persist loop and the reopen poll. A test
	// passes a [github.com/SukramJ/go-fabric/clock/clocktest.Fake].
	Clock clock.Clock
}

Config is the node's configuration, code-first (ADR 0018 decision 5). Its groups are the behaviour ids matter.js's ServerNode.Configuration keys its options by — `network`, `commissioning`, `productDescription`, `basicInformation` (packages/node/src/node/ServerNode.ts:107-127) — for the subset the reference daemon uses; the rest is what the daemon's bring-up needs beyond them (examples/reference-bridge/main.go:84-497 at b4ea1f96^).

func (*Config) Validate

func (c *Config) Validate() error

Validate holds the checks the daemon applies to its flags (main.go:113-131 at b4ea1f96^): the discriminator's 12 bits, the passcode's range and the trivially-guessable list, the PBKDF iteration range and salt length the SPAKE2+ verifier needs, and the identity the bridge and the assembler refuse to start without. The bounds are this package's MaxDiscriminator, PBKDFIterationsMin, PBKDFIterationsMax, PBKDFSaltMin and PBKDFSaltMax; the passcode check is ValidateSetupPIN — a host checks its own configuration against them before New.

type DeviceTypeValidationMode added in v0.10.0

type DeviceTypeValidationMode = endpoint.DeviceTypeValidationMode

DeviceTypeValidationMode is the type of Config.DeviceTypeValidation: how the node treats a device type that breaks its conformance (endpoint.DeviceTypeValidationMode).

type DiagnosticEvent added in v0.9.1

type DiagnosticEvent = diagevent.Event

DiagnosticEvent is one entry of the node's diagnostic trace (diagevent.Event): the moments that explain a failed pairing.

type Endpoint

type Endpoint interface {
	Spec() endpoint.Spec
}

Endpoint is what the Aggregator holds: anything that describes itself as an endpoint.Spec — a device.Device, or any type with a Spec method (ADR 0018 decision 4).

type EndpointPersistence added in v0.5.0

type EndpointPersistence interface {
	endpoint.ScenesStore
	// OnNodeLabelWritten persists a commissioner-written NodeLabel of the
	// bridged endpoint under key; it is endpoint.Config.OnNodeLabelWritten.
	OnNodeLabelWritten(key device.SourceKey, label string)
	// NodeLabel is the label persisted for key, "" for none.
	NodeLabel(ctx context.Context, key device.SourceKey) string
}

EndpointPersistence is the endpoint-level stack state the facade keeps for its own assembler, exported for a host that assembles its endpoints itself (Config.Topology, issue #117): a bridged endpoint's scene table (endpoint.Config.Scenes, under "scenes.<key>") and the per-endpoint NodeLabel a commissioner wrote (endpoint.Config.OnNodeLabelWritten, under "bridged_node_label.<key>"), each keyed by the endpoint's stable key's String(). A host restores a label by setting its endpoint.Spec's NodeLabel from EndpointPersistence.NodeLabel before assembling, as the facade's Aggregator does. matter.js keeps both as nonvolatile endpoint state (the citations on the methods of the implementation below and on endpoint.ScenesStore).

func NewEndpointPersistence added in v0.5.0

func NewEndpointPersistence(st *store.Store, logger *slog.Logger) EndpointPersistence

NewEndpointPersistence returns the facade's EndpointPersistence over st's settings table — the same keys Node.Persistence uses, so a host may build it before New (for the assembler its Topology runs) over a store the node later opens. st must hold the store schema (store.Apply); a nil logger is slog.Default().

type FabricInfo added in v0.3.1

type FabricInfo struct {
	FabricIndex        uint8
	FabricID           uint64
	NodeID             uint64
	RootPublicKey      []byte
	CompressedFabricID [8]byte
	// VendorID is the AdminVendorID AddNOC carried for the fabric.
	VendorID uint16
	// Label is the fabric's label (UpdateFabricLabel); empty until an
	// administrator sets one.
	Label string
}

FabricInfo names one fabric, as OperationalCredentials' AddNOC hook carries it (cluster/core OpcredsConfig.OnFabricInstalled: fabric index, fabric id, node id, root public key) plus the compressed fabric id the operational record is named by, and the vendor and label the fabric's administrator set — the fields of the store's record a host shows (Node.FabricInfos).

type GeneralDiagnosticsFeatures added in v0.10.0

type GeneralDiagnosticsFeatures = mattercore.GeneralDiagnosticsFeatures

GeneralDiagnosticsFeatures is the type of Config.GeneralDiagnosticsFeatures: the feature selection of the root GeneralDiagnostics (mattercore.GeneralDiagnosticsFeatures).

type Groups added in v0.10.0

type Groups = groups.Manager

Groups is the type of Config.Groups and of what Node.Groups returns: the group state one node shares between its Groups, GroupKeyManagement and Groupcast servers and its group messaging (groups.Manager). An owned name for the seam, as Advertiser is.

type Health added in v0.9.1

type Health struct {
	// Interval is the probe cadence; 0 is [DefaultProbeInterval].
	Interval time.Duration
	// OnSample receives every verdict, the first at [Node.Start]. An
	// unhealthy one (Healthy false) is a condition the probe states, not a
	// sample — what bridge.HealthRecorder.RecordUnhealthy receives — so a
	// host that damps flapping samples records it at once. It runs on the
	// probe's goroutine and must not block.
	OnSample func(HealthSample)
}

Health configures the node's health probe (bridge.StartHealthProbe): from Node.Start to Node.Stop the node checks its operational listener on Config.Clock and hands each verdict to OnSample; Node.Health returns the last one. The probe runs when OnSample is set or Interval is positive; the zero value runs none.

type HealthSample added in v0.9.1

type HealthSample = bridge.HealthSample

HealthSample is one verdict of the node's health probe (bridge.HealthSample): Healthy while the operational UDP listener is bound, with a stable English Note.

type MDNS added in v0.9.1

type MDNS struct {
	// Disabled publishes nothing (mdns.NewNoop): no commissioner discovers
	// the node, which a controller then reaches by address alone.
	Disabled bool
	// HostName, when set, is the SRV target of every record
	// (mdns.Zeroconf.HostName, without ".local"); empty is the name the
	// advertiser derives from the interface's MAC.
	HostName string
}

MDNS configures the DNS-SD advertiser the node builds when Config.Advertiser is nil. The zero value advertises on the network.

type MDNSFinding added in v0.9.1

type MDNSFinding = mdns.Finding

MDNSFinding is one result of Node.DiagnoseMDNS (mdns.Finding).

type MDNSService added in v0.9.1

type MDNSService = mdns.Service

MDNSService is one record the node advertises (Node.MDNSServices, mdns.Service).

type Network

type Network struct {
	// Listen is the UDP listen address; empty is ":5540".
	Listen string
	// PreferIPv4 forces an IPv4-only socket.
	PreferIPv4 bool
	// TCP selects the Matter TCP transport; the zero value is TCP off. A
	// TCP role is also what the node's PASE and CASE responders advertise
	// in their session parameters (SupportedTransports: tcpServer for
	// Incoming, tcpClient for Outgoing), so a peer learns it during the
	// handshake and may open TCP to us — matter.js
	// ServerNetworkRuntime.ts:355-363.
	TCP TCPConfig
	// WiFi mounts WiFiNetworkDiagnostics (0x0036) on the root for a node on
	// Wi-Fi; the zero value (no Reporter) mounts none. NetworkCommissioning
	// stays Ethernet-only either way (concept v2 §B.4): the node states the
	// RootNode device-type condition WiFi, under which RootNode lists the
	// cluster ("[WiFi]", device/root_node_gen.go), through the assembler's
	// RootDeviceConditions — with [Config].Topology the host's own
	// assembler states it. EthernetNetworkDiagnostics stays mounted beside
	// it.
	WiFi WiFi
	// WiFiCommissioning mounts NetworkCommissioning with the Wi-Fi feature
	// instead of Ethernet, its scan and connect done by Driver — what the
	// commissioner's network steps configure. TESTING ONLY: the module's
	// nodes are Ethernet-attached; the reference daemon's --wifi-sim is
	// the one user. The zero value (no Driver) keeps the Ethernet-only
	// server, and the composition is unchanged.
	WiFiCommissioning WiFiCommissioning
	// ReannounceInterval is the cadence at which the node re-publishes its
	// DNS-SD records when its Advertiser is an mdns.Reannouncer
	// (mdns.Zeroconf is): the loop starts on [Node.Start] and stops on
	// [Node.Stop]. 0 is [DefaultReannounceInterval]. The loop is this
	// module's own device, not matter.js's (mdns.Reannouncer).
	ReannounceInterval time.Duration
	// DisableReannounce keeps the re-announce loop off; [Node.TriggerReannounce]
	// still re-publishes on demand.
	DisableReannounce bool
	// MDNS configures the advertiser the node builds when
	// [Config].Advertiser is nil; the zero value advertises (Zeroconf with
	// the subtype responder).
	MDNS MDNS
}

Network is matter.js `network` for the keys the daemon uses (NetworkServer.ts:202-222: port and listening address, ipv4, tcp).

type Node

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

Node is a Matter node: the bridge, its root and Aggregator endpoints and every port bridge documents, wired in the documented order.

func New

func New(cfg Config) (*Node, error)

New builds the node: everything the reference daemon builds before bridge.Start (examples/reference-bridge/main.go:135-397 at b4ea1f96^), with every port of bridge/bridge.go's package doc attached in its documented order.

Nothing is left as a noop except what the configuration omits on purpose: a nil Advertiser is the node's own (Zeroconf with the subtype responder, or Noop under Network.MDNS.Disabled), a nil OTA mounts no OTA requestor. The TestEventTrigger enable key is not armed (Root().GeneralDiagnostics.EnableTestEventTriggers is the host's), and SetOnReassembled / SetOnFabricAdded stay the bridge's nil-safe hooks for the host.

New starts the subscription engine and the PASE / CASE reapers, as the daemon does before Start; call Node.Stop to end them, whether or not the node was started.

func (*Node) Aggregator

func (n *Node) Aggregator() *Aggregator

Aggregator returns the Aggregator endpoint's bridged-device set — nil when the host assembles its own topology (Config.Topology).

func (*Node) AttestationError added in v0.9.1

func (n *Node) AttestationError() error

AttestationError is the load error of Attestation.Files under Attestation.BlockCommissioningOnError: the node runs on the test chain and refuses every commissioning until the files are fixed and a new node is built. nil when the files loaded, named nothing, or are unset.

func (*Node) Bindings added in v0.4.0

func (n *Node) Bindings() *binding.Manager

Bindings returns the binding manager: it resolves the entries of the node's Binding servers into the peers they direct (package binding). Without the client stack, a node entry is dropped ("client stack disabled"); group and self-bindings resolve as ever.

func (*Node) BootReason

func (n *Node) BootReason() uint8

BootReason returns the GeneralDiagnostics BootReason the node was built with — the value Node.Start's EmitBootReason reports. The device layer passes it to the default OnOff servers (onoff.Config.BootReason), which skip StartUpOnOff after a software update (OnOffServer.ts:36, :326-331).

func (*Node) Bridge

func (n *Node) Bridge() *bridge.Bridge

Bridge returns the bridge, for a host that needs a port the facade does not cover (ADR 0018 decision 5).

func (*Node) CommissionerControl added in v0.4.0

func (n *Node) CommissionerControl() *mattercore.CommissionerControl

CommissionerControl returns the CommissionerControl server — nil unless Config.CommissionerControl mounts one on the Aggregator.

func (*Node) CommissioningWindow

func (n *Node) CommissioningWindow() *CommissioningWindow

CommissioningWindow returns the commissioning window.

func (*Node) DiagnoseMDNS added in v0.9.1

func (n *Node) DiagnoseMDNS() []MDNSFinding

DiagnoseMDNS inspects the records the node currently advertises and reports what would keep a controller from finding or commissioning it (mdns.Diagnose); nil when the advertiser publishes nothing on purpose (MDNS.Disabled, or a host's Noop).

func (*Node) FabricInfos added in v0.9.1

func (n *Node) FabricInfos(ctx context.Context) ([]FabricInfo, error)

FabricInfos returns the installed fabrics in the store's order (by fabric index): index, fabric and node id, root public key, compressed fabric id, vendor and label.

func (*Node) Groups added in v0.4.0

func (n *Node) Groups() *Groups

Groups returns the group state the node runs on — Config.Groups, or the manager the facade built. A host that assembles its own topology binds it into its assembler (endpoint.Config.Groups), so the endpoints' Groups servers, the bridge's group-message routing and the root's GroupKeyManagement share one state.

func (*Node) Health added in v0.9.1

func (n *Node) Health() (HealthSample, bool)

Health returns the health probe's last verdict; false before the first one and when Config.Health runs no probe.

func (*Node) LocalAddr added in v0.9.1

func (n *Node) LocalAddr() string

LocalAddr returns the bound `host:port` of the node's operational UDP listener — empty before Node.Start and after Node.Stop (bridge.Bridge.LocalAddr). It is what the health probe checks.

func (*Node) MDNSEnabled added in v0.9.1

func (n *Node) MDNSEnabled() bool

MDNSEnabled reports whether the node's advertiser publishes on the network (mdns.IsEnabled): false for Noop.

func (*Node) MDNSServices added in v0.9.1

func (n *Node) MDNSServices() []MDNSService

MDNSServices returns the records the node's advertiser currently publishes (mdns.Advertiser.Active).

func (*Node) OTAProvider added in v0.4.0

func (n *Node) OTAProvider() *mattercore.OTAProvider

OTAProvider returns the OTA Software Update Provider — nil unless Config.OTAProvider names an image source. A host that assembles its own topology (Config.Topology) mounts it on an endpoint of its own; with the facade's Aggregator the node mounts it.

func (*Node) OpenBasicWindow added in v0.3.1

func (n *Node) OpenBasicWindow(ctx context.Context, creds WindowCredentials) error

OpenBasicWindow opens the node's own commissioning window with its own credentials: PASE runs against a verifier computed from creds (spake2.NewVerifierContext, the function commissioning/ uses) and installed through the path an administrator's verifier takes, and the node is advertised with CM=1 under creds.Discriminator. The window is the node's own (CommissioningWindow().IsOwnWindow): it reads WindowNotOpen on the AdministratorCommissioning cluster, an administrator's OpenCommissioningWindow replaces it, and it closes on its timeout, on CommissioningComplete and on RevokeCommissioning. Opened while a basic window or the node's own window is open, it replaces that window; while an administrator's window is open it returns bridge.ErrAdministratorWindowOpen. A direct CommissioningWindow().OpenOwnWindow while it is open ends it: the restarted window runs with the configured credentials and is advertised under the configured discriminator. Once it closes, the configured credentials are back: a node without a fabric reopens its own window under the configured discriminator, a commissioned node publishes no commissionable record until the next window — the facade's window semantics, unchanged.

matter.js has no per-window basic credentials: openBasicCommissioningWindow opens the window with the node's own passcode (packages/node/src/behaviors/administrator-commissioning/ AdministratorCommissioningServer.ts:105-121), and DeviceCommissioner #openWindow advertises `discriminator ?? commissioningConfig.discriminator` (packages/protocol/src/protocol/DeviceCommissioner.ts:236-256). This is a host extension, exposed as the facade's own API rather than as a cluster command.

func (*Node) PairingCodes

func (n *Node) PairingCodes() (qr, manual string, err error)

PairingCodes returns the QR code payload and the manual pairing code of the configured passcode and discriminator — matter.js `commissioning.pairingCodes` (CommissioningServer.ts:400-410), as the daemon prints them (main.go:504-518 at b4ea1f96^).

func (*Node) PairingCodesFor added in v0.9.1

func (n *Node) PairingCodesFor(creds WindowCredentials) (qr, manual string, err error)

PairingCodesFor returns the QR code payload and the manual pairing code of a window the host opens with its own credentials (Node.OpenBasicWindow): creds' passcode and discriminator under the node's vendor and product, on-network discovery — what Node.PairingCodes returns for the configured secret.

func (*Node) Peers added in v0.4.0

func (n *Node) Peers() *peer.Set

Peers returns the client stack's peer set — the nodes of our fabrics the node talks to as a client — or nil when Config.Client is off.

func (*Node) Persistence added in v0.5.0

func (n *Node) Persistence() EndpointPersistence

Persistence is the endpoint-level persistence (scene tables, bridged NodeLabels) the facade's assembler uses: Config.EndpointPersistence when set, else the facade's own over Node.Store — what a host with its own assembler (Config.Topology) hands that assembler (issue #117).

func (*Node) RemoveFabric added in v0.4.0

func (n *Node) RemoveFabric(ctx context.Context, fabricIndex uint8) error

RemoveFabric removes a fabric without a commissioner — a host's revoke or factory reset — exactly as the RemoveFabric command does: the fabric's rows go, and the same fan-out runs (the Leave event, the OTA providers, the CASE identity and the operational record, the sessions and subscriptions, the group state, the node's own window once the last fabric is gone) followed by the host's OnFabricRemoved observer. matter.js reaches it the same way from the host, Fabric.leave() (Fabric.ts:423-433), the call the command itself makes (OperationalCredentialsServer.ts:425). An unknown index is store.ErrFabricNotFound.

func (*Node) Root

func (n *Node) Root() *RootClusters

Root returns the root endpoint's servers.

func (*Node) Run

func (n *Node) Run(ctx context.Context) error

Run starts the node, waits for ctx to end and stops it — matter.js Node.run (Node.ts:183-186).

func (*Node) Sessions added in v0.4.0

func (n *Node) Sessions() *SessionManager

Sessions returns the secure-session manager, for a host's diagnostics (operational.Manager.Sessions, Occupancy): which peers hold a PASE or CASE session, on which fabric, and when each was last active. The facade owns its lifecycle; a host reads it and leaves closing to the node.

func (*Node) SetCommissioningBlocked added in v0.5.4

func (n *Node) SetCommissioningBlocked(ctx context.Context, err error)

SetCommissioningBlocked refuses every new commissioning while err is non-nil — the node's own window (at Start and after the last fabric is removed), Node.OpenBasicWindow, the host's opener and both AdministratorCommissioning commands of a paired controller, which answer FAILURE — and revokes a window that is open; controllers already paired keep working. nil lifts the block and, on a node without a fabric, reopens its own window at once. A host that cannot serve the attestation chain it was configured with calls it before Node.Start. See bridge.CommissioningWindow.SetBlocked; matter.js has no counterpart (BD-Matter-CommissioningBlocked).

func (*Node) Start

func (n *Node) Start(ctx context.Context) error

Start brings the node online: the bridge starts, and the daemon's post-start sequence runs (main.go:428-489 at b4ea1f96^) — the diagnostic-log provider, the StartUp and BootReason events, the operational-time keeper, the PartsList providers, the CASE identities of the fabrics a previous run installed, the re-establishment of their subscriptions, the OTA requestor, their operational records, and the node's own commissioning window when no fabric exists. Start is idempotent, as matter.js Node.start (Node.ts:114-132); after Stop it is ErrStopped.

func (*Node) Stop

func (n *Node) Stop(ctx context.Context) error

Stop takes the node offline and releases what New and Start began, in the daemon's shutdown order (main.go:430-450 at b4ea1f96^): the OTA requestor, the operational time stored once more, BasicInformation ShutDown (when the node was started), the PASE providers, the CASE reaper, the session table's idle reaper, the subscription engine, the re-announce loop, the health probe, the bridge, the advertiser and the store the node opened for Store.Path. Stop is idempotent (matter.js Node.stop, Node.ts:193) and safe without Start.

func (*Node) Store

func (n *Node) Store() *store.Store

Store returns the credential store the node runs on.

func (*Node) Subscriptions added in v0.4.0

func (n *Node) Subscriptions() *SubscriptionManager

Subscriptions returns the subscription manager, for a host's diagnostics (subscription.Manager.CountBySession, Active): the subscriptions riding on each session. The facade owns its lifecycle; a host reads it and leaves closing to the node.

func (*Node) Topology added in v0.10.0

func (n *Node) Topology() BridgeTopology

Topology returns the host's view of the bridge as the node serves it now: empty before Node.Start. It is the facade's route to what the assembled endpoint tree (Node.Bridge().Topology()) holds — the endpoint numbers matter.js's node assigns its endpoints (packages/node/src/node/server/ServerEndpointInitializer.ts:34-42).

func (*Node) TriggerReannounce added in v0.5.0

func (n *Node) TriggerReannounce(ctx context.Context)

TriggerReannounce re-publishes the node's DNS-SD records now — for a host that observes a link change (interface up, address assigned) and should not wait for the next periodic re-announce. It forwards to the advertiser's mdns.Reannouncer.TriggerReannounce and is a no-op on an advertiser that is not one (mdns.Noop, a custom Advertiser).

func (*Node) UniqueID added in v0.9.1

func (n *Node) UniqueID() string

UniqueID returns the BasicInformation UniqueID the node serves: the host's BasicInformation.UniqueID, else the value the node pinned in its store at the first boot (or, with BootID.RotateUniqueIDs, this boot's value).

type OTAApplier added in v0.10.0

type OTAApplier = mattercore.OtaApplier

OTAApplier is the type of OtaConfig.Applier: the requestor's consent and apply hooks (mattercore.OtaApplier).

type OTAApplyPolicy added in v0.10.0

type OTAApplyPolicy = mattercore.OTAApplyPolicy

OTAApplyPolicy is the type of OTAProviderConfig.ApplyPolicy: when a requestor may apply a downloaded image (mattercore.OTAApplyPolicy).

type OTAConsent added in v0.10.0

type OTAConsent = mattercore.OTAConsent

OTAConsent is the type of OTAProviderConfig.Consent: the user-consent port of the provider (mattercore.OTAConsent).

type OTAConsentState added in v0.10.0

type OTAConsentState = mattercore.OTAConsentState

OTAConsentState is what an OTAConsent answers (mattercore.OTAConsentState).

type OTAImageSource added in v0.10.0

type OTAImageSource = mattercore.OTAImageSource

OTAImageSource is the type of OTAProviderConfig.ImageSource: where the provider reads the images it offers (mattercore.OTAImageSource).

type OTAPeer added in v0.10.0

type OTAPeer = mattercore.OTAPeer

OTAPeer names the requestor an OTAProviderConfig callback is about (mattercore.OTAPeer).

type OTAProviderConfig added in v0.4.0

type OTAProviderConfig struct {
	// ImageSource names and serves the images; nil mounts no provider.
	ImageSource OTAImageSource
	// Consent asks the user; nil declines an image that needs a consent
	// the requestor cannot give.
	Consent OTAConsent
	// ApplyPolicy decides an allowed apply; nil proceeds at once.
	ApplyPolicy OTAApplyPolicy
	// BDXMaxBlockSize, when set, caps the block size of the image
	// transfers.
	BDXMaxBlockSize uint16
	// OnStatusChange observes the requestors' update states; nil observes
	// nothing.
	OnStatusChange func(peer OTAPeer, status OTAUpdateStatus, version uint32)
}

OTAProviderConfig serves OTA software images to the requestors of the node's fabrics: the OTA Software Update Provider (0x0029) on an endpoint of its own, device type OtaProvider (0x0014), next to the Aggregator (ADR 0021). The three ports are the host's part of matter.js's SoftwareUpdateManager (mattercore.OTAProvider).

type OTAUpdateStatus added in v0.10.0

type OTAUpdateStatus = mattercore.OTAUpdateStatus

OTAUpdateStatus is the status OTAProviderConfig.OnStatusChange reports for a requestor (mattercore.OTAUpdateStatus).

type Observers added in v0.3.1

type Observers struct {
	// OnFabricAdded runs after an AddNOC installed a fabric and the
	// facade rebuilt the fabric's CASE identity and announced its
	// operational record. Mirrors matter.js FabricManager `events.added`
	// (FabricManager.ts:209).
	OnFabricAdded func(FabricInfo) error
	// OnFabricRemoved runs after RemoveFabric (or the fail-safe rollback
	// of an AddNOC) deleted a fabric and the facade's cleanup ran: the
	// fabric, its ACL and its keys are gone from the store, its CASE
	// identity and operational record are withdrawn, its sessions are
	// told and closed (the invoking one after the response). When it was
	// the last fabric the node's own window reopens afterwards, once the
	// node is idle — no fail-safe armed and no session left (matter.js
	// #resetWhenIdle); OnWindowTransition reports that. Mirrors
	// matter.js FabricManager `events.deleted` (FabricManager.ts:253).
	OnFabricRemoved func(FabricInfo) error
	// OnFabricUpdated runs after an UpdateNOC (or the fail-safe rollback
	// of one) changed a fabric's operational identity and the facade
	// moved the CASE identity and the operational record and closed the
	// fabric's other sessions, and after an UpdateFabricLabel or a
	// SetVIDVerificationStatement changed a fabric under the same
	// identity (nothing for the facade to move). Mirrors matter.js
	// FabricManager `events.replaced` (FabricManager.ts:236-246, :377),
	// which a fabric's persist emits too, and CommissioningServer's
	// fabricsChanged(index, "updated") (CommissioningServer.ts:118-141).
	OnFabricUpdated func(FabricInfo) error
	// OnCommissioningComplete runs after a successful
	// CommissioningComplete and the facade's own handling of it (pending
	// OperationalCredentials state cleared, the OTA requestor's query
	// scheduled), with the fabric the commissioning completed for. It
	// fires on every CommissioningComplete, whereas matter.js's
	// `commissioned` event fires when the fabric count crosses zero
	// (CommissioningServer.ts:143-157 #syncCommissioned).
	OnCommissioningComplete func(fabricIndex uint8) error
	// OnWindowTransition runs on every commissioning-window transition
	// (open, close, an administrator's AdminFabricIndex cleared), after
	// the facade switched the PASE acceptor and published or withdrew
	// the commissionable record.
	OnWindowTransition func(WindowSnapshot) error
}

Observers are the host's callbacks on the node's fabric and commissioning events (issue #58). Each is optional, and each is chained after the facade's own handler for the same event: the facade's wiring runs first and unchanged, the observer runs once it has returned, and an observer's error (or panic) is logged, never returned to the handler — the event has already happened.

The name follows matter.js, whose node events are Observables that observers attach to (packages/protocol/src/fabric/FabricManager.ts: 41-48 `#events`); an observer of an error-guarded event is logged and the remaining observers still run (FabricManager.ts:381-386 `unhandled`, "Log unhandled errors but do not abort deletion").

Observers run synchronously on the goroutine of the event — for the fabric events, inside the command that caused it and before its response is sent — so an observer that blocks delays the response. A host that fans an event out over the network hands it to its own goroutine.

type OtaConfig

type OtaConfig struct {
	// Dir receives the downloads; mandatory.
	Dir string
	// Harness applies an image in place, reporting its version as running
	// without a restart. TESTING ONLY — see the daemon's otaApplier.
	Harness bool
	// Applier carries out an update; nil is the daemon's applier, which
	// validates the image and keeps it under Dir/applied.
	Applier OTAApplier
}

OtaConfig mounts the OTA Software Update Requestor (ADR 0019).

type ProductDescription

type ProductDescription struct {
	// Name is the advertised device name; empty is
	// BasicInformation.NodeLabel, as the daemon advertises (main.go:285 at b4ea1f96^).
	Name string
	// DeviceType is the advertised device type; 0 is RootNode (0x0016),
	// as the daemon advertises (main.go:290 at b4ea1f96^).
	DeviceType uint16
	// VendorID and ProductID are the node's identity; both mandatory.
	VendorID, ProductID uint16
}

ProductDescription is matter.js `productDescription` (ProductDescriptionServer.ts:70-90).

type ReverseCommissioner added in v0.10.0

type ReverseCommissioner = mattercore.ReverseCommissioner

ReverseCommissioner is the type of CommissionerControlConfig.Commissioner: the host's commissioner of the requesting node (mattercore.ReverseCommissioner).

type RootClusters

type RootClusters struct {
	BasicInformation           *mattercore.BasicInformation
	AccessControl              *mattercore.AccessControl
	GeneralCommissioning       *mattercore.GeneralCommissioning
	AdministratorCommissioning *wire.AdministratorCommissioning
	// NetworkCommissioning is the Ethernet server; nil when
	// [Network].WiFiCommissioning has a Driver.
	NetworkCommissioning *mattercore.NetworkCommissioning
	// WiFiNetworkCommissioning is the Wi-Fi server, nil unless
	// [Network].WiFiCommissioning has a Driver (TESTING ONLY).
	WiFiNetworkCommissioning *mattercore.WiFiNetworkCommissioning
	GeneralDiagnostics       *mattercore.GeneralDiagnostics
	DiagnosticLogs           *mattercore.DiagnosticLogs
	// TimeSynchronization is nil when [Config].DisableTimeSynchronization
	// is set.
	TimeSynchronization    *mattercore.TimeSynchronization
	OperationalCredentials *mattercore.OperationalCredentials
	GroupKeyManagement     *mattercore.GroupKeyManagement
	Groupcast              *mattercore.Groupcast
	Descriptor             *mattercore.Descriptor
	// OTARequestor is nil unless [Config].OTA is set.
	OTARequestor *mattercore.OTASoftwareUpdateRequestor

	// WiFiNetworkDiagnostics is nil unless [Network].WiFi has a Reporter.
	WiFiNetworkDiagnostics *mattercore.WiFiNetworkDiagnostics
	// PowerSourceConfiguration lists the node's PowerSource endpoints;
	// it starts empty, for the host to fill once the topology exists.
	PowerSourceConfiguration *mattercore.PowerSourceConfiguration
	// contains filtered or unexported fields
}

RootClusters is endpoint 0's server set: matter.js's root endpoint composition (ServerNode.ts:274-309) as the reference daemon builds it (examples/reference-bridge/wiring.go:93-299 at b4ea1f96^, buildRootClusters, and root_optional.go). The fields are the servers a host may need a hook on; RootClusters.Servers is the mounted set in mount order.

func (*RootClusters) Servers

func (r *RootClusters) Servers() []contract.ClusterServer

Servers returns the mounted set, in mount order.

type SessionManager added in v0.9.1

type SessionManager = operational.Manager

SessionManager is the secure-session table Node.Sessions returns (operational.Manager): Sessions lists the PASE and CASE sessions, Occupancy the session-id space.

type Snapshotter added in v0.9.1

type Snapshotter = bridge.Snapshotter

Snapshotter is the type of Config.Topology: a host that assembles its own endpoints returns one Topology per call (bridge.Snapshotter).

type Store

type Store struct {
	// Path is a SQLite file the node opens (creating it on first use)
	// with the pure-Go driver modernc.org/sqlite, foreign keys on and a
	// 5 s busy timeout; [Node.Stop] closes it. It excludes DB.
	Path        string
	DB          *sql.DB
	Credentials *store.Store
	Endpoints   endpoint.Store
}

Store names the node's persistence. With DB the node applies both schemas (store.Apply, sqlitestore.Apply) and opens the two stores on it, as the daemon's openDB does (persist.go:95-110); the caller picks the SQLite driver and owns the handle. With Path the node opens that SQLite file itself and treats it as DB. Credentials and Endpoints override the stores built from DB or Path, or stand in for them when both are unset.

type SubscriptionManager added in v0.9.1

type SubscriptionManager = subscription.Manager

SubscriptionManager is the subscription table Node.Subscriptions returns (subscription.Manager): Active counts the subscriptions, CountBySession groups them by session.

type TCPConfig added in v0.9.1

type TCPConfig = bridge.TCPConfig

TCPConfig is the type of Network.TCP: the Matter TCP roles (bridge.TCPConfig).

type Topology added in v0.9.1

type Topology = endpoint.Topology

Topology is the assembled endpoint tree a Snapshotter returns (endpoint.Topology).

type WiFi added in v0.4.0

type WiFi struct {
	// Reporter answers the cluster's reads and ResetCounts
	// (WiFiReporter); nil mounts no cluster.
	Reporter WiFiReporter
	// Features is the cluster's FeatureMap: wifidiagdef.FeaturePacketCounts
	// (PKTCNT) and wifidiagdef.FeatureErrorCounts (ERRCNT, which brings
	// ResetCounts).
	Features wifidiagdef.Feature
	// Attributes are the optional attributes served
	// (wifidiagdef.AttrCurrentMaxRate).
	Attributes []uint32
}

WiFi is a Wi-Fi node's WiFiNetworkDiagnostics configuration.

type WiFiCommissioning added in v0.7.0

type WiFiCommissioning struct {
	// Driver scans and connects; nil mounts the Ethernet-only server.
	Driver contract.WiFiDriver
	// MaxNetworks is the size of the network list; 0 is 1.
	MaxNetworks uint8
	// ScanMaxTimeSeconds and ConnectMaxTimeSeconds; 0 are 10 and 20.
	ScanMaxTimeSeconds, ConnectMaxTimeSeconds uint8
}

WiFiCommissioning is the Wi-Fi NetworkCommissioning configuration (mattercore.WiFiNetworkCommissioningConfig).

type WiFiReporter added in v0.10.0

type WiFiReporter = mattercore.WiFiReporter

WiFiReporter is the type of WiFi.Reporter: the live Wi-Fi diagnostics the host reports (mattercore.WiFiReporter).

type WindowCredentials added in v0.3.1

type WindowCredentials struct {
	// Discriminator is the 12-bit discriminator the window is advertised
	// under.
	Discriminator uint16
	// Passcode is the window's setup passcode; it must pass
	// setup.IsValidSetupPIN.
	Passcode uint32
	// Iterations is the SPAKE2+ PBKDF2 iteration count, within
	// [spake2.IterationsMin, spake2.IterationsMax].
	Iterations uint32
	// Salt is the SPAKE2+ salt, spake2.PBKDFMinSaltSize to
	// spake2.PBKDFMaxSaltSize bytes.
	Salt []byte
	// Timeout is how long the window stays open; 0 is the node's own
	// window default (bridge.OwnWindowTimeoutUncommissioned while the node
	// has no fabric, bridge.OwnWindowTimeoutCommissioned once it has one).
	Timeout time.Duration
}

WindowCredentials are the setup credentials of one Node.OpenBasicWindow window.

type WindowSnapshot added in v0.3.1

type WindowSnapshot struct {
	// Open reports whether a window is open, whoever opened it.
	Open bool
	// Own reports whether it is the node's own window — the one an
	// uncommissioned node opens, [Node.OpenBasicWindow]'s, or one the
	// host opened through CommissioningWindow().OpenOwnWindow — rather
	// than an administrator's.
	Own bool
	// Administrator is the AdministratorCommissioning view of the
	// window: WindowStatus, AdminFabricIndex, AdminVendorId. The node's
	// own window reads WindowNotOpen there, as matter.js keeps those
	// attributes for administrator windows only.
	Administrator WindowStatus
	// CommissioningMode is the CM value of the commissionable record the
	// node publishes after the transition: 0 none, 1 a basic window, 2
	// an enhanced window with an administrator's verifier.
	CommissioningMode uint8
	// Discriminator is the published record's discriminator; 0 when
	// CommissioningMode is 0.
	Discriminator uint16
}

WindowSnapshot is the commissioning window after a transition.

type WindowStatus added in v0.10.0

type WindowStatus = wire.WindowStatusSnapshot

WindowStatus is the AdministratorCommissioning view WindowSnapshot.Administrator carries (wire.WindowStatusSnapshot).

Jump to

Keyboard shortcuts

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