Skip to content

Commit 7f9ccbc

Browse files
committed
Sequential Exchange API
1 parent 44e01a5 commit 7f9ccbc

36 files changed

+3200
-2989
lines changed

examples/onoff_light/src/main.rs

Lines changed: 84 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,23 @@ use log::info;
2323
use matter::core::{CommissioningData, Matter};
2424
use matter::data_model::cluster_basic_information::BasicInfoConfig;
2525
use matter::data_model::cluster_on_off;
26-
use matter::data_model::core::DataModel;
2726
use matter::data_model::device_types::DEV_TYPE_ON_OFF_LIGHT;
2827
use matter::data_model::objects::*;
2928
use matter::data_model::root_endpoint;
3029
use matter::data_model::system_model::descriptor;
3130
use matter::error::Error;
32-
use matter::interaction_model::core::InteractionModel;
3331
use matter::mdns::{DefaultMdns, DefaultMdnsRunner};
3432
use matter::secure_channel::spake2p::VerifierData;
35-
use matter::transport::network::{Address, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
36-
use matter::transport::{
37-
core::RecvAction, core::Transport, packet::MAX_RX_BUF_SIZE, packet::MAX_TX_BUF_SIZE,
38-
udp::UdpListener,
39-
};
33+
use matter::transport::network::{Ipv4Addr, Ipv6Addr};
34+
use matter::transport::runner::{RxBuf, TransportRunner, TxBuf};
4035
use matter::utils::select::EitherUnwrap;
4136

4237
mod dev_att;
4338

4439
#[cfg(feature = "std")]
4540
fn main() -> Result<(), Error> {
4641
let thread = std::thread::Builder::new()
47-
.stack_size(120 * 1024)
42+
.stack_size(140 * 1024)
4843
.spawn(run)
4944
.unwrap();
5045

@@ -62,10 +57,10 @@ fn run() -> Result<(), Error> {
6257
initialize_logger();
6358

6459
info!(
65-
"Matter memory: mDNS={}, Matter={}, Transport={}",
60+
"Matter memory: mDNS={}, Matter={}, TransportRunner={}",
6661
core::mem::size_of::<DefaultMdns>(),
6762
core::mem::size_of::<Matter>(),
68-
core::mem::size_of::<Transport>(),
63+
core::mem::size_of::<TransportRunner>(),
6964
);
7065

7166
let dev_det = BasicInfoConfig {
@@ -92,6 +87,8 @@ fn run() -> Result<(), Error> {
9287

9388
let mut mdns_runner = DefaultMdnsRunner::new(&mdns);
9489

90+
info!("mDNS initialized: {:p}, {:p}", &mdns, &mdns_runner);
91+
9592
let dev_att = dev_att::HardCodedDevAtt::new();
9693

9794
#[cfg(feature = "std")]
@@ -118,36 +115,25 @@ fn run() -> Result<(), Error> {
118115
matter::MATTER_PORT,
119116
);
120117

121-
let psm_path = std::env::temp_dir().join("matter-iot");
122-
info!("Persisting from/to {}", psm_path.display());
123-
124-
#[cfg(all(feature = "std", not(target_os = "espidf")))]
125-
let psm = matter::persist::FilePsm::new(psm_path)?;
118+
info!("Matter initialized: {:p}", &matter);
126119

127-
let mut buf = [0; 4096];
128-
let buf = &mut buf;
120+
let mut runner = TransportRunner::new(&matter);
129121

130-
#[cfg(all(feature = "std", not(target_os = "espidf")))]
131-
{
132-
if let Some(data) = psm.load("acls", buf)? {
133-
matter.load_acls(data)?;
134-
}
122+
info!("Transport Runner initialized: {:p}", &runner);
135123

136-
if let Some(data) = psm.load("fabrics", buf)? {
137-
matter.load_fabrics(data)?;
138-
}
139-
}
124+
let mut tx_buf = TxBuf::uninit();
125+
let mut rx_buf = RxBuf::uninit();
140126

141-
let mut transport = Transport::new(&matter);
127+
// #[cfg(all(feature = "std", not(target_os = "espidf")))]
128+
// {
129+
// if let Some(data) = psm.load("acls", buf)? {
130+
// matter.load_acls(data)?;
131+
// }
142132

143-
transport.start(
144-
CommissioningData {
145-
// TODO: Hard-coded for now
146-
verifier: VerifierData::new_with_pw(123456, *matter.borrow()),
147-
discriminator: 250,
148-
},
149-
buf,
150-
)?;
133+
// if let Some(data) = psm.load("fabrics", buf)? {
134+
// matter.load_fabrics(data)?;
135+
// }
136+
// }
151137

152138
let node = Node {
153139
id: 0,
@@ -161,69 +147,48 @@ fn run() -> Result<(), Error> {
161147
],
162148
};
163149

164-
let mut handler = handler(&matter);
150+
let handler = HandlerCompat(handler(&matter));
165151

166-
let mut im = InteractionModel(DataModel::new(matter.borrow(), &node, &mut handler));
167-
168-
let mut rx_buf = [0; MAX_RX_BUF_SIZE];
169-
let mut tx_buf = [0; MAX_TX_BUF_SIZE];
170-
171-
let im = &mut im;
172-
let mdns_runner = &mut mdns_runner;
173-
let transport = &mut transport;
174-
let rx_buf = &mut rx_buf;
152+
let matter = &matter;
153+
let node = &node;
154+
let handler = &handler;
155+
let runner = &mut runner;
175156
let tx_buf = &mut tx_buf;
157+
let rx_buf = &mut rx_buf;
176158

177-
let mut io_fut = pin!(async move {
178-
// NOTE (no_std): On no_std, the `UdpListener` implementation is a no-op so you might want to
179-
// replace it with your own UDP stack
180-
let udp = UdpListener::new(SocketAddr::new(
181-
IpAddr::V6(Ipv6Addr::UNSPECIFIED),
182-
matter::MATTER_PORT,
183-
))
184-
.await?;
185-
186-
loop {
187-
let (len, addr) = udp.recv(rx_buf).await?;
188-
189-
let mut completion = transport.recv(Address::Udp(addr), &mut rx_buf[..len], tx_buf);
190-
191-
while let Some(action) = completion.next_action()? {
192-
match action {
193-
RecvAction::Send(addr, buf) => {
194-
udp.send(addr.unwrap_udp(), buf).await?;
195-
}
196-
RecvAction::Interact(mut ctx) => {
197-
if im.handle(&mut ctx)? && ctx.send()? {
198-
udp.send(ctx.tx.peer.unwrap_udp(), ctx.tx.as_slice())
199-
.await?;
200-
}
201-
}
202-
}
203-
}
204-
205-
#[cfg(all(feature = "std", not(target_os = "espidf")))]
206-
{
207-
if let Some(data) = transport.matter().store_fabrics(buf)? {
208-
psm.store("fabrics", data)?;
209-
}
210-
211-
if let Some(data) = transport.matter().store_acls(buf)? {
212-
psm.store("acls", data)?;
213-
}
214-
}
215-
}
216-
217-
#[allow(unreachable_code)]
218-
Ok::<_, matter::error::Error>(())
219-
});
159+
info!(
160+
"About to run wth node {:p}, handler {:p}, transport runner {:p}, mdns_runner {:p}",
161+
node, handler, runner, &mdns_runner
162+
);
163+
164+
let mut fut = pin!(async move {
165+
// NOTE (no_std): On no_std, the `run_udp` is a no-op so you might want to replace it with `run` and
166+
// connect the pipes of the `run` method with your own UDP stack
167+
let mut transport = pin!(runner.run_udp(
168+
tx_buf,
169+
rx_buf,
170+
CommissioningData {
171+
// TODO: Hard-coded for now
172+
verifier: VerifierData::new_with_pw(123456, *matter.borrow()),
173+
discriminator: 250,
174+
},
175+
&handler,
176+
));
220177

221-
// NOTE (no_std): On no_std, the `run_udp` is a no-op so you might want to replace it with `run` and
222-
// connect the pipes of the `run` method with your own UDP stack
223-
let mut mdns_fut = pin!(async move { mdns_runner.run_udp().await });
178+
// NOTE (no_std): On no_std, the `run_udp` is a no-op so you might want to replace it with `run` and
179+
// connect the pipes of the `run` method with your own UDP stack
180+
let mut mdns = pin!(mdns_runner.run_udp());
224181

225-
let mut fut = pin!(async move { select(&mut io_fut, &mut mdns_fut).await.unwrap() });
182+
select(
183+
&mut transport,
184+
&mut mdns,
185+
//save(transport, &psm),
186+
)
187+
.await
188+
.unwrap()
189+
});
226190

191+
// NOTE: For no_std, replace with your own no_std way of polling the future
227192
#[cfg(feature = "std")]
228193
smol::block_on(&mut fut)?;
229194

@@ -235,18 +200,33 @@ fn run() -> Result<(), Error> {
235200
Ok(())
236201
}
237202

238-
fn handler<'a>(matter: &'a Matter<'a>) -> impl Handler + 'a {
239-
root_endpoint::handler(0, matter)
240-
.chain(
241-
1,
242-
descriptor::ID,
243-
descriptor::DescriptorCluster::new(*matter.borrow()),
244-
)
245-
.chain(
246-
1,
247-
cluster_on_off::ID,
248-
cluster_on_off::OnOffCluster::new(*matter.borrow()),
249-
)
203+
const NODE: Node<'static> = Node {
204+
id: 0,
205+
endpoints: &[
206+
root_endpoint::endpoint(0),
207+
Endpoint {
208+
id: 1,
209+
device_type: DEV_TYPE_ON_OFF_LIGHT,
210+
clusters: &[descriptor::CLUSTER, cluster_on_off::CLUSTER],
211+
},
212+
],
213+
};
214+
215+
fn handler<'a>(matter: &'a Matter<'a>) -> impl Metadata + NonBlockingHandler + 'a {
216+
(
217+
NODE,
218+
root_endpoint::handler(0, matter)
219+
.chain(
220+
1,
221+
descriptor::ID,
222+
descriptor::DescriptorCluster::new(*matter.borrow()),
223+
)
224+
.chain(
225+
1,
226+
cluster_on_off::ID,
227+
cluster_on_off::OnOffCluster::new(*matter.borrow()),
228+
),
229+
)
250230
}
251231

252232
// NOTE (no_std): For no_std, implement here your own way of initializing the logger

matter/src/data_model/cluster_on_off.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
use core::convert::TryInto;
18+
use core::{cell::Cell, convert::TryInto};
1919

2020
use super::objects::*;
2121
use crate::{
22-
attribute_enum, cmd_enter, command_enum, error::Error, interaction_model::core::Transaction,
23-
tlv::TLVElement, utils::rand::Rand,
22+
attribute_enum, cmd_enter, command_enum, error::Error, tlv::TLVElement,
23+
transport::exchange::Exchange, utils::rand::Rand,
2424
};
2525
use log::info;
2626
use strum::{EnumDiscriminants, FromRepr};
@@ -66,20 +66,20 @@ pub const CLUSTER: Cluster<'static> = Cluster {
6666

6767
pub struct OnOffCluster {
6868
data_ver: Dataver,
69-
on: bool,
69+
on: Cell<bool>,
7070
}
7171

7272
impl OnOffCluster {
7373
pub fn new(rand: Rand) -> Self {
7474
Self {
7575
data_ver: Dataver::new(rand),
76-
on: false,
76+
on: Cell::new(false),
7777
}
7878
}
7979

80-
pub fn set(&mut self, on: bool) {
81-
if self.on != on {
82-
self.on = on;
80+
pub fn set(&self, on: bool) {
81+
if self.on.get() != on {
82+
self.on.set(on);
8383
self.data_ver.changed();
8484
}
8585
}
@@ -90,15 +90,15 @@ impl OnOffCluster {
9090
CLUSTER.read(attr.attr_id, writer)
9191
} else {
9292
match attr.attr_id.try_into()? {
93-
Attributes::OnOff(codec) => codec.encode(writer, self.on),
93+
Attributes::OnOff(codec) => codec.encode(writer, self.on.get()),
9494
}
9595
}
9696
} else {
9797
Ok(())
9898
}
9999
}
100100

101-
pub fn write(&mut self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> {
101+
pub fn write(&self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> {
102102
let data = data.with_dataver(self.data_ver.get())?;
103103

104104
match attr.attr_id.try_into()? {
@@ -111,8 +111,8 @@ impl OnOffCluster {
111111
}
112112

113113
pub fn invoke(
114-
&mut self,
115-
transaction: &mut Transaction,
114+
&self,
115+
_exchange: &Exchange,
116116
cmd: &CmdDetails,
117117
_data: &TLVElement,
118118
_encoder: CmdDataEncoder,
@@ -128,12 +128,10 @@ impl OnOffCluster {
128128
}
129129
Commands::Toggle => {
130130
cmd_enter!("Toggle");
131-
self.set(!self.on);
131+
self.set(!self.on.get());
132132
}
133133
}
134134

135-
transaction.complete();
136-
137135
self.data_ver.changed();
138136

139137
Ok(())
@@ -145,18 +143,18 @@ impl Handler for OnOffCluster {
145143
OnOffCluster::read(self, attr, encoder)
146144
}
147145

148-
fn write(&mut self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> {
146+
fn write(&self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> {
149147
OnOffCluster::write(self, attr, data)
150148
}
151149

152150
fn invoke(
153-
&mut self,
154-
transaction: &mut Transaction,
151+
&self,
152+
exchange: &Exchange,
155153
cmd: &CmdDetails,
156154
data: &TLVElement,
157155
encoder: CmdDataEncoder,
158156
) -> Result<(), Error> {
159-
OnOffCluster::invoke(self, transaction, cmd, data, encoder)
157+
OnOffCluster::invoke(self, exchange, cmd, data, encoder)
160158
}
161159
}
162160

0 commit comments

Comments
 (0)