Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/sdl/hidapi/linux/hid.c
10279 views
1
/*******************************************************
2
HIDAPI - Multi-Platform library for
3
communication with HID devices.
4
5
Alan Ott
6
Signal 11 Software
7
8
libusb/hidapi Team
9
10
Copyright 2022, All Rights Reserved.
11
12
At the discretion of the user of this library,
13
this software may be licensed under the terms of the
14
GNU General Public License v3, a BSD-Style license, or the
15
original HIDAPI license as outlined in the LICENSE.txt,
16
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17
files located at the root of the source distribution.
18
These files may also be found in the public source
19
code repository located at:
20
https://github.com/libusb/hidapi .
21
********************************************************/
22
23
/* C */
24
#include <stdio.h>
25
#include <string.h>
26
#include <stdlib.h>
27
#include <locale.h>
28
#include <errno.h>
29
30
/* Unix */
31
#include <unistd.h>
32
#include <sys/types.h>
33
#include <sys/stat.h>
34
#include <sys/ioctl.h>
35
#include <sys/utsname.h>
36
#include <fcntl.h>
37
#include <poll.h>
38
39
/* Linux */
40
#include <linux/hidraw.h>
41
#include <linux/version.h>
42
#include <linux/input.h>
43
//#include <libudev.h>
44
#include "SDL_udev.h"
45
extern SDL_UDEV_PrivateData *SDL_UDEV_PrivateData_this;
46
#define udev_device_get_action (SDL_UDEV_PrivateData_this->syms.udev_device_get_action)
47
#define udev_device_get_devnode (SDL_UDEV_PrivateData_this->syms.udev_device_get_devnode)
48
#define udev_device_get_syspath (SDL_UDEV_PrivateData_this->syms.udev_device_get_syspath)
49
#define udev_device_get_subsystem (SDL_UDEV_PrivateData_this->syms.udev_device_get_subsystem)
50
#define udev_device_get_parent_with_subsystem_devtype (SDL_UDEV_PrivateData_this->syms.udev_device_get_parent_with_subsystem_devtype)
51
#define udev_device_get_property_value (SDL_UDEV_PrivateData_this->syms.udev_device_get_property_value)
52
#define udev_device_get_sysattr_value (SDL_UDEV_PrivateData_this->syms.udev_device_get_sysattr_value)
53
#define udev_device_new_from_syspath (SDL_UDEV_PrivateData_this->syms.udev_device_new_from_syspath)
54
#define udev_device_unref (SDL_UDEV_PrivateData_this->syms.udev_device_unref)
55
#define udev_enumerate_add_match_property (SDL_UDEV_PrivateData_this->syms.udev_enumerate_add_match_property)
56
#define udev_enumerate_add_match_subsystem (SDL_UDEV_PrivateData_this->syms.udev_enumerate_add_match_subsystem)
57
#define udev_enumerate_get_list_entry (SDL_UDEV_PrivateData_this->syms.udev_enumerate_get_list_entry)
58
#define udev_enumerate_new (SDL_UDEV_PrivateData_this->syms.udev_enumerate_new)
59
#define udev_enumerate_scan_devices (SDL_UDEV_PrivateData_this->syms.udev_enumerate_scan_devices)
60
#define udev_enumerate_unref (SDL_UDEV_PrivateData_this->syms.udev_enumerate_unref)
61
#define udev_list_entry_get_name (SDL_UDEV_PrivateData_this->syms.udev_list_entry_get_name)
62
#define udev_list_entry_get_next (SDL_UDEV_PrivateData_this->syms.udev_list_entry_get_next)
63
#define udev_monitor_enable_receiving (SDL_UDEV_PrivateData_this->syms.udev_monitor_enable_receiving)
64
#define udev_monitor_filter_add_match_subsystem_devtype (SDL_UDEV_PrivateData_this->syms.udev_monitor_filter_add_match_subsystem_devtype)
65
#define udev_monitor_get_fd (SDL_UDEV_PrivateData_this->syms.udev_monitor_get_fd)
66
#define udev_monitor_new_from_netlink (SDL_UDEV_PrivateData_this->syms.udev_monitor_new_from_netlink)
67
#define udev_monitor_receive_device (SDL_UDEV_PrivateData_this->syms.udev_monitor_receive_device)
68
#define udev_monitor_unref (SDL_UDEV_PrivateData_this->syms.udev_monitor_unref)
69
#define udev_new (SDL_UDEV_PrivateData_this->syms.udev_new)
70
#define udev_unref (SDL_UDEV_PrivateData_this->syms.udev_unref)
71
#define udev_device_new_from_devnum (SDL_UDEV_PrivateData_this->syms.udev_device_new_from_devnum)
72
#define udev_device_get_devnum (SDL_UDEV_PrivateData_this->syms.udev_device_get_devnum)
73
#undef SDL_UDEV_SYM
74
75
#include "../hidapi/hidapi.h"
76
77
#ifndef BUS_SPI
78
#define BUS_SPI 0x1C
79
#endif
80
81
#ifdef HIDAPI_ALLOW_BUILD_WORKAROUND_KERNEL_2_6_39
82
/* This definitions first appeared in Linux Kernel 2.6.39 in linux/hidraw.h.
83
hidapi doesn't support kernels older than that,
84
so we don't define macros below explicitly, to fail builds on old kernels.
85
For those who really need this as a workaround (e.g. to be able to build on old build machines),
86
can workaround by defining the macro above.
87
*/
88
#ifndef HIDIOCSFEATURE
89
#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
90
#endif
91
#ifndef HIDIOCGFEATURE
92
#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
93
#endif
94
95
#endif
96
97
98
// HIDIOCGINPUT is not defined in Linux kernel headers < 5.11.
99
// This definition is from hidraw.h in Linux >= 5.11.
100
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f43d3870cafa2a0f3854c1819c8385733db8f9ae
101
#ifndef HIDIOCGINPUT
102
#define HIDIOCGINPUT(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x0A, len)
103
#endif
104
105
struct hid_device_ {
106
int device_handle;
107
int blocking;
108
int needs_ble_hack;
109
wchar_t *last_error_str;
110
struct hid_device_info* device_info;
111
};
112
113
static struct hid_api_version api_version = {
114
.major = HID_API_VERSION_MAJOR,
115
.minor = HID_API_VERSION_MINOR,
116
.patch = HID_API_VERSION_PATCH
117
};
118
119
static wchar_t *last_global_error_str = NULL;
120
121
122
static hid_device *new_hid_device(void)
123
{
124
hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
125
if (dev == NULL) {
126
return NULL;
127
}
128
129
dev->device_handle = -1;
130
dev->blocking = 1;
131
dev->last_error_str = NULL;
132
dev->device_info = NULL;
133
134
return dev;
135
}
136
137
138
/* The caller must free the returned string with free(). */
139
static wchar_t *utf8_to_wchar_t(const char *utf8)
140
{
141
wchar_t *ret = NULL;
142
143
if (utf8) {
144
size_t wlen = mbstowcs(NULL, utf8, 0);
145
if ((size_t) -1 == wlen) {
146
return wcsdup(L"");
147
}
148
ret = (wchar_t*) calloc(wlen+1, sizeof(wchar_t));
149
if (ret == NULL) {
150
/* as much as we can do at this point */
151
return NULL;
152
}
153
mbstowcs(ret, utf8, wlen+1);
154
ret[wlen] = 0x0000;
155
}
156
157
return ret;
158
}
159
160
161
/* Makes a copy of the given error message (and decoded according to the
162
* currently locale) into the wide string pointer pointed by error_str.
163
* The last stored error string is freed.
164
* Use register_error_str(NULL) to free the error message completely. */
165
static void register_error_str(wchar_t **error_str, const char *msg)
166
{
167
free(*error_str);
168
#ifdef HIDAPI_USING_SDL_RUNTIME
169
/* Thread-safe error handling */
170
if (msg) {
171
SDL_SetError("%s", msg);
172
} else {
173
SDL_ClearError();
174
}
175
#else
176
*error_str = utf8_to_wchar_t(msg);
177
#endif
178
}
179
180
/* Semilar to register_error_str, but allows passing a format string with va_list args into this function. */
181
static void register_error_str_vformat(wchar_t **error_str, const char *format, va_list args)
182
{
183
char msg[256];
184
vsnprintf(msg, sizeof(msg), format, args);
185
186
register_error_str(error_str, msg);
187
}
188
189
/* Set the last global error to be reported by hid_error(NULL).
190
* The given error message will be copied (and decoded according to the
191
* currently locale, so do not pass in string constants).
192
* The last stored global error message is freed.
193
* Use register_global_error(NULL) to indicate "no error". */
194
static void register_global_error(const char *msg)
195
{
196
register_error_str(&last_global_error_str, msg);
197
}
198
199
/* Similar to register_global_error, but allows passing a format string into this function. */
200
static void register_global_error_format(const char *format, ...)
201
{
202
va_list args;
203
va_start(args, format);
204
register_error_str_vformat(&last_global_error_str, format, args);
205
va_end(args);
206
}
207
208
/* Set the last error for a device to be reported by hid_error(dev).
209
* The given error message will be copied (and decoded according to the
210
* currently locale, so do not pass in string constants).
211
* The last stored device error message is freed.
212
* Use register_device_error(dev, NULL) to indicate "no error". */
213
static void register_device_error(hid_device *dev, const char *msg)
214
{
215
register_error_str(&dev->last_error_str, msg);
216
}
217
218
/* Similar to register_device_error, but you can pass a format string into this function. */
219
static void register_device_error_format(hid_device *dev, const char *format, ...)
220
{
221
va_list args;
222
va_start(args, format);
223
register_error_str_vformat(&dev->last_error_str, format, args);
224
va_end(args);
225
}
226
227
/* Get an attribute value from a udev_device and return it as a whar_t
228
string. The returned string must be freed with free() when done.*/
229
static wchar_t *copy_udev_string(struct udev_device *dev, const char *udev_name)
230
{
231
return utf8_to_wchar_t(udev_device_get_sysattr_value(dev, udev_name));
232
}
233
234
/*
235
* Gets the size of the HID item at the given position
236
* Returns 1 if successful, 0 if an invalid key
237
* Sets data_len and key_size when successful
238
*/
239
static int get_hid_item_size(const __u8 *report_descriptor, __u32 size, unsigned int pos, int *data_len, int *key_size)
240
{
241
int key = report_descriptor[pos];
242
int size_code;
243
244
/*
245
* This is a Long Item. The next byte contains the
246
* length of the data section (value) for this key.
247
* See the HID specification, version 1.11, section
248
* 6.2.2.3, titled "Long Items."
249
*/
250
if ((key & 0xf0) == 0xf0) {
251
if (pos + 1 < size)
252
{
253
*data_len = report_descriptor[pos + 1];
254
*key_size = 3;
255
return 1;
256
}
257
*data_len = 0; /* malformed report */
258
*key_size = 0;
259
}
260
261
/*
262
* This is a Short Item. The bottom two bits of the
263
* key contain the size code for the data section
264
* (value) for this key. Refer to the HID
265
* specification, version 1.11, section 6.2.2.2,
266
* titled "Short Items."
267
*/
268
size_code = key & 0x3;
269
switch (size_code) {
270
case 0:
271
case 1:
272
case 2:
273
*data_len = size_code;
274
*key_size = 1;
275
return 1;
276
case 3:
277
*data_len = 4;
278
*key_size = 1;
279
return 1;
280
default:
281
/* Can't ever happen since size_code is & 0x3 */
282
*data_len = 0;
283
*key_size = 0;
284
break;
285
}
286
287
/* malformed report */
288
return 0;
289
}
290
291
/*
292
* Get bytes from a HID Report Descriptor.
293
* Only call with a num_bytes of 0, 1, 2, or 4.
294
*/
295
static __u32 get_hid_report_bytes(const __u8 *rpt, size_t len, size_t num_bytes, size_t cur)
296
{
297
/* Return if there aren't enough bytes. */
298
if (cur + num_bytes >= len)
299
return 0;
300
301
if (num_bytes == 0)
302
return 0;
303
else if (num_bytes == 1)
304
return rpt[cur + 1];
305
else if (num_bytes == 2)
306
return (rpt[cur + 2] * 256 + rpt[cur + 1]);
307
else if (num_bytes == 4)
308
return (
309
rpt[cur + 4] * 0x01000000 +
310
rpt[cur + 3] * 0x00010000 +
311
rpt[cur + 2] * 0x00000100 +
312
rpt[cur + 1] * 0x00000001
313
);
314
else
315
return 0;
316
}
317
318
/*
319
* Iterates until the end of a Collection.
320
* Assumes that *pos is exactly at the beginning of a Collection.
321
* Skips all nested Collection, i.e. iterates until the end of current level Collection.
322
*
323
* The return value is non-0 when an end of current Collection is found,
324
* 0 when error is occurred (broken Descriptor, end of a Collection is found before its begin,
325
* or no Collection is found at all).
326
*/
327
static int hid_iterate_over_collection(const __u8 *report_descriptor, __u32 size, unsigned int *pos, int *data_len, int *key_size)
328
{
329
int collection_level = 0;
330
331
while (*pos < size) {
332
int key = report_descriptor[*pos];
333
int key_cmd = key & 0xfc;
334
335
/* Determine data_len and key_size */
336
if (!get_hid_item_size(report_descriptor, size, *pos, data_len, key_size))
337
return 0; /* malformed report */
338
339
switch (key_cmd) {
340
case 0xa0: /* Collection 6.2.2.4 (Main) */
341
collection_level++;
342
break;
343
case 0xc0: /* End Collection 6.2.2.4 (Main) */
344
collection_level--;
345
break;
346
}
347
348
if (collection_level < 0) {
349
/* Broken descriptor or someone is using this function wrong,
350
* i.e. should be called exactly at the collection start */
351
return 0;
352
}
353
354
if (collection_level == 0) {
355
/* Found it!
356
* Also possible when called not at the collection start, but should not happen if used correctly */
357
return 1;
358
}
359
360
*pos += *data_len + *key_size;
361
}
362
363
return 0; /* Did not find the end of a Collection */
364
}
365
366
struct hid_usage_iterator {
367
unsigned int pos;
368
int usage_page_found;
369
unsigned short usage_page;
370
};
371
372
/*
373
* Retrieves the device's Usage Page and Usage from the report descriptor.
374
* The algorithm returns the current Usage Page/Usage pair whenever a new
375
* Collection is found and a Usage Local Item is currently in scope.
376
* Usage Local Items are consumed by each Main Item (See. 6.2.2.8).
377
* The algorithm should give similar results as Apple's:
378
* https://developer.apple.com/documentation/iokit/kiohiddeviceusagepairskey?language=objc
379
* Physical Collections are also matched (macOS does the same).
380
*
381
* This function can be called repeatedly until it returns non-0
382
* Usage is found. pos is the starting point (initially 0) and will be updated
383
* to the next search position.
384
*
385
* The return value is 0 when a pair is found.
386
* 1 when finished processing descriptor.
387
* -1 on a malformed report.
388
*/
389
static int get_next_hid_usage(const __u8 *report_descriptor, __u32 size, struct hid_usage_iterator *ctx, unsigned short *usage_page, unsigned short *usage)
390
{
391
int data_len, key_size;
392
int initial = ctx->pos == 0; /* Used to handle case where no top-level application collection is defined */
393
394
int usage_found = 0;
395
396
while (ctx->pos < size) {
397
int key = report_descriptor[ctx->pos];
398
int key_cmd = key & 0xfc;
399
400
/* Determine data_len and key_size */
401
if (!get_hid_item_size(report_descriptor, size, ctx->pos, &data_len, &key_size))
402
return -1; /* malformed report */
403
404
switch (key_cmd) {
405
case 0x4: /* Usage Page 6.2.2.7 (Global) */
406
ctx->usage_page = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
407
ctx->usage_page_found = 1;
408
break;
409
410
case 0x8: /* Usage 6.2.2.8 (Local) */
411
if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
412
ctx->usage_page = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos + 2);
413
ctx->usage_page_found = 1;
414
*usage = get_hid_report_bytes(report_descriptor, size, 2, ctx->pos);
415
usage_found = 1;
416
}
417
else {
418
*usage = get_hid_report_bytes(report_descriptor, size, data_len, ctx->pos);
419
usage_found = 1;
420
}
421
break;
422
423
case 0xa0: /* Collection 6.2.2.4 (Main) */
424
if (!hid_iterate_over_collection(report_descriptor, size, &ctx->pos, &data_len, &key_size)) {
425
return -1;
426
}
427
428
/* A pair is valid - to be reported when Collection is found */
429
if (usage_found && ctx->usage_page_found) {
430
*usage_page = ctx->usage_page;
431
return 0;
432
}
433
434
break;
435
}
436
437
/* Skip over this key and its associated data */
438
ctx->pos += data_len + key_size;
439
}
440
441
/* If no top-level application collection is found and usage page/usage pair is found, pair is valid
442
https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections */
443
if (initial && usage_found && ctx->usage_page_found) {
444
*usage_page = ctx->usage_page;
445
return 0; /* success */
446
}
447
448
return 1; /* finished processing */
449
}
450
451
/*
452
* Retrieves the hidraw report descriptor from a file.
453
* When using this form, <sysfs_path>/device/report_descriptor, elevated privileges are not required.
454
*/
455
static int get_hid_report_descriptor(const char *rpt_path, struct hidraw_report_descriptor *rpt_desc)
456
{
457
int rpt_handle;
458
ssize_t res;
459
460
rpt_handle = open(rpt_path, O_RDONLY | O_CLOEXEC);
461
if (rpt_handle < 0) {
462
register_global_error_format("open failed (%s): %s", rpt_path, strerror(errno));
463
return -1;
464
}
465
466
/*
467
* Read in the Report Descriptor
468
* The sysfs file has a maximum size of 4096 (which is the same as HID_MAX_DESCRIPTOR_SIZE) so we should always
469
* be ok when reading the descriptor.
470
* In practice if the HID descriptor is any larger I suspect many other things will break.
471
*/
472
memset(rpt_desc, 0x0, sizeof(*rpt_desc));
473
res = read(rpt_handle, rpt_desc->value, HID_MAX_DESCRIPTOR_SIZE);
474
if (res < 0) {
475
register_global_error_format("read failed (%s): %s", rpt_path, strerror(errno));
476
}
477
rpt_desc->size = (__u32) res;
478
479
close(rpt_handle);
480
return (int) res;
481
}
482
483
/* return size of the descriptor, or -1 on failure */
484
static int get_hid_report_descriptor_from_sysfs(const char *sysfs_path, struct hidraw_report_descriptor *rpt_desc)
485
{
486
int res = -1;
487
/* Construct <sysfs_path>/device/report_descriptor */
488
size_t rpt_path_len = strlen(sysfs_path) + 25 + 1;
489
char* rpt_path = (char*) calloc(1, rpt_path_len);
490
snprintf(rpt_path, rpt_path_len, "%s/device/report_descriptor", sysfs_path);
491
492
res = get_hid_report_descriptor(rpt_path, rpt_desc);
493
free(rpt_path);
494
495
return res;
496
}
497
498
/* return non-zero if successfully parsed */
499
static int parse_hid_vid_pid_from_uevent(const char *uevent, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
500
{
501
char tmp[1024];
502
size_t uevent_len = strlen(uevent);
503
if (uevent_len > sizeof(tmp) - 1)
504
uevent_len = sizeof(tmp) - 1;
505
memcpy(tmp, uevent, uevent_len);
506
tmp[uevent_len] = '\0';
507
508
char *saveptr = NULL;
509
char *line;
510
char *key;
511
char *value;
512
513
line = strtok_r(tmp, "\n", &saveptr);
514
while (line != NULL) {
515
/* line: "KEY=value" */
516
key = line;
517
value = strchr(line, '=');
518
if (!value) {
519
goto next_line;
520
}
521
*value = '\0';
522
value++;
523
524
if (strcmp(key, "HID_ID") == 0) {
525
/**
526
* type vendor product
527
* HID_ID=0003:000005AC:00008242
528
**/
529
int ret = sscanf(value, "%x:%hx:%hx", bus_type, vendor_id, product_id);
530
if (ret == 3) {
531
return 1;
532
}
533
}
534
535
next_line:
536
line = strtok_r(NULL, "\n", &saveptr);
537
}
538
539
register_global_error("Couldn't find/parse HID_ID");
540
return 0;
541
}
542
543
/* return non-zero if successfully parsed */
544
static int parse_hid_vid_pid_from_uevent_path(const char *uevent_path, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
545
{
546
int handle;
547
ssize_t res;
548
549
handle = open(uevent_path, O_RDONLY | O_CLOEXEC);
550
if (handle < 0) {
551
register_global_error_format("open failed (%s): %s", uevent_path, strerror(errno));
552
return 0;
553
}
554
555
char buf[1024];
556
res = read(handle, buf, sizeof(buf) - 1); /* -1 for '\0' at the end */
557
close(handle);
558
559
if (res < 0) {
560
register_global_error_format("read failed (%s): %s", uevent_path, strerror(errno));
561
return 0;
562
}
563
564
buf[res] = '\0';
565
return parse_hid_vid_pid_from_uevent(buf, bus_type, vendor_id, product_id);
566
}
567
568
/* return non-zero if successfully read/parsed */
569
static int parse_hid_vid_pid_from_sysfs(const char *sysfs_path, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id)
570
{
571
int res = 0;
572
/* Construct <sysfs_path>/device/uevent */
573
size_t uevent_path_len = strlen(sysfs_path) + 14 + 1;
574
char* uevent_path = (char*) calloc(1, uevent_path_len);
575
snprintf(uevent_path, uevent_path_len, "%s/device/uevent", sysfs_path);
576
577
res = parse_hid_vid_pid_from_uevent_path(uevent_path, bus_type, vendor_id, product_id);
578
free(uevent_path);
579
580
return res;
581
}
582
583
static int get_hid_report_descriptor_from_hidraw(hid_device *dev, struct hidraw_report_descriptor *rpt_desc)
584
{
585
int desc_size = 0;
586
587
/* Get Report Descriptor Size */
588
int res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
589
if (res < 0) {
590
register_device_error_format(dev, "ioctl(GRDESCSIZE): %s", strerror(errno));
591
return res;
592
}
593
594
/* Get Report Descriptor */
595
memset(rpt_desc, 0x0, sizeof(*rpt_desc));
596
rpt_desc->size = desc_size;
597
res = ioctl(dev->device_handle, HIDIOCGRDESC, rpt_desc);
598
if (res < 0) {
599
register_device_error_format(dev, "ioctl(GRDESC): %s", strerror(errno));
600
}
601
602
return res;
603
}
604
605
/*
606
* The caller is responsible for free()ing the (newly-allocated) character
607
* strings pointed to by serial_number_utf8 and product_name_utf8 after use.
608
*/
609
static int parse_uevent_info(const char *uevent, unsigned *bus_type,
610
unsigned short *vendor_id, unsigned short *product_id,
611
char **serial_number_utf8, char **product_name_utf8)
612
{
613
char tmp[1024];
614
615
if (!uevent) {
616
return 0;
617
}
618
619
size_t uevent_len = strlen(uevent);
620
if (uevent_len > sizeof(tmp) - 1)
621
uevent_len = sizeof(tmp) - 1;
622
memcpy(tmp, uevent, uevent_len);
623
tmp[uevent_len] = '\0';
624
625
char *saveptr = NULL;
626
char *line;
627
char *key;
628
char *value;
629
630
int found_id = 0;
631
int found_serial = 0;
632
int found_name = 0;
633
634
line = strtok_r(tmp, "\n", &saveptr);
635
while (line != NULL) {
636
/* line: "KEY=value" */
637
key = line;
638
value = strchr(line, '=');
639
if (!value) {
640
goto next_line;
641
}
642
*value = '\0';
643
value++;
644
645
if (strcmp(key, "HID_ID") == 0) {
646
/**
647
* type vendor product
648
* HID_ID=0003:000005AC:00008242
649
**/
650
int ret = sscanf(value, "%x:%hx:%hx", bus_type, vendor_id, product_id);
651
if (ret == 3) {
652
found_id = 1;
653
}
654
} else if (strcmp(key, "HID_NAME") == 0) {
655
/* The caller has to free the product name */
656
*product_name_utf8 = strdup(value);
657
found_name = 1;
658
} else if (strcmp(key, "HID_UNIQ") == 0) {
659
/* The caller has to free the serial number */
660
*serial_number_utf8 = strdup(value);
661
found_serial = 1;
662
}
663
664
next_line:
665
line = strtok_r(NULL, "\n", &saveptr);
666
}
667
668
return (found_id && found_name && found_serial);
669
}
670
671
static int is_BLE(hid_device *dev)
672
{
673
struct udev *udev;
674
struct udev_device *udev_dev, *hid_dev;
675
struct stat s;
676
int ret;
677
678
/* Create the udev object */
679
udev = udev_new();
680
if (!udev) {
681
printf("Can't create udev\n");
682
return -1;
683
}
684
685
/* Get the dev_t (major/minor numbers) from the file handle. */
686
if (fstat(dev->device_handle, &s) < 0) {
687
udev_unref(udev);
688
return -1;
689
}
690
691
/* Open a udev device from the dev_t. 'c' means character device. */
692
ret = 0;
693
udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
694
if (udev_dev) {
695
hid_dev = udev_device_get_parent_with_subsystem_devtype(
696
udev_dev,
697
"hid",
698
NULL);
699
if (hid_dev) {
700
unsigned short dev_vid = 0;
701
unsigned short dev_pid = 0;
702
unsigned bus_type = 0;
703
char *serial_number_utf8 = NULL;
704
char *product_name_utf8 = NULL;
705
706
parse_uevent_info(
707
udev_device_get_sysattr_value(hid_dev, "uevent"),
708
&bus_type,
709
&dev_vid,
710
&dev_pid,
711
&serial_number_utf8,
712
&product_name_utf8);
713
free(serial_number_utf8);
714
free(product_name_utf8);
715
716
if (bus_type == BUS_BLUETOOTH) {
717
/* Right now the Steam Controller is the only BLE device that we send feature reports to */
718
if (dev_vid == 0x28de /* Valve */) {
719
ret = 1;
720
}
721
}
722
723
/* hid_dev doesn't need to be (and can't be) unref'd.
724
I'm not sure why, but it'll throw double-free() errors. */
725
}
726
udev_device_unref(udev_dev);
727
}
728
729
udev_unref(udev);
730
731
return ret;
732
}
733
734
735
static struct hid_device_info * create_device_info_for_device(struct udev_device *raw_dev)
736
{
737
struct hid_device_info *root = NULL;
738
struct hid_device_info *cur_dev = NULL;
739
740
const char *sysfs_path;
741
const char *dev_path;
742
const char *str;
743
struct udev_device *hid_dev; /* The device's HID udev node. */
744
struct udev_device *usb_dev; /* The device's USB udev node. */
745
struct udev_device *intf_dev; /* The device's interface (in the USB sense). */
746
unsigned short dev_vid;
747
unsigned short dev_pid;
748
char *serial_number_utf8 = NULL;
749
char *product_name_utf8 = NULL;
750
unsigned bus_type;
751
int result;
752
struct hidraw_report_descriptor report_desc;
753
754
sysfs_path = udev_device_get_syspath(raw_dev);
755
dev_path = udev_device_get_devnode(raw_dev);
756
757
hid_dev = udev_device_get_parent_with_subsystem_devtype(
758
raw_dev,
759
"hid",
760
NULL);
761
762
if (!hid_dev) {
763
/* Unable to find parent hid device. */
764
goto end;
765
}
766
767
result = parse_uevent_info(
768
udev_device_get_sysattr_value(hid_dev, "uevent"),
769
&bus_type,
770
&dev_vid,
771
&dev_pid,
772
&serial_number_utf8,
773
&product_name_utf8);
774
775
if (!result) {
776
/* parse_uevent_info() failed for at least one field. */
777
goto end;
778
}
779
780
/* Filter out unhandled devices right away */
781
switch (bus_type) {
782
case BUS_BLUETOOTH:
783
case BUS_I2C:
784
case BUS_USB:
785
case BUS_SPI:
786
break;
787
788
default:
789
goto end;
790
}
791
792
/* Create the record. */
793
root = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
794
if (!root)
795
goto end;
796
797
cur_dev = root;
798
799
/* Fill out the record */
800
cur_dev->next = NULL;
801
cur_dev->path = dev_path? strdup(dev_path): NULL;
802
803
/* VID/PID */
804
cur_dev->vendor_id = dev_vid;
805
cur_dev->product_id = dev_pid;
806
807
/* Serial Number */
808
cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8);
809
810
/* Release Number */
811
cur_dev->release_number = 0x0;
812
813
/* Interface Number */
814
cur_dev->interface_number = -1;
815
816
switch (bus_type) {
817
case BUS_USB:
818
/* The device pointed to by raw_dev contains information about
819
the hidraw device. In order to get information about the
820
USB device, get the parent device with the
821
subsystem/devtype pair of "usb"/"usb_device". This will
822
be several levels up the tree, but the function will find
823
it. */
824
usb_dev = udev_device_get_parent_with_subsystem_devtype(
825
raw_dev,
826
"usb",
827
"usb_device");
828
829
/* uhid USB devices
830
* Since this is a virtual hid interface, no USB information will
831
* be available. */
832
if (!usb_dev) {
833
/* Manufacturer and Product strings */
834
cur_dev->manufacturer_string = wcsdup(L"");
835
cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
836
break;
837
}
838
839
cur_dev->manufacturer_string = copy_udev_string(usb_dev, "manufacturer");
840
cur_dev->product_string = copy_udev_string(usb_dev, "product");
841
842
cur_dev->bus_type = HID_API_BUS_USB;
843
844
str = udev_device_get_sysattr_value(usb_dev, "bcdDevice");
845
cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
846
847
/* Get a handle to the interface's udev node. */
848
intf_dev = udev_device_get_parent_with_subsystem_devtype(
849
raw_dev,
850
"usb",
851
"usb_interface");
852
if (intf_dev) {
853
str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
854
cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
855
}
856
857
break;
858
859
case BUS_BLUETOOTH:
860
cur_dev->manufacturer_string = wcsdup(L"");
861
cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
862
863
cur_dev->bus_type = HID_API_BUS_BLUETOOTH;
864
865
break;
866
case BUS_I2C:
867
cur_dev->manufacturer_string = wcsdup(L"");
868
cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
869
870
cur_dev->bus_type = HID_API_BUS_I2C;
871
872
break;
873
874
case BUS_SPI:
875
cur_dev->manufacturer_string = wcsdup(L"");
876
cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
877
878
cur_dev->bus_type = HID_API_BUS_SPI;
879
880
break;
881
882
default:
883
/* Unknown device type - this should never happen, as we
884
* check for USB and Bluetooth devices above */
885
break;
886
}
887
888
/* Usage Page and Usage */
889
result = get_hid_report_descriptor_from_sysfs(sysfs_path, &report_desc);
890
if (result >= 0) {
891
unsigned short page = 0, usage = 0;
892
struct hid_usage_iterator usage_iterator;
893
memset(&usage_iterator, 0, sizeof(usage_iterator));
894
895
/*
896
* Parse the first usage and usage page
897
* out of the report descriptor.
898
*/
899
if (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
900
cur_dev->usage_page = page;
901
cur_dev->usage = usage;
902
}
903
904
/*
905
* Parse any additional usage and usage pages
906
* out of the report descriptor.
907
*/
908
while (!get_next_hid_usage(report_desc.value, report_desc.size, &usage_iterator, &page, &usage)) {
909
/* Create new record for additional usage pairs */
910
struct hid_device_info *tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
911
struct hid_device_info *prev_dev = cur_dev;
912
913
if (!tmp)
914
continue;
915
cur_dev->next = tmp;
916
cur_dev = tmp;
917
918
/* Update fields */
919
cur_dev->path = dev_path? strdup(dev_path): NULL;
920
cur_dev->vendor_id = dev_vid;
921
cur_dev->product_id = dev_pid;
922
cur_dev->serial_number = prev_dev->serial_number? wcsdup(prev_dev->serial_number): NULL;
923
cur_dev->release_number = prev_dev->release_number;
924
cur_dev->interface_number = prev_dev->interface_number;
925
cur_dev->manufacturer_string = prev_dev->manufacturer_string? wcsdup(prev_dev->manufacturer_string): NULL;
926
cur_dev->product_string = prev_dev->product_string? wcsdup(prev_dev->product_string): NULL;
927
cur_dev->usage_page = page;
928
cur_dev->usage = usage;
929
cur_dev->bus_type = prev_dev->bus_type;
930
}
931
}
932
933
#ifdef HIDAPI_IGNORE_DEVICE
934
{
935
struct hid_device_info *prev_dev = NULL;
936
937
cur_dev = root;
938
while (cur_dev) {
939
if (HIDAPI_IGNORE_DEVICE(cur_dev->bus_type, cur_dev->vendor_id, cur_dev->product_id, cur_dev->usage_page, cur_dev->usage)) {
940
struct hid_device_info *tmp = cur_dev;
941
942
cur_dev = tmp->next;
943
if (prev_dev) {
944
prev_dev->next = cur_dev;
945
} else {
946
root = cur_dev;
947
}
948
tmp->next = NULL;
949
950
hid_free_enumeration(tmp);
951
} else {
952
prev_dev = cur_dev;
953
cur_dev = cur_dev->next;
954
}
955
}
956
}
957
#endif
958
959
end:
960
free(serial_number_utf8);
961
free(product_name_utf8);
962
963
return root;
964
}
965
966
static struct hid_device_info * create_device_info_for_hid_device(hid_device *dev) {
967
struct udev *udev;
968
struct udev_device *udev_dev;
969
struct stat s;
970
int ret = -1;
971
struct hid_device_info *root = NULL;
972
973
register_device_error(dev, NULL);
974
975
/* Get the dev_t (major/minor numbers) from the file handle. */
976
ret = fstat(dev->device_handle, &s);
977
if (-1 == ret) {
978
register_device_error(dev, "Failed to stat device handle");
979
return NULL;
980
}
981
982
/* Create the udev object */
983
udev = udev_new();
984
if (!udev) {
985
register_device_error(dev, "Couldn't create udev context");
986
return NULL;
987
}
988
989
/* Open a udev device from the dev_t. 'c' means character device. */
990
udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
991
if (udev_dev) {
992
root = create_device_info_for_device(udev_dev);
993
}
994
995
if (!root) {
996
/* TODO: have a better error reporting via create_device_info_for_device */
997
register_device_error(dev, "Couldn't create hid_device_info");
998
}
999
1000
udev_device_unref(udev_dev);
1001
udev_unref(udev);
1002
1003
return root;
1004
}
1005
1006
HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
1007
{
1008
return &api_version;
1009
}
1010
1011
HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
1012
{
1013
return HID_API_VERSION_STR;
1014
}
1015
1016
int HID_API_EXPORT hid_init(void)
1017
{
1018
const char *locale;
1019
1020
/* indicate no error */
1021
register_global_error(NULL);
1022
1023
/* Set the locale if it's not set. */
1024
locale = setlocale(LC_CTYPE, NULL);
1025
if (!locale)
1026
setlocale(LC_CTYPE, "");
1027
1028
return 0;
1029
}
1030
1031
int HID_API_EXPORT hid_exit(void)
1032
{
1033
/* Free global error message */
1034
register_global_error(NULL);
1035
1036
return 0;
1037
}
1038
1039
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
1040
{
1041
struct udev *udev;
1042
struct udev_enumerate *enumerate;
1043
struct udev_list_entry *devices, *dev_list_entry;
1044
1045
struct hid_device_info *root = NULL; /* return object */
1046
struct hid_device_info *cur_dev = NULL;
1047
1048
hid_init();
1049
/* register_global_error: global error is reset by hid_init */
1050
1051
/* Create the udev object */
1052
udev = udev_new();
1053
if (!udev) {
1054
register_global_error("Couldn't create udev context");
1055
return NULL;
1056
}
1057
1058
/* Create a list of the devices in the 'hidraw' subsystem. */
1059
enumerate = udev_enumerate_new(udev);
1060
udev_enumerate_add_match_subsystem(enumerate, "hidraw");
1061
udev_enumerate_scan_devices(enumerate);
1062
devices = udev_enumerate_get_list_entry(enumerate);
1063
/* For each item, see if it matches the vid/pid, and if so
1064
create a udev_device record for it */
1065
udev_list_entry_foreach(dev_list_entry, devices) {
1066
const char *sysfs_path;
1067
unsigned short dev_vid = 0;
1068
unsigned short dev_pid = 0;
1069
unsigned bus_type = 0;
1070
struct udev_device *raw_dev; /* The device's hidraw udev node. */
1071
struct hid_device_info * tmp;
1072
1073
/* Get the filename of the /sys entry for the device
1074
and create a udev_device object (dev) representing it */
1075
sysfs_path = udev_list_entry_get_name(dev_list_entry);
1076
if (!sysfs_path)
1077
continue;
1078
1079
if (vendor_id != 0 || product_id != 0) {
1080
if (!parse_hid_vid_pid_from_sysfs(sysfs_path, &bus_type, &dev_vid, &dev_pid))
1081
continue;
1082
1083
if (vendor_id != 0 && vendor_id != dev_vid)
1084
continue;
1085
if (product_id != 0 && product_id != dev_pid)
1086
continue;
1087
}
1088
1089
raw_dev = udev_device_new_from_syspath(udev, sysfs_path);
1090
if (!raw_dev)
1091
continue;
1092
1093
tmp = create_device_info_for_device(raw_dev);
1094
if (tmp) {
1095
if (cur_dev) {
1096
cur_dev->next = tmp;
1097
}
1098
else {
1099
root = tmp;
1100
}
1101
cur_dev = tmp;
1102
1103
/* move the pointer to the tail of returned list */
1104
while (cur_dev->next != NULL) {
1105
cur_dev = cur_dev->next;
1106
}
1107
}
1108
1109
udev_device_unref(raw_dev);
1110
}
1111
/* Free the enumerator and udev objects. */
1112
udev_enumerate_unref(enumerate);
1113
udev_unref(udev);
1114
1115
if (root == NULL) {
1116
if (vendor_id == 0 && product_id == 0) {
1117
register_global_error("No HID devices found in the system.");
1118
} else {
1119
register_global_error("No HID devices with requested VID/PID found in the system.");
1120
}
1121
}
1122
1123
return root;
1124
}
1125
1126
void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
1127
{
1128
struct hid_device_info *d = devs;
1129
while (d) {
1130
struct hid_device_info *next = d->next;
1131
free(d->path);
1132
free(d->serial_number);
1133
free(d->manufacturer_string);
1134
free(d->product_string);
1135
free(d);
1136
d = next;
1137
}
1138
}
1139
1140
hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1141
{
1142
struct hid_device_info *devs, *cur_dev;
1143
const char *path_to_open = NULL;
1144
hid_device *handle = NULL;
1145
1146
/* register_global_error: global error is reset by hid_enumerate/hid_init */
1147
devs = hid_enumerate(vendor_id, product_id);
1148
if (devs == NULL) {
1149
/* register_global_error: global error is already set by hid_enumerate */
1150
return NULL;
1151
}
1152
1153
cur_dev = devs;
1154
while (cur_dev) {
1155
if (cur_dev->vendor_id == vendor_id &&
1156
cur_dev->product_id == product_id) {
1157
if (serial_number) {
1158
if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
1159
path_to_open = cur_dev->path;
1160
break;
1161
}
1162
}
1163
else {
1164
path_to_open = cur_dev->path;
1165
break;
1166
}
1167
}
1168
cur_dev = cur_dev->next;
1169
}
1170
1171
if (path_to_open) {
1172
/* Open the device */
1173
handle = hid_open_path(path_to_open);
1174
} else {
1175
register_global_error("Device with requested VID/PID/(SerialNumber) not found");
1176
}
1177
1178
hid_free_enumeration(devs);
1179
1180
return handle;
1181
}
1182
1183
hid_device * HID_API_EXPORT hid_open_path(const char *path)
1184
{
1185
hid_device *dev = NULL;
1186
1187
hid_init();
1188
/* register_global_error: global error is reset by hid_init */
1189
1190
dev = new_hid_device();
1191
if (!dev) {
1192
register_global_error("Couldn't allocate memory");
1193
return NULL;
1194
}
1195
1196
const int MAX_ATTEMPTS = 50;
1197
int attempt;
1198
for (attempt = 1; attempt <= MAX_ATTEMPTS; ++attempt) {
1199
dev->device_handle = open(path, O_RDWR | O_CLOEXEC);
1200
if (dev->device_handle < 0 && errno == EACCES) {
1201
/* udev might be setting up permissions, wait a bit and try again */
1202
usleep(1 * 1000);
1203
continue;
1204
}
1205
break;
1206
}
1207
1208
if (dev->device_handle >= 0) {
1209
int res, desc_size = 0;
1210
1211
/* Make sure this is a HIDRAW device - responds to HIDIOCGRDESCSIZE */
1212
res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
1213
if (res < 0) {
1214
hid_close(dev);
1215
register_global_error_format("ioctl(GRDESCSIZE) error for '%s', not a HIDRAW device?: %s", path, strerror(errno));
1216
return NULL;
1217
}
1218
1219
dev->needs_ble_hack = (is_BLE(dev) == 1);
1220
1221
return dev;
1222
}
1223
else {
1224
/* Unable to open a device. */
1225
free(dev);
1226
register_global_error_format("Failed to open a device with path '%s': %s", path, strerror(errno));
1227
return NULL;
1228
}
1229
}
1230
1231
1232
int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1233
{
1234
int bytes_written;
1235
1236
if (!data || (length == 0)) {
1237
errno = EINVAL;
1238
register_device_error(dev, strerror(errno));
1239
return -1;
1240
}
1241
1242
bytes_written = write(dev->device_handle, data, length);
1243
1244
register_device_error(dev, (bytes_written == -1)? strerror(errno): NULL);
1245
1246
return bytes_written;
1247
}
1248
1249
1250
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1251
{
1252
/* Set device error to none */
1253
register_device_error(dev, NULL);
1254
1255
int bytes_read;
1256
1257
if (milliseconds >= 0) {
1258
/* Milliseconds is either 0 (non-blocking) or > 0 (contains
1259
a valid timeout). In both cases we want to call poll()
1260
and wait for data to arrive. Don't rely on non-blocking
1261
operation (O_NONBLOCK) since some kernels don't seem to
1262
properly report device disconnection through read() when
1263
in non-blocking mode. */
1264
int ret;
1265
struct pollfd fds;
1266
1267
fds.fd = dev->device_handle;
1268
fds.events = POLLIN;
1269
fds.revents = 0;
1270
ret = poll(&fds, 1, milliseconds);
1271
if (ret == 0) {
1272
/* Timeout */
1273
return ret;
1274
}
1275
if (ret == -1) {
1276
/* Error */
1277
register_device_error(dev, strerror(errno));
1278
return ret;
1279
}
1280
else {
1281
/* Check for errors on the file descriptor. This will
1282
indicate a device disconnection. */
1283
if (fds.revents & (POLLERR | POLLHUP | POLLNVAL)) {
1284
// We cannot use strerror() here as no -1 was returned from poll().
1285
register_device_error(dev, "hid_read_timeout: unexpected poll error (device disconnected)");
1286
return -1;
1287
}
1288
}
1289
}
1290
1291
bytes_read = read(dev->device_handle, data, length);
1292
if (bytes_read < 0) {
1293
if (errno == EAGAIN || errno == EINPROGRESS)
1294
bytes_read = 0;
1295
else
1296
register_device_error(dev, strerror(errno));
1297
}
1298
1299
return bytes_read;
1300
}
1301
1302
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1303
{
1304
return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
1305
}
1306
1307
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1308
{
1309
/* Do all non-blocking in userspace using poll(), since it looks
1310
like there's a bug in the kernel in some versions where
1311
read() will not return -1 on disconnection of the USB device */
1312
1313
dev->blocking = !nonblock;
1314
return 0; /* Success */
1315
}
1316
1317
1318
int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1319
{
1320
static const int MAX_RETRIES = 50;
1321
int retry;
1322
int res;
1323
1324
register_device_error(dev, NULL);
1325
1326
for (retry = 0; retry < MAX_RETRIES; ++retry) {
1327
res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
1328
if (res < 0 && errno == EPIPE) {
1329
/* Try again... */
1330
continue;
1331
}
1332
1333
if (res < 0)
1334
register_device_error_format(dev, "ioctl (SFEATURE): %s", strerror(errno));
1335
break;
1336
}
1337
return res;
1338
}
1339
1340
int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1341
{
1342
int res;
1343
unsigned char report = data[0];
1344
1345
register_device_error(dev, NULL);
1346
1347
res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
1348
if (res < 0)
1349
register_device_error_format(dev, "ioctl (GFEATURE): %s", strerror(errno));
1350
else if (dev->needs_ble_hack) {
1351
/* Versions of BlueZ before 5.56 don't include the report in the data,
1352
* and versions of BlueZ >= 5.56 include 2 copies of the report.
1353
* We'll fix it so that there is a single copy of the report in both cases
1354
*/
1355
if (data[0] == report && data[1] == report) {
1356
memmove(&data[0], &data[1], res);
1357
} else if (data[0] != report) {
1358
memmove(&data[1], &data[0], res);
1359
data[0] = report;
1360
++res;
1361
}
1362
}
1363
1364
return res;
1365
}
1366
1367
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1368
{
1369
int res;
1370
1371
register_device_error(dev, NULL);
1372
1373
res = ioctl(dev->device_handle, HIDIOCGINPUT(length), data);
1374
if (res < 0)
1375
register_device_error_format(dev, "ioctl (GINPUT): %s", strerror(errno));
1376
1377
return res;
1378
}
1379
1380
void HID_API_EXPORT hid_close(hid_device *dev)
1381
{
1382
if (!dev)
1383
return;
1384
1385
close(dev->device_handle);
1386
1387
/* Free the device error message */
1388
register_device_error(dev, NULL);
1389
1390
hid_free_enumeration(dev->device_info);
1391
1392
free(dev);
1393
}
1394
1395
1396
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1397
{
1398
if (!string || !maxlen) {
1399
register_device_error(dev, "Zero buffer/length");
1400
return -1;
1401
}
1402
1403
struct hid_device_info *info = hid_get_device_info(dev);
1404
if (!info) {
1405
// hid_get_device_info will have set an error already
1406
return -1;
1407
}
1408
1409
if (info->manufacturer_string) {
1410
wcsncpy(string, info->manufacturer_string, maxlen);
1411
string[maxlen - 1] = L'\0';
1412
}
1413
else {
1414
string[0] = L'\0';
1415
}
1416
1417
return 0;
1418
}
1419
1420
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1421
{
1422
if (!string || !maxlen) {
1423
register_device_error(dev, "Zero buffer/length");
1424
return -1;
1425
}
1426
1427
struct hid_device_info *info = hid_get_device_info(dev);
1428
if (!info) {
1429
// hid_get_device_info will have set an error already
1430
return -1;
1431
}
1432
1433
if (info->product_string) {
1434
wcsncpy(string, info->product_string, maxlen);
1435
string[maxlen - 1] = L'\0';
1436
}
1437
else {
1438
string[0] = L'\0';
1439
}
1440
1441
return 0;
1442
}
1443
1444
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1445
{
1446
if (!string || !maxlen) {
1447
register_device_error(dev, "Zero buffer/length");
1448
return -1;
1449
}
1450
1451
struct hid_device_info *info = hid_get_device_info(dev);
1452
if (!info) {
1453
// hid_get_device_info will have set an error already
1454
return -1;
1455
}
1456
1457
if (info->serial_number) {
1458
wcsncpy(string, info->serial_number, maxlen);
1459
string[maxlen - 1] = L'\0';
1460
}
1461
else {
1462
string[0] = L'\0';
1463
}
1464
1465
return 0;
1466
}
1467
1468
1469
HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
1470
if (!dev->device_info) {
1471
// Lazy initialize device_info
1472
dev->device_info = create_device_info_for_hid_device(dev);
1473
}
1474
1475
// create_device_info_for_hid_device will set an error if needed
1476
return dev->device_info;
1477
}
1478
1479
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1480
{
1481
(void)string_index;
1482
(void)string;
1483
(void)maxlen;
1484
1485
register_device_error(dev, "hid_get_indexed_string: not supported by hidraw");
1486
1487
return -1;
1488
}
1489
1490
1491
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1492
{
1493
struct hidraw_report_descriptor rpt_desc;
1494
int res = get_hid_report_descriptor_from_hidraw(dev, &rpt_desc);
1495
if (res < 0) {
1496
/* error already registered */
1497
return res;
1498
}
1499
1500
if (rpt_desc.size < buf_size) {
1501
buf_size = (size_t) rpt_desc.size;
1502
}
1503
1504
memcpy(buf, rpt_desc.value, buf_size);
1505
1506
return (int) buf_size;
1507
}
1508
1509
1510
/* Passing in NULL means asking for the last global error message. */
1511
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1512
{
1513
if (dev) {
1514
if (dev->last_error_str == NULL)
1515
return L"Success";
1516
return dev->last_error_str;
1517
}
1518
1519
if (last_global_error_str == NULL)
1520
return L"Success";
1521
return last_global_error_str;
1522
}
1523
1524