Skip to main content

matter_controller/
builder.rs

1//! Builder for [`MatterController`]. Configures attestation trust and the
2//! admin vendor id before spawning the owning actor.
3
4use std::sync::Arc;
5
6use crate::controller::MatterController;
7use crate::error::Error;
8use crate::store::ControllerStore;
9use crate::trust::AttestationTrust;
10
11/// Default admin vendor id used in `AddNOC` (CSA test VID). Override via
12/// [`MatterControllerBuilder::admin_vendor_id`].
13pub const DEFAULT_ADMIN_VENDOR_ID: u16 = 0xFFF1;
14
15/// Configures and opens a [`MatterController`].
16pub struct MatterControllerBuilder {
17    store: Arc<dyn ControllerStore>,
18    trust: Option<AttestationTrust>,
19    admin_vendor_id: u16,
20    multicast_if: Option<u32>,
21}
22
23impl MatterControllerBuilder {
24    pub(crate) fn new(store: Arc<dyn ControllerStore>) -> Self {
25        Self {
26            store,
27            trust: None,
28            admin_vendor_id: DEFAULT_ADMIN_VENDOR_ID,
29            multicast_if: None,
30        }
31    }
32
33    /// Set the device-attestation trust material. Required to `commission`.
34    #[must_use]
35    pub fn attestation_trust(mut self, trust: AttestationTrust) -> Self {
36        self.trust = Some(trust);
37        self
38    }
39
40    /// Override the admin vendor id used in `AddNOC` (default `0xFFF1`).
41    #[must_use]
42    pub fn admin_vendor_id(mut self, vid: u16) -> Self {
43        self.admin_vendor_id = vid;
44        self
45    }
46
47    /// Set the IPv6 multicast egress interface (an `if_nametoindex` value)
48    /// used for group commands (`invoke_group`). On a multi-homed host the
49    /// kernel default has no route for the admin-local `ff35:` group address
50    /// and group sends fail with "No route to host" — pick the LAN-facing
51    /// interface. When unset, the `MATTER_MULTICAST_IF` env var is honored as
52    /// a compat fallback, then the kernel default.
53    #[must_use]
54    pub fn multicast_interface(mut self, if_index: u32) -> Self {
55        self.multicast_if = Some(if_index);
56        self
57    }
58
59    /// Bind the socket + discovery, load persisted state, and spawn the actor.
60    ///
61    /// # Errors
62    ///
63    /// [`Error::Store`] / [`Error::Snapshot`] on load failure, or
64    /// [`Error::Operational`] if the socket / mDNS cannot start.
65    pub async fn build(self) -> Result<MatterController, Error> {
66        MatterController::spawn_default(
67            self.store,
68            self.trust,
69            self.admin_vendor_id,
70            self.multicast_if,
71        )
72        .await
73    }
74}