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), 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
- Variables
- type Aggregator
- func (a *Aggregator) Add(ctx context.Context, ep Endpoint) error
- func (a *Aggregator) Endpoints() []Endpoint
- func (a *Aggregator) IncreaseConfigurationVersion(key endpoint.SourceKey) error
- func (a *Aggregator) MarkComplete()
- func (a *Aggregator) Remove(ctx context.Context, key endpoint.SourceKey) error
- type Attestation
- type BasicInformation
- type Client
- type CommissionerControlConfig
- type Commissioning
- type Config
- type Endpoint
- type EndpointPersistence
- type FabricInfo
- type Network
- type Node
- func (n *Node) Aggregator() *Aggregator
- func (n *Node) Bindings() *binding.Manager
- func (n *Node) BootReason() uint8
- func (n *Node) Bridge() *bridge.Bridge
- func (n *Node) CommissionerControl() *mattercore.CommissionerControl
- func (n *Node) CommissioningWindow() *bridge.CommissioningWindow
- func (n *Node) Fabrics(ctx context.Context) ([]store.FabricRecord, error)
- func (n *Node) Groups() *groups.Manager
- func (n *Node) OTAProvider() *mattercore.OTAProvider
- func (n *Node) OpenBasicWindow(ctx context.Context, creds WindowCredentials) error
- func (n *Node) PairingCodes() (qr, manual string, err error)
- func (n *Node) Peers() *peer.Set
- func (n *Node) Persistence() EndpointPersistence
- func (n *Node) RemoveFabric(ctx context.Context, fabricIndex uint8) error
- func (n *Node) Root() *RootClusters
- func (n *Node) Run(ctx context.Context) error
- func (n *Node) Sessions() *operational.Manager
- func (n *Node) SetCommissioningBlocked(ctx context.Context, err error)
- func (n *Node) Start(ctx context.Context) error
- func (n *Node) Stop(ctx context.Context) error
- func (n *Node) Store() *store.Store
- func (n *Node) Subscriptions() *subscription.Manager
- func (n *Node) TriggerReannounce(ctx context.Context)
- type OTAProviderConfig
- type Observers
- type OtaConfig
- type ProductDescription
- type RootClusters
- type Store
- type WiFi
- type WiFiCommissioning
- type WindowCredentials
- type WindowSnapshot
Constants ¶
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.
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 ¶
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") )
Aggregator errors.
var ErrInvalidConfig = errors.New("node: invalid configuration")
ErrInvalidConfig wraps every Config.Validate failure.
var ErrInvalidWindowCredentials = errors.New("node: invalid window credentials")
ErrInvalidWindowCredentials wraps every Node.OpenBasicWindow credential failure.
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 ¶
This section is empty.
Types ¶
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.
func (*Aggregator) Add ¶
func (a *Aggregator) Add(ctx context.Context, ep Endpoint) error
Add adds ep under the Aggregator; a running node reassembles.
func (*Aggregator) Endpoints ¶
func (a *Aggregator) Endpoints() []Endpoint
Endpoints returns the set, in insertion order.
func (*Aggregator) IncreaseConfigurationVersion ¶
func (a *Aggregator) IncreaseConfigurationVersion(key endpoint.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).
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 ¶
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.
type Attestation ¶
type Attestation struct {
// Chain is the DAC, its key and the PAI; nil is the CSA test chain.
Chain *attestation.Chain
// 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 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 (a
// stored value flagged by the deprecated store.SettingUniqueIDRotated
// is re-derived and pinned once instead).
// 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, buildRootClusters), plus ProductLabel from matter.js's example (BridgedDevicesNode.ts:29-65).
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
}
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 mattercore.CommissioningApprover
// Commissioner commissions an approved client's node. Required.
Commissioner mattercore.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).
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 mdns.NewNoop(),
// as bridge.New treats a nil advertiser. [Node.Stop] closes it.
Advertiser mdns.Advertiser
// DeviceTypeValidation is the bridge's device-type judgement mode
// (bridge.SetDeviceTypeValidation); the zero value is matter.js's
// warn mode.
DeviceTypeValidation endpoint.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.
Groups *groups.Manager
// 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, 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 bridge.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).
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
// 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
// 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).
func (*Config) Validate ¶
Validate holds the checks the daemon applies to its flags (main.go:113-131): 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.
type Endpoint ¶
Endpoint is what the Aggregator holds: anything that describes itself as an endpoint.Spec. Brief P's device.Device satisfies it; until that lands, any type with a Spec method does (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 endpoint.SourceKey, label string)
// NodeLabel is the label persisted for key, "" for none.
NodeLabel(ctx context.Context, key endpoint.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
}
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.
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 bridge.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
}
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 ¶
New builds the node: everything the reference daemon builds before bridge.Start (examples/reference-bridge/main.go:135-397), 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 publishes nothing (mdns.NewNoop), 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) Bindings ¶ added in v0.4.0
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 ¶
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 ¶
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() *bridge.CommissioningWindow
CommissioningWindow returns the commissioning window.
func (*Node) Groups ¶ added in v0.4.0
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) 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 ¶
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).
func (*Node) Peers ¶ added in v0.4.0
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
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) Run ¶
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() *operational.Manager
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
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 ¶
Start brings the node online: the bridge starts, and the daemon's post-start sequence runs (main.go:428-489) — 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 ¶
Stop takes the node offline and releases what New and Start began, in the daemon's shutdown order (main.go:430-450): the OTA requestor, the operational time stored once more, BasicInformation ShutDown (when the node was started), the PASE providers, the CASE reaper, the subscription engine, the re-announce loop, the bridge and the advertiser. Stop is idempotent (matter.js Node.stop, Node.ts:193) and safe without Start.
func (*Node) Subscriptions ¶ added in v0.4.0
func (n *Node) Subscriptions() *subscription.Manager
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) TriggerReannounce ¶ added in v0.5.0
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).
type OTAProviderConfig ¶ added in v0.4.0
type OTAProviderConfig struct {
// ImageSource names and serves the images; nil mounts no provider.
ImageSource mattercore.OTAImageSource
// Consent asks the user; nil declines an image that needs a consent
// the requestor cannot give.
Consent mattercore.OTAConsent
// ApplyPolicy decides an allowed apply; nil proceeds at once.
ApplyPolicy mattercore.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 mattercore.OTAPeer, status mattercore.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 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. Mirrors matter.js FabricManager
// `events.replaced` (FabricManager.ts:236, :377).
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 mattercore.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).
Name string
// DeviceType is the advertised device type; 0 is RootNode (0x0016),
// as the daemon advertises (main.go:290).
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 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, 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 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:45-60); the caller picks the SQLite driver and owns the handle. Credentials and Endpoints override the stores built from DB, or stand in for it when DB is nil.
type WiFi ¶ added in v0.4.0
type WiFi struct {
// Reporter answers the cluster's reads and ResetCounts
// (mattercore.WiFiReporter); nil mounts no cluster.
Reporter mattercore.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 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 wire.WindowStatusSnapshot
// 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.