Search code examples
javausbcommunicationlibusb

Error sending data via USB in Java using LibUsb (Entity not found)


I tried to send data over USB by using LibUsb4Java, but I am getting an error in the bulkTransfer. I can't find the error and am requesting your help.

The first method returns the target device. It is a frdm-board.

The error "USB error 5: Control transfer failed: Entity not found" occurs when trying to send data in the bulkTransfer method.

What could be the problem?

I'm developing on OS X v10.10 (Yosemite):

// Create the libusb context
Context context = new Context();

// Initialize the libusb context
int result = LibUsb.init(context);
if (result < 0)
{
    throw new LibUsbException("Unable to initialize libusb", result);
}

// Read the USB device list
DeviceList list = new DeviceList();
result = LibUsb.getDeviceList(context, list);
if (result < 0)
{
    throw new LibUsbException("Unable to get device list", result);
}

try
{
    // Iterate over all devices and list them
    for (Device device: list)
    {
        DeviceDescriptor descriptor = new DeviceDescriptor();
        result = LibUsb.getDeviceDescriptor(device, descriptor);
        if (result < 0)
        {
            throw new LibUsbException(
                "Unable to read device descriptor", result);
        }
        if(descriptor.idVendor() == 0x1357 && descriptor.idProduct() == 0x0089)
        {
           frdmBoard = device;
        }
    }
   DeviceHandle handle = new DeviceHandle();
   int resultOpen = LibUsb.open(frdmBoard, handle);
   if (resultOpen != LibUsb.SUCCESS)
      throw new LibUsbException("Unable to open USB device", resultOpen);
   try
   {
       ByteBuffer buffer = ByteBuffer.allocateDirect(8);
       buffer.put(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
       IntBuffer transfered = IntBuffer.allocate(1);
       byte endpoint = (byte)LibUsb.getDeviceAddress(frdmBoard);
       int intResult = LibUsb.bulkTransfer(handle, endpoint, buffer, transfered, 1L);
       try{
          if (intResult != LibUsb.SUCCESS)
             throw new LibUsbException("Control transfer failed", intResult);
       }
       catch(Exception e)
       {
          e.printStackTrace();
       }
   }
   finally
   {
      LibUsb.close(handle);
   }
}
finally
{
   LibUsb.freeDeviceList(list, true);
}

Solution

  • Following the quickstart guide http://usb4java.org/quickstart/libusb.html I think you've missed to claim the interface. In section "Synchronous I/O" the guide says

    This examples sends 8 bytes to a claimed interface using a control transfer:

    Claiming the device should solve your problem:

    result = LibUsb.claimInterface(handle, interfaceNumber);
    if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to claim interface", result);
    

    Remember to detach the device, if it has already been registered by an kernel driver. This adapted solution from the quickstart guide worked for me on Ubuntu 14.04:

     boolean detach = (LibUsb.kernelDriverActive(handle, 0) == 1);
     if (detach) {
         result = LibUsb.detachKernelDriver(handle,  interfaceNumber);
         if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to detach kernel driver", result);
     }