/src/wireshark/epan/dissectors/packet-mausb.c
Line | Count | Source |
1 | | /* packet-mausb.c |
2 | | * Routines for Media Agnostic USB dissection |
3 | | * Copyright 2014, Intel Corporation |
4 | | * Author: Sean O. Stalley <sean.stalley@intel.com> |
5 | | * |
6 | | * Dedicated to Robert & Dorothy Stalley |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@wireshark.org> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/expert.h> |
19 | | #include <epan/oui.h> |
20 | | #include "packet-tcp.h" |
21 | | #include "packet-llc.h" |
22 | | #include "packet-usb.h" |
23 | | #include "packet-mausb.h" |
24 | | |
25 | | void proto_reg_handoff_mausb(void); |
26 | | void proto_register_mausb(void); |
27 | | |
28 | | static dissector_handle_t mausb_tcp_handle; |
29 | | static dissector_handle_t mausb_pkt_handle; |
30 | | |
31 | | /* For SNAP Packets */ |
32 | | static int hf_llc_mausb_pid; |
33 | | |
34 | | /* Initialize the protocol and registered fields */ |
35 | | static int proto_mausb; |
36 | | static int hf_mausb_version; |
37 | | static int hf_mausb_flags; |
38 | | static int hf_mausb_flag_host; |
39 | | static int hf_mausb_flag_retry; |
40 | | static int hf_mausb_flag_timestamp; |
41 | | static int hf_mausb_flag_reserved; |
42 | | |
43 | | |
44 | | static int * const mausb_flag_fields[] = { |
45 | | &hf_mausb_flag_host, |
46 | | &hf_mausb_flag_retry, |
47 | | &hf_mausb_flag_timestamp, |
48 | | &hf_mausb_flag_reserved, |
49 | | NULL |
50 | | }; |
51 | | |
52 | | static int hf_mausb_type; |
53 | | static int hf_mausb_length; |
54 | | static int hf_mausb_dev_handle; |
55 | | static int hf_mausb_ep_handle; |
56 | | static int hf_mausb_ep_handle_d; |
57 | | static int hf_mausb_ep_handle_ep_num; |
58 | | static int hf_mausb_ep_handle_dev_addr; |
59 | | static int hf_mausb_ep_handle_bus_num; |
60 | | static int hf_mausb_ma_dev_addr; |
61 | | static int hf_mausb_ssid; |
62 | | static int hf_mausb_status; |
63 | | |
64 | | /* management packet specific */ |
65 | | static int hf_mausb_token; |
66 | | static int hf_mausb_mgmt_pad; |
67 | | static int hf_mausb_mgmt_ep_handle_num; |
68 | | static int hf_mausb_mgmt_ep_handle_pad; |
69 | | static int hf_mausb_mgmt_ep_des_num; |
70 | | static int hf_mausb_mgmt_ep_des_size; |
71 | | static int hf_mausb_mgmt_ep_des_pad; |
72 | | static int hf_mausb_mgmt_type_spec; |
73 | | static int hf_mausb_mgmt_type_spec_generic; |
74 | | |
75 | | /* CapResp packet specific */ |
76 | | static int hf_mausb_cap_resp_num_ep; |
77 | | static int hf_mausb_cap_resp_num_dev; |
78 | | static int hf_mausb_cap_resp_num_stream; |
79 | | static int hf_mausb_cap_resp_dev_type; |
80 | | static int hf_mausb_cap_resp_desc_count; |
81 | | static int hf_mausb_cap_resp_desc_len; |
82 | | static int hf_mausb_cap_resp_transfer_req; |
83 | | static int hf_mausb_cap_resp_mgmt_req; |
84 | | static int hf_mausb_cap_resp_rsvd; |
85 | | |
86 | | static int hf_mausb_dev_cap_len; |
87 | | static int hf_mausb_dev_cap_type; |
88 | | static int hf_mausb_dev_cap_generic; |
89 | | |
90 | | /* EPHandleReq & Resp packet specific */ |
91 | | static int hf_mausb_ep_handle_req_pad; |
92 | | static int hf_mausb_ep_handle_resp_dir; |
93 | | static int hf_mausb_ep_handle_resp_iso; |
94 | | static int hf_mausb_ep_handle_resp_lman; |
95 | | static int hf_mausb_ep_handle_resp_valid; |
96 | | static int hf_mausb_ep_handle_resp_ccu; |
97 | | static int hf_mausb_ep_handle_resp_buf_size; |
98 | | static int hf_mausb_ep_handle_resp_iso_prog_dly; |
99 | | static int hf_mausb_ep_handle_resp_iso_resp_dly; |
100 | | |
101 | | /* (Clear/Cancel)TransferReq & Resp packet specific */ |
102 | | static int hf_mausb_clear_transfers_info_block; |
103 | | static int hf_mausb_clear_transfers_status_block; |
104 | | static int hf_mausb_cancel_transfer_rsvd; |
105 | | static int hf_mausb_clear_transfers_req_num; |
106 | | static int hf_mausb_clear_transfers_req_rsvd; |
107 | | static int hf_mausb_clear_transfers_resp_num; |
108 | | static int hf_mausb_clear_transfers_resp_rsvd; |
109 | | static int hf_mausb_cancel_transfer_status; |
110 | | static int hf_mausb_cancel_transfer_rsvd_2; |
111 | | static int hf_mausb_clear_transfers_status; |
112 | | static int hf_mausb_clear_transfers_partial; |
113 | | static int hf_mausb_clear_transfers_start_req_id; |
114 | | static int hf_mausb_clear_transfers_last_req_id; |
115 | | static int hf_mausb_clear_transfers_req_block_rsvd; |
116 | | static int hf_mausb_clear_transfers_resp_block_rsvd; |
117 | | static int hf_mausb_cancel_transfer_seq_num; |
118 | | static int hf_mausb_cancel_transfer_byte_offset; |
119 | | |
120 | | /* data packet specific */ |
121 | | static int hf_mausb_eps; |
122 | | static int hf_mausb_eps_rsvd; |
123 | | static int hf_mausb_tflags; |
124 | | static int hf_mausb_tflag_arq; |
125 | | static int hf_mausb_tflag_neg; |
126 | | static int hf_mausb_tflag_eot; |
127 | | static int hf_mausb_tflag_type; |
128 | | static int hf_mausb_tflag_rsvd; |
129 | | |
130 | | static int * const mausb_tflag_fields[] = { |
131 | | &hf_mausb_tflag_arq, |
132 | | &hf_mausb_tflag_neg, |
133 | | &hf_mausb_tflag_eot, |
134 | | &hf_mausb_tflag_type, |
135 | | &hf_mausb_tflag_rsvd, |
136 | | NULL |
137 | | }; |
138 | | |
139 | | static int hf_mausb_num_iso_hdr; |
140 | | static int hf_mausb_iflags; |
141 | | static int hf_mausb_iflag_mtd; |
142 | | static int hf_mausb_iflag_hdr_format; |
143 | | static int hf_mausb_iflag_asap; |
144 | | |
145 | | static int * const mausb_iflag_fields[] = { |
146 | | &hf_mausb_iflag_mtd, |
147 | | &hf_mausb_iflag_hdr_format, |
148 | | &hf_mausb_iflag_asap, |
149 | | NULL |
150 | | }; |
151 | | |
152 | | static int hf_mausb_stream_id; |
153 | | static int hf_mausb_seq_num; |
154 | | static int hf_mausb_req_id; |
155 | | static int hf_mausb_present_time; |
156 | | static int hf_mausb_uframe; |
157 | | static int hf_mausb_frame; |
158 | | static int hf_mausb_num_segs; |
159 | | |
160 | | static int hf_mausb_timestamp; |
161 | | static int hf_mausb_delta; |
162 | | static int hf_mausb_nom_interval; |
163 | | |
164 | | |
165 | | |
166 | | static int hf_mausb_mtd; |
167 | | static int hf_mausb_rem_size_credit; |
168 | | |
169 | | /* expert info fields */ |
170 | | static expert_field ei_ep_handle_len; |
171 | | static expert_field ei_len; |
172 | | static expert_field ei_mgmt_type_undef; |
173 | | static expert_field ei_mgmt_type_spec_len_long; |
174 | | static expert_field ei_mgmt_type_spec_len_short; |
175 | | static expert_field ei_dev_cap_len; |
176 | | static expert_field ei_dev_cap_resp_desc_len; |
177 | | static expert_field ei_cap_resp_desc_len; |
178 | | |
179 | | /* MAUSB Version, per 6.2.1.1 */ |
180 | | #define MAUSB_VERSION_1_0 0x0 |
181 | 16 | #define MAUSB_VERSION_MASK 0x0F |
182 | | |
183 | | /* for dissecting snap packets */ |
184 | | /* |
185 | | * TODO: determine assigned PID value |
186 | | * (yet to be assigned as of Earth Day 2014) |
187 | | */ |
188 | 16 | #define PID_MAUSB 0x1500 |
189 | | |
190 | | static const value_string mausb_pid_string[] = { |
191 | | { PID_MAUSB, "MAUSB" }, |
192 | | { 0, NULL} |
193 | | }; |
194 | | |
195 | | static const value_string mausb_version_string[] = { |
196 | | { MAUSB_VERSION_1_0, "MAUSB protocol version 1.0" }, |
197 | | { 0, NULL} |
198 | | }; |
199 | | |
200 | | /* Packet flags, per 6.2.1.2 */ |
201 | 16 | #define MAUSB_FLAG_MASK 0xF0 |
202 | 16 | #define MAUSB_FLAG_HOST (1 << 0) |
203 | 16 | #define MAUSB_FLAG_RETRY (1 << 1) |
204 | 16 | #define MAUSB_FLAG_TIMESTAMP (1 << 2) |
205 | 16 | #define MAUSB_FLAG_RESERVED (1 << 3) |
206 | 64 | #define MAUSB_FLAG_OFFSET 4 |
207 | | |
208 | | /* Packet Types, per 6.2.1.3 */ |
209 | 0 | #define MAUSB_PKT_TYPE_MASK 0xC0 |
210 | 0 | #define MAUSB_PKT_TYPE_MGMT (0 << 6) |
211 | | #define MAUSB_PKT_TYPE_CTRL (1 << 6) |
212 | 0 | #define MAUSB_PKT_TYPE_DATA (2 << 6) |
213 | | |
214 | | /* Packet Subtypes, per 6.2.1.3 */ |
215 | | #define MAUSB_SUBTYPE_MASK 0x3F |
216 | | |
217 | | enum mausb_pkt_type { |
218 | | /* Management packets */ |
219 | | CapReq = 0x00 | MAUSB_PKT_TYPE_MGMT, |
220 | | CapResp , |
221 | | USBDevHandleReq , |
222 | | USBDevHandleResp , |
223 | | EPHandleReq , |
224 | | EPHandleResp , |
225 | | EPActivateReq , |
226 | | EPActivateResp , |
227 | | EPInactivateReq , |
228 | | EPInactivateResp , |
229 | | EPResetReq , |
230 | | EPResetResp , |
231 | | ClearTransfersReq , |
232 | | ClearTransfersResp , |
233 | | EPHandleDeleteReq , |
234 | | EPHandleDeleteResp , |
235 | | |
236 | | DevResetReq , |
237 | | DevResetResp , |
238 | | ModifyEP0Req , |
239 | | ModifyEP0Resp , |
240 | | SetUSBDevAddrReq , |
241 | | SetUSBDevAddrResp , |
242 | | UpdateDevReq , |
243 | | UpdateDevResp , |
244 | | USBDevDisconnectReq , |
245 | | USBDevDisconnectResp , |
246 | | USBSuspendReq , |
247 | | USBSuspendResp , |
248 | | USBResumeReq , |
249 | | USBResumeResp , |
250 | | RemoteWakeReq , |
251 | | RemoteWakeResp , |
252 | | |
253 | | PingReq , |
254 | | PingResp , |
255 | | DevDisconnectReq , |
256 | | DevDisconnectResp , |
257 | | DevInitDisconnectReq , |
258 | | DevInitDisconnectResp , |
259 | | SynchReq , |
260 | | SynchResp , |
261 | | CancelTransferReq , |
262 | | CancelTransferResp , |
263 | | EPOpenStreamReq , |
264 | | EPOpenStreamResp , |
265 | | EPCloseStreamReq , |
266 | | EPCloseStreamResp , |
267 | | USBDevResetReq , |
268 | | USBDevResetResp , |
269 | | |
270 | | DevNotificationReq , |
271 | | DevNotificationResp , |
272 | | EPSetKeepAliveReq , |
273 | | EPSetKeepAliveResp , |
274 | | GetPortBWReq , |
275 | | GetPortBWResp , |
276 | | SleepReq , |
277 | | SleepResp , |
278 | | WakeReq , |
279 | | WakeResp , |
280 | | |
281 | | /* Vendor-Specific Management Packets */ |
282 | | VendorSpecificReq = 0x3E | MAUSB_PKT_TYPE_MGMT, |
283 | | VendorSpecificResp , |
284 | | |
285 | | /* Control Packets */ |
286 | | TransferSetupReq = MAUSB_PKT_TYPE_CTRL, |
287 | | TransferSetupResp , |
288 | | TransferTearDownConf , |
289 | | |
290 | | /* Data Packets */ |
291 | | TransferReq = MAUSB_PKT_TYPE_DATA, |
292 | | TransferResp , |
293 | | TransferAck , |
294 | | IsochTransferReq , |
295 | | IsochTransferResp |
296 | | }; |
297 | | |
298 | | |
299 | | /** |
300 | | * Type & Subtype values for MAUSB packet variants, per 6.2.1.3, Table 5 |
301 | | */ |
302 | | static const value_string mausb_type_string[] = { |
303 | | /* Management packets */ |
304 | | { CapReq , "CapReq" }, |
305 | | { CapResp , "CapResp" }, |
306 | | { USBDevHandleReq , "USBDevHandleReq" }, |
307 | | { USBDevHandleResp , "USBDevHandleResp" }, |
308 | | { EPHandleReq , "EPHandleReq" }, |
309 | | { EPHandleResp , "EPHandleResp" }, |
310 | | { EPActivateReq , "EPActivateReq" }, |
311 | | { EPActivateResp , "EPActivateResp" }, |
312 | | { EPInactivateReq , "EPInactivateReq" }, |
313 | | { EPInactivateResp , "EPInactivateResp" }, |
314 | | { EPResetReq , "EPResetReq" }, |
315 | | { EPResetResp , "EPResetResp" }, |
316 | | { ClearTransfersReq , "ClearTransfersReq" }, |
317 | | { ClearTransfersResp , "ClearTransfersResp" }, |
318 | | { EPHandleDeleteReq , "EPHandleDeleteReq" }, |
319 | | { EPHandleDeleteResp , "EPHandleDeleteResp" }, |
320 | | |
321 | | { DevResetReq , "DevResetReq" }, |
322 | | { DevResetResp , "DevResetResp" }, |
323 | | { ModifyEP0Req , "ModifyEP0Req" }, |
324 | | { ModifyEP0Resp , "ModifyEP0Resp" }, |
325 | | { SetUSBDevAddrReq , "SetUSBDevAddrReq" }, |
326 | | { SetUSBDevAddrResp , "SetUSBDevAddrResp" }, |
327 | | { UpdateDevReq , "UpdateDevReq" }, |
328 | | { UpdateDevResp , "UpdateDevResp" }, |
329 | | { USBDevDisconnectReq , "USBDevDisconnectReq" }, |
330 | | { USBDevDisconnectResp , "USBDevDisconnectResp" }, |
331 | | { USBSuspendReq , "USBSuspendReq" }, |
332 | | { USBSuspendResp , "USBSuspendResp" }, |
333 | | { USBResumeReq , "USBResumeReq" }, |
334 | | { USBResumeResp , "USBResumeResp" }, |
335 | | { RemoteWakeReq , "RemoteWakeReq" }, |
336 | | { RemoteWakeResp , "RemoteWakeResp" }, |
337 | | |
338 | | { PingReq , "PingReq" }, |
339 | | { PingResp , "PingResp" }, |
340 | | { DevDisconnectReq , "DevDisconnectReq " }, |
341 | | { DevDisconnectResp , "DevDisconnectResp" }, |
342 | | { DevInitDisconnectReq , "DevInitDisconnectReq" }, |
343 | | { DevInitDisconnectResp, "DevInitDisconnectResp" }, |
344 | | { SynchReq , "SynchReq" }, |
345 | | { SynchResp , "SynchResp" }, |
346 | | { CancelTransferReq , "CancelTransferReq" }, |
347 | | { CancelTransferResp , "CancelTransferResp" }, |
348 | | { EPOpenStreamReq , "EPOpenStreamReq" }, |
349 | | { EPOpenStreamResp , "EPOpenStreamResp" }, |
350 | | { EPCloseStreamReq , "EPCloseStreamReq" }, |
351 | | { EPCloseStreamResp , "EPCloseStreamResp" }, |
352 | | { USBDevResetReq , "USBDevResetReq" }, |
353 | | { USBDevResetResp , "USBDevResetResp" }, |
354 | | |
355 | | { DevNotificationReq , "DevNotificationReq" }, |
356 | | { DevNotificationResp , "DevNotificationResp" }, |
357 | | { EPSetKeepAliveReq , "EPSetKeepAliveReq" }, |
358 | | { EPSetKeepAliveResp , "EPSetKeepAliveResp" }, |
359 | | { GetPortBWReq , "GetPortBWReq" }, |
360 | | { GetPortBWResp , "GetPortBWResp" }, |
361 | | { SleepReq , "SleepReq" }, |
362 | | { SleepResp , "SleepResp" }, |
363 | | { WakeReq , "WakeReq" }, |
364 | | { WakeResp , "WakeResp" }, |
365 | | |
366 | | /* Vendor-Specific Management Packets */ |
367 | | { VendorSpecificReq , "VendorSpecificReq" }, |
368 | | { VendorSpecificResp , "VendorSpecificResp" }, |
369 | | |
370 | | /* Control Packets */ |
371 | | { TransferSetupReq , "TransferSetupReq" }, |
372 | | { TransferSetupResp , "TransferSetupResp" }, |
373 | | { TransferTearDownConf , "TransferTearDownConf" }, |
374 | | |
375 | | /* Data Packets */ |
376 | | { TransferReq , "TransferReq" }, |
377 | | { TransferResp , "TransferResp" }, |
378 | | { TransferAck , "TransferAck" }, |
379 | | { IsochTransferReq , "IsochTransferReq" }, |
380 | | { IsochTransferResp , "IsochTransferResp" }, |
381 | | { 0, NULL} |
382 | | }; |
383 | | |
384 | 16 | #define MAUSB_EP_HANDLE_D 0x0001 |
385 | 16 | #define MAUSB_EP_HANDLE_EP_NUM 0x001e |
386 | 16 | #define MAUSB_EP_HANDLE_DEV_ADDR 0x0fe0 |
387 | 16 | #define MAUSB_EP_HANDLE_BUS_NUM 0xf000 |
388 | | |
389 | 0 | #define MAUSB_EP_HANDLE_D_OFFSET 0 |
390 | 0 | #define MAUSB_EP_HANDLE_EP_NUM_OFFSET 1 |
391 | 0 | #define MAUSB_EP_HANDLE_DEV_ADDR_OFFSET 5 |
392 | 0 | #define MAUSB_EP_HANDLE_BUS_NUM_OFFSET 12 |
393 | | |
394 | | static const value_string mausb_status_string[] = { |
395 | | { 0, "SUCCESS (NO_ERROR)" }, |
396 | | { 128, "UNSUCCESSFUL" }, |
397 | | { 129, "INVALID_MA_USB_SESSION_STATE" }, |
398 | | { 130, "INVALID_DEVICE_HANDLE" }, |
399 | | { 131, "INVALID_EP_HANDLE" }, |
400 | | { 132, "INVALID_EP_HANDLE_STATE" }, |
401 | | { 133, "INVALID_REQUEST" }, |
402 | | { 134, "MISSING_SEQUENCE_NUMBER" }, |
403 | | { 135, "TRANSFER_PENDING" }, |
404 | | { 136, "TRANSFER_EP_STALL" }, |
405 | | { 137, "TRANSFER_SIZE_ERROR" }, |
406 | | { 138, "TRANSFER_DATA_BUFFER_ERROR" }, |
407 | | { 139, "TRANSFER_BABBLE_DETECTED" }, |
408 | | { 140, "TRANSFER_TRANSACTION_ERROR" }, |
409 | | { 141, "TRANSFER_SHORT_TRANSFER" }, |
410 | | { 142, "TRANSFER_CANCELLED" }, |
411 | | { 143, "INSUFFICIENT_RESOURCES" }, |
412 | | { 144, "NOT_SUFFICIENT_BANDWIDTH" }, |
413 | | { 145, "INTERNAL_ERROR" }, |
414 | | { 146, "DATA_OVERRUN" }, |
415 | | { 147, "DEVICE_NOT_ACCESSED" }, |
416 | | { 148, "BUFFER_OVERRUN" }, |
417 | | { 149, "BUSY" }, |
418 | | { 150, "DROPPED_PACKET" }, |
419 | | { 151, "ISOC_TIME_EXPIRED" }, |
420 | | { 152, "ISOCH_TIME_INVALID" }, |
421 | | { 153, "NO_USB_PING_RESPONSE" }, |
422 | | { 154, "NOT_SUPPORTED" }, |
423 | | { 155, "REQUEST_DENIED" }, |
424 | | { 156, "MISSING_REQUEST_ID" }, |
425 | | { 0, NULL} |
426 | | }; |
427 | | |
428 | | |
429 | | /* Number of Isochronous Headers, per 6.5.1.7 */ |
430 | 16 | #define MAUSB_NUM_ISO_HDR_MASK 0x0fff |
431 | | |
432 | | /* I-Flags, per 6.5.1.8 */ |
433 | 16 | #define MAUSB_IFLAG_ASAP (1 << 0) |
434 | 16 | #define MAUSB_IFLAG_HDR_FORMAT (3 << 1) |
435 | 16 | #define MAUSB_IFLAG_MTD (1 << 3) |
436 | 64 | #define MAUSB_IFLAG_OFFSET 12 |
437 | 16 | #define MAUSB_IFLAG_MASK (0xF << MAUSB_IFLAG_OFFSET) |
438 | | |
439 | | /* Presentation Time, per 6.5.1.9 */ |
440 | 16 | #define MAUSB_PRESENT_TIME_MASK 0x000fffff |
441 | 16 | #define MAUSB_UFRAME_MASK 0x00000007 |
442 | 16 | #define MAUSB_FRAME_MASK 0x000ffff8 |
443 | | |
444 | | /* Number of Segments, per 6.5.1.10 */ |
445 | 16 | #define MAUSB_NUM_SEGS_MASK 0xfff00000 |
446 | | |
447 | | /* MA USB Global Time fields, per 6.6.1 */ |
448 | 16 | #define MAUSB_DELTA_MASK 0x00000fff |
449 | 16 | #define MAUSB_INTERVAL_MASK 0xfffff000 |
450 | | |
451 | | |
452 | | |
453 | 16 | #define MAUSB_TOKEN_MASK 0x03ff |
454 | 16 | #define MAUSB_MGMT_PAD_MASK 0xfffc |
455 | 32 | #define MAUSB_MGMT_NUM_EP_DES_MASK 0x1f |
456 | 16 | #define MAUSB_MGMT_SIZE_EP_DES_OFFSET 5 |
457 | 16 | #define MAUSB_MGMT_SIZE_EP_DES_MASK (0x003f << MAUSB_MGMT_SIZE_EP_DES_OFFSET) |
458 | | |
459 | 0 | #define MAUSB_MGMT_CLEAR_TRANSFER_RESP_NUM_MASK 0x1f |
460 | | |
461 | | /* CapResp Bitfield Masks */ |
462 | 16 | #define MAUSB_CAP_RESP_NUM_STREAM_MASK 0x1f |
463 | 16 | #define MAUSB_CAP_RESP_DEV_TYPE_OFFSET 5 |
464 | 16 | #define MAUSB_CAP_RESP_DEV_TYPE_MASK (0x07 << MAUSB_CAP_RESP_DEV_TYPE_OFFSET) |
465 | 16 | #define MAUSB_CAP_RESP_MGMT_REQ_MASK 0x0fff |
466 | 16 | #define MAUSB_CAP_RESP_RSVD_MASK 0xf000 |
467 | | |
468 | | static const value_string mausb_cap_resp_dev_type[] = { |
469 | | { 0, "Integrated Device" }, |
470 | | { 1, "MAUSB 2.0 hub" }, |
471 | | { 2, "MAUSB 3.1 hub" }, |
472 | | { 0, NULL} |
473 | | }; |
474 | | |
475 | | static const value_string mausb_dev_cap_string[] = { |
476 | | { 0, "Speed Capability" }, |
477 | | { 1, "P-managed OUT Capabilities" }, |
478 | | { 2, "Isochronous Capabilities" }, |
479 | | { 3, "Synchronization Capabilities" }, |
480 | | { 4, "Container ID Capability" }, |
481 | | { 5, "Link Sleep Capability" }, |
482 | | { 0, NULL} |
483 | | }; |
484 | | |
485 | | enum mausb_dev_cap_type { |
486 | | SpeedCap = 0, |
487 | | PmanCap, |
488 | | IsoCap, |
489 | | SyncCap, |
490 | | ContainerIDCap, |
491 | | LinkSleepCap |
492 | | }; |
493 | | |
494 | | #define DWORD_MASK 0xffffffff |
495 | | #define MAUSB_MGMT_NUM_EP_HANDLE_PAD_MASK \ |
496 | | (DWORD_MASK & !(MAUSB_MGMT_NUM_EP_DES_MASK)) |
497 | | #define MAUSB_MGMT_EP_DES_PAD_MASK \ |
498 | | ((DWORD_MASK & !(MAUSB_MGMT_NUM_EP_DES_MASK | \ |
499 | | MAUSB_MGMT_SIZE_EP_DES_MASK)) >> 8) |
500 | | |
501 | | |
502 | | /* EPHandleResp Bitfield Masks */ |
503 | 16 | #define MAUSB_EP_HANDLE_RESP_DIR_MASK (1 << 0) |
504 | 16 | #define MAUSB_EP_HANDLE_RESP_ISO_MASK (1 << 1) |
505 | 16 | #define MAUSB_EP_HANDLE_RESP_LMAN_MASK (1 << 2) |
506 | 16 | #define MAUSB_EP_HANDLE_RESP_VALID_MASK (1 << 3) |
507 | | |
508 | | static const value_string mausb_eps_string[] = { |
509 | | { 0, "Unassigned" }, |
510 | | { 1, "Active" }, |
511 | | { 2, "Inactive" }, |
512 | | { 3, "Halted" }, |
513 | | { 0, NULL} |
514 | | }; |
515 | | |
516 | 32 | #define MAUSB_EPS_MASK 0x03 |
517 | | |
518 | 16 | #define MAUSB_TFLAG_MASK 0xfc |
519 | | |
520 | 0 | #define MAUSB_TX_TYPE_CTRL (0 << 3) |
521 | 0 | #define MAUSB_TX_TYPE_ISOC (1 << 3) |
522 | 0 | #define MAUSB_TX_TYPE_BULK (2 << 3) |
523 | 0 | #define MAUSB_TX_TYPE_INTR (3 << 3) |
524 | | |
525 | 80 | #define MAUSB_TFLAG_OFFSET 2 |
526 | 16 | #define MAUSB_TFLAG_ARQ (1 << 0) |
527 | 16 | #define MAUSB_TFLAG_NEG (1 << 1) |
528 | 16 | #define MAUSB_TFLAG_EOT (1 << 2) |
529 | 16 | #define MAUSB_TFLAG_TRANSFER_TYPE (3 << 3) |
530 | 16 | #define MAUSB_TFLAG_RSVD (1 << 5) |
531 | | |
532 | | static const value_string mausb_transfer_type_string[] = { |
533 | | { 0, "Control" }, |
534 | | { 1, "Isochronous" }, |
535 | | { 2, "Bulk" }, |
536 | | { 3, "Interrupt" }, |
537 | | { 0, NULL} |
538 | | }; |
539 | | |
540 | | static const true_false_string tfs_ep_handle_resp_dir = { "IN", "OUT or Control" }; |
541 | | |
542 | | #define MAUSB_TRANSFER_TYPE_OFFSET 3 /* Offset from start of TFlags Field */ |
543 | | /* (EPS not included) */ |
544 | | #define MAUSB_TRANSFER_TYPE_CTRL (0 << MAUSB_TRANSFER_TYPE_OFFSET) |
545 | | #define MAUSB_TRANSFER_TYPE_ISO (1 << MAUSB_TRANSFER_TYPE_OFFSET) |
546 | | #define MAUSB_TRANSFER_TYPE_BULK (2 << MAUSB_TRANSFER_TYPE_OFFSET) |
547 | | #define MAUSB_TRANSFER_TYPE_INTERRUPT (3 << MAUSB_TRANSFER_TYPE_OFFSET) |
548 | | |
549 | | static const value_string mausb_cancel_transfer_status_string[] = { |
550 | | { 0, "Cancel Unsuccessful"}, |
551 | | { 1, "Canceled before any data was moved"}, |
552 | | { 2, "Canceled after some data was moved"}, |
553 | | { 3, "Transfer completed"}, |
554 | | { 4, "Transfer not yet received"}, |
555 | | { 5, "Transfer cleared without any data moved"}, |
556 | | { 0, NULL} |
557 | | }; |
558 | | |
559 | 32 | #define MAUSB_CANCEL_TRANSFER_STATUS_MASK 0x07 |
560 | | |
561 | 32 | #define MAUSB_CLEAR_TRANSFERS_RESP_NUM_MASK 0x1f |
562 | 16 | #define MAUSB_CLEAR_TRANSFERS_STATUS_MASK 0x01 |
563 | 16 | #define MAUSB_CLEAR_TRANSFERS_PARTIAL_MASK 0x02 |
564 | 16 | #define MAUSB_CLEAR_TRANSFERS_RESP_BLOCK_RSVD_MASK 0xfffffffc |
565 | | |
566 | | |
567 | | /* We need at least the first DWORD to determine the packet length (for TCP) */ |
568 | 0 | #define MAUSB_MIN_LENGTH 4 |
569 | | |
570 | | #define MAUSB_MIN_MGMT_LENGTH 12 |
571 | | #define MAUSB_MIN_DATA_LENGTH 20 |
572 | | #define MAUSB_COMMON_LEN 9 |
573 | | |
574 | | |
575 | | /*** Packet parsing helper functions ***/ |
576 | | |
577 | | bool mausb_is_from_host(struct mausb_header *header) |
578 | 0 | { |
579 | 0 | return (MAUSB_FLAG_HOST << MAUSB_FLAG_OFFSET) & header->ver_flags; |
580 | 0 | } |
581 | | |
582 | | static bool mausb_is_mgmt_pkt(struct mausb_header *header) |
583 | 0 | { |
584 | 0 | return MAUSB_PKT_TYPE_MGMT == (header->type & MAUSB_PKT_TYPE_MASK); |
585 | 0 | } |
586 | | |
587 | | static bool mausb_is_data_pkt(struct mausb_header *header) |
588 | 0 | { |
589 | 0 | return MAUSB_PKT_TYPE_DATA == (header->type & MAUSB_PKT_TYPE_MASK); |
590 | 0 | } |
591 | | |
592 | | static bool mausb_is_transfer_req(struct mausb_header *header) |
593 | 0 | { |
594 | 0 | return TransferReq == header->type; |
595 | 0 | } |
596 | | |
597 | | static bool mausb_is_transfer_ack(struct mausb_header *header) |
598 | 0 | { |
599 | 0 | return TransferAck == header->type; |
600 | 0 | } |
601 | | |
602 | | static int8_t mausb_tx_type(struct mausb_header *header) |
603 | 0 | { |
604 | 0 | return (header->u.s.eps_tflags >> MAUSB_TFLAG_OFFSET) & MAUSB_TFLAG_TRANSFER_TYPE; |
605 | 0 | } |
606 | | |
607 | | static bool mausb_is_iso_pkt(struct mausb_header *header) |
608 | 0 | { |
609 | 0 | return MAUSB_TX_TYPE_ISOC == mausb_tx_type(header); |
610 | 0 | } |
611 | | |
612 | | static bool mausb_has_timestamp(struct mausb_header *header) |
613 | 0 | { |
614 | 0 | return (MAUSB_FLAG_TIMESTAMP << MAUSB_FLAG_OFFSET) & header->ver_flags; |
615 | 0 | } |
616 | | |
617 | | static bool mausb_has_mtd(struct mausb_header *header) |
618 | 0 | { |
619 | 0 | return (MAUSB_IFLAG_MTD << MAUSB_IFLAG_OFFSET) & header->u.s.u1.num_headers_iflags; |
620 | 0 | } |
621 | | |
622 | | static bool mausb_has_setup_data(struct mausb_header *header) |
623 | 0 | { |
624 | 0 | if ((TransferReq == header->type ) && |
625 | 0 | (mausb_is_from_host(header)) && |
626 | 0 | (0 == header->u.s.seq_num) && |
627 | 0 | (MAUSB_TX_TYPE_CTRL == mausb_tx_type(header))) { |
628 | |
|
629 | 0 | return true; |
630 | 0 | } |
631 | 0 | return false; |
632 | 0 | } |
633 | | |
634 | | static bool mausb_is_setup_response(struct mausb_header *header) |
635 | 0 | { |
636 | 0 | if ((TransferResp == header->type) && |
637 | 0 | (!mausb_is_from_host(header)) && |
638 | 0 | (MAUSB_TX_TYPE_CTRL == mausb_tx_type(header))) { |
639 | |
|
640 | 0 | return true; |
641 | 0 | } |
642 | 0 | return false; |
643 | 0 | } |
644 | | |
645 | | /*** EP Handle parsing helper functions */ |
646 | | |
647 | 0 | uint8_t mausb_ep_handle_ep_d(uint16_t handle) { |
648 | 0 | return (handle & MAUSB_EP_HANDLE_D) >> MAUSB_EP_HANDLE_D_OFFSET; |
649 | 0 | } |
650 | | |
651 | 0 | uint8_t mausb_ep_handle_ep_num(uint16_t handle) { |
652 | 0 | return (handle & MAUSB_EP_HANDLE_EP_NUM) >> MAUSB_EP_HANDLE_EP_NUM_OFFSET; |
653 | 0 | } |
654 | | |
655 | 0 | uint8_t mausb_ep_handle_dev_addr(uint16_t handle) { |
656 | 0 | return (handle & MAUSB_EP_HANDLE_DEV_ADDR) >> MAUSB_EP_HANDLE_DEV_ADDR_OFFSET; |
657 | 0 | } |
658 | | |
659 | 0 | uint8_t mausb_ep_handle_bus_num(uint16_t handle) { |
660 | 0 | return (handle & MAUSB_EP_HANDLE_BUS_NUM) >> MAUSB_EP_HANDLE_BUS_NUM_OFFSET; |
661 | 0 | } |
662 | | |
663 | | /* returns the length field of the MAUSB packet */ |
664 | | static unsigned mausb_get_pkt_len(packet_info *pinfo _U_, tvbuff_t *tvb, |
665 | | int offset, void *data _U_) |
666 | 0 | { |
667 | 0 | return tvb_get_letohs(tvb, offset + 2); |
668 | 0 | } |
669 | | |
670 | | /* Initialize the subtree pointers */ |
671 | | static int ett_mausb; |
672 | | static int ett_mausb_flags; |
673 | | static int ett_mausb_ep_handle; |
674 | | static int ett_mausb_tflags; |
675 | | static int ett_mausb_iflags; |
676 | | static int ett_mausb_present_time; |
677 | | static int ett_mausb_timestamp; |
678 | | static int ett_mgmt; |
679 | | static int ett_dev_cap; |
680 | | static int ett_clear_transfers_block; |
681 | | |
682 | | |
683 | 0 | #define USB_DT_EP_SIZE 7 |
684 | 0 | #define USB_DT_SS_EP_COMP_SIZE 6 |
685 | 0 | #define USB_DT_ISO_SSP_EP_COMP_SIZE 8 |
686 | | |
687 | | /* Size of EPHandleReq Descriptors */ |
688 | 0 | #define MAUSB_EP_DES_SIZE 8 |
689 | 0 | #define MAUSB_SS_EP_DES_SIZE 16 |
690 | 0 | #define MAUSB_ISO_SSP_EP_DES_SIZE 24 |
691 | | |
692 | | /* EPHandleReq Descriptor Padding */ |
693 | 0 | #define MAUSB_EP_DES_PAD (MAUSB_EP_DES_SIZE - USB_DT_EP_SIZE) |
694 | | |
695 | 0 | #define MAUSB_SS_EP_DES_PAD (MAUSB_SS_EP_DES_SIZE - \ |
696 | 0 | (USB_DT_EP_SIZE + USB_DT_SS_EP_COMP_SIZE)) |
697 | | |
698 | 0 | #define MAUSB_ISO_SSP_EP_DES_PAD (MAUSB_ISO_SSP_EP_DES_SIZE - \ |
699 | 0 | (USB_DT_EP_SIZE + USB_DT_SS_EP_COMP_SIZE + USB_DT_ISO_SSP_EP_COMP_SIZE)) |
700 | | |
701 | | |
702 | | /* Size of EPHandleResp Descriptor */ |
703 | 0 | #define MAUSB_SIZE_MAUSB_EP_DES 16 |
704 | | |
705 | | |
706 | | /* Size of EPHandleResp Descriptor */ |
707 | 0 | #define MAUSB_SIZE_EP_HANDLE 2 |
708 | | |
709 | | |
710 | | /* Dissects an individual Device Capability Descriptor */ |
711 | | static uint16_t dissect_mausb_dev_cap_desc(proto_tree *tree, tvbuff_t *tvb, |
712 | | packet_info *pinfo, int16_t offset) |
713 | 0 | { |
714 | 0 | uint8_t desc_len; |
715 | 0 | uint8_t cap_type; |
716 | 0 | int16_t desc_offset; |
717 | 0 | proto_item *len_field; |
718 | 0 | proto_tree *dev_cap_tree; |
719 | |
|
720 | 0 | desc_offset = offset; |
721 | 0 | desc_len = tvb_get_uint8(tvb, desc_offset); |
722 | 0 | cap_type = tvb_get_uint8(tvb, desc_offset + 1); |
723 | |
|
724 | 0 | dev_cap_tree = proto_tree_add_subtree(tree, tvb, desc_offset, desc_len, |
725 | 0 | ett_dev_cap, NULL, |
726 | 0 | val_to_str_const(cap_type, mausb_dev_cap_string, "Unknown Capability")); |
727 | |
|
728 | 0 | len_field = proto_tree_add_item(dev_cap_tree, hf_mausb_dev_cap_len, |
729 | 0 | tvb, desc_offset, 1, ENC_LITTLE_ENDIAN); |
730 | 0 | desc_offset += 1; |
731 | |
|
732 | 0 | proto_tree_add_item(dev_cap_tree, hf_mausb_dev_cap_type, |
733 | 0 | tvb, desc_offset, 1, ENC_LITTLE_ENDIAN); |
734 | 0 | desc_offset += 1; |
735 | |
|
736 | 0 | if (desc_len > 2) { |
737 | | |
738 | | /* TODO: dissect individual capabilities */ |
739 | 0 | switch (cap_type) { |
740 | 0 | case SpeedCap: |
741 | 0 | case PmanCap: |
742 | 0 | case IsoCap: |
743 | 0 | case SyncCap: |
744 | 0 | case ContainerIDCap: |
745 | 0 | case LinkSleepCap: |
746 | 0 | default: |
747 | 0 | proto_tree_add_item(dev_cap_tree, hf_mausb_dev_cap_generic, |
748 | 0 | tvb, desc_offset, (desc_len - 2), ENC_NA); |
749 | 0 | desc_offset += (desc_len - 2); |
750 | |
|
751 | 0 | break; |
752 | 0 | } |
753 | 0 | } |
754 | | |
755 | | /* Was this descriptor a different length than expected */ |
756 | 0 | if (desc_offset != offset + desc_len) { |
757 | 0 | expert_add_info(pinfo, len_field, &ei_dev_cap_len); |
758 | 0 | } |
759 | |
|
760 | 0 | return offset + desc_len; |
761 | 0 | } |
762 | | |
763 | | |
764 | | /* Dissects a MAUSB capability response packet |
765 | | * also dissects Capability Descriptors |
766 | | */ |
767 | | static uint16_t dissect_mausb_mgmt_pkt_cap_resp(struct mausb_header *header, |
768 | | proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int16_t offset) |
769 | 0 | { |
770 | |
|
771 | 0 | unsigned desc_len; |
772 | 0 | uint8_t desc_count; |
773 | 0 | proto_item *len_field; |
774 | 0 | uint16_t loop_offset; |
775 | 0 | int i; |
776 | | |
777 | | /* Fields present in all CapResp packets */ |
778 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_num_ep, |
779 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
780 | 0 | offset += 2; |
781 | |
|
782 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_num_dev, |
783 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); |
784 | 0 | offset += 1; |
785 | |
|
786 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_num_stream, |
787 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); /* really 5 bits */ |
788 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_dev_type, |
789 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); /* really 3 bits */ |
790 | 0 | offset += 1; |
791 | |
|
792 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_desc_count, |
793 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); |
794 | 0 | desc_count = tvb_get_uint8(tvb, offset); |
795 | 0 | offset += 1; |
796 | |
|
797 | 0 | len_field = proto_tree_add_item(tree, hf_mausb_cap_resp_desc_len, |
798 | 0 | tvb, offset, 3, ENC_LITTLE_ENDIAN); |
799 | 0 | desc_len = tvb_get_letoh24(tvb, offset); |
800 | 0 | offset += 3; |
801 | |
|
802 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_transfer_req, |
803 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
804 | 0 | offset += 2; |
805 | |
|
806 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_mgmt_req, |
807 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); /* really 12 bits */ |
808 | 0 | proto_tree_add_item(tree, hf_mausb_cap_resp_rsvd, |
809 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); /* really 4 bits */ |
810 | 0 | offset += 2; |
811 | | |
812 | | /* Descriptors length longer than remainder of packet */ |
813 | 0 | if (offset + desc_len > header->length) { |
814 | 0 | expert_add_info(pinfo, len_field, &ei_cap_resp_desc_len); |
815 | 0 | desc_len = header->length - offset; /* to avoid overflows */ |
816 | 0 | } |
817 | |
|
818 | 0 | loop_offset = offset; |
819 | | |
820 | | /* dissect capability descriptors */ |
821 | 0 | for (i = 0; i < desc_count; i++) { |
822 | 0 | loop_offset = dissect_mausb_dev_cap_desc(tree, tvb, pinfo, loop_offset); |
823 | 0 | } |
824 | | |
825 | | /* were the descriptors a different length than expected */ |
826 | 0 | if (loop_offset != offset + desc_len) { |
827 | 0 | expert_add_info(pinfo, len_field, &ei_dev_cap_resp_desc_len); |
828 | 0 | desc_len = header->length - offset; /* to avoid overflows */ |
829 | 0 | } |
830 | |
|
831 | 0 | return offset + desc_len; |
832 | 0 | } |
833 | | |
834 | | /* Dissects a MAUSB endpoint handle */ |
835 | | static int dissect_ep_handle(proto_tree *tree, tvbuff_t *tvb, int offset) |
836 | 0 | { |
837 | |
|
838 | 0 | proto_item *ti; |
839 | 0 | proto_tree *ep_handle_tree; |
840 | |
|
841 | 0 | ti = proto_tree_add_item(tree, hf_mausb_ep_handle, tvb, |
842 | 0 | offset, MAUSB_SIZE_EP_HANDLE, ENC_LITTLE_ENDIAN); |
843 | |
|
844 | 0 | ep_handle_tree = proto_item_add_subtree(ti, ett_mausb_ep_handle); |
845 | 0 | proto_tree_add_item(ep_handle_tree, hf_mausb_ep_handle_d, tvb, |
846 | 0 | offset, MAUSB_SIZE_EP_HANDLE, ENC_LITTLE_ENDIAN); |
847 | 0 | proto_tree_add_item(ep_handle_tree, hf_mausb_ep_handle_ep_num, tvb, |
848 | 0 | offset, MAUSB_SIZE_EP_HANDLE, ENC_LITTLE_ENDIAN); |
849 | 0 | proto_tree_add_item(ep_handle_tree, hf_mausb_ep_handle_dev_addr, tvb, |
850 | 0 | offset, MAUSB_SIZE_EP_HANDLE, ENC_LITTLE_ENDIAN); |
851 | 0 | proto_tree_add_item(ep_handle_tree, hf_mausb_ep_handle_bus_num, tvb, |
852 | 0 | offset, MAUSB_SIZE_EP_HANDLE, ENC_LITTLE_ENDIAN); |
853 | |
|
854 | 0 | return MAUSB_SIZE_EP_HANDLE; |
855 | |
|
856 | 0 | } |
857 | | |
858 | | /* dissects presentation time & subfields */ |
859 | | static void dissect_mausb_present_time(proto_tree *tree, tvbuff_t *tvb, |
860 | | int offset) |
861 | 0 | { |
862 | 0 | proto_item *ti; |
863 | 0 | proto_tree *present_time_tree; |
864 | |
|
865 | 0 | ti = proto_tree_add_item(tree, hf_mausb_present_time, tvb, |
866 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
867 | |
|
868 | 0 | present_time_tree = proto_item_add_subtree(ti, ett_mausb_present_time); |
869 | 0 | proto_tree_add_item(present_time_tree, hf_mausb_uframe, tvb, |
870 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
871 | 0 | proto_tree_add_item(present_time_tree, hf_mausb_frame, tvb, |
872 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
873 | |
|
874 | 0 | } |
875 | | |
876 | | static void dissect_mausb_timestamp(proto_tree *tree, tvbuff_t *tvb, |
877 | | int offset) |
878 | 0 | { |
879 | 0 | proto_item *ti; |
880 | 0 | proto_tree *timestamp_tree; |
881 | |
|
882 | 0 | ti = proto_tree_add_item(tree, hf_mausb_timestamp, tvb, |
883 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
884 | |
|
885 | 0 | timestamp_tree = proto_item_add_subtree(ti, ett_mausb_timestamp); |
886 | 0 | proto_tree_add_item(timestamp_tree, hf_mausb_delta, tvb, |
887 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
888 | 0 | proto_tree_add_item(timestamp_tree, hf_mausb_nom_interval, tvb, |
889 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
890 | |
|
891 | 0 | } |
892 | | |
893 | | /* gets the size of the endpoint descriptors in a EPHandleReq packet */ |
894 | | static uint8_t mausb_get_size_ep_des(tvbuff_t *tvb, int offset) |
895 | 0 | { |
896 | 0 | uint8_t size_ep_des = 0; |
897 | 0 | uint16_t temp_buffer = 0; /* for storing the offset data */ |
898 | | |
899 | | /* grab the 2 bytes with the size field */ |
900 | 0 | temp_buffer = tvb_get_letohs(tvb, offset); |
901 | | |
902 | | /* mask & shift the size field */ |
903 | 0 | temp_buffer = temp_buffer & MAUSB_MGMT_SIZE_EP_DES_MASK; |
904 | 0 | size_ep_des = (temp_buffer >> MAUSB_MGMT_SIZE_EP_DES_OFFSET); |
905 | |
|
906 | 0 | return size_ep_des; |
907 | 0 | } |
908 | | |
909 | | /* dissect an individual block for ClearTransfers */ |
910 | | static uint16_t dissect_clear_transfers_block(proto_tree *tree, |
911 | | tvbuff_t *tvb, int16_t offset, bool req) |
912 | 0 | { |
913 | 0 | proto_item *ti; |
914 | 0 | proto_tree *block_tree; |
915 | |
|
916 | 0 | if (req) { |
917 | 0 | ti = proto_tree_add_item(tree, hf_mausb_clear_transfers_info_block, |
918 | 0 | tvb, offset, 8, ENC_NA); |
919 | 0 | } else { |
920 | 0 | ti = proto_tree_add_item(tree, hf_mausb_clear_transfers_status_block, |
921 | 0 | tvb, offset, 16, ENC_NA); |
922 | 0 | } |
923 | |
|
924 | 0 | block_tree = proto_item_add_subtree(ti, ett_clear_transfers_block); |
925 | | |
926 | | |
927 | | /* EP Handle */ |
928 | 0 | offset += dissect_ep_handle(block_tree, tvb, offset); |
929 | | |
930 | | /* Stream ID */ |
931 | 0 | proto_tree_add_item(block_tree, hf_mausb_stream_id, tvb, offset, 2, |
932 | 0 | ENC_LITTLE_ENDIAN); |
933 | 0 | offset += 2; |
934 | |
|
935 | 0 | if (req) { |
936 | | /* Start Request ID */ |
937 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_start_req_id, |
938 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); |
939 | 0 | offset += 1; |
940 | | |
941 | | /* Rsvd */ |
942 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_req_block_rsvd, |
943 | 0 | tvb, offset, 3, ENC_NA); |
944 | 0 | offset += 3; |
945 | |
|
946 | 0 | } else { |
947 | | /* Cancel Status */ |
948 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_status, |
949 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
950 | | /* Partial Delivery */ |
951 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_partial, |
952 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
953 | | /* Rsvd */ |
954 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_resp_block_rsvd, |
955 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
956 | 0 | offset += 4; |
957 | | |
958 | | /* Last Request ID */ |
959 | 0 | proto_tree_add_item(block_tree, hf_mausb_clear_transfers_last_req_id, |
960 | 0 | tvb, offset, 1, ENC_LITTLE_ENDIAN); |
961 | 0 | offset += 1; |
962 | | |
963 | | /* Delivered Sequence Number */ |
964 | 0 | proto_tree_add_item(block_tree, hf_mausb_cancel_transfer_seq_num, tvb, |
965 | 0 | offset, 3, ENC_LITTLE_ENDIAN); |
966 | 0 | offset += 3; |
967 | | /* Delivered Byte Offset */ |
968 | 0 | proto_tree_add_item(block_tree, hf_mausb_cancel_transfer_byte_offset, |
969 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN); |
970 | 0 | offset += 4; |
971 | 0 | } |
972 | |
|
973 | 0 | return offset; |
974 | 0 | } |
975 | | |
976 | | /* dissects portions of a MA USB packet specific to ClearTransfers packets */ |
977 | | static uint16_t dissect_mausb_mgmt_pkt_clear_transfers(proto_tree *tree, |
978 | | tvbuff_t *tvb, int16_t offset, bool req) |
979 | 0 | { |
980 | 0 | uint8_t num_block; |
981 | 0 | int i; |
982 | |
|
983 | 0 | num_block = tvb_get_uint8(tvb, offset); |
984 | 0 | if (req) { |
985 | | /* Number of entries */ |
986 | 0 | proto_tree_add_item(tree, hf_mausb_clear_transfers_req_num, tvb, |
987 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
988 | 0 | offset += 1; |
989 | | |
990 | | /* Rsvd */ |
991 | 0 | proto_tree_add_item(tree, hf_mausb_clear_transfers_req_rsvd, tvb, |
992 | 0 | offset, 3, ENC_NA); |
993 | 0 | offset += 3; |
994 | |
|
995 | 0 | } else { |
996 | 0 | num_block &= MAUSB_MGMT_CLEAR_TRANSFER_RESP_NUM_MASK; |
997 | | |
998 | | /* Number of entries */ |
999 | 0 | proto_tree_add_item(tree, hf_mausb_clear_transfers_resp_num, tvb, |
1000 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1001 | | /* Rsvd */ |
1002 | 0 | proto_tree_add_item(tree, hf_mausb_clear_transfers_resp_rsvd, tvb, |
1003 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1004 | 0 | offset += 4; |
1005 | 0 | } |
1006 | |
|
1007 | 0 | for (i = 0; i < num_block; i++) { |
1008 | 0 | offset = dissect_clear_transfers_block(tree, tvb, offset, req); |
1009 | 0 | } |
1010 | |
|
1011 | 0 | return offset; |
1012 | 0 | } |
1013 | | |
1014 | | /* dissects portions of a MA USB packet specific to Endpoint Handle Request packets */ |
1015 | | static uint16_t dissect_mausb_mgmt_pkt_ep_handle( proto_tree *tree, tvbuff_t *tvb, |
1016 | | packet_info *pinfo, int16_t start, bool req, bool del) |
1017 | 0 | { |
1018 | 0 | urb_info_t urb; |
1019 | 0 | proto_item *size_field = NULL; |
1020 | 0 | uint16_t offset = start; |
1021 | 0 | uint16_t loop_offset; |
1022 | 0 | uint8_t num_ep; |
1023 | 0 | uint8_t size_ep_des; |
1024 | 0 | uint8_t last_ep_type = ENDPOINT_TYPE_NOT_SET; |
1025 | 0 | int i; |
1026 | |
|
1027 | 0 | memset(&urb, 0, sizeof(urb_info_t)); |
1028 | |
|
1029 | 0 | num_ep = tvb_get_uint8(tvb, offset) & MAUSB_MGMT_NUM_EP_DES_MASK; |
1030 | |
|
1031 | 0 | if (!del) { |
1032 | 0 | proto_tree_add_item(tree, hf_mausb_mgmt_ep_des_num, tvb, |
1033 | 0 | offset, 1, ENC_LITTLE_ENDIAN); /* really 5 bits */ |
1034 | 0 | } else { |
1035 | 0 | proto_tree_add_item(tree, hf_mausb_mgmt_ep_handle_num, tvb, |
1036 | 0 | offset, 1, ENC_LITTLE_ENDIAN); /* really 5 bits */ |
1037 | 0 | } |
1038 | |
|
1039 | 0 | if (req && !del) { |
1040 | |
|
1041 | 0 | size_ep_des = mausb_get_size_ep_des(tvb, offset); |
1042 | 0 | size_field = proto_tree_add_item(tree, hf_mausb_mgmt_ep_des_size, tvb, |
1043 | 0 | offset, 2, ENC_LITTLE_ENDIAN); /* really 6 bits over a byte boundary */ |
1044 | 0 | offset += 1; |
1045 | | |
1046 | | /* Padding to DWORD */ |
1047 | 0 | proto_tree_add_item(tree, hf_mausb_mgmt_ep_des_pad, tvb, |
1048 | 0 | offset, 3, ENC_NA); |
1049 | 0 | offset += 3; |
1050 | |
|
1051 | 0 | } else if (!req && !del) { |
1052 | 0 | size_ep_des = MAUSB_SIZE_MAUSB_EP_DES; |
1053 | 0 | proto_tree_add_item(tree, hf_mausb_mgmt_ep_handle_pad, tvb, |
1054 | 0 | offset, 4, ENC_NA); /* really 5 bits */ |
1055 | | /* Padding to DWORD */ |
1056 | 0 | offset += 4; |
1057 | |
|
1058 | 0 | } else { /* If it is an EPHandleDelete Req or Resp */ |
1059 | 0 | size_ep_des = MAUSB_SIZE_EP_HANDLE; |
1060 | | /* Padding to DWORD */ |
1061 | 0 | proto_tree_add_item(tree, hf_mausb_mgmt_ep_handle_pad, tvb, |
1062 | 0 | offset, 4, ENC_NA); |
1063 | 0 | offset += 4; /* Padding to DWORD */ |
1064 | |
|
1065 | 0 | } |
1066 | | |
1067 | | /* For every entry */ |
1068 | 0 | for (i = 0; i < num_ep; ++i) { |
1069 | 0 | loop_offset = offset; |
1070 | | |
1071 | | /* If it is an EPHandleDelete Req or Resp */ |
1072 | 0 | if (del) { |
1073 | 0 | loop_offset += dissect_ep_handle(tree, tvb, loop_offset); |
1074 | |
|
1075 | 0 | } else if (req) { |
1076 | | |
1077 | | /* Standard USB Endpoint Descriptor */ |
1078 | 0 | dissect_usb_endpoint_descriptor(pinfo, tree, tvb, loop_offset, |
1079 | 0 | &urb, &last_ep_type, USB_SPEED_UNKNOWN); |
1080 | 0 | loop_offset += USB_DT_EP_SIZE; |
1081 | | |
1082 | | /* If there are more descriptors to read */ |
1083 | 0 | if (MAUSB_EP_DES_SIZE < size_ep_des) { |
1084 | | /* TODO: Dissector for SS EP Companion Descriptors */ |
1085 | 0 | dissect_usb_unknown_descriptor(pinfo, tree, |
1086 | 0 | tvb, loop_offset, &urb); |
1087 | 0 | loop_offset += USB_DT_SS_EP_COMP_SIZE; |
1088 | |
|
1089 | 0 | if (MAUSB_SS_EP_DES_SIZE < size_ep_des) { |
1090 | | /* TODO: Dissector for SSP ISO EP Companion Descriptors */ |
1091 | 0 | loop_offset += dissect_usb_unknown_descriptor(pinfo, tree, |
1092 | 0 | tvb, loop_offset, &urb); |
1093 | | |
1094 | | /* Pad to a DWORD */ |
1095 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_req_pad, tvb, |
1096 | 0 | loop_offset, MAUSB_ISO_SSP_EP_DES_PAD, ENC_NA); |
1097 | 0 | loop_offset += MAUSB_ISO_SSP_EP_DES_PAD; |
1098 | |
|
1099 | 0 | } else { |
1100 | | /* Pad to a DWORD */ |
1101 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_req_pad, tvb, |
1102 | 0 | loop_offset, MAUSB_SS_EP_DES_PAD, ENC_NA); |
1103 | 0 | loop_offset += MAUSB_SS_EP_DES_PAD; |
1104 | 0 | } |
1105 | |
|
1106 | 0 | } else { |
1107 | | /* Pad to a DWORD */ |
1108 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_req_pad, tvb, |
1109 | 0 | loop_offset, MAUSB_EP_DES_PAD, ENC_NA); |
1110 | 0 | loop_offset += MAUSB_EP_DES_PAD; |
1111 | 0 | } |
1112 | |
|
1113 | 0 | } else { /* IE: it's a EPHandleResp */ |
1114 | | /* EP Handle */ |
1115 | 0 | loop_offset += dissect_ep_handle(tree, tvb, loop_offset); |
1116 | | |
1117 | | /* direction */ |
1118 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_dir, tvb, |
1119 | 0 | loop_offset, 1, ENC_LITTLE_ENDIAN); |
1120 | | |
1121 | | /* isochronous */ |
1122 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_iso, tvb, |
1123 | 0 | loop_offset, 1, ENC_LITTLE_ENDIAN); |
1124 | | |
1125 | | /* L-managed transfers */ |
1126 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_lman, tvb, |
1127 | 0 | loop_offset, 1, ENC_LITTLE_ENDIAN); |
1128 | | |
1129 | | /* valid handle bit */ |
1130 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_valid, tvb, |
1131 | 0 | loop_offset, 1, ENC_LITTLE_ENDIAN); |
1132 | 0 | loop_offset += 2; /* 4 bit flags + 12 reserved bits */ |
1133 | | |
1134 | | /* credit consumption unit */ |
1135 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_ccu, tvb, |
1136 | 0 | loop_offset, 2, ENC_LITTLE_ENDIAN); |
1137 | 0 | loop_offset += 2; |
1138 | |
|
1139 | 0 | loop_offset += 2; /* 2 bytes reserved */ |
1140 | | |
1141 | | /* buffer size (in bytes) */ |
1142 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_buf_size, tvb, |
1143 | 0 | loop_offset, 4, ENC_LITTLE_ENDIAN); |
1144 | 0 | loop_offset += 4; |
1145 | | |
1146 | | |
1147 | | /* max iso programming delay (in uSec) */ |
1148 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_iso_prog_dly, tvb, |
1149 | 0 | loop_offset, 2, ENC_LITTLE_ENDIAN); |
1150 | 0 | loop_offset += 2; |
1151 | | |
1152 | | /* max iso response delay (in uSec) */ |
1153 | 0 | proto_tree_add_item(tree, hf_mausb_ep_handle_resp_iso_resp_dly, tvb, |
1154 | 0 | loop_offset, 2, ENC_LITTLE_ENDIAN); |
1155 | 0 | loop_offset += 2; |
1156 | 0 | } |
1157 | | |
1158 | |
|
1159 | 0 | offset += size_ep_des; |
1160 | |
|
1161 | 0 | if (req && !del && loop_offset != offset){ |
1162 | 0 | expert_add_info(pinfo, size_field, &ei_ep_handle_len); |
1163 | 0 | } |
1164 | |
|
1165 | 0 | } |
1166 | |
|
1167 | 0 | return offset; |
1168 | |
|
1169 | 0 | } |
1170 | | |
1171 | | /* dissects portions of a MA USB packet specific to CancelTransfer packets */ |
1172 | | static uint16_t dissect_mausb_mgmt_pkt_cancel_transfer( proto_tree *tree, |
1173 | | tvbuff_t *tvb, int offset, bool req) |
1174 | 0 | { |
1175 | |
|
1176 | 0 | uint8_t status; |
1177 | |
|
1178 | 0 | offset += dissect_ep_handle(tree, tvb, offset); |
1179 | |
|
1180 | 0 | proto_tree_add_item(tree, hf_mausb_stream_id, tvb, offset, 2, |
1181 | 0 | ENC_LITTLE_ENDIAN); |
1182 | 0 | offset += 2; |
1183 | |
|
1184 | 0 | proto_tree_add_item(tree, hf_mausb_req_id, tvb, offset, 1, |
1185 | 0 | ENC_LITTLE_ENDIAN); |
1186 | 0 | offset += 1; |
1187 | |
|
1188 | 0 | if (req) { |
1189 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_rsvd, tvb, offset, 3, |
1190 | 0 | ENC_NA); |
1191 | 0 | offset += 3; |
1192 | |
|
1193 | 0 | return offset; |
1194 | 0 | } /* else resp */ |
1195 | | |
1196 | 0 | status = tvb_get_uint8(tvb, offset) | |
1197 | 0 | MAUSB_CANCEL_TRANSFER_STATUS_MASK; |
1198 | |
|
1199 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_status, tvb, offset, 3, |
1200 | 0 | ENC_LITTLE_ENDIAN); |
1201 | |
|
1202 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_rsvd_2, tvb, offset, 3, |
1203 | 0 | ENC_LITTLE_ENDIAN); |
1204 | | /* Reserved */ |
1205 | 0 | offset += 3; |
1206 | | |
1207 | | /* if some data was moved */ |
1208 | 0 | if (2 == status) { |
1209 | | /* TODO: sequence number reserved for INs */ |
1210 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_seq_num, tvb, offset, |
1211 | 0 | 3, ENC_LITTLE_ENDIAN); |
1212 | 0 | offset += 3; |
1213 | |
|
1214 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_rsvd, tvb, offset, 1, |
1215 | 0 | ENC_NA); |
1216 | 0 | offset += 1; |
1217 | |
|
1218 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_byte_offset, tvb, |
1219 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
1220 | 0 | offset += 4; |
1221 | |
|
1222 | 0 | } else { |
1223 | 0 | proto_tree_add_item(tree, hf_mausb_cancel_transfer_rsvd, tvb, offset, 8, |
1224 | 0 | ENC_NA); |
1225 | 0 | offset += 8; |
1226 | 0 | } |
1227 | |
|
1228 | 0 | return offset; |
1229 | |
|
1230 | 0 | } |
1231 | | |
1232 | | /* dissects portions of a MA USB packet specific to particular management packets */ |
1233 | | static uint16_t dissect_mausb_mgmt_pkt_flds(struct mausb_header *header, |
1234 | | proto_tree *tree, tvbuff_t *tvb, |
1235 | | packet_info *pinfo, int16_t start) |
1236 | 0 | { |
1237 | |
|
1238 | 0 | proto_item *ti; |
1239 | 0 | proto_tree *mgmt_tree; |
1240 | 0 | uint16_t offset = start; |
1241 | 0 | int type_spec_len = tvb_reported_length(tvb) - start; |
1242 | |
|
1243 | 0 | if (0 > type_spec_len) { |
1244 | 0 | expert_add_info(pinfo, tree, &ei_mgmt_type_spec_len_short); |
1245 | 0 | return offset; |
1246 | 0 | } |
1247 | | |
1248 | 0 | ti = proto_tree_add_item(tree, hf_mausb_mgmt_type_spec, tvb, |
1249 | 0 | offset, type_spec_len, ENC_NA); |
1250 | |
|
1251 | 0 | mgmt_tree = proto_item_add_subtree(ti, ett_mgmt); |
1252 | |
|
1253 | 0 | switch (header->type) { |
1254 | | |
1255 | | /* subtypes with variable length additional data */ |
1256 | 0 | case CapResp: |
1257 | 0 | offset = dissect_mausb_mgmt_pkt_cap_resp(header, mgmt_tree, tvb, pinfo, offset); |
1258 | 0 | break; |
1259 | 0 | case EPHandleReq: |
1260 | 0 | offset = dissect_mausb_mgmt_pkt_ep_handle(mgmt_tree, tvb, pinfo, |
1261 | 0 | offset, true, false); |
1262 | 0 | break; |
1263 | | |
1264 | 0 | case EPHandleResp: |
1265 | 0 | offset = dissect_mausb_mgmt_pkt_ep_handle(mgmt_tree, tvb, pinfo, |
1266 | 0 | offset, false, false); |
1267 | 0 | break; |
1268 | | |
1269 | | /* TODO: Dissect type-specific management packet fields */ |
1270 | 0 | case EPActivateReq: |
1271 | 0 | case EPActivateResp: |
1272 | 0 | case EPInactivateReq: |
1273 | 0 | case EPInactivateResp: |
1274 | 0 | case EPResetReq: |
1275 | 0 | case EPResetResp: |
1276 | 0 | proto_tree_add_item(mgmt_tree, hf_mausb_mgmt_type_spec_generic, |
1277 | 0 | tvb, offset, type_spec_len, ENC_NA); |
1278 | 0 | offset += type_spec_len; |
1279 | 0 | break; |
1280 | 0 | case ClearTransfersReq: |
1281 | 0 | offset = dissect_mausb_mgmt_pkt_clear_transfers(mgmt_tree, tvb, offset, true); |
1282 | 0 | break; |
1283 | 0 | case ClearTransfersResp: |
1284 | 0 | offset = dissect_mausb_mgmt_pkt_clear_transfers(mgmt_tree, tvb, offset, false); |
1285 | 0 | break; |
1286 | 0 | case EPHandleDeleteReq: |
1287 | 0 | offset = dissect_mausb_mgmt_pkt_ep_handle(mgmt_tree, tvb, pinfo, |
1288 | 0 | offset, true, true); |
1289 | 0 | break; |
1290 | 0 | case EPHandleDeleteResp: |
1291 | 0 | offset = dissect_mausb_mgmt_pkt_ep_handle(mgmt_tree, tvb, pinfo, |
1292 | 0 | offset, false, true); |
1293 | 0 | break; |
1294 | 0 | case ModifyEP0Resp: |
1295 | 0 | case EPCloseStreamResp: |
1296 | 0 | case USBDevResetReq: |
1297 | 0 | case USBDevResetResp: |
1298 | 0 | case EPOpenStreamResp: |
1299 | 0 | case VendorSpecificReq: |
1300 | 0 | case VendorSpecificResp: |
1301 | | /* FALLTHROUGH */ |
1302 | | |
1303 | | /* subtypes with constant length additional data */ |
1304 | 0 | case CapReq: |
1305 | 0 | case USBDevHandleReq: |
1306 | 0 | case USBDevHandleResp: |
1307 | 0 | case ModifyEP0Req: |
1308 | 0 | case SetUSBDevAddrReq: |
1309 | 0 | case SetUSBDevAddrResp: |
1310 | 0 | case UpdateDevReq: |
1311 | 0 | case SynchReq: |
1312 | 0 | case EPCloseStreamReq: |
1313 | 0 | proto_tree_add_item(mgmt_tree, hf_mausb_mgmt_type_spec_generic, |
1314 | 0 | tvb, offset, type_spec_len, ENC_NA); |
1315 | 0 | offset += type_spec_len; |
1316 | 0 | break; |
1317 | | |
1318 | 0 | case CancelTransferReq: |
1319 | 0 | offset = dissect_mausb_mgmt_pkt_cancel_transfer(mgmt_tree, tvb, offset, |
1320 | 0 | true); |
1321 | 0 | break; |
1322 | 0 | case CancelTransferResp: |
1323 | 0 | offset = dissect_mausb_mgmt_pkt_cancel_transfer(mgmt_tree, tvb, offset, |
1324 | 0 | false); |
1325 | 0 | break; |
1326 | 0 | case EPOpenStreamReq: |
1327 | |
|
1328 | 0 | proto_tree_add_item(mgmt_tree, hf_mausb_mgmt_type_spec_generic, |
1329 | 0 | tvb, offset, type_spec_len, ENC_NA); |
1330 | 0 | offset += type_spec_len; |
1331 | 0 | break; |
1332 | | |
1333 | | |
1334 | | /* Management packets with no additional data */ |
1335 | 0 | case DevResetReq: |
1336 | 0 | case DevResetResp: |
1337 | 0 | case UpdateDevResp: |
1338 | 0 | case USBDevDisconnectReq: |
1339 | 0 | case USBDevDisconnectResp: |
1340 | 0 | case SleepReq: |
1341 | 0 | case SleepResp: |
1342 | 0 | case WakeReq: |
1343 | 0 | case WakeResp: |
1344 | 0 | case PingReq: |
1345 | 0 | case PingResp: |
1346 | 0 | case DevDisconnectReq: |
1347 | 0 | case DevDisconnectResp: |
1348 | 0 | case DevInitDisconnectReq: |
1349 | 0 | case DevInitDisconnectResp: |
1350 | 0 | case SynchResp: |
1351 | 0 | break; |
1352 | | |
1353 | 0 | default: |
1354 | 0 | expert_add_info(pinfo, mgmt_tree, &ei_mgmt_type_undef); |
1355 | 0 | break; |
1356 | |
|
1357 | 0 | } |
1358 | | |
1359 | | |
1360 | 0 | if (offset < tvb_reported_length(tvb)) { |
1361 | 0 | expert_add_info(pinfo, mgmt_tree, &ei_mgmt_type_spec_len_long); |
1362 | 0 | } |
1363 | |
|
1364 | 0 | return offset; |
1365 | 0 | } |
1366 | | |
1367 | | void mausb_set_urb_info(urb_info_t *urb, struct mausb_header *header) |
1368 | 0 | { |
1369 | 0 | urb->is_request = mausb_is_transfer_req(header); |
1370 | 0 | urb->bus_id = mausb_ep_handle_bus_num(header->handle); |
1371 | 0 | urb->device_address = mausb_ep_handle_dev_addr(header->handle); |
1372 | 0 | urb->direction = mausb_is_from_host(header); |
1373 | 0 | urb->endpoint = mausb_ep_handle_ep_num(header->handle); |
1374 | 0 | if (mausb_ep_handle_ep_d(header->handle)) { |
1375 | | /* IN endpoint */ |
1376 | 0 | urb->endpoint |= 0x80; |
1377 | 0 | } |
1378 | 0 | urb->is_setup = mausb_has_setup_data(header) || |
1379 | 0 | mausb_is_setup_response(header); |
1380 | 0 | switch (mausb_tx_type(header)) { |
1381 | 0 | case MAUSB_TX_TYPE_CTRL: |
1382 | 0 | urb->transfer_type = URB_CONTROL; |
1383 | 0 | break; |
1384 | 0 | case MAUSB_TX_TYPE_ISOC: |
1385 | 0 | urb->transfer_type = URB_ISOCHRONOUS; |
1386 | 0 | break; |
1387 | 0 | case MAUSB_TX_TYPE_BULK: |
1388 | 0 | urb->transfer_type = URB_BULK; |
1389 | 0 | break; |
1390 | 0 | case MAUSB_TX_TYPE_INTR: |
1391 | 0 | urb->transfer_type = URB_INTERRUPT; |
1392 | 0 | break; |
1393 | 0 | default: |
1394 | 0 | urb->transfer_type = URB_UNKNOWN; |
1395 | 0 | break; |
1396 | 0 | } |
1397 | 0 | } |
1398 | | |
1399 | | /* Used to detect multiple MA Packets in a single TCP packet */ |
1400 | | /* Not used for MA Packets in SNAP Packets */ |
1401 | | static int mausb_num_pdus; |
1402 | | |
1403 | | |
1404 | | /* dissect fields common to all MAUSB packet types */ |
1405 | | static int |
1406 | | dissect_mausb_pkt_common(tvbuff_t *tvb, int offset, packet_info *pinfo, |
1407 | | proto_tree *mausb_tree, struct mausb_header *header) |
1408 | 0 | { |
1409 | 0 | proto_item *len_field; |
1410 | | |
1411 | | /* MAUSB Protocol Version */ |
1412 | 0 | header->ver_flags = tvb_get_uint8(tvb, offset); |
1413 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_version, tvb, |
1414 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1415 | | |
1416 | | /* Flags */ |
1417 | 0 | proto_tree_add_bitmask(mausb_tree, tvb, offset, hf_mausb_flags, |
1418 | 0 | ett_mausb_flags, mausb_flag_fields, ENC_LITTLE_ENDIAN); |
1419 | 0 | offset += 1; |
1420 | | |
1421 | | /* Packet Type */ |
1422 | 0 | header->type = tvb_get_uint8(tvb, offset); |
1423 | 0 | col_append_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, header->type, mausb_type_string, "%d")); |
1424 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_type, tvb, |
1425 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1426 | 0 | offset += 1; |
1427 | | |
1428 | | /* Packet Length */ |
1429 | 0 | header->length = tvb_get_letohs(tvb, offset); |
1430 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " Length=%u", header->length); |
1431 | 0 | len_field = proto_tree_add_item(mausb_tree, hf_mausb_length, tvb, |
1432 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1433 | 0 | offset += 2; |
1434 | | |
1435 | | /* Check to see if length field is valid */ |
1436 | 0 | if (tvb_reported_length(tvb) != header->length) { |
1437 | 0 | expert_add_info(pinfo, len_field, &ei_len); |
1438 | 0 | } |
1439 | | |
1440 | | /* Is the next field a device handle or an endpoint handle */ |
1441 | 0 | header->handle = tvb_get_letohs(tvb, offset); |
1442 | |
|
1443 | 0 | if (mausb_is_mgmt_pkt(header)) { |
1444 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_dev_handle, tvb, |
1445 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1446 | 0 | offset += 2; |
1447 | 0 | } else { |
1448 | 0 | offset += dissect_ep_handle(mausb_tree, tvb, offset); |
1449 | 0 | } |
1450 | | |
1451 | | /* MA Device Address */ |
1452 | 0 | header->ma_dev_addr = tvb_get_uint8(tvb, offset); |
1453 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_ma_dev_addr, tvb, |
1454 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1455 | 0 | offset += 1; |
1456 | | |
1457 | | /* SSID */ |
1458 | 0 | header->mass_id = tvb_get_uint8(tvb, offset); |
1459 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_ssid, tvb, |
1460 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1461 | 0 | offset += 1; |
1462 | | |
1463 | | /* Status */ |
1464 | 0 | header->status = tvb_get_uint8(tvb, offset); |
1465 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_status, tvb, |
1466 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1467 | 0 | offset += 1; |
1468 | |
|
1469 | 0 | return offset; |
1470 | 0 | } |
1471 | | |
1472 | | /* dissect datapacket specific values */ |
1473 | | static int |
1474 | | dissect_mausb_pkt_data(tvbuff_t *tvb, int offset, packet_info *pinfo, |
1475 | | proto_tree *mausb_tree, struct mausb_header *header) |
1476 | 0 | { |
1477 | | /* EPS */ |
1478 | 0 | header->u.s.eps_tflags = tvb_get_uint8(tvb, offset); |
1479 | 0 | if (mausb_is_from_host(header)) { |
1480 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_eps_rsvd, tvb, |
1481 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1482 | 0 | } else { |
1483 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_eps, tvb, |
1484 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1485 | 0 | } |
1486 | | |
1487 | | /* T-Flags */ |
1488 | 0 | proto_tree_add_bitmask(mausb_tree, tvb, offset, hf_mausb_tflags, |
1489 | 0 | ett_mausb_tflags, mausb_tflag_fields, ENC_LITTLE_ENDIAN); |
1490 | 0 | offset += 1; |
1491 | |
|
1492 | 0 | if (mausb_is_iso_pkt(header)) { |
1493 | | /* Number of Headers */ |
1494 | 0 | header->u.s.u1.num_headers_iflags = tvb_get_letohs(tvb, offset); |
1495 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_num_iso_hdr, tvb, |
1496 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1497 | | |
1498 | | /* I-Flags */ |
1499 | 0 | proto_tree_add_bitmask(mausb_tree, tvb, offset, hf_mausb_iflags, |
1500 | 0 | ett_mausb_iflags, mausb_iflag_fields, ENC_LITTLE_ENDIAN); |
1501 | |
|
1502 | 0 | } else { |
1503 | | /* Stream ID */ |
1504 | 0 | header->u.s.u1.stream_id = tvb_get_letohs(tvb, offset); |
1505 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_stream_id, tvb, |
1506 | 0 | offset, 2, ENC_LITTLE_ENDIAN); |
1507 | 0 | } |
1508 | 0 | offset += 2; |
1509 | | |
1510 | | /* Sequence Number */ |
1511 | 0 | header->u.s.seq_num = tvb_get_letoh24(tvb, offset); |
1512 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " SeqNum=%u", header->u.s.seq_num); |
1513 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_seq_num, tvb, |
1514 | 0 | offset, 3, ENC_LITTLE_ENDIAN); |
1515 | 0 | offset += 3; |
1516 | | |
1517 | | /* Request ID */ |
1518 | 0 | header->u.s.req_id = tvb_get_uint8(tvb, offset); |
1519 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " ReqID=%u", header->u.s.req_id); |
1520 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_req_id, tvb, |
1521 | 0 | offset, 1, ENC_LITTLE_ENDIAN); |
1522 | 0 | offset += 1; |
1523 | |
|
1524 | 0 | if (mausb_is_iso_pkt(header)) { |
1525 | | /* Presentation Time */ |
1526 | 0 | header->u.s.u2.present_time_num_seg = tvb_get_letohl(tvb, offset); |
1527 | 0 | dissect_mausb_present_time(mausb_tree, tvb, offset); |
1528 | | |
1529 | | /* Number of Segments */ |
1530 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_num_segs, tvb, |
1531 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
1532 | 0 | offset += 4; |
1533 | | |
1534 | | /* MA USB Timestamp */ |
1535 | 0 | if (mausb_has_timestamp(header)) { |
1536 | 0 | header->u.s.timestamp = tvb_get_letohl(tvb, offset); |
1537 | 0 | dissect_mausb_timestamp(mausb_tree, tvb, offset); |
1538 | 0 | offset += 4; |
1539 | 0 | } |
1540 | | |
1541 | | /* Media Time/Transmission Delay */ |
1542 | 0 | if (mausb_has_mtd(header)) { |
1543 | 0 | header->u.s.tx_dly = tvb_get_letohl(tvb, offset); |
1544 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_mtd, tvb, |
1545 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
1546 | 0 | offset += 4; |
1547 | 0 | } |
1548 | | |
1549 | | /* Not Iso */ |
1550 | 0 | } else { |
1551 | | /* Remaining Size/Credit */ |
1552 | 0 | header->u.s.u2.credit = tvb_get_letohl(tvb, offset); |
1553 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_rem_size_credit, tvb, |
1554 | 0 | offset, 4, ENC_LITTLE_ENDIAN); |
1555 | 0 | offset += 4; |
1556 | 0 | } |
1557 | |
|
1558 | 0 | return offset; |
1559 | 0 | } |
1560 | | |
1561 | | /* Code to actually dissect the packets */ |
1562 | | static int |
1563 | | dissect_mausb_pkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1564 | | void *data _U_) |
1565 | 0 | { |
1566 | | /* Set up structures needed to add the protocol subtree and manage it */ |
1567 | 0 | proto_item *ti; |
1568 | 0 | proto_tree *mausb_tree; |
1569 | | /* Other misc. local variables. */ |
1570 | 0 | struct mausb_header header; |
1571 | 0 | unsigned offset = 0; |
1572 | |
|
1573 | 0 | memset(&header, 0, sizeof(struct mausb_header)); |
1574 | | |
1575 | | /* Set the Protocol column to the constant string of mausb */ |
1576 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAUSB"); |
1577 | |
|
1578 | 0 | mausb_num_pdus++; |
1579 | |
|
1580 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "["); |
1581 | 0 | col_set_fence(pinfo->cinfo, COL_INFO); |
1582 | | |
1583 | | /*** PROTOCOL TREE ***/ |
1584 | | |
1585 | | /* create display subtree for the protocol */ |
1586 | 0 | ti = proto_tree_add_item(tree, proto_mausb, tvb, 0, |
1587 | 0 | mausb_get_pkt_len(pinfo, tvb, offset, NULL), ENC_NA); |
1588 | |
|
1589 | 0 | mausb_tree = proto_item_add_subtree(ti, ett_mausb); |
1590 | | |
1591 | | /* Add an item to the subtree, see section 1.5 of README.dissector for more |
1592 | | * information. */ |
1593 | |
|
1594 | 0 | offset = dissect_mausb_pkt_common(tvb, offset, pinfo, mausb_tree, &header); |
1595 | |
|
1596 | 0 | if (mausb_is_mgmt_pkt(&header)) { |
1597 | | |
1598 | | /* Dialog Token */ |
1599 | 0 | header.u.token = tvb_get_letohs(tvb, 9) & MAUSB_TOKEN_MASK; |
1600 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " Token=%u", header.u.token); |
1601 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_token, tvb, |
1602 | 0 | offset, 2, ENC_LITTLE_ENDIAN); /* Really 10 bits */ |
1603 | 0 | offset += 1; /* token */ |
1604 | | |
1605 | | /* Padding to a DWORD */ |
1606 | 0 | proto_tree_add_item(mausb_tree, hf_mausb_mgmt_pad, tvb, |
1607 | 0 | offset, 2, ENC_LITTLE_ENDIAN); /* Really 14 bits */ |
1608 | |
|
1609 | 0 | offset += 2; /* DWORD*/ |
1610 | | |
1611 | | /* Dissect additional management fields (when applicable) */ |
1612 | 0 | if (offset < header.length) { |
1613 | 0 | dissect_mausb_mgmt_pkt_flds(&header, mausb_tree, tvb, pinfo, offset); |
1614 | 0 | } |
1615 | |
|
1616 | 0 | } |
1617 | 0 | else if (mausb_is_data_pkt(&header)) { |
1618 | 0 | dissect_mausb_pkt_data(tvb, offset, pinfo, mausb_tree, &header); |
1619 | |
|
1620 | 0 | if (!mausb_is_transfer_ack(&header)) { |
1621 | 0 | dissect_usb_common(tvb, pinfo, tree, USB_HEADER_MAUSB, &header); |
1622 | 0 | } |
1623 | 0 | } |
1624 | |
|
1625 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "]"); |
1626 | 0 | col_set_fence(pinfo->cinfo, COL_INFO); |
1627 | |
|
1628 | 0 | return header.length; |
1629 | 0 | } |
1630 | | |
1631 | | /* Code to dissect the stream */ |
1632 | | static int |
1633 | | dissect_mausb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
1634 | 0 | { |
1635 | |
|
1636 | 0 | mausb_num_pdus = 0; |
1637 | |
|
1638 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, true, MAUSB_MIN_LENGTH, |
1639 | 0 | mausb_get_pkt_len, dissect_mausb_pkt, data); |
1640 | |
|
1641 | 0 | if (1 < mausb_num_pdus) { |
1642 | 0 | col_clear_fence(pinfo->cinfo, COL_INFO); |
1643 | 0 | col_prepend_fstr(pinfo->cinfo, COL_INFO, "[%i packets] ", mausb_num_pdus); |
1644 | 0 | } |
1645 | |
|
1646 | 0 | return tvb_reported_length(tvb); |
1647 | 0 | } |
1648 | | |
1649 | | |
1650 | | /* Register the protocol with Wireshark. |
1651 | | */ |
1652 | | void |
1653 | | proto_register_mausb(void) |
1654 | 16 | { |
1655 | | |
1656 | 16 | static hf_register_info hf[] = { |
1657 | 16 | { &hf_mausb_version, |
1658 | 16 | { "Version", "mausb.version", FT_UINT8, BASE_DEC, |
1659 | 16 | VALS(mausb_version_string), MAUSB_VERSION_MASK, NULL, HFILL |
1660 | 16 | } |
1661 | 16 | }, |
1662 | 16 | { &hf_mausb_flags, |
1663 | 16 | { "Flags", "mausb.flags", FT_UINT8, BASE_HEX, |
1664 | 16 | NULL, MAUSB_FLAG_MASK, NULL, HFILL |
1665 | 16 | } |
1666 | 16 | }, |
1667 | | |
1668 | | /* Flag Subfields */ |
1669 | 16 | { &hf_mausb_flag_host, |
1670 | 16 | { "Host", "mausb.flags.host", FT_BOOLEAN, 8, |
1671 | 16 | TFS(&tfs_set_notset), (MAUSB_FLAG_HOST << MAUSB_FLAG_OFFSET), |
1672 | 16 | NULL, HFILL |
1673 | 16 | } |
1674 | 16 | }, |
1675 | 16 | { &hf_mausb_flag_retry, |
1676 | 16 | { "Retry", "mausb.flags.retry", FT_BOOLEAN, 8, |
1677 | 16 | TFS(&tfs_yes_no), (MAUSB_FLAG_RETRY << MAUSB_FLAG_OFFSET), |
1678 | 16 | NULL, HFILL |
1679 | 16 | } |
1680 | 16 | }, |
1681 | 16 | { &hf_mausb_flag_timestamp, |
1682 | 16 | { "Timestamp", "mausb.flags.timestamp", FT_BOOLEAN, 8, |
1683 | 16 | TFS(&tfs_present_not_present), |
1684 | 16 | (MAUSB_FLAG_TIMESTAMP << MAUSB_FLAG_OFFSET), |
1685 | 16 | NULL, HFILL |
1686 | 16 | } |
1687 | 16 | }, |
1688 | 16 | { &hf_mausb_flag_reserved, |
1689 | 16 | { "Reserved", "mausb.flags.reserved", FT_BOOLEAN, 8, |
1690 | 16 | TFS(&tfs_set_notset), (MAUSB_FLAG_RESERVED << MAUSB_FLAG_OFFSET), |
1691 | 16 | NULL, HFILL |
1692 | 16 | } |
1693 | 16 | }, |
1694 | | |
1695 | | |
1696 | 16 | { &hf_mausb_type, |
1697 | 16 | { "Type", "mausb.type", FT_UINT8, BASE_HEX, |
1698 | 16 | VALS(mausb_type_string), 0, NULL, HFILL |
1699 | 16 | } |
1700 | 16 | }, |
1701 | 16 | { &hf_mausb_length, |
1702 | 16 | { "Length", "mausb.length", FT_UINT16, BASE_DEC, |
1703 | 16 | NULL, 0, NULL, HFILL |
1704 | 16 | } |
1705 | 16 | }, |
1706 | 16 | { &hf_mausb_dev_handle, |
1707 | 16 | { "Device Handle", "mausb.dev_handle", FT_UINT16, BASE_HEX, |
1708 | 16 | NULL, 0, NULL, HFILL |
1709 | 16 | } |
1710 | 16 | }, |
1711 | 16 | { &hf_mausb_ep_handle, |
1712 | 16 | { "Endpoint Handle", "mausb.ep_handle", FT_UINT16, BASE_HEX, |
1713 | 16 | NULL, 0, NULL, HFILL |
1714 | 16 | } |
1715 | 16 | }, |
1716 | | |
1717 | | /* EP Handle Subfields */ |
1718 | 16 | { &hf_mausb_ep_handle_d, |
1719 | 16 | { "Direction", "mausb.ep_handle.d", FT_BOOLEAN, 16, |
1720 | 16 | TFS(&tfs_endpoint_direction), MAUSB_EP_HANDLE_D, NULL, HFILL |
1721 | 16 | } |
1722 | 16 | }, |
1723 | 16 | { &hf_mausb_ep_handle_ep_num, |
1724 | 16 | { "Endpoint Number", "mausb.ep_handle.ep_num", FT_UINT16, BASE_DEC, |
1725 | 16 | NULL, MAUSB_EP_HANDLE_EP_NUM, NULL, HFILL |
1726 | 16 | } |
1727 | 16 | }, |
1728 | 16 | { &hf_mausb_ep_handle_dev_addr, |
1729 | 16 | { "USB Device Address", "mausb.ep_handle.dev_addr", FT_UINT16, BASE_DEC, |
1730 | 16 | NULL, MAUSB_EP_HANDLE_DEV_ADDR, NULL, HFILL |
1731 | 16 | } |
1732 | 16 | }, |
1733 | 16 | { &hf_mausb_ep_handle_bus_num, |
1734 | 16 | { "USB Bus Number", "mausb.ep_handle.bus_num", FT_UINT16, BASE_DEC, |
1735 | 16 | NULL, MAUSB_EP_HANDLE_BUS_NUM, NULL, HFILL |
1736 | 16 | } |
1737 | 16 | }, |
1738 | | |
1739 | | |
1740 | 16 | { &hf_mausb_ma_dev_addr, |
1741 | 16 | { "MA Device Address", "mausb.ma_dev_addr", FT_UINT8, BASE_HEX, |
1742 | 16 | NULL, 0, NULL, HFILL |
1743 | 16 | } |
1744 | 16 | }, |
1745 | 16 | { &hf_mausb_ssid, |
1746 | 16 | { "Service Set ID", "mausb.ssid", FT_UINT8, BASE_HEX, |
1747 | 16 | NULL, 0, NULL, HFILL |
1748 | 16 | } |
1749 | 16 | }, |
1750 | 16 | { &hf_mausb_status, |
1751 | 16 | { "Status", "mausb.status", FT_UINT8, BASE_DEC, |
1752 | 16 | VALS(mausb_status_string), 0, NULL, HFILL |
1753 | 16 | } |
1754 | 16 | }, |
1755 | | |
1756 | | /* Management Packets Only */ |
1757 | 16 | { &hf_mausb_token, |
1758 | 16 | { "Token", "mausb.token", FT_UINT16, BASE_DEC, |
1759 | 16 | NULL, MAUSB_TOKEN_MASK, NULL, HFILL |
1760 | 16 | } |
1761 | 16 | }, |
1762 | 16 | { &hf_mausb_mgmt_pad, |
1763 | 16 | { "Padding to a DWORD", "mausb.mgmt_pad", |
1764 | 16 | FT_UINT16, BASE_HEX, NULL, MAUSB_MGMT_PAD_MASK, |
1765 | 16 | NULL, HFILL |
1766 | 16 | } |
1767 | 16 | }, |
1768 | 16 | { &hf_mausb_mgmt_type_spec, |
1769 | 16 | { "Type-specific management packet fields", "mausb.mgmt_flds", |
1770 | 16 | FT_NONE, 0, NULL, 0, NULL, HFILL |
1771 | 16 | } |
1772 | 16 | }, |
1773 | 16 | { &hf_mausb_mgmt_type_spec_generic, |
1774 | 16 | { "Type-specific management packet fields", "mausb.mgmt_flds.generic", |
1775 | 16 | FT_NONE, 0, NULL, 0, NULL, HFILL |
1776 | 16 | } |
1777 | 16 | }, |
1778 | | |
1779 | | /* Data Packets Only */ |
1780 | 16 | { &hf_mausb_eps, |
1781 | 16 | { "EP Status", "mausb.eps", FT_UINT8, BASE_HEX, |
1782 | 16 | VALS(mausb_eps_string), MAUSB_EPS_MASK, NULL, HFILL |
1783 | 16 | } |
1784 | 16 | }, |
1785 | 16 | { &hf_mausb_eps_rsvd, |
1786 | 16 | { "EP Status", "mausb.eps.reserved", FT_UINT8, BASE_HEX, |
1787 | 16 | NULL, MAUSB_EPS_MASK, NULL, HFILL |
1788 | 16 | } |
1789 | 16 | }, |
1790 | 16 | { &hf_mausb_tflags, |
1791 | 16 | { "Transfer Flags", "mausb.tflag", FT_UINT8, BASE_HEX, |
1792 | 16 | NULL, MAUSB_TFLAG_MASK, NULL, HFILL |
1793 | 16 | } |
1794 | 16 | }, |
1795 | | |
1796 | | /* T-Flag Subfields */ |
1797 | 16 | { &hf_mausb_tflag_arq, |
1798 | 16 | { "ARQ", "mausb.tflag.arq", FT_BOOLEAN, 8, |
1799 | 16 | TFS(&tfs_set_notset), MAUSB_TFLAG_ARQ << MAUSB_TFLAG_OFFSET, |
1800 | 16 | NULL, HFILL |
1801 | 16 | } |
1802 | 16 | }, |
1803 | 16 | { &hf_mausb_tflag_neg, |
1804 | 16 | { "NEG", "mausb.tflag.neg", FT_BOOLEAN, 8, |
1805 | 16 | TFS(&tfs_set_notset), MAUSB_TFLAG_NEG << MAUSB_TFLAG_OFFSET, |
1806 | 16 | NULL, HFILL |
1807 | 16 | } |
1808 | 16 | }, |
1809 | 16 | { &hf_mausb_tflag_eot, |
1810 | 16 | { "EoT", "mausb.tflag.eot", FT_BOOLEAN, 8, |
1811 | 16 | TFS(&tfs_set_notset), MAUSB_TFLAG_EOT << MAUSB_TFLAG_OFFSET, |
1812 | 16 | NULL, HFILL |
1813 | 16 | } |
1814 | 16 | }, |
1815 | 16 | { &hf_mausb_tflag_type, |
1816 | 16 | { "Transfer Type", "mausb.tflag.type", FT_UINT8, BASE_HEX, |
1817 | 16 | VALS(mausb_transfer_type_string), |
1818 | 16 | MAUSB_TFLAG_TRANSFER_TYPE << MAUSB_TFLAG_OFFSET, |
1819 | 16 | NULL, HFILL |
1820 | 16 | } |
1821 | 16 | }, |
1822 | 16 | { &hf_mausb_tflag_rsvd, |
1823 | 16 | { "Reserved", "mausb.tflag.rsvd", FT_BOOLEAN, 8, |
1824 | 16 | TFS(&tfs_set_notset), MAUSB_TFLAG_RSVD << MAUSB_TFLAG_OFFSET, |
1825 | 16 | NULL, HFILL |
1826 | 16 | } |
1827 | 16 | }, |
1828 | | |
1829 | | |
1830 | 16 | { &hf_mausb_num_iso_hdr, |
1831 | 16 | { "Number of Iso Headers", "mausb.numisohdr", FT_UINT16, BASE_DEC, |
1832 | 16 | NULL, MAUSB_NUM_ISO_HDR_MASK, NULL, HFILL |
1833 | 16 | } |
1834 | 16 | }, |
1835 | 16 | { &hf_mausb_iflags, |
1836 | 16 | { "Isochronous Flags", "mausb.iflag", FT_UINT16, BASE_HEX, |
1837 | 16 | NULL, MAUSB_IFLAG_MASK, NULL, HFILL |
1838 | 16 | } |
1839 | 16 | }, |
1840 | | |
1841 | | /* I-Flag Subfields */ |
1842 | 16 | { &hf_mausb_iflag_mtd, |
1843 | 16 | { "MTD Valid", "mausb.iflag.mtd", FT_BOOLEAN, 8, |
1844 | 16 | TFS(&tfs_set_notset), MAUSB_IFLAG_MTD << MAUSB_IFLAG_OFFSET, |
1845 | 16 | NULL, HFILL |
1846 | 16 | } |
1847 | 16 | }, |
1848 | 16 | { &hf_mausb_iflag_hdr_format, |
1849 | 16 | { "Isochronous Header Format", "mausb.iflag.ihf", FT_UINT8, BASE_HEX, |
1850 | 16 | NULL, MAUSB_IFLAG_HDR_FORMAT << MAUSB_IFLAG_OFFSET, NULL, HFILL |
1851 | 16 | } |
1852 | 16 | }, |
1853 | 16 | { &hf_mausb_iflag_asap, |
1854 | 16 | { "ASAP", "mausb.iflag.asap", FT_BOOLEAN, 8, |
1855 | 16 | TFS(&tfs_set_notset), MAUSB_IFLAG_ASAP << MAUSB_IFLAG_OFFSET, |
1856 | 16 | NULL, HFILL |
1857 | 16 | } |
1858 | 16 | }, |
1859 | | |
1860 | 16 | { &hf_mausb_stream_id, |
1861 | 16 | { "Stream ID", "mausb.streamid", FT_UINT16, BASE_DEC, |
1862 | 16 | NULL, 0, NULL, HFILL |
1863 | 16 | } |
1864 | 16 | }, |
1865 | 16 | { &hf_mausb_seq_num, |
1866 | 16 | { "Sequence Number", "mausb.seqnum", FT_UINT24, BASE_DEC, |
1867 | 16 | NULL, 0, NULL, HFILL |
1868 | 16 | } |
1869 | 16 | }, |
1870 | 16 | { &hf_mausb_req_id, |
1871 | 16 | { "Request ID", "mausb.reqid", FT_UINT8, BASE_DEC, |
1872 | 16 | NULL, 0, NULL, HFILL |
1873 | 16 | } |
1874 | 16 | }, |
1875 | 16 | { &hf_mausb_present_time, |
1876 | 16 | { "Presentation Time", "mausb.presenttime", FT_UINT32, BASE_DEC, |
1877 | 16 | NULL, MAUSB_PRESENT_TIME_MASK, NULL, HFILL |
1878 | 16 | } |
1879 | 16 | }, |
1880 | 16 | { &hf_mausb_uframe, |
1881 | 16 | { "Microframe Number", "mausb.uframe", FT_UINT32, BASE_DEC, |
1882 | 16 | NULL, MAUSB_UFRAME_MASK, NULL, HFILL |
1883 | 16 | } |
1884 | 16 | }, |
1885 | 16 | { &hf_mausb_frame, |
1886 | 16 | { "Frame Number", "mausb.frame", FT_UINT32, BASE_DEC, |
1887 | 16 | NULL, MAUSB_FRAME_MASK, NULL, HFILL |
1888 | 16 | } |
1889 | 16 | }, |
1890 | 16 | { &hf_mausb_num_segs, |
1891 | 16 | { "Number of Segments", "mausb.numseg", FT_UINT32, BASE_DEC, |
1892 | 16 | NULL, MAUSB_NUM_SEGS_MASK, NULL, HFILL |
1893 | 16 | } |
1894 | 16 | }, |
1895 | 16 | { &hf_mausb_timestamp, |
1896 | 16 | { "Timestamp", "mausb.timestamp", FT_UINT32, BASE_DEC, |
1897 | 16 | NULL, 0, NULL, HFILL |
1898 | 16 | } |
1899 | 16 | }, |
1900 | 16 | { &hf_mausb_delta, |
1901 | 16 | { "Delta", "mausb.delta", FT_UINT32, BASE_DEC, |
1902 | 16 | NULL, MAUSB_DELTA_MASK, NULL, HFILL |
1903 | 16 | } |
1904 | 16 | }, |
1905 | 16 | { &hf_mausb_nom_interval, |
1906 | 16 | { "Nominal Bus Interval", "mausb.nomitvl", FT_UINT32, BASE_DEC, |
1907 | 16 | NULL, MAUSB_INTERVAL_MASK, NULL, HFILL |
1908 | 16 | } |
1909 | 16 | }, |
1910 | 16 | { &hf_mausb_mtd, |
1911 | 16 | { "Media Time/Transmission Delay", "mausb.mtd", FT_UINT32, BASE_DEC, |
1912 | 16 | NULL, 0, NULL, HFILL |
1913 | 16 | } |
1914 | 16 | }, |
1915 | 16 | { &hf_mausb_rem_size_credit, |
1916 | 16 | { "Remaining Size/Credit", "mausb.remsize_credit", FT_UINT32, BASE_DEC, |
1917 | 16 | NULL, 0, NULL, HFILL |
1918 | 16 | } |
1919 | 16 | }, |
1920 | 16 | }; |
1921 | | |
1922 | | |
1923 | | /* Register info for CapReq/Resp specific fields */ |
1924 | 16 | static hf_register_info hf_cap[] = { |
1925 | | |
1926 | 16 | { &hf_mausb_cap_resp_num_ep, |
1927 | 16 | { "Number of Endpoints", "mausb.cap_resp.num_ep", |
1928 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1929 | 16 | "the maximum number of endpoints for this device", |
1930 | 16 | HFILL |
1931 | 16 | } |
1932 | 16 | }, |
1933 | 16 | { &hf_mausb_cap_resp_num_dev, |
1934 | 16 | { "Number of Devices", "mausb.cap_resp.num_dev", |
1935 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
1936 | 16 | "the maximum number of USB devices the MA USB device can manage", |
1937 | 16 | HFILL |
1938 | 16 | } |
1939 | 16 | }, |
1940 | 16 | { &hf_mausb_cap_resp_num_stream, |
1941 | 16 | { "Number of Streams", "mausb.cap_resp.num_stream", |
1942 | 16 | FT_UINT8, BASE_DEC, NULL, MAUSB_CAP_RESP_NUM_STREAM_MASK, |
1943 | 16 | "2 to the power of this value is the max number of streams supported", |
1944 | | /* TODO: have dissector print the actual number of streams supported */ |
1945 | 16 | HFILL |
1946 | 16 | } |
1947 | 16 | }, |
1948 | 16 | { &hf_mausb_cap_resp_dev_type, |
1949 | 16 | { "Device Type", "mausb.cap_resp.dev_type", FT_UINT8, BASE_HEX, |
1950 | 16 | VALS(mausb_cap_resp_dev_type), MAUSB_CAP_RESP_DEV_TYPE_MASK, |
1951 | 16 | NULL, HFILL |
1952 | 16 | } |
1953 | 16 | }, |
1954 | 16 | { &hf_mausb_cap_resp_desc_count, |
1955 | 16 | { "Descriptors Count", "mausb.cap_resp.desc_count", |
1956 | 16 | FT_UINT8, BASE_DEC, |
1957 | 16 | NULL, 0, "The total number of MA Device Capabilities descriptors", |
1958 | 16 | HFILL |
1959 | 16 | } |
1960 | 16 | }, |
1961 | 16 | { &hf_mausb_cap_resp_desc_len, |
1962 | 16 | { "Descriptors Length", "mausb.cap_resp.desc_len", |
1963 | 16 | FT_UINT24, BASE_DEC, |
1964 | 16 | NULL, 0, "The total size of MA Device Capabilities descriptors", |
1965 | 16 | HFILL |
1966 | 16 | } |
1967 | 16 | }, |
1968 | 16 | { &hf_mausb_cap_resp_transfer_req, |
1969 | 16 | { "Number of Outstanding Transfer Requests", |
1970 | 16 | "mausb.cap_resp.transfer_req", |
1971 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
1972 | 16 | "The maximum number of total outstanding transfer requests", HFILL |
1973 | 16 | } |
1974 | 16 | }, |
1975 | 16 | { &hf_mausb_cap_resp_mgmt_req, |
1976 | 16 | { "Number of Outstanding Management Requests", "mausb.cap_resp.mgmt_req", |
1977 | 16 | FT_UINT16, BASE_DEC, NULL, |
1978 | 16 | MAUSB_CAP_RESP_MGMT_REQ_MASK, |
1979 | 16 | "The maximum number of host initiated outstanding management requests", |
1980 | 16 | HFILL |
1981 | 16 | } |
1982 | 16 | }, |
1983 | 16 | { &hf_mausb_cap_resp_rsvd, |
1984 | 16 | { "Reserved", "mausb.cap_resp.rsvd", FT_UINT16, BASE_HEX, |
1985 | 16 | NULL, MAUSB_CAP_RESP_RSVD_MASK, NULL, HFILL |
1986 | 16 | } |
1987 | 16 | }, |
1988 | | |
1989 | | /* Device Capability Descriptors */ |
1990 | 16 | { &hf_mausb_dev_cap_len, |
1991 | 16 | { "Length", "mausb.cap_resp.dev_cap.length", |
1992 | 16 | FT_UINT8, BASE_DEC, NULL, |
1993 | 16 | 0, NULL, HFILL |
1994 | 16 | } |
1995 | 16 | }, |
1996 | 16 | { &hf_mausb_dev_cap_type, |
1997 | 16 | { "Type", "mausb.cap_resp.dev_cap.type", |
1998 | 16 | FT_UINT8, BASE_DEC, VALS(mausb_dev_cap_string), |
1999 | 16 | 0, NULL, HFILL |
2000 | 16 | } |
2001 | 16 | }, |
2002 | 16 | { &hf_mausb_dev_cap_generic, |
2003 | 16 | { "Type-specific device capability descriptor fields", |
2004 | 16 | "mausb.cap_resp.dev_cap.generic", |
2005 | 16 | FT_NONE, 0, NULL, 0, NULL, HFILL |
2006 | 16 | } |
2007 | 16 | } |
2008 | 16 | }; |
2009 | | |
2010 | | |
2011 | | /* register info for ep_handle_* specific fields */ |
2012 | 16 | static hf_register_info hf_ep_handle[] = { |
2013 | 16 | { &hf_mausb_mgmt_ep_handle_num, |
2014 | 16 | { "Number of Endpoint Handles", "mausb.ep_handle_num", |
2015 | 16 | FT_UINT8, BASE_DEC, |
2016 | 16 | NULL, MAUSB_MGMT_NUM_EP_DES_MASK, NULL, HFILL |
2017 | 16 | } |
2018 | 16 | }, |
2019 | 16 | { &hf_mausb_mgmt_ep_handle_pad, |
2020 | 16 | { "Padding to a DWORD", "mausb.ep_handle_pad", |
2021 | 16 | FT_NONE, 0, |
2022 | 16 | NULL, 0x0, NULL, HFILL |
2023 | 16 | } |
2024 | 16 | }, |
2025 | 16 | { &hf_mausb_mgmt_ep_des_num, |
2026 | 16 | { "Number of Endpoint Descriptors", "mausb.ep_des_num", |
2027 | 16 | FT_UINT8, BASE_DEC, |
2028 | 16 | NULL, MAUSB_MGMT_NUM_EP_DES_MASK, NULL, HFILL |
2029 | 16 | } |
2030 | 16 | }, |
2031 | 16 | { &hf_mausb_mgmt_ep_des_size, |
2032 | 16 | { "Size of Endpoint Descriptors", "mausb.ep_des_size", |
2033 | 16 | FT_UINT16, BASE_DEC, |
2034 | 16 | NULL, MAUSB_MGMT_SIZE_EP_DES_MASK, NULL, HFILL |
2035 | 16 | } |
2036 | 16 | }, |
2037 | 16 | { &hf_mausb_mgmt_ep_des_pad, |
2038 | 16 | { "Padding to a DWORD", "mausb.ep_des_pad", |
2039 | 16 | FT_NONE, 0, NULL, |
2040 | 16 | 0x0, |
2041 | 16 | NULL, HFILL |
2042 | 16 | } |
2043 | 16 | }, |
2044 | | |
2045 | 16 | { &hf_mausb_ep_handle_req_pad, |
2046 | 16 | { "Padding to a DWORD", "mausb.ep_handle_req.pad", |
2047 | 16 | FT_NONE, 0, NULL, 0, NULL, HFILL |
2048 | 16 | } |
2049 | 16 | }, |
2050 | 16 | { &hf_mausb_ep_handle_resp_dir, |
2051 | 16 | { "Direction", "mausb.ep_dir", FT_BOOLEAN, 6, |
2052 | 16 | TFS(&tfs_ep_handle_resp_dir), MAUSB_EP_HANDLE_RESP_DIR_MASK, |
2053 | 16 | NULL, HFILL |
2054 | 16 | } |
2055 | 16 | }, |
2056 | 16 | { &hf_mausb_ep_handle_resp_iso, |
2057 | 16 | { "Isochronous", "mausb.ep_iso", FT_BOOLEAN, 6, |
2058 | 16 | TFS(&tfs_yes_no), MAUSB_EP_HANDLE_RESP_ISO_MASK, NULL, HFILL |
2059 | 16 | } |
2060 | 16 | }, |
2061 | 16 | { &hf_mausb_ep_handle_resp_lman, |
2062 | 16 | { "L-Managed", "mausb.ep_lman", FT_BOOLEAN, 6, |
2063 | 16 | TFS(&tfs_supported_not_supported), MAUSB_EP_HANDLE_RESP_LMAN_MASK, |
2064 | 16 | NULL, HFILL |
2065 | 16 | } |
2066 | 16 | }, |
2067 | 16 | { &hf_mausb_ep_handle_resp_valid, |
2068 | 16 | { "Valid", "mausb.ep_valid", FT_BOOLEAN, 6, |
2069 | 16 | TFS(&tfs_invalid_valid), MAUSB_EP_HANDLE_RESP_VALID_MASK, |
2070 | 16 | NULL, HFILL |
2071 | 16 | } |
2072 | 16 | }, |
2073 | 16 | { &hf_mausb_ep_handle_resp_ccu, |
2074 | 16 | { "CCU", "mausb.ep_ccu", FT_UINT16, BASE_DEC, |
2075 | 16 | NULL, 0, NULL, HFILL |
2076 | 16 | } |
2077 | 16 | }, |
2078 | 16 | { &hf_mausb_ep_handle_resp_buf_size, |
2079 | 16 | { "Buffer Size", "mausb.ep_buf_size", FT_UINT32, BASE_DEC, |
2080 | 16 | NULL, 0, NULL, HFILL |
2081 | 16 | } |
2082 | 16 | }, |
2083 | 16 | { &hf_mausb_ep_handle_resp_iso_prog_dly, |
2084 | 16 | { "Iso Programming Delay", "mausb.ep_iso_prog_dly", FT_UINT16, BASE_DEC, |
2085 | 16 | NULL, 0, NULL, HFILL |
2086 | 16 | } |
2087 | 16 | }, |
2088 | 16 | { &hf_mausb_ep_handle_resp_iso_resp_dly, |
2089 | 16 | { "Iso Response Delay", "mausb.ep_iso_resp_dly", FT_UINT16, BASE_DEC, |
2090 | 16 | NULL, 0, NULL, HFILL |
2091 | 16 | } |
2092 | 16 | } |
2093 | | |
2094 | | |
2095 | 16 | }; |
2096 | | |
2097 | | /* (Cancel/Clear)Transfer(Req/Resp) specific fields */ |
2098 | 16 | static hf_register_info hf_cancel_transfer[] = { |
2099 | 16 | { &hf_mausb_clear_transfers_info_block, |
2100 | 16 | { "Clear Transfers Information Block", "mausb.clear_transfers.info", FT_NONE, 0, |
2101 | 16 | NULL, 0, NULL, HFILL |
2102 | 16 | } |
2103 | 16 | }, |
2104 | 16 | { &hf_mausb_clear_transfers_status_block, |
2105 | 16 | { "Cancel Transfers Status Block", "mausb.clear_transfers.status_block", FT_NONE, 0, |
2106 | 16 | NULL, 0, NULL, HFILL |
2107 | 16 | } |
2108 | 16 | }, |
2109 | 16 | { &hf_mausb_cancel_transfer_rsvd, |
2110 | 16 | { "Reserved", "mausb.cancel_transfer.rsvd", FT_NONE, 0, |
2111 | 16 | NULL, 0, NULL, HFILL |
2112 | 16 | } |
2113 | 16 | }, |
2114 | 16 | { &hf_mausb_clear_transfers_req_num, |
2115 | 16 | { "Number of Blocks", "mausb.clear_transfers_req.num", FT_UINT8, BASE_DEC, |
2116 | 16 | NULL, 0, NULL, HFILL |
2117 | 16 | } |
2118 | 16 | }, |
2119 | 16 | { &hf_mausb_clear_transfers_req_rsvd, |
2120 | 16 | { "Reserved", "mausb.clear_transfers_req.rsvd", FT_NONE, 0, |
2121 | 16 | NULL, 0, NULL, HFILL |
2122 | 16 | } |
2123 | 16 | }, |
2124 | 16 | { &hf_mausb_clear_transfers_resp_num, |
2125 | 16 | { "Number of Blocks", "mausb.clear_transfers_resp.num", FT_UINT32, BASE_DEC, |
2126 | 16 | NULL, MAUSB_CLEAR_TRANSFERS_RESP_NUM_MASK , NULL, HFILL |
2127 | 16 | } |
2128 | 16 | }, |
2129 | 16 | { &hf_mausb_clear_transfers_resp_rsvd, |
2130 | 16 | { "Reserved", "mausb.clear_transfers_resp.rsvd", FT_UINT32, BASE_HEX, |
2131 | 16 | NULL, ~MAUSB_CLEAR_TRANSFERS_RESP_NUM_MASK, NULL, HFILL |
2132 | 16 | } |
2133 | 16 | }, |
2134 | 16 | { &hf_mausb_cancel_transfer_status, |
2135 | 16 | { "Status", "mausb.cancel_transfer.status", FT_UINT24, BASE_HEX, |
2136 | 16 | VALS(mausb_cancel_transfer_status_string), |
2137 | 16 | MAUSB_CANCEL_TRANSFER_STATUS_MASK, NULL, HFILL |
2138 | 16 | } |
2139 | 16 | }, |
2140 | 16 | { &hf_mausb_cancel_transfer_rsvd_2, |
2141 | 16 | { "Reserved", "mausb.cancel_transfer.rsvd_2", FT_UINT24, BASE_HEX, |
2142 | 16 | NULL, ~MAUSB_CANCEL_TRANSFER_STATUS_MASK, NULL, HFILL |
2143 | 16 | } |
2144 | 16 | }, |
2145 | 16 | { &hf_mausb_clear_transfers_status, |
2146 | 16 | { "Cancellation Status", "mausb.clear_transfers.status", FT_BOOLEAN, 6, |
2147 | 16 | TFS(&tfs_success_fail), MAUSB_CLEAR_TRANSFERS_STATUS_MASK, |
2148 | 16 | NULL, HFILL |
2149 | 16 | } |
2150 | 16 | }, |
2151 | 16 | { &hf_mausb_clear_transfers_partial, |
2152 | 16 | { "Partial Delivery", "mausb.clear_transfers.partial", FT_BOOLEAN, 6, |
2153 | 16 | NULL, MAUSB_CLEAR_TRANSFERS_PARTIAL_MASK, |
2154 | 16 | NULL, HFILL |
2155 | 16 | } |
2156 | 16 | }, |
2157 | 16 | { &hf_mausb_clear_transfers_start_req_id, |
2158 | 16 | { "Start Request ID", "mausb.clear_transfers.start_reqid", FT_UINT8, BASE_DEC, |
2159 | 16 | NULL, 0, NULL, HFILL |
2160 | 16 | } |
2161 | 16 | }, |
2162 | 16 | { &hf_mausb_clear_transfers_last_req_id, |
2163 | 16 | { "Last Request ID", "mausb.clear_transfers.last_reqid", FT_UINT8, BASE_DEC, |
2164 | 16 | NULL, 0, NULL, HFILL |
2165 | 16 | } |
2166 | 16 | }, |
2167 | 16 | { &hf_mausb_clear_transfers_req_block_rsvd, |
2168 | 16 | { "Reserved", "mausb.clear_transfers_req.block_rsvd", FT_NONE, 0, |
2169 | 16 | NULL, 0, NULL, HFILL |
2170 | 16 | } |
2171 | 16 | }, |
2172 | 16 | { &hf_mausb_clear_transfers_resp_block_rsvd, |
2173 | 16 | { "Reserved", "mausb.clear_transfers_resp.block_rsvd", FT_UINT32, BASE_HEX, |
2174 | 16 | NULL, MAUSB_CLEAR_TRANSFERS_RESP_BLOCK_RSVD_MASK, NULL, HFILL |
2175 | 16 | } |
2176 | 16 | }, |
2177 | | |
2178 | 16 | { &hf_mausb_cancel_transfer_seq_num, |
2179 | 16 | { "Delivered Sequence Number", "mausb.cancel_transfer.seqnum", |
2180 | 16 | FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL |
2181 | 16 | } |
2182 | 16 | }, |
2183 | 16 | { &hf_mausb_cancel_transfer_byte_offset, |
2184 | 16 | { "Delivered Byte Offset", "mausb.cancel_transfer.byte_offset", |
2185 | 16 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL |
2186 | 16 | } |
2187 | 16 | }, |
2188 | 16 | }; |
2189 | | |
2190 | 16 | static hf_register_info oui_hf[] = { |
2191 | 16 | { &hf_llc_mausb_pid, |
2192 | 16 | { "PID", "mausb.pid", FT_UINT16, BASE_HEX, |
2193 | 16 | VALS(mausb_pid_string), 0x0, NULL, HFILL } |
2194 | 16 | } |
2195 | 16 | }; |
2196 | | |
2197 | | /* Setup protocol subtree array */ |
2198 | 16 | static int *ett[] = { |
2199 | 16 | &ett_mausb, |
2200 | 16 | &ett_mausb_flags, |
2201 | 16 | &ett_mausb_ep_handle, |
2202 | 16 | &ett_mausb_tflags, |
2203 | 16 | &ett_mausb_iflags, |
2204 | 16 | &ett_mausb_present_time, |
2205 | 16 | &ett_mausb_timestamp, |
2206 | 16 | &ett_mgmt, |
2207 | 16 | &ett_dev_cap, |
2208 | 16 | &ett_clear_transfers_block |
2209 | 16 | }; |
2210 | | |
2211 | 16 | static ei_register_info ei[] = { |
2212 | 16 | { &ei_ep_handle_len, |
2213 | 16 | { "mausb.ei.ep_handle.length", PI_PROTOCOL, PI_WARN, |
2214 | 16 | "Invalid Endpoint handle length field", EXPFILL } |
2215 | 16 | }, |
2216 | 16 | { &ei_len, |
2217 | 16 | { "mausb.ei.length", PI_MALFORMED, PI_ERROR, |
2218 | 16 | "Packet length field does not match size of packet", EXPFILL } |
2219 | 16 | }, |
2220 | 16 | { &ei_mgmt_type_undef, |
2221 | 16 | { "mausb.ei.type", PI_PROTOCOL, PI_WARN, |
2222 | 16 | "Undefined management packet type", EXPFILL } |
2223 | 16 | }, |
2224 | 16 | { &ei_mgmt_type_spec_len_long, |
2225 | 16 | { "mausb.ei.type_spec.len_long", PI_PROTOCOL, PI_WARN, |
2226 | 16 | "Data exists after type-specific management packet field", EXPFILL } |
2227 | 16 | }, |
2228 | 16 | { &ei_mgmt_type_spec_len_short, |
2229 | 16 | { "mausb.ei.type_spec.len", PI_PROTOCOL, PI_WARN, |
2230 | 16 | "Expected type-specific management packet data", EXPFILL } |
2231 | 16 | }, |
2232 | 16 | { &ei_dev_cap_len, |
2233 | 16 | { "mausb.ei.cap_resp.dev_cap.length", PI_PROTOCOL, PI_WARN, |
2234 | 16 | "Incorrect length value for this device capability descriptor", |
2235 | 16 | EXPFILL } |
2236 | 16 | }, |
2237 | 16 | { &ei_dev_cap_resp_desc_len, |
2238 | 16 | { "mausb.ei.dev_cap_resp.desc_len", PI_PROTOCOL, PI_WARN, |
2239 | 16 | "Incorrect value in Device Descriptors Length field", EXPFILL } |
2240 | 16 | }, |
2241 | 16 | { &ei_cap_resp_desc_len, |
2242 | 16 | { "mausb.ei.cap_resp.desc_len", PI_PROTOCOL, PI_WARN, |
2243 | 16 | "Value in Descriptors Length field exceeds actual space in packet", EXPFILL } |
2244 | 16 | }, |
2245 | 16 | }; |
2246 | | |
2247 | 16 | expert_module_t* expert_mausb; |
2248 | | |
2249 | | /* Register the protocol name and description */ |
2250 | 16 | proto_mausb = proto_register_protocol("Media Agnostic USB", "MAUSB", "mausb"); |
2251 | | |
2252 | | /* Required function calls to register the header fields and subtrees */ |
2253 | 16 | proto_register_field_array(proto_mausb, hf, array_length(hf)); |
2254 | 16 | proto_register_field_array(proto_mausb, hf_cap, array_length(hf_cap)); |
2255 | 16 | proto_register_field_array(proto_mausb, hf_ep_handle, array_length(hf_ep_handle)); |
2256 | 16 | proto_register_field_array(proto_mausb, hf_cancel_transfer, array_length(hf_cancel_transfer)); |
2257 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
2258 | | |
2259 | | /* for Expert info */ |
2260 | 16 | expert_mausb = expert_register_protocol(proto_mausb); |
2261 | 16 | expert_register_field_array(expert_mausb, ei, array_length(ei)); |
2262 | | |
2263 | 16 | llc_add_oui(OUI_WFA, "llc.wfa_pid", "LLC WFA OUI PID", oui_hf, proto_mausb); |
2264 | | |
2265 | | /* Register the dissectors */ |
2266 | 16 | mausb_tcp_handle = register_dissector("mausb", dissect_mausb, proto_mausb); |
2267 | 16 | mausb_pkt_handle = register_dissector("mausb.pkt", dissect_mausb_pkt, proto_mausb); |
2268 | | |
2269 | 16 | } |
2270 | | |
2271 | | void |
2272 | | proto_reg_handoff_mausb(void) |
2273 | 16 | { |
2274 | 16 | dissector_add_uint("llc.wfa_pid", PID_MAUSB, mausb_pkt_handle); |
2275 | | |
2276 | 16 | dissector_add_uint_range_with_preference("tcp.port", "", mausb_tcp_handle); |
2277 | 16 | dissector_add_for_decode_as_with_preference("udp.port", mausb_pkt_handle); |
2278 | 16 | } |
2279 | | |
2280 | | /* |
2281 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
2282 | | * |
2283 | | * Local variables: |
2284 | | * c-basic-offset: 4 |
2285 | | * tab-width: 8 |
2286 | | * indent-tabs-mode: nil |
2287 | | * End: |
2288 | | * |
2289 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
2290 | | * :indentSize=4:tabSize=8:noTabs=true: |
2291 | | */ |