raknet_rust/protocol/
frame.rs1use bytes::{Buf, BufMut, Bytes};
2
3use crate::error::{DecodeError, EncodeError};
4
5use super::codec::RaknetCodec;
6use super::constants::MAX_SPLIT_PARTS;
7use super::frame_header::FrameHeader;
8use super::sequence24::Sequence24;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct SplitInfo {
12 pub part_count: u32,
13 pub part_id: u16,
14 pub part_index: u32,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Frame {
19 pub header: FrameHeader,
20 pub bit_length: u16,
21 pub reliable_index: Option<Sequence24>,
22 pub sequence_index: Option<Sequence24>,
23 pub ordering_index: Option<Sequence24>,
24 pub ordering_channel: Option<u8>,
25 pub split: Option<SplitInfo>,
26 pub payload: Bytes,
27}
28
29impl Frame {
30 pub fn payload_len(&self) -> usize {
31 ((self.bit_length as usize) + 7) >> 3
32 }
33
34 pub fn encoded_size(&self) -> usize {
35 let mut size = 3usize;
36 let rel = self.header.reliability;
37
38 if rel.is_reliable() {
39 size += 3;
40 }
41 if rel.is_sequenced() {
42 size += 3;
43 }
44 if rel.is_ordered() || rel.is_sequenced() {
45 size += 4;
46 }
47 if self.header.is_split {
48 size += 10;
49 }
50
51 size + self.payload_len()
52 }
53}
54
55impl RaknetCodec for Frame {
56 fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
57 if self.payload_len() != self.payload.len() {
58 return Err(EncodeError::FrameBitLengthMismatch);
59 }
60
61 self.header.encode_raknet(dst)?;
62 self.bit_length.encode_raknet(dst)?;
63
64 let rel = self.header.reliability;
65 if rel.is_reliable() {
66 self.reliable_index
67 .ok_or(EncodeError::MissingReliableIndex)?
68 .encode_raknet(dst)?;
69 }
70 if rel.is_sequenced() {
71 self.sequence_index
72 .ok_or(EncodeError::MissingSequenceIndex)?
73 .encode_raknet(dst)?;
74 }
75 if rel.is_ordered() || rel.is_sequenced() {
76 self.ordering_index
77 .ok_or(EncodeError::MissingOrderingIndex)?
78 .encode_raknet(dst)?;
79 self.ordering_channel
80 .ok_or(EncodeError::MissingOrderingChannel)?
81 .encode_raknet(dst)?;
82 }
83
84 if self.header.is_split {
85 let split = self.split.as_ref().ok_or(EncodeError::MissingSplitInfo)?;
86 split.part_count.encode_raknet(dst)?;
87 split.part_id.encode_raknet(dst)?;
88 split.part_index.encode_raknet(dst)?;
89 }
90
91 dst.put_slice(&self.payload);
92 Ok(())
93 }
94
95 fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
96 let header = FrameHeader::decode_raknet(src)?;
97 let bit_length = u16::decode_raknet(src)?;
98 let payload_len = ((bit_length as usize) + 7) >> 3;
99 if payload_len == 0 {
100 return Err(DecodeError::InvalidFrameBitLength(bit_length));
101 }
102
103 let rel = header.reliability;
104
105 let reliable_index = if rel.is_reliable() {
106 Some(Sequence24::decode_raknet(src)?)
107 } else {
108 None
109 };
110
111 let sequence_index = if rel.is_sequenced() {
112 Some(Sequence24::decode_raknet(src)?)
113 } else {
114 None
115 };
116
117 let (ordering_index, ordering_channel) = if rel.is_ordered() || rel.is_sequenced() {
118 (
119 Some(Sequence24::decode_raknet(src)?),
120 Some(u8::decode_raknet(src)?),
121 )
122 } else {
123 (None, None)
124 };
125
126 let split = if header.is_split {
127 let part_count = u32::decode_raknet(src)?;
128 if part_count == 0 {
129 return Err(DecodeError::SplitCountZero);
130 }
131 if part_count > MAX_SPLIT_PARTS {
132 return Err(DecodeError::SplitIndexOutOfRange);
133 }
134
135 let part_id = u16::decode_raknet(src)?;
136 let part_index = u32::decode_raknet(src)?;
137 if part_index >= part_count {
138 return Err(DecodeError::SplitIndexOutOfRange);
139 }
140
141 Some(SplitInfo {
142 part_count,
143 part_id,
144 part_index,
145 })
146 } else {
147 None
148 };
149
150 if src.remaining() < payload_len {
151 return Err(DecodeError::UnexpectedEof);
152 }
153 let payload = src.copy_to_bytes(payload_len);
154
155 Ok(Self {
156 header,
157 bit_length,
158 reliable_index,
159 sequence_index,
160 ordering_index,
161 ordering_channel,
162 split,
163 payload,
164 })
165 }
166}