@@ -293,24 +293,40 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
293293// Callback invoked when we receive Set_Report request through control endpoint
294294void 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 ) {
295295 (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+ }
300317 } else if (report_type != HID_REPORT_TYPE_OUTPUT && report_type != HID_REPORT_TYPE_FEATURE ) {
301318 return ;
302319 }
303320
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 )) {
308328 // 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;
315331 }
316332}
0 commit comments