1#![no_std]
2#![allow(dead_code)]
3#![allow(non_camel_case_types)]
4#![allow(static_mut_refs)]
5
6mod header;
9pub mod proto_data;
10pub mod rf;
11mod rpc;
12mod transport;
13
14mod esp_hosted_proto;
15mod esp_errors;
16
17use micropb::{MessageDecode, MessageEncode, PbDecoder, PbEncoder};
18
19use defmt::{Format, println};
20
21pub use header::PayloadHeader;
22use num_enum::TryFromPrimitive;
23pub use proto_data::*;
24pub use rpc::InterfaceType;
25pub use rf::*;
26
27pub use esp_hosted_proto::Rpc as RpcP;
28pub use esp_hosted_proto::RpcId as RpcIdP;
29pub use esp_hosted_proto::RpcType as RpcTypeP;
30pub use esp_hosted_proto::*;
31
32
33pub use crate::header::HEADER_SIZE;
34use crate::{
35 header::{PL_HEADER_SIZE},
36 proto_data::RpcId,
37 rpc::{RPC_MIN_SIZE, Rpc, setup_rpc},
38};
39pub use crate::rpc::*;
42
43#[macro_export]
44macro_rules! parse_le {
45 ($bytes:expr, $t:ty, $range:expr) => {{ <$t>::from_le_bytes($bytes[$range].try_into().unwrap()) }};
46}
47
48#[macro_export]
49macro_rules! copy_le {
50 ($dest:expr, $src:expr, $range:expr) => {{ $dest[$range].copy_from_slice(&$src.to_le_bytes()) }};
51}
52
53const AP_BUF_MAX: usize = 100;
54const BLE_BUF_MAX: usize = 100;
55
56const ESP_ERR_HOSTED_BASE: u16 = 0x2f00;
57
58const MORE_FRAGMENT: u8 = 1 << 0; const FRAME_LEN_TX: usize = HEADER_SIZE + RPC_MIN_SIZE + 300; static mut TX_BUF: [u8; FRAME_LEN_TX] = [0; FRAME_LEN_TX];
64#[derive(Format)]
68pub enum EspError {
69 Comms,
73 UnexpectedResponse(u8),
74 CrcMismatch,
75 Timeout,
76 InvalidData,
77 }
80
81pub fn cfg_heartbeat<W>(mut write: W, uid: u32, cfg: &RpcReqConfigHeartbeat) -> Result<(), EspError>
90where
92 W: FnMut(&[u8]) -> Result<(), EspError>,
93{
94 let rpc = Rpc::new_req(RpcId::ReqConfigHeartbeat, uid);
95
96 let mut data = [0; 5]; let data_size = cfg.to_bytes(&mut data);
98
99 unsafe {
100 let frame_len = setup_rpc(&mut TX_BUF, &rpc, &data[..data_size]);
101 write(&TX_BUF[..frame_len])?;
102 }
103
104 Ok(())
105}
106
107pub struct ParsedMsg<'a> {
108 pub header: PayloadHeader,
109 pub rpc: Rpc,
110 pub data: &'a[u8],
111 pub rpc_proto: RpcP,
112}
113
114pub fn parse_msg(buf: &[u8]) -> Result<ParsedMsg, EspError> {
118 let header = PayloadHeader::from_bytes(&buf[..HEADER_SIZE])?;
119 let total_size = header.len as usize + PL_HEADER_SIZE;
120
121 if total_size > buf.len() {
122 return Err(EspError::InvalidData);
123 }
124
125 let rpc_buf = &buf[HEADER_SIZE..total_size];
126
127 let (rpc, data_start_i, data_len_rpc) = Rpc::from_bytes(rpc_buf)?;
128
129 let mut decoder = PbDecoder::new(rpc_buf);
131
132 let mut rpc_proto = RpcP::default();
133 rpc_proto.decode(&mut decoder, rpc_buf.len()).map_err(|_| EspError::InvalidData)?;
134
135 let data = &rpc_buf[data_start_i..];
136
137 if data.len() == 2 {
138 let err = decode_varint(data)?.0 as u16;
141
142 }
146
147 Ok(ParsedMsg { header, rpc, data, rpc_proto })
148}