@@ -95,6 +95,8 @@ struct hid_device_ {
95
95
int interface ;
96
96
97
97
uint16_t report_descriptor_size ;
98
+ /* Includes report number. */
99
+ size_t max_input_report_size ;
98
100
99
101
/* Endpoint information */
100
102
int input_endpoint ;
@@ -135,6 +137,7 @@ static libusb_context *usb_context = NULL;
135
137
136
138
uint16_t get_usb_code_for_current_locale (void );
137
139
static 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 );
138
141
139
142
static hid_device * new_hid_device (void )
140
143
{
@@ -276,6 +279,74 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
276
279
return -1 ; /* failure */
277
280
}
278
281
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
+
279
350
#if defined(__FreeBSD__ ) && __FreeBSD__ < 10
280
351
/* The libusb version included in FreeBSD < 10 doesn't have this function. In
281
352
mainline libusb, it's inlined in libusb.h. This function will bear a striking
@@ -1024,7 +1095,14 @@ static void *read_thread(void *param)
1024
1095
int res ;
1025
1096
hid_device * dev = param ;
1026
1097
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
+ }
1028
1106
1029
1107
/* Set up the transfer object. */
1030
1108
buf = (uint8_t * ) malloc (length );
@@ -1216,6 +1294,7 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
1216
1294
dev -> interface = intf_desc -> bInterfaceNumber ;
1217
1295
1218
1296
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 );
1219
1298
1220
1299
dev -> input_endpoint = 0 ;
1221
1300
dev -> input_ep_max_packet_size = 0 ;
0 commit comments