← Documents Documentation/usb/usbip_protocol.rst GitHub 원문 ↗

Linux 6.18.37 · USB

USB/IP protocol

USB/IP의 device discovery·import·URB submit/unlink 흐름과 각 network message의 byte-level layout을 설명합니다.

Source pathDocumentation/usb/usbip_protocol.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

usbip_protocol.rst:1-452

USB/IP는 server가 물리 USB device를 export하고 client의 virtual host controller가 import하는 protocol입니다. discovery connection은 목록 응답 뒤 닫히지만 성공한 import connection은 URB traffic을 위해 유지됩니다.

wire field는 모두 big endian이며 공통 20-byte `usbip_header_basic` 뒤에 command별 field와 선택적 payload가 이어집니다. 표는 원문의 offset, length, constant와 조건을 빠짐없이 보존합니다.

USB/IP session
OP_REQ_DEVLIST / OP_REP_DEVLISTOP_REQ_IMPORT / OP_REP_IMPORTTCP/IP connection 유지USBIP_CMD_SUBMIT / USBIP_RET_SUBMIT필요 시 USBIP_CMD_UNLINK / USBIP_RET_UNLINK

장치 발견부터 URB 전송·해제까지의 상위 흐름입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ===============
2 USB/IP protocol
3 ===============
4
5 Architecture
6 ============
7
8 The USB/IP protocol follows a server/client architecture. The server exports the
9 USB devices and the clients import them. The device driver for the exported
10 USB device runs on the client machine.
11
12 The client may ask for the list of the exported USB devices. To get the list the
13 client opens a TCP/IP connection to the server, and sends an OP_REQ_DEVLIST
14 packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent
15 in one or more pieces at the low level transport layer). The server sends back
16 the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the
17 TCP/IP connection is closed.
18
19 ::
20
21 virtual host controller usb host
22 "client" "server"
23 (imports USB devices) (exports USB devices)
24 | |
25 | OP_REQ_DEVLIST |
26 | ----------------------------------------------> |
27 | |
28 | OP_REP_DEVLIST |
29 | <---------------------------------------------- |
30 | |
31
32 Once the client knows the list of exported USB devices it may decide to use one
33 of them. First the client opens a TCP/IP connection to the server and
34 sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the
35 import was successful the TCP/IP connection remains open and will be used
36 to transfer the URB traffic between the client and the server. The client may
37 send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and
38 USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the
39 server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively.
40
41 ::
42
43 virtual host controller usb host
44 "client" "server"
45 (imports USB devices) (exports USB devices)
46 | |
47 | OP_REQ_IMPORT |
48 | ----------------------------------------------> |
49 | |
50 | OP_REP_IMPORT |
51 | <---------------------------------------------- |
52 | |
53 | |
54 | USBIP_CMD_SUBMIT(seqnum = n) |
55 | ----------------------------------------------> |
56 | |
57 | USBIP_RET_SUBMIT(seqnum = n) |
58 | <---------------------------------------------- |
59 | . |
60 | : |
61 | |
62 | USBIP_CMD_SUBMIT(seqnum = m) |
63 | ----------------------------------------------> |
64 | |
65 | USBIP_CMD_SUBMIT(seqnum = m+1) |
66 | ----------------------------------------------> |
67 | |
68 | USBIP_CMD_SUBMIT(seqnum = m+2) |
69 | ----------------------------------------------> |
70 | |
71 | USBIP_RET_SUBMIT(seqnum = m) |
72 | <---------------------------------------------- |
73 | |
74 | USBIP_CMD_SUBMIT(seqnum = m+3) |
75 | ----------------------------------------------> |
76 | |
77 | USBIP_RET_SUBMIT(seqnum = m+1) |
78 | <---------------------------------------------- |
79 | |
80 | USBIP_CMD_SUBMIT(seqnum = m+4) |
81 | ----------------------------------------------> |
82 | |
83 | USBIP_RET_SUBMIT(seqnum = m+2) |
84 | <---------------------------------------------- |
85 | . |
86 | : |
87
88 For UNLINK, note that after a successful USBIP_RET_UNLINK, the unlinked URB
89 submission would not have a corresponding USBIP_RET_SUBMIT (this is explained in
90 function stub_recv_cmd_unlink of drivers/usb/usbip/stub_rx.c).
91
92 ::
93
94 virtual host controller usb host
95 "client" "server"
96 (imports USB devices) (exports USB devices)
97 | |
98 | USBIP_CMD_SUBMIT(seqnum = p) |
99 | ----------------------------------------------> |
100 | |
101 | USBIP_CMD_UNLINK |
102 | (seqnum = p+1, unlink_seqnum = p) |
103 | ----------------------------------------------> |
104 | |
105 | USBIP_RET_UNLINK |
106 | (seqnum = p+1, status = -ECONNRESET) |
107 | <---------------------------------------------- |
108 | |
109 | Note: No USBIP_RET_SUBMIT(seqnum = p) |
110 | <--X---X---X---X---X---X---X---X---X---X---X--- |
111 | . |
112 | : |
113 | |
114 | USBIP_CMD_SUBMIT(seqnum = q) |
115 | ----------------------------------------------> |
116 | |
117 | USBIP_RET_SUBMIT(seqnum = q) |
118 | <---------------------------------------------- |
119 | |
120 | USBIP_CMD_UNLINK |
121 | (seqnum = q+1, unlink_seqnum = q) |
122 | ----------------------------------------------> |
123 | |
124 | USBIP_RET_UNLINK |
125 | (seqnum = q+1, status = 0) |
126 | <---------------------------------------------- |
127 | |
128
129 The fields are in network (big endian) byte order meaning that the most significant
130 byte (MSB) is stored at the lowest address.
131
132 Protocol Version
133 ================
134
135 The documented USBIP version is v1.1.1. The binary representation of this
136 version in message headers is 0x0111.
137
138 This is defined in tools/usb/usbip/configure.ac
139
140 Message Format
141 ==============
142
143 OP_REQ_DEVLIST:
144 Retrieve the list of exported USB devices.
145
146 +-----------+--------+------------+---------------------------------------------------+
147 | Offset | Length | Value | Description |
148 +===========+========+============+===================================================+
149 | 0 | 2 | | USBIP version |
150 +-----------+--------+------------+---------------------------------------------------+
151 | 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB |
152 | | | | devices. |
153 +-----------+--------+------------+---------------------------------------------------+
154 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 |
155 +-----------+--------+------------+---------------------------------------------------+
156
157 OP_REP_DEVLIST:
158 Reply with the list of exported USB devices.
159
160 +-----------+--------+------------+---------------------------------------------------+
161 | Offset | Length | Value | Description |
162 +===========+========+============+===================================================+
163 | 0 | 2 | | USBIP version |
164 +-----------+--------+------------+---------------------------------------------------+
165 | 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. |
166 +-----------+--------+------------+---------------------------------------------------+
167 | 4 | 4 | 0x00000000 | Status: 0 for OK |
168 +-----------+--------+------------+---------------------------------------------------+
169 | 8 | 4 | n | Number of exported devices: 0 means no exported |
170 | | | | devices. |
171 +-----------+--------+------------+---------------------------------------------------+
172 | 0x0C | | | From now on the exported n devices are described, |
173 | | | | if any. If no devices are exported the message |
174 | | | | ends with the previous "number of exported |
175 | | | | devices" field. |
176 +-----------+--------+------------+---------------------------------------------------+
177 | | 256 | | path: Path of the device on the host exporting the|
178 | | | | USB device, string closed with zero byte, e.g. |
179 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" |
180 | | | | The unused bytes shall be filled with zero |
181 | | | | bytes. |
182 +-----------+--------+------------+---------------------------------------------------+
183 | 0x10C | 32 | | busid: Bus ID of the exported device, string |
184 | | | | closed with zero byte, e.g. "3-2". The unused |
185 | | | | bytes shall be filled with zero bytes. |
186 +-----------+--------+------------+---------------------------------------------------+
187 | 0x12C | 4 | | busnum |
188 +-----------+--------+------------+---------------------------------------------------+
189 | 0x130 | 4 | | devnum |
190 +-----------+--------+------------+---------------------------------------------------+
191 | 0x134 | 4 | | speed |
192 +-----------+--------+------------+---------------------------------------------------+
193 | 0x138 | 2 | | idVendor |
194 +-----------+--------+------------+---------------------------------------------------+
195 | 0x13A | 2 | | idProduct |
196 +-----------+--------+------------+---------------------------------------------------+
197 | 0x13C | 2 | | bcdDevice |
198 +-----------+--------+------------+---------------------------------------------------+
199 | 0x13E | 1 | | bDeviceClass |
200 +-----------+--------+------------+---------------------------------------------------+
201 | 0x13F | 1 | | bDeviceSubClass |
202 +-----------+--------+------------+---------------------------------------------------+
203 | 0x140 | 1 | | bDeviceProtocol |
204 +-----------+--------+------------+---------------------------------------------------+
205 | 0x141 | 1 | | bConfigurationValue |
206 +-----------+--------+------------+---------------------------------------------------+
207 | 0x142 | 1 | | bNumConfigurations |
208 +-----------+--------+------------+---------------------------------------------------+
209 | 0x143 | 1 | | bNumInterfaces |
210 +-----------+--------+------------+---------------------------------------------------+
211 | 0x144 | | m_0 | From now on each interface is described, all |
212 | | | | together bNumInterfaces times, with the following |
213 | | | | 4 fields: |
214 +-----------+--------+------------+---------------------------------------------------+
215 | | 1 | | bInterfaceClass |
216 +-----------+--------+------------+---------------------------------------------------+
217 | 0x145 | 1 | | bInterfaceSubClass |
218 +-----------+--------+------------+---------------------------------------------------+
219 | 0x146 | 1 | | bInterfaceProtocol |
220 +-----------+--------+------------+---------------------------------------------------+
221 | 0x147 | 1 | | padding byte for alignment, shall be set to zero |
222 +-----------+--------+------------+---------------------------------------------------+
223 | 0xC + | | | The second exported USB device starts at i=1 |
224 | i*0x138 + | | | with the path field. |
225 | m_(i-1)*4 | | | |
226 +-----------+--------+------------+---------------------------------------------------+
227
228 OP_REQ_IMPORT:
229 Request to import (attach) a remote USB device.
230
231 +-----------+--------+------------+---------------------------------------------------+
232 | Offset | Length | Value | Description |
233 +===========+========+============+===================================================+
234 | 0 | 2 | | USBIP version |
235 +-----------+--------+------------+---------------------------------------------------+
236 | 2 | 2 | 0x8003 | Command code: import a remote USB device. |
237 +-----------+--------+------------+---------------------------------------------------+
238 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 |
239 +-----------+--------+------------+---------------------------------------------------+
240 | 8 | 32 | | busid: the busid of the exported device on the |
241 | | | | remote host. The possible values are taken |
242 | | | | from the message field OP_REP_DEVLIST.busid. |
243 | | | | A string closed with zero, the unused bytes |
244 | | | | shall be filled with zeros. |
245 +-----------+--------+------------+---------------------------------------------------+
246
247 OP_REP_IMPORT:
248 Reply to import (attach) a remote USB device.
249
250 +-----------+--------+------------+---------------------------------------------------+
251 | Offset | Length | Value | Description |
252 +===========+========+============+===================================================+
253 | 0 | 2 | | USBIP version |
254 +-----------+--------+------------+---------------------------------------------------+
255 | 2 | 2 | 0x0003 | Reply code: Reply to import. |
256 +-----------+--------+------------+---------------------------------------------------+
257 | 4 | 4 | 0x00000000 | Status: |
258 | | | | |
259 | | | | - 0 for OK |
260 | | | | - 1 for error |
261 +-----------+--------+------------+---------------------------------------------------+
262 | 8 | | | From now on comes the details of the imported |
263 | | | | device, if the previous status field was OK (0), |
264 | | | | otherwise the reply ends with the status field. |
265 +-----------+--------+------------+---------------------------------------------------+
266 | | 256 | | path: Path of the device on the host exporting the|
267 | | | | USB device, string closed with zero byte, e.g. |
268 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" |
269 | | | | The unused bytes shall be filled with zero |
270 | | | | bytes. |
271 +-----------+--------+------------+---------------------------------------------------+
272 | 0x108 | 32 | | busid: Bus ID of the exported device, string |
273 | | | | closed with zero byte, e.g. "3-2". The unused |
274 | | | | bytes shall be filled with zero bytes. |
275 +-----------+--------+------------+---------------------------------------------------+
276 | 0x128 | 4 | | busnum |
277 +-----------+--------+------------+---------------------------------------------------+
278 | 0x12C | 4 | | devnum |
279 +-----------+--------+------------+---------------------------------------------------+
280 | 0x130 | 4 | | speed |
281 +-----------+--------+------------+---------------------------------------------------+
282 | 0x134 | 2 | | idVendor |
283 +-----------+--------+------------+---------------------------------------------------+
284 | 0x136 | 2 | | idProduct |
285 +-----------+--------+------------+---------------------------------------------------+
286 | 0x138 | 2 | | bcdDevice |
287 +-----------+--------+------------+---------------------------------------------------+
288 | 0x13A | 1 | | bDeviceClass |
289 +-----------+--------+------------+---------------------------------------------------+
290 | 0x13B | 1 | | bDeviceSubClass |
291 +-----------+--------+------------+---------------------------------------------------+
292 | 0x13C | 1 | | bDeviceProtocol |
293 +-----------+--------+------------+---------------------------------------------------+
294 | 0x13D | 1 | | bConfigurationValue |
295 +-----------+--------+------------+---------------------------------------------------+
296 | 0x13E | 1 | | bNumConfigurations |
297 +-----------+--------+------------+---------------------------------------------------+
298 | 0x13F | 1 | | bNumInterfaces |
299 +-----------+--------+------------+---------------------------------------------------+
300
301 The following four commands have a common basic header called
302 'usbip_header_basic', and their headers, called 'usbip_header' (before
303 transfer_buffer payload), have the same length, therefore paddings are needed.
304
305 usbip_header_basic:
306
307 +-----------+--------+---------------------------------------------------+
308 | Offset | Length | Description |
309 +===========+========+===================================================+
310 | 0 | 4 | command |
311 +-----------+--------+---------------------------------------------------+
312 | 4 | 4 | seqnum: sequential number that identifies requests|
313 | | | and corresponding responses; |
314 | | | incremented per connection |
315 +-----------+--------+---------------------------------------------------+
316 | 8 | 4 | devid: specifies a remote USB device uniquely |
317 | | | instead of busnum and devnum; |
318 | | | for client (request), this value is |
319 | | | ((busnum << 16) | devnum); |
320 | | | for server (response), this shall be set to 0 |
321 +-----------+--------+---------------------------------------------------+
322 | 0xC | 4 | direction: |
323 | | | |
324 | | | - 0: USBIP_DIR_OUT |
325 | | | - 1: USBIP_DIR_IN |
326 | | | |
327 | | | only used by client, for server this shall be 0 |
328 +-----------+--------+---------------------------------------------------+
329 | 0x10 | 4 | ep: endpoint number |
330 | | | only used by client, for server this shall be 0; |
331 | | | for UNLINK, this shall be 0 |
332 +-----------+--------+---------------------------------------------------+
333
334 USBIP_CMD_SUBMIT:
335 Submit an URB
336
337 +-----------+--------+---------------------------------------------------+
338 | Offset | Length | Description |
339 +===========+========+===================================================+
340 | 0 | 20 | usbip_header_basic, 'command' shall be 0x00000001 |
341 +-----------+--------+---------------------------------------------------+
342 | 0x14 | 4 | transfer_flags: possible values depend on the |
343 | | | USBIP_URB transfer_flags. |
344 | | | Refer to include/uapi/linux/usbip.h and |
345 | | | Documentation/driver-api/usb/URB.rst. |
346 | | | Refer to usbip_pack_cmd_submit() and |
347 | | | tweak_transfer_flags() in drivers/usb/usbip/ |
348 | | | usbip_common.c. |
349 +-----------+--------+---------------------------------------------------+
350 | 0x18 | 4 | transfer_buffer_length: |
351 | | | use URB transfer_buffer_length |
352 +-----------+--------+---------------------------------------------------+
353 | 0x1C | 4 | start_frame: use URB start_frame; |
354 | | | initial frame for ISO transfer; |
355 | | | shall be set to 0 if not ISO transfer |
356 +-----------+--------+---------------------------------------------------+
357 | 0x20 | 4 | number_of_packets: number of ISO packets; |
358 | | | shall be set to 0xffffffff if not ISO transfer |
359 +-----------+--------+---------------------------------------------------+
360 | 0x24 | 4 | interval: maximum time for the request on the |
361 | | | server-side host controller |
362 +-----------+--------+---------------------------------------------------+
363 | 0x28 | 8 | setup: data bytes for USB setup, filled with |
364 | | | zeros if not used. |
365 +-----------+--------+---------------------------------------------------+
366 | 0x30 | n | transfer_buffer. |
367 | | | If direction is USBIP_DIR_OUT then n equals |
368 | | | transfer_buffer_length; otherwise n equals 0. |
369 | | | For ISO transfers the padding between each ISO |
370 | | | packets is not transmitted. |
371 +-----------+--------+---------------------------------------------------+
372 | 0x30+n | m | iso_packet_descriptor |
373 +-----------+--------+---------------------------------------------------+
374
375 USBIP_RET_SUBMIT:
376 Reply for submitting an URB
377
378 +-----------+--------+---------------------------------------------------+
379 | Offset | Length | Description |
380 +===========+========+===================================================+
381 | 0 | 20 | usbip_header_basic, 'command' shall be 0x00000003 |
382 +-----------+--------+---------------------------------------------------+
383 | 0x14 | 4 | status: zero for successful URB transaction, |
384 | | | otherwise some kind of error happened. |
385 +-----------+--------+---------------------------------------------------+
386 | 0x18 | 4 | actual_length: number of URB data bytes; |
387 | | | use URB actual_length |
388 +-----------+--------+---------------------------------------------------+
389 | 0x1C | 4 | start_frame: use URB start_frame; |
390 | | | initial frame for ISO transfer; |
391 | | | shall be set to 0 if not ISO transfer |
392 +-----------+--------+---------------------------------------------------+
393 | 0x20 | 4 | number_of_packets: number of ISO packets; |
394 | | | shall be set to 0xffffffff if not ISO transfer |
395 +-----------+--------+---------------------------------------------------+
396 | 0x24 | 4 | error_count |
397 +-----------+--------+---------------------------------------------------+
398 | 0x28 | 8 | padding, shall be set to 0 |
399 +-----------+--------+---------------------------------------------------+
400 | 0x30 | n | transfer_buffer. |
401 | | | If direction is USBIP_DIR_IN then n equals |
402 | | | actual_length; otherwise n equals 0. |
403 | | | For ISO transfers the padding between each ISO |
404 | | | packets is not transmitted. |
405 +-----------+--------+---------------------------------------------------+
406 | 0x30+n | m | iso_packet_descriptor |
407 +-----------+--------+---------------------------------------------------+
408
409 USBIP_CMD_UNLINK:
410 Unlink an URB
411
412 +-----------+--------+---------------------------------------------------+
413 | Offset | Length | Description |
414 +===========+========+===================================================+
415 | 0 | 20 | usbip_header_basic, 'command' shall be 0x00000002 |
416 +-----------+--------+---------------------------------------------------+
417 | 0x14 | 4 | unlink_seqnum, of the SUBMIT request to unlink |
418 +-----------+--------+---------------------------------------------------+
419 | 0x18 | 24 | padding, shall be set to 0 |
420 +-----------+--------+---------------------------------------------------+
421
422 USBIP_RET_UNLINK:
423 Reply for URB unlink
424
425 +-----------+--------+---------------------------------------------------+
426 | Offset | Length | Description |
427 +===========+========+===================================================+
428 | 0 | 20 | usbip_header_basic, 'command' shall be 0x00000004 |
429 +-----------+--------+---------------------------------------------------+
430 | 0x14 | 4 | status: This is similar to the status of |
431 | | | USBIP_RET_SUBMIT (share the same memory offset). |
432 | | | When UNLINK is successful, status is -ECONNRESET; |
433 | | | when USBIP_CMD_UNLINK is after USBIP_RET_SUBMIT |
434 | | | status is 0 |
435 +-----------+--------+---------------------------------------------------+
436 | 0x18 | 24 | padding, shall be set to 0 |
437 +-----------+--------+---------------------------------------------------+
438
439 EXAMPLE
440 =======
441
442 The following data is captured from wire with Human Interface Devices (HID)
443 payload
444
445 ::
446
447 CmdIntrIN: 00000001 00000d05 0001000f 00000001 00000001 00000200 00000040 ffffffff 00000000 00000004 00000000 00000000
448 CmdIntrOUT: 00000001 00000d06 0001000f 00000000 00000001 00000000 00000040 ffffffff 00000000 00000004 00000000 00000000
449 ffffffff860008a784ce5ae212376300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
450 RetIntrOut: 00000003 00000d06 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
451 RetIntrIn: 00000003 00000d05 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
452 ffffffff860011a784ce5ae2123763612891b1020100000400000000000000000000000000000000000000000000000000000000000000000000000000000000
453

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Architecture: exported device 목록

1-31

USB/IP protocol은 server/client architecture를 따릅니다. server는 USB device를 export하고 client는 이를 import합니다. export된 USB device의 device driver는 client machine에서 실행됩니다.

client는 export된 USB device 목록을 요청할 수 있습니다. 목록을 얻으려면 server에 TCP/IP connection을 열고 그 위로 `OP_REQ_DEVLIST` packet을 보냅니다. 낮은 수준의 transport layer에서는 실제 packet이 하나 이상의 조각으로 전송될 수 있습니다.

server는 export된 USB device를 나열하는 `OP_REP_DEVLIST` packet을 돌려보내고, 이 교환이 끝나면 TCP/IP connection을 닫습니다.

Exported-device discovery
Client virtual host controller: TCP/IP connection 열기Client -> Server: OP_REQ_DEVLISTServer -> Client: OP_REP_DEVLISTExported device 목록 확인TCP/IP connection 닫기

원문의 client/server ASCII sequence를 같은 message 순서로 구조화했습니다.

===============
USB/IP protocol
===============

Architecture
============

The USB/IP protocol follows a server/client architecture. The server exports the
USB devices and the clients import them. The device driver for the exported
USB device runs on the client machine.

The client may ask for the list of the exported USB devices. To get the list the
client opens a TCP/IP connection to the server, and sends an OP_REQ_DEVLIST
packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent
in one or more pieces at the low level transport layer). The server sends back
the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the
TCP/IP connection is closed.

::

 virtual host controller                                 usb host
      "client"                                           "server"
  (imports USB devices)                             (exports USB devices)
          |                                                 |
          |                  OP_REQ_DEVLIST                 |
          | ----------------------------------------------> |
          |                                                 |
          |                  OP_REP_DEVLIST                 |
          | <---------------------------------------------- |
          |                                                 |

Architecture: import와 URB traffic

32-87

export 목록을 확인한 client는 그중 하나를 사용할 수 있습니다. 먼저 server에 TCP/IP connection을 열고 `OP_REQ_IMPORT` packet을 보내며 server는 `OP_REP_IMPORT`로 응답합니다.

import에 성공하면 TCP/IP connection을 계속 열어 두고 client와 server 사이의 URB traffic 전송에 사용합니다.

client가 보내는 packet은 URB를 제출하는 `USBIP_CMD_SUBMIT`과 이미 제출한 URB를 unlink하는 `USBIP_CMD_UNLINK` 두 종류입니다. server는 각각 `USBIP_RET_SUBMIT`과 `USBIP_RET_UNLINK`로 응답할 수 있습니다.

각 SUBMIT request와 reply는 같은 `seqnum`으로 대응합니다. 여러 request를 연속해서 전송할 수 있으므로 `m`, `m+1`, `m+2` request를 보낸 뒤 reply를 받는 동안 `m+3`, `m+4`를 추가로 보낼 수 있습니다.

Import 후 URB pipeline
Client -> Server: OP_REQ_IMPORTServer -> Client: OP_REP_IMPORT성공한 TCP/IP connection 유지Client -> Server: USBIP_CMD_SUBMIT(seqnum=n)Server -> Client: USBIP_RET_SUBMIT(seqnum=n)여러 seqnum request/reply를 pipeline으로 반복

원문의 import와 pipelined SUBMIT sequence를 구조화했습니다.

USB/IP URB message 쌍
발신응답용도
ClientServerPurpose
USBIP_CMD_SUBMITUSBIP_RET_SUBMITURB 제출과 결과
USBIP_CMD_UNLINKUSBIP_RET_UNLINK기제출 URB unlink와 결과

client command와 server response의 대응입니다.

Once the client knows the list of exported USB devices it may decide to use one
of them. First the client opens a TCP/IP connection to the server and
sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the
import was successful the TCP/IP connection remains open and will be used
to transfer the URB traffic between the client and the server. The client may
send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and
USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the
server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively.

::

 virtual host controller                                 usb host
      "client"                                           "server"
  (imports USB devices)                             (exports USB devices)
          |                                                 |
          |                  OP_REQ_IMPORT                  |
          | ----------------------------------------------> |
          |                                                 |
          |                  OP_REP_IMPORT                  |
          | <---------------------------------------------- |
          |                                                 |
          |                                                 |
          |            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)       |
          | <---------------------------------------------- |
          |                        .                        |
          |                        :                        |

Protocol version

132-139

문서화된 USBIP version은 `v1.1.1`이며 message header의 binary representation은 `0x0111`입니다.

이 값은 `tools/usb/usbip/configure.ac`에 정의되어 있습니다.

USB/IP version encoding
OffsetLengthValue설명
Header20x0111USBIP v1.1.1
Source--tools/usb/usbip/configure.ac

문서 version과 wire header 값입니다.

Protocol Version
================

The documented USBIP version is v1.1.1. The binary representation of this
version in message headers is 0x0111.

This is defined in tools/usb/usbip/configure.ac

OP_REQ_DEVLIST format

140-156

`OP_REQ_DEVLIST`는 export된 USB device 목록을 가져오는 request입니다.

OP_REQ_DEVLIST
OffsetLengthValue설명
02USBIP versionUSBIP version
220x8005export된 USB device 목록을 가져오는 command code
440x00000000사용하지 않는 status이며 반드시 0

모든 multi-byte field는 network byte order입니다.

Message Format
==============

OP_REQ_DEVLIST:
	Retrieve the list of exported USB devices.

+-----------+--------+------------+---------------------------------------------------+
| Offset    | Length | Value      | Description                                       |
+===========+========+============+===================================================+
| 0         | 2      |            | USBIP version                                     |
+-----------+--------+------------+---------------------------------------------------+
| 2         | 2      | 0x8005     | Command code: Retrieve the list of exported USB   |
|           |        |            | devices.                                          |
+-----------+--------+------------+---------------------------------------------------+
| 4         | 4      | 0x00000000 | Status: unused, shall be set to 0                 |
+-----------+--------+------------+---------------------------------------------------+

OP_REP_DEVLIST format

157-227

`OP_REP_DEVLIST`는 export된 USB device 목록을 반환합니다. offset 8의 `n`이 0이면 export된 장치가 없으며 message는 해당 field에서 끝납니다.

장치가 있으면 offset `0x0C`부터 n개의 장치가 이어집니다. 각 장치는 host의 sysfs `path`, `busid`, bus/device number, speed, USB device descriptor field, interface descriptor 묶음으로 기술됩니다.

`path`는 256-byte zero-terminated string이며 예는 `/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2`입니다. `busid`는 32-byte zero-terminated string이며 예는 `3-2`입니다. 두 field의 쓰지 않는 byte는 모두 0으로 채웁니다.

각 interface는 `bInterfaceClass`, `bInterfaceSubClass`, `bInterfaceProtocol`, alignment용 zero padding byte의 4 field로 표현하며 이 묶음을 `bNumInterfaces`번 반복합니다.

두 번째 이후 장치 i는 `0xC + i*0x138 + m_(i-1)*4`에서 path field로 시작합니다. 여기서 `m_(i-1)`은 앞선 장치들의 interface 수가 차지한 4-byte 묶음을 반영합니다.

OP_REP_DEVLIST header
OffsetLengthValue설명
02USBIP versionUSBIP version
220x0005export된 USB device 목록 reply code
440x00000000status; 성공은 0
84nexport된 장치 수; 0이면 없음
0x0Cvariable-n개 장치 설명 시작

장치 목록 전까지의 reply header입니다.

OP_REP_DEVLIST device record
OffsetLengthValue설명
0x0C256pathhost에서 장치의 sysfs path; NUL 종료, 나머지 0
0x10C32busidexport 장치 Bus ID; NUL 종료, 나머지 0
0x12C4busnumbus number
0x1304devnumdevice number
0x1344speedUSB speed
0x1382idVendorvendor ID
0x13A2idProductproduct ID
0x13C2bcdDevicedevice release
0x13E1bDeviceClassdevice class
0x13F1bDeviceSubClassdevice subclass
0x1401bDeviceProtocoldevice protocol
0x1411bConfigurationValueactive configuration
0x1421bNumConfigurationsconfiguration 수
0x1431bNumInterfacesinterface 수

첫 번째 장치 record의 offset과 descriptor field입니다.

OP_REP_DEVLIST interface record
OffsetLengthValue설명
0x144 + k*41bInterfaceClassinterface class
0x145 + k*41bInterfaceSubClassinterface subclass
0x146 + k*41bInterfaceProtocolinterface protocol
0x147 + k*410alignment padding; 반드시 0
0xC + i*0x138 + m_(i-1)*4variablenext pathi=1부터 다음 export 장치 시작

offset 0x144부터 interface마다 반복되는 4-byte 묶음입니다.

OP_REP_DEVLIST:
	Reply with the list of exported USB devices.

+-----------+--------+------------+---------------------------------------------------+
| Offset    | Length | Value      | Description                                       |
+===========+========+============+===================================================+
| 0         | 2      |            | USBIP version                                     |
+-----------+--------+------------+---------------------------------------------------+
| 2         | 2      | 0x0005     | Reply code: The list of exported USB devices.     |
+-----------+--------+------------+---------------------------------------------------+
| 4         | 4      | 0x00000000 | Status: 0 for OK                                  |
+-----------+--------+------------+---------------------------------------------------+
| 8         | 4      | n          | Number of exported devices: 0 means no exported   |
|           |        |            | devices.                                          |
+-----------+--------+------------+---------------------------------------------------+
| 0x0C      |        |            | From now on the exported n devices are described, |
|           |        |            | if any. If no devices are exported the message    |
|           |        |            | ends with the previous "number of exported        |
|           |        |            | devices" field.                                   |
+-----------+--------+------------+---------------------------------------------------+
|           | 256    |            | path: Path of the device on the host exporting the|
|           |        |            | USB device, string closed with zero byte, e.g.    |
|           |        |            | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2"   |
|           |        |            | The unused bytes shall be filled with zero        |
|           |        |            | bytes.                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x10C     | 32     |            | busid: Bus ID of the exported device, string      |
|           |        |            | closed with zero byte, e.g. "3-2". The unused     |
|           |        |            | bytes shall be filled with zero bytes.            |
+-----------+--------+------------+---------------------------------------------------+
| 0x12C     | 4      |            | busnum                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x130     | 4      |            | devnum                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x134     | 4      |            | speed                                             |
+-----------+--------+------------+---------------------------------------------------+
| 0x138     | 2      |            | idVendor                                          |
+-----------+--------+------------+---------------------------------------------------+
| 0x13A     | 2      |            | idProduct                                         |
+-----------+--------+------------+---------------------------------------------------+
| 0x13C     | 2      |            | bcdDevice                                         |
+-----------+--------+------------+---------------------------------------------------+
| 0x13E     | 1      |            | bDeviceClass                                      |
+-----------+--------+------------+---------------------------------------------------+
| 0x13F     | 1      |            | bDeviceSubClass                                   |
+-----------+--------+------------+---------------------------------------------------+
| 0x140     | 1      |            | bDeviceProtocol                                   |
+-----------+--------+------------+---------------------------------------------------+
| 0x141     | 1      |            | bConfigurationValue                               |
+-----------+--------+------------+---------------------------------------------------+
| 0x142     | 1      |            | bNumConfigurations                                |
+-----------+--------+------------+---------------------------------------------------+
| 0x143     | 1      |            | bNumInterfaces                                    |
+-----------+--------+------------+---------------------------------------------------+
| 0x144     |        | m_0        | From now on each interface is described, all      |
|           |        |            | together bNumInterfaces times, with the following |
|           |        |            | 4 fields:                                         |
+-----------+--------+------------+---------------------------------------------------+
|           | 1      |            | bInterfaceClass                                   |
+-----------+--------+------------+---------------------------------------------------+
| 0x145     | 1      |            | bInterfaceSubClass                                |
+-----------+--------+------------+---------------------------------------------------+
| 0x146     | 1      |            | bInterfaceProtocol                                |
+-----------+--------+------------+---------------------------------------------------+
| 0x147     | 1      |            | padding byte for alignment, shall be set to zero  |
+-----------+--------+------------+---------------------------------------------------+
| 0xC +     |        |            | The second exported USB device starts at i=1      |
| i*0x138 + |        |            | with the path field.                              |
| m_(i-1)*4 |        |            |                                                   |
+-----------+--------+------------+---------------------------------------------------+

OP_REQ_IMPORT format

228-246

`OP_REQ_IMPORT`는 remote USB device를 import, 즉 attach하도록 요청합니다.

offset 8의 32-byte `busid`는 remote host가 export한 장치의 Bus ID이며 `OP_REP_DEVLIST.busid`에서 받은 값 중 하나를 사용합니다. string은 zero byte로 끝내고 쓰지 않는 byte는 0으로 채웁니다.

OP_REQ_IMPORT
OffsetLengthValue설명
02USBIP versionUSBIP version
220x8003remote USB device import command code
440x00000000사용하지 않는 status; 반드시 0
832busidOP_REP_DEVLIST.busid에서 선택; NUL 종료, 나머지 0

remote 장치 attach request의 wire layout입니다.

OP_REQ_IMPORT:
	Request to import (attach) a remote USB device.

+-----------+--------+------------+---------------------------------------------------+
| Offset    | Length | Value      | Description                                       |
+===========+========+============+===================================================+
| 0         | 2      |            | USBIP version                                     |
+-----------+--------+------------+---------------------------------------------------+
| 2         | 2      | 0x8003     | Command code: import a remote USB device.         |
+-----------+--------+------------+---------------------------------------------------+
| 4         | 4      | 0x00000000 | Status: unused, shall be set to 0                 |
+-----------+--------+------------+---------------------------------------------------+
| 8         | 32     |            | busid: the busid of the exported device on the    |
|           |        |            | remote host. The possible values are taken        |
|           |        |            | from the message field OP_REP_DEVLIST.busid.      |
|           |        |            | A string closed with zero, the unused bytes       |
|           |        |            | shall be filled with zeros.                       |
+-----------+--------+------------+---------------------------------------------------+

OP_REP_IMPORT format

247-300

`OP_REP_IMPORT`는 remote USB device import 요청에 대한 reply입니다. status는 성공이면 0, error이면 1입니다.

status가 1이면 reply는 status field에서 끝납니다. status가 0이면 offset 8부터 import된 장치의 상세 정보가 이어집니다.

성공 record는 256-byte `path`, 32-byte `busid`, busnum/devnum/speed, USB device descriptor field로 구성됩니다. `path`와 `busid`는 NUL로 끝내고 나머지 byte를 0으로 채웁니다.

OP_REP_IMPORT header
OffsetLengthValue설명
02USBIP versionUSBIP version
220x0003import reply code
440 또는 10=OK, 1=error
8variable-status=0일 때만 imported-device detail 시작

status가 error이면 이 header 뒤에서 message가 끝납니다.

OP_REP_IMPORT success record
OffsetLengthValue설명
8256pathexport host의 sysfs path; NUL 종료, 나머지 0
0x10832busidBus ID; NUL 종료, 나머지 0
0x1284busnumbus number
0x12C4devnumdevice number
0x1304speedUSB speed
0x1342idVendorvendor ID
0x1362idProductproduct ID
0x1382bcdDevicedevice release
0x13A1bDeviceClassdevice class
0x13B1bDeviceSubClassdevice subclass
0x13C1bDeviceProtocoldevice protocol
0x13D1bConfigurationValueactive configuration
0x13E1bNumConfigurationsconfiguration 수
0x13F1bNumInterfacesinterface 수

성공한 import reply의 장치 descriptor입니다.

OP_REP_IMPORT:
	Reply to import (attach) a remote USB device.

+-----------+--------+------------+---------------------------------------------------+
| Offset    | Length | Value      | Description                                       |
+===========+========+============+===================================================+
| 0         | 2      |            | USBIP version                                     |
+-----------+--------+------------+---------------------------------------------------+
| 2         | 2      | 0x0003     | Reply code: Reply to import.                      |
+-----------+--------+------------+---------------------------------------------------+
| 4         | 4      | 0x00000000 | Status:                                           |
|           |        |            |                                                   |
|           |        |            |   - 0 for OK                                      |
|           |        |            |   - 1 for error                                   |
+-----------+--------+------------+---------------------------------------------------+
| 8         |        |            | From now on comes the details of the imported     |
|           |        |            | device, if the previous status field was OK (0),  |
|           |        |            | otherwise the reply ends with the status field.   |
+-----------+--------+------------+---------------------------------------------------+
|           | 256    |            | path: Path of the device on the host exporting the|
|           |        |            | USB device, string closed with zero byte, e.g.    |
|           |        |            | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2"   |
|           |        |            | The unused bytes shall be filled with zero        |
|           |        |            | bytes.                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x108     | 32     |            | busid: Bus ID of the exported device, string      |
|           |        |            | closed with zero byte, e.g. "3-2". The unused     |
|           |        |            | bytes shall be filled with zero bytes.            |
+-----------+--------+------------+---------------------------------------------------+
| 0x128     | 4      |            | busnum                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x12C     | 4      |            | devnum                                            |
+-----------+--------+------------+---------------------------------------------------+
| 0x130     | 4      |            | speed                                             |
+-----------+--------+------------+---------------------------------------------------+
| 0x134     | 2      |            | idVendor                                          |
+-----------+--------+------------+---------------------------------------------------+
| 0x136     | 2      |            | idProduct                                         |
+-----------+--------+------------+---------------------------------------------------+
| 0x138     | 2      |            | bcdDevice                                         |
+-----------+--------+------------+---------------------------------------------------+
| 0x13A     | 1      |            | bDeviceClass                                      |
+-----------+--------+------------+---------------------------------------------------+
| 0x13B     | 1      |            | bDeviceSubClass                                   |
+-----------+--------+------------+---------------------------------------------------+
| 0x13C     | 1      |            | bDeviceProtocol                                   |
+-----------+--------+------------+---------------------------------------------------+
| 0x13D     | 1      |            | bConfigurationValue                               |
+-----------+--------+------------+---------------------------------------------------+
| 0x13E     | 1      |            | bNumConfigurations                                |
+-----------+--------+------------+---------------------------------------------------+
| 0x13F     | 1      |            | bNumInterfaces                                    |
+-----------+--------+------------+---------------------------------------------------+

usbip_header_basic

301-333

다음 네 command는 `usbip_header_basic`이라는 공통 기본 header를 사용합니다. transfer_buffer payload 앞의 전체 header인 `usbip_header`는 네 command에서 길이가 같아야 하므로 짧은 command에는 padding이 필요합니다.

`seqnum`은 request와 대응 response를 식별하는 순차 번호이며 connection마다 증가합니다.

client request의 `devid`는 remote USB device를 고유하게 지정하며 `((busnum << 16) | devnum)`으로 만듭니다. server response에서는 0으로 설정합니다.

`direction`은 `0=USBIP_DIR_OUT`, `1=USBIP_DIR_IN`이며 client만 사용하고 server는 0으로 둡니다. `ep`는 endpoint number로 client만 사용하며 server와 UNLINK에서는 0입니다.

usbip_header_basic
OffsetLengthValue설명
04commandmessage command
44seqnumrequest/response 식별자; connection마다 증가
84devidclient=((busnum << 16) | devnum), server=0
0xC4direction0=USBIP_DIR_OUT, 1=USBIP_DIR_IN; server=0
0x104ependpoint number; server와 UNLINK는 0

모든 USBIP_CMD/RET message 앞에 오는 20-byte header입니다.

The following four commands have a common basic header called
'usbip_header_basic', and their headers, called 'usbip_header' (before
transfer_buffer payload), have the same length, therefore paddings are needed.

usbip_header_basic:

+-----------+--------+---------------------------------------------------+
| Offset    | Length | Description                                       |
+===========+========+===================================================+
| 0         | 4      | command                                           |
+-----------+--------+---------------------------------------------------+
| 4         | 4      | seqnum: sequential number that identifies requests|
|           |        | and corresponding responses;                      |
|           |        | incremented per connection                        |
+-----------+--------+---------------------------------------------------+
| 8         | 4      | devid: specifies a remote USB device uniquely     |
|           |        | instead of busnum and devnum;                     |
|           |        | for client (request), this value is               |
|           |        | ((busnum << 16) | devnum);                        |
|           |        | for server (response), this shall be set to 0     |
+-----------+--------+---------------------------------------------------+
| 0xC       | 4      | direction:                                        |
|           |        |                                                   |
|           |        |    - 0: USBIP_DIR_OUT                             |
|           |        |    - 1: USBIP_DIR_IN                              |
|           |        |                                                   |
|           |        | only used by client, for server this shall be 0   |
+-----------+--------+---------------------------------------------------+
| 0x10      | 4      | ep: endpoint number                               |
|           |        | only used by client, for server this shall be 0;  |
|           |        | for UNLINK, this shall be 0                       |
+-----------+--------+---------------------------------------------------+

USBIP_CMD_SUBMIT

334-374

`USBIP_CMD_SUBMIT`은 URB를 제출하며 `usbip_header_basic.command`는 `0x00000001`입니다.

`transfer_flags` 값은 `USBIP_URB transfer_flags`에 따라 달라집니다. 정의와 의미는 `include/uapi/linux/usbip.h`, `Documentation/driver-api/usb/URB.rst`, `drivers/usb/usbip/usbip_common.c`의 `usbip_pack_cmd_submit()`과 `tweak_transfer_flags()`를 참고합니다.

`transfer_buffer_length`는 URB의 같은 field를 사용합니다. `start_frame`은 ISO transfer의 initial frame이며 ISO가 아니면 0입니다. `number_of_packets`는 ISO packet 수이며 ISO가 아니면 `0xffffffff`입니다.

`interval`은 server-side host controller에서 request의 maximum time이며 `setup`은 USB setup data 8 byte입니다. 사용하지 않으면 0으로 채웁니다.

offset `0x30`의 transfer buffer는 `USBIP_DIR_OUT`일 때 길이가 `transfer_buffer_length`, 그 밖에는 0입니다. ISO transfer에서는 각 ISO packet 사이 padding을 전송하지 않습니다. 그 뒤 `iso_packet_descriptor`가 이어집니다.

USBIP_CMD_SUBMIT
OffsetLengthValue설명
020usbip_header_basiccommand=0x00000001
0x144transfer_flagsUSBIP_URB transfer_flags
0x184transfer_buffer_lengthURB transfer_buffer_length
0x1C4start_frameISO initial frame; non-ISO는 0
0x204number_of_packetsISO packet 수; non-ISO는 0xffffffff
0x244intervalserver host controller의 request maximum time
0x288setupUSB setup bytes; 미사용 시 0
0x30ntransfer_bufferOUT이면 n=transfer_buffer_length, 아니면 0
0x30+nmiso_packet_descriptorISO packet descriptor

URB submit request의 header와 payload layout입니다.

USBIP_CMD_SUBMIT:
	Submit an URB

+-----------+--------+---------------------------------------------------+
| Offset    | Length | Description                                       |
+===========+========+===================================================+
| 0         | 20     | usbip_header_basic, 'command' shall be 0x00000001 |
+-----------+--------+---------------------------------------------------+
| 0x14      | 4      | transfer_flags: possible values depend on the     |
|           |        | USBIP_URB transfer_flags.                         |
|           |        | Refer to include/uapi/linux/usbip.h and           |
|           |        | Documentation/driver-api/usb/URB.rst.             |
|           |        | Refer to usbip_pack_cmd_submit() and              |
|           |        | tweak_transfer_flags() in drivers/usb/usbip/      |
|           |        | usbip_common.c.                                   |
+-----------+--------+---------------------------------------------------+
| 0x18      | 4      | transfer_buffer_length:                           |
|           |        | use URB transfer_buffer_length                    |
+-----------+--------+---------------------------------------------------+
| 0x1C      | 4      | start_frame: use URB start_frame;                 |
|           |        | initial frame for ISO transfer;                   |
|           |        | shall be set to 0 if not ISO transfer             |
+-----------+--------+---------------------------------------------------+
| 0x20      | 4      | number_of_packets: number of ISO packets;         |
|           |        | shall be set to 0xffffffff if not ISO transfer    |
+-----------+--------+---------------------------------------------------+
| 0x24      | 4      | interval: maximum time for the request on the     |
|           |        | server-side host controller                       |
+-----------+--------+---------------------------------------------------+
| 0x28      | 8      | setup: data bytes for USB setup, filled with      |
|           |        | zeros if not used.                                |
+-----------+--------+---------------------------------------------------+
| 0x30      | n      | transfer_buffer.                                  |
|           |        | If direction is USBIP_DIR_OUT then n equals       |
|           |        | transfer_buffer_length; otherwise n equals 0.     |
|           |        | For ISO transfers the padding between each ISO    |
|           |        | packets is not transmitted.                       |
+-----------+--------+---------------------------------------------------+
| 0x30+n    | m      | iso_packet_descriptor                             |
+-----------+--------+---------------------------------------------------+

USBIP_RET_SUBMIT

375-408

`USBIP_RET_SUBMIT`은 URB submit에 대한 reply이며 `usbip_header_basic.command`는 `0x00000003`입니다.

`status`가 0이면 URB transaction 성공이며 0이 아니면 어떤 error가 발생한 것입니다. `actual_length`는 URB data byte 수로 URB의 같은 field를 사용합니다.

`start_frame`과 `number_of_packets`의 ISO/non-ISO 규칙은 SUBMIT과 같습니다. `error_count` 뒤의 8 byte는 padding이며 반드시 0입니다.

offset `0x30`의 transfer buffer는 `USBIP_DIR_IN`이면 길이가 `actual_length`, 그 밖에는 0입니다. ISO packet 사이 padding은 전송하지 않으며 뒤에 `iso_packet_descriptor`가 이어집니다.

USBIP_RET_SUBMIT
OffsetLengthValue설명
020usbip_header_basiccommand=0x00000003
0x144status0=성공, 그 밖에는 error
0x184actual_lengthURB actual_length
0x1C4start_frameISO initial frame; non-ISO는 0
0x204number_of_packetsISO packet 수; non-ISO는 0xffffffff
0x244error_countURB error count
0x288padding반드시 0
0x30ntransfer_bufferIN이면 n=actual_length, 아니면 0
0x30+nmiso_packet_descriptorISO packet descriptor

URB submit reply의 header와 payload layout입니다.

USBIP_RET_SUBMIT:
	Reply for submitting an URB

+-----------+--------+---------------------------------------------------+
| Offset    | Length | Description                                       |
+===========+========+===================================================+
| 0         | 20     | usbip_header_basic, 'command' shall be 0x00000003 |
+-----------+--------+---------------------------------------------------+
| 0x14      | 4      | status: zero for successful URB transaction,      |
|           |        | otherwise some kind of error happened.            |
+-----------+--------+---------------------------------------------------+
| 0x18      | 4      | actual_length: number of URB data bytes;          |
|           |        | use URB actual_length                             |
+-----------+--------+---------------------------------------------------+
| 0x1C      | 4      | start_frame: use URB start_frame;                 |
|           |        | initial frame for ISO transfer;                   |
|           |        | shall be set to 0 if not ISO transfer             |
+-----------+--------+---------------------------------------------------+
| 0x20      | 4      | number_of_packets: number of ISO packets;         |
|           |        | shall be set to 0xffffffff if not ISO transfer    |
+-----------+--------+---------------------------------------------------+
| 0x24      | 4      | error_count                                       |
+-----------+--------+---------------------------------------------------+
| 0x28      | 8      | padding, shall be set to 0                        |
+-----------+--------+---------------------------------------------------+
| 0x30      | n      | transfer_buffer.                                  |
|           |        | If direction is USBIP_DIR_IN then n equals        |
|           |        | actual_length; otherwise n equals 0.              |
|           |        | For ISO transfers the padding between each ISO    |
|           |        | packets is not transmitted.                       |
+-----------+--------+---------------------------------------------------+
| 0x30+n    | m      | iso_packet_descriptor                             |
+-----------+--------+---------------------------------------------------+

HID wire capture 예

439-452

마지막 data는 Human Interface Device(HID) payload를 wire에서 capture한 예입니다.

`CmdIntrIN`과 `CmdIntrOUT`은 command `00000001`, 즉 `USBIP_CMD_SUBMIT`이며 각각 direction `00000001`과 `00000000`을 가집니다. `RetIntrOut`과 `RetIntrIn`은 command `00000003`, 즉 `USBIP_RET_SUBMIT`입니다.

`CmdIntrOUT`과 `RetIntrIn`에는 header 다음의 실제 hexadecimal payload가 이어집니다. 아래 접을 수 있는 원문 block은 capture byte를 줄바꿈과 값까지 그대로 보존합니다.

HID capture message
LabelCommandDirection/payloadSequence
CmdIntrINUSBIP_CMD_SUBMITIN requestseqnum=00000d05
CmdIntrOUTUSBIP_CMD_SUBMITOUT request + payloadseqnum=00000d06
RetIntrOutUSBIP_RET_SUBMITOUT replyseqnum=00000d06
RetIntrInUSBIP_RET_SUBMITIN reply + payloadseqnum=00000d05

예제의 네 message label과 protocol 역할입니다.

EXAMPLE
=======

  The following data is captured from wire with Human Interface Devices (HID)
  payload

::

  CmdIntrIN:  00000001 00000d05 0001000f 00000001 00000001 00000200 00000040 ffffffff 00000000 00000004 00000000 00000000
  CmdIntrOUT: 00000001 00000d06 0001000f 00000000 00000001 00000000 00000040 ffffffff 00000000 00000004 00000000 00000000
              ffffffff860008a784ce5ae212376300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  RetIntrOut: 00000003 00000d06 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
  RetIntrIn:  00000003 00000d05 00000000 00000000 00000000 00000000 00000040 ffffffff 00000000 00000000 00000000 00000000
              ffffffff860011a784ce5ae2123763612891b1020100000400000000000000000000000000000000000000000000000000000000000000000000000000000000