java - usb4java:无法进行数据传输

标签 java windows usb usb4java

我正在尝试使用 usb4java(低级 API)与 USB 连接的科学仪器进行通信,该仪器在 Windows 上设置为 HID 设备(x86 和 x86_64)。有一个非常古老的 C++ 应用程序可以正常工作,但出于各种原因,我正在尝试用纯 Java 替换它。

我可以获得设备描述符并确定接口(interface)/端点,但异步传输永远不会发生(由 Device Monitoring Studio 检查)并且永远不会调用回调。 usb4java 没有抛出任何异常,并且不知道我是否可以访问 libusb 级别的任何日志(如果可能的话)。在处理硬件方面,我是一个完全的新手,所以它很可能是我所缺少的一些非常基本的东西。

只有一个端点,我不确定 C++ 代码如何管理双向通信。代码中没有明确提及传输类型,因为所有细节都隐藏在第三方库中。

我安装了 libusbK 驱动程序并尝试了高级实现 (javax-usb)。转账仍未通过。

下面是端点描述符转储的输出,以及代码的缩写版本。

    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              100
  extralen                 0
  extra:

代码如下:

import java.nio.*;
import java.util.*;
import org.usb4java.*;


/**
 * This class is intended to test USB communication using usb4java
 *
 */
public class Test {

    private static final String vendorId = "VVV";
    private static final String productId = "PPP";

    private Context context;
    private Device device;
    private Handle handle;

    static volatile boolean exit = false;
    Object synchObj = new Object();
    boolean readCompleted = false;

    private static final int BUFFER_SIZE = 8;

    private final byte[] idQuery = new byte[]{ 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

    public Test(){

        initialize();

        if (device == null){
            System.out.println("No target devices found");
            System.exit(0);
        }

        boolean loop = true;

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

        //this code doesn't get executed because the transfer never completes correctly
        final TransferCallback readCallback = new TransferCallback(){
            public void processTransfer(Transfer transfer){
                System.out.println(transfer.actualLength() + " bytes sent");

                //read the response here

                synchronized (synchObj){
                    readCompleted = true;
                    synchObj.notify();
                }
            }
        };

        //initial request writing the device identification query
        write(handle, idQuery, readCallback);

        //waiting for the write/response to complete
        while (loop){           
            synchronized (synchObj){
                while (!readCompleted){
                    try{
                        synchObj.wait();
                    }
                    catch (InterruptedException ex){
                        ex.printStackTrace();
                    }
                }
            }
            readCompleted = false;
            loop = false;
            System.out.println("Completed reading");
        }

        result = LibUsb.releaseInterface(handle, 0);
        LibUsb.close(handle);

    }

    private void initialize(){
        try{
            context = new Context();
            int result = LibUsb.init(context);
            if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to initialize libusb.", result);    

            DeviceList deviceList = new DeviceList();
            result = LibUsb.getDeviceList(context, deviceList);
            if (result < 0) throw new LibUsbException("Unable to get device list.", result);

            for (int i = 0; i < deviceList.getSize(); i++){
                Device dev = deviceList.get(i);

                DeviceHandle h = new DeviceHandle();
                int res = LibUsb.open(dev, h);
                if (res != LibUsb.SUCCESS) continue;

                DeviceDescriptor descriptor = new DeviceDescriptor();
                result = LibUsb.getDeviceDescriptor(dev, descriptor);
                if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to read device descriptor", result);

                String dump = descriptor.dump(h);               
                if (dump.indexOf("PPP") > -1){
                    device = dev;
                    handle = h;
                    System.out.println("Found target device");
                    break;
                }
            }

        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }

    public static void write(DeviceHandle handle, byte[] data, TransferCallback callback){
        ByteBuffer buffer = BufferUtils.allocateByteBuffer(data.length);
        buffer.put(data);
        Transfer transfer = LibUsb.allocTransfer();
        LibUsb.fillInterruptTransfer(transfer, handle, (byte)0x81, buffer, callback, null, 1000);
        System.out.println("Sending " + data.length + " bytes to device");
        int result = LibUsb.submitTransfer(transfer);
        if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to submit transfer", result);
    }

    public static void main(String[] args){
        Test app = new Test();
    }
}

提前感谢您的任何建议。

最佳答案

首先:如果您不喜欢摆弄和干预,我建议您最好只使用已经提供的软件。前面还有很多工作要做,因为这是一种科学设备,它有可能会扰乱您的读数。

现在为什么这行不通: 有趣的是这 block bEndpointAddress 0x81 EP 1 IN。它告诉我们的是,有一个端点可以向主机发送数据。是的,您可以写入此端点。这将等到设备有数据要发送并简单地覆盖您提供的缓冲区中的数据。

至于为什么会这样:您正在处理 HID。最好仔细阅读它,因为您不会简单地返回 ASCII 缓冲区,而是必须根据 HID 协议(protocol)进行解释的特殊格式的字节数组。

向此设备发送数据的唯一方法是在端点 0x00 上使用控制传输。

最简单的入门方法是使用带有 USB 嗅探器的 C++ 软件,并尝试理解来回传输的数据。

关于java - usb4java:无法进行数据传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39604836/

相关文章:

java - 如何使用java创建xml?

c - 无法作为进程执行命令

安卓 USB 主机。如何在不显示对话框的情况下获得使用 USB 设备的权限?

java - Java中如何将两个 "Cards"的值相加?

java - Neo4j 导入工具反斜杠转义

windows - 附加数据 : Error Value: 2147942402. 如何修复?

linux-kernel - Linux USB 小工具自定义配置

linux - 如何在 Linux 上检查 USB 存储

java - 在 Java 中控制 docker-compose

无论操作数和运算符如何,PHP MySQL 比较始终为真