@@ -95,6 +95,7 @@ struct hid_device_ {
9595 int interface ;
9696
9797 uint16_t report_descriptor_size ;
98+ size_t max_input_size ;
9899
99100 /* Endpoint information */
100101 int input_endpoint ;
@@ -135,6 +136,7 @@ static libusb_context *usb_context = NULL;
135136
136137uint16_t get_usb_code_for_current_locale (void );
137138static int return_data (hid_device * dev , unsigned char * data , size_t length );
139+ 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 );
138140
139141static hid_device * new_hid_device (void )
140142{
@@ -276,6 +278,73 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
276278 return -1 ; /* failure */
277279}
278280
281+ /* Retrieves the largest input report size (in bits, count * size) from the
282+ report descriptor. The algorithm is simple, as it just returns the first
283+ Usage and Usage Page that it finds in the descriptor.
284+
285+ Requires an opened device with *claimed interface*.
286+
287+ The return value is the size on success and -1 on failure. */
288+ static size_t get_max_input_size (libusb_device_handle * handle , int interface_num , uint16_t expected_report_descriptor_size )
289+ {
290+ int i = 0 ;
291+ int size_code ;
292+ int data_len , key_size ;
293+
294+ int64_t report_size = 0 , report_count = 0 ;
295+ ssize_t max_size = -1 ;
296+
297+ unsigned char report_descriptor [HID_API_MAX_REPORT_DESCRIPTOR_SIZE ];
298+
299+ int desc_size = hid_get_report_descriptor_libusb (handle , interface_num , expected_report_descriptor_size , report_descriptor , sizeof (report_descriptor ));
300+ if (desc_size < 0 ) {
301+ return -1 ;
302+ }
303+
304+ while (i < desc_size ) {
305+ int key = report_descriptor [i ];
306+ int key_cmd = key & 0xfc ;
307+
308+ if ((key & 0xf0 ) == 0xf0 ) {
309+ /* This is a Long Item. The next byte contains the
310+ length of the data section (value) for this key.
311+ See the HID specification, version 1.11, section
312+ 6.2.2.3, titled "Long Items." */
313+ if (i + 1 < desc_size )
314+ data_len = report_descriptor [i + 1 ];
315+ else
316+ data_len = 0 ; /* malformed report */
317+ key_size = 3 ;
318+ } else {
319+ /* This is a Short Item. The bottom two bits of the
320+ key contain the size code for the data section
321+ (value) for this key. Refer to the HID
322+ specification, version 1.11, section 6.2.2.2,
323+ titled "Short Items." */
324+ size_code = key & 0x3 ;
325+ data_len = (size_code < 3 ) ? size_code : 4 ;
326+ key_size = 1 ;
327+ }
328+
329+ if (key_cmd == 0x94 ) {
330+ report_count = get_bytes (report_descriptor , desc_size , data_len , i );
331+ }
332+ if (key_cmd == 0x74 ) {
333+ report_size = get_bytes (report_descriptor , desc_size , data_len , i );
334+ }
335+ if (key_cmd == 0x80 ) { // Input
336+ ssize_t size = report_count * report_size ;
337+ if (size > max_size )
338+ max_size = size ;
339+ }
340+
341+ /* Skip over this key and it's associated data */
342+ i += data_len + key_size ;
343+ }
344+
345+ return max_size ;
346+ }
347+
279348#if defined(__FreeBSD__ ) && __FreeBSD__ < 10
280349/* The libusb version included in FreeBSD < 10 doesn't have this function. In
281350 mainline libusb, it's inlined in libusb.h. This function will bear a striking
@@ -1024,7 +1093,16 @@ static void *read_thread(void *param)
10241093 int res ;
10251094 hid_device * dev = param ;
10261095 uint8_t * buf ;
1027- const size_t length = dev -> input_ep_max_packet_size ;
1096+ size_t length ;
1097+ if (dev -> max_input_size > 0 ) {
1098+ /* max_input_size is in bits. Convert to bytes (rounding up).
1099+ Then add one byte for the report ID byte. */
1100+ length = ((dev -> max_input_size + 7 ) / 8 ) + 1 ;
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_size = get_max_input_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