ironrdp_pdu/codecs/rfx/
header_messages.rs1use ironrdp_core::{
2 cast_length, ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
3 WriteCursor,
4};
5
6const SYNC_MAGIC: u32 = 0xCACC_ACCA;
7const SYNC_VERSION: u16 = 0x0100;
8const CODECS_NUMBER: u8 = 1;
9const CODEC_ID: u8 = 1;
10const CODEC_VERSION: u16 = 0x0100;
11const CHANNEL_ID: u8 = 0;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct SyncPdu;
18
19impl SyncPdu {
20 const NAME: &'static str = "RfxSync";
21
22 const FIXED_PART_SIZE: usize = 4 + 2 ;
23}
24
25impl Encode for SyncPdu {
26 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
27 ensure_fixed_part_size!(in: dst);
28
29 dst.write_u32(SYNC_MAGIC);
30 dst.write_u16(SYNC_VERSION);
31
32 Ok(())
33 }
34
35 fn name(&self) -> &'static str {
36 Self::NAME
37 }
38
39 fn size(&self) -> usize {
40 Self::FIXED_PART_SIZE
41 }
42}
43
44impl<'de> Decode<'de> for SyncPdu {
45 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
46 ensure_fixed_part_size!(in: src);
47
48 let magic = src.read_u32();
49 if magic != SYNC_MAGIC {
50 return Err(invalid_field_err!("magic", "Invalid sync magic"));
51 }
52 let version = src.read_u16();
53 if version != SYNC_VERSION {
54 return Err(invalid_field_err!("version", "Invalid sync version"));
55 }
56
57 Ok(Self)
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
65pub struct CodecVersionsPdu;
66
67impl CodecVersionsPdu {
68 const NAME: &'static str = "RfxCodecVersions";
69
70 const FIXED_PART_SIZE: usize = 1 + CodecVersion::FIXED_PART_SIZE ;
71}
72
73impl Encode for CodecVersionsPdu {
74 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
75 ensure_fixed_part_size!(in: dst);
76
77 dst.write_u8(CODECS_NUMBER);
78 CodecVersion.encode(dst)?;
79
80 Ok(())
81 }
82
83 fn name(&self) -> &'static str {
84 Self::NAME
85 }
86
87 fn size(&self) -> usize {
88 Self::FIXED_PART_SIZE
89 }
90}
91
92impl<'de> Decode<'de> for CodecVersionsPdu {
93 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
94 ensure_fixed_part_size!(in: src);
95
96 let codec_number = src.read_u8();
97 if codec_number != CODECS_NUMBER {
98 return Err(invalid_field_err!("codec_number", "Invalid codec number"));
99 }
100
101 let _codec_version = CodecVersion::decode(src)?;
102
103 Ok(Self)
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct ChannelsPdu(pub Vec<RfxChannel>);
112
113impl ChannelsPdu {
114 const NAME: &'static str = "RfxChannels";
115
116 const FIXED_PART_SIZE: usize = 1 ;
117}
118
119impl Encode for ChannelsPdu {
120 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
121 ensure_fixed_part_size!(in: dst);
122
123 dst.write_u8(cast_length!("num_channels", self.0.len())?);
124 for channel in &self.0 {
125 channel.encode(dst)?;
126 }
127
128 Ok(())
129 }
130
131 fn name(&self) -> &'static str {
132 Self::NAME
133 }
134
135 fn size(&self) -> usize {
136 Self::FIXED_PART_SIZE + self.0.iter().map(|channel| channel.size()).sum::<usize>()
137 }
138}
139
140impl<'de> Decode<'de> for ChannelsPdu {
141 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
142 ensure_fixed_part_size!(in: src);
143
144 let num_channels = src.read_u8();
145 let channels = (0..num_channels)
146 .map(|_| RfxChannel::decode(src))
147 .collect::<DecodeResult<Vec<_>>>()?;
148
149 Ok(Self(channels))
150 }
151}
152
153#[derive(Debug, Copy, Clone, PartialEq, Eq)]
157pub struct RfxChannel {
158 pub width: i16,
159 pub height: i16,
160}
161
162impl RfxChannel {
163 const NAME: &'static str = "RfxChannel";
164
165 const FIXED_PART_SIZE: usize = 1 + 2 + 2 ;
166}
167
168impl Encode for RfxChannel {
169 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
170 ensure_fixed_part_size!(in: dst);
171
172 dst.write_u8(CHANNEL_ID);
173 dst.write_i16(self.width);
174 dst.write_i16(self.height);
175
176 Ok(())
177 }
178
179 fn name(&self) -> &'static str {
180 Self::NAME
181 }
182
183 fn size(&self) -> usize {
184 Self::FIXED_PART_SIZE
185 }
186}
187
188impl<'de> Decode<'de> for RfxChannel {
189 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
190 ensure_fixed_part_size!(in: src);
191
192 let channel_id = src.read_u8();
193 if channel_id != CHANNEL_ID {
194 return Err(invalid_field_err!("channelId", "Invalid channel ID"));
195 }
196
197 let width = src.read_i16();
198 let height = src.read_i16();
199
200 Ok(Self { width, height })
201 }
202}
203
204#[derive(Debug, Clone, PartialEq)]
208struct CodecVersion;
209
210impl CodecVersion {
211 const NAME: &'static str = "RfxCodecVersion";
212
213 const FIXED_PART_SIZE: usize = 1 + 2 ;
214}
215
216impl Encode for CodecVersion {
217 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
218 ensure_fixed_part_size!(in: dst);
219
220 dst.write_u8(CODEC_ID);
221 dst.write_u16(CODEC_VERSION);
222
223 Ok(())
224 }
225
226 fn name(&self) -> &'static str {
227 Self::NAME
228 }
229
230 fn size(&self) -> usize {
231 Self::FIXED_PART_SIZE
232 }
233}
234
235impl<'de> Decode<'de> for CodecVersion {
236 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
237 ensure_fixed_part_size!(in: src);
238
239 let codec_id = src.read_u8();
240 if codec_id != CODEC_ID {
241 return Err(invalid_field_err!("codec_id", "Invalid codec ID"));
242 }
243 let codec_version = src.read_u16();
244 if codec_version != CODEC_VERSION {
245 return Err(invalid_field_err!("codec_version", "Invalid codec version"));
246 }
247
248 Ok(Self)
249 }
250}