rs_matter/dm/clusters/
wifi_diag.rs1use core::fmt::Debug;
21
22use crate::dm::{Cluster, Dataver, InvokeContext, ReadContext};
23use crate::error::{Error, ErrorCode};
24use crate::tlv::{Nullable, NullableBuilder, Octets, OctetsBuilder, TLVBuilderParent};
25use crate::utils::sync::DynBase;
26use crate::with;
27
28pub use crate::dm::clusters::decl::wi_fi_network_diagnostics::*;
29
30pub trait WirelessDiag: DynBase {
33 fn connected(&self) -> Result<bool, Error> {
35 Ok(false)
36 }
37}
38
39impl<T> WirelessDiag for &T
40where
41 T: WirelessDiag,
42{
43 fn connected(&self) -> Result<bool, Error> {
44 (*self).connected()
45 }
46}
47
48impl WirelessDiag for () {}
49
50pub struct AlwaysConnected;
56
57impl DynBase for AlwaysConnected {}
58
59impl WirelessDiag for AlwaysConnected {
60 fn connected(&self) -> Result<bool, Error> {
61 Ok(true)
62 }
63}
64
65pub trait WifiDiag: WirelessDiag {
70 #[allow(clippy::type_complexity)]
71 fn bssid(&self, f: &mut dyn FnMut(Option<&[u8]>) -> Result<(), Error>) -> Result<(), Error> {
72 f(None)
73 }
74
75 fn security_type(&self) -> Result<Nullable<SecurityTypeEnum>, Error> {
76 Ok(Nullable::none())
77 }
78
79 fn wi_fi_version(&self) -> Result<Nullable<WiFiVersionEnum>, Error> {
80 Ok(Nullable::none())
81 }
82
83 fn channel_number(&self) -> Result<Nullable<u16>, Error> {
84 Ok(Nullable::none())
85 }
86
87 fn rssi(&self) -> Result<Nullable<i8>, Error> {
88 Ok(Nullable::none())
89 }
90}
91
92impl<T> WifiDiag for &T
93where
94 T: WifiDiag,
95{
96 fn bssid(&self, f: &mut dyn FnMut(Option<&[u8]>) -> Result<(), Error>) -> Result<(), Error> {
97 (*self).bssid(f)
98 }
99
100 fn security_type(&self) -> Result<Nullable<SecurityTypeEnum>, Error> {
101 (*self).security_type()
102 }
103
104 fn wi_fi_version(&self) -> Result<Nullable<WiFiVersionEnum>, Error> {
105 (*self).wi_fi_version()
106 }
107
108 fn channel_number(&self) -> Result<Nullable<u16>, Error> {
109 (*self).channel_number()
110 }
111
112 fn rssi(&self) -> Result<Nullable<i8>, Error> {
113 (*self).rssi()
114 }
115}
116
117impl WifiDiag for () {}
118
119#[derive(Clone)]
121pub struct WifiDiagHandler<'a> {
122 dataver: Dataver,
123 diag: &'a dyn WifiDiag,
124}
125
126impl<'a> WifiDiagHandler<'a> {
127 pub const fn new(dataver: Dataver, diag: &'a dyn WifiDiag) -> Self {
129 Self { dataver, diag }
130 }
131
132 pub const fn adapt(self) -> HandlerAdaptor<Self> {
134 HandlerAdaptor(self)
135 }
136}
137
138impl ClusterHandler for WifiDiagHandler<'_> {
139 const CLUSTER: Cluster<'static> = FULL_CLUSTER.with_attrs(with!(required)).with_cmds(with!());
140
141 fn dataver(&self) -> u32 {
142 self.dataver.get()
143 }
144
145 fn dataver_changed(&self) {
146 self.dataver.changed();
147 }
148
149 fn bssid<P: TLVBuilderParent>(
150 &self,
151 _ctx: impl ReadContext,
152 builder: NullableBuilder<P, OctetsBuilder<P>>,
153 ) -> Result<P, Error> {
154 let mut builder = Some(builder);
155 let mut parent = None;
156
157 self.diag.bssid(&mut |bssid| {
158 let builder = unwrap!(builder.take());
159
160 parent = Some(if let Some(bssid) = bssid {
161 builder.non_null()?.set(Octets::new(bssid))?
162 } else {
163 builder.null()?
164 });
165
166 Ok(())
167 })?;
168
169 Ok(unwrap!(parent.take()))
170 }
171
172 fn security_type(&self, _ctx: impl ReadContext) -> Result<Nullable<SecurityTypeEnum>, Error> {
173 self.diag.security_type()
174 }
175
176 fn wi_fi_version(&self, _ctx: impl ReadContext) -> Result<Nullable<WiFiVersionEnum>, Error> {
177 self.diag.wi_fi_version()
178 }
179
180 fn channel_number(&self, _ctx: impl ReadContext) -> Result<Nullable<u16>, Error> {
181 self.diag.channel_number()
182 }
183
184 fn rssi(&self, _ctx: impl ReadContext) -> Result<Nullable<i8>, Error> {
185 self.diag.rssi()
186 }
187
188 fn handle_reset_counts(&self, _ctx: impl InvokeContext) -> Result<(), Error> {
189 Err(ErrorCode::CommandNotFound.into())
190 }
191}
192
193impl Debug for WifiDiagHandler<'_> {
194 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
195 f.debug_struct("WifiDiagHandler")
196 .field("dataver", &self.dataver)
197 .finish()
198 }
199}
200
201#[cfg(feature = "defmt")]
202impl defmt::Format for WifiDiagHandler<'_> {
203 fn format(&self, f: defmt::Formatter) {
204 defmt::write!(f, "WifiDiagHandler {{ dataver: {} }}", self.dataver.get());
205 }
206}