Fixed double-copy of the report in BlueZ >= 5.56
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
diff --git a/src/hidapi/linux/hid.c b/src/hidapi/linux/hid.c
index 19a0d96..b954415 100644
--- a/src/hidapi/linux/hid.c
+++ b/src/hidapi/linux/hid.c
@@ -843,20 +843,24 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char
int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
int res;
-
- /* It looks like HIDIOCGFEATURE() on Bluetooth LE devices doesn't return the report number */
- if (dev->needs_ble_hack) {
- data[1] = data[0];
- ++data;
- --length;
- }
- res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
- if (res < 0)
- perror("ioctl (GFEATURE)");
- else if (dev->needs_ble_hack)
- ++res;
-
- return res;
+ unsigned char report = data[0];
+
+ res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
+ if (res < 0)
+ perror("ioctl (GFEATURE)");
+ else if (dev->needs_ble_hack) {
+ /* Versions of BlueZ before 5.56 don't include the report in the data, and versions of BlueZ >= 5.56 include 2 copies of the report.
+ * We'll fix it so that there is a single copy of the report in both cases
+ */
+ if (data[0] == report && data[1] == report) {
+ memmove(&data[0], &data[1], res);
+ } else if (data[0] != report) {
+ memmove(&data[1], &data[0], res);
+ data[0] = report;
+ ++res;
+ }
+ }
+ return res;
}