prns_runtime_embassy/manifold/driver/interface_seam/
mod.rs1use embassy_sync::blocking_mutex::raw::RawMutex;
2use embassy_sync::channel::Sender;
3
4use crate::interfaces::{FrameSink, InterfaceId, PacketPhyStats};
5use crate::manifold::grant::{FrameTarget, GrantConsumer, GrantProducer};
6use crate::manifold::interface_seam::{InterfaceSeam, OutboundDisposition};
7
8use super::{EmbassyGrantConsumer, EmbassyGrantProducer};
9
10pub struct EmbassyInterfaceSeam<'a, M: RawMutex, const NOTIFY: usize, const FRAME: usize> {
11 id: InterfaceId,
12 inbound: EmbassyGrantProducer<'a, M, FRAME>,
13 notify: Sender<'a, M, InterfaceId, NOTIFY>,
14 outbound: EmbassyGrantConsumer<'a, M, FRAME>,
15 fill_entropy: fn(&mut [u8]),
16}
17
18impl<'a, M: RawMutex, const NOTIFY: usize, const FRAME: usize>
19 EmbassyInterfaceSeam<'a, M, NOTIFY, FRAME>
20{
21 #[must_use]
22 pub fn new(
23 id: InterfaceId,
24 inbound: EmbassyGrantProducer<'a, M, FRAME>,
25 notify: Sender<'a, M, InterfaceId, NOTIFY>,
26 outbound: EmbassyGrantConsumer<'a, M, FRAME>,
27 fill_entropy: fn(&mut [u8]),
28 ) -> Self {
29 Self {
30 id,
31 inbound,
32 notify,
33 outbound,
34 fill_entropy,
35 }
36 }
37}
38
39impl<M: RawMutex, const NOTIFY: usize, const FRAME: usize> InterfaceSeam
40 for EmbassyInterfaceSeam<'_, M, NOTIFY, FRAME>
41{
42 fn fill_entropy(&mut self, bytes: &mut [u8]) {
43 (self.fill_entropy)(bytes);
44 }
45
46 async fn inbound_sink(&mut self) -> &mut dyn FrameSink {
47 let slot = self.inbound.grant().await;
48 slot.target = FrameTarget::Direct(self.id);
49 slot
50 }
51
52 async fn commit_inbound(&mut self) {
53 let slot = self.inbound.grant().await;
54 if slot.len == 0 {
55 return;
56 }
57 self.inbound.commit();
58 let _ = self.notify.try_send(self.id);
59 }
60
61 async fn next_inbound_with_phy(&mut self, frame: &[u8], packet_phy: PacketPhyStats) {
62 let slot = self.inbound.grant().await;
63 slot.clear();
64 if slot.extend_from_slice(frame).is_err() {
65 return;
66 }
67 slot.packet_phy = packet_phy;
68 self.commit_inbound().await;
69 }
70
71 async fn next_outbound(&mut self) -> &[u8] {
72 self.outbound.release();
73 self.outbound.peek().await.frame()
74 }
75
76 fn accept_outbound_custody(&mut self) {
77 self.outbound.release();
78 }
79
80 fn complete_outbound(&mut self, _disposition: OutboundDisposition) {
81 self.outbound.release();
82 }
83}
84
85#[cfg(test)]
86mod tests;