USB数据长度为0的DATA/IN事务
前言
使用BUSHOUND是抓不到这种包的。而且一些令牌包如SOF等这些是统计不到的。BUSHOUND是一个基本windows过滤驱动的,所以抓到的是数据已经传输的并且已经在主机方面的,所以USB总线上的一些状态是统计不到的。
其实关于控制传输的0字节长度,可详见:USB2.0 控制传输数据包PID序列 http://www.usbzh.com/article/detail-708.html 表示状态阶段。
案例1-获取设备描述符
使用一些USB抓包工具,会经常看到一些传输数据长度为0的事务。不过由于没有负载有效的数据,在USB协议分析的过程中,我们经常将这种类忽略掉。但是它又是确实存在的。
如下图的获取设备描述符抓包:
可以看到,主机使用事务0发起控请求,请求的内容是获取设备描述符。
然后设备通过一个IN的事务,返回18个字节的设备描述符,使用的事务是1。
但是在事务1结束后,又有一个编号为2的OUT事务,也是主机发送数据给设备,不过返回的数据长度为0。
案例2-设置设置地址SetAddress
在设备枚举过程中,主机会给设备分配一个地址。这个地址是由主机直接发送给设备的。设备端不需要返回数据的。
但是在事务3之后,也有一个编号为4的IN事务。也是返回的是数据长度为0。
案例3-获取状态GetStatus
USB主机获取设备状态时,设备返回2字节的状态,同样也会有一个事务为37的IN事务。数据长度为0。
案例4-配置设备SetConfigure
主机配置设备后,设备返回一个编号为39的IN事务,数据长度为0。
案例5-数据传输IN事务
有效数据传输完成后,也会有一个编号为1413的IN事务,数据长度为0。
案例5-U盘的BULK传输
这个0长度的发生在有效数据之前。
USB数据长度为0的DATA事务的总结
- 长度为0的包一般是用来表示一个传输结束的即多发送一个0字节的长度数据包通知USB主机没有更多的数据可以发送了。如USB主机需要从USB设备获取255个字节,但USB设备只有64字节的数据,并且USB设备端点0的最大包工度刚好是64,详仔细观察案例1中的DATA0的数据长度。
- 或者表示数据还没有准备好,如批量传输或同步传输中。
- 这个数据阶段叫做状态阶段的数据包,并且PID必须是DATA1.
控制传输
感谢USB中文网技术交流群Always Online的贡献
控制传输是USB传输中最重要的传输。控制传输类型分为2~3个阶段:设置阶段、数据阶段(无数据控制没有此阶段)、确认阶段。
阶段一:设置阶段
都是由USB主机发起,主机从USB设备获取配置信息,并设置设备的配置值。
设置阶段的数据交换包包含了SETUP令牌包、DATA0数据包以及ACK握手包
阶段二:数据传输阶段
数据传输阶段用来传输主机与设备之间的数据。根据数据传输的方向,分为3种类型:控制读取(读取USB描述符)、控制写入(配置USB设备)以及无数据控制。
控制读取是将数据从设备读到主机上,读取的数据是USB设备描述度。首先,主机发送一个IN令牌信息包,然后设备将数据通过DATA1数据信息包回给主机,最后主机以下列方式响应:当数据正确接收时,主机送出ACK握手信息包;当主机忙碌时,发出NAK握手信息包;当发生错误时,主机发出STALL握手信息包。
控制写入是将数据从主机传到设备上,所传的数据即为对USB设备的配置信息。对每一个数据信息包而言,主机将会送出一个OUT令牌信息包表示信息要送出去。接着主机将数据通过DATA0数据信息包传递至设备。最后设备将以下列方式加以响应:当数据已经正确接收时,设备送出ACK握手信息包;当设备忙碌时,设备发出NAK握手信息包;当发生错误时,设备发出STALL握手信息包。
阶段三:确认阶段
确认阶段用来表示整个传输过程已完全结束。
确认阶段传输的方向必须与数据阶段的方向相反,即原来是IN令牌包,这个阶段应该是OUT令牌包;反之原来是OUT令牌包,这个阶段应为IN令牌包。对于控制读取而言,主机会送出OUT包,其后跟着0长度的DATA1包,此时设备也会做出相应的动作,送ACK、NAK、STALL握手包。相对地对于控制写入传输,主机会送出IN令牌包,然后设备送出表示完成状态阶段的0长度DATA1包,主机再做出相对应的动作:送ACK、NAK、STALL握手包。