rs_matter/dm/networks/wireless/
wifi.rs1use core::fmt::{Debug, Display};
21
22use crate::dm::clusters::net_comm::WirelessCreds;
23use crate::error::{Error, ErrorCode};
24use crate::tlv::{FromTLV, OctetsOwned, ToTLV};
25use crate::utils::init::{init, Init, IntoFallibleInit};
26use crate::utils::storage::Vec;
27
28use super::{WirelessNetwork, WirelessNetworks};
29
30pub type WifiNetworks<const N: usize> = WirelessNetworks<N, Wifi>;
31
32#[derive(Debug, Clone, Eq, PartialEq, Hash, ToTLV, FromTLV)]
34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
35pub struct Wifi {
36 pub ssid: OctetsOwned<32>,
38 pub password: OctetsOwned<64>,
40}
41
42impl Default for Wifi {
43 fn default() -> Self {
44 Self::new()
45 }
46}
47
48impl Wifi {
49 pub const fn new() -> Self {
51 Self {
52 ssid: OctetsOwned { vec: Vec::new() },
53 password: OctetsOwned { vec: Vec::new() },
54 }
55 }
56
57 pub fn init() -> impl Init<Self> {
59 init!(Self {
60 ssid <- OctetsOwned::init(),
61 password <- OctetsOwned::init(),
62 })
63 }
64}
65
66impl WirelessNetwork for Wifi {
67 fn id(&self) -> &[u8] {
68 &self.ssid
69 }
70
71 #[cfg(not(feature = "defmt"))]
72 fn display_id(id: &[u8]) -> impl Display {
73 use super::DisplayId;
74
75 DisplayId::Wifi(id)
76 }
77
78 #[cfg(feature = "defmt")]
79 fn display_id(id: &[u8]) -> impl Display + defmt::Format {
80 use super::DisplayId;
81
82 DisplayId::Wifi(id)
83 }
84
85 fn init_from<'a>(creds: &'a WirelessCreds<'a>) -> impl Init<Self, Error> + 'a {
86 Self::init().into_fallible().chain(move |network| {
87 let WirelessCreds::Wifi { ssid, pass } = creds else {
88 return Err(ErrorCode::InvalidData.into());
89 };
90
91 network
92 .ssid
93 .vec
94 .extend_from_slice(ssid)
95 .map_err(|_| ErrorCode::InvalidData)?;
96 network
97 .password
98 .vec
99 .extend_from_slice(pass)
100 .map_err(|_| ErrorCode::InvalidData)?;
101
102 Ok(())
103 })
104 }
105
106 fn update(&mut self, creds: &WirelessCreds<'_>) -> Result<(), Error> {
107 let WirelessCreds::Wifi { ssid, pass } = creds else {
108 return Err(ErrorCode::InvalidData.into());
109 };
110
111 if ssid.len() > self.ssid.vec.capacity() {
112 return Err(ErrorCode::InvalidData.into());
113 }
114
115 if pass.len() > self.password.vec.capacity() {
116 return Err(ErrorCode::InvalidData.into());
117 }
118
119 self.ssid.vec.clear();
120 self.password.vec.clear();
121
122 unwrap!(self.ssid.vec.extend_from_slice(ssid));
123 unwrap!(self.password.vec.extend_from_slice(pass));
124
125 Ok(())
126 }
127
128 fn creds(&self) -> WirelessCreds<'_> {
129 WirelessCreds::Wifi {
130 ssid: &self.ssid.vec,
131 pass: &self.password.vec,
132 }
133 }
134}