usb4java-javax icon indicating copy to clipboard operation
usb4java-javax copied to clipboard

get device path / port number

Open siochs opened this issue 8 years ago • 4 comments

Hi, using following code:

        UsbPort port = usbDevice.getParentUsbPort();
        System.out.println("Connected to port: " + port.getPortNumber());
        System.out.println("Parent: " + port.getUsbHub()); 

I can dump some basic info about the device connection. However, I need to know the physical location of the device. I can see it in dmesg:

[ 1415.390194] usb 1-1.2: Manufacturer: SanDisk

Attaching the device to another port prints

[ 1415.390194] usb 1-1.4: Manufacturer: SanDisk

So how do I retrieve the physical address 1-1.4 using usb4java-javax? The code above always prints the same port information, even when switching the ports. See also this thread on StackOverflow.

siochs avatar Dec 15 '17 10:12 siochs

Additional info: I looked a bit into Usb4Java and was able to retrieve the physical path with the following code:

                        ByteBuffer path = BufferUtils.allocateByteBuffer(8);
                        result = LibUsb.getPortNumbers(device, path);
                        if (result > 0)
                        {
                            for (int i = 0; i < result; i++)
                            {                                
                                System.out.print(path.get(i));
                                if (i + 1 < result) System.out.print("-");
                            }
                            System.out.println("");
                        }                        

So when attaching a thumb drive between two different usb jacks it prints me for example 1-2 or 1-4. It took a look into getPortNumbers(device, path); which dervies from libusb_get_port_numbers from LibUsb core.c. Basically, libusb_get_port_numbers does nothing elese then descending the device tree and places the according port number in a byte array:

...
		port_numbers[i] = dev->port_number;
		dev = dev->parent_dev;
...

Then, I tried to mimick that behaviour with Usb4Java-Javax:

        UsbPort port = usbDevice.getParentUsbPort();
        while (port != null)
        {
            System.out.print(port.getPortNumber());
            port = port.getUsbHub().getParentUsbPort();
            if (port != null) System.out.print("-");
        }

However, this does not work as expected since this allways gives me 1-2, independet of the port I attach the thumb drive to. Is this a bug or do I oversee something?

siochs avatar Dec 15 '17 14:12 siochs

perhaps it is easier to hack around package/protected name space and cast UsbDevice -> AbstractDevice to get access to bus/addr/port triple from DeviceId

see:

Andrei-Pozolotin avatar Jun 05 '18 17:06 Andrei-Pozolotin

Yeah, this is what I ended up with. I added an Usb4JavaJavaxLibraryWrapper as part of the package org.usb4java.javax and wrote some casting functions like

public int getBusNumberFromUsbDevice(UsbDevice usbDevice)
    {
        DeviceId deviceId = ((AbstractDevice) usbDevice).getId();
        return deviceId.getBusNumber();        
    }

siochs avatar Oct 02 '18 13:10 siochs

Changing the visibility of classes or methods is not an option here because this would break the compatibility to the javax.usb spec. But I guess this could be fixed properly by using the port numbers reported by libusb instead of creating virtual port numbers. I'm open for pull requests here because of lack of time and fading javax-usb knowledge.

kayahr avatar Oct 21 '18 20:10 kayahr