-
Notifications
You must be signed in to change notification settings - Fork 474
I have a small program written in Rust that uses libusb's hotplug API to detect when a device with a specific VID/PID is connected. Once this is detected, I wake up a waiting thread via a channel where I again enumerate the devices via hidapi, find it, open it and try to read data.
The problem is that when I try to open the device, I get a permission denied error. If I add a 2 second delay before I try to open the device then everything works, if I run my program as sudo then it also works.
If I the device is already plugged in when my program starts then I get no error either.
Below are my udev rules.
$ cat /etc/udev/rules.d/69-chatmix.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1038", ATTRS{idProduct}=="2202", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="1038", ATTRS{idProduct}=="2202", TAG+="uaccess"
The device itself is a wireless transmitter for a SteelSeries Arctis Nova 7 gaming headset and my program implements the ChatMix functionality.
The fact that adding a delay fixes my problem makes me think that there is some sort of timing issue going on and somehow my program tries to open the USB device before all the rules are applied, but at the same time, I also found libusb/libusb#718 which directly contradicts this.
Here are the system logs when the device is plugged in:
feb 08 19:20:02 workstation kernel: usb 3-1: new full-speed USB device number 57 using xhci_hcd
feb 08 19:20:02 workstation kernel: usb 3-1: New USB device found, idVendor=1038, idProduct=2202, bcdDevice= 1.11
feb 08 19:20:02 workstation kernel: usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
feb 08 19:20:02 workstation kernel: usb 3-1: Product: Arctis Nova 7
feb 08 19:20:02 workstation kernel: usb 3-1: Manufacturer: SteelSeries
feb 08 19:20:02 workstation kernel: hid-generic 0003:1038:2202.0139: hiddev96,hidraw0: USB HID v1.11 Device [SteelSeries Arctis Nova 7] on usb-.&checktime(0000,08,00,':').3-1/input3
feb 08 19:20:02 workstation kernel: input: SteelSeries Arctis Nova 7 as /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-1/3-1:1.4/0003:1038:2202.013A/input/input332
feb 08 19:20:02 workstation kernel: hid-generic 0003:1038:2202.013A: input,hidraw1: USB HID v1.11 Device [SteelSeries Arctis Nova 7] on usb-.&checktime(0000,08,00,':').3-1/input4
feb 08 19:20:02 workstation kernel: hid-generic 0003:1038:2202.013B: hiddev97,hidraw2: USB HID v1.11 Device [SteelSeries Arctis Nova 7] on usb-.&checktime(0000,08,00,':').3-1/input5
feb 08 19:20:02 workstation mtp-probe[2108325]: checking bus 3, device 57: "/sys/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-1"
feb 08 19:20:02 workstation mtp-probe[2108325]: bus: 3, device: 57 was not an MTP device
feb 08 19:20:02 workstation mtp-probe[2108348]: checking bus 3, device 57: "/sys/devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:08:00.3/usb3/3-1"
feb 08 19:20:02 workstation mtp-probe[2108348]: bus: 3, device: 57 was not an MTP device
I have restarted my computer. Nothing looks wrong I am at a bit of a loss on where to continue the investigation.
P.S.:
The hotplug support was an afterthought after it became too much trouble to have my program invoked by systemd when the USB device was connected. Ideally I would not have a half and half solution, but I already had my code written for talking to the device via hidapi and I thought I can use libusb's hotplug support until hidapi gets it's own.
It is not feasible to run my program as root because it needs to talk to services that are started via systemctl --user.
All reactions
Replies: 1 comment 1 reply
The fact that adding a delay fixes my problem makes me think that there is some sort of timing issue going on and somehow my program tries to open the USB device before all the rules are applied, but at the same time, I also found libusb/libusb#718 which directly contradicts this.
I think your assumption is correct. After all, libusb is listening udev for usb device appear.
But HIDRAW backend doesn't use libusb. It uses hidraw subsystem of the kernel, which gets initialized (and its udev rules) some moments after USB subsystem initializes.
To make this work properly (and w/o delay+retry, which is also an option/workaround) - you'd have to make your own implementation of a hotplug detection using udev but listen for hidraw subsystem devices.
All reactions
Thanks for the suggestion. I will give this a try.