Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */