ergot_base/interface_manager/
mod.rs1use crate::{Header, HeaderSeq, ProtocolError};
43use serde::Serialize;
44
45pub mod cobs_stream;
46pub mod framed_stream;
47pub mod null;
48
49#[cfg(feature = "embassy-usb-v0_4")]
50pub mod eusb_0_4_client;
51
52#[cfg(feature = "nusb-v0_1")]
53pub mod nusb_0_1_router;
54
55#[cfg(feature = "std")]
56pub mod std_tcp_client;
57#[cfg(feature = "std")]
58pub mod std_tcp_router;
59#[cfg(feature = "std")]
60pub mod std_utils;
61
62#[derive(Debug, PartialEq, Eq)]
63#[non_exhaustive]
64pub enum InterfaceSendError {
65 DestinationLocal,
67 NoRouteToDest,
69 InterfaceFull,
72 PlaceholderOhNo,
74 AnyPortMissingKey,
76 TtlExpired,
78}
79
80pub trait ConstInit {
81 const INIT: Self;
82}
83
84pub trait InterfaceManager {
91 fn send<T: Serialize>(&mut self, hdr: &Header, data: &T) -> Result<(), InterfaceSendError>;
92 fn send_err(&mut self, hdr: &Header, err: ProtocolError) -> Result<(), InterfaceSendError>;
93 fn send_raw(
94 &mut self,
95 hdr: &Header,
96 hdr_raw: &[u8],
97 data: &[u8],
98 ) -> Result<(), InterfaceSendError>;
99}
100
101impl InterfaceSendError {
102 pub fn to_error(&self) -> ProtocolError {
103 match self {
104 InterfaceSendError::DestinationLocal => ProtocolError::ISE_DESTINATION_LOCAL,
105 InterfaceSendError::NoRouteToDest => ProtocolError::ISE_NO_ROUTE_TO_DEST,
106 InterfaceSendError::InterfaceFull => ProtocolError::ISE_INTERFACE_FULL,
107 InterfaceSendError::PlaceholderOhNo => ProtocolError::ISE_PLACEHOLDER_OH_NO,
108 InterfaceSendError::AnyPortMissingKey => ProtocolError::ISE_ANY_PORT_MISSING_KEY,
109 InterfaceSendError::TtlExpired => ProtocolError::ISE_TTL_EXPIRED,
110 }
111 }
112}
113
114pub mod wire_frames {
115 use log::warn;
116 use postcard::{Serializer, ser_flavors};
117 use serde::{Deserialize, Serialize};
118
119 use crate::{
120 Address, AnyAllAppendix, FrameKind, HeaderSeq, Key, ProtocolError, nash::NameHash,
121 };
122
123 use super::BorrowedFrame;
124
125 #[derive(Serialize, Deserialize, Debug)]
126 pub struct CommonHeader {
127 pub src: u32,
128 pub dst: u32,
129 pub seq_no: u16,
130 pub kind: u8,
131 pub ttl: u8,
132 }
133
134 pub enum PartialDecodeTail<'a> {
135 Specific(&'a [u8]),
136 AnyAll {
137 apdx: AnyAllAppendix,
138 body: &'a [u8],
139 },
140 Err(ProtocolError),
141 }
142
143 pub struct PartialDecode<'a> {
144 pub hdr: CommonHeader,
145 pub hdr_raw: &'a [u8],
146 pub tail: PartialDecodeTail<'a>,
147 }
148
149 pub(crate) fn decode_frame_partial(data: &[u8]) -> Option<PartialDecode<'_>> {
150 let (common, remain) = postcard::take_from_bytes::<CommonHeader>(data).ok()?;
151 let is_err = common.kind == FrameKind::PROTOCOL_ERROR.0;
152 let any_all = [0, 255].contains(&Address::from_word(common.dst).port_id);
153
154 match (is_err, any_all) {
155 (true, true) => {
157 warn!("Rejecting any/all protocol error message");
158 None
159 }
160 (true, false) => {
161 let hdr_raw_len = data.len() - remain.len();
162 let hdr_raw = &data[..hdr_raw_len];
163 let (err, remain) = postcard::take_from_bytes::<ProtocolError>(remain).ok()?;
165 if !remain.is_empty() {
166 warn!("Excess data, rejecting");
167 return None;
168 }
169 Some(PartialDecode {
170 hdr: common,
171 tail: PartialDecodeTail::Err(err),
172 hdr_raw,
173 })
174 }
175 (false, true) => {
176 let (key, remain) = postcard::take_from_bytes::<Key>(remain).ok()?;
177 let (nash, remain) = postcard::take_from_bytes::<u32>(remain).ok()?;
178 let hdr_raw_len = data.len() - remain.len();
179 let hdr_raw = &data[..hdr_raw_len];
180
181 Some(PartialDecode {
182 hdr: common,
183 tail: PartialDecodeTail::AnyAll {
184 apdx: AnyAllAppendix {
185 key,
186 nash: NameHash::from_u32(nash),
187 },
188 body: remain,
189 },
190 hdr_raw,
191 })
192 }
193 (false, false) => {
194 let hdr_raw_len = data.len() - remain.len();
195 let hdr_raw = &data[..hdr_raw_len];
196
197 Some(PartialDecode {
198 hdr: common,
199 tail: PartialDecodeTail::Specific(remain),
200 hdr_raw,
201 })
202 }
203 }
204 }
205
206 pub fn encode_frame_ty<F, T>(
209 flav: F,
210 hdr: &CommonHeader,
211 apdx: Option<&AnyAllAppendix>,
212 body: &T,
213 ) -> Result<F::Output, ()>
214 where
215 F: ser_flavors::Flavor,
216 T: Serialize,
217 {
218 let mut serializer = Serializer { output: flav };
219 hdr.serialize(&mut serializer).map_err(drop)?;
220
221 if let Some(app) = apdx {
222 serializer.output.try_extend(&app.key.0).map_err(drop)?;
223 let val: u32 = app.nash.as_ref().map(NameHash::to_u32).unwrap_or(0);
224 val.serialize(&mut serializer).map_err(drop)?;
225 }
226
227 body.serialize(&mut serializer).map_err(drop)?;
228 serializer.output.finalize().map_err(drop)
229 }
230
231 pub fn encode_frame_raw<F>(
234 flav: F,
235 hdr: &CommonHeader,
236 key: Option<&Key>,
237 body: &[u8],
238 ) -> Result<F::Output, ()>
239 where
240 F: ser_flavors::Flavor,
241 {
242 let mut serializer = Serializer { output: flav };
243 hdr.serialize(&mut serializer).map_err(drop)?;
244
245 if let Some(key) = key {
246 serializer.output.try_extend(&key.0).map_err(drop)?;
247 }
248
249 serializer.output.try_extend(body).map_err(drop)?;
250 serializer.output.finalize().map_err(drop)
251 }
252
253 pub fn encode_frame_err<F>(
254 flav: F,
255 hdr: &CommonHeader,
256 err: ProtocolError,
257 ) -> Result<F::Output, ()>
258 where
259 F: ser_flavors::Flavor,
260 {
261 let mut serializer = Serializer { output: flav };
262 hdr.serialize(&mut serializer).map_err(drop)?;
263 err.serialize(&mut serializer).map_err(drop)?;
264 serializer.output.finalize().map_err(drop)
265 }
266
267 pub fn de_frame(remain: &[u8]) -> Option<BorrowedFrame<'_>> {
268 let res = decode_frame_partial(remain)?;
269
270 let app;
271 let body = match res.tail {
272 PartialDecodeTail::Specific(body) => {
273 app = None;
274 Ok(body)
275 }
276 PartialDecodeTail::AnyAll { apdx, body } => {
277 app = Some(apdx);
278 Ok(body)
279 }
280 PartialDecodeTail::Err(protocol_error) => {
281 app = None;
282 Err(protocol_error)
283 }
284 };
285
286 let CommonHeader {
287 src,
288 dst,
289 seq_no,
290 kind,
291 ttl,
292 } = res.hdr;
293
294 Some(BorrowedFrame {
295 hdr: HeaderSeq {
296 src: Address::from_word(src),
297 dst: Address::from_word(dst),
298 seq_no,
299 any_all: app,
300 kind: FrameKind(kind),
301 ttl,
302 },
303 body,
304 hdr_raw: res.hdr_raw,
305 })
306 }
307}
308
309#[allow(dead_code)]
310pub struct BorrowedFrame<'a> {
311 pub hdr: HeaderSeq,
312 pub hdr_raw: &'a [u8],
313 pub body: Result<&'a [u8], ProtocolError>,
314}