summaryrefslogtreecommitdiff
path: root/usbredirparser
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-10-06 11:13:49 +0200
committerHans de Goede <hdegoede@redhat.com>2012-10-06 11:16:35 +0200
commit14476dabacb3fd189261e866e96907ba0aa35b96 (patch)
tree827b38417e39dc423ac91620e185551e880d78fa /usbredirparser
parentcf0c0b5b7230aa47edec430d8eb624750ac3f233 (diff)
usbredirparser: Add support for bulk packets longer then 65535 bytes
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'usbredirparser')
-rw-r--r--usbredirparser/usbredirparser.c26
-rw-r--r--usbredirparser/usbredirproto-compat.h7
-rw-r--r--usbredirparser/usbredirproto.h3
3 files changed, 32 insertions, 4 deletions
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c
index 64875df..e68fc28 100644
--- a/usbredirparser/usbredirparser.c
+++ b/usbredirparser/usbredirparser.c
@@ -448,7 +448,14 @@ static int usbredirparser_get_type_header_len(
case usb_redir_control_packet:
return sizeof(struct usb_redir_control_packet_header);
case usb_redir_bulk_packet:
- return sizeof(struct usb_redir_bulk_packet_header);
+ if (usbredirparser_have_cap(parser_pub,
+ usb_redir_cap_32bits_bulk_length) &&
+ usbredirparser_peer_has_cap(parser_pub,
+ usb_redir_cap_32bits_bulk_length)) {
+ return sizeof(struct usb_redir_bulk_packet_header);
+ } else {
+ return sizeof(struct usb_redir_bulk_packet_header_16bit_length);
+ }
case usb_redir_iso_packet:
return sizeof(struct usb_redir_iso_packet_header);
case usb_redir_interrupt_packet:
@@ -541,10 +548,21 @@ static int usbredirparser_verify_type_header(
length = ((struct usb_redir_control_packet_header *)header)->length;
ep = ((struct usb_redir_control_packet_header *)header)->endpoint;
break;
- case usb_redir_bulk_packet:
- length = ((struct usb_redir_bulk_packet_header *)header)->length;
- ep = ((struct usb_redir_bulk_packet_header *)header)->endpoint;
+ case usb_redir_bulk_packet: {
+ struct usb_redir_bulk_packet_header *bulk_packet = header;
+ if (usbredirparser_have_cap(parser_pub,
+ usb_redir_cap_32bits_bulk_length) &&
+ usbredirparser_peer_has_cap(parser_pub,
+ usb_redir_cap_32bits_bulk_length)) {
+ length = (bulk_packet->length_high << 16) | bulk_packet->length;
+ } else {
+ length = bulk_packet->length;
+ if (!send)
+ bulk_packet->length_high = 0;
+ }
+ ep = bulk_packet->endpoint;
break;
+ }
case usb_redir_iso_packet:
length = ((struct usb_redir_iso_packet_header *)header)->length;
ep = ((struct usb_redir_iso_packet_header *)header)->endpoint;
diff --git a/usbredirparser/usbredirproto-compat.h b/usbredirparser/usbredirproto-compat.h
index c647c91..fc8ca16 100644
--- a/usbredirparser/usbredirproto-compat.h
+++ b/usbredirparser/usbredirproto-compat.h
@@ -63,6 +63,13 @@ struct usb_redir_header_32bit_id {
uint32_t id;
} ATTR_PACKED;
+struct usb_redir_bulk_packet_header_16bit_length {
+ uint8_t endpoint;
+ uint8_t status;
+ uint16_t length;
+ uint32_t stream_id;
+} ATTR_PACKED;
+
#undef ATTR_PACKED
#if defined(__MINGW32__) || !defined(__GNUC__)
diff --git a/usbredirparser/usbredirproto.h b/usbredirparser/usbredirproto.h
index ede0e7f..cdbd1c3 100644
--- a/usbredirparser/usbredirproto.h
+++ b/usbredirparser/usbredirproto.h
@@ -117,6 +117,8 @@ enum {
usb_redir_cap_ep_info_max_packet_size,
/* Supports 64 bits ids in usb_redir_header */
usb_redir_cap_64bits_ids,
+ /* Supports 32 bits length in usb_redir_bulk_packet_header */
+ usb_redir_cap_32bits_bulk_length,
};
/* Number of uint32_t-s needed to hold all (known) capabilities */
#define USB_REDIR_CAPS_SIZE 1
@@ -239,6 +241,7 @@ struct usb_redir_bulk_packet_header {
uint8_t status;
uint16_t length;
uint32_t stream_id;
+ uint16_t length_high; /* High 16 bits of the packet length */
} ATTR_PACKED;
struct usb_redir_iso_packet_header {