Skip to content

Commit 30c07d0

Browse files
committed
Global error implementation for libusb
1 parent af6468b commit 30c07d0

File tree

1 file changed

+62
-12
lines changed

1 file changed

+62
-12
lines changed

libusb/hid.c

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ static struct hid_api_version api_version = {
147147

148148
static libusb_context *usb_context = NULL;
149149

150+
static hidapi_error_ctx last_global_error;
151+
150152
uint16_t get_usb_code_for_current_locale(void);
151153
static int return_data(hid_device *dev, unsigned char *data, size_t length);
152154

@@ -583,12 +585,17 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
583585

584586
int HID_API_EXPORT hid_init(void)
585587
{
588+
register_libusb_error(&last_global_error, LIBUSB_SUCCESS, NULL);
589+
586590
if (!usb_context) {
587591
const char *locale;
588592

589593
/* Init Libusb */
590-
if (libusb_init(&usb_context))
594+
int res = libusb_init(&usb_context);
595+
if (res) {
596+
register_libusb_error(&last_global_error, res, "libusb_init");
591597
return -1;
598+
}
592599

593600
/* Set the locale if it's not set. */
594601
locale = setlocale(LC_CTYPE, NULL);
@@ -606,6 +613,10 @@ int HID_API_EXPORT hid_exit(void)
606613
usb_context = NULL;
607614
}
608615

616+
/* Free global error state */
617+
free_hidapi_error(&last_global_error);
618+
memset(&last_global_error, 0, sizeof(last_global_error));
619+
609620
return 0;
610621
}
611622

@@ -898,11 +909,14 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
898909
struct hid_device_info *cur_dev = NULL;
899910

900911
if(hid_init() < 0)
912+
/* register_global_error: global error is set by hid_init */
901913
return NULL;
902914

903915
num_devs = libusb_get_device_list(usb_context, &devs);
904-
if (num_devs < 0)
916+
if (num_devs < 0) {
917+
register_libusb_error(&last_global_error, (enum libusb_error)num_devs, "libusb_get_device_list");
905918
return NULL;
919+
}
906920
while ((dev = devs[i++]) != NULL) {
907921
struct libusb_device_descriptor desc;
908922
struct libusb_config_descriptor *conf_desc = NULL;
@@ -997,6 +1011,14 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
9971011

9981012
libusb_free_device_list(devs, 1);
9991013

1014+
if (root == NULL) {
1015+
if (vendor_id == 0 && product_id == 0) {
1016+
register_string_error(&last_global_error, "No HID devices found in the system.");
1017+
} else {
1018+
register_string_error(&last_global_error, "No HID devices with requested VID/PID found in the system.");
1019+
}
1020+
}
1021+
10001022
return root;
10011023
}
10021024

@@ -1020,7 +1042,13 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
10201042
const char *path_to_open = NULL;
10211043
hid_device *handle = NULL;
10221044

1045+
/* register_global_error: global error is reset by hid_enumerate/hid_init */
10231046
devs = hid_enumerate(vendor_id, product_id);
1047+
if (!devs) {
1048+
/* register_global_error: global error is already set by hid_enumerate */
1049+
return NULL;
1050+
}
1051+
10241052
cur_dev = devs;
10251053
while (cur_dev) {
10261054
if (cur_dev->vendor_id == vendor_id &&
@@ -1043,6 +1071,8 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
10431071
if (path_to_open) {
10441072
/* Open the device */
10451073
handle = hid_open_path(path_to_open);
1074+
} else {
1075+
register_string_error(&last_global_error, "Device with requested VID/PID/(SerialNumber) not found");
10461076
}
10471077

10481078
hid_free_enumeration(devs);
@@ -1371,15 +1401,22 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
13711401
int good_open = 0;
13721402

13731403
if(hid_init() < 0)
1404+
/* register_global_error: global error is set by hid_init */
13741405
return NULL;
13751406

13761407
dev = new_hid_device();
13771408
if (!dev) {
13781409
LOG("hid_open_path failed: Couldn't allocate memory\n");
1410+
register_string_error(&last_global_error, "hid_open_path: Couldn't allocate memory");
13791411
return NULL;
13801412
}
13811413

1382-
libusb_get_device_list(usb_context, &devs);
1414+
res = libusb_get_device_list(usb_context, &devs);
1415+
if (res < 0) {
1416+
register_libusb_error(&last_global_error, res, "hid_open_path/libusb_get_device_list");
1417+
free_hid_device(dev);
1418+
return NULL;
1419+
}
13831420
while ((usb_dev = devs[d++]) != NULL && !good_open) {
13841421
struct libusb_device_descriptor desc;
13851422
struct libusb_config_descriptor *conf_desc = NULL;
@@ -1409,11 +1446,14 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
14091446
res = libusb_open(usb_dev, &dev->device_handle);
14101447
if (res < 0) {
14111448
LOG("can't open device\n");
1449+
register_libusb_error(&last_global_error, res, "hid_open_path/libusb_open");
14121450
break;
14131451
}
14141452
good_open = hidapi_initialize_device(dev, intf_desc, conf_desc);
1415-
if (!good_open)
1453+
if (!good_open) {
1454+
register_string_error(&last_global_error, "hid_open_path: failed to initialize device");
14161455
libusb_close(dev->device_handle);
1456+
}
14171457
}
14181458
}
14191459
}
@@ -1429,6 +1469,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
14291469
}
14301470
else {
14311471
/* Unable to open any devices. */
1472+
if (last_global_error.error_code == LIBUSB_SUCCESS) {
1473+
register_string_error(&last_global_error, "hid_open_path: device not found");
1474+
}
14321475
free_hid_device(dev);
14331476
return NULL;
14341477
}
@@ -1446,17 +1489,19 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys
14461489
int j = 0, k = 0;
14471490

14481491
if(hid_init() < 0)
1492+
/* register_global_error: global error is set by hid_init */
14491493
return NULL;
14501494

14511495
dev = new_hid_device();
14521496
if (!dev) {
1453-
LOG("libusb_wrap_sys_device failed: Couldn't allocate memory\n");
1497+
register_string_error(&last_global_error, "hid_libusb_wrap_sys_device: Couldn't allocate memory");
14541498
return NULL;
14551499
}
14561500

14571501
res = libusb_wrap_sys_device(usb_context, sys_dev, &dev->device_handle);
14581502
if (res < 0) {
14591503
LOG("libusb_wrap_sys_device failed: %d %s\n", res, libusb_error_name(res));
1504+
register_libusb_error(&last_global_error, res, "hid_libusb_wrap_sys_device/libusb_wrap_sys_device");
14601505
goto err;
14611506
}
14621507

@@ -1466,6 +1511,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys
14661511

14671512
if (!conf_desc) {
14681513
LOG("Failed to get configuration descriptor: %d %s\n", res, libusb_error_name(res));
1514+
register_libusb_error(&last_global_error, res, "hid_libusb_wrap_sys_device/get_config_descriptor");
14691515
goto err;
14701516
}
14711517

@@ -1486,15 +1532,19 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys
14861532
if (!selected_intf_desc) {
14871533
if (interface_num < 0) {
14881534
LOG("Sys USB device doesn't contain a HID interface\n");
1535+
register_string_error(&last_global_error, "hid_libusb_wrap_sys_device: device doesn't contain a HID interface");
14891536
}
14901537
else {
14911538
LOG("Sys USB device doesn't contain a HID interface with number %d\n", interface_num);
1539+
register_string_error(&last_global_error, "hid_libusb_wrap_sys_device: device doesn't contain the requested HID interface");
14921540
}
14931541
goto err;
14941542
}
14951543

1496-
if (!hidapi_initialize_device(dev, selected_intf_desc, conf_desc))
1544+
if (!hidapi_initialize_device(dev, selected_intf_desc, conf_desc)) {
1545+
register_string_error(&last_global_error, "hid_libusb_wrap_sys_device: failed to initialize device");
14971546
goto err;
1547+
}
14981548

14991549
return dev;
15001550

@@ -1508,6 +1558,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys
15081558
(void)sys_dev;
15091559
(void)interface_num;
15101560
LOG("libusb_wrap_sys_device is not available\n");
1561+
register_string_error(&last_global_error, "libusb_wrap_sys_device is not available (libusb API too old)");
15111562
#endif
15121563
return NULL;
15131564
}
@@ -1998,11 +2049,11 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
19982049
hidapi_error_ctx *err;
19992050

20002051
if (!dev) {
2001-
/* TODO: have a global error handling */
2002-
return L"Global hid_error is not implemented yet";
2052+
err = &last_global_error;
2053+
}
2054+
else {
2055+
err = &dev->error;
20032056
}
2004-
2005-
err = &dev->error;
20062057

20072058
if (err->error_code == LIBUSB_SUCCESS) {
20082059
return L"Success";
@@ -2065,8 +2116,7 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
20652116
HID_API_EXPORT int HID_API_CALL hid_libusb_error(hid_device *dev)
20662117
{
20672118
if (!dev) {
2068-
/* TODO: to be implemented as part of global error implementation */
2069-
return LIBUSB_SUCCESS;
2119+
return last_global_error.error_code;
20702120
}
20712121

20722122
return dev->error.error_code;

0 commit comments

Comments
 (0)