1use msrt::endpoint::{EndpointPoll, EngineConfig, PassiveEndpoint, PeerState};
4
5use crate::event::UartBackendEvent;
6use crate::traits::{UartError, UartIo, UartIoError, UartResult};
7
8const RX_BYTES: usize = 512;
9const TX_BYTES: usize = 256;
10
11#[derive(Debug)]
16pub struct UartBackend<T> {
17 io: T,
18 endpoint: PassiveEndpoint,
19 rx_buf: [u8; RX_BYTES],
20 tx_buf: [u8; TX_BYTES],
21}
22
23impl<T> UartBackend<T>
24where
25 T: UartIo,
26{
27 pub fn new(io: T) -> Self {
29 Self::with_config(io, EngineConfig::default())
30 }
31
32 pub fn with_config(io: T, config: EngineConfig) -> Self {
34 Self {
35 io,
36 endpoint: PassiveEndpoint::new(config),
37 rx_buf: [0; RX_BYTES],
38 tx_buf: [0; TX_BYTES],
39 }
40 }
41
42 pub fn peer_state(&self) -> PeerState {
44 self.endpoint.peer().state()
45 }
46
47 pub const fn io(&self) -> &T {
49 &self.io
50 }
51
52 pub fn io_mut(&mut self) -> &mut T {
54 &mut self.io
55 }
56
57 pub fn into_inner(self) -> T {
59 self.io
60 }
61
62 pub fn disconnect(&mut self) {
64 self.endpoint.disconnect();
65 }
66
67 pub fn send(&mut self, message: &[u8]) -> UartResult<bool, T::Error> {
69 self.endpoint
70 .send(message)
71 .map(|id| id.is_some())
72 .map_err(UartError::Protocol)
73 }
74
75 pub fn receive_available(&mut self, now_ms: u64) -> UartResult<usize, T::Error> {
77 let mut total = 0;
78 loop {
79 match self.io.read(&mut self.rx_buf) {
80 Ok(0) => return Ok(total),
81 Ok(n) => {
82 total += n;
83 let _ = self.endpoint.receive(now_ms, &self.rx_buf[..n]);
84 if n < self.rx_buf.len() {
85 return Ok(total);
86 }
87 }
88 Err(UartIoError::WouldBlock) => return Ok(total),
89 Err(UartIoError::Interrupted) => continue,
90 Err(error) => return Err(UartError::Io(error)),
91 }
92 }
93 }
94
95 pub fn poll(&mut self, now_ms: u64) -> UartResult<UartBackendEvent, T::Error> {
97 loop {
98 match self
99 .endpoint
100 .poll(now_ms, &mut self.tx_buf)
101 .map_err(UartError::Protocol)?
102 {
103 EndpointPoll::Transmit { bytes, .. } => {
104 self.io.write_all(bytes).map_err(UartError::Io)?;
105 }
106 EndpointPoll::Message(message) => return Ok(UartBackendEvent::Message(message)),
107 EndpointPoll::SendFailed(failed) => {
108 return Ok(UartBackendEvent::SendFailed(failed));
109 }
110 EndpointPoll::Idle => return Ok(UartBackendEvent::Idle),
111 }
112 }
113 }
114
115 pub fn tick(&mut self, now_ms: u64) -> UartResult<UartBackendEvent, T::Error> {
117 let _ = self.receive_available(now_ms)?;
118 self.poll(now_ms)
119 }
120}