ironrdp_pdu/rdp/vc/dvc/gfx/graphics_messages/
client.rs

1use ironrdp_core::{
2    cast_length, ensure_fixed_part_size, ensure_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
3    WriteCursor,
4};
5
6use super::CapabilitySet;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct CapabilitiesAdvertisePdu(pub Vec<CapabilitySet>);
10
11impl CapabilitiesAdvertisePdu {
12    const NAME: &'static str = "CapabilitiesAdvertisePdu";
13
14    const FIXED_PART_SIZE: usize  = 2 /* Count */;
15}
16
17impl Encode for CapabilitiesAdvertisePdu {
18    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
19        ensure_size!(in: dst, size: self.size());
20
21        dst.write_u16(cast_length!("Count", self.0.len())?);
22
23        for capability_set in self.0.iter() {
24            capability_set.encode(dst)?;
25        }
26
27        Ok(())
28    }
29
30    fn name(&self) -> &'static str {
31        Self::NAME
32    }
33
34    fn size(&self) -> usize {
35        Self::FIXED_PART_SIZE + self.0.iter().map(|c| c.size()).sum::<usize>()
36    }
37}
38
39impl<'a> Decode<'a> for CapabilitiesAdvertisePdu {
40    fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
41        ensure_fixed_part_size!(in: src);
42
43        let capabilities_count = cast_length!("Count", src.read_u16())?;
44
45        ensure_size!(in: src, size: capabilities_count * CapabilitySet::FIXED_PART_SIZE);
46
47        let capabilities = (0..capabilities_count)
48            .map(|_| CapabilitySet::decode(src))
49            .collect::<Result<_, _>>()?;
50
51        Ok(Self(capabilities))
52    }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct FrameAcknowledgePdu {
57    pub queue_depth: QueueDepth,
58    pub frame_id: u32,
59    pub total_frames_decoded: u32,
60}
61
62impl FrameAcknowledgePdu {
63    const NAME: &'static str = "FrameAcknowledgePdu";
64
65    const FIXED_PART_SIZE: usize = 4 /* QueueDepth */ + 4 /* FrameId */ + 4 /* TotalFramesDecoded */;
66}
67
68impl Encode for FrameAcknowledgePdu {
69    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
70        ensure_fixed_part_size!(in: dst);
71
72        dst.write_u32(self.queue_depth.to_u32());
73        dst.write_u32(self.frame_id);
74        dst.write_u32(self.total_frames_decoded);
75
76        Ok(())
77    }
78
79    fn name(&self) -> &'static str {
80        Self::NAME
81    }
82
83    fn size(&self) -> usize {
84        Self::FIXED_PART_SIZE
85    }
86}
87
88impl<'a> Decode<'a> for FrameAcknowledgePdu {
89    fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
90        ensure_fixed_part_size!(in: src);
91
92        let queue_depth = QueueDepth::from_u32(src.read_u32());
93        let frame_id = src.read_u32();
94        let total_frames_decoded = src.read_u32();
95
96        Ok(Self {
97            queue_depth,
98            frame_id,
99            total_frames_decoded,
100        })
101    }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
105pub struct CacheImportReplyPdu {
106    pub cache_slots: Vec<u16>,
107}
108
109impl CacheImportReplyPdu {
110    const NAME: &'static str = "CacheImportReplyPdu";
111
112    const FIXED_PART_SIZE: usize = 2 /* Count */;
113}
114
115impl Encode for CacheImportReplyPdu {
116    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
117        ensure_size!(in: dst, size: self.size());
118
119        dst.write_u16(cast_length!("Count", self.cache_slots.len())?);
120
121        for cache_slot in self.cache_slots.iter() {
122            dst.write_u16(*cache_slot);
123        }
124
125        Ok(())
126    }
127
128    fn name(&self) -> &'static str {
129        Self::NAME
130    }
131
132    fn size(&self) -> usize {
133        Self::FIXED_PART_SIZE + self.cache_slots.iter().map(|_| 2).sum::<usize>()
134    }
135}
136
137impl<'a> Decode<'a> for CacheImportReplyPdu {
138    fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
139        ensure_fixed_part_size!(in: src);
140
141        let entries_count = src.read_u16();
142
143        let cache_slots = (0..entries_count).map(|_| src.read_u16()).collect();
144
145        Ok(Self { cache_slots })
146    }
147}
148
149#[repr(u32)]
150#[derive(Debug, Copy, Clone, PartialEq, Eq)]
151pub enum QueueDepth {
152    Unavailable,
153    AvailableBytes(u32),
154    Suspend,
155}
156
157impl QueueDepth {
158    pub fn from_u32(v: u32) -> Self {
159        match v {
160            0x0000_0000 => Self::Unavailable,
161            0x0000_0001..=0xFFFF_FFFE => Self::AvailableBytes(v),
162            0xFFFF_FFFF => Self::Suspend,
163        }
164    }
165
166    pub fn to_u32(self) -> u32 {
167        match self {
168            Self::Unavailable => 0x0000_0000,
169            Self::AvailableBytes(v) => v,
170            Self::Suspend => 0xFFFF_FFFF,
171        }
172    }
173}