2 use std::{borrow::Cow, collections::HashMap, io, sync::Arc};
3 use tokio::sync::{watch, Mutex, RwLock};
6 pub(crate) struct Ack {
7 pub(crate) tx: watch::Sender<bool>,
8 pub(crate) rx: watch::Receiver<bool>,
9 pub(crate) data: Vec<u8>,
13 pub(crate) struct Chan {
14 pub(crate) acks: HashMap<u16, Ack>,
15 pub(crate) seqnum: u16,
19 pub(crate) struct RudpShare<P: UdpPeer> {
21 pub(crate) remote_id: RwLock<u16>,
22 pub(crate) chans: [Mutex<Chan>; NUM_CHANS],
23 pub(crate) udp_tx: P::Sender,
24 pub(crate) close: watch::Sender<bool>,
27 pub async fn new<P: UdpPeer>(
32 ) -> io::Result<(RudpSender<P>, RudpReceiver<P>)> {
33 let (close_tx, close_rx) = watch::channel(false);
35 let share = Arc::new(RudpShare {
37 remote_id: RwLock::new(remote_id),
40 chans: std::array::from_fn(|_| {
50 share: Arc::clone(&share),
52 RudpReceiver::new(udp_rx, share, close_rx),
56 macro_rules! impl_share {
58 impl<P: UdpPeer> $T<P> {
59 pub async fn peer_id(&self) -> u16 {
63 pub async fn is_server(&self) -> bool {
64 self.share.id == PeerID::Srv as u16
67 pub async fn close(self) {
68 self.share.close.send(true).ok(); // FIXME: handle err?
76 data: Cow::Borrowed(&[CtlType::Disco as u8]),
86 impl_share!(RudpReceiver);
87 impl_share!(RudpSender);