pub struct MatterControllerBuilder { /* private fields */ }Expand description
Configures and opens a MatterController.
Implementations§
Source§impl MatterControllerBuilder
impl MatterControllerBuilder
Sourcepub fn attestation_trust(self, trust: AttestationTrust) -> Self
pub fn attestation_trust(self, trust: AttestationTrust) -> Self
Set the device-attestation trust material. Required to commission.
Sourcepub fn admin_vendor_id(self, vid: u16) -> Self
pub fn admin_vendor_id(self, vid: u16) -> Self
Override the admin vendor id used in AddNOC (default 0xFFF1).
Sourcepub fn multicast_interface(self, if_index: u32) -> Self
pub fn multicast_interface(self, if_index: u32) -> Self
Set the IPv6 multicast egress interface (an if_nametoindex value)
used for group commands (invoke_group). On a multi-homed host the
kernel default has no route for the admin-local ff35: group address
and group sends fail with “No route to host” — pick the LAN-facing
interface. When unset, the MATTER_MULTICAST_IF env var is honored as
a compat fallback, then the kernel default.
Sourcepub fn response_deadline(self, deadline: Duration) -> Self
pub fn response_deadline(self, deadline: Duration) -> Self
Bound how long an operational read/write/invoke waits for its Interaction Model response (default 30 s).
Matter’s MRP bounds delivery, not response: once a device
acknowledges a request, the retransmit timer for that exchange is
discarded. A device that accepts a request and then never answers it
therefore has nothing left to expire, and without this deadline the
call waits forever. Real devices do this — a Tapo H100 bridge silently
drops the 9th consecutive read on a session — so every operational verb
is bounded by this value and fails with
Error::ResponseTimeout when it elapses.
The request is not retried first. Delivery was confirmed, so the device may already have executed a non-idempotent command; deciding whether a retry is safe belongs to you, not the library. This is deliberately unlike a lost-packet timeout, which the controller does retry once on a fresh session.
Lower it if you front the controller with your own per-operation timeout and would rather see the library’s error than your own; raise it for devices that are legitimately slow to answer.
Sourcepub fn discovery<D>(self, discovery: D) -> Self
pub fn discovery<D>(self, discovery: D) -> Self
Supply your own mDNS stack instead of the built-in one.
§What the default is
Leave this unset and the controller starts
MdnsSdDiscovery — a pure-Rust
responder built on the mdns-sd crate, with no system daemon required.
That remains the default and is not going away; this method exists so
the mDNS stack is your choice rather than something the library
imposes on you.
§Why you might replace it
- You already run a system responder. On a typical Linux host
avahi-daemon(orsystemd-resolved) already owns UDP 5353. A second in-process responder is a second cache, a second set of probes, and a second opinion about what is on the network. Delegating to the daemon you already run removes that whole class of disagreement. - You want the OS-native stack. Bonjour on macOS, or a platform/embedded resolver that is better placed than we are to know about interface changes, sleep/wake, and roaming.
- You are testing. A deterministic test double lets you drive resolution outcomes — a node that never appears, one that appears late, one that resolves to a fixed loopback address — without any real network.
§What your implementation is responsible for
Implement matter_transport::Discovery; its own documentation is the
contract. In short: publish/unpublish advertise and withdraw our
services, and query → poll_results → stop_query is a browse whose
records you buffer per handle and hand over on each drain. Read the notes
on query and
stop_query about handle
lifetime before you start — a handle that is never stopped keeps costing
resources.
The trait may also grow methods that carry a default implementation, so that adding one does not break existing implementors. Your type keeps compiling when that happens, but it silently takes the generic default until you override it — and a default is by definition the unrefined path (for instance, a fallback that browses every operational record rather than a narrowed subset). When you upgrade, check the trait for defaulted methods worth overriding.
§Scope: this covers the controller’s own resolution, not the servers
The discovery you pass here is owned by the controller’s actor task and is what every client operation resolves through — connecting to a node, commissioning, resubscribing.
It is not used by the self-hosted server entry points
(listen_for_checkin_once,
the ota feature’s serve_ota, and the unstable-provider feature’s
serve_provider_once). Each of those runs
off the actor on its own socket and needs a Discovery it exclusively
owns for the duration of the call, which a single value moved into the
actor cannot provide; they each construct their own MdnsSdDiscovery
and use it only to publish and withdraw one operational record. So if
you supply an Avahi-backed implementation and then serve OTA, your
backend does the resolving while that record is still advertised through
mdns-sd. If that matters to you, say so on issue #113 — closing the
gap means taking a discovery factory here rather than a value, and
that is worth doing on demand rather than on speculation.
§Example
let controller = MatterController::builder(store)
.discovery(my_discovery)
.build()
.await?;Sourcepub async fn build(self) -> Result<MatterController, Error>
pub async fn build(self) -> Result<MatterController, Error>
Bind the socket + discovery, load persisted state, and spawn the actor.
Uses the discovery supplied to Self::discovery, or starts the default
MdnsSdDiscovery if none was.
§Errors
Error::Store / Error::Snapshot on load failure, or
Error::Operational if the socket / mDNS cannot start.