rak_rs/protocol/
frame.rs

1use binary_util::{
2    interfaces::{Reader, Writer},
3    BinaryIo,
4};
5
6/// The information for the given fragment.
7/// This is used to determine how to reassemble the frame.
8#[derive(Debug, Clone, BinaryIo)]
9pub struct FragmentMeta {
10    pub(crate) size: u32,
11    pub(crate) id: u16,
12    pub(crate) index: u32,
13}
14
15impl FragmentMeta {
16    /// Creates a new fragment meta with the given size, id, and index.
17    pub fn new(size: u32, id: u16, index: u32) -> Self {
18        Self { size, id, index }
19    }
20}
21
22use crate::rakrs_debug;
23
24use super::reliability::Reliability;
25
26/// Frames are a encapsulation of a packet or packets.
27/// They are used to send packets to the connection in a reliable way.
28#[derive(Debug, Clone)]
29pub struct FramePacket {
30    pub sequence: u32,
31    pub frames: Vec<Frame>,
32    pub reliability: Reliability,
33}
34
35impl FramePacket {
36    /// Creates an empty frame packet.
37    pub fn new() -> Self {
38        Self {
39            sequence: 0,
40            frames: Vec::new(),
41            reliability: Reliability::ReliableOrd,
42        }
43    }
44}
45
46impl Reader<FramePacket> for FramePacket {
47    fn read(buf: &mut binary_util::ByteReader) -> Result<FramePacket, std::io::Error> {
48        // FRAME PACKET HEADER
49        let id = buf.read_u8()?;
50        match id {
51            0x80..=0x8d => {}
52            _ => {
53                return Err(std::io::Error::new(
54                    std::io::ErrorKind::InvalidData,
55                    "Invalid Frame Packet ID",
56                ))
57            }
58        }
59        let mut frames: Vec<Frame> = Vec::new();
60
61        let sequence = buf.read_u24_le()?;
62
63        loop {
64            let frame_pos = buf.read_type::<Frame>();
65            if let Ok(frame) = frame_pos {
66                frames.push(frame);
67            } else {
68                break;
69            }
70        }
71
72        Ok(FramePacket {
73            sequence,
74            frames,
75            reliability: Reliability::ReliableOrd,
76        })
77    }
78}
79
80impl Writer for FramePacket {
81    fn write(&self, buf: &mut binary_util::ByteWriter) -> Result<(), std::io::Error> {
82        buf.write_u8(0x84)?;
83        buf.write_u24_le(self.sequence)?;
84
85        for frame in &self.frames {
86            buf.write(frame.write_to_bytes()?.as_slice())?;
87        }
88
89        Ok(())
90    }
91}
92
93/// An individual data frame, these are constructed from a payload.
94#[derive(Debug, Clone)]
95pub struct Frame {
96    /// The flags for this frame, the first 3 bits are reserved for the reliability while the 4th
97    /// bit is used to represent if this is a fragment.
98    pub flags: u8,
99    /// The length of the body of the frame.
100    /// This is sized to 24 bits internally, so any number here must be within that range.
101    pub size: u16,
102    /// The Reliable index of the frame (if reliable)
103    pub reliable_index: Option<u32>,
104    /// The sequenced index of the frame (if sequenced)
105    /// This is used to determine the position in frame list.
106    pub sequence_index: Option<u32>,
107    /// The order index of the frame (if ordered)
108    /// This is used to determine the position in frame list,
109    /// This is different from the sequence index in that it is
110    /// used more to sequence packets in a specific manner.
111    pub order_index: Option<u32>,
112    /// The order channel of the frame (if ordered)
113    /// This is used to store order information for the frame.
114    pub order_channel: Option<u8>,
115    /// The information for fragmentation (if the frame is split into parts)
116    /// This is used to determine how to reassemble the frame.
117    pub fragment_meta: Option<FragmentMeta>,
118    /// The reliability of this frame, this is essentially used to save frames and send them back if
119    /// they are lost. Otherwise, the frame is sent unreliably.
120    pub reliability: Reliability,
121    /// The body of the frame, this is the payload of the frame.
122    pub body: Vec<u8>,
123}
124
125impl Frame {
126    /// Initializes a new empty frame that is Unreliable.
127    /// This is usually used to inject data into.
128    pub fn init() -> Self {
129        Self {
130            flags: 0,
131            size: 0,
132            reliable_index: None,
133            sequence_index: None,
134            order_index: None,
135            order_channel: None,
136            fragment_meta: None,
137            reliability: Reliability::Unreliable,
138            body: Vec::new(),
139        }
140    }
141
142    /// Initializes a new frame with the given reliability.
143    pub fn new(reliability: Reliability, body: Option<&[u8]>) -> Self {
144        Self {
145            flags: 0,
146            size: if let Some(b) = body {
147                b.len() as u16
148            } else {
149                0
150            },
151            reliable_index: None,
152            sequence_index: None,
153            order_index: None,
154            order_channel: None,
155            fragment_meta: None,
156            reliability,
157            body: body.unwrap_or(&[]).to_vec(),
158        }
159    }
160
161    /// Whether or not the frame is fragmented.
162    pub fn is_fragmented(&self) -> bool {
163        self.fragment_meta.is_some()
164    }
165
166    /// Whether or not the frame is sequenced and reliable.
167    pub fn is_sequenced(&self) -> bool {
168        self.reliability.is_sequenced()
169    }
170
171    pub fn with_meta(mut self, meta: FragmentMeta) -> Self {
172        self.fragment_meta = Some(meta);
173        self
174    }
175}
176
177impl Reader<Frame> for Frame {
178    fn read(buf: &mut binary_util::ByteReader) -> Result<Frame, std::io::Error> {
179        let mut frame = Frame::init();
180
181        frame.flags = buf.read_u8()?;
182        frame.reliability = Reliability::from_flags(frame.flags);
183
184        let size = buf.read_u16();
185
186        if let Ok(size) = size {
187            frame.size = size / 8;
188        }
189
190        if frame.reliability.is_reliable() {
191            frame.reliable_index = Some(buf.read_u24_le()?);
192        }
193
194        if frame.reliability.is_sequenced() {
195            frame.sequence_index = Some(buf.read_u24_le()?);
196        }
197
198        if frame.reliability.is_ordered() {
199            frame.order_index = Some(buf.read_u24_le()?);
200            frame.order_channel = Some(buf.read_u8()?);
201        }
202
203        if (frame.flags & 0x10) > 0 {
204            frame.fragment_meta = Some(FragmentMeta::read(buf)?);
205        }
206
207        let mut body = vec![0; frame.size as usize];
208
209        // if let Ok(_) = buf.read(&mut body) {
210        //     frame.body = body.to_vec();
211        //     println!("Frame body is: {:?}", frame.body);
212        // }
213
214        match buf.read(&mut body) {
215            Ok(_) => {
216                frame.body = body.to_vec();
217                // println!("Frame body is: {:?}", frame.body);
218            }
219            Err(e) => {
220                rakrs_debug!(true, "[DECODE_ERR] Error reading frame body: {:?}", e);
221            }
222        }
223
224        Ok(frame)
225    }
226}
227
228impl Writer for Frame {
229    fn write(&self, buf: &mut binary_util::ByteWriter) -> Result<(), std::io::Error> {
230        let mut flags = self.reliability.to_flags();
231
232        // check whether or not this frame is fragmented, if it is, set the fragment flag
233        if self.fragment_meta.is_some() {
234            flags |= 0x10;
235        }
236
237        buf.write_u8(flags)?;
238        buf.write_u16(self.size * 8)?;
239
240        if self.reliability.is_reliable() {
241            buf.write_u24_le(self.reliable_index.unwrap_or(0))?;
242        }
243
244        if self.reliability.is_sequenced() {
245            buf.write_u24_le(self.sequence_index.unwrap_or(0))?;
246        }
247
248        if self.reliability.is_ordered() {
249            buf.write_u24_le(self.order_index.unwrap_or(0))?;
250            buf.write_u8(self.order_channel.unwrap_or(0))?;
251        }
252
253        if self.fragment_meta.is_some() {
254            buf.write(
255                self.fragment_meta
256                    .as_ref()
257                    .unwrap()
258                    .write_to_bytes()?
259                    .as_slice(),
260            )?;
261        }
262
263        buf.write(&self.body)?;
264
265        Ok(())
266    }
267}