aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-esp-hosted/src/control.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-net-esp-hosted/src/control.rs')
-rw-r--r--embassy-net-esp-hosted/src/control.rs69
1 files changed, 37 insertions, 32 deletions
diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs
index cbc194877..a7f5168c2 100644
--- a/embassy-net-esp-hosted/src/control.rs
+++ b/embassy-net-esp-hosted/src/control.rs
@@ -1,6 +1,7 @@
1use embassy_net_driver_channel as ch; 1use embassy_net_driver_channel as ch;
2use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; 2use embassy_net_driver_channel::driver::{HardwareAddress, LinkState};
3use heapless::String; 3use heapless::String;
4use micropb::{MessageDecode, MessageEncode, PbEncoder};
4 5
5use crate::ioctl::Shared; 6use crate::ioctl::Shared;
6use crate::proto::{self, CtrlMsg}; 7use crate::proto::{self, CtrlMsg};
@@ -38,7 +39,7 @@ enum WifiMode {
38 ApSta = 3, 39 ApSta = 3,
39} 40}
40 41
41pub use proto::CtrlWifiSecProt as Security; 42pub use proto::Ctrl_WifiSecProt as Security;
42 43
43/// WiFi status. 44/// WiFi status.
44#[derive(Clone, Debug)] 45#[derive(Clone, Debug)]
@@ -59,18 +60,18 @@ pub struct Status {
59macro_rules! ioctl { 60macro_rules! ioctl {
60 ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => { 61 ($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => {
61 let mut msg = proto::CtrlMsg { 62 let mut msg = proto::CtrlMsg {
62 msg_id: proto::CtrlMsgId::$req_variant as _, 63 r#msg_id: proto::CtrlMsgId::$req_variant,
63 msg_type: proto::CtrlMsgType::Req as _, 64 r#msg_type: proto::CtrlMsgType::Req,
64 payload: Some(proto::CtrlMsgPayload::$req_variant($req)), 65 r#payload: Some(proto::CtrlMsg_::Payload::$req_variant($req)),
65 }; 66 };
66 $self.ioctl(&mut msg).await?; 67 $self.ioctl(&mut msg).await?;
67 #[allow(unused_mut)] 68 #[allow(unused_mut)]
68 let Some(proto::CtrlMsgPayload::$resp_variant(mut $resp)) = msg.payload else { 69 let Some(proto::CtrlMsg_::Payload::$resp_variant(mut $resp)) = msg.payload else {
69 warn!("unexpected response variant"); 70 warn!("unexpected response variant");
70 return Err(Error::Internal); 71 return Err(Error::Internal);
71 }; 72 };
72 if $resp.resp != 0 { 73 if $resp.resp != 0 {
73 return Err(Error::Failed($resp.resp)); 74 return Err(Error::Failed($resp.resp as u32));
74 } 75 }
75 }; 76 };
76} 77}
@@ -100,26 +101,28 @@ impl<'a> Control<'a> {
100 101
101 /// Get the current status. 102 /// Get the current status.
102 pub async fn get_status(&mut self) -> Result<Status, Error> { 103 pub async fn get_status(&mut self) -> Result<Status, Error> {
103 let req = proto::CtrlMsgReqGetApConfig {}; 104 let req = proto::CtrlMsg_Req_GetAPConfig {};
104 ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); 105 ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp);
105 trim_nulls(&mut resp.ssid); 106 let ssid = core::str::from_utf8(&resp.ssid).map_err(|_| Error::Internal)?;
107 let ssid = String::try_from(ssid.trim_end_matches('\0')).map_err(|_| Error::Internal)?;
108 let bssid_str = core::str::from_utf8(&resp.bssid).map_err(|_| Error::Internal)?;
106 Ok(Status { 109 Ok(Status {
107 ssid: resp.ssid, 110 ssid,
108 bssid: parse_mac(&resp.bssid)?, 111 bssid: parse_mac(bssid_str)?,
109 rssi: resp.rssi as _, 112 rssi: resp.rssi as _,
110 channel: resp.chnl, 113 channel: resp.chnl as u32,
111 security: resp.sec_prot, 114 security: resp.sec_prot,
112 }) 115 })
113 } 116 }
114 117
115 /// Connect to the network identified by ssid using the provided password. 118 /// Connect to the network identified by ssid using the provided password.
116 pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { 119 pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> {
117 let req = proto::CtrlMsgReqConnectAp { 120 let req = proto::CtrlMsg_Req_ConnectAP {
118 ssid: unwrap!(String::try_from(ssid)), 121 r#ssid: unwrap!(String::try_from(ssid)),
119 pwd: unwrap!(String::try_from(password)), 122 r#pwd: unwrap!(String::try_from(password)),
120 bssid: String::new(), 123 r#bssid: String::new(),
121 listen_interval: 3, 124 r#listen_interval: 3,
122 is_wpa3_supported: true, 125 r#is_wpa3_supported: true,
123 }; 126 };
124 ioctl!(self, ReqConnectAp, RespConnectAp, req, resp); 127 ioctl!(self, ReqConnectAp, RespConnectAp, req, resp);
125 self.state_ch.set_link_state(LinkState::Up); 128 self.state_ch.set_link_state(LinkState::Up);
@@ -128,7 +131,7 @@ impl<'a> Control<'a> {
128 131
129 /// Disconnect from any currently connected network. 132 /// Disconnect from any currently connected network.
130 pub async fn disconnect(&mut self) -> Result<(), Error> { 133 pub async fn disconnect(&mut self) -> Result<(), Error> {
131 let req = proto::CtrlMsgReqGetStatus {}; 134 let req = proto::CtrlMsg_Req_GetStatus {};
132 ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); 135 ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp);
133 self.state_ch.set_link_state(LinkState::Down); 136 self.state_ch.set_link_state(LinkState::Down);
134 Ok(()) 137 Ok(())
@@ -136,21 +139,25 @@ impl<'a> Control<'a> {
136 139
137 /// duration in seconds, clamped to [10, 3600] 140 /// duration in seconds, clamped to [10, 3600]
138 async fn set_heartbeat(&mut self, duration: u32) -> Result<(), Error> { 141 async fn set_heartbeat(&mut self, duration: u32) -> Result<(), Error> {
139 let req = proto::CtrlMsgReqConfigHeartbeat { enable: true, duration }; 142 let req = proto::CtrlMsg_Req_ConfigHeartbeat {
143 r#enable: true,
144 r#duration: duration as i32,
145 };
140 ioctl!(self, ReqConfigHeartbeat, RespConfigHeartbeat, req, resp); 146 ioctl!(self, ReqConfigHeartbeat, RespConfigHeartbeat, req, resp);
141 Ok(()) 147 Ok(())
142 } 148 }
143 149
144 async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> { 150 async fn get_mac_addr(&mut self) -> Result<[u8; 6], Error> {
145 let req = proto::CtrlMsgReqGetMacAddress { 151 let req = proto::CtrlMsg_Req_GetMacAddress {
146 mode: WifiMode::Sta as _, 152 r#mode: WifiMode::Sta as _,
147 }; 153 };
148 ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp); 154 ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp);
149 parse_mac(&resp.mac) 155 let mac_str = core::str::from_utf8(&resp.mac).map_err(|_| Error::Internal)?;
156 parse_mac(mac_str)
150 } 157 }
151 158
152 async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> { 159 async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> {
153 let req = proto::CtrlMsgReqSetMode { mode }; 160 let req = proto::CtrlMsg_Req_SetMode { r#mode: mode as i32 };
154 ioctl!(self, ReqSetWifiMode, RespSetWifiMode, req, resp); 161 ioctl!(self, ReqSetWifiMode, RespSetWifiMode, req, resp);
155 162
156 Ok(()) 163 Ok(())
@@ -160,11 +167,15 @@ impl<'a> Control<'a> {
160 debug!("ioctl req: {:?}", &msg); 167 debug!("ioctl req: {:?}", &msg);
161 168
162 let mut buf = [0u8; 128]; 169 let mut buf = [0u8; 128];
170 let buf_len = buf.len();
163 171
164 let req_len = noproto::write(msg, &mut buf).map_err(|_| { 172 let mut encoder = PbEncoder::new(&mut buf[..]);
173 msg.encode(&mut encoder).map_err(|_| {
165 warn!("failed to serialize control request"); 174 warn!("failed to serialize control request");
166 Error::Internal 175 Error::Internal
167 })?; 176 })?;
177 let remaining = encoder.into_writer();
178 let req_len = buf_len - remaining.len();
168 179
169 struct CancelOnDrop<'a>(&'a Shared); 180 struct CancelOnDrop<'a>(&'a Shared);
170 181
@@ -186,8 +197,8 @@ impl<'a> Control<'a> {
186 197
187 ioctl.defuse(); 198 ioctl.defuse();
188 199
189 *msg = noproto::read(&buf[..resp_len]).map_err(|_| { 200 msg.decode_from_bytes(&buf[..resp_len]).map_err(|_| {
190 warn!("failed to serialize control request"); 201 warn!("failed to deserialize control response");
191 Error::Internal 202 Error::Internal
192 })?; 203 })?;
193 debug!("ioctl resp: {:?}", msg); 204 debug!("ioctl resp: {:?}", msg);
@@ -221,9 +232,3 @@ fn parse_mac(mac: &str) -> Result<[u8; 6], Error> {
221 } 232 }
222 Ok(res) 233 Ok(res)
223} 234}
224
225fn trim_nulls<const N: usize>(s: &mut String<N>) {
226 while s.chars().rev().next() == Some(0 as char) {
227 s.pop();
228 }
229}