Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call to open() fails on Mint Linux #106

Closed
wholder opened this issue Oct 16, 2020 · 6 comments
Closed

Call to open() fails on Mint Linux #106

wholder opened this issue Oct 16, 2020 · 6 comments
Assignees
Labels

Comments

@wholder
Copy link

wholder commented Oct 16, 2020

I have a Java program using Hid4Java that runs successfully on macOs and Windows 10, but fails on Mint Linux 19 when it tries to open() the device. Here is printout from test code when run on these three operating systems:

macOs 10.14.6
 VID  PID - Description                    - Manf                 - Serial Num      - Can open
03EB:2141 - Atmel-ICE CMSIS-DAP            - Atmel Corp.          - J41800089996    - yes

Microsoft Windows [Version 10.0.19041.508]
03EB:2141 - Atmel-ICE CMSIS-DAP            - Atmel Corp.          - J41800089996    - yes

Mint Linux, version="19 (Tara)", 4.15.0-118-generic
03EB:2141 - Atmel-ICE CMSIS-DAP            - Atmel Corp.          - J41800089996    - no

The troubleshooting section does not seem to cover Mint Linux, but I tried the advice given for Ubuntu and created a rules file in /etc/udev/rules.d/ that contains:

KERNEL=="hidraw*", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2141", MODE="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl"

Then, used the following commands to verify the "plugdev" group:

$ groups
parallels adm cdrom sudo dip plugdev lpadmin sambashare

$ whoami
parallels

$ groups parallels
parallels : parallels adm cdrom sudo dip plugdev lpadmin sambashare

What am I missing?

Wayne

p.s. these test code I used is, as follows:

import org.hid4java.*;

public class ListHIDDevices {

  public static void main(String[] args) throws HidException {
    HidServicesSpecification hidServicesSpecification = new HidServicesSpecification();
    hidServicesSpecification.setAutoShutdown(true);
    hidServicesSpecification.setScanInterval(500);
    hidServicesSpecification.setPauseInterval(5000);
    hidServicesSpecification.setScanMode(ScanMode.SCAN_AT_FIXED_INTERVAL_WITH_PAUSE_AFTER_WRITE);
    HidServices hidServices = HidManager.getHidServices(hidServicesSpecification);
    hidServices.start();
    System.out.printf(" %-3s  %-3s - %-30s - %-20s - %-15s - %-10s\n", "VID", "PID", "Description", "Manf", "Serial Num", "Can open");
    for (HidDevice hidDevice : hidServices.getAttachedHidDevices()) {
      String manf = hidDevice.getManufacturer().trim();
      String prod = hidDevice.getProduct();
      int vendor = hidDevice.getVendorId();
      int product = hidDevice.getProductId();
      String serialNum = hidDevice.getSerialNumber();
      serialNum = serialNum != null ? serialNum : "";
      System.out.printf("%04X:%04X - %-30s - %-20s - %-15s", vendor, product, prod, manf, serialNum);
      if (hidDevice.isOpen()) {
        System.out.print(" - open");
      } else if (hidDevice.open() && hidDevice.isOpen()) {
        hidDevice.setNonBlocking(true);
        System.out.print(" - yes");
        hidDevice.close();
      } else {
        System.out.print(" - no");
      }
      System.out.println();
    }
    hidServices.shutdown();
  }
}
@wholder
Copy link
Author

wholder commented Oct 16, 2020

BTW, running as root works:

parallels@parallels-Parallels-Virtual-Platform:~/Documents$ sudo java -jar Hid4JavaTest.jar
 VID  PID - Description                    - Manf                 - Serial Num      - Can open  
03EB:2141 - Atmel-ICE CMSIS-DAP            - Atmel Corp.          - J41800089996    - yes

Wayne

@gary-rowe
Copy link
Owner

Hi @wholder,

I did some brief digging around and it could be a permissions issue with /dev/hidraw*. You could experiment with chmod 666 /dev/hidrawX (assuming lsusb indicates /dev/hidrawX as where your device is showing up on your system). If it bursts into life then a bit more narrowing of permissions would be needed.

Let me know how you get on.

@gary-rowe gary-rowe self-assigned this Oct 18, 2020
@wholder
Copy link
Author

wholder commented Oct 21, 2020

You could experiment with chmod 666 /dev/hidrawX (assuming lsusb indicates /dev/hidrawX as where your device
is showing up on your system).

First, thinks for trying to help. I'm not sure what you mean by "assuming lsusb indicates /dev/hidrawX as where your device is showing up". When I run lsusb -v, a stream of text but, nothing in the text includes the string "hidraw", or anything similar. However, I'm not that skilled with linux and know even less about these "rules" files and how they work. I also tried running lsusb -t and got the printout included below. The Atmel-ICE show up as being Device 006 on Bus 001, so I'm guessing the relevant item in the tree is:

|__ Port 6: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 480M

Does this help narrow things down?

Wayne

$ lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 1: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/15p, 480M
    |__ Port 1: Dev 2, If 0, Class=Printer, Driver=usblp, 480M
    |__ Port 2: Dev 3, If 0, Class=Printer, Driver=usblp, 480M
    |__ Port 3: Dev 5, If 0, Class=Printer, Driver=usblp, 480M
    |__ Port 5: Dev 4, If 0, Class=Printer, Driver=usblp, 480M
    |__ Port 6: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 480M
    |__ Port 6: Dev 6, If 1, Class=Vendor Specific Class, Driver=, 480M

@gary-rowe
Copy link
Owner

gary-rowe commented Oct 21, 2020

Yes, I have accidentally misled you with the mapping between the lsusb output and /dev/hidraw. It is more complex than I thought (Linux is not my primary dev platform) so I've written up a more detailed explanation in the wiki. You may find the information there (and the links) helpful.

I still think it's a permissions problem, possibly in /dev/hidrawX or /etc/udev/rules.d/<your rules file>.

@wholder
Copy link
Author

wholder commented Oct 23, 2020

Ok, after a few hours of trial and error and reading through more web posts than I can remember, I stumbled upon the fix. It's as simple as adding a single ':' (colon) character so that MODE="0666" becomes MODE:="0666". Apparently, versions of Linux based on Ubuntu, as I think is the case for Mint, require the colon to indicate an assignment. To simplify making the change, I used this command line:

echo 'KERNEL=="hidraw*", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="*", MODE:="0666", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl"' | sudo tee /etc/udev/rules.d/100-atmel.rules

where this is entered as a single line followed by pressing enter. Then, to be sure, I recommend a restart for the new rule to take effect.

Wayne

@gary-rowe
Copy link
Owner

Thanks for coming back with an answer. It's interesting that the solution involves := which is essentially the final keyword in the udev rules. It could be that there are other files in your system that are overriding the values in your .rules file.

I would counsel against using a wildcard in the idProduct field since a given vendor is unlikely to make a vast number of variants of a device - you may find explicitly declaring the product IDs to be a more secure approach.

Anyway, I'll close this issue now and I've updated the wiki to reflect your findings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants