USB-IP协议栈

数据包处理流程

角色

在TCP传输过程中的角色:

  • 其中客户端Client为将设备通过网络映射到本机的一方
  • 服务端server为提供USB接口的一方

1. 询问设备详情

  1. 客户端发出OP_REQ_DEVLIST包,要求获取USB设备列表
  2. 服务端返回OP_REP_DEVLIST包,包含USB设备列表响应
virtual host controller                                 usb host
     "client"                                           "server"
 (imports USB devices)                             (exports USB devices)
         |                                                 |
         |                  OP_REQ_DEVLIST                 |
         | ----------------------------------------------> |
         |                                                 |
         |                  OP_REP_DEVLIST                 |
         | <---------------------------------------------- |
         |                                                 |

2. 选定特定设备

  • 客户端在判断完自身需要哪个USB设备后,发出OP_REQ_IMPORT包,其中含有选定的USB设备
  • 服务端以OP_REP_IMPORT包进行应答
virtual host controller                                 usb host
     "client"                                           "server"
 (imports USB devices)                             (exports USB devices)
         |                                                 |
         |                  OP_REQ_IMPORT                  |
         | ----------------------------------------------> |
         |                                                 |
         |                  OP_REP_IMPORT                  |
         | <---------------------------------------------- |

3. URB数据块传输

分别有两种请求,一种为提交URB包,一种为取消上次的URB包。

  1. 提交URB包: 客户端发送USBIP_CMD_SUBMIT包,服务端发送USBIP_RET_SUBMIT响应
  2. 撤销URB包: 客户端发送USBIP_CMD_UNLINK包,服务端发送USBIP_RET_UNLINK响应
virtual host controller                                 usb host
     "client"                                           "server"
 (imports USB devices)                             (exports USB devices)
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = n)         |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = n)         |
         | <---------------------------------------------- |
         |                        .                        |
         |                        :                        |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m)         |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+1)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+2)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m)         |
         | <---------------------------------------------- |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+3)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m+1)       |
         | <---------------------------------------------- |
         |                                                 |
         |            USBIP_CMD_SUBMIT(seqnum = m+4)       |
         | ----------------------------------------------> |
         |                                                 |
         |            USBIP_RET_SUBMIT(seqnum = m+2)       |
         | <---------------------------------------------- |
         |                        .                        |
         |                        :                        |
         |                                                 |
         |               USBIP_CMD_UNLINK                  |
         | ----------------------------------------------> |
         |                                                 |
         |               USBIP_RET_UNLINK                  |
         | <---------------------------------------------- |
         |                                                 |

Endpoint

  • OUT always means from host to device.
  • IN always means from device to host.

数据处理

  1. 在endpoint 0 处理所有标准请求
  2. 在其余endpoint处理数据请求
def handle_usb_request(self, usb_req):
    if usb_req.ep == 0:
        self.handle_usb_control(usb_req)
    else:
        self.handle_data(usb_req)

第三方库中的写法

USBDeviceIntHandlerInternal这里处理所有在USB上面的中断事件
g_psUSBDStdRequests 这里面有所有的标准请求回调函数

几个偏向硬件层面的handle不知道USB/ip中有没有实现:

  • ResetHandler
  • SuspendHandler
  • ResumeHandler
  • DisconnectHandler