1use defmt::{Format, println};
6use heapless::Vec;
7use micropb::{MessageEncode, PbEncoder};
8use num_enum::TryFromPrimitive;
9
10use crate::{EspError, header::build_frame, proto_data::RpcId, transport::{RPC_EP_NAME_EVT, RPC_EP_NAME_RSP}, RpcP, TX_BUF};
11
12pub(crate) const MAX_RPC_SIZE: usize = 300;
13pub(crate) const RPC_MIN_SIZE: usize = 10;
14
15
16#[derive(Clone, Copy, Format)]
18#[repr(u8)]
19pub enum InterfaceType {
20 Station = 0,
21 Ap = 1,
22}
23
24#[derive(Format)]
26pub struct Rpc {
27 pub msg_type: RpcType,
29 pub msg_id: RpcId,
31 pub uid: u32,
33 }
36
37impl Rpc {
38 pub fn new_req(msg_id: RpcId, uid: u32) -> Self {
39 Self {
40 msg_type: RpcType::Req,
41 msg_id,
42 uid,
43 }
44 }
45
46 pub fn to_bytes(&self, buf: &mut [u8], data: &[u8]) -> usize {
48 let mut i = 0;
49 let data_len = data.len();
50
51 write_rpc(buf, 1, WireType::Varint, self.msg_type as u64, &mut i);
53 write_rpc(buf, 2, WireType::Varint, self.msg_id as u64, &mut i);
54 write_rpc(buf, 3, WireType::Varint, self.uid as u64, &mut i);
55
56 write_rpc(
60 buf,
61 self.msg_id as u16,
62 WireType::Len,
63 data_len as u64,
64 &mut i,
65 );
66
67 buf[i..i + data_len].copy_from_slice(data);
68 i += data_len;
69
70 i
71 }
72
73 pub fn from_bytes(buf: &[u8]) -> Result<(Self, usize, usize), EspError> {
75 let msg_type = buf[1].try_into().map_err(|e| EspError::InvalidData)?;
76
77 let (rpc_id, rpc_id_size) = decode_varint(&buf[3..])?;
78 let msg_id = (rpc_id as u16)
79 .try_into()
80 .map_err(|e| EspError::InvalidData)?;
81
82 let mut i = 4 + rpc_id_size;
84
85 let (uid, uid_size) = decode_varint(&buf[i..])?;
86 i += uid_size;
87
88 let result = Self {
89 msg_type,
90 msg_id,
91 uid: uid as u32,
92 };
93
94
95 let (_data_tag, data_tag_size) = decode_varint(&buf[i..])?;
96 i += data_tag_size;
97
98 let (data_len, data_len_size) = decode_varint(&buf[i..])?;
99 i += data_len_size;
100
101 Ok((result, i, data_len as usize))
102 }
103}
104
105#[derive(Clone, Copy, PartialEq, TryFromPrimitive)]
107#[repr(u8)]
108pub enum WireType {
109 Varint = 0,
111 I64 = 1,
113 Len = 2,
115 I32 = 5,
117}
118
119#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Format)]
120#[repr(u8)]
121pub(crate) enum Rpc_WifiBw {
123 BW_Invalid = 0,
124 HT20 = 1,
125 HT40 = 2,
126}
127
128#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Format)]
129#[repr(u8)]
130pub(crate) enum Rpc_WifiPowerSave {
132 PS_Invalid = 0,
133 MIN_MODEM = 1,
134 MAX_MODEM = 2,
135}
136
137#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Format)]
138#[repr(u8)]
139pub(crate) enum Rpc_WifiSecProt {
141 Open = 0,
142 WEP = 1,
143 WPA_PSK = 2,
144 WPA2_PSK = 3,
145 WPA_WPA2_PSK = 4,
146 WPA2_ENTERPRISE = 5,
147 WPA3_PSK = 6,
148 WPA2_WPA3_PSK = 7,
149}
150
151#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Format)]
152#[repr(u8)]
153pub(crate) enum Rpc_Status {
155 Connected = 0,
156 Not_Connected = 1,
157 No_AP_Found = 2,
158 Connection_Fail = 3,
159 Invalid_Argument = 4,
160 Out_Of_Range = 5,
161}
162
163#[derive(Clone, Copy, PartialEq, TryFromPrimitive, Format)]
164#[repr(u8)]
165pub enum RpcType {
168 MsgType_Invalid = 0,
169 Req = 1,
170 Resp = 2,
171 Event = 3,
172 MsgType_Max = 4,
173}
174
175#[derive(Clone, Copy, PartialEq, TryFromPrimitive)]
176#[repr(u8)]
177pub(crate) enum EndpointType {
179 EndpointName = 0x01,
181 Data = 0x02,
183}
184
185#[derive(Clone, Copy, PartialEq, TryFromPrimitive)]
186#[repr(u8)]
187pub(crate) enum RpcEndpoint {
191 CtrlResp,
192 CtrlEvent,
193}
194
195impl RpcEndpoint {
196 pub fn as_bytes(&self) -> &'static [u8] {
197 match self {
198 Self::CtrlResp => RPC_EP_NAME_RSP,
200 Self::CtrlEvent => RPC_EP_NAME_EVT,
202 }
203 .as_bytes()
204 }
205}
206
207pub fn setup_rpc(frame: &mut [u8], rpc: &Rpc, data: &[u8]) -> usize {
211 let mut rpc_buf = [0; MAX_RPC_SIZE];
213
214 let mut i = 0;
215 i += rpc.to_bytes(&mut rpc_buf, data);
216
217 build_frame(frame, &rpc_buf[..i])
218}
219
220pub fn setup_rpc_proto(frame: &mut [u8], message: RpcP) -> usize {
223 let mut rpc_buf = Vec::<u8, MAX_RPC_SIZE>::new();
224
225 let mut encoder = PbEncoder::new(&mut rpc_buf);
226 message.encode(&mut encoder).unwrap();
227
228 let i = build_frame(frame, &rpc_buf[..message.compute_size()]);
229
230 println!("RCP data from .proto: {:?}", &rpc_buf[..message.compute_size()]);
231
232 i
233}
234
235pub fn write_rpc_proto<W>(mut write: W, msg: RpcP) -> Result<(), EspError>
237where
238 W: FnMut(&[u8]) -> Result<(), EspError>,
239{
240 unsafe {
241 let frame_len = setup_rpc_proto(&mut TX_BUF, msg);
242 write(&TX_BUF[..frame_len])?;
243 }
244
245 Ok(())
246}
247
248pub(crate) fn write_rpc(
251 buf: &mut [u8],
252 field: u16,
253 wire_type: WireType,
254 val: u64,
255 i: &mut usize,
256) {
257 let tag = make_tag(field, wire_type);
258 *i += encode_varint(tag as u64, &mut buf[*i..]);
259 *i += encode_varint(val, &mut buf[*i..]);
260}
261
262
263pub(crate) fn make_tag(field: u16, wire_type: WireType) -> u16 {
265 (field << 3) | (wire_type as u16)
266}
267
268pub(crate) fn encode_varint(mut v: u64, out: &mut [u8]) -> usize {
271 let mut idx = 0;
272 loop {
273 let byte = (v & 0x7F) as u8;
274 v >>= 7;
275 if v == 0 {
276 out[idx] = byte; idx += 1;
278 break;
279 } else {
280 out[idx] = byte | 0x80; idx += 1;
282 }
283 }
284 idx
285}
286
287pub(crate) fn decode_varint(input: &[u8]) -> Result<(u64, usize), EspError> {
290 let mut val = 0u64;
291 let mut shift = 0;
292 for (idx, &byte) in input.iter().enumerate() {
293 val |= ((byte & 0x7F) as u64) << shift;
294 if byte & 0x80 == 0 {
295 return Ok((val, idx + 1));
296 }
297 shift += 7;
298 }
299
300 Err(EspError::InvalidData)
301}