Conversation
|
Extremely interested in this PR, what is blocking it, since this is a awesome added feature :D |
Nothing is blocking it - just the time required to review the PR. |
|
@aleitner The usbconnect_handler is defined as a function pointer type and struct member, but there's no implementation assigned to it. It is incomplete same for other functions usbdata_handler and usbdisconnect_handler |
|
@coolkingh Yes, this is the framework for it that provides methods for handling USB device redirection. This particular pull request does not implement it concretely for any of the protocols. Once this pull request is merged the changes can be made at the protocol level (RDP, SSH, etc.) that would actually enable this to function for a particular protocol. |
|
@necouchman What's the point of merging if implementation is incomplete for any of the protocol. |
|
@coolkingh The point is that the base components - the Guacamole protocol bits and hooks for the handler functions - are available in case someone wants to use them. The second sentence of this pull request says:
This indicates to me that @aleitner never intended this pull request to fully implement USB redirection support in any of the protocols, but only to provide these core components. There are several reasons why we might decide to merge only the core framework components and not the protocol-specific implementations. We often break complex implementations into multiple pull requests, where a more basic or foundational level of code is done prior to the detailed or specific implementations. It can make it easier to track down when bugs are introduced, it helps to break up work among people who have varying degrees of time and expertise, etc. In the case of WebUSB support, I would imagine that this part - the addition of it to the Guacamole protocol and the implementation of the hooks - is the simpler part, whereas implementing the actual protocol-level of support will require a lot more time and effort to hook in these handlers to FreeRDP, libssh, libvncserver, etc. It makes sense to go ahead and get the framework/infrastructure out and available so that others who want to work on the protocol-level components can do so. |
necouchman
left a comment
There was a problem hiding this comment.
@aleitner Overall looks pretty good to me - my comments are mostly about documentation and not the actual implementation, aside from the one question about a protocol-level usbconnect function.
necouchman
left a comment
There was a problem hiding this comment.
@aleitner One more comment, but, also, it looks like you added the RDP functionality, here - not sure if that was intended or not? Also, with that change, the check of the PR is failing, as the build has an issue.
| * @param interface_data | ||
| * Encoded string containing interface and endpoint information. Required. | ||
| * Format: "ifaceNum:class:subclass:protocol:ep1Num:ep1Dir:ep1Type:ep1Size;ep2...,iface2..." | ||
| * where multiple endpoints within an interface are separated by semicolons | ||
| * and multiple interfaces are separated by commas. |
There was a problem hiding this comment.
A couple of more question from me, here, regarding this...
First, are the format and fields of this interface_data parameter something standard an well-known/documented when dealing with USB devices? Is this data that will be provided automatically by the web browser, or something that it would be expected that someone would know how and what to assemble for it? I can kind of guess what each of the fields means, but a few are a bit obscure.
Somewhat related, it looks like some of the data in this interface_data field is the same as the other parameters to the function (class, subclass, protocol). How does that work out between the parameters provided in the function and the interface data? Should they always be identical? Or are there situations where the individual interfaces will differ from the overall "device" being connected?
I ask for two reasons:
- Curiosity, so I understand better how it works.
- To make sure we're not sending duplicate data, both for efficiency but also because of the risk that it'll be mis-matched.
There was a problem hiding this comment.
The format ifaceNum:class:subclass:protocol:ep1Num:ep1Dir:ep1Type:ep1Size;ep2...,iface2... is not a USB standard. It's a custom encoding I set up for this Guacamole protocol.
The data itself comes from standard USB descriptors that the browser's WebUSB API provides automatically. We can see in ManagedUSB.js in our client PR that we're just reading properties that WebUSB gives us:
alt.interfaceClass // Standard USB class code
alt.interfaceSubclass // Standard USB subclass code
alt.interfaceProtocol // Standard USB protocol code
ep.endpointNumber // Standard USB endpoint number
ep.direction // 'in' or 'out'
ep.type // 'bulk', 'interrupt', 'isochronous'
ep.packetSize // Max packet size in bytes
These are all standard USB descriptor fields defined in the USB specification. We're just encoding them into a string format for sending over the Guacamole protocol.
As you pointed out thoguh we can see that USB has class/subclass/protocol at two levels.
These describe the overall device and are often set to 0 for composite devices:
device_class,device_subclass,device_protocol
Composite devices like webcams with microphones commonly use:
- Device class 0xEF (Miscellaneous Device)
- Device subclass 0x02 (Common Class)
- Device protocol 0x01 (Interface Association Descriptor)
These describe each individual interface and is where the actual functionality is usually defined:
interfaceClass,interfaceSubclass,interfaceProtocol
HID devices like keyboards/mice commonly have:
- Device class 0x00 (defined at interface level)
- Interface class 0x03 (HID)
- Interface subclass 0x01 (Boot Interface)
- Interface protocol 0x01 (Keyboard) or 0x02 (Mouse)
- Interface 0: class=0x03 (HID), subclass=0x01 (Boot), protocol=0x01 (Keyboard)
There was a problem hiding this comment.
Okay - I'd suggest this all of this - both the encoding of the fields for Guacamole, and the way composite devices are handled - get documented somewhere - I'm not really sure if the code is the best place, or the manual, but I think it'd be useful for folks looking to implement USB functionality with Guacamole to know how we're handling this data.
f9df463 to
73b5861
Compare
Whoops, didn't mean to push the rdp code as that has a good bit of work that needs to be done |
This PR implements the server-side protocol support for Web USB device redirection, complementing the client-side PR. This provides the infrastructure for Guacamole protocol plugins (RDP, VNC, etc.) to handle USB device redirection from browser clients.
Data Flow
usbconnectwith device descriptors and interface/endpoint datausbconnect_handleris invoked to establish redirectionusbdatamessages flow between client device and server handlerusbdisconnectNew Protocol Instructions
usbdataandusbdisconnectinstructions for sending data to USB devices and requesting disconnectionusbconnect,usbdata, andusbdisconnectinstructionsHandlers
guac_user_usbconnect_handler: Processes USB device connections with full device metadata (vendor/product IDs, interfaces, endpoints)guac_user_usbdata_handler: Handles USB data transfer from the client with USB endpoint and transfer type information.guac_user_usbdisconnect_handler: Manages USB device disconnection events.