use rand_core::RngCore;
use crate::dm::{ClusterId, EmptyHandler};
use crate::handler_chain_type;
use super::clusters::acl::{self, AclHandler, ClusterHandler as _};
use super::clusters::adm_comm::{self, AdminCommHandler, ClusterHandler as _};
use super::clusters::basic_info::{self, BasicInfoHandler, ClusterHandler as _};
use super::clusters::desc::{self, ClusterHandler as _, DescHandler};
use super::clusters::eth_diag::{self, ClusterHandler as _, EthDiagHandler};
use super::clusters::gen_comm::{self, ClusterHandler as _, CommPolicy, GenCommHandler};
use super::clusters::gen_diag::{self, ClusterHandler as _, GenDiag, GenDiagHandler, NetifDiag};
use super::clusters::grp_key_mgmt::{self, ClusterHandler as _, GrpKeyMgmtHandler};
use super::clusters::net_comm::{
self, ClusterAsyncHandler as _, NetCommHandler, NetCtl, NetCtlStatus,
};
use super::clusters::noc::{self, ClusterHandler as _, NocHandler};
use super::clusters::sw_diag::{self, ClusterHandler as _, SwDiag, SwDiagHandler};
use super::clusters::thread_diag::{self, ClusterHandler as _, ThreadDiag, ThreadDiagHandler};
use super::clusters::time_sync::{self, ClusterHandler as _, TimeSync, TimeSyncHandler};
use super::clusters::wifi_diag::{self, ClusterHandler as _, WifiDiag, WifiDiagHandler};
use super::networks::eth::EthNetCtl;
use super::types::{Async, ChainedHandler, Dataver, EndptId, EpClMatcher};
#[allow(unused_macros)]
#[macro_export]
macro_rules! root_endpoint {
($t:ident
$(, sw_diag($($sw_opt:ident),* $(,)?))?
$(, time_sync($($ts_opt:ident),* $(,)?))?
) => {
$crate::dm::Endpoint {
id: $crate::dm::endpoints::ROOT_ENDPOINT_ID,
device_types: $crate::devices!($crate::dm::devices::DEV_TYPE_ROOT_NODE),
clusters: $crate::clusters!(
$t
$(, sw_diag($($sw_opt),*))?
$(, time_sync($($ts_opt),*))?
;
),
client_clusters: &[],
}
}
}
pub type EthSysHandler<'a> = SysHandler<'a, EthNetCtl, eth_diag::HandlerAdaptor<EthDiagHandler>>;
pub type WifiSysHandler<'a, T> = SysHandler<'a, T, wifi_diag::HandlerAdaptor<WifiDiagHandler<'a>>>;
pub type ThreadSysHandler<'a, T> =
SysHandler<'a, T, thread_diag::HandlerAdaptor<ThreadDiagHandler<'a>>>;
pub type SysHandler<'a, T, N> = handler_chain_type!(
EpClMatcher => net_comm::HandlerAsyncAdaptor<NetCommHandler<T>>
| Async<handler_chain_type!(
EpClMatcher => desc::HandlerAdaptor<DescHandler<'a>>,
EpClMatcher => basic_info::HandlerAdaptor<BasicInfoHandler>,
EpClMatcher => gen_comm::HandlerAdaptor<GenCommHandler<'a>>,
EpClMatcher => adm_comm::HandlerAdaptor<AdminCommHandler>,
EpClMatcher => noc::HandlerAdaptor<NocHandler>,
EpClMatcher => acl::HandlerAdaptor<acl::AclHandler>,
EpClMatcher => grp_key_mgmt::HandlerAdaptor<GrpKeyMgmtHandler>,
EpClMatcher => sw_diag::HandlerAdaptor<SwDiagHandler<'a>>,
EpClMatcher => time_sync::HandlerAdaptor<TimeSyncHandler<'a>>,
EpClMatcher => gen_diag::HandlerAdaptor<GenDiagHandler<'a>>,
EpClMatcher => N
)>
);
pub const ROOT_ENDPOINT_ID: EndptId = 0;
#[allow(clippy::too_many_arguments)]
pub fn eth_sys_handler<'a, R: RngCore>(
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
mut rand: R,
) -> EthSysHandler<'a> {
sys_handler(
comm_policy,
gen_diag,
netif_diag,
time_sync,
sw_diag,
EthNetCtl,
EthDiagHandler::CLUSTER.id,
EthDiagHandler::new(Dataver::new_rand(&mut rand)).adapt(),
rand,
)
}
#[allow(clippy::too_many_arguments)]
pub fn wifi_sys_handler<'a, R: RngCore, T>(
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
wifi_diag: &'a dyn WifiDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
net_ctl: T,
mut rand: R,
) -> WifiSysHandler<'a, T>
where
T: NetCtl + NetCtlStatus,
{
sys_handler(
comm_policy,
gen_diag,
netif_diag,
time_sync,
sw_diag,
net_ctl,
WifiDiagHandler::CLUSTER.id,
WifiDiagHandler::new(Dataver::new_rand(&mut rand), wifi_diag).adapt(),
rand,
)
}
#[allow(clippy::too_many_arguments)]
pub fn thread_sys_handler<'a, R: RngCore, T>(
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
thread_diag: &'a dyn ThreadDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
net_ctl: T,
mut rand: R,
) -> ThreadSysHandler<'a, T>
where
T: NetCtl + NetCtlStatus,
{
sys_handler(
comm_policy,
gen_diag,
netif_diag,
time_sync,
sw_diag,
net_ctl,
ThreadDiagHandler::CLUSTER.id,
ThreadDiagHandler::new(Dataver::new_rand(&mut rand), thread_diag).adapt(),
rand,
)
}
#[allow(clippy::too_many_arguments)]
fn sys_handler<'a, R: RngCore, T, N>(
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
net_ctl: T,
netw_diag_cluster_id: ClusterId,
netw_diag: N,
mut rand: R,
) -> SysHandler<'a, T, N>
where
T: NetCtl + NetCtlStatus,
{
ChainedHandler::new(
EpClMatcher::new(
Some(ROOT_ENDPOINT_ID),
Some(NetCommHandler::<T>::CLUSTER.id),
),
NetCommHandler::new(Dataver::new_rand(&mut rand), net_ctl).adapt(),
Async(
ChainedHandler::new(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(netw_diag_cluster_id)),
netw_diag,
EmptyHandler,
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenDiagHandler::CLUSTER.id)),
GenDiagHandler::new(Dataver::new_rand(&mut rand), gen_diag, netif_diag).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(TimeSyncHandler::CLUSTER.id)),
TimeSyncHandler::new(Dataver::new_rand(&mut rand), time_sync).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(SwDiagHandler::CLUSTER.id)),
SwDiagHandler::new(Dataver::new_rand(&mut rand), sw_diag).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GrpKeyMgmtHandler::CLUSTER.id)),
GrpKeyMgmtHandler::new(Dataver::new_rand(&mut rand)).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AclHandler::CLUSTER.id)),
AclHandler::new(Dataver::new_rand(&mut rand)).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(NocHandler::CLUSTER.id)),
NocHandler::new(Dataver::new_rand(&mut rand)).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(AdminCommHandler::CLUSTER.id)),
AdminCommHandler::new(Dataver::new_rand(&mut rand)).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(GenCommHandler::CLUSTER.id)),
GenCommHandler::new(Dataver::new_rand(&mut rand), comm_policy).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(BasicInfoHandler::CLUSTER.id)),
BasicInfoHandler::new(Dataver::new_rand(&mut rand)).adapt(),
)
.chain(
EpClMatcher::new(Some(ROOT_ENDPOINT_ID), Some(DescHandler::CLUSTER.id)),
DescHandler::new(Dataver::new_rand(&mut rand)).adapt(),
),
),
)
}
pub struct EthSysHandlerBuilder<'a> {
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
}
impl Default for EthSysHandlerBuilder<'_> {
fn default() -> Self {
Self::new()
}
}
impl<'a> EthSysHandlerBuilder<'a> {
pub const fn new() -> Self {
Self {
comm_policy: &true,
gen_diag: &(),
netif_diag: &(),
time_sync: &(),
sw_diag: &(),
}
}
pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
self.comm_policy = comm_policy;
self
}
pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
self.gen_diag = gen_diag;
self
}
pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
self.netif_diag = netif_diag;
self
}
pub const fn time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
self.time_sync = time_sync;
self
}
pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
self.sw_diag = sw_diag;
self
}
pub fn build<R: RngCore>(self, rand: R) -> EthSysHandler<'a> {
eth_sys_handler(
self.comm_policy,
self.gen_diag,
self.netif_diag,
self.time_sync,
self.sw_diag,
rand,
)
}
}
pub struct WifiSysHandlerBuilder<'a, T> {
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
wifi_diag: &'a dyn WifiDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
net_ctl: T,
}
impl<'a, T> WifiSysHandlerBuilder<'a, T>
where
T: NetCtl + NetCtlStatus,
{
pub const fn new(net_ctl: T, wifi_diag: &'a dyn WifiDiag) -> Self {
Self {
comm_policy: &true,
gen_diag: &(),
netif_diag: &(),
wifi_diag,
time_sync: &(),
sw_diag: &(),
net_ctl,
}
}
pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
self.comm_policy = comm_policy;
self
}
pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
self.gen_diag = gen_diag;
self
}
pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
self.netif_diag = netif_diag;
self
}
pub const fn time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
self.time_sync = time_sync;
self
}
pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
self.sw_diag = sw_diag;
self
}
pub fn build<R: RngCore>(self, rand: R) -> WifiSysHandler<'a, T> {
wifi_sys_handler(
self.comm_policy,
self.gen_diag,
self.netif_diag,
self.wifi_diag,
self.time_sync,
self.sw_diag,
self.net_ctl,
rand,
)
}
}
pub struct ThreadSysHandlerBuilder<'a, T> {
comm_policy: &'a dyn CommPolicy,
gen_diag: &'a dyn GenDiag,
netif_diag: &'a dyn NetifDiag,
thread_diag: &'a dyn ThreadDiag,
time_sync: &'a dyn TimeSync,
sw_diag: &'a dyn SwDiag,
net_ctl: T,
}
impl<'a, T> ThreadSysHandlerBuilder<'a, T>
where
T: NetCtl + NetCtlStatus,
{
pub const fn new(net_ctl: T, thread_diag: &'a dyn ThreadDiag) -> Self {
Self {
comm_policy: &true,
gen_diag: &(),
netif_diag: &(),
thread_diag,
time_sync: &(),
sw_diag: &(),
net_ctl,
}
}
pub const fn comm_policy(mut self, comm_policy: &'a dyn CommPolicy) -> Self {
self.comm_policy = comm_policy;
self
}
pub const fn gen_diag(mut self, gen_diag: &'a dyn GenDiag) -> Self {
self.gen_diag = gen_diag;
self
}
pub const fn netif_diag(mut self, netif_diag: &'a dyn NetifDiag) -> Self {
self.netif_diag = netif_diag;
self
}
pub const fn time_sync(mut self, time_sync: &'a dyn TimeSync) -> Self {
self.time_sync = time_sync;
self
}
pub const fn sw_diag(mut self, sw_diag: &'a dyn SwDiag) -> Self {
self.sw_diag = sw_diag;
self
}
pub fn build<R: RngCore>(self, rand: R) -> ThreadSysHandler<'a, T> {
thread_sys_handler(
self.comm_policy,
self.gen_diag,
self.netif_diag,
self.thread_diag,
self.time_sync,
self.sw_diag,
self.net_ctl,
rand,
)
}
}