|
Packit |
9795e1 |
USB Network Redirection protocol description version 0.7 (19 May 2014)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Revisions
|
|
Packit |
9795e1 |
---------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.1
|
|
Packit |
9795e1 |
-Initial version (released as initial RFC without a version number)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.2
|
|
Packit |
9795e1 |
-Version demo-ed at FOSDEM 2011
|
|
Packit |
9795e1 |
-Remove usb_redir_report_descriptor packet, as it is not possible to get
|
|
Packit |
9795e1 |
the cached descriptors from the OS on all platforms and we can do without
|
|
Packit |
9795e1 |
-Replace vm-host with usb-guest
|
|
Packit |
9795e1 |
-Replace the synchroneous / asynchroneous commands nomenclature with
|
|
Packit |
9795e1 |
control / data packets
|
|
Packit |
9795e1 |
-Move the packet id to the main packet header shared by all packets
|
|
Packit |
9795e1 |
-Add note: "All integers in the protocol are send over the pipe in least
|
|
Packit |
9795e1 |
significant byte first order."
|
|
Packit |
9795e1 |
-Add note: "All structs are packed"
|
|
Packit |
9795e1 |
-s/data_size/length/
|
|
Packit |
9795e1 |
-Add an usb_redir_cancel_data_packet packet
|
|
Packit |
9795e1 |
-Add usb_redir_reset and usb_redir_reset_status packets
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.3, released 14 July 2011
|
|
Packit |
9795e1 |
-First "stable" version, all later versions should be compatible with this
|
|
Packit |
9795e1 |
version
|
|
Packit |
9795e1 |
-Add an usb_redir_device_connect packet
|
|
Packit |
9795e1 |
-Add an usb_redir_device_disconnect packet
|
|
Packit |
9795e1 |
-Add an usb_redir_interface_info packet
|
|
Packit |
9795e1 |
-Add an usb_redir_ep_info packet
|
|
Packit |
9795e1 |
-Add support for interrupt transfers, add the following packets:
|
|
Packit |
9795e1 |
usb_redir_start_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_interrupt_receiving_status
|
|
Packit |
9795e1 |
usb_redir_interrupt_packet
|
|
Packit |
9795e1 |
-Add a list with the possible values for the status field
|
|
Packit |
9795e1 |
-Report usb_redir_stall as iso status error to indicate a stream stop
|
|
Packit |
9795e1 |
-Drop usb_redir_disconnect status, instead the usb-host should always
|
|
Packit |
9795e1 |
send a usb_redir_device_disconnect packet on device disconnection. The
|
|
Packit |
9795e1 |
reason behind this is that having to handle disconnection from data packet
|
|
Packit |
9795e1 |
handlers make things unnecessarily hard for the usb-guest
|
|
Packit |
9795e1 |
-Drop usb_redir_reset_status, instead if reconnecting to the device fails
|
|
Packit |
9795e1 |
after reset the usb-host will send a usb_redir_device_disconnect packet
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.3.1, released 18 August 2011
|
|
Packit |
9795e1 |
- No protocol changes
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.3.2, released 3 January 2012
|
|
Packit |
9795e1 |
-The usb_redir_device_connect_header has been extended with a
|
|
Packit |
9795e1 |
device_version_bcd field. This is only send / received if both sides
|
|
Packit |
9795e1 |
have the usb_redir_cap_connect_device_version capability
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.3.3, released 12 January 2012
|
|
Packit |
9795e1 |
- No protocol changes
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.4, released 22 February 2012
|
|
Packit |
9795e1 |
- Add usb_redir_filter_reject and usb_redir_filter_filter packets and
|
|
Packit |
9795e1 |
an usb_redir_cap_filter capability flag
|
|
Packit |
9795e1 |
- Add an usb_redir_device_disconnect_ack packet and
|
|
Packit |
9795e1 |
an usb_redir_cap_device_disconnect_ack capability flag
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.4.1, released 25 February 2012
|
|
Packit |
9795e1 |
- No protocol changes
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.4.2, released 6 March 2012
|
|
Packit |
9795e1 |
- Add usb_redir_babble status code
|
|
Packit |
9795e1 |
- The usb_redir_ep_info_header has been extended with a max_packet_size field
|
|
Packit |
9795e1 |
This is only send / received if both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_ep_info_max_packet_size capability
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.5, released 7 September 2012
|
|
Packit |
9795e1 |
- Add the posibility to use 64 bits packet ids
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.5.3, released 7 October 2012
|
|
Packit |
9795e1 |
- Extend the length field in bulk packets headers to 32 bits, the extra 16
|
|
Packit |
9795e1 |
bits are only send / received if both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_32bits_bulk_length capability
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.6, released 13 December 2012
|
|
Packit |
9795e1 |
- Add support for buffered bulk input, new packets:
|
|
Packit |
9795e1 |
usb_redir_start_bulk_receiving, usb_redir_stop_bulk_receiving,
|
|
Packit |
9795e1 |
usb_redir_bulk_receiving_status, usb_redir_buffered_bulk_packet
|
|
Packit |
9795e1 |
New capability: usb_redir_cap_bulk_receiving
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Version 0.7, released 19 May 2014
|
|
Packit |
9795e1 |
- The usb_redir_ep_info_header has been extended with a max_streams field
|
|
Packit |
9795e1 |
This is only send / received if both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_streams capability.
|
|
Packit |
9795e1 |
- Change bulk_stream packet definitions to allow allocating / freeing
|
|
Packit |
9795e1 |
streams on multiple endpoints in one go, technically this is a protocol
|
|
Packit |
9795e1 |
change, but no-one has implemented usb_redir_cap_bulk_streams so far, so
|
|
Packit |
9795e1 |
we can safely do this
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
USB redirection protocol version 0.7
|
|
Packit |
9795e1 |
------------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The protocol described in this document is meant for tunneling usb transfers
|
|
Packit |
9795e1 |
to a single usb device. Note: not an entire hub, only a single device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The most significant use case for this is taking a usb device attached to
|
|
Packit |
9795e1 |
some machine "a" which acts as a client / viewer to a virtual machine "v"
|
|
Packit |
9795e1 |
hosted on another machine "b", and make the usb device show up inside the
|
|
Packit |
9795e1 |
virtual machine as if it were attached directly to the virtual machine "v".
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The described protocol assumes a reliable ordered bidirectional transport is
|
|
Packit |
9795e1 |
available, for example a tcp socket. All integers in the protocol are send
|
|
Packit |
9795e1 |
over the pipe in least significant byte first order. All structs send over
|
|
Packit |
9795e1 |
the pipe are packed (no padding).
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Definitions:
|
|
Packit |
9795e1 |
usb-device: The usb-device whose usb transfers are being tunneled.
|
|
Packit |
9795e1 |
usb-guest: The entity connecting to the usb-device and using it as if
|
|
Packit |
9795e1 |
connected directly to it. For example a virtual machine running a guest
|
|
Packit |
9795e1 |
os which accesses a usb-device over the network as if it is part of the
|
|
Packit |
9795e1 |
virtual machine.
|
|
Packit |
9795e1 |
usb-host: The entity making the usb-device available for use by a usb-guest.
|
|
Packit |
9795e1 |
For example a daemon on a machine which "exports" the usb-device over the
|
|
Packit |
9795e1 |
network which then "appears" inside a virtual machine on another machine.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Basic packet structure / communication
|
|
Packit |
9795e1 |
--------------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Each packet exchanged between the usb-guest and the usb-host starts with a
|
|
Packit |
9795e1 |
usb_redir_header, followed by an optional packet type specific header
|
|
Packit |
9795e1 |
follow by optional additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The usb_redir_header each packet starts with looks as follows:
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_header {
|
|
Packit |
9795e1 |
uint32_t type;
|
|
Packit |
9795e1 |
uint32_t length;
|
|
Packit |
9795e1 |
uint32_t id;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Or, if both sides have the usb_redir_cap_64bits_ids capability, it looks as
|
|
Packit |
9795e1 |
follows! :
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_header {
|
|
Packit |
9795e1 |
uint32_t type;
|
|
Packit |
9795e1 |
uint32_t length;
|
|
Packit |
9795e1 |
uint64_t id;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
type: This identifies the type of packet, from the type enum
|
|
Packit |
9795e1 |
length: Length of the optional type specific packet header + the optional
|
|
Packit |
9795e1 |
additional data. Can be 0.
|
|
Packit |
9795e1 |
id: A unique id, generated by the usb-guest when sending a packet,
|
|
Packit |
9795e1 |
the usb-host will use the same id in its response packet, allowing
|
|
Packit |
9795e1 |
the usb-guest to match responses to its original requests.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
There are 2 types of packets:
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
1) control packets
|
|
Packit |
9795e1 |
2) data packets
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Control packets are handled synchroneously inside the usb-host, it will hand
|
|
Packit |
9795e1 |
the request over to the host os and then *wait* for a response. The usb-host
|
|
Packit |
9795e1 |
will thus stop processing further packets. Where as for data packets the
|
|
Packit |
9795e1 |
usb-host hands them over to the host os with the request to let the usb-host
|
|
Packit |
9795e1 |
process know when there is a response from the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that control packets should only be send to the usb-host when no data
|
|
Packit |
9795e1 |
packets are pending on the device / interface / endpoint affected by the
|
|
Packit |
9795e1 |
control packet. Any pending data packets will get dropped, and any active
|
|
Packit |
9795e1 |
iso streams / allocated bulk streams will get stopped / free-ed.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Packet type list
|
|
Packit |
9795e1 |
----------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
control packets:
|
|
Packit |
9795e1 |
usb_redir_hello
|
|
Packit |
9795e1 |
usb_redir_device_connect
|
|
Packit |
9795e1 |
usb_redir_device_disconnect
|
|
Packit |
9795e1 |
usb_redir_reset
|
|
Packit |
9795e1 |
usb_redir_interface_info
|
|
Packit |
9795e1 |
usb_redir_ep_info
|
|
Packit |
9795e1 |
usb_redir_set_configuration
|
|
Packit |
9795e1 |
usb_redir_get_configuration
|
|
Packit |
9795e1 |
usb_redir_configuration_status
|
|
Packit |
9795e1 |
usb_redir_set_alt_setting
|
|
Packit |
9795e1 |
usb_redir_get_alt_setting
|
|
Packit |
9795e1 |
usb_redir_alt_setting_status
|
|
Packit |
9795e1 |
usb_redir_start_iso_stream
|
|
Packit |
9795e1 |
usb_redir_stop_iso_stream
|
|
Packit |
9795e1 |
usb_redir_iso_stream_status
|
|
Packit |
9795e1 |
usb_redir_start_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_interrupt_receiving_status
|
|
Packit |
9795e1 |
usb_redir_alloc_bulk_streams
|
|
Packit |
9795e1 |
usb_redir_free_bulk_streams
|
|
Packit |
9795e1 |
usb_redir_bulk_streams_status
|
|
Packit |
9795e1 |
usb_redir_cancel_data_packet
|
|
Packit |
9795e1 |
usb_redir_filter_reject
|
|
Packit |
9795e1 |
usb_redir_filter_filter
|
|
Packit |
9795e1 |
usb_redir_device_disconnect_ack
|
|
Packit |
9795e1 |
usb_redir_start_bulk_receiving
|
|
Packit |
9795e1 |
usb_redir_stop_bulk_receiving
|
|
Packit |
9795e1 |
usb_redir_bulk_receiving_status
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
data packets:
|
|
Packit |
9795e1 |
usb_redir_control_packet
|
|
Packit |
9795e1 |
usb_redir_bulk_packet
|
|
Packit |
9795e1 |
usb_redir_iso_packet
|
|
Packit |
9795e1 |
usb_redir_interrupt_packet
|
|
Packit |
9795e1 |
usb_redir_buffered_bulk_packet
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Status code list
|
|
Packit |
9795e1 |
----------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Many usb-host replies have a status field, this field can have the following
|
|
Packit |
9795e1 |
values:
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
enum {
|
|
Packit |
9795e1 |
usb_redir_success,
|
|
Packit |
9795e1 |
usb_redir_cancelled, /* The transfer was cancelled */
|
|
Packit |
9795e1 |
usb_redir_inval, /* Invalid packet type / length / ep, etc. */
|
|
Packit |
9795e1 |
usb_redir_ioerror, /* IO error */
|
|
Packit |
9795e1 |
usb_redir_stall, /* Stalled */
|
|
Packit |
9795e1 |
usb_redir_timeout, /* Request timed out */
|
|
Packit |
9795e1 |
usb_redir_babble, /* The device has "babbled" */
|
|
Packit |
9795e1 |
};
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that in future versions there may be additional status codes to signal
|
|
Packit |
9795e1 |
new / other *error* conditions. So any unknown status value should be
|
|
Packit |
9795e1 |
interpreted as an error.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_hello
|
|
Packit |
9795e1 |
---------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_hello
|
|
Packit |
9795e1 |
usb_redir_header.length: <see description>
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_hello_header {
|
|
Packit |
9795e1 |
char version[64];
|
|
Packit |
9795e1 |
uint32_t capabilities[0];
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
A packet of this type is send by both sides as soon as a connection is
|
|
Packit |
9795e1 |
establised. It is mandatory that this packet is the first packet send by
|
|
Packit |
9795e1 |
both sides! This packet contains:
|
|
Packit |
9795e1 |
version: A free form 0 terminated version string, useful for logging
|
|
Packit |
9795e1 |
should not be parsed! Suggested format: "qemu 0.13",
|
|
Packit |
9795e1 |
"usb-redir-daemon 0.1", etc.
|
|
Packit |
9795e1 |
capabilities: A variable length array for announcing capabilities.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that since the peer caps are not known until the usb_redir_hello
|
|
Packit |
9795e1 |
packet is received, the hello packet always has 32 bits id fields!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The value of the length field depends on the size of the capabilities array.
|
|
Packit |
9795e1 |
If we cross the 32 capabilities count, it will go from 1 uint32_t to 2,
|
|
Packit |
9795e1 |
etc. the value is 64 + capabilities-array-size * sizeof(uint32_t).
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Currently the following capabilities are defined:
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
enum {
|
|
Packit |
9795e1 |
/* Supports USB 3 bulk streams */
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_streams,
|
|
Packit |
9795e1 |
/* The device_connect packet has the device_version_bcd field */
|
|
Packit |
9795e1 |
usb_redir_cap_connect_device_version,
|
|
Packit |
9795e1 |
/* Supports usb_redir_filter_reject and usb_redir_filter_filter pkts */
|
|
Packit |
9795e1 |
usb_redir_cap_filter,
|
|
Packit |
9795e1 |
/* Supports the usb_redir_device_disconnect_ack packet */
|
|
Packit |
9795e1 |
usb_redir_cap_device_disconnect_ack,
|
|
Packit |
9795e1 |
/* The ep_info packet has the max_packet_size field */
|
|
Packit |
9795e1 |
usb_redir_cap_ep_info_max_packet_size,
|
|
Packit |
9795e1 |
/* Supports 64 bits ids in usb_redir_header */
|
|
Packit |
9795e1 |
usb_redir_cap_64bits_ids,
|
|
Packit |
9795e1 |
/* Supports 32 bits length in usb_redir_bulk_packet_header */
|
|
Packit |
9795e1 |
usb_redir_cap_32bits_bulk_length,
|
|
Packit |
9795e1 |
/* Supports bulk receiving / buffered bulk input */
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_receiving,
|
|
Packit |
9795e1 |
};
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_device_connect
|
|
Packit |
9795e1 |
------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_device_connect
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_device_connect_header)
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
enum {
|
|
Packit |
9795e1 |
usb_redir_speed_low,
|
|
Packit |
9795e1 |
usb_redir_speed_full,
|
|
Packit |
9795e1 |
usb_redir_speed_high,
|
|
Packit |
9795e1 |
usb_redir_speed_super,
|
|
Packit |
9795e1 |
usb_redir_speed_unknown = 255
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_device_connect_header {
|
|
Packit |
9795e1 |
uint8_t speed;
|
|
Packit |
9795e1 |
uint8_t device_class;
|
|
Packit |
9795e1 |
uint8_t device_subclass;
|
|
Packit |
9795e1 |
uint8_t device_protocol;
|
|
Packit |
9795e1 |
uint16_t vendor_id;
|
|
Packit |
9795e1 |
uint16_t product_id;
|
|
Packit |
9795e1 |
uint16_t device_version_bcd;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet gets send by the usb-host when a device becomes available (it is
|
|
Packit |
9795e1 |
possible for the usb-host to wait for a device to get plugged in).
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The device_version_bcd field should only be send (and expected on receive)
|
|
Packit |
9795e1 |
when both sides have the usb_redir_cap_connect_device_version capability.
|
|
Packit |
9795e1 |
If this is not the case the length of the packet will be 2 bytes less!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that a usb-host may re-use the existing connection for a new / re-plugged
|
|
Packit |
9795e1 |
device in this case this packet can be send after a usb_redir_device_disconnect
|
|
Packit |
9795e1 |
message to notify the usb-guest that a new device is available.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note the usbredir-host *must* first send usb_redir_ep_info followed by
|
|
Packit |
9795e1 |
usb_redir_interface_info before sending the usb_redir_device_connect_info!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_device_disconnect
|
|
Packit |
9795e1 |
---------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_device_disconnect
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet may be send by the usb-host to indicate that the device has been
|
|
Packit |
9795e1 |
disconnect (unplugged). Note on some platforms the usb-host may not become
|
|
Packit |
9795e1 |
aware of the disconnection until a usb packet is send to the device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_reset
|
|
Packit |
9795e1 |
---------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_reset
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to cause a reset of the usb
|
|
Packit |
9795e1 |
device. Note that of things go wrong the usb-host may be unable to re-connect
|
|
Packit |
9795e1 |
to the device after the reset! If this happens a usb_redir_device_disconnect
|
|
Packit |
9795e1 |
packet will be send by the usb-host.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_interface_info
|
|
Packit |
9795e1 |
------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_interface_info
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_interface_info_header)
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_interface_info_header {
|
|
Packit |
9795e1 |
uint32_t interface_count;
|
|
Packit |
9795e1 |
uint8_t interface[32];
|
|
Packit |
9795e1 |
uint8_t interface_class[32];
|
|
Packit |
9795e1 |
uint8_t interface_subclass[32];
|
|
Packit |
9795e1 |
uint8_t interface_protocol[32];
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet gets send by the usb-host to inform the usb-guest about the
|
|
Packit |
9795e1 |
interfaces of the device. It contains the interface number, class and protocol
|
|
Packit |
9795e1 |
info for interface_count interfaces. This gets send after a (successful)
|
|
Packit |
9795e1 |
initial connection, set_config and set_alt_setting.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_ep_info
|
|
Packit |
9795e1 |
-----------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_ep_info
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_ep_info_header)
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
enum {
|
|
Packit |
9795e1 |
/* Note these 4 match the usb spec! */
|
|
Packit |
9795e1 |
usb_redir_type_control,
|
|
Packit |
9795e1 |
usb_redir_type_iso,
|
|
Packit |
9795e1 |
usb_redir_type_bulk,
|
|
Packit |
9795e1 |
usb_redir_type_interrupt,
|
|
Packit |
9795e1 |
usb_redir_type_invalid = 255
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_ep_info_header {
|
|
Packit |
9795e1 |
uint8_t type[32];
|
|
Packit |
9795e1 |
uint8_t interval[32];
|
|
Packit |
9795e1 |
uint8_t interface[32];
|
|
Packit |
9795e1 |
uint16_t max_packet_size[32];
|
|
Packit |
9795e1 |
uint32_t max_streams[32];
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet gets send by the usb-host to let the usb-guest know the endpoint
|
|
Packit |
9795e1 |
type, interval and interface it belongs to for all possible endpoints,
|
|
Packit |
9795e1 |
first 0-15 out, then 0-15 in. This gets send after a (successful) initial
|
|
Packit |
9795e1 |
connection, set_config and set_alt_setting.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The max_packet_size field should only be send (and expected on receive)
|
|
Packit |
9795e1 |
when both sides have the usb_redir_cap_ep_info_max_packet_size capability.
|
|
Packit |
9795e1 |
If this is not the case the length of the packet will be 64 bytes less!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The max_streams field should only be send (and expected on receive)
|
|
Packit |
9795e1 |
when both sides have the usb_redir_cap_bulk_streams capability. If this is
|
|
Packit |
9795e1 |
not the case the length of the packet will be 128 bytes less!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note implementations with the usb_redir_cap_bulk_streams capability must
|
|
Packit |
9795e1 |
always also have the usb_redir_cap_ep_info_max_packet_size capability.
|
|
Packit |
9795e1 |
Advertising usb_redir_cap_bulk_streams without
|
|
Packit |
9795e1 |
usb_redir_cap_ep_info_max_packet_size is not allowed!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_set_configuration
|
|
Packit |
9795e1 |
---------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_set_configuration
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_set_configuration_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_set_configuration_header {
|
|
Packit |
9795e1 |
uint8_t configuration;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to set (change) the active
|
|
Packit |
9795e1 |
configuration of the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_get_configuration
|
|
Packit |
9795e1 |
---------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_get_configuration
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to get (query) the active
|
|
Packit |
9795e1 |
configuration of the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_configuration_status
|
|
Packit |
9795e1 |
------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_configuration_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_configuration_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_configuration_status_header {
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint8_t configuration;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This is send by the usb-host in response to a usb_redir_set_configuration /
|
|
Packit |
9795e1 |
usb_redir_get_configuration packet. It reports a status code and on success
|
|
Packit |
9795e1 |
the resulting / active configuration.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that after a successful usb_redir_set_configuration command the
|
|
Packit |
9795e1 |
usbredir-host *must* first send usb_redir_ep_info followed by
|
|
Packit |
9795e1 |
usb_redir_interface_info before sending the usb_redir_configuration_status,
|
|
Packit |
9795e1 |
to ensure the usb-guest has the new info when it starts using the new
|
|
Packit |
9795e1 |
configuration.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_set_alt_setting
|
|
Packit |
9795e1 |
-------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_set_alt_setting
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_set_alt_setting_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_set_alt_setting_header {
|
|
Packit |
9795e1 |
uint8_t interface;
|
|
Packit |
9795e1 |
uint8_t alt;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to set (change) the alt_setting of
|
|
Packit |
9795e1 |
interface <interface> to <alt>.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_get_alt_setting
|
|
Packit |
9795e1 |
---------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_get_alt_setting
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_get_alt_setting_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_get_alt_setting_header {
|
|
Packit |
9795e1 |
uint8_t interface;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to get (query) the active
|
|
Packit |
9795e1 |
alt_setting of an interface of the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_alt_setting_status
|
|
Packit |
9795e1 |
----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_alt_setting_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_alt_setting_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_alt_setting_status_header {
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint8_t interface;
|
|
Packit |
9795e1 |
uint8_t alt;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This is send by the usb-host in response to a usb_redir_set_alt_setting /
|
|
Packit |
9795e1 |
usb_redir_get_alt_setting packet. It reports a status code, the affected
|
|
Packit |
9795e1 |
interface and on success the resulting / active alt_setting for that interface.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that after a successful usb_redir_set_alt_setting command the
|
|
Packit |
9795e1 |
usbredir-host *must* first send usb_redir_ep_info followed by
|
|
Packit |
9795e1 |
usb_redir_interface_info before sending the usb_redir_alt_setting_status,
|
|
Packit |
9795e1 |
to ensure the usb-guest has the new info when it starts using the new
|
|
Packit |
9795e1 |
alt setting.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_start_iso_stream
|
|
Packit |
9795e1 |
--------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_start_iso_stream
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_start_iso_stream_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_start_iso_stream_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t pkts_per_urb;
|
|
Packit |
9795e1 |
uint8_t no_urbs;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to start a iso stream on the
|
|
Packit |
9795e1 |
designated endpoint of the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This function allocates no_urbs urbs with pkts_per_urb iso packets/frames
|
|
Packit |
9795e1 |
per urb. For iso input endpoints these urbs will get submitted to the
|
|
Packit |
9795e1 |
device *immediately*, for iso output endpoints the usb-host will wait till
|
|
Packit |
9795e1 |
it has received (pkts_per_urb * no_urbs / 2) packets to fill its buffers,
|
|
Packit |
9795e1 |
before submitting the first urb.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_stop_iso_stream
|
|
Packit |
9795e1 |
-------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_stop_iso_stream
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(struct usb_redir_start_iso_stream_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_stop_iso_stream_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to stop an iso stream on the
|
|
Packit |
9795e1 |
designated endpoint. This will cancel all pending urbs, flush the usb-host's
|
|
Packit |
9795e1 |
buffers and free all relevant resources. Note that the usb-guest can still
|
|
Packit |
9795e1 |
receive isoc data packets from an isoc in endpoint after sending this, as
|
|
Packit |
9795e1 |
some data packets may already be inside the transport pipe.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_iso_stream_status
|
|
Packit |
9795e1 |
---------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_iso_stream_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_iso_stream_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_iso_stream_status_header {
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-host in response to a
|
|
Packit |
9795e1 |
usb_redir_start_iso_stream or usb_redir_stop_iso_stream packet. Note that
|
|
Packit |
9795e1 |
for the starting of output iso streams a success status only indicates that
|
|
Packit |
9795e1 |
all the buffers were successfully allocated, the actual stream is not
|
|
Packit |
9795e1 |
started until enough packets are buffered.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that this can also be send unsolicited by a usb-host in case of an
|
|
Packit |
9795e1 |
error with an iso output stream, see usb_redir_iso_packet.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
To allow the usb-guest to detect if the stream was adversely stopped, the
|
|
Packit |
9795e1 |
usb-host will always report usb_redir_stall as status if the stream was
|
|
Packit |
9795e1 |
stopped for any reason other then an usb_redir_stop_iso_stream.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_start_interrupt_receiving
|
|
Packit |
9795e1 |
-----------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_start_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_start_interrupt_receiving_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_start_interrupt_receiving_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to start receiving interrupts
|
|
Packit |
9795e1 |
from the designated endpoint of the usb-device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This function is for *input* interrupt endpoints only. Input interrupt
|
|
Packit |
9795e1 |
endpoints need to be polled timely otherwise data may get lost. So for
|
|
Packit |
9795e1 |
input interrupt endpoints the usb-host takes care of the submitting and
|
|
Packit |
9795e1 |
re-submitting of urbs.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
On receiving this packet the usb-host will start an interrupt transfer
|
|
Packit |
9795e1 |
to the endpoint using the interval and maxPacketSize from the descriptors.
|
|
Packit |
9795e1 |
When this transfer completes, the usb-host will send an
|
|
Packit |
9795e1 |
usb_redir_interrupt_packet to the usb-guest, and will re-submit the urb.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
----------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(struct usb_redir_start_interrupt_receiving_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_stop_interrupt_receiving_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to stop interrupt receiving on the
|
|
Packit |
9795e1 |
designated endpoint. This will cancel the pending urb. Note that the usb-guest
|
|
Packit |
9795e1 |
can still receive usb_redir_interrupt_packet-s after sending this, as
|
|
Packit |
9795e1 |
some data packets may already be inside the transport pipe.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_interrupt_receiving_status
|
|
Packit |
9795e1 |
------------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_interrupt_receiving_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_interrupt_receiving_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_interrupt_receiving_status_header {
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-host in response to a
|
|
Packit |
9795e1 |
usb_redir_start_interrupt_receiving or usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
packet.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that this can also be send unsolicited by a usb-host in case of an
|
|
Packit |
9795e1 |
error re-submitting the interrupt urb.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
To allow the usb-guest to detect if the stream was adversely stopped, the
|
|
Packit |
9795e1 |
usb-host will always report usb_redir_stall as status if the stream was
|
|
Packit |
9795e1 |
stopped for any reason other then an usb_redir_stop_interrupt_receiving.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_alloc_bulk_streams
|
|
Packit |
9795e1 |
----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_alloc_bulk_streams
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_alloc_bulk_streams_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_alloc_bulk_streams_header {
|
|
Packit |
9795e1 |
uint32_t endpoints; /* bitmask indicating on which eps to alloc streams */
|
|
Packit |
9795e1 |
uint32_t no_streams;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to the usb-host to request
|
|
Packit |
9795e1 |
that the usb-host allocates IDs so the usb-guest can use up to no_streams
|
|
Packit |
9795e1 |
stream IDs on the endpoints indicated by the endpoints bitmask. Endpoints in
|
|
Packit |
9795e1 |
the bitmask are indicated by bit number (0-31) using the same numbering as
|
|
Packit |
9795e1 |
in usb_redir_ep_info_header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_free_bulk_streams
|
|
Packit |
9795e1 |
----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_free_bulk_streams
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_free_bulk_streams_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_free_bulk_streams_header {
|
|
Packit |
9795e1 |
uint32_t endpoints; /* bitmask indicating on which eps to free streams */
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to the usb-host to free any
|
|
Packit |
9795e1 |
bulk streams previously allocated on the endpoints indicated by the
|
|
Packit |
9795e1 |
endpoints bitmask.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_bulk_streams_status
|
|
Packit |
9795e1 |
-----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_bulk_streams_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_bulk_streams_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_bulk_streams_status_header {
|
|
Packit |
9795e1 |
uint32_t endpoints; /* bitmask indicating eps this status message is for */
|
|
Packit |
9795e1 |
uint32_t no_streams;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-host in response to a
|
|
Packit |
9795e1 |
usb_redir_alloc_bulk_streams or usb_redir_free_bulk_streams packet.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
For usb_redir_alloc_bulk_streams responses no_streams will be the no_streams
|
|
Packit |
9795e1 |
passed to the usb_redir_alloc_bulk_streams packet. usb-hosts are not allowed
|
|
Packit |
9795e1 |
to return less streams then requested! For usb_redir_free_bulk_streams
|
|
Packit |
9795e1 |
responses no_streams will be 0.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
On a success status in response to a usb_redir_alloc_bulk_streams
|
|
Packit |
9795e1 |
the usb-guest may use stream ids 1 through no_streams.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_start_bulk_receiving
|
|
Packit |
9795e1 |
------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_start_bulk_receiving
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_start_bulk_receiving_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_start_bulk_receiving_header {
|
|
Packit |
9795e1 |
uint32_t stream_id;
|
|
Packit |
9795e1 |
uint32_t bytes_per_transfer;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t no_transfers;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to start buffered reading from a
|
|
Packit |
9795e1 |
bulk endpoint.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Upon receiving this packet the usb-host will submit no_transfers bulk in
|
|
Packit |
9795e1 |
transfer of bytes_per_transfer each to the designated endpoint of the
|
|
Packit |
9795e1 |
usb-device. Upon completion of a transfer the usb-host will send an
|
|
Packit |
9795e1 |
usb_redir_buffered_bulk_packet with the received data to the usb-guest,
|
|
Packit |
9795e1 |
and immediately re-submit the completed transfer.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note bytes_per_transfer must be a multiple of the endpoints max_packet_size.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note this packet should only be send to usb-hosts with the
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_receiving capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_stop_bulk_receiving
|
|
Packit |
9795e1 |
-----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_stop_bulk_receiving
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_stop_bulk_receiving_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_stop_bulk_receiving_header {
|
|
Packit |
9795e1 |
uint32_t stream_id;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to stop bulk receiving on the
|
|
Packit |
9795e1 |
designated endpoint. This will cancel all pending transfers. Note that the
|
|
Packit |
9795e1 |
usb-guest can still receive usb_redir_bulk_packet-s after sending this, as
|
|
Packit |
9795e1 |
some data packets may already be inside the transport pipe.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note this packet should only be send to usb-hosts with the
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_receiving capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_bulk_receiving_status
|
|
Packit |
9795e1 |
-------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_bulk_receiving_status
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_bulk_receiving_status_header)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_bulk_receiving_status_header {
|
|
Packit |
9795e1 |
uint32_t stream_id;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-host in response to a
|
|
Packit |
9795e1 |
usb_redir_start_bulk_receiving or usb_redir_stop_bulk_receiving packet.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that this can also be send unsolicited by an usb-host in case of an
|
|
Packit |
9795e1 |
error re-submitting the bulk transfer.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
To allow the usb-guest to detect if the stream was adversely stopped, the
|
|
Packit |
9795e1 |
usb-host will always report usb_redir_stall as status if the stream was
|
|
Packit |
9795e1 |
stopped for any reason other then an usb_redir_stop_interrupt_receiving.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note this packet should only be send to usb-guests with the
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_receiving capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_cancel_data_packet
|
|
Packit |
9795e1 |
----------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_cancel_data_packet
|
|
Packit |
9795e1 |
usb_redir_header.id <id of packet to cancel>
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send by the usb-guest to cancel an earlier send data
|
|
Packit |
9795e1 |
packet, the id should be set to the id used when sending the packet the
|
|
Packit |
9795e1 |
guest now wishes to cancel.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that the usb-guest will always receive back a data packet of the same type
|
|
Packit |
9795e1 |
and with the same id, the usb-guest can check if the packet completed
|
|
Packit |
9795e1 |
normally (before the cancel packet was processed by the usb-host), or was
|
|
Packit |
9795e1 |
cancelled by looking at the return data packet's status field.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_filter_reject
|
|
Packit |
9795e1 |
-----------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_filter_reject
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-guest after receiving a usb_redir_device_connect
|
|
Packit |
9795e1 |
or usb_redir_interface_info packet which was rejected by an usb-guest side
|
|
Packit |
9795e1 |
device filter. This packet should only be send to usb-hosts with the
|
|
Packit |
9795e1 |
usb_redir_cap_filter capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_filter_filter
|
|
Packit |
9795e1 |
-----------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_filter_filter
|
|
Packit |
9795e1 |
usb_redir_header.length: string-length + 1 (for 0 termination)
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (always as this is an unsolicited packet)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains a 0 terminated usredirfilter string.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet can be send directly after the hello packet to inform the other
|
|
Packit |
9795e1 |
side that a filter is in place and some devices may be rejected.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
An usredirfilter consists of one or more rules, where in string form each rule
|
|
Packit |
9795e1 |
has the following format:
|
|
Packit |
9795e1 |
<class>,<vendor>,<product>,<version>,<allow>
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Values can be either in decimal format, or in hexadecimal format pre-fixed
|
|
Packit |
9795e1 |
with 0x, a value of -1 can be used to allow any value.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
All rules of a filter are concatenated, separated by the '|' character
|
|
Packit |
9795e1 |
to form a single usredirfilter string:
|
|
Packit |
9795e1 |
<rule1>|<rule2>|<rule3>
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
If a device matches none of the rules the result of the filter is deny and
|
|
Packit |
9795e1 |
the device will be rejected.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
For more info on filtering see usbredirfilter.h
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet should only be send to peers with the usb_redir_cap_filter
|
|
Packit |
9795e1 |
capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_device_disconnect_ack
|
|
Packit |
9795e1 |
-------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_device_disconnect_ack
|
|
Packit |
9795e1 |
usb_redir_header.length: 0
|
|
Packit |
9795e1 |
usb_redir_header.id: 0 (as the id of the device_disconnect is always 0)
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific header.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
No packet type specific additional data.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
This packet is send by the usb-guest after having processed a
|
|
Packit |
9795e1 |
usb_redir_device_disconnect packet send by the usb-host. This allows an
|
|
Packit |
9795e1 |
usb-host which wants to re-use an existing connection to know that the
|
|
Packit |
9795e1 |
usb-guest has seen the disconnect and will not send any more packets intended
|
|
Packit |
9795e1 |
for the disconnected device. Without this there is a race where the usb-host
|
|
Packit |
9795e1 |
may have a new device available, but it is still receiving packets intended for
|
|
Packit |
9795e1 |
the old device as the usb-guest has not yet seen the disconnect.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note this packet is only send if both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_device_disconnect_ack capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_control_packet
|
|
Packit |
9795e1 |
------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_control_packet
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_control_packet_header) [+ length]
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_control_packet_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t request;
|
|
Packit |
9795e1 |
uint8_t requesttype;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint16_t value;
|
|
Packit |
9795e1 |
uint16_t index;
|
|
Packit |
9795e1 |
uint16_t length;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains the control msg data to be send / received.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Packets of this type can be send by the usb-guest to the usb-host to
|
|
Packit |
9795e1 |
initiate a control transfer on the usb-device. endpoint, request, requesttype,
|
|
Packit |
9795e1 |
value and index have their standard meaning for usb control messages.
|
|
Packit |
9795e1 |
The status field is only used in the usb-host's response.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
length is the amount of data the usb-guest is sending / expects to read
|
|
Packit |
9795e1 |
(in the USB_DIR_IN case). Note that the length should only be added
|
|
Packit |
9795e1 |
to usb_redir_header.length in one direction (and the actual packet
|
|
Packit |
9795e1 |
length should match).
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
When the control msg has been processed by the usb-device the usb-host sends
|
|
Packit |
9795e1 |
a usb_redir_control_packet back to the usb-guest, with all fields unchanged
|
|
Packit |
9795e1 |
except for the status field and length which get updated to match the
|
|
Packit |
9795e1 |
actual results.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_bulk_packet
|
|
Packit |
9795e1 |
---------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_bulk_packet
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_bulk_packet_header) [+ length]
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_bulk_packet_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint16_t length;
|
|
Packit |
9795e1 |
uint32_t stream_id;
|
|
Packit |
9795e1 |
uint16_t length_high; /* High 16 bits of the packet length */
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains the bulk msg data to be send / received.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Packets of this type can be send by the usb-guest to the usb-host to
|
|
Packit |
9795e1 |
initiate a bulk transfer on the usb-device. endpoint and stream_id have
|
|
Packit |
9795e1 |
their standard meaning for usb bulk messages. The status field is only used
|
|
Packit |
9795e1 |
in the usb-host's response. length is the amount of data the usb-guest is
|
|
Packit |
9795e1 |
sending / expects to read (depending on the direction of the endpoint).
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
length_high contains the 16 high bits of length to allow packets larger
|
|
Packit |
9795e1 |
then 65535 bytes, it is only send/received if both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_32bits_bulk_length capability.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
When the bulk msg has been processed by the usb-device the usb-host sends
|
|
Packit |
9795e1 |
a usb_redir_bulk_packet back to the usb-guest, with the status field and
|
|
Packit |
9795e1 |
length updated to match the actual results.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note just as usb_redir_control_packet this packet only has additional data
|
|
Packit |
9795e1 |
in one direction depending on the direction of the endpoint.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note see usb_redir_buffered_bulk_packet for an alternative for receiving data
|
|
Packit |
9795e1 |
from bulk endpoints.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_iso_packet
|
|
Packit |
9795e1 |
--------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_iso_packet
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_iso_packet_header) + length
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_iso_packet_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint16_t length;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains the iso msg data to be send / received.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Packets of this type should be send continuesly (at the endpoint interval
|
|
Packit |
9795e1 |
speed) as soon as an iso stream is started using usb_redir_start_iso_stream
|
|
Packit |
9795e1 |
the direction in which they gets send depends on the endpoints direction.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The status field only has meaning for packets send from the usb-host to
|
|
Packit |
9795e1 |
the usb-guest (for iso input endpoints). Due to buffering it is not possibly
|
|
Packit |
9795e1 |
to timely notify the usb-guest of transfer errors for iso output packets. The
|
|
Packit |
9795e1 |
usb-host will try to clear any error conditions itself. If it fails to do
|
|
Packit |
9795e1 |
so it will send a usb_redir_iso_stream_status to the usb-guest indicating
|
|
Packit |
9795e1 |
there is a problem with the iso stream.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Since usb_redir_iso_packet's are send continuously by the usb-host once
|
|
Packit |
9795e1 |
a stream is started on an iso input endpoint, the usb-host cannot set the
|
|
Packit |
9795e1 |
usb_redir_header.id to the id of the corresponding received packet. So for
|
|
Packit |
9795e1 |
usb_redir_iso_packet's the usb-host simply starts with an id of 0 and
|
|
Packit |
9795e1 |
increments this every packet. Note that when the usb-host has recovered from
|
|
Packit |
9795e1 |
a stall the id will restart at 0!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_interrupt_packet
|
|
Packit |
9795e1 |
--------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_interrupt_packet
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_interrupt_packet_header) [+ length]
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_interrupt_packet_header {
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
uint16_t length;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains the interrupt msg data to be send / received.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The handling of interrupt endpoints differs significantly depending on wether
|
|
Packit |
9795e1 |
the endpoint is an input or output endpoint.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Input endpoints:
|
|
Packit |
9795e1 |
================
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Input interrupt endpoints need to
|
|
Packit |
9795e1 |
be polled timely otherwise data may get lost. So for input interrupt endpoints
|
|
Packit |
9795e1 |
the usb-host takes care of the submitting and re-submitting of urbs, the
|
|
Packit |
9795e1 |
usb-guest can start / stop the receiving of interrupt packets using the
|
|
Packit |
9795e1 |
usb_redir_start_interrupt_receiving / usb_redir_stop_interrupt_receiving
|
|
Packit |
9795e1 |
packets. Note that for an input interrupt endpoint usb_redir_interrupt_packet-s
|
|
Packit |
9795e1 |
are only send in one direction, from the usb-host to the usb-guest!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Since usb_redir_interrupt_packet's are send unsolicited by the usb-host once
|
|
Packit |
9795e1 |
interrupt receiving has started, the usb-host cannot set the
|
|
Packit |
9795e1 |
usb_redir_header.id to the id of the corresponding received packet. So for
|
|
Packit |
9795e1 |
usb_redir_interrupt_packet's the usb-host simply starts with an id of 0 and
|
|
Packit |
9795e1 |
increments this every packet. Note that when the usb-host has recovered from
|
|
Packit |
9795e1 |
a stall the id will restart at 0!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Output endpoints:
|
|
Packit |
9795e1 |
=================
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
For interrupt output endpoints the normal asynchroneous mechanism also used
|
|
Packit |
9795e1 |
for control and bulk transfers is used:
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The usb-guest sends a usb_redir_interrupt_packet to the usb-host. When the
|
|
Packit |
9795e1 |
interrupt msg has been processed by the usb-device the usb-host sends
|
|
Packit |
9795e1 |
a usb_redir_interrupt_packet back to the usb-guest, with the status field and
|
|
Packit |
9795e1 |
length updated to match the actual results. This packet only has additional
|
|
Packit |
9795e1 |
data (the data to output) when send from usb-guest to usb-host.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that since unlike with iso data there is usually no notion of a stream
|
|
Packit |
9795e1 |
with interrupt data, buffering makes no sense for output interrupt packets,
|
|
Packit |
9795e1 |
instead they are delivered asap. Despite this asap delivery it is likely
|
|
Packit |
9795e1 |
that the timing constraints which apply to interrupt output transfers will
|
|
Packit |
9795e1 |
not be met. The consequences of this will vary from device to device.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_buffered_bulk_packet
|
|
Packit |
9795e1 |
------------------------------
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
usb_redir_header.type: usb_redir_bulk_packet
|
|
Packit |
9795e1 |
usb_redir_header.length: sizeof(usb_redir_bulk_packet_header) + length
|
|
Packit |
9795e1 |
usb_redir_header.id: starts at 0, incremented by 1 per send packet
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
struct usb_redir_buffered_bulk_packet_header {
|
|
Packit |
9795e1 |
uint32_t stream_id;
|
|
Packit |
9795e1 |
uint32_t length;
|
|
Packit |
9795e1 |
uint8_t endpoint;
|
|
Packit |
9795e1 |
uint8_t status;
|
|
Packit |
9795e1 |
}
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
The additional data contains the bulk msg data received.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Buffered bulk mode is intended for bulk *input* endpoints, where the data is
|
|
Packit |
9795e1 |
of a streaming nature (not part of a command-response protocol). These
|
|
Packit |
9795e1 |
endpoints' input buffer may overflow if data is not read quickly enough.
|
|
Packit |
9795e1 |
So in buffered bulk mode the usb-host takes care of the submitting and
|
|
Packit |
9795e1 |
re-submitting of bulk transfers. The usb-guest can start / stop the receiving
|
|
Packit |
9795e1 |
of buffered bulk data using the usb_redir_start_bulk_receiving /
|
|
Packit |
9795e1 |
usb_redir_stop_bulk_receiving packets.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note that usb_redir_buffered_bulk_packet-s are only send in one direction,
|
|
Packit |
9795e1 |
from the usb-host to the usb-guest!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Since usb_redir_buffered_bulk_packet-s are send unsolicited by the usb-host
|
|
Packit |
9795e1 |
once bulk receiving has started, the usb-host cannot set the
|
|
Packit |
9795e1 |
usb_redir_header.id to the id of the corresponding received packet. So for
|
|
Packit |
9795e1 |
usb_redir_buffered_bulk_packet-s the usb-host simply starts with an id of 0 and
|
|
Packit |
9795e1 |
increments this every packet. Note that when the usb-host has recovered from
|
|
Packit |
9795e1 |
a stall the id will restart at 0!
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
A typical example where buffered bulk mode should be used is with the bulk in
|
|
Packit |
9795e1 |
endpoints of usb to serial convertors.
|
|
Packit |
9795e1 |
|
|
Packit |
9795e1 |
Note buffered bulk mode can only be used when both sides have the
|
|
Packit |
9795e1 |
usb_redir_cap_bulk_receiving capability.
|