ergot_base/interface_manager/
cobs_stream.rs

1use 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)] // todo
19impl<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            // todo: use a different interface for this
33            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            // todo: use a different interface for this
52            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        // note: here it SHOULD be an err!
73        if !is_err {
74            // todo: use a different interface for this
75            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}