1use rand_core::RngCore;
19
20use crate::dm::{ClusterId, EmptyHandler};
21use crate::handler_chain_type;
22
23use super::clusters::acl::{self, AclHandler, ClusterHandler as _};
24use super::clusters::adm_comm::{self, AdminCommHandler, ClusterHandler as _};
25use super::clusters::basic_info::{self, BasicInfoHandler, ClusterHandler as _};
26use super::clusters::desc::{self, ClusterHandler as _, DescHandler};
27use super::clusters::eth_diag::{self, ClusterHandler as _, EthDiagHandler};
28use super::clusters::gen_comm::{self, ClusterHandler as _, CommPolicy, GenCommHandler};
29use super::clusters::gen_diag::{self, ClusterHandler as _, GenDiag, GenDiagHandler, NetifDiag};
30use super::clusters::grp_key_mgmt::{self, ClusterHandler as _, GrpKeyMgmtHandler};
31use super::clusters::net_comm::{
32 self, ClusterAsyncHandler as _, NetCommHandler, NetCtl, NetCtlStatus,
33};
34use super::clusters::noc::{self, ClusterHandler as _, NocHandler};
35use super::clusters::sw_diag::{self, ClusterHandler as _, SwDiag, SwDiagHandler};
36use super::clusters::thread_diag::{self, ClusterHandler as _, ThreadDiag, ThreadDiagHandler};
37use super::clusters::time_sync::{self, ClusterHandler as _, TimeSyncHandler};
38use super::clusters::wifi_diag::{
39 self, AlwaysConnected, ClusterHandler as _, WifiDiag, WifiDiagHandler, WirelessDiag,
40};
41use super::networks::eth::EthNetCtl;
42use super::types::{Async, ChainedHandler, Dataver, EndptId, EpClMatcher};
43
44#[allow(unused_macros)]
65#[macro_export]
66macro_rules! root_endpoint {
67 ($t:ident
68 $(, acl($($acl_opt:ident),* $(,)?))?
69 $(, sw_diag($($sw_opt:ident),* $(,)?))?
70 $(, time_sync($($ts_opt:ident),* $(,)?))?
71 ) => {
72 $crate::dm::Endpoint {
73 id: $crate::dm::endpoints::ROOT_ENDPOINT_ID,
74 device_types: $crate::devices!($crate::dm::devices::DEV_TYPE_ROOT_NODE),
75 clusters: $crate::clusters!(
76 $t
77 $(, acl($($acl_opt),*))?
78 $(, sw_diag($($sw_opt),*))?
79 $(, time_sync($($ts_opt),*))?
80 ;
81 ),
82 client_clusters: &[],
83 unique_id: None,
84 semantic_tags: &[],
85 }
86 }
87}
88
89pub type EthSysHandler<'a> =
91 SysHandler<'a, EthNetCtl<'a>, eth_diag::HandlerAdaptor<EthDiagHandler>>;
92
93pub type WifiSysHandler<'a, T> = SysHandler<'a, T, wifi_diag::HandlerAdaptor<WifiDiagHandler<'a>>>;
95
96pub type ThreadSysHandler<'a, T> =
98 SysHandler<'a, T, thread_diag::HandlerAdaptor<ThreadDiagHandler<'a>>>;
99
100pub type SysHandler<'a, T, N> = handler_chain_type!(
102 EpClMatcher => net_comm::HandlerAsyncAdaptor<NetCommHandler<'a, T>>
103 | Async<handler_chain_type!(
104 EpClMatcher => desc::HandlerAdaptor<DescHandler<'a>>,
105 EpClMatcher => basic_info::HandlerAdaptor<BasicInfoHandler>,
106 EpClMatcher => gen_comm::HandlerAdaptor<GenCommHandler<'a>>,
107 EpClMatcher => adm_comm::HandlerAdaptor<AdminCommHandler>,
108 EpClMatcher => noc::HandlerAdaptor<NocHandler>,
109 EpClMatcher => acl::HandlerAdaptor<acl::AclHandler>,
110 EpClMatcher => grp_key_mgmt::HandlerAdaptor<GrpKeyMgmtHandler>,
111 EpClMatcher => sw_diag::HandlerAdaptor<SwDiagHandler<'a>>,
112 EpClMatcher => time_sync::HandlerAdaptor<TimeSyncHandler<'a>>,
113 EpClMatcher => gen_diag::HandlerAdaptor<GenDiagHandler<'a>>,
114 EpClMatcher => N
115 )>
116);
117
118pub const ROOT_ENDPOINT_ID: EndptId = 0;
120
121#[allow(clippy::too_many_arguments)]
132pub fn eth_sys_handler<'a, R: RngCore>(
133 comm_policy: &'a dyn CommPolicy,
134 gen_diag: &'a dyn GenDiag,
135 netif_diag: &'a dyn NetifDiag,
136 sw_diag: &'a dyn SwDiag,
137 mut rand: R,
138) -> EthSysHandler<'a> {
139 sys_handler(
140 comm_policy,
141 gen_diag,
142 netif_diag,
143 sw_diag,
144 EthNetCtl::new_default(),
145 &AlwaysConnected,
146 EthDiagHandler::CLUSTER.id,
147 EthDiagHandler::new(Dataver::new_rand(&mut rand)).adapt(),
148 rand,
149 )
150}
151
152#[allow(clippy::too_many_arguments)]
164pub fn wifi_sys_handler<'a, R: RngCore, T>(
165 comm_policy: &'a dyn CommPolicy,
166 gen_diag: &'a dyn GenDiag,
167 netif_diag: &'a dyn NetifDiag,
168 wifi_diag: &'a dyn WifiDiag,
169 sw_diag: &'a dyn SwDiag,
170 net_ctl: T,
171 mut rand: R,
172) -> WifiSysHandler<'a, T>
173where
174 T: NetCtl + NetCtlStatus,
175{
176 sys_handler(
177 comm_policy,
178 gen_diag,
179 netif_diag,
180 sw_diag,
181 net_ctl,
182 wifi_diag,
183 WifiDiagHandler::CLUSTER.id,
184 WifiDiagHandler::new(Dataver::new_rand(&mut rand), wifi_diag).adapt(),
185 rand,
186 )
187}
188
189#[allow(clippy::too_many_arguments)]
201pub fn thread_sys_handler<'a, R: RngCore, T>(
202 comm_policy: &'a dyn CommPolicy,
203 gen_diag: &'a dyn GenDiag,
204 netif_diag: &'a dyn NetifDiag,
205 thread_diag: &'a dyn ThreadDiag,
206 sw_diag: &'a dyn SwDiag,
207 net_ctl: T,
208 mut rand: R,
209) -> ThreadSysHandler<'a, T>
210where
211 T: NetCtl + NetCtlStatus,
212{
213 sys_handler(
214 comm_policy,
215 gen_diag,
216 netif_diag,
217 sw_diag,
218 net_ctl,
219 thread_diag,
220 ThreadDiagHandler::CLUSTER.id,
221 ThreadDiagHandler::new(Dataver::new_rand(&mut rand), thread_diag).adapt(),
222 rand,
223 )
224}
225
226#[allow(clippy::too_many_arguments)]
241fn sys_handler<'a, R: RngCore, T, N>(
242 comm_policy: &'a dyn CommPolicy,
243 gen_diag: &'a dyn GenDiag,
244 netif_diag: &'a dyn NetifDiag,
245 sw_diag: &'a dyn SwDiag,
246 net_ctl: T,
247 wireless_diag: &'a dyn WirelessDiag,
248 netw_diag_cluster_id: ClusterId,
249 netw_diag: N,
250 mut rand: R,
251) -> SysHandler<'a, T, N>
252where
253 T: NetCtl + NetCtlStatus,
254{
255 ChainedHandler::new(
256 EpClMatcher::new(
257 Some(ROOT_ENDPOINT_ID),
258 Some(NetCommHandler::<T>::CLUSTER.id),
259 ),
260 NetCommHandler::new(Dataver::new_rand(&mut rand), net_ctl, wireless_diag).adapt(),
261 Async(
262 ChainedHandler::new(
263 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(netw_diag_cluster_id)),
264 netw_diag,
265 EmptyHandler,
266 )
267 .chain(
268 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenDiagHandler::CLUSTER.id)),
269 GenDiagHandler::new(Dataver::new_rand(&mut rand), gen_diag, netif_diag).adapt(),
270 )
271 .chain(
272 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(TimeSyncHandler::CLUSTER.id)),
273 TimeSyncHandler::new(Dataver::new_rand(&mut rand)).adapt(),
274 )
275 .chain(
276 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(SwDiagHandler::CLUSTER.id)),
277 SwDiagHandler::new(Dataver::new_rand(&mut rand), sw_diag).adapt(),
278 )
279 .chain(
280 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GrpKeyMgmtHandler::CLUSTER.id)),
281 GrpKeyMgmtHandler::new(Dataver::new_rand(&mut rand)).adapt(),
282 )
283 .chain(
284 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AclHandler::CLUSTER.id)),
285 AclHandler::new(Dataver::new_rand(&mut rand)).adapt(),
286 )
287 .chain(
288 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(NocHandler::CLUSTER.id)),
289 NocHandler::new(Dataver::new_rand(&mut rand)).adapt(),
290 )
291 .chain(
292 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AdminCommHandler::CLUSTER.id)),
293 AdminCommHandler::new(Dataver::new_rand(&mut rand)).adapt(),
294 )
295 .chain(
296 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenCommHandler::CLUSTER.id)),
297 GenCommHandler::new(Dataver::new_rand(&mut rand), comm_policy).adapt(),
298 )
299 .chain(
300 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(BasicInfoHandler::CLUSTER.id)),
301 BasicInfoHandler::new(Dataver::new_rand(&mut rand)).adapt(),
302 )
303 .chain(
304 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(DescHandler::CLUSTER.id)),
305 DescHandler::new(Dataver::new_rand(&mut rand)).adapt(),
306 ),
307 ),
308 )
309}
310
311pub struct EthSysHandlerBuilder<'a> {
334 comm_policy: &'a dyn CommPolicy,
335 gen_diag: &'a dyn GenDiag,
336 netif_diag: &'a dyn NetifDiag,
337 sw_diag: &'a dyn SwDiag,
338}
339
340impl Default for EthSysHandlerBuilder<'_> {
341 fn default() -> Self {
342 Self::new()
343 }
344}
345
346impl<'a> EthSysHandlerBuilder<'a> {
347 pub const fn new() -> Self {
349 Self {
350 comm_policy: &true,
351 gen_diag: &(),
352 netif_diag: &(),
353 sw_diag: &(),
354 }
355 }
356
357 pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
359 self.comm_policy = comm_policy;
360 self
361 }
362
363 pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
365 self.gen_diag = gen_diag;
366 self
367 }
368
369 pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
371 self.netif_diag = netif_diag;
372 self
373 }
374
375 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
377 self.sw_diag = sw_diag;
378 self
379 }
380
381 pub fn build<R: RngCore>(self, rand: R) -> EthSysHandler<'a> {
383 eth_sys_handler(
384 self.comm_policy,
385 self.gen_diag,
386 self.netif_diag,
387 self.sw_diag,
388 rand,
389 )
390 }
391}
392
393pub struct WifiSysHandlerBuilder<'a, T> {
398 comm_policy: &'a dyn CommPolicy,
399 gen_diag: &'a dyn GenDiag,
400 netif_diag: &'a dyn NetifDiag,
401 wifi_diag: &'a dyn WifiDiag,
402 sw_diag: &'a dyn SwDiag,
403 net_ctl: T,
404}
405
406impl<'a, T> WifiSysHandlerBuilder<'a, T>
407where
408 T: NetCtl + NetCtlStatus,
409{
410 pub const fn new(net_ctl: T, wifi_diag: &'a dyn WifiDiag) -> Self {
413 Self {
414 comm_policy: &true,
415 gen_diag: &(),
416 netif_diag: &(),
417 wifi_diag,
418 sw_diag: &(),
419 net_ctl,
420 }
421 }
422
423 pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
425 self.comm_policy = comm_policy;
426 self
427 }
428
429 pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
431 self.gen_diag = gen_diag;
432 self
433 }
434
435 pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
437 self.netif_diag = netif_diag;
438 self
439 }
440
441 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
443 self.sw_diag = sw_diag;
444 self
445 }
446
447 pub fn build<R: RngCore>(self, rand: R) -> WifiSysHandler<'a, T> {
449 wifi_sys_handler(
450 self.comm_policy,
451 self.gen_diag,
452 self.netif_diag,
453 self.wifi_diag,
454 self.sw_diag,
455 self.net_ctl,
456 rand,
457 )
458 }
459}
460
461pub struct ThreadSysHandlerBuilder<'a, T> {
466 comm_policy: &'a dyn CommPolicy,
467 gen_diag: &'a dyn GenDiag,
468 netif_diag: &'a dyn NetifDiag,
469 thread_diag: &'a dyn ThreadDiag,
470 sw_diag: &'a dyn SwDiag,
471 net_ctl: T,
472}
473
474impl<'a, T> ThreadSysHandlerBuilder<'a, T>
475where
476 T: NetCtl + NetCtlStatus,
477{
478 pub const fn new(net_ctl: T, thread_diag: &'a dyn ThreadDiag) -> Self {
481 Self {
482 comm_policy: &true,
483 gen_diag: &(),
484 netif_diag: &(),
485 thread_diag,
486 sw_diag: &(),
487 net_ctl,
488 }
489 }
490
491 pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
493 self.comm_policy = comm_policy;
494 self
495 }
496
497 pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
499 self.gen_diag = gen_diag;
500 self
501 }
502
503 pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
505 self.netif_diag = netif_diag;
506 self
507 }
508
509 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
511 self.sw_diag = sw_diag;
512 self
513 }
514
515 pub fn build<R: RngCore>(self, rand: R) -> ThreadSysHandler<'a, T> {
517 thread_sys_handler(
518 self.comm_policy,
519 self.gen_diag,
520 self.netif_diag,
521 self.thread_diag,
522 self.sw_diag,
523 self.net_ctl,
524 rand,
525 )
526 }
527}