use core::fmt::Debug;
use crate::dm::{Cluster, Dataver, InvokeContext, ReadContext};
use crate::error::{Error, ErrorCode};
use crate::tlv::{Nullable, NullableBuilder, Octets, OctetsBuilder, TLVBuilderParent};
use crate::utils::sync::DynBase;
use crate::with;
pub use crate::dm::clusters::decl::wi_fi_network_diagnostics::*;
pub trait WirelessDiag: DynBase {
fn connected(&self) -> Result<bool, Error> {
Ok(false)
}
}
impl<T> WirelessDiag for &T
where
T: WirelessDiag,
{
fn connected(&self) -> Result<bool, Error> {
(*self).connected()
}
}
impl WirelessDiag for () {}
pub trait WifiDiag: WirelessDiag {
#[allow(clippy::type_complexity)]
fn bssid(&self, f: &mut dyn FnMut(Option<&[u8]>) -> Result<(), Error>) -> Result<(), Error> {
f(None)
}
fn security_type(&self) -> Result<Nullable<SecurityTypeEnum>, Error> {
Ok(Nullable::none())
}
fn wi_fi_version(&self) -> Result<Nullable<WiFiVersionEnum>, Error> {
Ok(Nullable::none())
}
fn channel_number(&self) -> Result<Nullable<u16>, Error> {
Ok(Nullable::none())
}
fn rssi(&self) -> Result<Nullable<i8>, Error> {
Ok(Nullable::none())
}
}
impl<T> WifiDiag for &T
where
T: WifiDiag,
{
fn bssid(&self, f: &mut dyn FnMut(Option<&[u8]>) -> Result<(), Error>) -> Result<(), Error> {
(*self).bssid(f)
}
fn security_type(&self) -> Result<Nullable<SecurityTypeEnum>, Error> {
(*self).security_type()
}
fn wi_fi_version(&self) -> Result<Nullable<WiFiVersionEnum>, Error> {
(*self).wi_fi_version()
}
fn channel_number(&self) -> Result<Nullable<u16>, Error> {
(*self).channel_number()
}
fn rssi(&self) -> Result<Nullable<i8>, Error> {
(*self).rssi()
}
}
impl WifiDiag for () {}
#[derive(Clone)]
pub struct WifiDiagHandler<'a> {
dataver: Dataver,
diag: &'a dyn WifiDiag,
}
impl<'a> WifiDiagHandler<'a> {
pub const fn new(dataver: Dataver, diag: &'a dyn WifiDiag) -> Self {
Self { dataver, diag }
}
pub const fn adapt(self) -> HandlerAdaptor<Self> {
HandlerAdaptor(self)
}
}
impl ClusterHandler for WifiDiagHandler<'_> {
const CLUSTER: Cluster<'static> = FULL_CLUSTER.with_attrs(with!(required)).with_cmds(with!());
fn dataver(&self) -> u32 {
self.dataver.get()
}
fn dataver_changed(&self) {
self.dataver.changed();
}
fn bssid<P: TLVBuilderParent>(
&self,
_ctx: impl ReadContext,
builder: NullableBuilder<P, OctetsBuilder<P>>,
) -> Result<P, Error> {
let mut builder = Some(builder);
let mut parent = None;
self.diag.bssid(&mut |bssid| {
let builder = unwrap!(builder.take());
parent = Some(if let Some(bssid) = bssid {
builder.non_null()?.set(Octets::new(bssid))?
} else {
builder.null()?
});
Ok(())
})?;
Ok(unwrap!(parent.take()))
}
fn security_type(&self, _ctx: impl ReadContext) -> Result<Nullable<SecurityTypeEnum>, Error> {
self.diag.security_type()
}
fn wi_fi_version(&self, _ctx: impl ReadContext) -> Result<Nullable<WiFiVersionEnum>, Error> {
self.diag.wi_fi_version()
}
fn channel_number(&self, _ctx: impl ReadContext) -> Result<Nullable<u16>, Error> {
self.diag.channel_number()
}
fn rssi(&self, _ctx: impl ReadContext) -> Result<Nullable<i8>, Error> {
self.diag.rssi()
}
fn handle_reset_counts(&self, _ctx: impl InvokeContext) -> Result<(), Error> {
Err(ErrorCode::CommandNotFound.into())
}
}
impl Debug for WifiDiagHandler<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("WifiDiagHandler")
.field("dataver", &self.dataver)
.finish()
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for WifiDiagHandler<'_> {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "WifiDiagHandler {{ dataver: {} }}", self.dataver.get());
}
}