ergot_base/interface_manager/
cobs_stream.rs1use bbq2::{prod_cons::stream::StreamProducer, traits::bbqhdl::BbqHandle};
2use postcard::ser_flavors::{self, Flavor};
3use serde::Serialize;
4
5use crate::{
6 AnyAllAppendix, FrameKind, ProtocolError,
7 wire_frames::{self, CommonHeader},
8};
9
10pub struct Interface<Q>
11where
12 Q: BbqHandle,
13{
14 pub(crate) mtu: u16,
15 pub(crate) prod: StreamProducer<Q>,
16}
17
18#[allow(clippy::result_unit_err)] impl<Q> Interface<Q>
20where
21 Q: BbqHandle,
22{
23 pub fn send_ty<T: Serialize>(
24 &mut self,
25 hdr: &CommonHeader,
26 apdx: Option<&AnyAllAppendix>,
27 body: &T,
28 ) -> Result<(), ()> {
29 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
30
31 if is_err {
32 return Err(());
34 }
35
36 let max_len = cobs::max_encoding_length(self.mtu as usize);
37 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
38
39 let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
40 let used = wire_frames::encode_frame_ty(ser, hdr, apdx, body).map_err(drop)?;
41 let len = used.len();
42 wgr.commit(len);
43
44 Ok(())
45 }
46
47 pub fn send_raw(&mut self, hdr: &CommonHeader, hdr_raw: &[u8], body: &[u8]) -> Result<(), ()> {
48 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
49
50 if is_err {
51 return Err(());
53 }
54
55 let max_len = cobs::max_encoding_length(hdr_raw.len() + body.len());
56 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
57
58 let mut ser =
59 ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
60 ser.try_extend(hdr_raw).map_err(drop)?;
61 ser.try_extend(body).map_err(drop)?;
62 let fin = ser.finalize().map_err(drop)?;
63 let len = fin.len();
64 wgr.commit(len);
65
66 Ok(())
67 }
68
69 pub fn send_err(&mut self, hdr: &CommonHeader, err: ProtocolError) -> Result<(), ()> {
70 let is_err = hdr.kind == FrameKind::PROTOCOL_ERROR;
71
72 if !is_err {
74 return Err(());
76 }
77
78 let max_len = cobs::max_encoding_length(self.mtu as usize);
79 let mut wgr = self.prod.grant_exact(max_len).map_err(drop)?;
80
81 let ser = ser_flavors::Cobs::try_new(ser_flavors::Slice::new(&mut wgr)).map_err(drop)?;
82 let used = wire_frames::encode_frame_err(ser, hdr, err).map_err(drop)?;
83 let len = used.len();
84 wgr.commit(len);
85
86 Ok(())
87 }
88}