hosted/cmsis_dap: Enhanced the hid_open failure output on Linux to help users narrow down the issue faster

This commit is contained in:
dragonmux 2022-07-12 11:33:33 -04:00 committed by Piotr Esden-Tempski
parent 0d2fb6ab79
commit ae81d1635f
1 changed files with 41 additions and 2 deletions

View File

@ -33,6 +33,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <hidapi.h> #include <hidapi.h>
#include <wchar.h> #include <wchar.h>
#include <sys/stat.h>
#include "bmp_hosted.h" #include "bmp_hosted.h"
#include "dap.h" #include "dap.h"
@ -80,6 +81,38 @@ static size_t mbslen(const char *str)
return result; return result;
} }
#ifdef __linux__
static void dap_hid_print_permissions_for(const struct hid_device_info *const dev)
{
const char *const path = dev->path;
PRINT_INFO("Tried device '%s'", path);
struct stat dev_stat;
if (stat(path, &dev_stat) == 0) {
PRINT_INFO(", permissions = %04o, owner = %u, group = %u",
dev_stat.st_mode & ACCESSPERMS, dev_stat.st_uid, dev_stat.st_gid);
}
PRINT_INFO("\n");
}
static void dap_hid_print_permissions(const uint16_t vid, const uint16_t pid, const wchar_t *const serial)
{
struct hid_device_info *const devs = hid_enumerate(vid, pid);
if (!devs)
return;
for (const struct hid_device_info *dev = devs; dev; dev = dev->next) {
if (serial) {
if (wcscmp(serial, dev->serial_number) == 0) {
dap_hid_print_permissions_for(dev);
break;
}
}
else
dap_hid_print_permissions_for(dev);
}
hid_free_enumeration(devs);
}
#endif
static bool dap_init_hid(const bmp_info_t *const info) static bool dap_init_hid(const bmp_info_t *const info)
{ {
DEBUG_INFO("Using hid transfer\n"); DEBUG_INFO("Using hid transfer\n");
@ -89,24 +122,30 @@ static bool dap_init_hid(const bmp_info_t *const info)
const size_t size = mbslen(info->serial); const size_t size = mbslen(info->serial);
if (size > 64) { if (size > 64) {
PRINT_INFO("Serial number invalid, aborting\n"); PRINT_INFO("Serial number invalid, aborting\n");
hid_exit();
return false; return false;
} }
wchar_t serial[65] = {0}; wchar_t serial[65] = {0};
if (mbstowcs(serial, info->serial, size) != size) { if (mbstowcs(serial, info->serial, size) != size) {
PRINT_INFO("Serial number conversion failed, aborting\n"); PRINT_INFO("Serial number conversion failed, aborting\n");
hid_exit();
return false; return false;
} }
serial[size] = 0; serial[size] = 0;
/* Blacklist devices that do not work with 513 byte report length /* Blacklist devices that do not work with 513 byte report length
* FIXME: Find a solution to decipher from the device. * FIXME: Find a solution to decipher from the device.
*/ */
if ((info->vid == 0x1fc9) && (info->pid == 0x0132)) { if (info->vid == 0x1fc9 && info->pid == 0x0132) {
DEBUG_WARN("Blacklist\n"); DEBUG_WARN("Blacklist\n");
report_size = 64 + 1; report_size = 64 + 1;
} }
handle = hid_open(info->vid, info->pid, (serial[0]) ? serial : NULL); handle = hid_open(info->vid, info->pid, serial[0] ? serial : NULL);
if (!handle) { if (!handle) {
PRINT_INFO("hid_open failed: %ls\n", hid_error(NULL)); PRINT_INFO("hid_open failed: %ls\n", hid_error(NULL));
#ifdef __linux__
dap_hid_print_permissions(info->vid, info->pid, serial[0] ? serial : NULL);
#endif
hid_exit();
return false; return false;
} }
return true; return true;