@@ -5,6 +5,7 @@ use core::any::TypeId;
55use core:: fmt;
66
77use crate :: alloc:: borrow:: ToOwned as _;
8+ use crate :: complete_data:: CompleteData ;
89use ironrdp_core:: { Decode as _, DecodeResult , ReadCursor , impl_as_any} ;
910use ironrdp_pdu:: { self as pdu, decode_err, encode_err, pdu_other_err} ;
1011use ironrdp_svc:: { ChannelFlags , CompressionCondition , SvcClientProcessor , SvcMessage , SvcProcessor } ;
@@ -14,9 +15,9 @@ use tracing::debug;
1415
1516use crate :: pdu:: {
1617 CapabilitiesResponsePdu , CapsVersion , ClosePdu , CreateResponsePdu , CreationStatus , DrdynvcClientPdu ,
17- DrdynvcServerPdu ,
18+ DrdynvcDataPdu , DrdynvcServerPdu ,
1819} ;
19- use crate :: { DvcProcessor , DynamicChannelId , DynamicChannelName , DynamicVirtualChannel , encode_dvc_messages} ;
20+ use crate :: { DvcMessage , DvcProcessor , DynamicChannelId , DynamicChannelName , encode_dvc_messages} ;
2021
2122pub trait DvcClientProcessor : DvcProcessor { }
2223
@@ -56,6 +57,73 @@ impl DvcChannelListener for OnceListener {
5657 }
5758}
5859
60+ pub struct DynamicVirtualChannel {
61+ channel_processor : Box < dyn DvcClientProcessor + Send > ,
62+ complete_data : CompleteData ,
63+ /// The channel ID assigned by the server.
64+ ///
65+ /// `Some` only after [`DynamicVirtualChannel::start`] has succeeded. This invariant
66+ channel_id : Option < DynamicChannelId > ,
67+ }
68+
69+ impl Drop for DynamicVirtualChannel {
70+ fn drop ( & mut self ) {
71+ if let Some ( id) = self . channel_id {
72+ self . channel_processor . close ( id) ;
73+ }
74+ }
75+ }
76+
77+ impl DynamicVirtualChannel {
78+ fn from_boxed ( processor : Box < dyn DvcClientProcessor + Send > ) -> Self {
79+ Self {
80+ channel_processor : processor,
81+ complete_data : CompleteData :: new ( ) ,
82+ channel_id : None ,
83+ }
84+ }
85+
86+ fn processor_type_id ( & self ) -> TypeId {
87+ self . channel_processor . as_any ( ) . type_id ( )
88+ }
89+
90+ pub fn is_open ( & self ) -> bool {
91+ self . channel_id . is_some ( )
92+ }
93+
94+ pub fn channel_id ( & self ) -> Option < DynamicChannelId > {
95+ self . channel_id
96+ }
97+
98+ pub fn channel_processor_downcast_ref < T : DvcClientProcessor > ( & self ) -> Option < & T > {
99+ self . channel_processor . as_any ( ) . downcast_ref ( )
100+ }
101+
102+ pub fn channel_processor_downcast_mut < T : DvcClientProcessor > ( & mut self ) -> Option < & mut T > {
103+ self . channel_processor . as_any_mut ( ) . downcast_mut ( )
104+ }
105+
106+ fn start ( & mut self , channel_id : DynamicChannelId ) -> PduResult < Vec < DvcMessage > > {
107+ let messages = self . channel_processor . start ( channel_id) ?;
108+ self . channel_id = Some ( channel_id) ;
109+ Ok ( messages)
110+ }
111+
112+ fn process ( & mut self , pdu : DrdynvcDataPdu ) -> PduResult < Vec < DvcMessage > > {
113+ let channel_id = pdu. channel_id ( ) ;
114+ let complete_data = self . complete_data . process_data ( pdu) . map_err ( |e| decode_err ! ( e) ) ?;
115+ if let Some ( complete_data) = complete_data {
116+ self . channel_processor . process ( channel_id, & complete_data)
117+ } else {
118+ Ok ( Vec :: new ( ) )
119+ }
120+ }
121+
122+ fn channel_name ( & self ) -> & str {
123+ self . channel_processor . channel_name ( )
124+ }
125+ }
126+
59127/// DRDYNVC Static Virtual Channel (the Remote Desktop Protocol: Dynamic Virtual Channel Extension)
60128///
61129/// It adds support for dynamic virtual channels (DVC).
0 commit comments