ergot_base/interface_manager/
std_utils.rs1use crate::{Address, FrameKind, HeaderSeq, Key};
2
3pub(crate) struct OwnedFrame {
4 pub(crate) hdr: HeaderSeq,
5 pub(crate) body: Vec<u8>,
6}
7
8#[derive(Debug, PartialEq)]
9pub enum ReceiverError {
10 SocketClosed,
11}
12
13pub(crate) fn ser_frame(frame: OwnedFrame) -> Vec<u8> {
14 let dst_any = frame.hdr.dst.port_id == 0;
15 let src = frame.hdr.src.as_u32();
16 let dst = frame.hdr.dst.as_u32();
17 let seq = frame.hdr.seq_no;
18
19 let mut out = vec![];
20 out.extend_from_slice(&postcard::to_stdvec(&src).unwrap());
23 out.extend_from_slice(&postcard::to_stdvec(&dst).unwrap());
24 out.push(frame.hdr.kind.0);
25 if dst_any {
26 let key = frame.hdr.key.unwrap();
27 out.extend_from_slice(&key.0);
28 }
29
30 out.extend_from_slice(&postcard::to_stdvec(&seq).unwrap());
31 out.extend_from_slice(&frame.body);
32 let mut out = cobs::encode_vec(&out);
33 out.push(0);
34 out
35}
36
37pub(crate) fn de_frame(remain: &[u8]) -> Option<OwnedFrame> {
38 let (src_word, remain) = postcard::take_from_bytes::<u32>(remain).ok()?;
39 let src = Address::from_word(src_word);
40 let (dst_word, remain) = postcard::take_from_bytes::<u32>(remain).ok()?;
41 let dst = Address::from_word(dst_word);
42 let (kind, remain) = remain.split_first()?;
43 let kind = FrameKind(*kind);
44 let (key, remain) = if dst.port_id == 0 {
45 if remain.len() < 8 {
46 return None;
47 }
48 let (keyb, remain) = remain.split_at(8);
49 let mut buf = [0u8; 8];
50 buf.copy_from_slice(keyb);
51 (Some(Key(buf)), remain)
52 } else {
53 (None, remain)
54 };
55
56 let (seq, remain) = postcard::take_from_bytes::<u16>(remain).ok()?;
57 let body = remain.to_vec();
58
59 Some(OwnedFrame {
60 hdr: HeaderSeq {
61 src,
62 dst,
63 seq_no: seq,
64 key,
65 kind,
66 },
67 body,
68 })
69}
70
71pub(crate) mod acc {
72 pub struct CobsAccumulator {
75 buf: Box<[u8]>,
76 idx: usize,
77 }
78
79 pub enum FeedResult<'input, 'buf> {
81 Consumed,
83
84 OverFull(&'input [u8]),
86
87 DeserError(&'input [u8]),
90
91 Success {
92 data: &'buf [u8],
94
95 remaining: &'input [u8],
97 },
98 }
99
100 impl CobsAccumulator {
101 pub fn new(sz: usize) -> Self {
103 CobsAccumulator {
104 buf: vec![0u8; sz].into_boxed_slice(),
105 idx: 0,
106 }
107 }
108
109 pub fn feed_raw<'me, 'input>(
116 &'me mut self,
117 input: &'input [u8],
118 ) -> FeedResult<'input, 'me> {
119 if input.is_empty() {
120 return FeedResult::Consumed;
121 }
122
123 let zero_pos = input.iter().position(|&i| i == 0);
124 let max_len = self.buf.len();
125
126 if let Some(n) = zero_pos {
127 let (take, release) = input.split_at(n + 1);
131
132 if (self.idx + take.len()) <= max_len {
137 self.extend_unchecked(take);
139
140 let retval = match cobs::decode_in_place(&mut self.buf[..self.idx]) {
141 Ok(ct) => FeedResult::Success {
142 data: &self.buf[..ct],
143 remaining: release,
144 },
145 Err(_) => FeedResult::DeserError(release),
146 };
147 self.idx = 0;
148 retval
149 } else {
150 self.idx = 0;
151 FeedResult::OverFull(release)
152 }
153 } else {
154 if (self.idx + input.len()) > max_len {
156 let new_start = max_len - self.idx;
158 self.idx = 0;
159 FeedResult::OverFull(&input[new_start..])
160 } else {
161 self.extend_unchecked(input);
163 FeedResult::Consumed
164 }
165 }
166 }
167
168 fn extend_unchecked(&mut self, input: &[u8]) {
174 let new_end = self.idx + input.len();
175 self.buf[self.idx..new_end].copy_from_slice(input);
176 self.idx = new_end;
177 }
178 }
179}