HID开发笔记
+ -

Windows HID设备SET_IDLE请求的寂寞操作

2022-04-15 66 0

在HID规范中SET_IDLE请求用于节省USB带宽的,使用这个请求可以设置HID设备空闲速率。
不过我们一般抓包的内容是这样的:

 CTL    21 0a 00 00  00 00 00 00                            SET IDLE

这样的

 CTL    21 0a 00 00  01 00 00 00                            SET IDLE

对照HID规范的SET_IDLE的HID请求分析可以知道,这里除了接口描述符的ID不同类,其它都一样,特别是wValue(其高字节用于指定空闲速率,以4ms为单位,可选的值为4ms~1020ms,低字节为ReportId)的值永远是00。

所以说,这玩意有啥用了?没啥用。不过也有一个区别就是固件关于SET_IDLE的响应问题,如果支持,表示该请求成功。如果不支持,会使用BUSHOUND抓包返回一个C0000004的STALL PID错误。不过通过我们之前的文章 Windows系统HID设备的启动过程(http://www.usbzh.com/article/detail-905.html ),这玩意就算错误了,也不是致命性的错误,所以以驱动中,其压根也不进行执行对果的判断。

这里我们结合SET_IDLE请求的代码来看:

   if (DeviceExtension->DeviceFlags & DEVICE_FLAGS_HID_1_0_D3_COMPAT_DEVICE) {
                HumBuildClassRequest(Urb,
                                    URB_FUNCTION_CLASS_ENDPOINT,   // function
                                    0,              // transferFlags
                                    NULL,           // transferBuffer
                                    0,              // transferBufferLength
                                    0x22,           // requestTypeFlags
                                    HID_SET_IDLE,   // request
                                    0,              // value
                                    0,              // index
                                    0);             // reqLength
            } else {
                HumBuildClassRequest(Urb,
                                    URB_FUNCTION_CLASS_INTERFACE,   // function
                                    0,                                  // transferFlags
                                    NULL,                               // transferBuffer
                                    0,                                  // transferBufferLength
                                    0x22,                               // requestTypeFlags
                                    HID_SET_IDLE,                       // request
                                    0,                                  // value
                                    DeviceExtension->Interface->InterfaceNumber,    // index
                                    0);                                 // reqLength
            }

HumBuildClassRequest的宏定义为:

#define HumBuildClassRequest(urb, \
                                       function, \
                                       transferFlags, \
                                       transferBuffer, \
                                       transferBufferLength, \
                                       requestType, \
                                       request, \
                                       value, \
                                       index, \
                                       reqLength){ \
            (urb)->UrbHeader.Length = (USHORT) sizeof( struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); \
            (urb)->UrbHeader.Function = function; \
            (urb)->UrbControlVendorClassRequest.Index = (index); \
            (urb)->UrbControlVendorClassRequest.RequestTypeReservedBits = (requestType); \
            (urb)->UrbControlVendorClassRequest.Request = (request); \
            (urb)->UrbControlVendorClassRequest.Value = (value); \
            (urb)->UrbControlVendorClassRequest.TransferFlags = (transferFlags); \
            (urb)->UrbControlVendorClassRequest.TransferBuffer = (transferBuffer); \
            (urb)->UrbControlVendorClassRequest.TransferBufferLength = (transferBufferLength); }

所以说,这里在初始化时的值就是那样,为0。
至于DEVICE_FLAGS_HID_1_0_D3_COMPAT_DEVICE的标识问题,也是因为:

对于HID 1.0草案性,下一个描述符是HID。然而,对于早些时候草稿,端点先出现,然后才是HID描述符。我们正努力支持这两种观点。

所以说,在实际抓包的时候,你会看到,主机还是会按端点描述符定时下发IN请求,只是设备端无数据时,会一直NAK。然后永远的在这个重复过程中。

NAK

0 篇笔记 写笔记

USB2.0 NAK握手包
NAK 握手包一般由 USB 设备发出。对于IN数据传输,表示 USB 设备没有计划向 USB 主机发送数据;对于 OUT 数据传输,表示 USB 设备无法接收 USB 主机发送的数据。NAK包的PID的低4位为1010,故高4位的补码为0101,所以其包PID值为0x5a.PID含......
HID设备SET_IDLE时遇到c0000004
下午,USB中文网技术交流群里的一个同学,说他的HID设备时好时不好的,有时会花很长的时间才能枚举成功。没有抓包,没的截图…我是一顿乱扯,从硬件电路到各种抓包方法….晚上11点,这位同学发来了BUSHOUND抓的包,打开一看:Device Length Phase Data ......
USB键盘在Linux环境下一直返回NAK的输入端点和一直OUT数据的输出端点
群里有同学反馈,自己做的USB键盘在Windows下正常,但在Linux下就失败,想让帮忙分析一下原因。一个比较好的消息是他那边有USB总线分析仪,所以只需要抓包就可以进行分析了。最好开他给的抓包截图是样子的:从它的截图可以看到,USB键盘在获取了该键盘的HID报告描述符后,紧跟着一下发Report......
USB2.0 IN/OUT事务NAK的数据翻转(DATA TOGGLE)
NAK由USB设备发送,用于表示设备当前无法接收数据或者无数据发送给主机。USB设备返回NAK握手包给主机后,USB主机会重传该事务,而对于高速OUT事务,会使用PING令牌来PING设备是否可以接收数据。USB主机不会发送NAK握手包给设备。IN事务DATA0/DATA1 NAK的数据翻转......
HID协议SET_IDLE请求的解释说明
SET_IDLE请求会使HID设备相关的中断管道(端点)停止定时上报报告数据,直到有新的事件(有效数据)或直到的SET_IDLE时才继续上报报告数据。在SET_IDLE的时间周期内,如果没有变化的情况下,由设备周期性地返回NAK。关于SET_IDLE的功能讨论HID设备以中断的方向进行上报数据给方......
Windows HID设备SET_IDLE请求的寂寞操作
在HID规范中SET_IDLE请求用于节省USB带宽的,使用这个请求可以设置HID设备空闲速率。不过我们一般抓包的内容是这样的: CTL 21 0a 00 00 00 00 00 00 SET IDLE这样的 CTL 21 0......
作者信息
USB中文网
B站搜索 站长漫谈 看视频。
pnpon内核开网,USB中文网,
busrom硬核技术网站长
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!