aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-esp-hosted
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-net-esp-hosted')
-rw-r--r--embassy-net-esp-hosted/src/control.rs85
1 files changed, 63 insertions, 22 deletions
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs
index ce6636a8e..a4996b584 100644
--- a/embassy-net-esp-hosted/src/control.rs
+++ b/embassy-net-esp-hosted/src/control.rs
@@ -19,6 +19,8 @@ pub struct Control<'a> {
19} 19}
20 20
21#[allow(unused)] 21#[allow(unused)]
22#[derive(Copy, Clone, PartialEq, Eq, Debug)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
22enum WifiMode { 24enum WifiMode {
23 None = 0, 25 None = 0,
24 Sta = 1, 26 Sta = 1,
@@ -26,6 +28,18 @@ enum WifiMode {
26 ApSta = 3, 28 ApSta = 3,
27} 29}
28 30
31pub use proto::CtrlWifiSecProt as Security;
32
33#[derive(Clone, Debug)]
34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
35pub struct Status {
36 pub ssid: String<32>,
37 pub bssid: [u8; 6],
38 pub rssi: i32,
39 pub channel: u32,
40 pub security: Security,
41}
42
29macro_rules! ioctl { 43macro_rules! ioctl {
30 ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => { 44 ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => {
31 let mut msg = proto::CtrlMsg { 45 let mut msg = proto::CtrlMsg {
@@ -34,7 +48,9 @@ macro_rules! ioctl {
34 payload: Some(proto::CtrlMsgPayload::$req_variant($req)), 48 payload: Some(proto::CtrlMsgPayload::$req_variant($req)),
35 }; 49 };
36 $self.ioctl(&mut msg).await?; 50 $self.ioctl(&mut msg).await?;
37 let Some(proto::CtrlMsgPayload::$resp_variant($resp)) = msg.payload else { 51 #[allow(unused_mut)]
52 let Some(proto::CtrlMsgPayload::$resp_variant(mut $resp)) = msg.payload
53 else {
38 warn!("unexpected response variant"); 54 warn!("unexpected response variant");
39 return Err(Error::Internal); 55 return Err(Error::Internal);
40 }; 56 };
@@ -66,6 +82,19 @@ impl<'a> Control<'a> {
66 Ok(()) 82 Ok(())
67 } 83 }
68 84
85 pub async fn get_status(&mut self) -> Result<Status, Error> {
86 let req = proto::CtrlMsgReqGetApConfig {};
87 ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp);
88 trim_nulls(&mut resp.ssid);
89 Ok(Status {
90 ssid: resp.ssid,
91 bssid: parse_mac(&resp.bssid)?,
92 rssi: resp.rssi as _,
93 channel: resp.chnl,
94 security: resp.sec_prot,
95 })
96 }
97
69 pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { 98 pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> {
70 let req = proto::CtrlMsgReqConnectAp { 99 let req = proto::CtrlMsgReqConnectAp {
71 ssid: String::from(ssid), 100 ssid: String::from(ssid),
@@ -98,27 +127,7 @@ impl<'a> Control<'a> {
98 mode: WifiMode::Sta as _, 127 mode: WifiMode::Sta as _,
99 }; 128 };
100 ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp); 129 ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp);
101 130 parse_mac(&resp.mac)
102 // WHY IS THIS A STRING? WHYYYY
103 fn nibble_from_hex(b: u8) -> u8 {
104 match b {
105 b'0'..=b'9' => b - b'0',
106 b'a'..=b'f' => b + 0xa - b'a',
107 b'A'..=b'F' => b + 0xa - b'A',
108 _ => panic!("invalid hex digit {}", b),
109 }
110 }
111
112 let mac = resp.mac.as_bytes();
113 let mut res = [0; 6];
114 if mac.len() != 17 {
115 warn!("unexpected MAC respnse length");
116 return Err(Error::Internal);
117 }
118 for (i, b) in res.iter_mut().enumerate() {
119 *b = (nibble_from_hex(mac[i * 3]) << 4) | nibble_from_hex(mac[i * 3 + 1])
120 }
121 Ok(res)
122 } 131 }
123 132
124 async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> { 133 async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> {
@@ -167,3 +176,35 @@ impl<'a> Control<'a> {
167 Ok(()) 176 Ok(())
168 } 177 }
169} 178}
179
180// WHY IS THIS A STRING? WHYYYY
181fn parse_mac(mac: &str) -> Result<[u8; 6], Error> {
182 fn nibble_from_hex(b: u8) -> Result<u8, Error> {
183 match b {
184 b'0'..=b'9' => Ok(b - b'0'),
185 b'a'..=b'f' => Ok(b + 0xa - b'a'),
186 b'A'..=b'F' => Ok(b + 0xa - b'A'),
187 _ => {
188 warn!("invalid hex digit {}", b);
189 Err(Error::Internal)
190 }
191 }
192 }
193
194 let mac = mac.as_bytes();
195 let mut res = [0; 6];
196 if mac.len() != 17 {
197 warn!("unexpected MAC length");
198 return Err(Error::Internal);
199 }
200 for (i, b) in res.iter_mut().enumerate() {
201 *b = (nibble_from_hex(mac[i * 3])? << 4) | nibble_from_hex(mac[i * 3 + 1])?
202 }
203 Ok(res)
204}
205
206fn trim_nulls<const N: usize>(s: &mut String<N>) {
207 while s.chars().rev().next() == Some(0 as char) {
208 s.pop();
209 }
210}