@@ -293,24 +293,40 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
293
293
// Callback invoked when we receive Set_Report request through control endpoint
294
294
void tud_hid_set_report_cb (uint8_t itf , uint8_t report_id , hid_report_type_t report_type , uint8_t const * buffer , uint16_t bufsize ) {
295
295
(void )itf ;
296
- if (report_type == HID_REPORT_TYPE_INVALID ) {
297
- report_id = buffer [0 ];
298
- buffer ++ ;
299
- bufsize -- ;
296
+
297
+ usb_hid_device_obj_t * hid_device = NULL ;
298
+ size_t id_idx ;
299
+
300
+ if (report_id == 0 && report_type == HID_REPORT_TYPE_INVALID ) {
301
+ // This could be a report with a non-zero report ID in the first byte, or
302
+ // it could be for report ID 0.
303
+ // Heuristic: see if there's a device with report ID 0, and if its report length matches
304
+ // the size of the incoming buffer. In that case, assume the first byte is not the report ID,
305
+ // but is data. Otherwise use the first byte as the report id.
306
+ if (usb_hid_get_device_with_report_id (0 , & hid_device , & id_idx ) &&
307
+ hid_device &&
308
+ hid_device -> out_report_buffers [id_idx ] &&
309
+ hid_device -> out_report_lengths [id_idx ] == bufsize ) {
310
+ // Use as is, with report_id 0.
311
+ } else {
312
+ // No matching report ID 0, so use the first byte as the report ID.
313
+ report_id = buffer [0 ];
314
+ buffer ++ ;
315
+ bufsize -- ;
316
+ }
300
317
} else if (report_type != HID_REPORT_TYPE_OUTPUT && report_type != HID_REPORT_TYPE_FEATURE ) {
301
318
return ;
302
319
}
303
320
304
- usb_hid_device_obj_t * hid_device ;
305
- size_t id_idx ;
306
- // Find device with this report id, and get the report id index.
307
- if (usb_hid_get_device_with_report_id (report_id , & hid_device , & id_idx )) {
321
+ // report_id might be changed due to parsing above, so test again.
322
+ if ((report_id == 0 && report_type == HID_REPORT_TYPE_INVALID ) ||
323
+ // Fetch the matching device if we don't already have the report_id 0 device.
324
+ (usb_hid_get_device_with_report_id (report_id , & hid_device , & id_idx ) &&
325
+ hid_device &&
326
+ hid_device -> out_report_buffers [id_idx ] &&
327
+ hid_device -> out_report_lengths [id_idx ] == bufsize )) {
308
328
// If a report of the correct size has been read, save it in the proper OUT report buffer.
309
- if (hid_device &&
310
- hid_device -> out_report_buffers [id_idx ] &&
311
- hid_device -> out_report_lengths [id_idx ] >= bufsize ) {
312
- memcpy (hid_device -> out_report_buffers [id_idx ], buffer , bufsize );
313
- hid_device -> out_report_buffers_updated [id_idx ] = true;
314
- }
329
+ memcpy (hid_device -> out_report_buffers [id_idx ], buffer , bufsize );
330
+ hid_device -> out_report_buffers_updated [id_idx ] = true;
315
331
}
316
332
}
0 commit comments