robert
robert

Reputation: 21

Usb4java alternate setting

I have a device, with which I have to communicate with, through USB.

It has 1 active configuration, that has 1 interface.

The interface has more alternate settings (IDLE, PROF1, PROF2). By default IDLE is active.

My question is, that how can I make the PROF2 setting active?

bNumConfigurations:   0x01
bNumInterfaces:       0x01

[IDLE]
bInterfaceNumber:     0x00
bAlternateSetting:    0x00

[PROF1]
bInterfaceNumber:     0x00
bAlternateSetting:    0x01

[PROF2]
bInterfaceNumber:     0x00
bAlternateSetting:    0x02

Code...

UsbConfiguration config = (UsbConfiguration) device.getActiveUsbConfiguration();    
UsbInterface iface = config.getUsbInterface((byte)0x00);    
UsbInterface alt = iface.getSetting((byte)0x02);                // <= Setting is not active.
UsbEndpoint endpoint = alt.getUsbEndpoint((byte)0x83);    
UsbPipe pipe = endpoint.getUsbPipe();    
pipe.open();                                                    // <= Pipe is not active.

Upvotes: 2

Views: 973

Answers (1)

tresf
tresf

Reputation: 7922

I believe the problem here is that the high-level API simply doesn't provide a way to set either the active configuration or the alternate setting to something other than default.

The low level API does though... here's what I used::

// Iterate over the devices using low-level API to match a device + config combo from a high-level API
DeviceList list = new DeviceList();
LibUsb.getDeviceList(null, list);
for (Device d : list) {
    DeviceDescriptor descriptor = new DeviceDescriptor();
    LibUsb.getDeviceDescriptor(d, descriptor);
    if (descriptor.idVendor() == device.getUsbDeviceDescriptor().idVendor() &&
            descriptor.idProduct() == device.getUsbDeviceDescriptor().idProduct()) {
        Context context = new Context();
        LibUsb.init(context);
        DeviceHandle handle = new DeviceHandle();
        LibUsb.open(d, handle);
        LibUsb.setConfiguration(handle, 0x02); // or cfg.getUsbConfigurationDescriptor().bConfigurationValue()
        LibUsb.setInterfaceAltSetting(handle, 0x00, 0x02);
        LibUsb.claimInterface(handle, ifc);    // valid test, can't claim unless active
        LibUsb.releaseInterface(handle, ifc);
        LibUsb.close(handle);
        LibUsb.exit(context);
        return; // break, etc
    }
}
LibUsb.freeDeviceList(list, true); // usually in a finally block

When placed in a helper function, this logic should be valid for setting the active configuration.

According to the libusb devs, the configuration will remain active so as long as the device isn't unplugged. This is per https://github.com/libusb/libusb/issues/158#issuecomment-190501281.

Finally, if you're not doing it already, I recommend setting DEBUG via command line LIBUSB_DEBUG=4 to get the raw output from libusb. This helped considerably in my troubleshooting efforts. In this case you should see something along the lines of:

[21.987087] [0000d903] libusb: debug [libusb_set_configuration] configuration 2

Upvotes: 2

Related Questions