1#![no_std]
2#![allow(dead_code)]
3#![allow(non_camel_case_types)]
4#![allow(static_mut_refs)]
5
6mod header;
26pub mod proto_data;
27mod rpc;
28mod transport;
29pub mod wifi;
30
31pub mod ble;
32mod esp_errors;
33pub mod proto;
34mod util;
35
36use defmt::{Format, println};
38pub use esp_errors::EspCode;
39pub use header::{PayloadHeader, build_frame_ble};
40use micropb::{MessageDecode, PbDecoder};
41pub use proto::{Rpc as RpcP, RpcId as RpcIdP, RpcType as RpcTypeP};
42pub use proto_data::RpcId;
43
44pub use crate::rpc::*;
45use crate::{
46 header::{HEADER_SIZE, InterfaceType, PL_HEADER_SIZE},
47 proto_data::RpcReqConfigHeartbeat,
48};
49
50#[macro_export]
51macro_rules! parse_le {
52 ($bytes:expr, $t:ty, $range:expr) => {{ <$t>::from_le_bytes($bytes[$range].try_into().unwrap()) }};
53}
54
55#[macro_export]
56macro_rules! copy_le {
57 ($dest:expr, $src:expr, $range:expr) => {{ $dest[$range].copy_from_slice(&$src.to_le_bytes()) }};
58}
59
60const AP_BUF_MAX: usize = 100;
61const BLE_BUF_MAX: usize = 100;
62
63const ESP_ERR_HOSTED_BASE: u16 = 0x2f00;
64
65#[derive(Format)]
67pub enum EspError {
68 Comms,
72 UnexpectedResponse(u8),
73 CrcMismatch,
74 Timeout,
75 InvalidData,
76 Proto,
77 Capacity,
78 Esp(EspCode),
80}
81
82pub fn cfg_heartbeat<W>(
91 buf: &mut [u8],
92 mut write: W,
93 uid: u32,
94 cfg: &RpcReqConfigHeartbeat,
95) -> Result<(), EspError>
96where
98 W: FnMut(&[u8]) -> Result<(), EspError>,
99{
100 let rpc = Rpc::new_req(RpcId::ReqConfigHeartbeat, uid);
101
102 let mut data = [0; 5]; let data_size = cfg.to_bytes(&mut data);
104
105 let frame_len = setup_rpc(buf, &rpc, &data[..data_size]);
107 write(&buf[..frame_len])?;
108 Ok(())
111}
112
113pub struct WifiMsg<'a> {
114 pub header: PayloadHeader,
115 pub rpc: Rpc,
116 pub data: &'a [u8],
117 pub rpc_parsed: RpcP,
119}
120
121pub struct HciMsg<'a> {
122 pub data: &'a [u8],
123}
124
125pub enum MsgParsed<'a> {
126 Wifi(WifiMsg<'a>),
127 Hci(HciMsg<'a>),
128}
129
130pub fn parse_msg(buf: &[u8]) -> Result<MsgParsed, EspError> {
133 let header = PayloadHeader::from_bytes(&buf[..HEADER_SIZE])?;
134 let total_size = header.len as usize + PL_HEADER_SIZE;
135
136 if total_size >= buf.len() {
137 return Err(EspError::Capacity);
138 }
139
140 if header.if_type == InterfaceType::Hci {
141 return Ok(MsgParsed::Hci(HciMsg {
142 data: &buf[PL_HEADER_SIZE..],
143 }));
144 }
145
146 if HEADER_SIZE >= total_size {
147 println!("Error: Invalid RPC packet: {:?}", buf[0..24]);
148 return Err(EspError::InvalidData);
149 }
150
151 let rpc_buf = &buf[HEADER_SIZE..total_size];
152 let (rpc, data_start_i, _data_len_rpc) = Rpc::from_bytes(rpc_buf)?;
153 let data = &rpc_buf[data_start_i..];
154
155 let mut decoder = PbDecoder::new(rpc_buf);
157 let mut rpc_parsed = RpcP::default();
158
159 rpc_parsed
160 .decode(&mut decoder, rpc_buf.len())
161 .map_err(|_| EspError::Proto)?;
162
163 Ok(MsgParsed::Wifi(WifiMsg {
164 header,
165 rpc,
166 data,
167 rpc_parsed,
168 }))
169}