@@ -95,6 +95,8 @@ struct hid_device_ {
9595 int interface ;
9696
9797 uint16_t report_descriptor_size ;
98+ /* Includes report number. */
99+ size_t max_input_report_size ;
98100
99101 /* Endpoint information */
100102 int input_endpoint ;
@@ -135,6 +137,7 @@ static libusb_context *usb_context = NULL;
135137
136138uint16_t get_usb_code_for_current_locale (void );
137139static int return_data (hid_device * dev , unsigned char * data , size_t length );
140+ static int hid_get_report_descriptor_libusb (libusb_device_handle * handle , int interface_num , uint16_t expected_report_descriptor_size , unsigned char * buf , size_t buf_size );
138141
139142static hid_device * new_hid_device (void )
140143{
@@ -276,6 +279,74 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
276279 return -1 ; /* failure */
277280}
278281
282+ /* Retrieves the largest input report size (in bytes) from the report descriptor.
283+
284+ Requires an opened device with *claimed interface*.
285+
286+ The return value is the size on success and -1 on failure. */
287+ static size_t get_max_input_report_size (libusb_device_handle * handle , int interface_num , uint16_t expected_report_descriptor_size )
288+ {
289+ int i = 0 ;
290+ int size_code ;
291+ int data_len , key_size ;
292+
293+ int64_t report_size = 0 , report_count = 0 ;
294+ ssize_t max_size = -1 ;
295+
296+ unsigned char report_descriptor [HID_API_MAX_REPORT_DESCRIPTOR_SIZE ];
297+
298+ int desc_size = hid_get_report_descriptor_libusb (handle , interface_num , expected_report_descriptor_size , report_descriptor , sizeof (report_descriptor ));
299+ if (desc_size < 0 ) {
300+ return -1 ;
301+ }
302+
303+ while (i < desc_size ) {
304+ int key = report_descriptor [i ];
305+ int key_cmd = key & 0xfc ;
306+
307+ if ((key & 0xf0 ) == 0xf0 ) {
308+ /* This is a Long Item. The next byte contains the
309+ length of the data section (value) for this key.
310+ See the HID specification, version 1.11, section
311+ 6.2.2.3, titled "Long Items." */
312+ if (i + 1 < desc_size )
313+ data_len = report_descriptor [i + 1 ];
314+ else
315+ data_len = 0 ; /* malformed report */
316+ key_size = 3 ;
317+ } else {
318+ /* This is a Short Item. The bottom two bits of the
319+ key contain the size code for the data section
320+ (value) for this key. Refer to the HID
321+ specification, version 1.11, section 6.2.2.2,
322+ titled "Short Items." */
323+ size_code = key & 0x3 ;
324+ data_len = (size_code < 3 ) ? size_code : 4 ;
325+ key_size = 1 ;
326+ }
327+
328+ if (key_cmd == 0x94 ) {
329+ report_count = get_bytes (report_descriptor , desc_size , data_len , i );
330+ }
331+ if (key_cmd == 0x74 ) {
332+ report_size = get_bytes (report_descriptor , desc_size , data_len , i );
333+ }
334+ if (key_cmd == 0x80 ) { // Input
335+ /* report_size is in bits. Determine the total size (count * size),
336+ convert to bytes (rounded up), and add one byte for the report
337+ number. */
338+ ssize_t size = (((report_count * report_size ) + 7 ) / 8 ) + 1 ;
339+ if (size > max_size )
340+ max_size = size ;
341+ }
342+
343+ /* Skip over this key and it's associated data */
344+ i += data_len + key_size ;
345+ }
346+
347+ return max_size ;
348+ }
349+
279350#if defined(__FreeBSD__ ) && __FreeBSD__ < 10
280351/* The libusb version included in FreeBSD < 10 doesn't have this function. In
281352 mainline libusb, it's inlined in libusb.h. This function will bear a striking
@@ -1024,7 +1095,14 @@ static void *read_thread(void *param)
10241095 int res ;
10251096 hid_device * dev = param ;
10261097 uint8_t * buf ;
1027- const size_t length = dev -> input_ep_max_packet_size ;
1098+ size_t length ;
1099+ if (dev -> max_input_report_size > 0 ) {
1100+ length = dev -> max_input_report_size ;
1101+ } else {
1102+ /* If we were unable to reliably determine the maximum input size, fall back
1103+ to the max packet size. */
1104+ length = dev -> input_ep_max_packet_size ;
1105+ }
10281106
10291107 /* Set up the transfer object. */
10301108 buf = (uint8_t * ) malloc (length );
@@ -1216,6 +1294,7 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
12161294 dev -> interface = intf_desc -> bInterfaceNumber ;
12171295
12181296 dev -> report_descriptor_size = get_report_descriptor_size_from_interface_descriptors (intf_desc );
1297+ dev -> max_input_report_size = get_max_input_report_size (dev -> device_handle , dev -> interface , dev -> report_descriptor_size );
12191298
12201299 dev -> input_endpoint = 0 ;
12211300 dev -> input_ep_max_packet_size = 0 ;
0 commit comments