use embassy_sync::{blocking_mutex::raw::RawMutex, channel};
use embedded_buffer_pool::{BufferGuard, BufferPool, MappedBufferGuard};
use heapless::Vec;
use crate::protocol::{Ack, CHUNK_LEN_MAX};
pub struct SecureSerialResources<
M: RawMutex + 'static,
const N_INFLIGHT: usize,
const N_RX_POOL: usize,
const N_BUF: usize,
> {
tx_pool: BufferPool<M, Vec<u8, CHUNK_LEN_MAX>, N_INFLIGHT>,
tx_chunks: channel::Channel<M, BufferGuard<M, Vec<u8, CHUNK_LEN_MAX>>, N_INFLIGHT>,
acks_to_send: channel::Channel<M, Ack, N_INFLIGHT>,
acks_received: channel::Channel<M, Ack, N_INFLIGHT>,
rx_pool: BufferPool<M, [u8; N_BUF], N_RX_POOL>,
rx_complete: channel::Channel<M, MappedBufferGuard<M, [u8]>, N_RX_POOL>,
}
pub type SecureSerialResourcesDefault<M> = SecureSerialResources<M, 8, 4, 4096>;
impl<M: RawMutex + 'static, const N_INFLIGHT: usize, const N_RX_POOL: usize, const N_BUF: usize>
SecureSerialResources<M, N_INFLIGHT, N_RX_POOL, N_BUF>
{
pub fn new() -> Self {
assert!(N_INFLIGHT > 0 && N_INFLIGHT <= 32);
assert!(N_RX_POOL > 0 && N_RX_POOL <= 32);
let tx_backing = core::array::from_fn(|_| Vec::new());
let tx_pool = BufferPool::new(tx_backing);
let tx_chunks = channel::Channel::new();
let acks_to_send = channel::Channel::new();
let acks_received = channel::Channel::new();
let rx_backing = core::array::from_fn(|_| [0u8; N_BUF]);
let rx_pool = BufferPool::new(rx_backing);
let rx_complete = channel::Channel::new();
Self {
tx_pool,
tx_chunks,
acks_to_send,
acks_received,
rx_pool,
rx_complete,
}
}
#[inline]
pub fn tx_pool(&self) -> &BufferPool<M, Vec<u8, CHUNK_LEN_MAX>, N_INFLIGHT> {
&self.tx_pool
}
#[inline]
pub fn tx_chunks_sender(
&self,
) -> channel::Sender<'_, M, BufferGuard<M, Vec<u8, CHUNK_LEN_MAX>>, N_INFLIGHT> {
self.tx_chunks.sender()
}
#[inline]
pub fn tx_chunks_receiver(
&self,
) -> channel::Receiver<'_, M, BufferGuard<M, Vec<u8, CHUNK_LEN_MAX>>, N_INFLIGHT> {
self.tx_chunks.receiver()
}
#[inline]
pub fn acks_to_wire_sender(&self) -> channel::Sender<'_, M, Ack, N_INFLIGHT> {
self.acks_to_send.sender()
}
#[inline]
pub fn acks_to_wire_receiver(&self) -> channel::Receiver<'_, M, Ack, N_INFLIGHT> {
self.acks_to_send.receiver()
}
#[inline]
pub fn acks_from_peer_sender(&self) -> channel::Sender<'_, M, Ack, N_INFLIGHT> {
self.acks_received.sender()
}
#[inline]
pub fn acks_from_peer_receiver(&self) -> channel::Receiver<'_, M, Ack, N_INFLIGHT> {
self.acks_received.receiver()
}
#[inline]
pub fn rx_pool(&self) -> &BufferPool<M, [u8; N_BUF], N_RX_POOL> {
&self.rx_pool
}
#[inline]
pub fn rx_complete_sender(
&self,
) -> channel::Sender<'_, M, MappedBufferGuard<M, [u8]>, N_RX_POOL> {
self.rx_complete.sender()
}
#[inline]
pub fn rx_complete_receiver(
&self,
) -> channel::Receiver<'_, M, MappedBufferGuard<M, [u8]>, N_RX_POOL> {
self.rx_complete.receiver()
}
}