Accessing a USB device with libusb-1.0 as a non-root user

13,251

Solution 1

The udev rules I use to be able to access devices with libusb look like this: SUBSYSTEMS=="usb", ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="ffc3", SYMLINK+="sub20", GROUP="usb", MODE="660". It's supposed to just add a symlink to the device, but the permissions are also working for me afterwards (I am a member of the group usb).

Solution 2

For usb devices FTDI I use the script:

ftdi_config.sh

#!/bin/sh

echo "This script is for modern debian systems, and does everything that should"
echo "be necessary to use ftdi usb devices as a regular user with libftdi,"
echo "instead of the built-in dumb kernel driver."
echo
if [ $(id -u) != 0 ]; then
  echo "This script must be run as root."
  exit 1
else
  read -p "Press enter to continue, or ctrl-c to bail..." x
fi
echo
echo "** Adding usb group"
groupadd usb
echo
echo "** Setting udev permissions on usb devices"
echo 'SUBSYSTEMS=="usb", ACTION=="add", MODE="0664", GROUP="usb"' >> /etc/udev/rules.d/99-usbftdi.rules
echo
echo "** Reloading udev rules"
/etc/init.d/udev reload
echo
echo "** Blacklisting ftdi_sio driver"
echo 'blacklist ftdi_sio' > /etc/modprobe.d/ftdi.conf
echo
echo "** Removing old ftdi_sio driver (it's ok if it fails)"
rmmod ftdi_sio
echo
echo "!! Run the following command as root, to add your user to the usb group:"
echo "useradd -G usb yourusernamehere"
echo
echo "or"
echo
echo "Adding to a existing user:"
echo "usermod -a -G usb yourusernamehere"
echo
echo "as then you must reboot the system:"
echo "reboot" 

then run your app as a non-root user. It works!!!

Share:
13,251
Admin
Author by

Admin

Updated on June 27, 2022

Comments

  • Admin
    Admin almost 2 years

    I am trying to interface with a USB device as a non-root user on RHEL5. The device is a GPIO interface (its documentation can be found at http://www.xdimax.com/sub20/sub20.html) which uses libusb-1.0. The procedure for opening the device, using its API, is:

    sub_device d;
    d = sub_find_devices(0);
    sub_handle h = sub_open(d);
    

    When I do this, the sub_find_devices() call works, but on the sub_open() call, I get the libusb error -3, which indicates that I do not have permissions to open the device for writing.

    I did some research on this problem, and found that I should create a udev rule. Using udevinfo on the device's sysfs node, I got:

    looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2':
    KERNEL=="2-1.2"
    SUBSYSTEM=="usb"
    SYSFS{configuration}==""
    SYSFS{serial}=="15F2"
    SYSFS{product}=="SUB-20"
    SYSFS{manufacturer}=="XDIMAX"
    SYSFS{maxchild}=="0"
    SYSFS{version}==" 1.10"
    SYSFS{devnum}=="6"
    SYSFS{speed}=="12"
    SYSFS{bMaxPacketSize0}=="64"
    SYSFS{bNumConfigurations}=="1"
    SYSFS{bDeviceProtocol}=="00"
    SYSFS{bDeviceSubClass}=="00"
    SYSFS{bDeviceClass}=="ff"
    SYSFS{bcdDevice}=="0001"
    SYSFS{idProduct}=="ffc3"
    SYSFS{idVendor}=="04d8"
    SYSFS{bMaxPower}=="100mA"
    SYSFS{bmAttributes}=="80"
    SYSFS{bConfigurationValue}=="1"
    SYSFS{bNumInterfaces}==" 1"
    

    I then created the following udev rule, in the file /etc/udev/rules.d/991-local.rules:

    SYSFS{idVendor}=="04d8", SYSFS{idProduct}=="ffc3", NAME="sub20", GROUP="582", MODE="0660"
    

    582 is the GID of a group that my normal user belongs to. I also tried the rule with the group name and it did not work. After creating this rule, the device file /dev/sub20 is created with the correct permissions, but only exists when the device is plugged in, which gives me reasonable confidence that the udev rule is matching on the correct device. However, my code still gets error -3.

    Doing an strace on the code revealed this call:

    open("/dev/bus/usb/002/006", O_RDWR)    = -1 EACCES (Permission denied)
    

    The permissions on the /dev/bus/usb... node are still root:root, so maybe this is an indication that there is a problem with my udev rule, although I don't know what that could be.

    If I try doing a call to open("/dev/sub20", O_RDWR), I get the return value ENXIO (No such device or address), another possible indicator of an error in the udev rule, although the /dev/sub20 file clearly is associated with the correct device somehow, since it only exists when the device is plugged in.

    What else can I do to try and get this to work?