usb: device_next: hid: fix Get Report buffer handling
After the get_report() callback, we need to determine how many bytes the HID device wrote to the report buffer. Use the callback return value to do this, and modify the net_buf data length value if get_report was successful. Reported-by: Marek Pieta <Marek.Pieta@nordicsemi.no> Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
parent
a33341ac66
commit
af63e488f0
2 changed files with 16 additions and 5 deletions
|
|
@ -106,8 +106,10 @@ struct hid_device_ops {
|
|||
* feature, input, or output report, which is specified by the argument
|
||||
* type. If there is no report ID in the report descriptor, the id
|
||||
* argument is zero. The callback implementation must check the
|
||||
* arguments, such as whether the report type is supported, and return
|
||||
* a nonzero value to indicate an unsupported type or an error.
|
||||
* arguments, such as whether the report type is supported and the
|
||||
* report length, and return a negative value to indicate an
|
||||
* unsupported type or an error, or return the length of the report
|
||||
* written to the buffer.
|
||||
*/
|
||||
int (*get_report)(const struct device *dev,
|
||||
const uint8_t type, const uint8_t id,
|
||||
|
|
|
|||
|
|
@ -231,25 +231,34 @@ static int handle_get_report(const struct device *dev,
|
|||
const uint8_t id = HID_GET_REPORT_ID(setup->wValue);
|
||||
struct hid_device_data *const ddata = dev->data;
|
||||
const struct hid_device_ops *ops = ddata->ops;
|
||||
const size_t size = net_buf_tailroom(buf);
|
||||
int ret = 0;
|
||||
|
||||
switch (type) {
|
||||
case HID_REPORT_TYPE_INPUT:
|
||||
LOG_DBG("Get Report, Input Report ID %u", id);
|
||||
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
|
||||
ret = ops->get_report(dev, type, id, size, buf->data);
|
||||
break;
|
||||
case HID_REPORT_TYPE_OUTPUT:
|
||||
LOG_DBG("Get Report, Output Report ID %u", id);
|
||||
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
|
||||
ret = ops->get_report(dev, type, id, size, buf->data);
|
||||
break;
|
||||
case HID_REPORT_TYPE_FEATURE:
|
||||
LOG_DBG("Get Report, Feature Report ID %u", id);
|
||||
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
|
||||
ret = ops->get_report(dev, type, id, size, buf->data);
|
||||
break;
|
||||
default:
|
||||
errno = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
__ASSERT(ret <= size, "Buffer overflow in the HID driver");
|
||||
net_buf_add(buf, MIN(size, ret));
|
||||
} else {
|
||||
errno = ret ? ret : -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue