]> git.lizzy.rs Git - mt_rudp.git/blob - src/share.rs
Fix reverse order of chunk count and index
[mt_rudp.git] / src / share.rs
1 use super::*;
2 use std::{borrow::Cow, collections::HashMap, io, sync::Arc};
3 use tokio::sync::{watch, Mutex, RwLock};
4
5 #[derive(Debug)]
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>,
10 }
11
12 #[derive(Debug)]
13 pub(crate) struct Chan {
14     pub(crate) acks: HashMap<u16, Ack>,
15     pub(crate) seqnum: u16,
16 }
17
18 #[derive(Debug)]
19 pub(crate) struct RudpShare<P: UdpPeer> {
20     pub(crate) id: u16,
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>,
25 }
26
27 pub async fn new<P: UdpPeer>(
28     id: u16,
29     remote_id: u16,
30     udp_tx: P::Sender,
31     udp_rx: P::Receiver,
32 ) -> io::Result<(RudpSender<P>, RudpReceiver<P>)> {
33     let (close_tx, close_rx) = watch::channel(false);
34
35     let share = Arc::new(RudpShare {
36         id,
37         remote_id: RwLock::new(remote_id),
38         udp_tx,
39         close: close_tx,
40         chans: std::array::from_fn(|_| {
41             Mutex::new(Chan {
42                 acks: HashMap::new(),
43                 seqnum: INIT_SEQNUM,
44             })
45         }),
46     });
47
48     Ok((
49         RudpSender {
50             share: Arc::clone(&share),
51         },
52         RudpReceiver::new(udp_rx, share, close_rx),
53     ))
54 }
55
56 macro_rules! impl_share {
57     ($T:ident) => {
58         impl<P: UdpPeer> $T<P> {
59             pub async fn peer_id(&self) -> u16 {
60                 self.share.id
61             }
62
63             pub async fn is_server(&self) -> bool {
64                 self.share.id == PeerID::Srv as u16
65             }
66
67             pub async fn close(self) {
68                 self.share.close.send(true).ok(); // FIXME: handle err?
69
70                 self.share
71                     .send(
72                         PktType::Ctl,
73                         Pkt {
74                             unrel: true,
75                             chan: 0,
76                             data: Cow::Borrowed(&[CtlType::Disco as u8]),
77                         },
78                     )
79                     .await
80                     .ok();
81             }
82         }
83     };
84 }
85
86 impl_share!(RudpReceiver);
87 impl_share!(RudpSender);