Skip to content

Commit 31eba10

Browse files
committed
linux/hidraw: Parse Report ID
Some reports have an optional and/or device specific Report ID that someone sending the report need to prefix to the actual report when sending one. This adds an easy way on Linux to retrieve that ID. Signed-off-by: Werner Sembach <[email protected]>
1 parent 9904cbe commit 31eba10

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

hidapi/hidapi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ extern "C" {
176176
/** Usage for this Device/Interface
177177
(Windows/Mac/hidraw only) */
178178
unsigned short usage;
179+
/** Report ID for this Device/Interface
180+
(hidraw only) */
181+
unsigned char report_id;
179182
/** The USB interface which this logical device
180183
represents.
181184

linux/hid.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ struct hid_usage_iterator {
347347
* 1 when finished processing descriptor.
348348
* -1 on a malformed report.
349349
*/
350-
static int get_next_hid_usage(const __u8 *report_descriptor, __u32 size, struct hid_usage_iterator *ctx, unsigned short *usage_page, unsigned short *usage)
350+
static int get_next_hid_usage(const __u8 *report_descriptor, __u32 size, struct hid_usage_iterator *ctx, unsigned short *usage_page, unsigned short *usage, unsigned char *report_id)
351351
{
352352
int data_len, key_size;
353353
int initial = ctx->pos == 0; /* Used to handle case where no top-level application collection is defined */
@@ -381,6 +381,10 @@ static int get_next_hid_usage(const __u8 *report_descriptor, __u32 size, struct
381381
}
382382
break;
383383

384+
case 0x84: /* Report ID 6.2.2.7 (Global) */
385+
*report_id = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
386+
break;
387+
384388
case 0xa0: /* Collection 6.2.2.4 (Main) */
385389
if (!hid_iterate_over_collection(report_descriptor, size, &ctx->pos, &data_len, &key_size)) {
386390
return -1;
@@ -805,23 +809,25 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device
805809

806810
if (result >= 0) {
807811
unsigned short page = 0, usage = 0;
812+
unsigned char report_id = 0;
808813
struct hid_usage_iterator usage_iterator;
809814
memset(&usage_iterator, 0, sizeof(usage_iterator));
810815

811816
/*
812817
* Parse the first usage and usage page
813818
* out of the report descriptor.
814819
*/
815-
if (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
820+
if (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage, &report_id)) {
816821
cur_dev->usage_page = page;
817822
cur_dev->usage = usage;
823+
cur_dev->report_id = report_id;
818824
}
819825

820826
/*
821827
* Parse any additional usage and usage pages
822828
* out of the report descriptor.
823829
*/
824-
while (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
830+
while (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage, &report_id)) {
825831
/* Create new record for additional usage pairs */
826832
struct hid_device_info *tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
827833
struct hid_device_info *prev_dev = cur_dev;
@@ -842,6 +848,7 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device
842848
cur_dev->product_string = prev_dev->product_string? wcsdup(prev_dev->product_string): NULL;
843849
cur_dev->usage_page = page;
844850
cur_dev->usage = usage;
851+
cur_dev->report_id = report_id;
845852
cur_dev->bus_type = prev_dev->bus_type;
846853
}
847854
}

0 commit comments

Comments
 (0)