Skip to content

Commit

Permalink
Independent HID OUT buffer
Browse files Browse the repository at this point in the history
- Separate buffer for FEATURE and OUT reports
- Prevents a bug where an OUT report can overwrite a FEATURE report and vice versa
  • Loading branch information
RockyZeroFour committed Jan 20, 2025
1 parent b7dcbca commit 73e0056
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/class/hid/hid_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef struct

CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t feat_buf[CFG_TUD_HID_FEATURE_BUFSIZE];

// TODO save hid descriptor since host can specifically request this after enumeration
// Note: HID descriptor may be not available from application after enumeration
Expand Down Expand Up @@ -320,16 +321,32 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t
case HID_REQ_CONTROL_SET_REPORT:
if ( stage == CONTROL_STAGE_SETUP )
{
TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf));
tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength);
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t * report_buf;

if ( report_type == HID_REPORT_TYPE_FEATURE )
{
TU_VERIFY(request->wLength <= sizeof(p_hid->feat_buf));

report_buf = p_hid->feat_buf;
}
else
{
TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf));

report_buf = p_hid->epout_buf;
}

tud_control_xfer(rhport, request, report_buf, request->wLength);
}
else if ( stage == CONTROL_STAGE_ACK )
{
uint8_t const report_type = tu_u16_high(request->wValue);
uint8_t const report_id = tu_u16_low(request->wValue);

uint8_t const* report_buf = p_hid->epout_buf;
uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE);
uint8_t const* report_buf = (report_type == HID_REPORT_TYPE_FEATURE) ? p_hid->feat_buf : p_hid->epout_buf;

uint16_t report_len = tu_min16(request->wLength, (report_type == HID_REPORT_TYPE_FEATURE) ? CFG_TUD_HID_FEATURE_BUFSIZE : CFG_TUD_HID_EP_BUFSIZE);

// If host request a specific Report ID, extract report ID in buffer before invoking callback
if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) )
Expand Down

0 comments on commit 73e0056

Please sign in to comment.