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 _, TimeSync, TimeSyncHandler};
38use super::clusters::wifi_diag::{self, ClusterHandler as _, WifiDiag, WifiDiagHandler};
39use super::networks::eth::EthNetCtl;
40use super::types::{Async, ChainedHandler, Dataver, EndptId, EpClMatcher};
41
42#[allow(unused_macros)]
60#[macro_export]
61macro_rules! root_endpoint {
62 ($t:ident
63 $(, sw_diag($($sw_opt:ident),* $(,)?))?
64 $(, time_sync($($ts_opt:ident),* $(,)?))?
65 ) => {
66 $crate::dm::Endpoint {
67 id: $crate::dm::endpoints::ROOT_ENDPOINT_ID,
68 device_types: $crate::devices!($crate::dm::devices::DEV_TYPE_ROOT_NODE),
69 clusters: $crate::clusters!(
70 $t
71 $(, sw_diag($($sw_opt),*))?
72 $(, time_sync($($ts_opt),*))?
73 ;
74 ),
75 client_clusters: &[],
76 }
77 }
78}
79
80pub type EthSysHandler<'a> = SysHandler<'a, EthNetCtl, eth_diag::HandlerAdaptor<EthDiagHandler>>;
82
83pub type WifiSysHandler<'a, T> = SysHandler<'a, T, wifi_diag::HandlerAdaptor<WifiDiagHandler<'a>>>;
85
86pub type ThreadSysHandler<'a, T> =
88 SysHandler<'a, T, thread_diag::HandlerAdaptor<ThreadDiagHandler<'a>>>;
89
90pub type SysHandler<'a, T, N> = handler_chain_type!(
92 EpClMatcher => net_comm::HandlerAsyncAdaptor<NetCommHandler<T>>
93 | Async<handler_chain_type!(
94 EpClMatcher => desc::HandlerAdaptor<DescHandler<'a>>,
95 EpClMatcher => basic_info::HandlerAdaptor<BasicInfoHandler>,
96 EpClMatcher => gen_comm::HandlerAdaptor<GenCommHandler<'a>>,
97 EpClMatcher => adm_comm::HandlerAdaptor<AdminCommHandler>,
98 EpClMatcher => noc::HandlerAdaptor<NocHandler>,
99 EpClMatcher => acl::HandlerAdaptor<acl::AclHandler>,
100 EpClMatcher => grp_key_mgmt::HandlerAdaptor<GrpKeyMgmtHandler>,
101 EpClMatcher => sw_diag::HandlerAdaptor<SwDiagHandler<'a>>,
102 EpClMatcher => time_sync::HandlerAdaptor<TimeSyncHandler<'a>>,
103 EpClMatcher => gen_diag::HandlerAdaptor<GenDiagHandler<'a>>,
104 EpClMatcher => N
105 )>
106);
107
108pub const ROOT_ENDPOINT_ID: EndptId = 0;
110
111#[allow(clippy::too_many_arguments)]
125pub fn eth_sys_handler<'a, R: RngCore>(
126 comm_policy: &'a dyn CommPolicy,
127 gen_diag: &'a dyn GenDiag,
128 netif_diag: &'a dyn NetifDiag,
129 time_sync: &'a dyn TimeSync,
130 sw_diag: &'a dyn SwDiag,
131 mut rand: R,
132) -> EthSysHandler<'a> {
133 sys_handler(
134 comm_policy,
135 gen_diag,
136 netif_diag,
137 time_sync,
138 sw_diag,
139 EthNetCtl,
140 EthDiagHandler::CLUSTER.id,
141 EthDiagHandler::new(Dataver::new_rand(&mut rand)).adapt(),
142 rand,
143 )
144}
145
146#[allow(clippy::too_many_arguments)]
159pub fn wifi_sys_handler<'a, R: RngCore, T>(
160 comm_policy: &'a dyn CommPolicy,
161 gen_diag: &'a dyn GenDiag,
162 netif_diag: &'a dyn NetifDiag,
163 wifi_diag: &'a dyn WifiDiag,
164 time_sync: &'a dyn TimeSync,
165 sw_diag: &'a dyn SwDiag,
166 net_ctl: T,
167 mut rand: R,
168) -> WifiSysHandler<'a, T>
169where
170 T: NetCtl + NetCtlStatus,
171{
172 sys_handler(
173 comm_policy,
174 gen_diag,
175 netif_diag,
176 time_sync,
177 sw_diag,
178 net_ctl,
179 WifiDiagHandler::CLUSTER.id,
180 WifiDiagHandler::new(Dataver::new_rand(&mut rand), wifi_diag).adapt(),
181 rand,
182 )
183}
184
185#[allow(clippy::too_many_arguments)]
198pub fn thread_sys_handler<'a, R: RngCore, T>(
199 comm_policy: &'a dyn CommPolicy,
200 gen_diag: &'a dyn GenDiag,
201 netif_diag: &'a dyn NetifDiag,
202 thread_diag: &'a dyn ThreadDiag,
203 time_sync: &'a dyn TimeSync,
204 sw_diag: &'a dyn SwDiag,
205 net_ctl: T,
206 mut rand: R,
207) -> ThreadSysHandler<'a, T>
208where
209 T: NetCtl + NetCtlStatus,
210{
211 sys_handler(
212 comm_policy,
213 gen_diag,
214 netif_diag,
215 time_sync,
216 sw_diag,
217 net_ctl,
218 ThreadDiagHandler::CLUSTER.id,
219 ThreadDiagHandler::new(Dataver::new_rand(&mut rand), thread_diag).adapt(),
220 rand,
221 )
222}
223
224#[allow(clippy::too_many_arguments)]
239fn sys_handler<'a, R: RngCore, T, N>(
240 comm_policy: &'a dyn CommPolicy,
241 gen_diag: &'a dyn GenDiag,
242 netif_diag: &'a dyn NetifDiag,
243 time_sync: &'a dyn TimeSync,
244 sw_diag: &'a dyn SwDiag,
245 net_ctl: T,
246 netw_diag_cluster_id: ClusterId,
247 netw_diag: N,
248 mut rand: R,
249) -> SysHandler<'a, T, N>
250where
251 T: NetCtl + NetCtlStatus,
252{
253 ChainedHandler::new(
254 EpClMatcher::new(
255 Some(ROOT_ENDPOINT_ID),
256 Some(NetCommHandler::<T>::CLUSTER.id),
257 ),
258 NetCommHandler::new(Dataver::new_rand(&mut rand), net_ctl).adapt(),
259 Async(
260 ChainedHandler::new(
261 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(netw_diag_cluster_id)),
262 netw_diag,
263 EmptyHandler,
264 )
265 .chain(
266 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenDiagHandler::CLUSTER.id)),
267 GenDiagHandler::new(Dataver::new_rand(&mut rand), gen_diag, netif_diag).adapt(),
268 )
269 .chain(
270 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(TimeSyncHandler::CLUSTER.id)),
271 TimeSyncHandler::new(Dataver::new_rand(&mut rand), time_sync).adapt(),
272 )
273 .chain(
274 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(SwDiagHandler::CLUSTER.id)),
275 SwDiagHandler::new(Dataver::new_rand(&mut rand), sw_diag).adapt(),
276 )
277 .chain(
278 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GrpKeyMgmtHandler::CLUSTER.id)),
279 GrpKeyMgmtHandler::new(Dataver::new_rand(&mut rand)).adapt(),
280 )
281 .chain(
282 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AclHandler::CLUSTER.id)),
283 AclHandler::new(Dataver::new_rand(&mut rand)).adapt(),
284 )
285 .chain(
286 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(NocHandler::CLUSTER.id)),
287 NocHandler::new(Dataver::new_rand(&mut rand)).adapt(),
288 )
289 .chain(
290 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AdminCommHandler::CLUSTER.id)),
291 AdminCommHandler::new(Dataver::new_rand(&mut rand)).adapt(),
292 )
293 .chain(
294 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenCommHandler::CLUSTER.id)),
295 GenCommHandler::new(Dataver::new_rand(&mut rand), comm_policy).adapt(),
296 )
297 .chain(
298 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(BasicInfoHandler::CLUSTER.id)),
299 BasicInfoHandler::new(Dataver::new_rand(&mut rand)).adapt(),
300 )
301 .chain(
302 EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(DescHandler::CLUSTER.id)),
303 DescHandler::new(Dataver::new_rand(&mut rand)).adapt(),
304 ),
305 ),
306 )
307}
308
309pub struct EthSysHandlerBuilder<'a> {
332 comm_policy: &'a dyn CommPolicy,
333 gen_diag: &'a dyn GenDiag,
334 netif_diag: &'a dyn NetifDiag,
335 time_sync: &'a dyn TimeSync,
336 sw_diag: &'a dyn SwDiag,
337}
338
339impl Default for EthSysHandlerBuilder<'_> {
340 fn default() -> Self {
341 Self::new()
342 }
343}
344
345impl<'a> EthSysHandlerBuilder<'a> {
346 pub const fn new() -> Self {
348 Self {
349 comm_policy: &true,
350 gen_diag: &(),
351 netif_diag: &(),
352 time_sync: &(),
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 time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
383 self.time_sync = time_sync;
384 self
385 }
386
387 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
389 self.sw_diag = sw_diag;
390 self
391 }
392
393 pub fn build<R: RngCore>(self, rand: R) -> EthSysHandler<'a> {
395 eth_sys_handler(
396 self.comm_policy,
397 self.gen_diag,
398 self.netif_diag,
399 self.time_sync,
400 self.sw_diag,
401 rand,
402 )
403 }
404}
405
406pub struct WifiSysHandlerBuilder<'a, T> {
411 comm_policy: &'a dyn CommPolicy,
412 gen_diag: &'a dyn GenDiag,
413 netif_diag: &'a dyn NetifDiag,
414 wifi_diag: &'a dyn WifiDiag,
415 time_sync: &'a dyn TimeSync,
416 sw_diag: &'a dyn SwDiag,
417 net_ctl: T,
418}
419
420impl<'a, T> WifiSysHandlerBuilder<'a, T>
421where
422 T: NetCtl + NetCtlStatus,
423{
424 pub const fn new(net_ctl: T, wifi_diag: &'a dyn WifiDiag) -> Self {
427 Self {
428 comm_policy: &true,
429 gen_diag: &(),
430 netif_diag: &(),
431 wifi_diag,
432 time_sync: &(),
433 sw_diag: &(),
434 net_ctl,
435 }
436 }
437
438 pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
440 self.comm_policy = comm_policy;
441 self
442 }
443
444 pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
446 self.gen_diag = gen_diag;
447 self
448 }
449
450 pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
452 self.netif_diag = netif_diag;
453 self
454 }
455
456 pub const fn time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
459 self.time_sync = time_sync;
460 self
461 }
462
463 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
465 self.sw_diag = sw_diag;
466 self
467 }
468
469 pub fn build<R: RngCore>(self, rand: R) -> WifiSysHandler<'a, T> {
471 wifi_sys_handler(
472 self.comm_policy,
473 self.gen_diag,
474 self.netif_diag,
475 self.wifi_diag,
476 self.time_sync,
477 self.sw_diag,
478 self.net_ctl,
479 rand,
480 )
481 }
482}
483
484pub struct ThreadSysHandlerBuilder<'a, T> {
489 comm_policy: &'a dyn CommPolicy,
490 gen_diag: &'a dyn GenDiag,
491 netif_diag: &'a dyn NetifDiag,
492 thread_diag: &'a dyn ThreadDiag,
493 time_sync: &'a dyn TimeSync,
494 sw_diag: &'a dyn SwDiag,
495 net_ctl: T,
496}
497
498impl<'a, T> ThreadSysHandlerBuilder<'a, T>
499where
500 T: NetCtl + NetCtlStatus,
501{
502 pub const fn new(net_ctl: T, thread_diag: &'a dyn ThreadDiag) -> Self {
505 Self {
506 comm_policy: &true,
507 gen_diag: &(),
508 netif_diag: &(),
509 thread_diag,
510 time_sync: &(),
511 sw_diag: &(),
512 net_ctl,
513 }
514 }
515
516 pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
518 self.comm_policy = comm_policy;
519 self
520 }
521
522 pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
524 self.gen_diag = gen_diag;
525 self
526 }
527
528 pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
530 self.netif_diag = netif_diag;
531 self
532 }
533
534 pub const fn time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
537 self.time_sync = time_sync;
538 self
539 }
540
541 pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
543 self.sw_diag = sw_diag;
544 self
545 }
546
547 pub fn build<R: RngCore>(self, rand: R) -> ThreadSysHandler<'a, T> {
549 thread_sys_handler(
550 self.comm_policy,
551 self.gen_diag,
552 self.netif_diag,
553 self.thread_diag,
554 self.time_sync,
555 self.sw_diag,
556 self.net_ctl,
557 rand,
558 )
559 }
560}