Skip to content

feat(rdpeusb): implement urbdrc client#1365

Open
uchouT (uchouT) wants to merge 3 commits into
Devolutions:masterfrom
uchouT:urbdrc-client
Open

feat(rdpeusb): implement urbdrc client#1365
uchouT (uchouT) wants to merge 3 commits into
Devolutions:masterfrom
uchouT:urbdrc-client

Conversation

@uchouT

@uchouT uchouT (uchouT) commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Resolves #1137

The device dvc processor manages a pending_io map internally and offers API for upper layer to construct completion DvcMessage.

@uchouT uchouT (uchouT) marked this pull request as draft June 9, 2026 09:42
@uchouT uchouT (uchouT) marked this pull request as ready for review June 10, 2026 08:36
@uchouT

uchouT (uchouT) commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Marc-Andre Lureau (@elmarco) Benoît Cortier (@CBenoit)
Hi, I've implemented the DVC processors for the urbdrc client. I would like to implement the urbdrc listener in a subsequent PR, as this PR has become too large and will require some modifications to drdynvc.

[EDIT]: UrbdrcListener is implemented in this PR.

@uchouT uchouT (uchouT) changed the title feat(rdpeusb): implement urbdrc control client feat(rdpeusb): implement urbdrc client dvc processor Jun 10, 2026
@uchouT uchouT (uchouT) changed the title feat(rdpeusb): implement urbdrc client dvc processor feat(rdpeusb): implement urbdrc client Jun 11, 2026
@uchouT uchouT (uchouT) force-pushed the urbdrc-client branch 10 times, most recently from c25c053 to b478576 Compare June 15, 2026 19:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The client state machine currently diverges from the issue’s required startup sequencing and adds substantial new protocol logic without the acceptance-criteria unit tests.

Pull request overview

Adds an ironrdp-rdpeusb client-side implementation of the URBDRC dynamic virtual channel, including a control-channel processor, per-device channel processor, and backend-neutral device metadata conversion used to construct RDPEUSB PDUs.

Changes:

  • Introduces UrbdrcListener, UrbdrcControlClient, and UrbdrcDeviceClient with a backend trait surface and pending-IO completion helpers.
  • Adds backend-neutral DeviceInfoADD_DEVICE conversion (PnP-style IDs, container IDs, capabilities) following observed FreeRDP behavior.
  • Integrates RDPEUSB PDUs with the DVC layer by implementing ironrdp_dvc::DvcEncode and adding an ironrdp-dvc dependency.
File summaries
File Description
crates/ironrdp-rdpeusb/src/pdu/usb_dev/mod.rs Adds DvcEncode impls and a helper to extract transfer request IDs.
crates/ironrdp-rdpeusb/src/pdu/sink.rs Marks sink PDUs as DVC-encodable (DvcEncode).
crates/ironrdp-rdpeusb/src/pdu/notify.rs Marks CHANNEL_CREATED as DVC-encodable (DvcEncode).
crates/ironrdp-rdpeusb/src/pdu/iface_manipulation.rs Marks interface-manipulation PDUs as DVC-encodable (DvcEncode).
crates/ironrdp-rdpeusb/src/pdu/header.rs Exposes InterfaceId::from_raw within the crate for client allocation.
crates/ironrdp-rdpeusb/src/pdu/completion/mod.rs Marks completion PDUs as DVC-encodable (DvcEncode).
crates/ironrdp-rdpeusb/src/pdu/caps.rs Marks capability PDUs as DVC-encodable (DvcEncode).
crates/ironrdp-rdpeusb/src/lib.rs Adds channel name, exports client module, and introduces InvalidDeviceInterfaceId error type.
crates/ironrdp-rdpeusb/src/client/mod.rs Implements the URBDRC listener + control/device client processors and backend traits.
crates/ironrdp-rdpeusb/src/client/device.rs Implements backend-neutral USB device facts and ADD_DEVICE PDU construction.
crates/ironrdp-rdpeusb/Cargo.toml Adds public dependency on ironrdp-dvc.
Cargo.lock Records the new ironrdp-dvc dependency edge.

Copilot's findings

  • Files reviewed: 11/12 changed files
  • Comments generated: 8

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +67 to +90
const fn alloc(&mut self) -> InterfaceId {
self.id += 1;
if self.id > 0x3F_FF_FF_FF {
panic!("USB device amount overflow")
}
InterfaceId::from_raw(self.id)
}
}

impl DvcChannelListener for UrbdrcListener {
fn channel_name(&self) -> &str {
CHANNEL_NAME
}

fn create(&mut self, channel_id: u32) -> Option<Box<dyn DvcProcessor>> {
if let Some(callback) = self.on_capability_exchanged.take() {
self.device_man.control_channel_assigned(channel_id);
Some(Box::new(UrbdrcControlClient::new(callback)))
} else {
#[expect(clippy::as_conversions)]
self.device_man.take_device_for_channel(channel_id).map(|backend| {
Box::new(UrbdrcDeviceClient::new(self.iface_man.alloc(), backend).expect("invalid interface id"))
as Box<dyn DvcProcessor>
})
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
Comment thread crates/ironrdp-rdpeusb/src/lib.rs Outdated
Comment thread crates/ironrdp-rdpeusb/src/client/mod.rs
uchouT (uchouT) and others added 3 commits June 18, 2026 02:31
Signed-off-by: uchouT <i@uchout.moe>
`ADD_DEVICE` message is constructed following FreeRDP's pattern.

`UrbdrcDeviceClient` maintains a pending IO request map. When the packet
is handled asynchronously, the information for the completion message
construction (such as output buffer size) will be stored in this map,
and `UrbdrcDeviceClient` provides public APIs for completion message
construction, which will consume the map items internally.

Signed-off-by: uchouT <i@uchout.moe>
Signed-off-by: uchouT <i@uchout.moe>

Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@uchouT

Copy link
Copy Markdown
Contributor Author

Updated ironrdp-dvc deps to launch ci, and accepted style suggestions by Copilot. No other changes. Benoît Cortier (@CBenoit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[ironrdp-rdpeusb] Client-side protocol state machine

2 participants