summaryrefslogtreecommitdiff
path: root/profiles/input
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2020-11-20 12:42:46 +1100
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2020-11-20 09:46:02 -0800
commit35a2c50437cca4d26ac6537ce3a964bb509c9b62 (patch)
tree4696da58db409879c3d77d911d74d2a37c9a9f57 /profiles/input
parente892dd0cd7689c1ffb8ad2c07113acc9d19e3973 (diff)
downloadbluez-35a2c50437cca4d26ac6537ce3a964bb509c9b62.tar.gz
hog: Fix stripping off read report bytes
If the HID subsystem requests a HID report to be read from the device, we currently incorrectly strip off the first byte of the response, if the device has report IDs set in the HID report descriptor. This is incorrect; unlike USB HID, the report ID is *not* included in the HOG profile's HID reports, and instead exists out of band in a descriptor on the report's bluetooth characteristic in the device. In this patch, we remove the erroneous stripping of the first byte of the report, and (if report IDs are enabled) prepend the report ID to the front of the result. This makes the HID report returned indentical in format to that of a USB HID report, so that the upper HID drivers can consume HOG device reports in the same way as USB.
Diffstat (limited to 'profiles/input')
-rw-r--r--profiles/input/hog-lib.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/profiles/input/hog-lib.c b/profiles/input/hog-lib.c
index 78018aad3..ee811d301 100644
--- a/profiles/input/hog-lib.c
+++ b/profiles/input/hog-lib.c
@@ -779,7 +779,8 @@ fail:
static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
- struct bt_hog *hog = user_data;
+ struct report *report = user_data;
+ struct bt_hog *hog = report->hog;
struct uhid_event rsp;
int err;
@@ -808,14 +809,16 @@ static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
--len;
++pdu;
+
if (hog->has_report_id && len > 0) {
- --len;
- ++pdu;
+ rsp.u.get_report_reply.size = len + 1;
+ rsp.u.get_report_reply.data[0] = report->id;
+ memcpy(&rsp.u.get_report_reply.data[1], pdu, len);
+ } else {
+ rsp.u.get_report_reply.size = len;
+ memcpy(rsp.u.get_report_reply.data, pdu, len);
}
- rsp.u.get_report_reply.size = len;
- memcpy(rsp.u.get_report_reply.data, pdu, len);
-
exit:
rsp.u.get_report_reply.err = status;
err = bt_uhid_send(hog->uhid, &rsp);
@@ -846,7 +849,7 @@ static void get_report(struct uhid_event *ev, void *user_data)
hog->getrep_att = gatt_read_char(hog->attrib,
report->value_handle,
- get_report_cb, hog);
+ get_report_cb, report);
if (!hog->getrep_att) {
err = ENOMEM;
goto fail;