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(&mut self, hdr: &Header, data: &[u8]) -> Result<(), InterfaceSendError>;
94}
95
96impl InterfaceSendError {
97 pub fn to_error(&self) -> ProtocolError {
98 match self {
99 InterfaceSendError::DestinationLocal => ProtocolError::ISE_DESTINATION_LOCAL,
100 InterfaceSendError::NoRouteToDest => ProtocolError::ISE_NO_ROUTE_TO_DEST,
101 InterfaceSendError::InterfaceFull => ProtocolError::ISE_INTERFACE_FULL,
102 InterfaceSendError::PlaceholderOhNo => ProtocolError::ISE_PLACEHOLDER_OH_NO,
103 InterfaceSendError::AnyPortMissingKey => ProtocolError::ISE_ANY_PORT_MISSING_KEY,
104 InterfaceSendError::TtlExpired => ProtocolError::ISE_TTL_EXPIRED,
105 }
106 }
107}
108
109pub mod wire_frames {
110 use log::warn;
111 use postcard::{Serializer, ser_flavors};
112 use serde::{Deserialize, Serialize};
113
114 use crate::{Address, FrameKind, HeaderSeq, Key, ProtocolError};
115
116 use super::BorrowedFrame;
117
118 #[derive(Serialize, Deserialize, Debug)]
119 pub struct CommonHeader {
120 pub src: u32,
121 pub dst: u32,
122 pub seq_no: u16,
123 pub kind: u8,
124 pub ttl: u8,
125 }
126
127 pub enum PartialDecodeTail<'a> {
128 Specific(&'a [u8]),
129 AnyAll { key: Key, body: &'a [u8] },
130 Err(ProtocolError),
131 }
132
133 pub struct PartialDecode<'a> {
134 pub hdr: CommonHeader,
135 pub tail: PartialDecodeTail<'a>,
136 }
137
138 pub(crate) fn decode_frame_partial(data: &[u8]) -> Option<PartialDecode<'_>> {
139 let (common, remain) = postcard::take_from_bytes::<CommonHeader>(data).ok()?;
140 let is_err = common.kind == FrameKind::PROTOCOL_ERROR.0;
141 let any_all = [0, 255].contains(&Address::from_word(common.dst).port_id);
142
143 match (is_err, any_all) {
144 (true, true) => {
146 warn!("Rejecting any/all protocol error message");
147 None
148 }
149 (true, false) => {
150 let (err, remain) = postcard::take_from_bytes::<ProtocolError>(remain).ok()?;
152 if !remain.is_empty() {
153 warn!("Excess data, rejecting");
154 return None;
155 }
156 Some(PartialDecode {
157 hdr: common,
158 tail: PartialDecodeTail::Err(err),
159 })
160 }
161 (false, true) => {
162 let (key, remain) = postcard::take_from_bytes::<Key>(remain).ok()?;
163 Some(PartialDecode {
164 hdr: common,
165 tail: PartialDecodeTail::AnyAll { key, body: remain },
166 })
167 }
168 (false, false) => Some(PartialDecode {
169 hdr: common,
170 tail: PartialDecodeTail::Specific(remain),
171 }),
172 }
173 }
174
175 pub(crate) fn encode_frame_ty<F, T>(
178 flav: F,
179 hdr: &CommonHeader,
180 key: Option<&Key>,
181 body: &T,
182 ) -> Result<F::Output, ()>
183 where
184 F: ser_flavors::Flavor,
185 T: Serialize,
186 {
187 let mut serializer = Serializer { output: flav };
188 hdr.serialize(&mut serializer).map_err(drop)?;
189
190 if let Some(key) = key {
191 serializer.output.try_extend(&key.0).map_err(drop)?;
192 }
193
194 body.serialize(&mut serializer).map_err(drop)?;
195 serializer.output.finalize().map_err(drop)
196 }
197
198 pub(crate) fn encode_frame_raw<F>(
201 flav: F,
202 hdr: &CommonHeader,
203 key: Option<&Key>,
204 body: &[u8],
205 ) -> Result<F::Output, ()>
206 where
207 F: ser_flavors::Flavor,
208 {
209 let mut serializer = Serializer { output: flav };
210 hdr.serialize(&mut serializer).map_err(drop)?;
211
212 if let Some(key) = key {
213 serializer.output.try_extend(&key.0).map_err(drop)?;
214 }
215
216 serializer.output.try_extend(body).map_err(drop)?;
217 serializer.output.finalize().map_err(drop)
218 }
219
220 pub(crate) fn encode_frame_err<F>(
221 flav: F,
222 hdr: &CommonHeader,
223 err: ProtocolError,
224 ) -> Result<F::Output, ()>
225 where
226 F: ser_flavors::Flavor,
227 {
228 let mut serializer = Serializer { output: flav };
229 hdr.serialize(&mut serializer).map_err(drop)?;
230 err.serialize(&mut serializer).map_err(drop)?;
231 serializer.output.finalize().map_err(drop)
232 }
233
234 #[allow(dead_code)]
235 pub(crate) fn de_frame(remain: &[u8]) -> Option<BorrowedFrame<'_>> {
236 let res = decode_frame_partial(remain)?;
237
238 let key;
239 let body = match res.tail {
240 PartialDecodeTail::Specific(body) => {
241 key = None;
242 Ok(body)
243 }
244 PartialDecodeTail::AnyAll { key: skey, body } => {
245 key = Some(skey);
246 Ok(body)
247 }
248 PartialDecodeTail::Err(protocol_error) => {
249 key = None;
250 Err(protocol_error)
251 }
252 };
253
254 let CommonHeader {
255 src,
256 dst,
257 seq_no,
258 kind,
259 ttl,
260 } = res.hdr;
261
262 Some(BorrowedFrame {
263 hdr: HeaderSeq {
264 src: Address::from_word(src),
265 dst: Address::from_word(dst),
266 seq_no,
267 key,
268 kind: FrameKind(kind),
269 ttl,
270 },
271 body,
272 })
273 }
274}
275
276#[allow(dead_code)]
277pub(crate) struct BorrowedFrame<'a> {
278 pub(crate) hdr: HeaderSeq,
279 pub(crate) body: Result<&'a [u8], ProtocolError>,
280}