Java 读取传输时LibUsb获取错误超时-7

Java 读取传输时LibUsb获取错误超时-7,java,raspberry-pi,usb,libusb,usb4java,Java,Raspberry Pi,Usb,Libusb,Usb4java,我一直在使用usb4java库,了解了很多USB设备是如何通信的 我在web应用程序中使用usb4java低级API(libusb1.0)库来读取Raspberry Pi中的条形码扫描仪输入。Raspberry Pi通过发行版更新为最新的软件包 我从以下资源中获得了如何在Java中实现此过程的以下示例: 问题: 我可以成功地做到: 列出所有设备 根据供应商ID和产品ID选择我的设备 开放式设备 分离内核驱动程序 认领设备 当需要读取扫描仪发送的设备数据时,我总是会收到一个超时错误(-7)

我一直在使用usb4java库,了解了很多USB设备是如何通信的

我在web应用程序中使用usb4java低级API(libusb1.0)库来读取Raspberry Pi中的条形码扫描仪输入。Raspberry Pi通过发行版更新为最新的软件包

我从以下资源中获得了如何在Java中实现此过程的以下示例:

问题:

我可以成功地做到:

  • 列出所有设备
  • 根据供应商ID和产品ID选择我的设备
  • 开放式设备
  • 分离内核驱动程序
  • 认领设备
当需要读取扫描仪发送的设备数据时,我总是会收到一个超时错误(-7)

下面的示例,调用该方法10次以获得响应,超时时间为5秒

for(int i=10; i >= 0; --i)
{
    writeOutput(read(DeviceHandle, this.bufferSize, this.timeout, this.transfer));
}
Main类:缺少定义的变量,仅用于说明过程

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

// Initialize the libusb context
int result = LibUsb.init(context);
if ((result != LibUsb.SUCCESS) || (result < 0))
{
    writeOutput("Unable to initialize libusb " + result);
}
else
{
    // Try to open the device.
    DeviceHandle DeviceHandle = new DeviceHandle();

    // Get device
    Device device = findDevice((short) 0x0c2e, (short) 0x0200);

    if (device == null)
    {
        writeConsole("Unable to find device");
    }
    else
    {
        writeConsole("Device found");
    }

    // Open I/O with the device handle
    result = LibUsb.open(device, DeviceHandle);

    if (result < 0)
    {
        writeOutput("Unable to open device");
        DeviceHandle = null;
    }
    else
    {
        writeOutput("Opening device");
        try
        {
            boolean detach = LibUsb.hasCapability(LibUsb.CAP_SUPPORTS_DETACH_KERNEL_DRIVER);
            int detachActive = LibUsb.kernelDriverActive(DeviceHandle, this.interFace);

            // Detach the kernel driver
            if ((detach) || (detachActive == 1))
            {
                result = LibUsb.detachKernelDriver(DeviceHandle, this.interFace);
                if (result != LibUsb.SUCCESS)
                {
                    writeOutput("Cannot detach kernel from this interface (" + this.interFace + ") error " + result);

                }
                else
                {
                    writeOutput("Detaching kernel driver (" + this.interFace + ")");
                }
            }

            //set configuration
            result = LibUsb.setConfiguration(DeviceHandle, this.configuration);
            if (result != LibUsb.SUCCESS)
            {
                writeOutput("Cannot set device configuration (" + this.configuration + ") error " + result);

            }
            else
            {
                writeOutput("Setting device configuration (" + this.configuration + ")");

                // Claim the device
                result = LibUsb.claimInterface(DeviceHandle, this.interFace);

                if (result != LibUsb.SUCCESS)
                {
                    writeOutput("Cannot open device interface (" + this.interFace + ") error " + result);
                }
                else
                {
                    try
                    {
                        writeOutput("Claiming device on interface (" + this.interFace + ")");

                        switch(this.transfer)
                        {
                            case 0:
                                writeOutput("Set to Interrupt Transfer type");
                                break;
                            case 1:
                                writeOutput("Set to Bulk Transfer type");
                                break;
                        }

                        for (int i=10; i >= 0; --i)
                        {
                            writeOutput(read(DeviceHandle, this.bufferSize, this.timeout, this.transfer));
                        }
                    }
                    finally
                    {
                        result = LibUsb.releaseInterface(DeviceHandle, this.interFace);
                        if (result != LibUsb.SUCCESS)
                        {
                            writeOutput("Failure releasing device interface (" + this.interFace + ") error " + result);
                        }
                        else
                        {
                            writeOutput("Releasing device interface (" + this.interFace + ")");
                        }

                        if ((detach) || (detachActive == 1))
                        {
                            result = LibUsb.attachKernelDriver(DeviceHandle, this.interFace);
                            if (result != LibUsb.SUCCESS)
                            {
                                writeOutput("Cannot attach kernel driver back to the device (" + this.interFace + ") error " + result);

                            }
                            else
                            {
                                writeOutput("Re attaching kernel driver back (" + this.interFace + ")");
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            LibUsb.close(DeviceHandle);
            writeOutput("Closing... ");
        }
    }
    LibUsb.exit(context);
    writeOutput("Exiting... ");
}
这是USB设备的描述符

Device Descriptor:
  bLength                 18
  bDescriptorType          1
  bcdUSB                1.10
  bDeviceClass             0 Per Interface
  bDeviceSubClass          0
  bDeviceProtocol          0
  bMaxPacketSize0          8
  idVendor            0x0c2e
  idProduct           0x0200
  bcdDevice            53.32
  iManufacturer            1 Metrologic
  iProduct                 2 Metrologic Scanner
  iSerial                  0
  bNumConfigurations       1
  Configuration Descriptor:
    bLength                  9
    bDescriptorType          2
    wTotalLength            34
    bNumInterfaces           1
    bConfigurationValue      1
    iConfiguration           3
    bmAttributes          0x80
      (Bus Powered)
    bMaxPower              300mA
    extralen                 0
    extra:

  Interface:
    numAltsetting          1
  Interface Descriptor:
    bLength                  9
    bDescriptorType          4
    bInterfaceNumber         0
    bAlternateSetting        0
    bNumEndpoints            1
    bInterfaceClass          3 HID
    bInterfaceSubClass       1
    bInterfaceProtocol       1
    iInterface               0
    extralen                 9
    extra:
      09 21 11 01 00 01 22 3f 00
  Endpoint Descriptor:
    bLength                  7
    bDescriptorType          5
    bEndpointAddress      0x81  EP 1 IN
    bmAttributes             3
      Transfer Type             Interrupt
      Synch Type                None
      Usage Type                Data
    wMaxPacketSize           8
    bInterval               10
    extralen                 0
    extra:
--- Device END ---
我使用的接口为0,端点为0x81,供应商ID为0x0c2e,产品ID为0x0200。此外,我还将LibUsb.bulkTransfer()更改为LibUsb.interruptTransfer(),因为该设备只接受中断传输。缓冲区设置为8字节,如wMaxPacketSize所示

我已尝试并取消了以下测试:

  • 将缓冲区传输大小从1字节更改为64字节
  • 已使用LibUsb.bulkTransfer()
  • 将超时时间从100毫秒更改为20000毫秒
  • 添加了LibUsb.clearhalt()

我如何克服这个问题?我错过了什么吗?

首先,我可以告诉你,你必须坚持中断传输和8字节缓冲区,HID总是这样工作的。有时,您必须找到端点的正确间隔。您是否尝试过声明接口1-5?此外:如果您直接与HID设备通信,则无法获得实际字符,但必须先对HID数据进行解释,然后才能从中读取字符串。我知道接口仅存在于可以“查看”的LibUsb中。在上面的列表中,只有一个设备存在,对吗?关于HID数据,您指的是我分配给的缓冲区中的字节。如果你能在red()方法中看到,有一个循环用于处理缓冲区。因为我有一个计量学,所以我自己尝试了一下,它(在Windows上)起了作用。唯一的区别可能是:您是否设置了任何配置?对于缓冲区来说,这正是问题所在:设备接收到的一个字节不是字符。在本例中,所有8个字节仅为一次按键,因此最多为一个字符;)那么
wMaxPacketSize
是错误的吗?它说整个传输是8字节还是一个字符?你能和我分享一下你的设置吗?也许我设置了一些错误的东西,比如端点、接口、缓冲区大小、超时等等?在中断传输之前,我需要分配多少字节?我还没有看到任何配置设置到任何示例中,所以我自己也没有添加配置。我会尝试一下,让你知道。首先,我可以告诉你,你必须坚持中断传输和8字节缓冲区,HID总是这样工作的。有时,您必须找到端点的正确间隔。您是否尝试过声明接口1-5?此外:如果您直接与HID设备通信,则无法获得实际字符,但必须先对HID数据进行解释,然后才能从中读取字符串。我知道接口仅存在于可以“查看”的LibUsb中。在上面的列表中,只有一个设备存在,对吗?关于HID数据,您指的是我分配给的缓冲区中的字节。如果你能在red()方法中看到,有一个循环用于处理缓冲区。因为我有一个计量学,所以我自己尝试了一下,它(在Windows上)起了作用。唯一的区别可能是:您是否设置了任何配置?对于缓冲区来说,这正是问题所在:设备接收到的一个字节不是字符。在本例中,所有8个字节仅为一次按键,因此最多为一个字符;)那么
wMaxPacketSize
是错误的吗?它说整个传输是8字节还是一个字符?你能和我分享一下你的设置吗?也许我设置了一些错误的东西,比如端点、接口、缓冲区大小、超时等等?在中断传输之前,我需要分配多少字节?我还没有看到任何配置设置到任何示例中,所以我自己也没有添加配置。我会试试,让你知道。
// Read data from device after claiming it
  public static String read(DeviceHandle handle, int size, long timeout, int readType) {

      byte endpointId = (byte) 0x81;
      StringBuilder stringBuilder = new StringBuilder();
      boolean started = false;

      while(true)
      {
          ByteBuffer buffer = BufferUtils.allocateByteBuffer(size).order(ByteOrder.LITTLE_ENDIAN);
          IntBuffer transferred = BufferUtils.allocateIntBuffer();

          int result;

          switch(readType)
          {
              case 0:
                  result = LibUsb.interruptTransfer(handle, endpointId, buffer, transferred, timeout);
                  break;

              case 1:
                  result = LibUsb.bulkTransfer(handle, endpointId, buffer, transferred, timeout);
                  break;

              default:
                  result = LibUsb.interruptTransfer(handle, endpointId, buffer, transferred, timeout);
                  break;
          }

          if (result != LibUsb.SUCCESS)
          {
              return "Failure reading data with"
                          + " buffer size:"
                          + size + " bytes timeout:"
                          + timeout + " ms error code:"
                          + result;
          }
          else
          {
              CharBuffer charBuffer = buffer.asCharBuffer();
              while(charBuffer.hasRemaining())
              {
                  char nextChar = charBuffer.get();
                  if (nextChar == '\n')
                      started = true; //Start Character
                  else if(nextChar == '\r' && started)
                      return stringBuilder.toString(); //End Character
                  else if(started)
                      stringBuilder.append(nextChar);
              }
          }
      }
  }
Device Descriptor:
  bLength                 18
  bDescriptorType          1
  bcdUSB                1.10
  bDeviceClass             0 Per Interface
  bDeviceSubClass          0
  bDeviceProtocol          0
  bMaxPacketSize0          8
  idVendor            0x0c2e
  idProduct           0x0200
  bcdDevice            53.32
  iManufacturer            1 Metrologic
  iProduct                 2 Metrologic Scanner
  iSerial                  0
  bNumConfigurations       1
  Configuration Descriptor:
    bLength                  9
    bDescriptorType          2
    wTotalLength            34
    bNumInterfaces           1
    bConfigurationValue      1
    iConfiguration           3
    bmAttributes          0x80
      (Bus Powered)
    bMaxPower              300mA
    extralen                 0
    extra:

  Interface:
    numAltsetting          1
  Interface Descriptor:
    bLength                  9
    bDescriptorType          4
    bInterfaceNumber         0
    bAlternateSetting        0
    bNumEndpoints            1
    bInterfaceClass          3 HID
    bInterfaceSubClass       1
    bInterfaceProtocol       1
    iInterface               0
    extralen                 9
    extra:
      09 21 11 01 00 01 22 3f 00
  Endpoint Descriptor:
    bLength                  7
    bDescriptorType          5
    bEndpointAddress      0x81  EP 1 IN
    bmAttributes             3
      Transfer Type             Interrupt
      Synch Type                None
      Usage Type                Data
    wMaxPacketSize           8
    bInterval               10
    extralen                 0
    extra:
--- Device END ---