Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux USB隐藏报告-哪个端点正确?_Linux_Windows_Usb_Endpoint_Hid - Fatal编程技术网

Linux USB隐藏报告-哪个端点正确?

Linux USB隐藏报告-哪个端点正确?,linux,windows,usb,endpoint,hid,Linux,Windows,Usb,Endpoint,Hid,我们有一个基于TI的CC2531的嵌入式设备,该设备(除了控制EP0和一些IN-only端点外)有一个IN和OUT端点。我们注意到windows发送报告的方式与linux发送报告的方式有所不同。这实际上让我们困惑了很长一段时间,但我们一直无法找到解释 在我看来,linux的工作方式应该是这样的:OUT报告通过与HID报告关联的端点传输,正如我们从libusb获得的那样: Item | Dev | EP | Status | Speed |Payload ---------

我们有一个基于TI的CC2531的嵌入式设备,该设备(除了控制EP0和一些IN-only端点外)有一个IN和OUT端点。我们注意到windows发送报告的方式与linux发送报告的方式有所不同。这实际上让我们困惑了很长一段时间,但我们一直无法找到解释

在我看来,linux的工作方式应该是这样的:OUT报告通过与HID报告关联的端点传输,正如我们从libusb获得的那样:

Item             | Dev | EP | Status | Speed |Payload
-----------------+-----+----+--------+-------+-------------------------------
OUT transaction  | 13  | 4  |  ACK   |  FS   | 64 bytes (90 13 00 00 00 00 ..
另一方面,Windows通过控制端点(EP0)发送。我们使用setupapi查找具有所需用法的设备,打开它进行输入和输出,并使用相同的文件描述符进行读取和写入。通过此文件描述符可以很好地接收EP4 IN报告,但通过相同的文件描述符编写报告最终会出现在EP0上:

Item               | Dev | EP | Status | Speed |Payload
-------------------+-----+----+--------+-------+-------------------------------
Class request OUT  | 25  | 0  |   OK   |  FS   | 64 bytes (90 13 00 00 00 00 ..
(对不起,现在还不能发布图片。我手工复制了Ellisys报告)


嵌入式设备不会检查接收到输出报告的EP(即,在处理HID事件时,EP0上的SET报告将与在其他端点上找到的输出报告进入相同的功能),因此它将以任何方式响应

我的问题是:这两种方法都正确吗?如果不正确,哪种方法正确,哪种方法不正确?我们的描述符中的错误是否会触发windows上的这种行为

完整地说:这是我们的描述:(从供应商标识中剥离以使我的老板高兴:)

在windows上放大报告:(高兴!我现在可以拍照了:)

整个交易:

Windows上使用的库:hid.lib、hidclass.lib和setupapi.lib。编写报告时,我们使用函数HidP_SetUsageValueArray和HidD_SetOutputReport。PHIDP_PREPARSED_DATA和HIDP_CAPS可通过函数HidD_GetAttributes、HidD_GetPreparsedData和HIDP_GetCaps找到。使用SetupDienumDeviceInterface可以找到设备的文件路径。如果我们发现一个设备具有正确的VID、PID、caps.UsagePage和caps.Usage,那就是我们使用的设备


在linux上有点棘手,因为我不是实现linux代码的人。我能说的是,使用了libusb-1.0.9,使用libusb\u open\u device\u打开设备,并使用libusb\u fill\u interrupt\u transfer和libusb\u submit\u transfer发送报告。我看到libuwand\u fill\u interrupt\u transfer接受一个端点作为参数,因此我认为只需使用libusb\u open\u device\u的句柄和\u vid\u pid,并将正确的参数作为端点传递,libusb就可以找到报告的放置位置。

我想我已经找到了答案

纯粹是巧合,我偶然发现了Keil论坛,在那里我发现了一条语句“HidD_SetOutputReport将使用控制端点,如果您希望它通过另一个端点,请使用WriteFile”。我知道5年多前我就尝试过这条路,但我被困在具有重叠结构的异步IO中。因为我似乎找到了出路(使用HidD_SetOutputReport),所以我放弃了WriteFile路径。因此,现在是时候再次寻求这条道路了,我做到了。守则:

res = HidD_SetOutputReport(m_DeviceControl[dev], report, m_CapsControl[dev].OutputReportByteLength);
已被替换为

                DWORD bytesWritten;
                OVERLAPPED eventWrite = {0};

                eventWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

                int rv3 = WriteFile(m_DeviceControl[dev], report, m_CapsControl[dev].OutputReportByteLength, &bytesWritten, &eventWrite);
                if (rv3 == 0)
                {
                    int err = GetLastError();

                    if (err == ERROR_IO_PENDING)
                    {
                        bool done = false;

                        do
                        {
                            // yes. Wait till pending state has gone
                            rv3 = WaitForSingleObject(eventWrite.hEvent, 25);
                            if (rv3 == WAIT_OBJECT_0)
                            {
                                GetOverlappedResult(m_DeviceControl[dev], &eventWrite, &bytesWritten, FALSE);
                                done = true;
                                res = TRUE;
                            }
                            else if (rv3 == WAIT_TIMEOUT)
                            {
                                // Need to try again.
                            }
                            else
                            {
                                m_StoppingControlOut = true;
                                done = true;
                            }
                        }
                        while (!done && !m_StoppingControlOut);
                    }
                }
            }
这使得请求经过适当的端点

因此,我得出以下结论:

  • 我认为HID设备解释通过控制端点发送的OUT报告是错误的
  • 正确使用WriteFile(使用重叠IO)可以使输出报告使用正确的端点

端点0是为控制传输保留的,因此必须在有效负载之前发送一个8字节的设置数据包,其参数包括bRequestType、bRequest、wValue等。你能把安装包的值贴出来吗?有了这些信息,我们可以查看HID规范,查看Windows发送的请求,以及它是否有效。另外,您在Linux和Windows上使用哪些驱动程序/库堆栈发送数据?Windows使用的端点可能取决于驱动程序(例如hidubs.sys)和用于与驱动程序对话的库(例如libusb)以及您的代码。“嵌入式设备不检查接收到输出报告的EP”:这听起来很不寻常。这是怎么回事?端点0上发送的控制传输的结构比正常中断或批量端点上的数据复杂得多,因此首先需要特殊代码来处理端点0数据。