pub struct MatterController { /* private fields */ }Expand description
The high-level Matter controller. Cloneable; all clones talk to one owning task.
Implementations§
Source§impl MatterController
impl MatterController
Sourcepub fn builder(store: Arc<dyn ControllerStore>) -> MatterControllerBuilder
pub fn builder(store: Arc<dyn ControllerStore>) -> MatterControllerBuilder
Begin configuring a controller (attestation trust, admin vendor id).
Sourcepub async fn open(store: Arc<dyn ControllerStore>) -> Result<Self, Error>
pub async fn open(store: Arc<dyn ControllerStore>) -> Result<Self, Error>
Open a controller with default settings and no attestation trust —
sufficient for operating already-commissioned devices, but commission
will return Error::NoTrust. Use Self::builder to commission.
§Errors
Sourcepub async fn serve_provider_once<H>(
&self,
port: u16,
handler: H,
max_invokes: usize,
) -> Result<usize, Error>
pub async fn serve_provider_once<H>( &self, port: u16, handler: H, max_invokes: usize, ) -> Result<usize, Error>
Serve the OTA provider role once: advertise our operational service,
accept one inbound CASE session, and dispatch up to max_invokes
server-side InvokeRequests through handler, then withdraw the
advertisement. handler maps a parsed request to the encoded
InvokeResponse bytes (e.g. via matter_interaction::build_invoke_response_*).
The server runs on its own freshly-bound UDP socket and its own mDNS daemon — it does not touch the client actor (the long-running accept is kept off the proven request/MRP loop). It authenticates as our persisted operational identity (the M8 commissioner NOC/IPK/root).
F3 ships the generic plumbing; F4 supplies the OTA QueryImage handler
and the BDX transfer. Note: advertising a wildcard-bound address may not
be routable to a foreign requestor — see the F3 runbook for the
interface-selection caveat (the automated validation is the in-process
loopback test).
§Errors
Error::NotCommissioned if no fabric exists; Error::Operational on
bind / mDNS / clock failure; otherwise any CASE-accept or dispatch error
from crate::provider_server::ProviderServer.
Sourcepub async fn serve_ota(
&self,
target_node_id: u64,
image: Vec<u8>,
software_version: u32,
port: u16,
) -> Result<(), Error>
pub async fn serve_ota( &self, target_node_id: u64, image: Vec<u8>, software_version: u32, port: u16, ) -> Result<(), Error>
Announce ourselves as an OTA provider to target_node_id, advertise our
operational service, and serve image over the full OTA flow (the
requestor resolves us, opens CASE, queries, BDX-downloads, applies, and
— possibly after rebooting into the new image — sends
NotifyUpdateApplied). Returns once NotifyUpdateApplied is received.
software_version is offered in QueryImageResponse (must exceed the
requestor’s current version for it to update — and match the version
baked into the .ota header for a live requestor). port binds the
provider socket (0 = ephemeral). The image is served verbatim over BDX
(unsigned; the requestor parses the OTAImageHeader).
Because a real requestor reboots into the new image before notifying,
the call may block for an extended period. Callers should bound the wait
with tokio::time::timeout. Each accepted CASE session’s resumption
record is persisted immediately via an internal sink (best-effort: a
failed store only costs a future fast path).
§Errors
Error::NotCommissioned if no fabric exists; Error::Operational on
bind / mDNS / clock failure; otherwise any announce or serve error.
Sourcepub async fn serve_ota_with_block_size(
&self,
target_node_id: u64,
image: Vec<u8>,
software_version: u32,
port: u16,
max_block_size: u16,
) -> Result<(), Error>
pub async fn serve_ota_with_block_size( &self, target_node_id: u64, image: Vec<u8>, software_version: u32, port: u16, max_block_size: u16, ) -> Result<(), Error>
Self::serve_ota with an explicit BDX max_block_size. Pass a smaller
value (~512) for a Thread-routed requestor so each block fits fewer
6LoWPAN fragments; 960 is the Wi-Fi/IP default (see Self::serve_ota).
§Errors
Same as Self::serve_ota.
Sourcepub async fn listen_for_checkin_once(&self, port: u16) -> Result<CheckIn, Error>
pub async fn listen_for_checkin_once(&self, port: u16) -> Result<CheckIn, Error>
Advertise our operational service and listen for ONE inbound Check-In
from a registered ICD, verify it against the stored registration key
(enforcing counter monotonicity), and return it — the caller then
re-establishes a session and reads/subscribes / stay_active_requests
while the device is briefly active.
Runs on its own freshly-bound UDP socket + mDNS daemon (the F3
pattern), off the client actor. Requires at least one registration from
Node::register_icd_client.
§Errors
Error::NotCommissioned if no fabric exists; Error::Operational if
no ICD clients are registered, on bind / mDNS failure, or if no
verifiable Check-In arrives before the internal frame budget is reached.
Sourcepub async fn create_fabric(&self, cfg: FabricConfig) -> Result<u64, Error>
pub async fn create_fabric(&self, cfg: FabricConfig) -> Result<u64, Error>
Create and persist a new fabric (mints the stable commissioner identity). Returns the new fabric id.
§Errors
Error::ControllerStopped if the task has stopped; otherwise any
minting / persistence error.
Sourcepub async fn commission(
&self,
setup_code: &str,
label: Option<String>,
) -> Result<NodeInfo, Error>
pub async fn commission( &self, setup_code: &str, label: Option<String>, ) -> Result<NodeInfo, Error>
Commission a device from a QR (MT:...) or manual pairing code, bring it
onto the controller’s fabric, and persist it. Returns a NodeInfo for
the commissioned device.
After the device is on the fabric, a best-effort BasicInformation read
captures its VendorID/ProductID into the returned NodeInfo and
persists them on the device entry. That read is best-effort: if it fails,
commissioning still succeeds and NodeInfo::vendor_id/product_id are
left None (re-readable later via Self::nodes).
label is an opaque, caller-supplied string (e.g. a friendly name like
"kitchen plug") persisted on the device’s entry atomically with the
rest of the commissioning result — a crash after this call returns
either sees the fully-commissioned device with its label, or nothing
at all, never a device missing its label. Pass None if you have no
label to attach yet; it can be left unset.
§Errors
Error::NoTrust if no attestation trust was configured,
Error::SetupCode if the code is invalid, Error::ControllerStopped
if the task stopped, or any driver/commissioning error.
Sourcepub async fn nodes(&self) -> Result<Vec<NodeInfo>, Error>
pub async fn nodes(&self) -> Result<Vec<NodeInfo>, Error>
Enumerate every node this controller has commissioned, across all
fabrics, as typed NodeInfo. Replaces the need to deserialize the
on-disk snapshot to discover node ids and metadata.
§Errors
Error::ControllerStopped if the owning task has stopped.
Sourcepub async fn forget_node(&self, node_id: u64) -> Result<bool, Error>
pub async fn forget_node(&self, node_id: u64) -> Result<bool, Error>
Forget a node: drop ALL of the controller’s own state for it — the
persisted device record, any cached CASE session, and its resumption
data — WITHOUT contacting the device. Use this to reclaim a node that is
unreachable or already factory-reset (where remove_fabric cannot run).
Returns true if a node was found and removed, false if no such node
was commissioned. This does NOT remove the controller’s fabric from the
device; a still-live device keeps its NOC until it is reset or its fabric
removed via Node::remove_fabric.
§Errors
Error::ControllerStopped if the task stopped, or a store error while
persisting the removal.
Sourcepub fn node(&self, node_id: u64) -> Node
pub fn node(&self, node_id: u64) -> Node
Handle addressing a device by node id (single-fabric in M8.2).
Sourcepub async fn create_group(
&self,
key_set_id: u16,
epoch_start_time: u64,
) -> Result<GroupKeySet, Error>
pub async fn create_group( &self, key_set_id: u16, epoch_start_time: u64, ) -> Result<GroupKeySet, Error>
Create a group key set on the controller’s fabric: mints a fresh 16-byte
epoch key from the CSPRNG, persists a GroupKeySetConfig under
key_set_id, and returns the GroupKeySet so the caller can program
it onto each member device via
Node::write_group_key_set and map a
group to it. The key set is stored durably before this returns, so the
controller can encrypt outbound group messages for it immediately
(see Self::invoke_group).
epoch_start_time is the Matter-epoch start time recorded in the
returned GroupKeySet (the device-side KeySetWrite echoes it).
§Errors
Error::NotCommissioned if no single fabric exists,
Error::ControllerStopped if the task has stopped, or any
CSPRNG / persistence error.
Sourcepub async fn invoke_group(
&self,
group_id: u16,
key_set_id: u16,
path: CommandPath,
fields: Value,
) -> Result<(), Error>
pub async fn invoke_group( &self, group_id: u16, key_set_id: u16, path: CommandPath, fields: Value, ) -> Result<(), Error>
Fire-and-forget multicast group invoke: send path/fields to every
device in group_id, encrypted with the operational group key derived
from the persisted key_set_id. Returns as soon as the datagram is sent
— group commands are unacknowledged, so there is no response.
The caller supplies key_set_id (the key set the group was bound to when
it was created): the controller’s persisted group_keys are keyed by
key set id, avoiding a separate group→key-set map. The outbound group
message counter is bumped and persisted before the send so a counter
is never reused across a crash.
Real multicast delivery requires the host network to route the Matter site-local group address; on a host without it the send still succeeds at the socket layer (the bytes are correct — see the loopback test).
§Errors
Error::GroupNotProvisioned if key_set_id has no persisted key set,
Error::NotCommissioned if no single fabric exists,
Error::Operational on counter exhaustion or send failure,
Error::ControllerStopped if the task has stopped, or any
crypto / persistence error.
Trait Implementations§
Source§impl Clone for MatterController
impl Clone for MatterController
Source§fn clone(&self) -> MatterController
fn clone(&self) -> MatterController
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more