diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-09-05 19:50:21 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-09-05 19:50:21 +0200 |
| commit | 1180e1770d8cbf0fe6cb1729f3a2d113d4b13dfc (patch) | |
| tree | eaef55e73122fc5bd96510f2e15f813349037bdc /embassy-net-esp-hosted/src | |
| parent | ce662766be80d75b5f9294ae4b792f7db252ccd3 (diff) | |
net-esp-hosted: add get_status()
Diffstat (limited to 'embassy-net-esp-hosted/src')
| -rw-r--r-- | embassy-net-esp-hosted/src/control.rs | 85 |
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))] | ||
| 22 | enum WifiMode { | 24 | enum 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 | ||
| 31 | pub use proto::CtrlWifiSecProt as Security; | ||
| 32 | |||
| 33 | #[derive(Clone, Debug)] | ||
| 34 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 35 | pub 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 | |||
| 29 | macro_rules! ioctl { | 43 | macro_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 | ||
| 181 | fn 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 | |||
| 206 | fn trim_nulls<const N: usize>(s: &mut String<N>) { | ||
| 207 | while s.chars().rev().next() == Some(0 as char) { | ||
| 208 | s.pop(); | ||
| 209 | } | ||
| 210 | } | ||
