4

我需要对定制的 HID USB 设备(控制面板上的一些按钮和 LED)的驱动程序进行逆向工程。该驱动程序仅在 Windows 上可用,我们需要一个 *nix 实现。

该设备显然是 HID 设备,尽管不是特定类别。它提供了两个接口,每个接口都有一个中断端点。

我的设置目前涉及在 Ubuntu 主机上运行 Windows 的 VirtualBox,以通过 Wireshark 捕获 USB 流量。该协议相当简单,我已经获得了相当好的理解。

我在一个简单的 C++ 控制台程序中使用 libusb-1.0 进行原型设计。我已经设法通过发出 SET_REPORT 控制传输来切换 LED,但很难通过传输中断接收按钮按下。

事实上,以下调用会永远阻塞:

unsigned char bytes[8] = { 0 };
int len = 0;
int ret = libusb_interrupt_transfer(handle, 0x81, bytes, 8, &len, 0); 

在 Wireshark 中检查生成的 URB 时,它看起来与在 Windows 会话中捕获的等效 URB 完全一样。我仍然没有得到设备的回复。

我跌倒了,我错过了一些设置。请注意,设备已正确打开,并且设备提供的两个接口均已成功声明。即使在我的 linux 应用程序中,通过控制传输的输入报告也正在出现。

感谢您的任何指示!阿恩

附录 I:我想知道在使用时我应该如何指定要接收的报告 ID libusb_interrupt_transfer()

附录二:当将 Windows 驱动程序发出的请求与 Wireshark 中上述代码生成的请求进行比较时,我没有看到任何差异(URB 中的值相同)。但是,只有当 Windows 驱动程序发出中断传输时才会返回。

在 Wireshark 中检查 Windows 驱动程序通信时,除了各种GET_DESCRIPTOR(...). 最重要的是:否SET_INTERFACESET_CONFIGURATION因此我怀疑问题与库或我如何使用它有关,与设备无关

4

2 回答 2

1

There is a problem with the code you posted. The syntax you wrote for defining bytes will not result in an 8-byte array, but you are requesting that libusb write 8 bytes in to that address so you might get an error or memory corruption. Try this instead:

unsigned char buffer[8];
int len = 0;
int ret = libusb_interrupt_transfer(handle, 0x81, buffer, sizeof(buffer), &len, 0);

Each HID report has its own endpoint, so you specify which report you want to receive by specifying the correct endpoint. You specified Endpoint 1 IN (0x81). Are you sure that endpoint is defined in the device's descriptors? Maybe you should get the descriptors (with lsusb -v in Ubuntu) and post them here so we can check them.

于 2011-06-25T06:20:13.607 回答
1

我有同样的问题,libusb_interrupt_transfer()读取端点永远阻塞(bEndpointAddress:0x81 EP 1 IN(输出lsusb -v)),但解决了。

就我而言,我是这样写的。

#define ENDPOINT_IN 0x81
unsigned char buffer[8];
int len = 0;
int ret = libusb_interrupt_transfer(handle, ENDPOINT_IN, buffer, sizeof(buffer), &len, 0);

但是,我的设备需要在读取数据之前发送一些代码,
并且需要 sizeof 64 缓冲区,尽管lsusb -v的输出bLength为 7。

#define ENDPOINT_OUT 0x01
#define ENDPOINT_IN 0x81
unsigned char buffer[64] = {0x20, 0x01, 0x03, 0x02, 0x07};
int len = 0;
int send_ret = libusb_interrupt_transfer(handle, ENDPOINT_OUT, buffer, sizeof(buffer), &len, 0);
int recv_ret = libusb_interrupt_transfer(handle, ENDPOINT_IN, buffer, sizeof(buffer), &len, 0);

buffer[64] = {0x20, 0x01, 0x03, 0x02, 0x07}取决于设备规格。

希望这可以帮助。

于 2019-05-25T05:46:14.890 回答