@@ -95,6 +95,7 @@ struct hid_device_ {
95
95
int interface ;
96
96
97
97
uint16_t report_descriptor_size ;
98
+ size_t max_input_size ;
98
99
99
100
/* Endpoint information */
100
101
int input_endpoint ;
@@ -135,6 +136,7 @@ static libusb_context *usb_context = NULL;
135
136
136
137
uint16_t get_usb_code_for_current_locale (void );
137
138
static 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 );
138
140
139
141
static hid_device * new_hid_device (void )
140
142
{
@@ -276,6 +278,73 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
276
278
return -1 ; /* failure */
277
279
}
278
280
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
+
279
348
#if defined(__FreeBSD__ ) && __FreeBSD__ < 10
280
349
/* The libusb version included in FreeBSD < 10 doesn't have this function. In
281
350
mainline libusb, it's inlined in libusb.h. This function will bear a striking
@@ -1024,7 +1093,16 @@ static void *read_thread(void *param)
1024
1093
int res ;
1025
1094
hid_device * dev = param ;
1026
1095
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
+ }
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_size = get_max_input_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