pub struct InteractionModel<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}>{ /* private fields */ }Expand description
The implementation needs a DataModel instance to interact with the underlying clusters of the data model.
NC is the network controller type driving the (optional) wireless connection
manager from InteractionModel::run. It defaults to NoopWirelessNetCtl, which is
the right choice for Ethernet (and what the convenience InteractionModel::new
constructor wires up); wireless devices pass a real controller via
InteractionModel::new_with_net_ctl.
Implementations§
Source§impl<'a, C, B, T, K, N, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NoopWirelessNetCtl, (), NS, NE>
impl<'a, C, B, T, K, N, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NoopWirelessNetCtl, (), NS, NE>
Sourcepub fn new(
matter: &'a Matter<'a>,
crypto: C,
buffers: &'a B,
handler: T,
kv: K,
state: &'a InteractionModelState<N, NS, NE>,
) -> InteractionModel<'a, C, B, T, K, N, NoopWirelessNetCtl, (), NS, NE>
pub fn new( matter: &'a Matter<'a>, crypto: C, buffers: &'a B, handler: T, kv: K, state: &'a InteractionModelState<N, NS, NE>, ) -> InteractionModel<'a, C, B, T, K, N, NoopWirelessNetCtl, (), NS, NE>
Create the data model for a device that does not need an operational wireless connection manager (typically an Ethernet device).
This is a convenience wrapper around InteractionModel::new_with_net_ctl that
fixes the network controller to an inert NoopWirelessNetCtl, so
InteractionModel::run’s connection-management branch stays dormant.
§Arguments
matter- a reference to theMatterinstancebuffers- a reference to an implementation ofBuffers<IMBuffer>which is used for allocating RX and TX buffers on the fly, when necessaryhandler- an instance of typeTwhich implements theDataModeltrait. This instance is used for interacting with the underlying clusters of the data model. Note that the expectations is for the user to provide a handler that handles the Matter system clusters as well (Endpoint 0), possibly by decorating her own clusters with thers_matter::dm::root_endpoint::with_methodskv- an instance of typeKwhich implements theKvBlobStoreAccesstrait (obtain one viaMatter::kv). This instance is used for interacting with the key-value blob store.state- a reference to theInteractionModelStateholding the subscriptions table, the events queue and the network store (the latter parameterized by theNetworksimplementationN).
Source§impl<'a, C, B, T, K, N, NC, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NC, (), NS, NE>
impl<'a, C, B, T, K, N, NC, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NC, (), NS, NE>
Sourcepub fn new_with_net_ctl(
matter: &'a Matter<'a>,
crypto: C,
buffers: &'a B,
handler: T,
kv: K,
net_ctl: NC,
state: &'a InteractionModelState<N, NS, NE>,
) -> InteractionModel<'a, C, B, T, K, N, NC, (), NS, NE>
pub fn new_with_net_ctl( matter: &'a Matter<'a>, crypto: C, buffers: &'a B, handler: T, kv: K, net_ctl: NC, state: &'a InteractionModelState<N, NS, NE>, ) -> InteractionModel<'a, C, B, T, K, N, NC, (), NS, NE>
Create the data model with an explicit network controller net_ctl.
Use this for wireless devices: net_ctl drives the operational connection
manager run from InteractionModel::run (and is typically the same controller
instance also wired into the NetworkCommissioning cluster handler). For
Ethernet devices prefer the InteractionModel::new convenience constructor.
§Arguments
matter- a reference to theMatterinstancebuffers- a reference to an implementation ofBuffers<IMBuffer>which is used for allocating RX and TX buffers on the fly, when necessaryhandler- an instance of typeTwhich implements theDataModeltrait. This instance is used for interacting with the underlying clusters of the data model. Note that the expectations is for the user to provide a handler that handles the Matter system clusters as well (Endpoint 0), possibly by decorating her own clusters with thers_matter::dm::root_endpoint::with_methodskv- an instance of typeKwhich implements theKvBlobStoreAccesstrait (obtain one viaMatter::kv). This instance is used for interacting with the key-value blob store.net_ctl- the network controller (NetCtl+WirelessDiag+NetChangeNotif) used by the operational wireless connection manager driven fromInteractionModel::run.state- a reference to theInteractionModelStateholding the subscriptions table, the events queue and the network store (the latter parameterized by theNetworksimplementationN).
Source§impl<'a, C, B, T, K, N, NC, R, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>where
C: Crypto,
B: Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>,
T: DataModel,
K: KvBlobStoreAccess,
N: Networks,
R: ReportDataHandler,
impl<'a, C, B, T, K, N, NC, R, const NS: usize, const NE: usize> InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>where
C: Crypto,
B: Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>,
T: DataModel,
K: KvBlobStoreAccess,
N: Networks,
R: ReportDataHandler,
Sourcepub fn new_with_reports(
matter: &'a Matter<'a>,
crypto: C,
buffers: &'a B,
handler: T,
kv: K,
net_ctl: NC,
report_handler: R,
state: &'a InteractionModelState<N, NS, NE>,
) -> InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
pub fn new_with_reports( matter: &'a Matter<'a>, crypto: C, buffers: &'a B, handler: T, kv: K, net_ctl: NC, report_handler: R, state: &'a InteractionModelState<N, NS, NE>, ) -> InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
Create the data model with an explicit network controller net_ctl and a
ReportDataHandler report_handler — the controller / subscriber role.
This is InteractionModel::new_with_net_ctl plus a report consumer:
after this node establishes subscriptions (via the IM client), the
publishers push ReportData on fresh inbound exchanges, which the
InteractionModel routes to report_handler. The default
(new/new_with_net_ctl) constructors leave the report handler as (),
which disowns every report — correct for a pure accessory.
§Arguments
Same as InteractionModel::new_with_net_ctl, plus:
report_handler- an instance of typeRimplementingReportDataHandler, invoked once per receivedReportDatachunk.
Sourcepub const fn matter(&self) -> &'a Matter<'a>
pub const fn matter(&self) -> &'a Matter<'a>
Get a reference to the Matter instance this data model is associated with.
pub const fn crypto(&self) -> &C
Sourcepub fn open_basic_comm_window(&self, timeout_secs: u16) -> Result<(), Error>
pub fn open_basic_comm_window(&self, timeout_secs: u16) -> Result<(), Error>
Open the basic commissioning window.
Equivalent to Matter::open_basic_comm_window but additionally
bumps the data version of the AdministratorCommissioning
cluster on the root endpoint and routes the change to
subscribers — both happen automatically because this InteractionModel
is itself the AttrChangeNotifier passed down.
Prefer this entry point over the Matter one for any code path
that has a InteractionModel available; Matter::open_basic_comm_window
is the building block we delegate to and does not bump dataver
(see its docs).
Sourcepub fn close_comm_window(&self) -> Result<bool, Error>
pub fn close_comm_window(&self) -> Result<bool, Error>
Close the active commissioning window.
Equivalent to Matter::close_comm_window but additionally
bumps the AdministratorCommissioning dataver and routes
subscribers via this InteractionModel’s AttrChangeNotifier. See
open_basic_comm_window for the rationale.
Sourcepub fn bump_configuration_version(&self) -> Result<u32, Error>
pub fn bump_configuration_version(&self) -> Result<u32, Error>
Bump BasicInformation::ConfigurationVersion by one, persist
the new value, and notify subscribers (which also bumps the
BasicInformation cluster’s dataver via this InteractionModel’s
AttrChangeNotifier).
Per Matter Core Spec, callers MUST invoke this
whenever the node’s exposed fixed-quality surface changes —
typically after a firmware update that adds or removes
functionality, after an internal reconfiguration that changes
any F-quality attribute (Descriptor::ServerList,
PartsList, …), or (for bridges) after a bridged node is added
or removed. It is not invoked automatically by rs-matter
because the library has no way to know about an application’s
reconfiguration events.
Returns the new ConfigurationVersion value.
Sourcepub async fn startup(&self) -> Result<(), Error>
pub async fn startup(&self) -> Result<(), Error>
Bring the Data Model to its operational state after a reboot.
Call once, after constructing the InteractionModel and before running
it or serving exchanges. In order:
- Re-hydrates the
InteractionModelState- the events-queue epoch (so event numbers are not reused across reboots) and the network store; - Replays any persisted subscriptions into the reporter’s table (if the
persistent-subscriptionsfeature is enabled), so a subscriber that had a subscription before this reboot keeps receiving reports instead of having to notice the loss and re-subscribe; - Broadcasts
LifecycleOp::Startupto every cluster handler in the data model, so handlers with a persistence story of their own (which the Interaction Model otherwise treats as opaque) can re-hydrate their state fromHandlerContext::kv.
The Matter-level counterpart is Matter::startup - call that one
first.
Sourcepub async fn factory_reset(&self) -> Result<(), Error>
pub async fn factory_reset(&self) -> Result<(), Error>
Factory-reset the Data Model persistable state.
The counterpart of InteractionModel::startup. In order:
- Resets the
InteractionModelStatepersisted contents to factory defaults - the events-queue epoch, the network store and (if compiled in) the persisted subscriptions - removing them from the KV store; - Broadcasts
LifecycleOp::FactoryResetto every cluster handler in the data model, so handlers can reset their own state and remove their persisted data fromHandlerContext::kv.
Call when the node is factory-reset, alongside the Matter-level
counterpart, Matter::factory_reset.
pub async fn run(&self) -> Result<(), Error>
Sourcepub async fn connect_once(&self, network_id: &[u8]) -> Result<(), Error>
pub async fn connect_once(&self, network_id: &[u8]) -> Result<(), Error>
Perform a single, one-shot connect to the wireless network with the given ID, immediately and regardless of the commissioning status.
This drives the same WirelessMgr used by InteractionModel::run
(over this model’s network controller and the network store owned by its
InteractionModelState), but calls WirelessMgr::connect_once rather
than the operational loop. It exists so a stack performing non-concurrent
(BLE-only) commissioning can replay the deferred ConnectNetwork once the
operational radio is up but before commissioning completes - without having
to own a WirelessMgr (or the networks) itself.
Source§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
Sourcepub fn load_stats(&self, fab_idx: Option<NonZero<u8>>) -> DeviceLoad
pub fn load_stats(&self, fab_idx: Option<NonZero<u8>>) -> DeviceLoad
The node’s resource-utilisation metrics, for the GeneralDiagnostics
cluster’s DeviceLoadStatus attribute.
fab_idx is the fabric of the reading subject, for
CurrentSubscriptionsForFabric; pass None when no fabric is in scope.
Handlers reach this through ImStats::device_load rather than calling
it directly, but it is public so a controller can query its own load.
Deliberately free of the R: ReportDataHandler bound the other
InteractionModel methods carry: the figures come from the transport and
the subscriptions table, so both the accessory and controller roles can
report them.
Trait Implementations§
Source§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> AttrChangeNotifier for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> AttrChangeNotifier for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
Source§fn notify_attr_changed(&self, endpoint_id: u16, cluster_id: u32, attr_id: u32)
fn notify_attr_changed(&self, endpoint_id: u16, cluster_id: u32, attr_id: u32)
Source§fn notify_cluster_changed(&self, endpoint_id: u16, cluster_id: u32)
fn notify_cluster_changed(&self, endpoint_id: u16, cluster_id: u32)
Source§fn notify_endpoint_changed(&self, endpoint_id: u16)
fn notify_endpoint_changed(&self, endpoint_id: u16)
Source§fn notify_all_changed(&self)
fn notify_all_changed(&self)
Source§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> EventEmitter for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> EventEmitter for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
Source§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> ExchangeHandler for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>where
C: Crypto,
B: Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>,
T: DataModel,
K: KvBlobStoreAccess,
N: Networks,
R: ReportDataHandler,
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> ExchangeHandler for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>where
C: Crypto,
B: Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>,
T: DataModel,
K: KvBlobStoreAccess,
N: Networks,
R: ReportDataHandler,
Source§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> HandlerContext for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> HandlerContext for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
Source§fn crypto(&self) -> impl Crypto
fn crypto(&self) -> impl Crypto
Source§fn kv(&self) -> impl KvBlobStoreAccess
fn kv(&self) -> impl KvBlobStoreAccess
Source§fn networks(&self) -> impl NetworksAccess
fn networks(&self) -> impl NetworksAccess
Source§fn metadata(&self) -> impl Metadata
fn metadata(&self) -> impl Metadata
Source§fn handler(&self) -> impl AsyncHandler
fn handler(&self) -> impl AsyncHandler
Source§fn buffers(
&self,
) -> impl Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>
fn buffers( &self, ) -> impl Buffers<Vec<u8, rs_matter::::transport::exchange::Buffer::{constant#0}>>
Source§fn im_stats(&self) -> impl ImStats
fn im_stats(&self) -> impl ImStats
Source§fn notify_fabric_removed(&self, fab_idx: NonZero<u8>)
fn notify_fabric_removed(&self, fab_idx: NonZero<u8>)
LifecycleOp::FabricRemoval to every handler in the data model. Read moreSource§impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> ImStats for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
impl<C, B, T, K, N, NC, R, const NS: usize, const NE: usize> ImStats for InteractionModel<'_, C, B, T, K, N, NC, R, NS, NE>
Source§fn device_load(&self, fab_idx: Option<NonZero<u8>>) -> DeviceLoad
fn device_load(&self, fab_idx: Option<NonZero<u8>>) -> DeviceLoad
GeneralDiagnostics::DeviceLoadStatus. Read moreAuto Trait Implementations§
impl<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}> !Freeze for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}> !RefUnwindSafe for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}> !Send for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}> !Sync for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC = NoopWirelessNetCtl, R = (), const NS: usize = rs_matter::::im::InteractionModel::{constant#0}, const NE: usize = rs_matter::::im::InteractionModel::{constant#1}> !UnwindSafe for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC, R, const NS: usize, const NE: usize> Unpin for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>
impl<'a, C, B, T, K, N, NC, R, const NS: usize, const NE: usize> UnsafeUnpin for InteractionModel<'a, C, B, T, K, N, NC, R, NS, NE>where
C: UnsafeUnpin,
K: UnsafeUnpin,
NC: UnsafeUnpin,
T: UnsafeUnpin,
R: UnsafeUnpin,
<B as Buffers<Vec<u8, 1583>>>::Buffer<'a>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more