aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-esp-hosted
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-10-29 18:24:57 +0100
committerDario Nieuwenhuis <[email protected]>2025-10-29 19:33:41 +0100
commit252664c1b0b4d81c34953c92bdcec84f7b5d3986 (patch)
treef84c40c84aa81d99bcb2fdb734186e8972891236 /embassy-net-esp-hosted
parent98de11e5e3ae437676198a105ffab8c0f4977513 (diff)
net-esp-hosted: switch from noproto to micropb.
Diffstat (limited to 'embassy-net-esp-hosted')
-rw-r--r--embassy-net-esp-hosted/Cargo.toml5
-rw-r--r--embassy-net-esp-hosted/build.rs33
-rw-r--r--embassy-net-esp-hosted/src/control.rs69
-rw-r--r--embassy-net-esp-hosted/src/lib.rs28
-rw-r--r--embassy-net-esp-hosted/src/proto.rs656
5 files changed, 94 insertions, 697 deletions
diff --git a/embassy-net-esp-hosted/Cargo.toml b/embassy-net-esp-hosted/Cargo.toml
index f148f4762..2442b3235 100644
--- a/embassy-net-esp-hosted/Cargo.toml
+++ b/embassy-net-esp-hosted/Cargo.toml
@@ -25,9 +25,12 @@ embassy-net-driver-channel = { version = "0.3.2", path = "../embassy-net-driver-
25embedded-hal = { version = "1.0" } 25embedded-hal = { version = "1.0" }
26embedded-hal-async = { version = "1.0" } 26embedded-hal-async = { version = "1.0" }
27 27
28noproto = "0.1.0" 28micropb = { version = "0.4.0", default-features = false, features = ["container-heapless", "encode", "decode"] }
29heapless = "0.8" 29heapless = "0.8"
30 30
31[build-dependencies]
32micropb-gen = "0.4.0"
33
31[package.metadata.embassy_docs] 34[package.metadata.embassy_docs]
32src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-esp-hosted-v$VERSION/embassy-net-esp-hosted/src/" 35src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-esp-hosted-v$VERSION/embassy-net-esp-hosted/src/"
33src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-esp-hosted/src/" 36src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-esp-hosted/src/"
diff --git a/embassy-net-esp-hosted/build.rs b/embassy-net-esp-hosted/build.rs
new file mode 100644
index 000000000..1e9b8cffd
--- /dev/null
+++ b/embassy-net-esp-hosted/build.rs
@@ -0,0 +1,33 @@
1fn main() {
2 let out_dir = std::env::var("OUT_DIR").unwrap();
3
4 let mut g = micropb_gen::Generator::new();
5 g.use_container_heapless();
6
7 g.configure(
8 ".",
9 micropb_gen::Config::new()
10 .max_bytes(32) // For ssid, mac, etc - strings
11 .max_len(16) // For repeated fields
12 .type_attributes("#[cfg_attr(feature = \"defmt\", derive(defmt::Format))]"),
13 );
14
15 // Special config for things that need to be larger
16 g.configure(
17 ".CtrlMsg_Req_OTAWrite.ota_data",
18 micropb_gen::Config::new().max_bytes(1024),
19 );
20 g.configure(
21 ".CtrlMsg_Event_ESPInit.init_data",
22 micropb_gen::Config::new().max_bytes(64),
23 );
24 g.configure(
25 ".CtrlMsg_Req_VendorIEData.payload",
26 micropb_gen::Config::new().max_bytes(64),
27 );
28
29 g.compile_protos(&["src/esp_hosted_config.proto"], format!("{}/proto.rs", out_dir))
30 .unwrap();
31
32 println!("cargo:rerun-if-changed=src/esp_hosted_config.proto");
33}
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}
diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs
index 8da0cd4dc..1fbed3e83 100644
--- a/embassy-net-esp-hosted/src/lib.rs
+++ b/embassy-net-esp-hosted/src/lib.rs
@@ -10,9 +10,19 @@ use embassy_time::{Duration, Instant, Timer};
10use embedded_hal::digital::OutputPin; 10use embedded_hal::digital::OutputPin;
11 11
12use crate::ioctl::{PendingIoctl, Shared}; 12use crate::ioctl::{PendingIoctl, Shared};
13use crate::proto::{CtrlMsg, CtrlMsgPayload}; 13use crate::proto::{CtrlMsg, CtrlMsg_};
14 14
15mod proto; 15mod proto {
16 #![allow(unused)]
17 #![allow(non_snake_case)]
18 #![allow(non_camel_case_types)]
19 #![allow(non_upper_case_globals)]
20 #![allow(missing_docs)]
21 #![allow(clippy::all)]
22
23 // Include the generated protobuf code from micropb-gen
24 include!(concat!(env!("OUT_DIR"), "/proto.rs"));
25}
16 26
17// must be first 27// must be first
18mod fmt; 28mod fmt;
@@ -313,10 +323,12 @@ where
313 } 323 }
314 324
315 fn handle_event(&mut self, data: &[u8]) { 325 fn handle_event(&mut self, data: &[u8]) {
316 let Ok(event) = noproto::read::<CtrlMsg>(data) else { 326 use micropb::MessageDecode;
327 let mut event = CtrlMsg::default();
328 if event.decode_from_bytes(data).is_err() {
317 warn!("failed to parse event"); 329 warn!("failed to parse event");
318 return; 330 return;
319 }; 331 }
320 332
321 debug!("event: {:?}", &event); 333 debug!("event: {:?}", &event);
322 334
@@ -326,9 +338,9 @@ where
326 }; 338 };
327 339
328 match payload { 340 match payload {
329 CtrlMsgPayload::EventEspInit(_) => self.shared.init_done(), 341 CtrlMsg_::Payload::EventEspInit(_) => self.shared.init_done(),
330 CtrlMsgPayload::EventHeartbeat(_) => self.heartbeat_deadline = Instant::now() + HEARTBEAT_MAX_GAP, 342 CtrlMsg_::Payload::EventHeartbeat(_) => self.heartbeat_deadline = Instant::now() + HEARTBEAT_MAX_GAP,
331 CtrlMsgPayload::EventStationDisconnectFromAp(e) => { 343 CtrlMsg_::Payload::EventStationDisconnectFromAp(e) => {
332 info!("disconnected, code {}", e.resp); 344 info!("disconnected, code {}", e.resp);
333 self.state_ch.set_link_state(LinkState::Down); 345 self.state_ch.set_link_state(LinkState::Down);
334 } 346 }
diff --git a/embassy-net-esp-hosted/src/proto.rs b/embassy-net-esp-hosted/src/proto.rs
deleted file mode 100644
index 089ded677..000000000
--- a/embassy-net-esp-hosted/src/proto.rs
+++ /dev/null
@@ -1,656 +0,0 @@
1#![allow(unused)]
2
3use heapless::{String, Vec};
4
5/// internal supporting structures for CtrlMsg
6
7#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
8#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub(crate) struct ScanResult {
10 #[noproto(tag = "1")]
11 pub ssid: String<32>,
12 #[noproto(tag = "2")]
13 pub chnl: u32,
14 #[noproto(tag = "3")]
15 pub rssi: u32,
16 #[noproto(tag = "4")]
17 pub bssid: String<32>,
18 #[noproto(tag = "5")]
19 pub sec_prot: CtrlWifiSecProt,
20}
21
22#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24pub(crate) struct ConnectedStaList {
25 #[noproto(tag = "1")]
26 pub mac: String<32>,
27 #[noproto(tag = "2")]
28 pub rssi: u32,
29}
30/// * Req/Resp structure *
31
32#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34pub(crate) struct CtrlMsgReqGetMacAddress {
35 #[noproto(tag = "1")]
36 pub mode: u32,
37}
38
39#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
40#[cfg_attr(feature = "defmt", derive(defmt::Format))]
41pub(crate) struct CtrlMsgRespGetMacAddress {
42 #[noproto(tag = "1")]
43 pub mac: String<32>,
44 #[noproto(tag = "2")]
45 pub resp: u32,
46}
47
48#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
49#[cfg_attr(feature = "defmt", derive(defmt::Format))]
50pub(crate) struct CtrlMsgReqGetMode {}
51
52#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
53#[cfg_attr(feature = "defmt", derive(defmt::Format))]
54pub(crate) struct CtrlMsgRespGetMode {
55 #[noproto(tag = "1")]
56 pub mode: u32,
57 #[noproto(tag = "2")]
58 pub resp: u32,
59}
60
61#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
62#[cfg_attr(feature = "defmt", derive(defmt::Format))]
63pub(crate) struct CtrlMsgReqSetMode {
64 #[noproto(tag = "1")]
65 pub mode: u32,
66}
67
68#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70pub(crate) struct CtrlMsgRespSetMode {
71 #[noproto(tag = "1")]
72 pub resp: u32,
73}
74
75#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
76#[cfg_attr(feature = "defmt", derive(defmt::Format))]
77pub(crate) struct CtrlMsgReqGetStatus {}
78
79#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81pub(crate) struct CtrlMsgRespGetStatus {
82 #[noproto(tag = "1")]
83 pub resp: u32,
84}
85
86#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88pub(crate) struct CtrlMsgReqSetMacAddress {
89 #[noproto(tag = "1")]
90 pub mac: String<32>,
91 #[noproto(tag = "2")]
92 pub mode: u32,
93}
94
95#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
96#[cfg_attr(feature = "defmt", derive(defmt::Format))]
97pub(crate) struct CtrlMsgRespSetMacAddress {
98 #[noproto(tag = "1")]
99 pub resp: u32,
100}
101
102#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
103#[cfg_attr(feature = "defmt", derive(defmt::Format))]
104pub(crate) struct CtrlMsgReqGetApConfig {}
105
106#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub(crate) struct CtrlMsgRespGetApConfig {
109 #[noproto(tag = "1")]
110 pub ssid: String<32>,
111 #[noproto(tag = "2")]
112 pub bssid: String<32>,
113 #[noproto(tag = "3")]
114 pub rssi: u32,
115 #[noproto(tag = "4")]
116 pub chnl: u32,
117 #[noproto(tag = "5")]
118 pub sec_prot: CtrlWifiSecProt,
119 #[noproto(tag = "6")]
120 pub resp: u32,
121}
122
123#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
124#[cfg_attr(feature = "defmt", derive(defmt::Format))]
125pub(crate) struct CtrlMsgReqConnectAp {
126 #[noproto(tag = "1")]
127 pub ssid: String<32>,
128 #[noproto(tag = "2")]
129 pub pwd: String<32>,
130 #[noproto(tag = "3")]
131 pub bssid: String<32>,
132 #[noproto(tag = "4")]
133 pub is_wpa3_supported: bool,
134 #[noproto(tag = "5")]
135 pub listen_interval: u32,
136}
137
138#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
139#[cfg_attr(feature = "defmt", derive(defmt::Format))]
140pub(crate) struct CtrlMsgRespConnectAp {
141 #[noproto(tag = "1")]
142 pub resp: u32,
143 #[noproto(tag = "2")]
144 pub mac: String<32>,
145}
146
147#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
148#[cfg_attr(feature = "defmt", derive(defmt::Format))]
149pub(crate) struct CtrlMsgReqGetSoftApConfig {}
150
151#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
152#[cfg_attr(feature = "defmt", derive(defmt::Format))]
153pub(crate) struct CtrlMsgRespGetSoftApConfig {
154 #[noproto(tag = "1")]
155 pub ssid: String<32>,
156 #[noproto(tag = "2")]
157 pub pwd: String<32>,
158 #[noproto(tag = "3")]
159 pub chnl: u32,
160 #[noproto(tag = "4")]
161 pub sec_prot: CtrlWifiSecProt,
162 #[noproto(tag = "5")]
163 pub max_conn: u32,
164 #[noproto(tag = "6")]
165 pub ssid_hidden: bool,
166 #[noproto(tag = "7")]
167 pub bw: u32,
168 #[noproto(tag = "8")]
169 pub resp: u32,
170}
171
172#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
173#[cfg_attr(feature = "defmt", derive(defmt::Format))]
174pub(crate) struct CtrlMsgReqStartSoftAp {
175 #[noproto(tag = "1")]
176 pub ssid: String<32>,
177 #[noproto(tag = "2")]
178 pub pwd: String<32>,
179 #[noproto(tag = "3")]
180 pub chnl: u32,
181 #[noproto(tag = "4")]
182 pub sec_prot: CtrlWifiSecProt,
183 #[noproto(tag = "5")]
184 pub max_conn: u32,
185 #[noproto(tag = "6")]
186 pub ssid_hidden: bool,
187 #[noproto(tag = "7")]
188 pub bw: u32,
189}
190
191#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
192#[cfg_attr(feature = "defmt", derive(defmt::Format))]
193pub(crate) struct CtrlMsgRespStartSoftAp {
194 #[noproto(tag = "1")]
195 pub resp: u32,
196 #[noproto(tag = "2")]
197 pub mac: String<32>,
198}
199
200#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
201#[cfg_attr(feature = "defmt", derive(defmt::Format))]
202pub(crate) struct CtrlMsgReqScanResult {}
203
204#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
205#[cfg_attr(feature = "defmt", derive(defmt::Format))]
206pub(crate) struct CtrlMsgRespScanResult {
207 #[noproto(tag = "1")]
208 pub count: u32,
209 #[noproto(repeated, tag = "2")]
210 pub entries: Vec<ScanResult, 16>,
211 #[noproto(tag = "3")]
212 pub resp: u32,
213}
214
215#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
216#[cfg_attr(feature = "defmt", derive(defmt::Format))]
217pub(crate) struct CtrlMsgReqSoftApConnectedSta {}
218
219#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
220#[cfg_attr(feature = "defmt", derive(defmt::Format))]
221pub(crate) struct CtrlMsgRespSoftApConnectedSta {
222 #[noproto(tag = "1")]
223 pub num: u32,
224 #[noproto(repeated, tag = "2")]
225 pub stations: Vec<ConnectedStaList, 16>,
226 #[noproto(tag = "3")]
227 pub resp: u32,
228}
229
230#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
231#[cfg_attr(feature = "defmt", derive(defmt::Format))]
232pub(crate) struct CtrlMsgReqOtaBegin {}
233
234#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
235#[cfg_attr(feature = "defmt", derive(defmt::Format))]
236pub(crate) struct CtrlMsgRespOtaBegin {
237 #[noproto(tag = "1")]
238 pub resp: u32,
239}
240
241#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
242#[cfg_attr(feature = "defmt", derive(defmt::Format))]
243pub(crate) struct CtrlMsgReqOtaWrite {
244 #[noproto(tag = "1")]
245 pub ota_data: Vec<u8, 1024>,
246}
247
248#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
249#[cfg_attr(feature = "defmt", derive(defmt::Format))]
250pub(crate) struct CtrlMsgRespOtaWrite {
251 #[noproto(tag = "1")]
252 pub resp: u32,
253}
254
255#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
256#[cfg_attr(feature = "defmt", derive(defmt::Format))]
257pub(crate) struct CtrlMsgReqOtaEnd {}
258
259#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
260#[cfg_attr(feature = "defmt", derive(defmt::Format))]
261pub(crate) struct CtrlMsgRespOtaEnd {
262 #[noproto(tag = "1")]
263 pub resp: u32,
264}
265
266#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
268pub(crate) struct CtrlMsgReqVendorIeData {
269 #[noproto(tag = "1")]
270 pub element_id: u32,
271 #[noproto(tag = "2")]
272 pub length: u32,
273 #[noproto(tag = "3")]
274 pub vendor_oui: Vec<u8, 8>,
275 #[noproto(tag = "4")]
276 pub vendor_oui_type: u32,
277 #[noproto(tag = "5")]
278 pub payload: Vec<u8, 64>,
279}
280
281#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
282#[cfg_attr(feature = "defmt", derive(defmt::Format))]
283pub(crate) struct CtrlMsgReqSetSoftApVendorSpecificIe {
284 #[noproto(tag = "1")]
285 pub enable: bool,
286 #[noproto(tag = "2")]
287 pub r#type: CtrlVendorIeType,
288 #[noproto(tag = "3")]
289 pub idx: CtrlVendorIeid,
290 #[noproto(optional, tag = "4")]
291 pub vendor_ie_data: Option<CtrlMsgReqVendorIeData>,
292}
293
294#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
295#[cfg_attr(feature = "defmt", derive(defmt::Format))]
296pub(crate) struct CtrlMsgRespSetSoftApVendorSpecificIe {
297 #[noproto(tag = "1")]
298 pub resp: u32,
299}
300
301#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
302#[cfg_attr(feature = "defmt", derive(defmt::Format))]
303pub(crate) struct CtrlMsgReqSetWifiMaxTxPower {
304 #[noproto(tag = "1")]
305 pub wifi_max_tx_power: u32,
306}
307
308#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
309#[cfg_attr(feature = "defmt", derive(defmt::Format))]
310pub(crate) struct CtrlMsgRespSetWifiMaxTxPower {
311 #[noproto(tag = "1")]
312 pub resp: u32,
313}
314
315#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
316#[cfg_attr(feature = "defmt", derive(defmt::Format))]
317pub(crate) struct CtrlMsgReqGetWifiCurrTxPower {}
318
319#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
320#[cfg_attr(feature = "defmt", derive(defmt::Format))]
321pub(crate) struct CtrlMsgRespGetWifiCurrTxPower {
322 #[noproto(tag = "1")]
323 pub wifi_curr_tx_power: u32,
324 #[noproto(tag = "2")]
325 pub resp: u32,
326}
327
328#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
329#[cfg_attr(feature = "defmt", derive(defmt::Format))]
330pub(crate) struct CtrlMsgReqConfigHeartbeat {
331 #[noproto(tag = "1")]
332 pub enable: bool,
333 #[noproto(tag = "2")]
334 pub duration: u32,
335}
336
337#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
338#[cfg_attr(feature = "defmt", derive(defmt::Format))]
339pub(crate) struct CtrlMsgRespConfigHeartbeat {
340 #[noproto(tag = "1")]
341 pub resp: u32,
342}
343/// * Event structure *
344
345#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
346#[cfg_attr(feature = "defmt", derive(defmt::Format))]
347pub(crate) struct CtrlMsgEventEspInit {
348 #[noproto(tag = "1")]
349 pub init_data: Vec<u8, 64>,
350}
351
352#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
353#[cfg_attr(feature = "defmt", derive(defmt::Format))]
354pub(crate) struct CtrlMsgEventHeartbeat {
355 #[noproto(tag = "1")]
356 pub hb_num: u32,
357}
358
359#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
360#[cfg_attr(feature = "defmt", derive(defmt::Format))]
361pub(crate) struct CtrlMsgEventStationDisconnectFromAp {
362 #[noproto(tag = "1")]
363 pub resp: u32,
364}
365
366#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
367#[cfg_attr(feature = "defmt", derive(defmt::Format))]
368pub(crate) struct CtrlMsgEventStationDisconnectFromEspSoftAp {
369 #[noproto(tag = "1")]
370 pub resp: u32,
371 #[noproto(tag = "2")]
372 pub mac: String<32>,
373}
374
375#[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)]
376#[cfg_attr(feature = "defmt", derive(defmt::Format))]
377pub(crate) struct CtrlMsg {
378 /// msg_type could be req, resp or Event
379 #[noproto(tag = "1")]
380 pub msg_type: CtrlMsgType,
381 /// msg id
382 #[noproto(tag = "2")]
383 pub msg_id: CtrlMsgId,
384 /// union of all msg ids
385 #[noproto(
386 oneof,
387 tags = "101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 301, 302, 303, 304"
388 )]
389 pub payload: Option<CtrlMsgPayload>,
390}
391
392/// union of all msg ids
393#[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)]
394#[cfg_attr(feature = "defmt", derive(defmt::Format))]
395pub(crate) enum CtrlMsgPayload {
396 /// * Requests *
397 #[noproto(tag = "101")]
398 ReqGetMacAddress(CtrlMsgReqGetMacAddress),
399 #[noproto(tag = "102")]
400 ReqSetMacAddress(CtrlMsgReqSetMacAddress),
401 #[noproto(tag = "103")]
402 ReqGetWifiMode(CtrlMsgReqGetMode),
403 #[noproto(tag = "104")]
404 ReqSetWifiMode(CtrlMsgReqSetMode),
405 #[noproto(tag = "105")]
406 ReqScanApList(CtrlMsgReqScanResult),
407 #[noproto(tag = "106")]
408 ReqGetApConfig(CtrlMsgReqGetApConfig),
409 #[noproto(tag = "107")]
410 ReqConnectAp(CtrlMsgReqConnectAp),
411 #[noproto(tag = "108")]
412 ReqDisconnectAp(CtrlMsgReqGetStatus),
413 #[noproto(tag = "109")]
414 ReqGetSoftapConfig(CtrlMsgReqGetSoftApConfig),
415 #[noproto(tag = "110")]
416 ReqSetSoftapVendorSpecificIe(CtrlMsgReqSetSoftApVendorSpecificIe),
417 #[noproto(tag = "111")]
418 ReqStartSoftap(CtrlMsgReqStartSoftAp),
419 #[noproto(tag = "112")]
420 ReqSoftapConnectedStasList(CtrlMsgReqSoftApConnectedSta),
421 #[noproto(tag = "113")]
422 ReqStopSoftap(CtrlMsgReqGetStatus),
423 #[noproto(tag = "114")]
424 ReqSetPowerSaveMode(CtrlMsgReqSetMode),
425 #[noproto(tag = "115")]
426 ReqGetPowerSaveMode(CtrlMsgReqGetMode),
427 #[noproto(tag = "116")]
428 ReqOtaBegin(CtrlMsgReqOtaBegin),
429 #[noproto(tag = "117")]
430 ReqOtaWrite(CtrlMsgReqOtaWrite),
431 #[noproto(tag = "118")]
432 ReqOtaEnd(CtrlMsgReqOtaEnd),
433 #[noproto(tag = "119")]
434 ReqSetWifiMaxTxPower(CtrlMsgReqSetWifiMaxTxPower),
435 #[noproto(tag = "120")]
436 ReqGetWifiCurrTxPower(CtrlMsgReqGetWifiCurrTxPower),
437 #[noproto(tag = "121")]
438 ReqConfigHeartbeat(CtrlMsgReqConfigHeartbeat),
439 /// * Responses *
440 #[noproto(tag = "201")]
441 RespGetMacAddress(CtrlMsgRespGetMacAddress),
442 #[noproto(tag = "202")]
443 RespSetMacAddress(CtrlMsgRespSetMacAddress),
444 #[noproto(tag = "203")]
445 RespGetWifiMode(CtrlMsgRespGetMode),
446 #[noproto(tag = "204")]
447 RespSetWifiMode(CtrlMsgRespSetMode),
448 #[noproto(tag = "205")]
449 RespScanApList(CtrlMsgRespScanResult),
450 #[noproto(tag = "206")]
451 RespGetApConfig(CtrlMsgRespGetApConfig),
452 #[noproto(tag = "207")]
453 RespConnectAp(CtrlMsgRespConnectAp),
454 #[noproto(tag = "208")]
455 RespDisconnectAp(CtrlMsgRespGetStatus),
456 #[noproto(tag = "209")]
457 RespGetSoftapConfig(CtrlMsgRespGetSoftApConfig),
458 #[noproto(tag = "210")]
459 RespSetSoftapVendorSpecificIe(CtrlMsgRespSetSoftApVendorSpecificIe),
460 #[noproto(tag = "211")]
461 RespStartSoftap(CtrlMsgRespStartSoftAp),
462 #[noproto(tag = "212")]
463 RespSoftapConnectedStasList(CtrlMsgRespSoftApConnectedSta),
464 #[noproto(tag = "213")]
465 RespStopSoftap(CtrlMsgRespGetStatus),
466 #[noproto(tag = "214")]
467 RespSetPowerSaveMode(CtrlMsgRespSetMode),
468 #[noproto(tag = "215")]
469 RespGetPowerSaveMode(CtrlMsgRespGetMode),
470 #[noproto(tag = "216")]
471 RespOtaBegin(CtrlMsgRespOtaBegin),
472 #[noproto(tag = "217")]
473 RespOtaWrite(CtrlMsgRespOtaWrite),
474 #[noproto(tag = "218")]
475 RespOtaEnd(CtrlMsgRespOtaEnd),
476 #[noproto(tag = "219")]
477 RespSetWifiMaxTxPower(CtrlMsgRespSetWifiMaxTxPower),
478 #[noproto(tag = "220")]
479 RespGetWifiCurrTxPower(CtrlMsgRespGetWifiCurrTxPower),
480 #[noproto(tag = "221")]
481 RespConfigHeartbeat(CtrlMsgRespConfigHeartbeat),
482 /// * Notifications *
483 #[noproto(tag = "301")]
484 EventEspInit(CtrlMsgEventEspInit),
485 #[noproto(tag = "302")]
486 EventHeartbeat(CtrlMsgEventHeartbeat),
487 #[noproto(tag = "303")]
488 EventStationDisconnectFromAp(CtrlMsgEventStationDisconnectFromAp),
489 #[noproto(tag = "304")]
490 EventStationDisconnectFromEspSoftAp(CtrlMsgEventStationDisconnectFromEspSoftAp),
491}
492
493/// Enums similar to ESP IDF
494#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
495#[repr(u32)]
496#[cfg_attr(feature = "defmt", derive(defmt::Format))]
497pub(crate) enum CtrlVendorIeType {
498 #[default]
499 Beacon = 0,
500 ProbeReq = 1,
501 ProbeResp = 2,
502 AssocReq = 3,
503 AssocResp = 4,
504}
505
506#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
507#[repr(u32)]
508#[cfg_attr(feature = "defmt", derive(defmt::Format))]
509pub(crate) enum CtrlVendorIeid {
510 #[default]
511 Id0 = 0,
512 Id1 = 1,
513}
514
515#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
516#[repr(u32)]
517#[cfg_attr(feature = "defmt", derive(defmt::Format))]
518pub(crate) enum CtrlWifiMode {
519 #[default]
520 None = 0,
521 Sta = 1,
522 Ap = 2,
523 Apsta = 3,
524}
525
526#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
527#[repr(u32)]
528#[cfg_attr(feature = "defmt", derive(defmt::Format))]
529pub(crate) enum CtrlWifiBw {
530 #[default]
531 BwInvalid = 0,
532 Ht20 = 1,
533 Ht40 = 2,
534}
535
536#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
537#[repr(u32)]
538#[cfg_attr(feature = "defmt", derive(defmt::Format))]
539pub(crate) enum CtrlWifiPowerSave {
540 #[default]
541 PsInvalid = 0,
542 MinModem = 1,
543 MaxModem = 2,
544}
545
546/// Wifi Security Settings
547#[allow(missing_docs)]
548#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
549#[repr(u32)]
550#[cfg_attr(feature = "defmt", derive(defmt::Format))]
551pub enum CtrlWifiSecProt {
552 #[default]
553 Open = 0,
554 Wep = 1,
555 WpaPsk = 2,
556 Wpa2Psk = 3,
557 WpaWpa2Psk = 4,
558 Wpa2Enterprise = 5,
559 Wpa3Psk = 6,
560 Wpa2Wpa3Psk = 7,
561}
562
563/// enums for Control path
564#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
565#[repr(u32)]
566#[cfg_attr(feature = "defmt", derive(defmt::Format))]
567pub(crate) enum CtrlStatus {
568 #[default]
569 Connected = 0,
570 NotConnected = 1,
571 NoApFound = 2,
572 ConnectionFail = 3,
573 InvalidArgument = 4,
574 OutOfRange = 5,
575}
576
577#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
578#[repr(u32)]
579#[cfg_attr(feature = "defmt", derive(defmt::Format))]
580pub(crate) enum CtrlMsgType {
581 #[default]
582 MsgTypeInvalid = 0,
583 Req = 1,
584 Resp = 2,
585 Event = 3,
586 MsgTypeMax = 4,
587}
588
589#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)]
590#[repr(u32)]
591#[cfg_attr(feature = "defmt", derive(defmt::Format))]
592pub(crate) enum CtrlMsgId {
593 #[default]
594 MsgIdInvalid = 0,
595 /// * Request Msgs *
596 ReqBase = 100,
597 ReqGetMacAddress = 101,
598 ReqSetMacAddress = 102,
599 ReqGetWifiMode = 103,
600 ReqSetWifiMode = 104,
601 ReqGetApScanList = 105,
602 ReqGetApConfig = 106,
603 ReqConnectAp = 107,
604 ReqDisconnectAp = 108,
605 ReqGetSoftApConfig = 109,
606 ReqSetSoftApVendorSpecificIe = 110,
607 ReqStartSoftAp = 111,
608 ReqGetSoftApConnectedStaList = 112,
609 ReqStopSoftAp = 113,
610 ReqSetPowerSaveMode = 114,
611 ReqGetPowerSaveMode = 115,
612 ReqOtaBegin = 116,
613 ReqOtaWrite = 117,
614 ReqOtaEnd = 118,
615 ReqSetWifiMaxTxPower = 119,
616 ReqGetWifiCurrTxPower = 120,
617 ReqConfigHeartbeat = 121,
618 /// Add new control path command response before Req_Max
619 /// and update Req_Max
620 ReqMax = 122,
621 /// * Response Msgs *
622 RespBase = 200,
623 RespGetMacAddress = 201,
624 RespSetMacAddress = 202,
625 RespGetWifiMode = 203,
626 RespSetWifiMode = 204,
627 RespGetApScanList = 205,
628 RespGetApConfig = 206,
629 RespConnectAp = 207,
630 RespDisconnectAp = 208,
631 RespGetSoftApConfig = 209,
632 RespSetSoftApVendorSpecificIe = 210,
633 RespStartSoftAp = 211,
634 RespGetSoftApConnectedStaList = 212,
635 RespStopSoftAp = 213,
636 RespSetPowerSaveMode = 214,
637 RespGetPowerSaveMode = 215,
638 RespOtaBegin = 216,
639 RespOtaWrite = 217,
640 RespOtaEnd = 218,
641 RespSetWifiMaxTxPower = 219,
642 RespGetWifiCurrTxPower = 220,
643 RespConfigHeartbeat = 221,
644 /// Add new control path command response before Resp_Max
645 /// and update Resp_Max
646 RespMax = 222,
647 /// * Event Msgs *
648 EventBase = 300,
649 EventEspInit = 301,
650 EventHeartbeat = 302,
651 EventStationDisconnectFromAp = 303,
652 EventStationDisconnectFromEspSoftAp = 304,
653 /// Add new control path command notification before Event_Max
654 /// and update Event_Max
655 EventMax = 305,
656}