Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-ieee1722.c
Line
Count
Source
1
/* packet-ieee1722.c
2
 * Routines for AVTP (Audio Video Transport Protocol) dissection
3
 * Copyright 2010, Torrey Atcitty <tatcitty@harman.com>
4
 *                 Dave Olsen <dave.olsen@harman.com>
5
 *                 Levi Pearson <levi.pearson@harman.com>
6
 *
7
 * Copyright 2011, Thomas Bottom <tom.bottom@labxtechnologies.com>
8
 *
9
 * Copyright 2016, Andreas Leibold <andreas.leibold@harman.com>
10
 *                 Dissection for the following 1722 subtypes added:
11
 *                 Clock Reference Format (CRF).
12
 *                 IEC 61883-4 MPEG-TS data transmission.
13
 *                 IEC 61883-6 audio/music data transmission protocol improved.
14
 *                 Changes to meet 1722 Draft 15 specification.
15
 *
16
 * Copyright 2017, Marouen Ghodhbane <marouen.ghodhbane@nxp.com>
17
 *                 Dissection for the 1722 Compressed Video subtype added.
18
 *                 CVF Format subtype supported: H264 and MJPEG
19
 *                 The dissection meets the 1722-2016 specification.
20
 *
21
 * Copyright 2019, Dmitry Linikov <linikov@arrival.com>
22
 *                 Dissection for the 1722 Time-Sensitive and Non-Time-Sensitive
23
 *                 Control formats added.
24
 *                 ACF Message types supported: CAN, CAN_BRIEF, LIN
25
 *
26
 * Wireshark - Network traffic analyzer
27
 * By Gerald Combs <gerald@wireshark.org>
28
 * Copyright 1998 Gerald Combs
29
 *
30
 * SPDX-License-Identifier: GPL-2.0-or-later
31
 *
32
 * The 1722 Protocol specification can be found at the following:
33
 * http://grouper.ieee.org/groups/1722/
34
 *
35
 */
36
37
#include "config.h"
38
39
#include <epan/packet.h>
40
#include <epan/conversation.h>
41
#include <epan/expert.h>
42
#include <epan/etypes.h>
43
#include <epan/decode_as.h>
44
#include <epan/proto_data.h>
45
#include <epan/tfs.h>
46
#include <epan/unit_strings.h>
47
#include "packet-socketcan.h"
48
49
#include "packet-mp2t.h"
50
51
void proto_register_1722(void);
52
void proto_reg_handoff_1722(void);
53
void proto_register_1722_crf(void);
54
void proto_reg_handoff_1722_crf(void);
55
void proto_register_1722_aaf(void);
56
void proto_reg_handoff_1722_aaf(void);
57
void proto_register_1722_61883(void);
58
void proto_reg_handoff_1722_61883(void);
59
void proto_register_1722_cvf(void);
60
void proto_reg_handoff_1722_cvf(void);
61
void proto_register_1722_ntscf(void);
62
void proto_reg_handoff_1722_ntscf(void);
63
void proto_register_1722_tscf(void);
64
void proto_reg_handoff_1722_tscf(void);
65
void proto_register_1722_acf(void);
66
void proto_reg_handoff_1722_acf(void);
67
void proto_register_1722_acf_can(void);
68
void proto_reg_handoff_1722_acf_can(void);
69
void proto_register_1722_acf_lin(void);
70
void proto_reg_handoff_1722_acf_lin(void);
71
72
static dissector_handle_t avtp_handle_eth;
73
static dissector_handle_t avtp_handle_udp;
74
static dissector_handle_t avb1722_61883_handle;
75
static dissector_handle_t avb1722_aaf_handle;
76
static dissector_handle_t avb1722_cvf_handle;
77
static dissector_handle_t avb1722_crf_handle;
78
static dissector_handle_t avb1722_ntscf_handle;
79
static dissector_handle_t avb1722_tscf_handle;
80
static dissector_handle_t avb1722_acf_lin_handle;
81
82
static dissector_handle_t jpeg_handle;
83
static dissector_handle_t h264_handle;
84
static dissector_handle_t mp2t_handle;
85
86
15
#define UDP_PORT_IEEE_1722   17220 /* One of two IANA registered ports */
87
88
enum IEEE_1722_TRANSPORT {
89
    IEEE_1722_TRANSPORT_ETH,
90
    IEEE_1722_TRANSPORT_UDP,
91
};
92
93
typedef struct _ieee1722_seq_data_t {
94
    uint32_t    seqnum_exp;
95
} ieee1722_seq_data_t;
96
97
/**************************************************************************************************/
98
/* 1722                                                                                           */
99
/*                                                                                                */
100
/**************************************************************************************************/
101
15
#define IEEE_1722_SUBTYPE_61883             0x00
102
15
#define IEEE_1722_SUBTYPE_AAF               0x02
103
15
#define IEEE_1722_SUBTYPE_CVF               0x03
104
15
#define IEEE_1722_SUBTYPE_CRF               0x04
105
15
#define IEEE_1722_SUBTYPE_TSCF              0x05
106
15
#define IEEE_1722_SUBTYPE_NTSCF             0x82
107
108
/* Bit Field Masks */
109
15
#define IEEE_1722_SV_MASK        0x80
110
15
#define IEEE_1722_VER_MASK       0x70
111
112
/**************************************************************************************************/
113
/* subtype IEC 61883                                                                              */
114
/*                                                                                                */
115
/**************************************************************************************************/
116
0
#define IEEE_1722_CIP_HEADER_SIZE           8
117
0
#define IEEE_1722_61883_TAG_NO_CIP          0x00
118
0
#define IEEE_1722_61883_TAG_CIP             0x40
119
1
#define IEEE_1722_61883_CHANNEL_AVTP        31
120
0
#define IEEE_1722_61883_SID_AVTP            63
121
0
#define IEEE_1722_61883_4_LEN_SOURCE_PACKET 192
122
0
#define IEEE_1722_61883_4_LEN_SP_TIMESTAMP  4
123
0
#define IEEE_1722_61883_4                   0x20
124
0
#define IEEE_1722_61883_6                   0x10
125
126
/* Bit Field Masks */
127
#define IEEE_1722_MR_MASK       0x08
128
15
#define IEEE_1722_GV_MASK       0x02
129
#define IEEE_1722_TV_MASK       0x01
130
#define IEEE_1722_TU_MASK       0x01
131
15
#define IEEE_1722_TAG_MASK      0xc0
132
15
#define IEEE_1722_CHANNEL_MASK  0x3f
133
15
#define IEEE_1722_TCODE_MASK    0xf0
134
15
#define IEEE_1722_SY_MASK       0x0f
135
15
#define IEEE_1722_QI1_MASK      0xc0
136
15
#define IEEE_1722_SID_MASK      0x3f
137
15
#define IEEE_1722_FN_MASK       0xc0
138
15
#define IEEE_1722_QPC_MASK      0x38
139
15
#define IEEE_1722_SPH_MASK      0x04
140
15
#define IEEE_1722_QI2_MASK      0xc0
141
15
#define IEEE_1722_FMT_MASK      0x3f
142
15
#define IEEE_1722_FDF_TSF_MASK  0x80
143
15
#define IEEE_1722_FDF_MASK      0xff
144
145
/**************************************************************************************************/
146
/* subtype AAF                                                                                    */
147
/*                                                                                                */
148
/**************************************************************************************************/
149
1
#define IEEE_1722_AAF_FORMAT_USER                       0x00
150
0
#define IEEE_1722_AAF_FORMAT_FLOAT_32_BIT               0x01
151
1
#define IEEE_1722_AAF_FORMAT_INT_32_BIT                 0x02
152
1
#define IEEE_1722_AAF_FORMAT_INT_24_BIT                 0x03
153
0
#define IEEE_1722_AAF_FORMAT_INT_16_BIT                 0x04
154
7
#define IEEE_1722_AAF_FORMAT_AES3_32_BIT                0x05
155
156
/* Bit Field Masks */
157
#define IEEE_1722_MR_MASK                               0x08
158
45
#define IEEE_1722_TV_MASK                               0x01
159
30
#define IEEE_1722_SEQ_NUM_MASK                          0x0
160
#define IEEE_1722_TU_MASK                               0x01
161
30
#define IEEE_1722_STREAM_ID_MASK                        0x0
162
30
#define IEEE_1722_TIMESTAMP_MASK                        0x0
163
30
#define IEEE_1722_FORMAT_MASK                           0x0
164
15
#define IEEE_1722_NOM_SAMPLE_RATE_MASK                  0xf000
165
15
#define IEEE_1722_CHANNEL_PER_FRAME_MASK                0x03ff
166
15
#define IEEE_1722_BIT_DEPTH_MASK                        0x0
167
#define IEEE_1722_AES3_DATA_TYPE_H_MASK                 0x0
168
30
#define IEEE_1722_STREAM_DATA_LENGTH_MASK               0x0
169
#define IEEE_1722_AES3_DATA_TYPE_REFERENCE_MASK         0xe0
170
15
#define IEEE_1722_SP_MASK                               0x10
171
30
#define IEEE_1722_EVT_MASK                              0x0f
172
#define IEEE_1722_AES3_DATA_TYPE_L_MASK                 0x0
173
15
#define IEEE_1722_DATA_MASK                             0x0
174
15
#define IEEE_1722_SAMPLE_MASK                           0x0
175
176
/**************************************************************************************************/
177
/* subtype CVF                                                                                    */
178
/*                                                                                                */
179
/**************************************************************************************************/
180
456
#define IEEE_1722_CVF_FORMAT_RFC                        0x02
181
2
#define IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG              0x0
182
215
#define IEEE_1722_CVF_FORMAT_SUBTYPE_H264               0x01
183
0
#define IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000           0x02
184
185
/* More bit Field Masks */
186
15
#define IEEE_1722_FORMAT_SUBTYPE_MASK                   0x0
187
15
#define IEEE_1722_CVF_H264_TIMESTAMP_MASK               0x0
188
15
#define IEEE_1722_H264_PTV_MASK                         0x20
189
15
#define IEEE_1722_MARKER_BIT_MASK                       0x10
190
191
/**************************************************************************************************/
192
/* subtype CRF                                                                                    */
193
/*                                                                                                */
194
/**************************************************************************************************/
195
1
#define IEEE_1722_CRF_TIMESTAMP_SIZE        8 /* size of the CRF timestamp in bytes */
196
197
/* Bit Field Masks */
198
60
#define IEEE_1722_MR_MASK                   0x08
199
15
#define IEEE_1722_FS_MASK                   0x02
200
60
#define IEEE_1722_TU_MASK                   0x01
201
15
#define IEEE_1722_PULL_MASK                 0xe0000000
202
15
#define IEEE_1722_BASE_FREQUENCY_MASK       0x1fffffff
203
204
/**************************************************************************************************/
205
/* subtype NTSCF                                                                                  */
206
/*                                                                                                */
207
/**************************************************************************************************/
208
6
#define IEEE_1722_NTSCF_HEADER_SIZE                     12      /* including common header */
209
210
/* Bit Field Masks */
211
15
#define IEEE_1722_NTSCF_R_MASK                          0x0800
212
15
#define IEEE_1722_NTSCF_DATA_LENGTH_MASK                0x07ff
213
#define IEEE_1722_NTSCF_SEQ_NUM_MASK                    0xff
214
#define IEEE_1722_NTSCF_STREAM_ID_MASK                  0x00
215
216
/**************************************************************************************************/
217
/* subtype TSCF                                                                                   */
218
/*                                                                                                */
219
/**************************************************************************************************/
220
13
#define IEEE_1722_TSCF_HEADER_SIZE                      24      /* including common header */
221
222
/* Bit Field Masks */
223
15
#define IEEE_1722_TSCF_MR_MASK                          0x08
224
15
#define IEEE_1722_TSCF_RSV1_MASK                        0x06
225
15
#define IEEE_1722_TSCF_TV_MASK                          0x01
226
15
#define IEEE_1722_TSCF_SEQNUM_MASK                      0x0
227
15
#define IEEE_1722_TSCF_RSV2_MASK                        0xFE
228
15
#define IEEE_1722_TSCF_TU_MASK                          0x01
229
15
#define IEEE_1722_TSCF_STREAM_ID_MASK                   0x0
230
15
#define IEEE_1722_TSCF_AVTP_TIMESTAMP_MASK              0x0
231
15
#define IEEE_1722_TSCF_RSV3_MASK                        0x0
232
15
#define IEEE_1722_TSCF_DATA_LENGTH_MASK                 0x0
233
15
#define IEEE_1722_TSCF_RSV4_MASK                        0x0
234
235
/**************************************************************************************************/
236
/* AVTP Control Format (ACF) Message Header                                                       */
237
/*                                                                                                */
238
/**************************************************************************************************/
239
194
#define IEEE_1722_ACF_HEADER_SIZE                       2
240
241
/* ACF message types */
242
#define IEEE_1722_ACF_TYPE_FLEXRAY                      0x00
243
15
#define IEEE_1722_ACF_TYPE_CAN                          0x01
244
15
#define IEEE_1722_ACF_TYPE_CAN_BRIEF                    0x02
245
15
#define IEEE_1722_ACF_TYPE_LIN                          0x03
246
#define IEEE_1722_ACF_TYPE_MOST                         0x04
247
#define IEEE_1722_ACF_TYPE_GPC                          0x05
248
#define IEEE_1722_ACF_TYPE_SERIAL                       0x06
249
#define IEEE_1722_ACF_TYPE_PARALLEL                     0x07
250
#define IEEE_1722_ACF_TYPE_SENSOR                       0x08
251
#define IEEE_1722_ACF_TYPE_SENSOR_BRIEF                 0x09
252
#define IEEE_1722_ACF_TYPE_AECP                         0x0A
253
#define IEEE_1722_ACF_TYPE_ANCILLARY                    0x0B
254
#define IEEE_1722_ACF_TYPE_USER0                        0x78
255
#define IEEE_1722_ACF_TYPE_USER1                        0x79
256
#define IEEE_1722_ACF_TYPE_USER2                        0x7A
257
#define IEEE_1722_ACF_TYPE_USER3                        0x7B
258
#define IEEE_1722_ACF_TYPE_USER4                        0x7C
259
#define IEEE_1722_ACF_TYPE_USER5                        0x7D
260
#define IEEE_1722_ACF_TYPE_USER6                        0x7E
261
#define IEEE_1722_ACF_TYPE_USER7                        0x7F
262
263
/* Bit Field Masks */
264
15
#define IEEE_1722_ACF_MSG_TYPE_MASK                     0xFE00
265
15
#define IEEE_1722_ACF_MSG_LENGTH_MASK                   0x01FF
266
267
/**************************************************************************************************/
268
/* ACF CAN Message                                                                                */
269
/*                                                                                                */
270
/**************************************************************************************************/
271
1
#define IEEE_1722_ACF_CAN_BRIEF_HEADER_SIZE             6
272
27
#define IEEE_1722_ACF_CAN_HEADER_SIZE                   14
273
274
/* Bit Field Masks */
275
15
#define IEEE_1722_ACF_CAN_PAD_MASK                      0xC0u
276
#define IEEE_1722_ACF_CAN_FLAGS_MASK                    0x3Fu
277
22
#define IEEE_1722_ACF_CAN_MTV_MASK                      0x20u
278
36
#define IEEE_1722_ACF_CAN_RTR_MASK                      0x10u
279
50
#define IEEE_1722_ACF_CAN_EFF_MASK                      0x08u
280
36
#define IEEE_1722_ACF_CAN_BRS_MASK                      0x04u
281
36
#define IEEE_1722_ACF_CAN_FDF_MASK                      0x02u
282
36
#define IEEE_1722_ACF_CAN_ESI_MASK                      0x01u
283
15
#define IEEE_1722_ACF_CAN_RSV1_MASK                     0xE0u
284
15
#define IEEE_1722_ACF_CAN_BUS_ID_MASK                   0x1Fu
285
15
#define IEEE_1722_ACF_CAN_MSG_TIMESTAMP_MASK            0x00u
286
15
#define IEEE_1722_ACF_CAN_RSV2_MASK                     0xE0000000u
287
15
#define IEEE_1722_ACF_CAN_IDENTIFIER_MASK               0x1FFFFFFFu
288
5
#define IEEE_1722_ACF_CAN_11BIT_ID_MASK                 0x7FFu
289
290
/* Definitions to forge socketcan frame from acf-can message */
291
#define SOCKETCAN_HEADER_SIZE       8
292
#define SOCKETCAN_PAYLOAD_SIZE      8
293
#define SOCKETCANFD_PAYLOAD_SIZE    64
294
#define SOCKETCAN_FRAME_SIZE        (SOCKETCAN_HEADER_SIZE + SOCKETCAN_PAYLOAD_SIZE)
295
#define SOCKETCANFD_FRAME_SIZE      (SOCKETCAN_HEADER_SIZE + SOCKETCANFD_PAYLOAD_SIZE)
296
#define SOCKETCAN_MAX_FRAME_SIZE    SOCKETCANFD_FRAME_SIZE
297
#define SOCKETCAN_BRS_FLAG          0x01
298
#define SOCKETCAN_ESI_FLAG          0x02
299
300
301
/**************************************************************************************************/
302
/* ACF LIN Message                                                                                */
303
/*                                                                                                */
304
/**************************************************************************************************/
305
3
#define IEEE_1722_ACF_LIN_HEADER_SIZE                   10
306
307
/* Bit Field Masks */
308
15
#define IEEE_1722_ACF_LIN_PAD_MASK                      0xC0
309
15
#define IEEE_1722_ACF_LIN_MTV_MASK                      0x20
310
15
#define IEEE_1722_ACF_LIN_BUS_ID_MASK                   0x1F
311
15
#define IEEE_1722_ACF_LIN_IDENTIFIER_MASK               0x0
312
15
#define IEEE_1722_ACF_LIN_MSG_TIMESTAMP_MASK            0x0
313
314
/**************************************************************************************************/
315
/* 1722                                                                                           */
316
/*                                                                                                */
317
/**************************************************************************************************/
318
static const range_string subtype_range_rvals[] = {
319
    { 0,    0,      "IEC 61883/IIDC Format" },
320
    { 1,    1,      "MMA Streams" },
321
    { 2,    2,      "AVTP Audio Format" },
322
    { 3,    3,      "Compressed Video Format" },
323
    { 4,    4,      "Clock Reference Format" },
324
    { 5,    5,      "Time Synchronous Control Format" },
325
    { 6,    6,      "SDI Video Format" },
326
    { 7,    7,      "Raw Video Format" },
327
    { 8,    0x6d,   "Reserved for future protocols" },
328
    { 0x6e, 0x6e,   "AES Encrypted Format Continuous" },
329
    { 0x6f, 0x6f,   "Vendor Specific Format Stream" },
330
    { 0x70, 0x7e,   "Reserved for future protocols" },
331
    { 0x7f, 0x7f,   "Experimental Format Stream" },
332
    { 0x80, 0x81,   "Reserved for future protocols" },
333
    { 0x82, 0x82,   "Non Time Synchronous Control Format" },
334
    { 0x83, 0xeb,   "Reserved for future protocols" },
335
    { 0xec, 0xec,   "ECC Signed Control Format" },
336
    { 0xed, 0xed,   "ECC Encrypted Control Format" },
337
    { 0xee, 0xee,   "AES Encrypted Format Discrete" },
338
    { 0xef, 0xf9,   "Reserved for future protocols" },
339
    { 0xfa, 0xfa,   "AVDECC Discovery Protocol" },
340
    { 0xfb, 0xfb,   "AVDECC Enumeration and Control Protocol" },
341
    { 0xfc, 0xfc,   "AVDECC Connection Management Protocol" },
342
    { 0xfd, 0xfd,   "Reserved for future protocols" },
343
    { 0xfe, 0xfe,   "MAAP" },
344
    { 0xff, 0xff,   "Experimental Format Control" },
345
    { 0,    0,      NULL }
346
};
347
348
/* Initialize the protocol and registered fields          */
349
static int proto_1722;
350
static int hf_1722_encap_seqnum;
351
static int hf_1722_subtype;
352
static int hf_1722_svfield;
353
static int hf_1722_verfield;
354
355
/* Initialize the subtree pointers */
356
static int ett_1722;
357
358
static expert_field ei_1722_encap_seqnum_dup;
359
static expert_field ei_1722_encap_seqnum_ooo;
360
361
static dissector_table_t avb_dissector_table;
362
363
/**************************************************************************************************/
364
/* subtype IEC 61883                                                                              */
365
/*                                                                                                */
366
/**************************************************************************************************/
367
static const value_string tag_vals [] = {
368
    {0, "No CIP header included"},
369
    {1, "CIP header included"},
370
    {2, "Reserved by IEEE 1394.1 clock adjustment"},
371
    {3, "Global asynchronous stream packet format"},
372
    {0, NULL}
373
};
374
375
static const range_string format_rvals [] = {
376
    {0,                 0,                  "DVCR transmission"},
377
    {1,                 0x0f,               "Reserved"},
378
    {IEEE_1722_61883_4, IEEE_1722_61883_4,  "IEC 61883-4: MPEG2-TS data transmission"},
379
    {0x11,              0x1d,               "Reserved"},
380
    {0x1e,              0x1e,               "Free (vendor unique)"},
381
    {0x1f,              0x1f,               "Reserved"},
382
    {IEEE_1722_61883_6, IEEE_1722_61883_6,  "IEC 61883-6: Audio and music transmission"},
383
    {0x21,              0x21,               "ITU-R B0.1294 System B transmission"},
384
    {0x22,              0x2d,               "Reserved"},
385
    {0x3e,              0x3e,               "Free (vendor unique)"},
386
    {0x3f,              0x3f,               "No data"},
387
    {0,                 0,                  NULL}
388
};
389
390
static const value_string fraction_number_vals [] = {
391
    {0,    "Not divided"},
392
    {1,    "Divided into 2 datablocks"},
393
    {2,    "Divided into 4 datablocks"},
394
    {3,    "Divided into 8 datablocks"},
395
    {0,    NULL}
396
};
397
398
static const range_string fdf_rvals [] = {
399
    {0x00, 0x07,    "Basic format for AM824"},
400
    {0x08, 0x0f,    "Basic format for AM824. Transmission rate may be controlled by an AV/C command set"},
401
    {0x10, 0x17,    "Basic format for 24-bit*4 audio pack"},
402
    {0x18, 0x1f,    "Reserved"},
403
    {0x20, 0x27,    "Basic format for 32-bit floating-point data"},
404
    {0x28, 0x2f,    "Reserved"},
405
    {0x30, 0x37,    "Basic format for 32-bit generic data"},
406
    {0x38, 0x3f,    "Reserved"},
407
    {0x40, 0xfe,    "Reserved"},
408
    {0xff, 0xff,    "Packet for NO-DATA"},
409
    {0,    0,       NULL}
410
};
411
412
static const range_string syt_rvals [] = {
413
    {0x0000, 0x0bff,    "Timestamp"},
414
    {0x0c00, 0x0fff,    "Reserved"},
415
    {0x1000, 0x1bff,    "Timestamp"},
416
    {0x1c00, 0x1fff,    "Reserved"},
417
    {0x2000, 0x2bff,    "Timestamp"},
418
    {0x2c00, 0x2fff,    "Reserved"},
419
    {0x3000, 0x3bff,    "Timestamp"},
420
    {0x3c00, 0x3fff,    "Reserved"},
421
    {0x4000, 0x4bff,    "Timestamp"},
422
    {0x4c00, 0x4fff,    "Reserved"},
423
    {0x5000, 0x5bff,    "Timestamp"},
424
    {0x5c00, 0x5fff,    "Reserved"},
425
    {0x6000, 0x6bff,    "Timestamp"},
426
    {0x6c00, 0x6fff,    "Reserved"},
427
    {0x7000, 0x7bff,    "Timestamp"},
428
    {0x7c00, 0x7fff,    "Reserved"},
429
    {0x8000, 0x8bff,    "Timestamp"},
430
    {0x8c00, 0x8fff,    "Reserved"},
431
    {0x9000, 0x9bff,    "Timestamp"},
432
    {0x9c00, 0x9fff,    "Reserved"},
433
    {0xa000, 0xabff,    "Timestamp"},
434
    {0xac00, 0xafff,    "Reserved"},
435
    {0xb000, 0xbbff,    "Timestamp"},
436
    {0xbc00, 0xbfff,    "Reserved"},
437
    {0xc000, 0xcbff,    "Timestamp"},
438
    {0xcc00, 0xcfff,    "Reserved"},
439
    {0xd000, 0xdbff,    "Timestamp"},
440
    {0xdc00, 0xdfff,    "Reserved"},
441
    {0xe000, 0xebff,    "Timestamp"},
442
    {0xec00, 0xefff,    "Reserved"},
443
    {0xf000, 0xfbff,    "Timestamp"},
444
    {0xfc00, 0xfffe,    "Reserved"},
445
    {0xffff, 0xffff,    "No information"},
446
    {0,      0,         NULL}
447
};
448
449
/* Initialize the protocol and registered fields          */
450
static int proto_1722_61883;
451
static int hf_1722_61883_mrfield;
452
static int hf_1722_61883_gvfield;
453
static int hf_1722_61883_tvfield;
454
static int hf_1722_61883_seqnum;
455
static int hf_1722_61883_tufield;
456
static int hf_1722_61883_stream_id;
457
static int hf_1722_61883_avtp_timestamp;
458
static int hf_1722_61883_gateway_info;
459
static int hf_1722_61883_stream_data_length;
460
static int hf_1722_61883_tag;
461
static int hf_1722_61883_channel;
462
static int hf_1722_61883_tcode;
463
static int hf_1722_61883_sy;
464
static int hf_1722_61883_cip_qi1;
465
static int hf_1722_61883_cip_sid;
466
static int hf_1722_61883_cip_dbs;
467
static int hf_1722_61883_cip_fn;
468
static int hf_1722_61883_cip_qpc;
469
static int hf_1722_61883_cip_sph;
470
static int hf_1722_61883_cip_dbc;
471
static int hf_1722_61883_cip_qi2;
472
static int hf_1722_61883_cip_fmt;
473
static int hf_1722_61883_cip_fdf_no_syt;
474
static int hf_1722_61883_cip_fdf_tsf;
475
static int hf_1722_61883_cip_fdf;
476
static int hf_1722_61883_cip_syt;
477
static int hf_1722_61883_audio_data;
478
static int hf_1722_61883_label;
479
static int hf_1722_61883_sample;
480
static int hf_1722_61883_video_data;
481
static int hf_1722_61883_source_packet_header_timestamp;
482
483
/* Initialize the subtree pointers */
484
static int ett_1722_61883;
485
static int ett_1722_61883_audio;
486
static int ett_1722_61883_sample;
487
static int ett_1722_61883_video;
488
489
/* Initialize expert fields */
490
static expert_field ei_1722_61883_incorrect_tag;
491
static expert_field ei_1722_61883_incorrect_tcode;
492
static expert_field ei_1722_61883_incorrect_qi1;
493
static expert_field ei_1722_61883_incorrect_qpc;
494
static expert_field ei_1722_61883_incorrect_qi2;
495
static expert_field ei_1722_61883_unknown_format;
496
static expert_field ei_1722_61883_incorrect_channel_sid;
497
static expert_field ei_1722_61883_incorrect_datalen;
498
static expert_field ei_1722_61883_4_incorrect_cip_fn;
499
static expert_field ei_1722_61883_4_incorrect_cip_dbs;
500
static expert_field ei_1722_61883_4_incorrect_cip_sph;
501
static expert_field ei_1722_61883_6_incorrect_cip_fn;
502
static expert_field ei_1722_61883_6_incorrect_cip_sph;
503
static expert_field ei_1722_61883_incorrect_cip_fdf;
504
505
/**************************************************************************************************/
506
/* subtype AAF                                                                                    */
507
/*                                                                                                */
508
/**************************************************************************************************/
509
static const range_string aaf_format_range_rvals [] = {
510
    {0, 0,      "User specified"},
511
    {1, 1,      "32bit floating point"},
512
    {2, 2,      "32bit integer"},
513
    {3, 3,      "24bit integer"},
514
    {4, 4,      "16bit integer"},
515
    {5, 5,      "32bit AES3 format"},
516
    {6, 0xff,   "Reserved"},
517
    {0, 0,      NULL}
518
};
519
520
static const range_string aaf_nominal_sample_rate_range_rvals [] = {
521
    {0,    0,       "User specified"},
522
    {1,    1,       "8kHz"},
523
    {2,    2,       "16kHz"},
524
    {3,    3,       "32kHz"},
525
    {4,    4,       "44.1kHz"},
526
    {5,    5,       "48kHz"},
527
    {6,    6,       "88.2kHz"},
528
    {7,    7,       "96kHz"},
529
    {8,    8,       "176.4kHz"},
530
    {9,    9,       "192kHz"},
531
    {0xa, 0xa,      "24kHz"},
532
    {0xb, 0xf,      "Reserved"},
533
    {0,    0,       NULL}
534
};
535
536
static const value_string aaf_sparse_timestamp_vals [] = {
537
    {0,     "Normal operation, timestamp in every AAF AVTPDU"},
538
    {1,     "Sparse mode, timestamp in every eighth AAF AVTPDU"},
539
    {0,     NULL}
540
};
541
542
/* Initialize the protocol and registered fields          */
543
static int proto_1722_aaf;
544
static int hf_1722_aaf_mrfield;
545
static int hf_1722_aaf_tvfield;
546
static int hf_1722_aaf_seqnum;
547
static int hf_1722_aaf_tufield;
548
static int hf_1722_aaf_stream_id;
549
static int hf_1722_aaf_avtp_timestamp;
550
static int hf_1722_aaf_format;
551
static int hf_1722_aaf_nominal_sample_rate;
552
static int hf_1722_aaf_bit_depth;
553
static int hf_1722_aaf_stream_data_length;
554
static int hf_1722_aaf_sparse_timestamp;
555
static int hf_1722_aaf_evtfield;
556
static int hf_1722_aaf_reserved;
557
static int hf_1722_aaf_channels_per_frame;
558
static int hf_1722_aaf_data;
559
static int hf_1722_aaf_sample;
560
561
/* Initialize the subtree pointers */
562
static int ett_1722_aaf;
563
static int ett_1722_aaf_audio;
564
static int ett_1722_aaf_sample;
565
566
/* Initialize expert fields */
567
static expert_field ei_aaf_sample_width;
568
static expert_field ei_aaf_reserved_format;
569
static expert_field ei_aaf_aes3_format;
570
static expert_field ei_aaf_channels_per_frame;
571
static expert_field ei_aaf_incorrect_bit_depth;
572
573
/**************************************************************************************************/
574
/* subtype CRF                                                                                    */
575
/*                                                                                                */
576
/**************************************************************************************************/
577
static const range_string crf_pull_range_rvals [] = {
578
    {0, 0,  "[1.0]"},
579
    {1, 1,  "[1/1.001]"},
580
    {2, 2,  "[1.001]"},
581
    {3, 3,  "[24/25]"},
582
    {4, 4,  "[25/24]"},
583
    {5, 5,  "[1/8]"},
584
    {6, 7,  "Reserved"},
585
    {0, 0,  NULL}
586
};
587
588
static const range_string crf_type_range_rvals [] = {
589
    {0, 0,      "User Specified"},
590
    {1, 1,      "Audio Sample Timestamp"},
591
    {2, 2,      "Video Frame Sync Timestamp"},
592
    {3, 3,      "Video Line Sync Timestamp"},
593
    {4, 4,      "Machine Cycle Timestamp"},
594
    {5, 0xff,   "Reserved"},
595
    {0, 0,      NULL}
596
};
597
598
/* Initialize the protocol and registered fields          */
599
static int proto_1722_crf;
600
static int hf_1722_crf_mrfield;
601
static int hf_1722_crf_fsfield;
602
static int hf_1722_crf_tufield;
603
static int hf_1722_crf_seqnum;
604
static int hf_1722_crf_type;
605
static int hf_1722_crf_stream_id;
606
static int hf_1722_crf_pull;
607
static int hf_1722_crf_base_frequency;
608
static int hf_1722_crf_data_length;
609
static int hf_1722_crf_timestamp_interval;
610
static int hf_1722_crf_timestamp_data;
611
static int hf_1722_crf_timestamp;
612
613
/* Initialize the subtree pointers */
614
static int ett_1722_crf;
615
static int ett_1722_crf_timestamp;
616
617
/* Initialize expert fields */
618
static expert_field ei_crf_datalen;
619
620
/**************************************************************************************************/
621
/* subtype CVF                                                                                    */
622
/*                                                                                                */
623
/**************************************************************************************************/
624
static const range_string cvf_format_range_rvals [] = {
625
    {0, 1,      "Reserved"},
626
    {2, 2,      "RFC payload type"},
627
    {3, 0xff,   "Reserved"},
628
    {0, 0,      NULL}
629
};
630
631
static const range_string cvf_format_subtype_range_rvals [] = {
632
    {0, 0,      "MJPEG Format (RFC 2435)"},
633
    {1, 1,      "H.264 Format (RFC 6184)"},
634
    {2, 2,      "JPEG 2000 Video (RFC 5371)"},
635
    {3, 0xff,   "Reserved"},
636
    {0, 0,      NULL}
637
};
638
639
/* Initialize the protocol and registered fields          */
640
641
static int proto_1722_cvf;
642
static int hf_1722_cvf_mrfield;
643
static int hf_1722_cvf_tvfield;
644
static int hf_1722_cvf_seqnum;
645
static int hf_1722_cvf_tufield;
646
static int hf_1722_cvf_stream_id;
647
static int hf_1722_cvf_avtp_timestamp;
648
static int hf_1722_cvf_format;
649
static int hf_1722_cvf_format_subtype;
650
static int hf_1722_cvf_stream_data_length;
651
static int hf_1722_cvf_evtfield;
652
static int hf_1722_cvf_marker_bit;
653
static int hf_1722_cvf_h264_ptvfield;
654
static int hf_1722_cvf_h264_timestamp;
655
656
/* Initialize the subtree pointers */
657
static int ett_1722_cvf;
658
659
/* Initialize expert fields */
660
static expert_field ei_cvf_jpeg2000_format;
661
static expert_field ei_cvf_reserved_format;
662
static expert_field ei_cvf_invalid_data_length;
663
664
/**************************************************************************************************/
665
/* subtype NTSCF                                                                                  */
666
/*                                                                                                */
667
/**************************************************************************************************/
668
669
/* Initialize the protocol and registered fields          */
670
static int proto_1722_ntscf;
671
static int hf_1722_ntscf_rfield;
672
static int hf_1722_ntscf_data_length;
673
static int hf_1722_ntscf_seqnum;
674
static int hf_1722_ntscf_stream_id;
675
676
/* Initialize the subtree pointers */
677
static int ett_1722_ntscf;
678
679
/* Initialize expert fields */
680
static expert_field ei_1722_ntscf_no_space_for_header;
681
static expert_field ei_1722_ntscf_invalid_data_length;
682
683
/**************************************************************************************************/
684
/* subtype TSCF                                                                                   */
685
/*                                                                                                */
686
/**************************************************************************************************/
687
688
/* Initialize the protocol and registered fields          */
689
static int proto_1722_tscf;
690
static int hf_1722_tscf_mr;
691
static int hf_1722_tscf_rsv1;
692
static int hf_1722_tscf_tv;
693
static int hf_1722_tscf_seqnum;
694
static int hf_1722_tscf_rsv2;
695
static int hf_1722_tscf_tu;
696
static int hf_1722_tscf_stream_id;
697
static int hf_1722_tscf_avtp_timestamp;
698
static int hf_1722_tscf_rsv3;
699
static int hf_1722_tscf_data_length;
700
static int hf_1722_tscf_rsv4;
701
702
/* Initialize the subtree pointers */
703
static int ett_1722_tscf;
704
static int ett_1722_tscf_flags;
705
static int ett_1722_tscf_tu;
706
707
/* Initialize expert fields */
708
static expert_field ei_1722_tscf_no_space_for_header;
709
static expert_field ei_1722_tscf_invalid_data_length;
710
711
712
/**************************************************************************************************/
713
/* AVTP Control Format (ACF) Message Header                                                       */
714
/*                                                                                                */
715
/**************************************************************************************************/
716
717
static const range_string acf_msg_type_range_rvals [] = {
718
    {0x00, 0x00,    "FlexRay"},
719
    {0x01, 0x01,    "CAN"},
720
    {0x02, 0x02,    "CAN Brief"},
721
    {0x03, 0x03,    "LIN"},
722
    {0x04, 0x04,    "MOST"},
723
    {0x05, 0x05,    "General purpose control"},
724
    {0x06, 0x06,    "Serial port"},
725
    {0x07, 0x07,    "Parallel port"},
726
    {0x08, 0x08,    "Analog sensor"},
727
    {0x09, 0x09,    "Abbreviated sensor"},
728
    {0x0A, 0x0A,    "IEEE Std 1722.1 AECP"},
729
    {0x0B, 0x0B,    "Video ancillary data"},
730
    {0x0C, 0x77,    "Reserved"},
731
    {0x78, 0x7F,    "User-defined"},
732
    {0, 0,      NULL}
733
};
734
735
/* Initialize the protocol and registered fields          */
736
static int proto_1722_acf;
737
static int hf_1722_acf_msg_type;
738
static int hf_1722_acf_msg_length;
739
740
/* Initialize the subtree pointers */
741
static int ett_1722_acf;
742
static int ett_1722_acf_header;
743
744
/* Initialize expert fields */
745
static expert_field ei_1722_acf_invalid_msg_length;
746
static expert_field ei_1722_acf_message_is_cropped;
747
748
/* Dissector handles */
749
static dissector_handle_t  avb1722_acf_handle;
750
static dissector_table_t   avb1722_acf_dissector_table;
751
752
/**************************************************************************************************/
753
/* ACF CAN Message                                                                                */
754
/*                                                                                                */
755
/**************************************************************************************************/
756
757
typedef struct {
758
    uint32_t    id;
759
    uint32_t    bus_id;
760
    unsigned    datalen;
761
    bool        is_fd;
762
    bool        is_xtd;
763
    bool        is_rtr;
764
    bool        is_brs;
765
    bool        is_esi;
766
} acf_can_t;
767
768
/* Initialize the protocol and registered fields          */
769
static int proto_1722_acf_can;
770
static int hf_1722_can_flags;
771
static int hf_1722_can_pad;
772
static int hf_1722_can_len;
773
static int hf_1722_can_mtvfield;
774
static int hf_1722_can_rtrfield;
775
static int hf_1722_can_efffield;
776
static int hf_1722_can_brsfield;
777
static int hf_1722_can_fdffield;
778
static int hf_1722_can_esifield;
779
static int hf_1722_can_rsv1;
780
static int hf_1722_can_bus_id;
781
static int hf_1722_can_message_timestamp;
782
static int hf_1722_can_rsv2;
783
static int hf_1722_can_identifier;
784
static int hf_1722_can_padding;
785
786
/* Initialize the subtree pointers */
787
static int ett_can;
788
static int ett_1722_can;
789
static int ett_1722_can_flags;
790
static int ett_1722_can_bus_id;
791
static int ett_1722_can_msg_id;
792
793
/* Initialize expert fields */
794
static expert_field ei_1722_can_header_cropped;
795
static expert_field ei_1722_can_invalid_message_id;
796
static expert_field ei_1722_can_invalid_payload_length;
797
static expert_field ei_1722_canfd_invalid_payload_length;
798
799
/* Dissector handles */
800
static dissector_handle_t avb1722_can_brief_handle;
801
static dissector_handle_t avb1722_can_handle;
802
803
static int                      proto_can;
804
static int                      proto_canfd;
805
static bool                 can_heuristic_first;
806
807
/**************************************************************************************************/
808
/* ACF LIN Message                                                                                */
809
/*                                                                                                */
810
/**************************************************************************************************/
811
812
/* Initialize the protocol and registered fields          */
813
static int proto_1722_acf_lin;
814
static int hf_1722_lin_pad;
815
static int hf_1722_lin_mtv;
816
static int hf_1722_lin_bus_id;
817
static int hf_1722_lin_identifier;
818
static int hf_1722_lin_message_timestamp;
819
static int hf_1722_lin_padding;
820
821
/* Initialize the subtree pointers */
822
static int ett_1722_lin;
823
static int ett_1722_lin_flags;
824
825
/* Initialize expert fields */
826
static expert_field ei_1722_lin_header_cropped;
827
static expert_field ei_1722_lin_invalid_payload_length;
828
829
static dissector_table_t avb1722_acf_lin_dissector_table;
830
831
/**************************************************************************************************/
832
/* 1722 dissector implementation                                                                  */
833
/*                                                                                                */
834
/**************************************************************************************************/
835
836
static uint32_t
837
get_seqnum_exp_1722_udp(packet_info *pinfo, const uint32_t seqnum)
838
83
{
839
83
    conversation_t *conv;
840
83
    ieee1722_seq_data_t *conv_seq_data, *p_seq_data;
841
842
83
    if (!PINFO_FD_VISITED(pinfo)) {
843
83
        conv = find_or_create_conversation(pinfo);
844
83
        conv_seq_data = (ieee1722_seq_data_t *)conversation_get_proto_data(conv, proto_1722);
845
83
        if (conv_seq_data == NULL) {
846
14
            conv_seq_data = wmem_new(wmem_file_scope(), ieee1722_seq_data_t);
847
14
            conv_seq_data->seqnum_exp = seqnum;
848
849
14
            conversation_add_proto_data(conv, proto_1722, conv_seq_data);
850
69
        } else {
851
69
            conv_seq_data->seqnum_exp++;
852
69
        }
853
83
        p_seq_data = wmem_new(wmem_file_scope(), ieee1722_seq_data_t);
854
83
        p_seq_data->seqnum_exp = conv_seq_data->seqnum_exp;
855
83
        p_add_proto_data(wmem_file_scope(), pinfo, proto_1722, 0, p_seq_data);
856
857
83
    } else {
858
0
        p_seq_data = (ieee1722_seq_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_1722, 0);
859
0
    }
860
83
    DISSECTOR_ASSERT(p_seq_data != NULL);
861
83
    return p_seq_data->seqnum_exp;
862
83
}
863
864
static int dissect_1722_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, enum IEEE_1722_TRANSPORT transport)
865
161
{
866
161
    tvbuff_t   *next_tvb;
867
161
    proto_item *ti;
868
161
    proto_tree *ieee1722_tree;
869
161
    uint32_t    encap_seqnum, encap_seqnum_exp;
870
161
    unsigned    subtype = 0;
871
161
    int         offset = 0;
872
161
    int         dissected_size;
873
161
    static int * const fields[] = {
874
161
        &hf_1722_svfield,
875
161
        &hf_1722_verfield,
876
161
        NULL
877
161
    };
878
879
161
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE1722");
880
161
    col_set_str(pinfo->cinfo, COL_INFO, "Audio Video Transport Protocol");
881
882
161
    ti = proto_tree_add_item(tree, proto_1722, tvb, 0, -1, ENC_NA);
883
161
    ieee1722_tree = proto_item_add_subtree(ti, ett_1722);
884
885
161
    if (transport == IEEE_1722_TRANSPORT_UDP) {
886
        /* IEEE 1722-2016 Annex J IP Encapsulation */
887
83
        ti = proto_tree_add_item_ret_uint(ieee1722_tree, hf_1722_encap_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &encap_seqnum);
888
83
        encap_seqnum_exp = get_seqnum_exp_1722_udp(pinfo, encap_seqnum);
889
83
        if (encap_seqnum != encap_seqnum_exp) {
890
69
            if ((encap_seqnum + 1) == encap_seqnum_exp) {
891
4
                expert_add_info(pinfo, ti, &ei_1722_encap_seqnum_dup);
892
65
            } else {
893
65
                expert_add_info(pinfo, ti, &ei_1722_encap_seqnum_ooo);
894
65
            }
895
69
        }
896
83
        offset += 4;
897
83
        next_tvb = tvb_new_subset_remaining(tvb, offset);
898
83
    } else {
899
78
        next_tvb = tvb;
900
78
    }
901
902
161
    proto_tree_add_item_ret_uint(ieee1722_tree, hf_1722_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &subtype);
903
161
    offset += 1;
904
161
    proto_tree_add_bitmask_list(ieee1722_tree, tvb, offset, 1, fields, ENC_NA);
905
906
    /* call any registered subtype dissectors which use only the common AVTPDU (e.g. 1722.1, MAAP, 61883, AAF, CRF or CVF) */
907
161
    dissected_size = dissector_try_uint(avb_dissector_table, subtype, next_tvb, pinfo, tree);
908
161
    if (dissected_size > 0) {
909
98
        return dissected_size;
910
98
    }
911
912
63
    call_data_dissector(next_tvb, pinfo, ieee1722_tree);
913
63
    return tvb_captured_length(tvb);
914
161
}
915
916
static int dissect_1722_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
917
78
{
918
78
    return dissect_1722_common(tvb, pinfo, tree, IEEE_1722_TRANSPORT_ETH);
919
78
}
920
921
static int dissect_1722_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
922
83
{
923
83
    return dissect_1722_common(tvb, pinfo, tree, IEEE_1722_TRANSPORT_UDP);
924
83
}
925
926
/* Register the protocol with Wireshark */
927
void proto_register_1722(void)
928
15
{
929
15
    static hf_register_info hf[] = {
930
15
        { &hf_1722_encap_seqnum,
931
15
            { "Encapsulation Sequence Number", "ieee1722.encapsulation_sequence_num",
932
15
              FT_UINT32, BASE_HEX, NULL, 0x0,
933
15
              "Sequence number incremented for each AVTPDU on a 5-tuple", HFILL }
934
15
        },
935
15
        { &hf_1722_subtype,
936
15
            { "AVTP Subtype", "ieee1722.subtype",
937
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(subtype_range_rvals), 0x0, NULL, HFILL }
938
15
        },
939
15
        { &hf_1722_svfield,
940
15
            { "AVTP Stream ID Valid", "ieee1722.svfield",
941
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_SV_MASK, NULL, HFILL }
942
15
        },
943
15
        { &hf_1722_verfield,
944
15
            { "AVTP Version", "ieee1722.verfield",
945
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_VER_MASK, NULL, HFILL }
946
15
        }
947
15
    };
948
949
15
    static ei_register_info ei[] = {
950
15
        { &ei_1722_encap_seqnum_dup,          { "ieee1722.encapsulation_sequence_num.dup", PI_SEQUENCE, PI_NOTE, "Duplicate encapsulation_sequence_num (retransmission?)", EXPFILL }},
951
15
        { &ei_1722_encap_seqnum_ooo,          { "ieee1722.encapsulation_sequence_num.ooo", PI_SEQUENCE, PI_WARN, "Unexpected encapsulation_sequence_num (lost or out-of-order?)", EXPFILL }},
952
15
    };
953
954
15
    static int *ett[] = {
955
15
        &ett_1722
956
15
    };
957
958
15
    expert_module_t *expert_1722;
959
960
    /* Register the protocol name and description */
961
15
    proto_1722 = proto_register_protocol("IEEE 1722 Audio Video Transport Protocol (AVTP)", "IEEE1722", "ieee1722");
962
963
    /* Required function calls to register the header fields and subtrees used */
964
15
    proto_register_field_array(proto_1722, hf, array_length(hf));
965
15
    proto_register_subtree_array(ett, array_length(ett));
966
967
15
    expert_1722 = expert_register_protocol(proto_1722);
968
15
    expert_register_field_array(expert_1722, ei, array_length(ei));
969
970
    /* Sub-dissector for 1722.1, 1722 AAF, 1722 CRF, 1722 61883, 1722 CVF */
971
15
    avb_dissector_table = register_dissector_table("ieee1722.subtype",
972
15
                          "IEEE1722 AVTP Subtype", proto_1722, FT_UINT8, BASE_HEX);
973
974
15
    avtp_handle_eth = register_dissector("ieee1722.eth", dissect_1722_eth, proto_1722);
975
15
    avtp_handle_udp = register_dissector("ieee1722.udp", dissect_1722_udp, proto_1722);
976
15
}
977
978
void proto_reg_handoff_1722(void)
979
15
{
980
15
    dissector_add_uint("ethertype", ETHERTYPE_AVTP, avtp_handle_eth);
981
15
    dissector_add_uint_with_preference("udp.port", UDP_PORT_IEEE_1722, avtp_handle_udp);
982
15
}
983
984
/**************************************************************************************************/
985
/* IEC 61883 dissector implementation                                                             */
986
/*                                                                                                */
987
/**************************************************************************************************/
988
static int dissect_1722_61883(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
989
1
{
990
1
    proto_item *ti;
991
1
    proto_tree *ti_61883_tree;
992
1
    proto_tree *ti_channel;
993
1
    proto_tree *ti_datalen;
994
1
    proto_tree *ti_cip_fn;
995
1
    proto_tree *ti_cip_dbs;
996
1
    proto_tree *ti_cip_sph;
997
1
    proto_tree *ti_cip_fmt;
998
1
    proto_tree *ti_cip_fdf;
999
1
    proto_tree *ti_audio_tree;
1000
1
    proto_tree *ti_sample_tree;
1001
1
    proto_tree *ti_video_tree;
1002
1
    int         offset = 1;
1003
1
    uint8_t     cip_dbs = 0;
1004
1
    uint8_t     tag = 0;
1005
1
    uint8_t     channel = 0;
1006
1
    uint8_t     tcode = 0;
1007
1
    uint8_t     cip_qi1 = 0;
1008
1
    uint8_t     cip_sid = 0;
1009
1
    uint8_t     cip_qpc = 0;
1010
1
    uint8_t     cip_qi2 = 0;
1011
1
    uint8_t     cip_fmt = 0;
1012
1
    bool        cip_sph = false;
1013
1
    uint8_t     cip_fn = 0;
1014
1
    unsigned    datalen = 0;
1015
1
    unsigned    db_size = 0;
1016
1
    unsigned    numSourcePackets = 0;
1017
1
    unsigned    i = 0;
1018
1
    unsigned    j = 0;
1019
1
    static int * const fields[] = {
1020
1
        &hf_1722_61883_mrfield,
1021
1
        &hf_1722_61883_gvfield,
1022
1
        &hf_1722_61883_tvfield,
1023
1
        NULL
1024
1
    };
1025
1026
1
    ti = proto_tree_add_item(tree, proto_1722_61883, tvb, 0, -1, ENC_NA);
1027
1
    ti_61883_tree = proto_item_add_subtree(ti, ett_1722_61883);
1028
1029
1
    proto_tree_add_bitmask_list(ti_61883_tree, tvb, offset, 1, fields, ENC_NA);
1030
1
    offset += 1;
1031
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1032
1
    offset += 1;
1033
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1034
1
    offset += 1;
1035
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1036
1
    offset += 8;
1037
1038
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1039
1
    offset += 4;
1040
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_gateway_info, tvb, offset, 4, ENC_BIG_ENDIAN);
1041
1
    offset += 4;
1042
1043
1
    ti_datalen = proto_tree_add_item_ret_uint(ti_61883_tree, hf_1722_61883_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1044
1
    offset += 2;
1045
1046
    /* tag field defines if CIP header is included or not */
1047
1
    ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_tag, tvb, offset, 1, ENC_BIG_ENDIAN, &tag);
1048
1
    if (tag > 0x40)
1049
0
    {
1050
0
        expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_tag);
1051
0
    }
1052
1053
1
    ti_channel = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_channel, tvb, offset, 1, ENC_BIG_ENDIAN, &channel);
1054
1
    if (channel != IEEE_1722_61883_CHANNEL_AVTP)
1055
1
    {
1056
1
        proto_item_append_text(ti_channel, ": Originating Source ID from an IEEE 1394 serial bus");
1057
1
    }
1058
0
    else
1059
0
    {
1060
0
        proto_item_append_text(ti_channel, ": Originating source is on AVTP network (native AVTP)");
1061
0
    }
1062
1
    offset += 1;
1063
1064
1
    ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_tcode, tvb, offset, 1, ENC_BIG_ENDIAN, &tcode);
1065
1
    if (tcode != 0xa0)
1066
1
    {
1067
1
       expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_tcode);
1068
1
    }
1069
1070
1
    proto_tree_add_item(ti_61883_tree, hf_1722_61883_sy, tvb, offset, 1, ENC_BIG_ENDIAN);
1071
1
    offset += 1;
1072
1073
1
    switch (tag) {
1074
0
    case IEEE_1722_61883_TAG_NO_CIP:
1075
0
        proto_item_prepend_text(ti, "IIDC 1394 video payload:");
1076
0
        break;
1077
0
    case IEEE_1722_61883_TAG_CIP:
1078
0
        ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_qi1, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_qi1);
1079
0
        if (cip_qi1 != 0)
1080
0
        {
1081
0
            expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qi1);
1082
0
        }
1083
1084
0
        ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_sid, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_sid);
1085
0
        if (cip_sid != IEEE_1722_61883_SID_AVTP)
1086
0
        {
1087
0
            proto_item_append_text(ti, ": Originating Source ID from an IEEE 1394 serial bus");
1088
0
            if (channel == IEEE_1722_61883_CHANNEL_AVTP)
1089
0
            {
1090
0
                expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_channel_sid);
1091
0
                expert_add_info(pinfo, ti_channel, &ei_1722_61883_incorrect_channel_sid);
1092
1093
0
            }
1094
0
        }
1095
0
        else
1096
0
        {
1097
0
            proto_item_append_text(ti, ": Originating source is on AVTP network");
1098
0
            if (channel != IEEE_1722_61883_CHANNEL_AVTP)
1099
0
            {
1100
0
                expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_channel_sid);
1101
0
                expert_add_info(pinfo, ti_channel, &ei_1722_61883_incorrect_channel_sid);
1102
0
            }
1103
0
        }
1104
0
        offset += 1;
1105
1106
0
        ti_cip_dbs = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_dbs, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_dbs);
1107
0
        offset += 1;
1108
0
        ti_cip_fn = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fn, tvb, offset, 1, ENC_BIG_ENDIAN);
1109
1110
0
        switch (tvb_get_uint8(tvb, offset) & IEEE_1722_FN_MASK) {
1111
0
        case 0:
1112
0
            cip_fn = 0;
1113
0
            break;
1114
0
        case 0x40:
1115
0
            cip_fn = 2;
1116
0
            break;
1117
0
        case 0x80:
1118
0
            cip_fn = 4;
1119
0
            break;
1120
0
        case 0xc0:
1121
0
            cip_fn = 8;
1122
0
            break;
1123
0
        default:
1124
0
            break;
1125
0
        }
1126
1127
0
        ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_qpc, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_qpc);
1128
0
        if (cip_qpc != 0)
1129
0
        {
1130
0
            expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qpc);
1131
0
        }
1132
1133
0
        ti_cip_sph = proto_tree_add_item_ret_boolean(ti_61883_tree, hf_1722_61883_cip_sph, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_sph);
1134
0
        offset += 1;
1135
0
        proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_dbc, tvb, offset, 1, ENC_BIG_ENDIAN);
1136
0
        offset += 1;
1137
1138
0
        ti = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_qi2, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_qi2);
1139
0
        if (cip_qi2 != 0x02)
1140
0
        {
1141
0
            expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qi2);
1142
0
        }
1143
1144
        /* Check format field for 61883-4 MPEG-TS video or 61883-6 for audio */
1145
0
        ti_cip_fmt = proto_tree_add_item_ret_uint8(ti_61883_tree, hf_1722_61883_cip_fmt, tvb, offset, 1, ENC_BIG_ENDIAN, &cip_fmt);
1146
0
        offset += 1;
1147
1148
0
        if ((cip_fmt & 0x20) == 0)
1149
0
        {
1150
0
            proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf, tvb, offset, 1, ENC_BIG_ENDIAN);
1151
0
            offset += 1;
1152
0
            proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_syt, tvb, offset, 2, ENC_BIG_ENDIAN);
1153
0
            offset += 2;
1154
0
        }
1155
0
        else
1156
0
        {
1157
0
            ti_cip_fdf = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf_no_syt, tvb, offset, 3, ENC_BIG_ENDIAN);
1158
0
            if (((tvb_get_ntoh24(tvb, offset) & 0x7fffff) != 0))
1159
0
            {
1160
0
                expert_add_info(pinfo, ti_cip_fdf, &ei_1722_61883_incorrect_cip_fdf);
1161
0
            }
1162
1163
0
            proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf_tsf, tvb, offset, 3, ENC_BIG_ENDIAN);
1164
0
            offset += 3;
1165
0
        }
1166
1167
        /* Calculate the remaining size by subtracting the CIP header size from the value in the packet data length field */
1168
0
        datalen -= IEEE_1722_CIP_HEADER_SIZE;
1169
1170
0
        if (cip_dbs == 0) {
1171
0
            db_size = 256;
1172
0
        }
1173
0
        else
1174
0
        {
1175
0
            db_size = cip_dbs;
1176
0
        }
1177
1178
0
        switch (cip_fmt) {
1179
0
        case IEEE_1722_61883_6:
1180
0
            if (cip_fn != 0)
1181
0
            {
1182
0
                expert_add_info(pinfo, ti_cip_fn, &ei_1722_61883_6_incorrect_cip_fn);
1183
0
            }
1184
0
            if (cip_sph != 0)
1185
0
            {
1186
0
                expert_add_info(pinfo, ti_cip_sph, &ei_1722_61883_6_incorrect_cip_sph);
1187
0
            }
1188
1189
            /* Make the Audio sample tree. */
1190
0
            ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_audio_data, tvb, offset, datalen, ENC_NA);
1191
0
            ti_audio_tree = proto_item_add_subtree(ti, ett_1722_61883_audio);
1192
0
            if ((datalen % (db_size*4)) != 0)
1193
0
            {
1194
0
                expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_datalen);
1195
0
                expert_add_info(pinfo, ti_datalen, &ei_1722_61883_incorrect_datalen);
1196
0
            }
1197
0
            numSourcePackets = datalen / (db_size*4);
1198
1199
0
            if (ti_audio_tree) {
1200
                /* Loop through all samples and add them to the audio tree. */
1201
0
                for (j = 0; j < numSourcePackets; j++) {
1202
0
                    ti_sample_tree = proto_tree_add_subtree_format(ti_audio_tree, tvb, offset, 1, ett_1722_61883_sample, NULL, "Sample %d", j+1);
1203
0
                    for (i = 0; i < db_size; i++) {
1204
0
                        proto_tree_add_item(ti_sample_tree, hf_1722_61883_label, tvb, offset, 1, ENC_BIG_ENDIAN);
1205
0
                        offset += 1;
1206
0
                        proto_tree_add_item(ti_sample_tree, hf_1722_61883_sample, tvb, offset, 3, ENC_NA);
1207
0
                        offset += 3;
1208
0
                    }
1209
0
                }
1210
0
            }
1211
0
            break;
1212
0
        case IEEE_1722_61883_4:
1213
0
            if (db_size != 6)
1214
0
            {
1215
0
                expert_add_info(pinfo, ti_cip_dbs, &ei_1722_61883_4_incorrect_cip_dbs);
1216
0
            }
1217
0
            if (cip_fn != 8)
1218
0
            {
1219
0
                expert_add_info(pinfo, ti_cip_fn, &ei_1722_61883_4_incorrect_cip_fn);
1220
0
            }
1221
0
            if (!cip_sph)
1222
0
            {
1223
0
                expert_add_info(pinfo, ti_cip_sph, &ei_1722_61883_4_incorrect_cip_sph);
1224
0
            }
1225
            /* Make the video tree. */
1226
0
            ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_video_data, tvb, offset, datalen, ENC_NA);
1227
0
            ti_video_tree = proto_item_add_subtree(ti, ett_1722_61883_video);
1228
0
            if ((datalen % IEEE_1722_61883_4_LEN_SOURCE_PACKET) != 0)
1229
0
            {
1230
0
                expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_datalen);
1231
0
                expert_add_info(pinfo, ti_datalen, &ei_1722_61883_incorrect_datalen);
1232
0
            }
1233
0
            numSourcePackets = datalen / IEEE_1722_61883_4_LEN_SOURCE_PACKET;
1234
1235
            /* if (ti_video_tree) - MP2T needs to be called regardless
1236
             * for fragmentation handling */
1237
0
            for (j = 0; j < numSourcePackets; j++) {
1238
0
                proto_tree_add_item(ti_video_tree, hf_1722_61883_source_packet_header_timestamp, tvb, offset, IEEE_1722_61883_4_LEN_SP_TIMESTAMP, ENC_BIG_ENDIAN);
1239
0
                offset += IEEE_1722_61883_4_LEN_SP_TIMESTAMP;
1240
0
                call_dissector(mp2t_handle, tvb_new_subset_length(tvb, offset, MP2T_PACKET_SIZE), pinfo, ti_video_tree);
1241
0
                offset += MP2T_PACKET_SIZE;
1242
0
            }
1243
0
            break;
1244
0
        default:
1245
0
            expert_add_info(pinfo, ti_cip_fmt, &ei_1722_61883_unknown_format);
1246
0
            break;
1247
0
        }
1248
0
        break;
1249
1
    default:
1250
1
        break;
1251
1
    }
1252
1
    return tvb_captured_length(tvb);
1253
1
}
1254
1255
void proto_register_1722_61883(void)
1256
15
{
1257
15
    static hf_register_info hf[] = {
1258
15
        { &hf_1722_61883_mrfield,
1259
15
            { "Media Clock Restart", "iec61883.mrfield",
1260
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1261
15
        },
1262
15
        { &hf_1722_61883_gvfield,
1263
15
            { "Gateway Info Valid", "iec61883.gvfield",
1264
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_GV_MASK, NULL, HFILL }
1265
15
        },
1266
15
        { &hf_1722_61883_tvfield,
1267
15
            { "Timestamp Valid", "iec61883.tvfield",
1268
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TV_MASK, NULL, HFILL }
1269
15
            },
1270
15
        { &hf_1722_61883_seqnum,
1271
15
            { "Sequence Number", "iec61883.seqnum",
1272
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1273
15
        },
1274
15
        { &hf_1722_61883_tufield,
1275
15
            { "Timestamp Uncertain", "iec61883.tufield",
1276
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1277
15
        },
1278
15
        { &hf_1722_61883_stream_id,
1279
15
            { "Stream ID", "iec61883.stream_id",
1280
15
              FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1281
15
        },
1282
15
        { &hf_1722_61883_avtp_timestamp,
1283
15
            { "AVTP Timestamp", "iec61883.avtp_timestamp",
1284
15
              FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1285
15
        },
1286
15
        { &hf_1722_61883_gateway_info,
1287
15
            { "Gateway Info", "iec61883.gateway_info",
1288
15
              FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1289
15
        },
1290
15
        { &hf_1722_61883_stream_data_length,
1291
15
            { "1394 Stream Data Length", "iec61883.stream_data_len",
1292
15
              FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
1293
15
        },
1294
15
        { &hf_1722_61883_tag,
1295
15
            { "1394 Packet Format Tag", "iec61883.tag",
1296
15
              FT_UINT8, BASE_HEX, VALS(tag_vals), IEEE_1722_TAG_MASK, NULL, HFILL }
1297
15
        },
1298
15
        { &hf_1722_61883_channel,
1299
15
            { "1394 Packet Channel", "iec61883.channel",
1300
15
                FT_UINT8, BASE_DEC, NULL, IEEE_1722_CHANNEL_MASK, NULL, HFILL }
1301
15
        },
1302
15
        { &hf_1722_61883_tcode,
1303
15
            { "1394 Packet Tcode", "iec61883.tcode",
1304
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_TCODE_MASK, NULL, HFILL }
1305
15
        },
1306
15
        { &hf_1722_61883_sy,
1307
15
            { "1394 App-specific Control", "iec61883.sy",
1308
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_SY_MASK, NULL, HFILL }
1309
15
        },
1310
15
        { &hf_1722_61883_cip_qi1,
1311
15
            { "CIP Quadlet Indicator 1", "iec61883.qi1",
1312
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_QI1_MASK, NULL, HFILL }
1313
15
        },
1314
15
        { &hf_1722_61883_cip_sid,
1315
15
            { "CIP Source ID", "iec61883.sid",
1316
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_SID_MASK, NULL, HFILL }
1317
15
        },
1318
15
        { &hf_1722_61883_cip_dbs,
1319
15
            { "CIP Data Block Size", "iec61883.dbs",
1320
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1321
15
        },
1322
15
        { &hf_1722_61883_cip_fn,
1323
15
            { "CIP Fraction Number", "iec61883.fn",
1324
15
              FT_UINT8, BASE_HEX, VALS(fraction_number_vals), IEEE_1722_FN_MASK, NULL, HFILL }
1325
15
        },
1326
15
        { &hf_1722_61883_cip_qpc,
1327
15
            { "CIP Quadlet Padding Count", "iec61883.qpc",
1328
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_QPC_MASK, NULL, HFILL }
1329
15
        },
1330
15
        { &hf_1722_61883_cip_sph,
1331
15
            { "CIP Source Packet Header", "iec61883.sph",
1332
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_SPH_MASK, NULL, HFILL }
1333
15
        },
1334
15
        { &hf_1722_61883_cip_dbc,
1335
15
            { "CIP Data Block Continuity", "iec61883.dbc",
1336
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1337
15
        },
1338
15
        { &hf_1722_61883_cip_qi2,
1339
15
            { "CIP Quadlet Indicator 2", "iec61883.qi2",
1340
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_QI2_MASK, NULL, HFILL }
1341
15
        },
1342
15
        { &hf_1722_61883_cip_fmt,
1343
15
            { "CIP Format ID", "iec61883.fmt",
1344
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(format_rvals), IEEE_1722_FMT_MASK, NULL, HFILL }
1345
15
        },
1346
15
        { &hf_1722_61883_cip_fdf_no_syt,
1347
15
            { "CIP Format Dependent Field", "iec61883.fdf_no_syt",
1348
15
              FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }
1349
15
        },
1350
15
        { &hf_1722_61883_cip_fdf_tsf,
1351
15
            { "Time shift flag", "iec61883.fdf_tsf",
1352
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_FDF_TSF_MASK, NULL, HFILL }
1353
15
        },
1354
15
        { &hf_1722_61883_cip_fdf,
1355
15
            { "CIP Format Dependent Field", "iec61883.fdf",
1356
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(fdf_rvals), IEEE_1722_FDF_MASK, NULL, HFILL }
1357
15
        },
1358
15
        { &hf_1722_61883_cip_syt,
1359
15
            { "CIP SYT", "iec61883.syt",
1360
15
              FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(syt_rvals), 0x0, NULL, HFILL }
1361
15
        },
1362
15
        { &hf_1722_61883_audio_data,
1363
15
            { "Audio Data", "iec61883.audiodata",
1364
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1365
15
        },
1366
15
        { &hf_1722_61883_label,
1367
15
            { "Label", "iec61883.audiodata.sample.label",
1368
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1369
15
        },
1370
15
        { &hf_1722_61883_sample,
1371
15
            { "Sample", "iec61883.audiodata.sample.sampledata",
1372
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1373
15
        },
1374
15
        { &hf_1722_61883_video_data,
1375
15
            { "Video Data", "iec61883.videodata",
1376
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1377
15
        },
1378
15
        { &hf_1722_61883_source_packet_header_timestamp,
1379
15
            { "Source Packet Header Timestamp", "iec61883.spht",
1380
15
              FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1381
15
        }
1382
15
    };
1383
1384
15
    static int *ett[] = {
1385
15
        &ett_1722_61883,
1386
15
        &ett_1722_61883_audio,
1387
15
        &ett_1722_61883_sample,
1388
15
        &ett_1722_61883_video
1389
15
    };
1390
1391
15
    static ei_register_info ei[] = {
1392
15
        { &ei_1722_61883_incorrect_tag,         { "iec61883.incorrect_tag", PI_PROTOCOL, PI_WARN,
1393
15
                                                  "Incorrect tag field, only 0x00 and 0x01 supported for AVTP", EXPFILL }},
1394
15
        { &ei_1722_61883_incorrect_tcode,       { "iec61883.incorrect_tcode", PI_PROTOCOL, PI_WARN,
1395
15
                                                  "Incorrect tcode, talker shall set this field to 0x0A", EXPFILL }},
1396
15
        { &ei_1722_61883_incorrect_qi1,         { "iec61883.incorrect_qi1", PI_PROTOCOL, PI_WARN,
1397
15
                                                  "Incorrect quadlet indicator 1 field, talker shall set this field to 0x00", EXPFILL }},
1398
15
        { &ei_1722_61883_incorrect_qpc,         { "iec61883.incorrect_qpc", PI_PROTOCOL, PI_WARN,
1399
15
                                                  "Incorrect quadlet padding count field, shall be set to 0", EXPFILL }},
1400
15
        { &ei_1722_61883_incorrect_qi2,         { "iec61883.incorrect_qi2", PI_PROTOCOL, PI_WARN,
1401
15
                                                  "Incorrect quadlet indicator 2 field, talker shall set this field to 0x02", EXPFILL }},
1402
15
        { &ei_1722_61883_unknown_format,        { "iec61883.unknown_format", PI_PROTOCOL, PI_NOTE,
1403
15
                                                  "IEC 61883 format not dissected yet", EXPFILL }},
1404
15
        { &ei_1722_61883_incorrect_channel_sid, { "iec61883.incorrect_channel_sid", PI_PROTOCOL, PI_WARN,
1405
15
                                                  "1394 Packet Channel and Source ID don`t match", EXPFILL }},
1406
15
        { &ei_1722_61883_incorrect_datalen,     { "iec61883.incorrect_datalen", PI_PROTOCOL, PI_WARN,
1407
15
                                                  "Incorrect stream data length field, must be multiple of 192 plus 8 bytes CIP header", EXPFILL }},
1408
15
        { &ei_1722_61883_4_incorrect_cip_fn,    { "iec61883.4_incorrect_cip_fn", PI_PROTOCOL, PI_WARN,
1409
15
                                                  "Incorrect fraction number, shall be 8 for IEC 61883-4", EXPFILL }},
1410
15
        { &ei_1722_61883_4_incorrect_cip_dbs,   { "iec61883.4_incorrect_cip_dbs", PI_PROTOCOL, PI_WARN,
1411
15
                                                  "Incorrect data block size, shall be 6 for IEC 61883-4", EXPFILL }},
1412
15
        { &ei_1722_61883_4_incorrect_cip_sph,   { "iec61883.4_incorrect_cip_sph", PI_PROTOCOL, PI_WARN,
1413
15
                                                  "Incorrect source packet header value, shall be 1 for IEC 61883-4", EXPFILL }},
1414
15
        { &ei_1722_61883_6_incorrect_cip_fn,    { "iec61883.6_incorrect_cip_fn", PI_PROTOCOL, PI_WARN,
1415
15
                                                  "Incorrect fraction number, shall be 0 for IEC 61883-6", EXPFILL }},
1416
15
        { &ei_1722_61883_6_incorrect_cip_sph,   { "iec61883.6_incorrect_cip_sph", PI_PROTOCOL, PI_WARN,
1417
15
                                                  "Incorrect source packet header value, shall be 0 for IEC 61883-6", EXPFILL }},
1418
15
        { &ei_1722_61883_incorrect_cip_fdf,     { "iec61883.6_incorrect_cip_fdf", PI_PROTOCOL, PI_WARN,
1419
15
                                                  "Incorrect frame dependent field value, shall be 0", EXPFILL }}
1420
15
    };
1421
1422
15
    expert_module_t* expert_1722_61883;
1423
1424
    /* Register the protocol name and description */
1425
15
    proto_1722_61883 = proto_register_protocol("IEC 61883 Protocol", "IEC 61883", "iec61883");
1426
1427
    /* Required function calls to register the header fields and subtrees used */
1428
15
    proto_register_field_array(proto_1722_61883, hf, array_length(hf));
1429
15
    proto_register_subtree_array(ett, array_length(ett));
1430
15
    expert_1722_61883 = expert_register_protocol(proto_1722_61883);
1431
15
    expert_register_field_array(expert_1722_61883, ei, array_length(ei));
1432
1433
15
    avb1722_61883_handle = register_dissector("iec61883", dissect_1722_61883, proto_1722_61883);
1434
15
}
1435
1436
void proto_reg_handoff_1722_61883(void)
1437
15
{
1438
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_61883, avb1722_61883_handle);
1439
1440
15
    mp2t_handle = find_dissector_add_dependency("mp2t", proto_1722_61883);
1441
15
}
1442
1443
/**************************************************************************************************/
1444
/* 1722 AAF dissector implementation                                                              */
1445
/*                                                                                                */
1446
/**************************************************************************************************/
1447
static int dissect_1722_aaf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1448
5
{
1449
5
    proto_item *ti;
1450
5
    proto_tree *ti_aaf_tree;
1451
5
    proto_tree *ti_channels_per_frame;
1452
5
    proto_tree *ti_format;
1453
5
    proto_tree *ti_audio_tree;
1454
5
    proto_tree *ti_sample_tree;
1455
5
    int         offset = 1;
1456
5
    unsigned    datalen = 0;
1457
5
    unsigned    channels_per_frame = 0;
1458
5
    unsigned    bit_depth = 0;
1459
5
    unsigned    sample_width = 0;
1460
5
    unsigned    format = 0;
1461
5
    unsigned    i = 0;
1462
5
    unsigned    j = 0;
1463
5
    static int * const fields[] = {
1464
5
        &hf_1722_aaf_mrfield,
1465
5
        &hf_1722_aaf_tvfield,
1466
5
        NULL
1467
5
    };
1468
5
    static int * const fields_pcm[] = {
1469
5
        &hf_1722_aaf_sparse_timestamp,
1470
5
        &hf_1722_aaf_evtfield,
1471
5
        NULL
1472
5
    };
1473
1474
5
    ti = proto_tree_add_item(tree, proto_1722_aaf, tvb, 0, -1, ENC_NA);
1475
5
    ti_aaf_tree = proto_item_add_subtree(ti, ett_1722_aaf);
1476
1477
5
    proto_tree_add_bitmask_list(ti_aaf_tree, tvb, offset, 1, fields, ENC_NA);
1478
5
    offset += 1;
1479
5
    proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1480
5
    offset += 1;
1481
5
    proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1482
5
    offset += 1;
1483
5
    proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1484
5
    offset += 8;
1485
5
    proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1486
5
    offset += 4;
1487
1488
5
    ti_format = proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_format, tvb, offset, 1, ENC_BIG_ENDIAN, &format);
1489
5
    offset += 1;
1490
5
    switch (format)
1491
5
    {
1492
1
    case IEEE_1722_AAF_FORMAT_USER:
1493
1
        break;
1494
0
    case IEEE_1722_AAF_FORMAT_FLOAT_32_BIT:
1495
0
        sample_width = 32;
1496
0
        break;
1497
1
    case IEEE_1722_AAF_FORMAT_INT_32_BIT:
1498
1
        sample_width = 32;
1499
1
        break;
1500
1
    case IEEE_1722_AAF_FORMAT_INT_24_BIT:
1501
1
        sample_width = 24;
1502
1
        break;
1503
0
    case IEEE_1722_AAF_FORMAT_INT_16_BIT:
1504
0
        sample_width = 16;
1505
0
        break;
1506
0
    case IEEE_1722_AAF_FORMAT_AES3_32_BIT:
1507
0
        sample_width = 32;
1508
0
        break;
1509
2
    default:
1510
2
        break;
1511
5
    }
1512
1513
5
    if (format < IEEE_1722_AAF_FORMAT_AES3_32_BIT)
1514
3
    {
1515
        /* PCM Format */
1516
3
        proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_nominal_sample_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
1517
3
        ti_channels_per_frame = proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_channels_per_frame, tvb, offset, 2, ENC_BIG_ENDIAN, &channels_per_frame);
1518
3
        if (channels_per_frame == 0)
1519
0
        {
1520
0
            expert_add_info(pinfo, ti_channels_per_frame, &ei_aaf_channels_per_frame);
1521
0
        }
1522
3
        else
1523
3
        {
1524
3
            offset += 2;
1525
3
            ti = proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_bit_depth, tvb, offset, 1, ENC_BIG_ENDIAN, &bit_depth);
1526
3
            if ((bit_depth == 0) || (bit_depth > sample_width))
1527
2
            {
1528
2
                expert_add_info(pinfo, ti, &ei_aaf_incorrect_bit_depth);
1529
2
            }
1530
3
            offset += 1;
1531
3
            proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1532
3
            offset += 2;
1533
1534
3
            proto_tree_add_bitmask_list(ti_aaf_tree, tvb, offset, 1, fields_pcm, ENC_BIG_ENDIAN);
1535
3
            offset += 1;
1536
1537
3
            proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_reserved, tvb, offset, 1, ENC_NA);
1538
3
            offset += 1;
1539
1540
            /* Make the Audio sample tree. */
1541
3
            ti            = proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_data, tvb, offset, datalen, ENC_NA);
1542
3
            ti_audio_tree = proto_item_add_subtree(ti, ett_1722_aaf_audio);
1543
1544
3
            if (sample_width == 0)
1545
0
            {
1546
0
                expert_add_info(pinfo, ti, &ei_aaf_sample_width);
1547
0
            }
1548
3
            else
1549
3
            {
1550
                /* Loop through all samples and add them to the audio tree. */
1551
3
                for (j = 0; j < ((datalen * 8) / (channels_per_frame * sample_width)); j++)
1552
0
                {
1553
0
                    ti_sample_tree = proto_tree_add_subtree_format(ti_audio_tree, tvb, offset, 1,
1554
0
                                         ett_1722_aaf_sample, NULL, "Sample Chunk %d", j);
1555
0
                    for (i = 0; i < channels_per_frame; i++)
1556
0
                    {
1557
0
                        ti = proto_tree_add_item(ti_sample_tree, hf_1722_aaf_sample, tvb, offset, sample_width / 8, ENC_NA);
1558
0
                        proto_item_prepend_text(ti, "Channel: %d ", i);
1559
0
                        offset += (sample_width / 8);
1560
0
                    }
1561
0
                }
1562
3
            }
1563
3
        }
1564
3
    }
1565
2
    else if (format == IEEE_1722_AAF_FORMAT_AES3_32_BIT)
1566
0
    {
1567
0
        expert_add_info(pinfo, ti_format, &ei_aaf_aes3_format);
1568
0
    }
1569
2
    else
1570
2
    {
1571
2
        expert_add_info(pinfo, ti_format, &ei_aaf_reserved_format);
1572
2
    }
1573
5
    return tvb_captured_length(tvb);
1574
5
}
1575
1576
void proto_register_1722_aaf (void)
1577
15
{
1578
15
    static hf_register_info hf[] =
1579
15
    {
1580
15
        { &hf_1722_aaf_mrfield,
1581
15
            { "Media Clock Restart", "aaf.mrfield",
1582
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1583
15
        },
1584
15
        { &hf_1722_aaf_tvfield,
1585
15
            { "Source Timestamp Valid", "aaf.tvfield",
1586
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TV_MASK, NULL, HFILL }
1587
15
            },
1588
15
        { &hf_1722_aaf_seqnum,
1589
15
            { "Sequence Number", "aaf.seqnum",
1590
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_SEQ_NUM_MASK, NULL, HFILL }
1591
15
        },
1592
15
        { &hf_1722_aaf_tufield,
1593
15
            { "Timestamp Uncertain", "aaf.tufield",
1594
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1595
15
        },
1596
15
        { &hf_1722_aaf_stream_id,
1597
15
            { "Stream ID", "aaf.stream_id",
1598
15
              FT_UINT64, BASE_HEX, NULL, IEEE_1722_STREAM_ID_MASK, NULL, HFILL }
1599
15
        },
1600
15
        { &hf_1722_aaf_avtp_timestamp,
1601
15
            { "AVTP Timestamp", "aaf.avtp_timestamp",
1602
15
              FT_UINT32, BASE_DEC, NULL, IEEE_1722_TIMESTAMP_MASK, NULL, HFILL }
1603
15
        },
1604
15
        { &hf_1722_aaf_format,
1605
15
            { "Format", "aaf.format_info",
1606
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(aaf_format_range_rvals), IEEE_1722_FORMAT_MASK, NULL, HFILL }
1607
15
        },
1608
15
        { &hf_1722_aaf_nominal_sample_rate,
1609
15
            { "Nominal Sample Rate", "aaf.nominal_sample_rate",
1610
15
              FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(aaf_nominal_sample_rate_range_rvals), IEEE_1722_NOM_SAMPLE_RATE_MASK, NULL, HFILL }
1611
15
        },
1612
15
        { &hf_1722_aaf_channels_per_frame,
1613
15
            { "Channels per Frame", "aaf.channels_per_frame",
1614
15
              FT_UINT16, BASE_DEC, NULL, IEEE_1722_CHANNEL_PER_FRAME_MASK, NULL, HFILL }
1615
15
        },
1616
15
        { &hf_1722_aaf_bit_depth,
1617
15
            { "Bit Depth", "aaf.bit_depth",
1618
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_BIT_DEPTH_MASK, NULL, HFILL }
1619
15
        },
1620
15
        { &hf_1722_aaf_stream_data_length,
1621
15
            { "Stream Data Length", "aaf.stream_data_len",
1622
15
              FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), IEEE_1722_STREAM_DATA_LENGTH_MASK, NULL, HFILL }
1623
15
        },
1624
15
        { &hf_1722_aaf_sparse_timestamp,
1625
15
            { "Sparse Timestamp Mode", "aaf.sparse_timestamp",
1626
15
              FT_UINT8, BASE_DEC, VALS(aaf_sparse_timestamp_vals), IEEE_1722_SP_MASK, NULL, HFILL }
1627
15
        },
1628
15
        { &hf_1722_aaf_evtfield,
1629
15
            { "EVT", "aaf.evtfield",
1630
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_EVT_MASK, NULL, HFILL }
1631
15
        },
1632
15
        { &hf_1722_aaf_reserved,
1633
15
            { "Reserved", "aaf.reserved",
1634
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1635
15
        },
1636
15
        { &hf_1722_aaf_data,
1637
15
            { "Audio Data", "aaf.data",
1638
15
              FT_BYTES, BASE_NONE, NULL, IEEE_1722_DATA_MASK, NULL, HFILL }
1639
15
        },
1640
15
        { &hf_1722_aaf_sample,
1641
15
            { "Sample Data", "aaf.data.sample",
1642
15
              FT_BYTES, BASE_NONE, NULL, IEEE_1722_SAMPLE_MASK, NULL, HFILL }
1643
15
        }
1644
15
    };
1645
1646
15
    static ei_register_info ei[] = {
1647
15
        { &ei_aaf_sample_width,          { "aaf.expert.sample_width_zero", PI_PROTOCOL, PI_WARN, "Sample_width of 0 can`t be dissected", EXPFILL }},
1648
15
        { &ei_aaf_reserved_format,       { "aaf.expert.reserved_format", PI_PROTOCOL, PI_WARN, "Incorrect format, can`t be dissected", EXPFILL }},
1649
15
        { &ei_aaf_aes3_format,           { "aaf.expert.aes3_format", PI_PROTOCOL, PI_WARN, "AES3 format is currently not supported", EXPFILL }},
1650
15
        { &ei_aaf_channels_per_frame,    { "aaf.expert.channels_per_frame_zero", PI_PROTOCOL, PI_WARN, "Channels_per_frame value shall not be 0", EXPFILL }},
1651
15
        { &ei_aaf_incorrect_bit_depth,   { "aaf.expert.incorrect_bit_depth", PI_PROTOCOL, PI_WARN, "Incorrect bit_depth value", EXPFILL }}
1652
15
    };
1653
1654
15
    static int *ett[] =
1655
15
    {
1656
15
        &ett_1722_aaf,
1657
15
        &ett_1722_aaf_audio,
1658
15
        &ett_1722_aaf_sample,
1659
15
    };
1660
1661
15
    expert_module_t *expert_1722_aaf;
1662
1663
    /* Register the protocol name and description */
1664
15
    proto_1722_aaf = proto_register_protocol("AVTP Audio Format", "AAF", "aaf");
1665
1666
    /* Required function calls to register the header fields and subtrees used */
1667
15
    proto_register_field_array(proto_1722_aaf, hf, array_length(hf));
1668
15
    proto_register_subtree_array(ett, array_length(ett));
1669
1670
15
    expert_1722_aaf = expert_register_protocol(proto_1722_aaf);
1671
15
    expert_register_field_array(expert_1722_aaf, ei, array_length(ei));
1672
1673
15
    avb1722_aaf_handle = register_dissector("aaf", dissect_1722_aaf, proto_1722_aaf);
1674
15
}
1675
1676
void proto_reg_handoff_1722_aaf(void)
1677
15
{
1678
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_AAF, avb1722_aaf_handle);
1679
15
}
1680
1681
/**************************************************************************************************/
1682
/* 1722 CVF dissector implementation                                                              */
1683
/*                                                                                                */
1684
/**************************************************************************************************/
1685
static int dissect_1722_cvf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1686
114
{
1687
114
    proto_item *ti;
1688
114
    proto_tree *ti_cvf_tree;
1689
114
    tvbuff_t   *next_tvb;
1690
114
    int         offset = 1;
1691
114
    unsigned    reported_len;
1692
114
    uint32_t    datalen, format, format_subtype = 0;
1693
114
    proto_tree *ti_format, *ti_datalen;
1694
1695
114
    static int * const fields[] = {
1696
114
        &hf_1722_cvf_mrfield,
1697
114
        &hf_1722_cvf_tvfield,
1698
114
        NULL
1699
114
    };
1700
1701
114
    static int * const fields_cvf[] = {
1702
114
        &hf_1722_cvf_marker_bit,
1703
114
        &hf_1722_cvf_evtfield,
1704
114
        NULL
1705
114
    };
1706
1707
    /* The PTV field is only defined for the H264 subtype,
1708
     * reserved for others.
1709
     */
1710
114
    static int * const fields_h264[] = {
1711
114
        &hf_1722_cvf_h264_ptvfield,
1712
114
        &hf_1722_cvf_marker_bit,
1713
114
        &hf_1722_cvf_evtfield,
1714
114
        NULL
1715
114
    };
1716
1717
114
    ti = proto_tree_add_item(tree, proto_1722_cvf, tvb, 0, 24, ENC_NA);
1718
114
    ti_cvf_tree = proto_item_add_subtree(ti, ett_1722_cvf);
1719
1720
114
    proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields, ENC_NA);
1721
114
    offset += 1;
1722
114
    proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1723
114
    offset += 1;
1724
114
    proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1725
114
    offset += 1;
1726
114
    proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1727
114
    offset += 8;
1728
114
    proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1729
114
    offset += 4;
1730
114
    ti_format = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_format, tvb, offset, 1, ENC_BIG_ENDIAN, &format);
1731
114
    if (format == IEEE_1722_CVF_FORMAT_RFC) {
1732
109
        offset += 1;
1733
109
        ti_format = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_format_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &format_subtype);
1734
109
        offset += 3;
1735
109
    } else {
1736
5
        expert_add_info(pinfo, ti_format, &ei_cvf_reserved_format);
1737
5
        offset += 4;
1738
5
    }
1739
114
    ti_datalen = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1740
114
    offset += 2;
1741
114
    if (format == IEEE_1722_CVF_FORMAT_RFC &&
1742
109
            format_subtype == IEEE_1722_CVF_FORMAT_SUBTYPE_H264) {
1743
106
        proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_h264, ENC_BIG_ENDIAN);
1744
106
    } else {
1745
8
        proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_cvf, ENC_BIG_ENDIAN);
1746
8
    }
1747
114
    offset += 2;
1748
1749
114
    reported_len = tvb_reported_length_remaining(tvb, offset);
1750
114
    if (reported_len < datalen) {
1751
109
        expert_add_info(pinfo, ti_datalen, &ei_cvf_invalid_data_length);
1752
109
        datalen = reported_len;
1753
109
    }
1754
114
    next_tvb = tvb_new_subset_length(tvb, offset, datalen);
1755
1756
114
    if (format == IEEE_1722_CVF_FORMAT_RFC) {
1757
108
        switch(format_subtype) {
1758
2
        case IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG:
1759
2
            call_dissector(jpeg_handle, next_tvb, pinfo, tree);
1760
2
            break;
1761
1762
106
        case IEEE_1722_CVF_FORMAT_SUBTYPE_H264:
1763
106
            proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_h264_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1764
106
            call_dissector(h264_handle, tvb_new_subset_remaining(next_tvb, 4), pinfo, tree);
1765
106
            break;
1766
1767
0
        case IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000:
1768
0
            expert_add_info(pinfo, ti_format, &ei_cvf_jpeg2000_format);
1769
0
            call_data_dissector(next_tvb, pinfo, tree);
1770
0
            break;
1771
1772
0
        default:
1773
0
            expert_add_info(pinfo, ti_format, &ei_cvf_reserved_format);
1774
0
            call_data_dissector(next_tvb, pinfo, tree);
1775
0
            break;
1776
108
        }
1777
108
    } else {
1778
6
        call_data_dissector(next_tvb, pinfo, tree);
1779
6
    }
1780
71
    return offset + datalen;
1781
114
}
1782
1783
void proto_register_1722_cvf (void)
1784
15
{
1785
15
    static hf_register_info hf[] =
1786
15
    {
1787
15
        { &hf_1722_cvf_mrfield,
1788
15
            { "Media Clock Restart", "cvf.mrfield",
1789
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1790
15
        },
1791
15
        { &hf_1722_cvf_tvfield,
1792
15
            { "Source Timestamp Valid", "cvf.tvfield",
1793
15
              FT_BOOLEAN, 8, TFS(&tfs_valid_invalid), IEEE_1722_TV_MASK,
1794
15
              "Indicates whether avtp_timestamp contains a valid value", HFILL }
1795
15
        },
1796
15
        { &hf_1722_cvf_seqnum,
1797
15
            { "Sequence Number", "cvf.seqnum",
1798
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_SEQ_NUM_MASK, NULL, HFILL }
1799
15
        },
1800
15
        { &hf_1722_cvf_tufield,
1801
15
            { "Timestamp Uncertain", "cvf.tufield",
1802
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1803
15
        },
1804
15
        { &hf_1722_cvf_stream_id,
1805
15
            { "Stream ID", "cvf.stream_id",
1806
15
              FT_UINT64, BASE_HEX, NULL, IEEE_1722_STREAM_ID_MASK, NULL, HFILL }
1807
15
        },
1808
15
        { &hf_1722_cvf_avtp_timestamp,
1809
15
            { "AVTP Timestamp", "cvf.avtp_timestamp",
1810
15
              FT_UINT32, BASE_DEC, NULL, IEEE_1722_TIMESTAMP_MASK, NULL, HFILL }
1811
15
        },
1812
15
        { &hf_1722_cvf_format,
1813
15
            { "Format", "cvf.format",
1814
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_range_rvals), IEEE_1722_FORMAT_MASK, NULL, HFILL }
1815
15
        },
1816
15
        { &hf_1722_cvf_format_subtype,
1817
15
            { "CVF Format Subtype", "cvf.format_subtype",
1818
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_subtype_range_rvals), IEEE_1722_FORMAT_SUBTYPE_MASK, NULL, HFILL }
1819
15
        },
1820
15
        { &hf_1722_cvf_stream_data_length,
1821
15
            { "Stream Data Length", "cvf.stream_data_len",
1822
15
              FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_byte_bytes), IEEE_1722_STREAM_DATA_LENGTH_MASK, NULL, HFILL }
1823
15
        },
1824
15
        { &hf_1722_cvf_h264_ptvfield,
1825
15
            { "H264 Payload Timestamp Valid", "cvf.h264_ptvfield",
1826
15
              FT_BOOLEAN, 8, TFS(&tfs_valid_invalid), IEEE_1722_H264_PTV_MASK,
1827
15
              "Indicates whether h264_timestamp contains a valid value", HFILL }
1828
15
        },
1829
15
        { &hf_1722_cvf_marker_bit,
1830
15
            { "Marker Bit", "cvf.marker_bit",
1831
15
              FT_BOOLEAN, 8, TFS(&tfs_set_notset), IEEE_1722_MARKER_BIT_MASK, NULL, HFILL }
1832
15
        },
1833
15
        { &hf_1722_cvf_evtfield,
1834
15
            { "EVT", "cvf.evtfield",
1835
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_EVT_MASK, NULL, HFILL }
1836
15
        },
1837
15
        { &hf_1722_cvf_h264_timestamp,
1838
15
            { "H264 Timestamp", "cvf.h264_timestamp",
1839
15
              FT_UINT32, BASE_DEC, NULL, IEEE_1722_CVF_H264_TIMESTAMP_MASK, NULL, HFILL }
1840
15
        },
1841
15
    };
1842
1843
15
    static ei_register_info ei[] = {
1844
15
        { &ei_cvf_jpeg2000_format,          { "cvf.expert.jpeg2000_video", PI_UNDECODED, PI_WARN, "JPEG2000 format is currently not supported", EXPFILL }},
1845
15
        { &ei_cvf_reserved_format,          { "cvf.expert.reserved_format", PI_PROTOCOL, PI_WARN, "Incorrect format, can't be dissected", EXPFILL }},
1846
15
        { &ei_cvf_invalid_data_length,      { "cvf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
1847
15
    };
1848
1849
15
    static int *ett[] =
1850
15
    {
1851
15
        &ett_1722_cvf,
1852
15
    };
1853
1854
15
    expert_module_t *expert_1722_cvf;
1855
1856
    /* Register the protocol name and description */
1857
15
    proto_1722_cvf = proto_register_protocol("AVTP Compressed Video Format", "CVF", "cvf");
1858
1859
    /* Required function calls to register the header fields and subtrees used */
1860
15
    proto_register_field_array(proto_1722_cvf, hf, array_length(hf));
1861
15
    proto_register_subtree_array(ett, array_length(ett));
1862
1863
15
    expert_1722_cvf = expert_register_protocol(proto_1722_cvf);
1864
15
    expert_register_field_array(expert_1722_cvf, ei, array_length(ei));
1865
1866
15
    avb1722_cvf_handle = register_dissector("cvf", dissect_1722_cvf, proto_1722_cvf);
1867
15
}
1868
1869
void proto_reg_handoff_1722_cvf(void)
1870
15
{
1871
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_CVF, avb1722_cvf_handle);
1872
1873
15
    jpeg_handle = find_dissector_add_dependency("jpeg", proto_1722_cvf);
1874
15
    h264_handle = find_dissector_add_dependency("h264", proto_1722_cvf);
1875
15
}
1876
1877
/**************************************************************************************************/
1878
/* 1722 CRF dissector implementation                                                              */
1879
/*                                                                                                */
1880
/**************************************************************************************************/
1881
static int dissect_1722_crf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1882
1
{
1883
1
    proto_item *ti;
1884
1
    proto_tree *ti_crf_tree;
1885
1
    proto_tree *timestamp_tree;
1886
1
    int         offset = 1;
1887
1
    unsigned    datalen = 0;
1888
1
    unsigned    j = 0;
1889
1
    static int * const fields[] = {
1890
1
        &hf_1722_crf_mrfield,
1891
1
        &hf_1722_crf_fsfield,
1892
1
        &hf_1722_crf_tufield,
1893
1
        NULL
1894
1
    };
1895
1
    static int * const pull_frequency[] = {
1896
1
        &hf_1722_crf_pull,
1897
1
        &hf_1722_crf_base_frequency,
1898
1
        NULL
1899
1
    };
1900
1901
1
    ti = proto_tree_add_item(tree, proto_1722_crf, tvb, 0, -1, ENC_NA);
1902
1
    ti_crf_tree = proto_item_add_subtree(ti, ett_1722_crf);
1903
1904
1
    proto_tree_add_bitmask_list(ti_crf_tree, tvb, offset, 1, fields, ENC_NA);
1905
1
    offset += 1;
1906
1
    proto_tree_add_item(ti_crf_tree, hf_1722_crf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1907
1
    offset += 1;
1908
1
    proto_tree_add_item(ti_crf_tree, hf_1722_crf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1909
1
    offset += 1;
1910
1
    proto_tree_add_item(ti_crf_tree, hf_1722_crf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1911
1
    offset += 8;
1912
1
    proto_tree_add_bitmask_list(ti_crf_tree, tvb, offset, 4, pull_frequency, ENC_NA);
1913
1
    offset += 4;
1914
1
    proto_tree_add_item_ret_uint(ti_crf_tree, hf_1722_crf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1915
1
    offset += 2;
1916
1
    proto_tree_add_item(ti_crf_tree, hf_1722_crf_timestamp_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
1917
1
    offset += 2;
1918
1919
    /* Make the Timestamp tree. */
1920
1
    ti = proto_tree_add_item(ti_crf_tree, hf_1722_crf_timestamp_data, tvb, offset, datalen, ENC_NA);
1921
1
    timestamp_tree = proto_item_add_subtree(ti, ett_1722_crf_timestamp);
1922
1923
1
    if (datalen%8)
1924
0
    {
1925
0
        expert_add_info(pinfo, ti, &ei_crf_datalen);
1926
0
    }
1927
1
    else
1928
1
    {
1929
        /* Loop through all timestamps and add them to the timestamp tree. */
1930
1
        for (j = 0; j < (datalen / IEEE_1722_CRF_TIMESTAMP_SIZE); j++)
1931
0
        {
1932
0
            ti = proto_tree_add_item(timestamp_tree, hf_1722_crf_timestamp, tvb, offset, IEEE_1722_CRF_TIMESTAMP_SIZE, ENC_BIG_ENDIAN);
1933
0
            proto_item_prepend_text(ti, "Timestamp %d ", j);
1934
0
            offset += IEEE_1722_CRF_TIMESTAMP_SIZE;
1935
0
        }
1936
1
    }
1937
1938
1
    return tvb_captured_length(tvb);
1939
1
}
1940
1941
void proto_register_1722_crf(void)
1942
15
{
1943
15
    static hf_register_info hf[] =
1944
15
    {
1945
15
        { &hf_1722_crf_mrfield,
1946
15
          { "Media Clock Restart", "crf.mrfield",
1947
15
            FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1948
15
        },
1949
15
        { &hf_1722_crf_fsfield,
1950
15
          { "Frame Sync", "crf.fsfield",
1951
15
            FT_BOOLEAN, 8, NULL, IEEE_1722_FS_MASK, NULL, HFILL }
1952
15
        },
1953
15
        { &hf_1722_crf_tufield,
1954
15
            { "Timestamp Uncertain", "crf.tufield",
1955
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1956
15
        },
1957
15
        { &hf_1722_crf_seqnum,
1958
15
            { "Sequence Number", "crf.seqnum",
1959
15
              FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1960
15
        },
1961
15
        { &hf_1722_crf_type,
1962
15
            { "Type", "crf.type",
1963
15
              FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(crf_type_range_rvals), 0x0, NULL, HFILL }
1964
15
        },
1965
15
        { &hf_1722_crf_stream_id,
1966
15
            { "Stream ID", "crf.stream_id",
1967
15
              FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1968
15
        },
1969
15
        { &hf_1722_crf_pull,
1970
15
            { "Pull", "crf.pull",
1971
15
              FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(crf_pull_range_rvals), IEEE_1722_PULL_MASK, NULL, HFILL }
1972
15
        },
1973
15
        { &hf_1722_crf_base_frequency,
1974
15
            { "Base Frequency", "crf.base_frequency",
1975
15
              FT_UINT32, BASE_DEC, NULL, IEEE_1722_BASE_FREQUENCY_MASK, NULL, HFILL }
1976
15
        },
1977
15
        { &hf_1722_crf_data_length,
1978
15
            { "Data Length", "crf.data_len",
1979
15
              FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
1980
15
        },
1981
15
        { &hf_1722_crf_timestamp_interval,
1982
15
            { "Timestamp Interval", "crf.timestamp_interval",
1983
15
              FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1984
15
        },
1985
15
        { &hf_1722_crf_timestamp_data,
1986
15
            { "Timestamp Data", "crf.timestamp_data",
1987
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1988
15
        },
1989
15
        { &hf_1722_crf_timestamp,
1990
15
            { "Data", "crf.timestamp",
1991
15
              FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1992
15
        }
1993
15
    };
1994
1995
15
    static ei_register_info ei[] = {
1996
15
        { &ei_crf_datalen,              { "crf.expert.crf_datalen", PI_PROTOCOL, PI_WARN, "The CRF data length must be multiple of 8", EXPFILL }}
1997
15
    };
1998
1999
15
    static int *ett[] =
2000
15
    {
2001
15
        &ett_1722_crf,
2002
15
        &ett_1722_crf_timestamp
2003
15
    };
2004
2005
15
    expert_module_t *expert_1722_crf;
2006
2007
    /* Register the protocol name and description */
2008
15
    proto_1722_crf = proto_register_protocol("Clock Reference Format", "CRF", "crf");
2009
2010
    /* Required function calls to register the header fields and subtrees used */
2011
15
    proto_register_field_array(proto_1722_crf, hf, array_length(hf));
2012
15
    proto_register_subtree_array(ett, array_length(ett));
2013
15
    expert_1722_crf = expert_register_protocol(proto_1722_crf);
2014
15
    expert_register_field_array(expert_1722_crf, ei, array_length(ei));
2015
2016
15
    avb1722_crf_handle = register_dissector("crf", dissect_1722_crf, proto_1722_crf);
2017
15
}
2018
2019
void proto_reg_handoff_1722_crf(void)
2020
15
{
2021
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_CRF, avb1722_crf_handle);
2022
15
}
2023
2024
/**************************************************************************************************/
2025
/* 1722 NTSCF dissector implementation                                                            */
2026
/*                                                                                                */
2027
/**************************************************************************************************/
2028
static int dissect_1722_ntscf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2029
6
{
2030
6
    proto_item *ti_ntscf;
2031
6
    proto_item *ti_data_length;
2032
6
    proto_tree *tree_ntscf;
2033
6
    int         offset = 1;
2034
6
    uint32_t    datalen = 0;
2035
6
    unsigned    captured_length = tvb_captured_length(tvb);
2036
6
    int         captured_payload_length;
2037
2038
6
    static int * const fields[] = {
2039
6
        &hf_1722_ntscf_rfield,
2040
6
        NULL,
2041
6
    };
2042
2043
6
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NTSCF");
2044
6
    col_set_str(pinfo->cinfo, COL_INFO, "AVTP Non-Time-Synchronous Control Format");
2045
2046
6
    ti_ntscf = proto_tree_add_item(tree, proto_1722_ntscf, tvb, 0, -1, ENC_NA);
2047
6
    tree_ntscf = proto_item_add_subtree(ti_ntscf, ett_1722_ntscf);
2048
2049
6
    if (captured_length < IEEE_1722_NTSCF_HEADER_SIZE) {
2050
0
        expert_add_info(pinfo, ti_ntscf, &ei_1722_ntscf_no_space_for_header);
2051
0
        return captured_length;
2052
0
    }
2053
2054
6
    proto_tree_add_bitmask_list(tree_ntscf, tvb, offset, 2, fields, ENC_BIG_ENDIAN);
2055
6
    ti_data_length = proto_tree_add_item_ret_uint(tree_ntscf, hf_1722_ntscf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
2056
6
    offset += 2;
2057
6
    proto_tree_add_item(tree_ntscf, hf_1722_ntscf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
2058
6
    offset += 1;
2059
6
    proto_tree_add_item(tree_ntscf, hf_1722_ntscf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
2060
6
    offset += 8;
2061
2062
6
    captured_payload_length = tvb_captured_length_remaining(tvb, offset);
2063
6
    if (captured_payload_length < 0 || (int)datalen > captured_payload_length) {
2064
5
        expert_add_info(pinfo, ti_data_length, &ei_1722_ntscf_invalid_data_length);
2065
5
    }
2066
2067
6
    if ((int)datalen > captured_payload_length) {
2068
5
        datalen = captured_payload_length > 0
2069
5
                ? captured_payload_length
2070
5
                : 0;
2071
5
    }
2072
2073
22
    while(datalen > 0) {
2074
16
        unsigned    processed_bytes;
2075
16
        tvbuff_t*   next_tvb;
2076
2077
16
        next_tvb = tvb_new_subset_length(tvb, offset, datalen);
2078
16
        if (call_dissector(avb1722_acf_handle, next_tvb, pinfo, tree) <= 0) {
2079
0
            break;
2080
0
        }
2081
2082
16
        processed_bytes = tvb_reported_length(next_tvb);
2083
2084
16
        offset += processed_bytes;
2085
16
        if (processed_bytes < datalen) {
2086
11
            datalen -= processed_bytes;
2087
11
        } else {
2088
5
            datalen = 0;
2089
5
        }
2090
16
    }
2091
2092
6
    set_actual_length(tvb, offset);
2093
6
    proto_item_set_len(ti_ntscf, offset);
2094
2095
6
    return tvb_captured_length(tvb);
2096
6
}
2097
2098
void proto_register_1722_ntscf(void)
2099
15
{
2100
15
    static hf_register_info hf[] =
2101
15
    {
2102
15
        { &hf_1722_ntscf_rfield,
2103
15
            { "Reserved bits", "ntscf.rfield",
2104
15
              FT_UINT16, BASE_HEX, NULL, IEEE_1722_NTSCF_R_MASK, NULL, HFILL }
2105
15
        },
2106
15
        { &hf_1722_ntscf_data_length,
2107
15
            { "Data Length", "ntscf.data_len",
2108
15
              FT_UINT16, BASE_DEC, NULL, IEEE_1722_NTSCF_DATA_LENGTH_MASK, NULL, HFILL }
2109
15
        },
2110
15
        { &hf_1722_ntscf_seqnum,
2111
15
            { "Sequence Number", "ntscf.seqnum",
2112
15
              FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
2113
15
        },
2114
15
        { &hf_1722_ntscf_stream_id,
2115
15
            { "Stream ID", "ntscf.stream_id",
2116
15
              FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
2117
15
        }
2118
15
    };
2119
2120
15
    static int *ett[] =
2121
15
    {
2122
15
        &ett_1722_ntscf
2123
15
    };
2124
2125
15
    static ei_register_info ei[] = {
2126
15
        { &ei_1722_ntscf_no_space_for_header, { "ntscf.expert.no_space_for_header", PI_PROTOCOL, PI_WARN, "Frame is cropped: NTSCF header won't fit into captured data.", EXPFILL}},
2127
15
        { &ei_1722_ntscf_invalid_data_length, { "ntscf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
2128
15
    };
2129
2130
15
    expert_module_t *expert_1722_ntscf;
2131
2132
    /* Register the protocol name and description */
2133
15
    proto_1722_ntscf = proto_register_protocol("Non-Time-Synchronous Control Format", "NTSCF", "ntscf");
2134
2135
    /* Required function calls to register the header fields and subtrees used */
2136
15
    proto_register_field_array(proto_1722_ntscf, hf, array_length(hf));
2137
15
    proto_register_subtree_array(ett, array_length(ett));
2138
2139
15
    expert_1722_ntscf = expert_register_protocol(proto_1722_ntscf);
2140
15
    expert_register_field_array(expert_1722_ntscf, ei, array_length(ei));
2141
2142
15
    avb1722_ntscf_handle = register_dissector("ntscf", dissect_1722_ntscf, proto_1722_ntscf);
2143
15
}
2144
2145
void proto_reg_handoff_1722_ntscf(void)
2146
15
{
2147
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_NTSCF, avb1722_ntscf_handle);
2148
15
}
2149
2150
2151
/**************************************************************************************************/
2152
/* 1722 TSCF dissector implementation                                                            */
2153
/*                                                                                                */
2154
/**************************************************************************************************/
2155
static int dissect_1722_tscf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2156
13
{
2157
13
    proto_item *ti;
2158
13
    proto_item *ti_tscf;
2159
13
    proto_tree *tree_tscf;
2160
13
    proto_tree *tree_flags;
2161
13
    proto_tree *tree_tu;
2162
13
    int         offset = 1;
2163
13
    uint32_t    mr;
2164
13
    uint32_t    tv;
2165
13
    uint32_t    tu;
2166
13
    uint32_t    datalen = 0;
2167
13
    unsigned    captured_length = tvb_captured_length(tvb);
2168
13
    int         captured_payload_length;
2169
2170
13
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "TSCF");
2171
13
    col_set_str(pinfo->cinfo, COL_INFO, "AVTP Time-Synchronous Control Format");
2172
2173
13
    ti_tscf = proto_tree_add_item(tree, proto_1722_tscf, tvb, 0, -1, ENC_NA);
2174
13
    tree_tscf = proto_item_add_subtree(ti_tscf, ett_1722_tscf);
2175
2176
13
    if (captured_length < IEEE_1722_TSCF_HEADER_SIZE) {
2177
1
        expert_add_info(pinfo, ti_tscf, &ei_1722_tscf_no_space_for_header);
2178
1
        return captured_length;
2179
1
    }
2180
2181
12
    tree_flags = proto_tree_add_subtree(tree_tscf, tvb, offset, 1, ett_1722_tscf_flags, &ti, "Flags");
2182
12
    proto_tree_add_item_ret_uint(tree_flags, hf_1722_tscf_mr, tvb, offset, 1, ENC_BIG_ENDIAN, &mr);
2183
12
    proto_tree_add_item(tree_flags, hf_1722_tscf_rsv1, tvb, offset, 1, ENC_BIG_ENDIAN);
2184
12
    proto_tree_add_item_ret_uint(tree_flags, hf_1722_tscf_tv, tvb, offset, 1, ENC_BIG_ENDIAN, &tv);
2185
12
    proto_item_append_text(ti, ": mr=%d, tv=%d", mr, tv);
2186
12
    offset += 1;
2187
2188
12
    proto_tree_add_item(tree_tscf, hf_1722_tscf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
2189
12
    offset += 1;
2190
2191
12
    tree_tu = proto_tree_add_subtree(tree_tscf, tvb, offset, 1, ett_1722_tscf_tu, &ti, "Timestamp Uncertain");
2192
12
    proto_tree_add_item(tree_tu, hf_1722_tscf_rsv2, tvb, offset, 1, ENC_BIG_ENDIAN);
2193
12
    proto_tree_add_item_ret_uint(tree_tu, hf_1722_tscf_tu, tvb, offset, 1, ENC_BIG_ENDIAN, &tu);
2194
12
    proto_item_append_text(ti, ": %d", tu);
2195
12
    offset += 1;
2196
2197
12
    proto_tree_add_item(tree_tscf, hf_1722_tscf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
2198
12
    offset += 8;
2199
2200
12
    proto_tree_add_item(tree_tscf, hf_1722_tscf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
2201
12
    offset += 4;
2202
2203
12
    proto_tree_add_item(tree_tscf, hf_1722_tscf_rsv3, tvb, offset, 4, ENC_BIG_ENDIAN);
2204
12
    offset += 4;
2205
2206
12
    ti = proto_tree_add_item_ret_uint(tree_tscf, hf_1722_tscf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
2207
12
    captured_payload_length = tvb_captured_length_remaining(tvb, offset);
2208
12
    if (captured_payload_length < 0 || (int)datalen > captured_payload_length) {
2209
9
        expert_add_info(pinfo, ti, &ei_1722_tscf_invalid_data_length);
2210
9
    }
2211
12
    offset += 2;
2212
2213
12
    proto_tree_add_item(tree_tscf, hf_1722_tscf_rsv4, tvb, offset, 2, ENC_BIG_ENDIAN);
2214
12
    offset += 2;
2215
2216
12
    if ((int)datalen > captured_payload_length) {
2217
9
        datalen = captured_payload_length > 0
2218
9
                ? captured_payload_length
2219
9
                : 0;
2220
9
    }
2221
2222
51
    while(datalen > 0) {
2223
42
        unsigned    processed_bytes;
2224
42
        tvbuff_t*   next_tvb = tvb_new_subset_length(tvb, offset, datalen);
2225
42
        if (call_dissector(avb1722_acf_handle, next_tvb, pinfo, tree) <= 0) {
2226
3
            break;
2227
3
        }
2228
39
        processed_bytes = tvb_reported_length(next_tvb);
2229
2230
39
        offset += processed_bytes;
2231
39
        if (processed_bytes < datalen) {
2232
30
            datalen -= processed_bytes;
2233
30
        } else {
2234
9
            datalen = 0;
2235
9
        }
2236
39
    }
2237
2238
12
    set_actual_length(tvb, offset);
2239
12
    proto_item_set_len(ti_tscf, offset);
2240
2241
12
    return captured_length;
2242
13
}
2243
2244
void proto_register_1722_tscf(void)
2245
15
{
2246
15
    static hf_register_info hf[] =
2247
15
    {
2248
15
        { &hf_1722_tscf_mr,
2249
15
            { "Media Clock Restart", "tscf.flags.mr",
2250
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_MR_MASK, NULL, HFILL }
2251
15
        },
2252
2253
15
        { &hf_1722_tscf_rsv1,
2254
15
            { "Reserved bits", "tscf.flags.rsv1",
2255
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_RSV1_MASK, NULL, HFILL }
2256
15
        },
2257
2258
15
        { &hf_1722_tscf_tv,
2259
15
            { "Avtp Timestamp Valid", "tscf.flags.tv",
2260
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_TV_MASK, NULL, HFILL }
2261
15
        },
2262
2263
15
        { &hf_1722_tscf_seqnum,
2264
15
            { "Sequence Number", "tscf.seqnum",
2265
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_SEQNUM_MASK, NULL, HFILL }
2266
15
        },
2267
2268
15
        { &hf_1722_tscf_rsv2,
2269
15
            { "Reserved Bits", "tscf.rsv2",
2270
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_RSV2_MASK, NULL, HFILL }
2271
15
        },
2272
2273
15
        { &hf_1722_tscf_tu,
2274
15
            { "Timestamp Uncertain", "tscf.flags.tu",
2275
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_TU_MASK, NULL, HFILL }
2276
15
        },
2277
2278
15
        { &hf_1722_tscf_stream_id,
2279
15
            { "Stream ID", "tscf.stream_id",
2280
15
              FT_UINT64, BASE_HEX, NULL, IEEE_1722_TSCF_STREAM_ID_MASK, NULL, HFILL }
2281
15
        },
2282
2283
15
        { &hf_1722_tscf_avtp_timestamp,
2284
15
            { "AVTP Timestamp", "tscf.avtp_timestamp",
2285
15
              FT_UINT32, BASE_HEX, NULL, IEEE_1722_TSCF_AVTP_TIMESTAMP_MASK, NULL, HFILL }
2286
15
        },
2287
2288
15
        { &hf_1722_tscf_rsv3,
2289
15
            { "Reserved Bits", "tscf.rsv3",
2290
15
              FT_UINT32, BASE_HEX, NULL, IEEE_1722_TSCF_RSV3_MASK, NULL, HFILL }
2291
15
        },
2292
2293
15
        { &hf_1722_tscf_data_length,
2294
15
            { "Data Length", "tscf.data_len",
2295
15
              FT_UINT16, BASE_DEC, NULL, IEEE_1722_TSCF_DATA_LENGTH_MASK, NULL, HFILL }
2296
15
        },
2297
2298
15
        { &hf_1722_tscf_rsv4,
2299
15
            { "Reserved Bits", "tscf.rsv4",
2300
15
              FT_UINT16, BASE_HEX, NULL, IEEE_1722_TSCF_RSV4_MASK, NULL, HFILL }
2301
15
        },
2302
15
    };
2303
2304
15
    static int *ett[] =
2305
15
    {
2306
15
        &ett_1722_tscf,
2307
15
        &ett_1722_tscf_flags,
2308
15
        &ett_1722_tscf_tu,
2309
15
    };
2310
2311
15
    static ei_register_info ei[] = {
2312
15
        { &ei_1722_tscf_no_space_for_header, { "tscf.expert.no_space_for_header", PI_PROTOCOL, PI_WARN, "Frame is cropped: TSCF header won't fit into captured data.", EXPFILL}},
2313
15
        { &ei_1722_tscf_invalid_data_length, { "tscf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
2314
15
    };
2315
2316
15
    expert_module_t *expert_1722_tscf;
2317
2318
    /* Register the protocol name and description */
2319
15
    proto_1722_tscf = proto_register_protocol("Time-Synchronous Control Format", "TSCF", "tscf");
2320
2321
    /* Required function calls to register the header fields and subtrees used */
2322
15
    proto_register_field_array(proto_1722_tscf, hf, array_length(hf));
2323
15
    proto_register_subtree_array(ett, array_length(ett));
2324
2325
15
    expert_1722_tscf = expert_register_protocol(proto_1722_tscf);
2326
15
    expert_register_field_array(expert_1722_tscf, ei, array_length(ei));
2327
2328
15
    avb1722_tscf_handle = register_dissector("tscf", dissect_1722_tscf, proto_1722_tscf);
2329
15
}
2330
2331
void proto_reg_handoff_1722_tscf(void)
2332
15
{
2333
15
    dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_TSCF, avb1722_tscf_handle);
2334
15
}
2335
2336
/**************************************************************************************************/
2337
/* AVTP Control Format (ACF) Message dissector implementation                                     */
2338
/*                                                                                                */
2339
/**************************************************************************************************/
2340
static int dissect_1722_acf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2341
58
{
2342
58
    proto_item     *ti;
2343
58
    proto_item     *ti_acf;
2344
58
    proto_item     *ti_header;
2345
58
    proto_tree     *tree_acf;
2346
58
    proto_tree     *tree_header;
2347
58
    uint32_t        msg_type;
2348
58
    uint32_t        msg_length;
2349
58
    uint32_t        payload_length;
2350
58
    unsigned        captured_length = tvb_captured_length(tvb);
2351
58
    const char     *msg_type_str;
2352
58
    tvbuff_t       *next_tvb;
2353
2354
58
    if (captured_length < IEEE_1722_ACF_HEADER_SIZE) {
2355
4
        return captured_length;
2356
4
    }
2357
2358
54
    ti_acf = proto_tree_add_item(tree, proto_1722_acf, tvb, 0, -1, ENC_NA);
2359
54
    tree_acf = proto_item_add_subtree(ti_acf, ett_1722_acf);
2360
2361
54
    tree_header = proto_tree_add_subtree(tree_acf, tvb, 0, 2, ett_1722_acf_header, &ti_header, "ACF Header");
2362
54
    proto_tree_add_item_ret_uint(tree_header, hf_1722_acf_msg_type, tvb, 0, 2, ENC_BIG_ENDIAN, &msg_type);
2363
54
    ti = proto_tree_add_item_ret_uint(tree_header, hf_1722_acf_msg_length, tvb, 0, 2, ENC_BIG_ENDIAN, &msg_length);
2364
54
    msg_length = msg_length * 4; /* msg_length is stored as number of quadlets */
2365
2366
54
    if (msg_length < IEEE_1722_ACF_HEADER_SIZE) {
2367
2
        expert_add_info(pinfo, ti, &ei_1722_acf_invalid_msg_length);
2368
2
        return captured_length;
2369
2
    }
2370
2371
52
    if (captured_length < msg_length) {
2372
11
        expert_add_info_format(pinfo, ti, &ei_1722_acf_message_is_cropped,
2373
11
                               "expected: %u bytes, available: %u bytes",
2374
11
                               msg_length, tvb_captured_length(tvb));
2375
11
        return captured_length;
2376
11
    }
2377
2378
41
    set_actual_length(tvb, msg_length);
2379
41
    proto_item_set_len(ti_acf, msg_length);
2380
41
    msg_type_str = rval_to_str_const(msg_type, acf_msg_type_range_rvals, "Unknown");
2381
41
    proto_item_append_text(ti_header, ": %s (0x%02X), %d bytes with header",
2382
41
                           msg_type_str, msg_type, msg_length);
2383
41
    proto_item_append_text(ti_acf, ": %s (0x%02X)", msg_type_str, msg_type);
2384
41
    payload_length = msg_length - IEEE_1722_ACF_HEADER_SIZE;
2385
2386
    /* call any registered message dissectors */
2387
41
    next_tvb = tvb_new_subset_length(tvb, IEEE_1722_ACF_HEADER_SIZE, payload_length);
2388
2389
41
    if (!dissector_try_uint(avb1722_acf_dissector_table, msg_type, next_tvb, pinfo, tree_acf)) {
2390
24
        call_data_dissector(next_tvb, pinfo, tree_acf);
2391
24
    }
2392
2393
41
    return captured_length;
2394
52
}
2395
2396
void proto_register_1722_acf(void)
2397
15
{
2398
15
    static hf_register_info hf[] = {
2399
15
        { &hf_1722_acf_msg_type,
2400
15
            { "Message Type", "acf.msg_type",
2401
15
              FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(acf_msg_type_range_rvals), IEEE_1722_ACF_MSG_TYPE_MASK, NULL, HFILL }
2402
15
        },
2403
15
        { &hf_1722_acf_msg_length,
2404
15
            { "Message Length (Quadlets)", "acf.msg_length",
2405
15
              FT_UINT16, BASE_DEC, NULL, IEEE_1722_ACF_MSG_LENGTH_MASK, NULL, HFILL }
2406
15
        },
2407
15
    };
2408
2409
15
    static int *ett[] =
2410
15
    {
2411
15
        &ett_1722_acf,
2412
15
        &ett_1722_acf_header,
2413
15
    };
2414
2415
2416
15
    static ei_register_info ei[] = {
2417
15
        { &ei_1722_acf_invalid_msg_length, { "acf.expert.msg_length", PI_PROTOCOL, PI_WARN, "msg_length shall be at least 1 quadlet", EXPFILL }},
2418
15
        { &ei_1722_acf_message_is_cropped, { "acf.expert.msg_cropped", PI_PROTOCOL, PI_WARN, "Message is cropped or msg_length is invalid", EXPFILL }},
2419
15
    };
2420
2421
15
    expert_module_t *expert_1722_acf;
2422
2423
    /* Register the protocol name and description */
2424
15
    proto_1722_acf = proto_register_protocol("ACF Message", "ACF", "acf");
2425
15
    avb1722_acf_handle = register_dissector("acf", dissect_1722_acf, proto_1722_acf);
2426
2427
    /* Required function calls to register the header fields and subtrees used */
2428
15
    proto_register_field_array(proto_1722_acf, hf, array_length(hf));
2429
15
    proto_register_subtree_array(ett, array_length(ett));
2430
2431
    /* Sub-dissector for ACF messages */
2432
15
    avb1722_acf_dissector_table = register_dissector_table("acf.msg_type",
2433
15
                          "IEEE1722 AVTP Control Message Type", proto_1722_acf,
2434
15
                          FT_UINT8, BASE_HEX);
2435
2436
15
    expert_1722_acf = expert_register_protocol(proto_1722_acf);
2437
15
    expert_register_field_array(expert_1722_acf, ei, array_length(ei));
2438
15
}
2439
2440
void proto_reg_handoff_1722_acf(void)
2441
15
{
2442
15
    register_depend_dissector("ntscf", "acf");
2443
15
    register_depend_dissector("tscf", "acf");
2444
15
}
2445
2446
/**************************************************************************************************/
2447
/* ACF CAN Message dissector implementation                                                       */
2448
/*                                                                                                */
2449
/**************************************************************************************************/
2450
static void describe_can_message(proto_item* dst, unsigned bus_id, uint32_t can_id, uint8_t flags)
2451
14
{
2452
    /* Add text describing the CAN message to the parent item.
2453
     * Example: ": bus_id=2, id=0x100, rtr=1, brs=1, esi=1" */
2454
14
    const char* format_str = (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0
2455
14
                           ? ": bus_id=%u, id=0x%08X"
2456
14
                           : ": bus_id=%u, id=0x%03X";
2457
2458
14
    proto_item_append_text (dst, format_str, bus_id, can_id);
2459
14
}
2460
2461
static void describe_can_flags(proto_item* dst, uint8_t pad, uint8_t flags)
2462
7
{
2463
7
    proto_item_append_text(dst, ": pad=%u, mtv=%d, rtr=%d, eff=%d, brs=%d, fdf=%d, esi=%d",
2464
7
                           pad,
2465
7
                           (flags & IEEE_1722_ACF_CAN_MTV_MASK) != 0,
2466
7
                           (flags & IEEE_1722_ACF_CAN_RTR_MASK) != 0,
2467
7
                           (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0,
2468
7
                           (flags & IEEE_1722_ACF_CAN_BRS_MASK) != 0,
2469
7
                           (flags & IEEE_1722_ACF_CAN_FDF_MASK) != 0,
2470
7
                           (flags & IEEE_1722_ACF_CAN_ESI_MASK) != 0
2471
7
    );
2472
7
}
2473
2474
static int is_valid_can_payload_length(int len)
2475
7
{
2476
7
    return len >= 0 && len <= 8;
2477
7
}
2478
2479
static int is_valid_canfd_payload_length(int len)
2480
2
{
2481
2
    return is_valid_can_payload_length(len) ||
2482
2
           len == 12 ||
2483
2
           len == 16 ||
2484
2
           len == 20 ||
2485
2
           len == 24 ||
2486
2
           len == 32 ||
2487
1
           len == 48 ||
2488
1
           len == 64;
2489
2
}
2490
2491
static int dissect_1722_acf_can_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_, const bool is_brief)
2492
14
{
2493
14
    acf_can_t           parsed;
2494
14
    uint32_t            pad_length;
2495
14
    int                 payload_length;
2496
14
    uint8_t             flags;
2497
14
    proto_item         *ti;
2498
2499
14
    proto_item         *ti_acf_can;
2500
14
    proto_tree         *tree_acf_can;
2501
14
    proto_tree         *tree_acf_can_flags;
2502
14
    proto_tree         *tree_acf_can_bus_id;
2503
2504
14
    proto_item         *ti_can;
2505
14
    proto_tree         *tree_can;
2506
14
    proto_tree         *tree_can_id;
2507
14
    int                 can_protocol;
2508
14
    int                * const *can_flags;
2509
14
    struct can_info     can_info;
2510
2511
14
    tvbuff_t*           next_tvb;
2512
14
    int                 offset = 0;
2513
14
    unsigned            captured_length = tvb_captured_length(tvb);
2514
14
    unsigned            header_size = is_brief
2515
14
                                    ? IEEE_1722_ACF_CAN_BRIEF_HEADER_SIZE
2516
14
                                    : IEEE_1722_ACF_CAN_HEADER_SIZE;
2517
2518
2519
14
    static int * const fields[] = {
2520
14
        &hf_1722_can_mtvfield,
2521
14
        &hf_1722_can_fdffield,
2522
14
        NULL,
2523
14
    };
2524
2525
14
    static int * const can_std_flags[] = {
2526
14
        &hf_1722_can_rtrfield,
2527
14
        &hf_1722_can_efffield,
2528
14
        NULL
2529
14
    };
2530
2531
14
    static int * const can_fd_flags[] = {
2532
14
        &hf_1722_can_efffield,
2533
14
        &hf_1722_can_brsfield,
2534
14
        &hf_1722_can_esifield,
2535
14
        NULL
2536
14
    };
2537
2538
14
    memset(&parsed, 0, sizeof(parsed));
2539
2540
    /* create tree for ACF-CAN-specific fields */
2541
14
    ti_acf_can = proto_tree_add_item(tree, proto_1722_acf_can, tvb, offset, -1, ENC_NA);
2542
14
    tree_acf_can = proto_item_add_subtree(ti_acf_can, ett_1722_can);
2543
14
    if (is_brief) {
2544
1
        proto_item_append_text(ti_acf_can, " Brief");
2545
1
    }
2546
2547
    /* parse flags */
2548
14
    flags = tvb_get_uint8(tvb, offset);
2549
14
    parsed.is_fd   = (flags & IEEE_1722_ACF_CAN_FDF_MASK) != 0;
2550
14
    parsed.is_xtd  = (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0;
2551
14
    parsed.is_rtr  = (flags & IEEE_1722_ACF_CAN_RTR_MASK) != 0;
2552
14
    parsed.is_brs  = (flags & IEEE_1722_ACF_CAN_BRS_MASK) != 0;
2553
14
    parsed.is_esi  = (flags & IEEE_1722_ACF_CAN_ESI_MASK) != 0;
2554
2555
    /* create the tree for CAN-specific fields */
2556
14
    can_protocol = parsed.is_fd ? proto_canfd : proto_can;
2557
14
    can_flags    = parsed.is_fd ? can_fd_flags : can_std_flags;
2558
14
    ti_can = proto_tree_add_item(tree, can_protocol, tvb, offset, -1, ENC_NA);
2559
14
    tree_can = proto_item_add_subtree(ti_can, ett_can);
2560
2561
14
    if (captured_length < header_size) {
2562
7
        expert_add_info(pinfo, ti_acf_can, &ei_1722_can_header_cropped);
2563
7
        return captured_length;
2564
7
    }
2565
2566
    /* Add flags subtree to ACF_CAN message */
2567
7
    ti = proto_tree_add_item(tree_acf_can, hf_1722_can_flags, tvb, offset, 1, ENC_NA);
2568
7
    tree_acf_can_flags = proto_item_add_subtree(ti, ett_1722_can_flags);
2569
2570
7
    proto_tree_add_item_ret_uint(tree_acf_can_flags, hf_1722_can_pad, tvb, offset, 1, ENC_BIG_ENDIAN, &pad_length);
2571
7
    proto_tree_add_bitmask_list(tree_acf_can_flags, tvb, offset, 1, fields, ENC_BIG_ENDIAN);
2572
7
    describe_can_flags(ti, pad_length, flags);
2573
2574
    /* Add flags to CAN message */
2575
7
    proto_tree_add_bitmask_list(tree_can, tvb, offset, 1, can_flags, ENC_BIG_ENDIAN);
2576
7
    offset += 1;
2577
2578
    /* Add bus id subtree to ACF_CAN message */
2579
7
    tree_acf_can_bus_id = proto_tree_add_subtree(tree_acf_can, tvb, offset, 1, ett_1722_can_bus_id, &ti, "Bus Identifier");
2580
7
    proto_tree_add_item(tree_acf_can_bus_id, hf_1722_can_rsv1, tvb, offset, 1, ENC_BIG_ENDIAN);
2581
7
    proto_tree_add_item_ret_uint(tree_acf_can_bus_id, hf_1722_can_bus_id, tvb, offset, 1, ENC_BIG_ENDIAN, &parsed.bus_id);
2582
7
    proto_item_append_text(ti, ": %u", parsed.bus_id);
2583
7
    offset += 1;
2584
2585
    /* Add message_timestamp to ACF_CAN if present */
2586
7
    if (!is_brief) {
2587
6
        proto_tree_add_item(tree_acf_can, hf_1722_can_message_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
2588
6
        offset += 8;
2589
6
    }
2590
2591
    /* Add message id subtree to CAN message */
2592
7
    tree_can_id = proto_tree_add_subtree(tree_can, tvb, offset, 4, ett_1722_can_msg_id, &ti, "Message Identifier");
2593
7
    proto_tree_add_item(tree_can_id, hf_1722_can_rsv2, tvb, offset, 4, ENC_BIG_ENDIAN);
2594
7
    proto_item *ti_id = proto_tree_add_item_ret_uint(tree_can_id, hf_1722_can_identifier, tvb, offset, 4, ENC_BIG_ENDIAN, &parsed.id);
2595
7
    proto_item_append_text(ti, parsed.is_xtd ? ": 0x%08X" : ": 0x%03X", parsed.id);
2596
7
    if (!parsed.is_xtd && (parsed.id & ~IEEE_1722_ACF_CAN_11BIT_ID_MASK) != 0) {
2597
5
        expert_add_info(pinfo, ti_id, &ei_1722_can_invalid_message_id);
2598
5
    }
2599
7
    offset += 4;
2600
2601
    /* Add text description to tree items and info column*/
2602
7
    describe_can_message(ti_acf_can, parsed.bus_id, parsed.id, flags);
2603
7
    describe_can_message(proto_tree_get_parent(tree), parsed.bus_id, parsed.id, flags);
2604
2605
7
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACF-CAN");
2606
7
    col_clear(pinfo->cinfo, COL_INFO);
2607
7
    col_add_fstr(pinfo->cinfo, COL_INFO, "ACF-CAN(%u): 0x%08x   ", parsed.bus_id, parsed.id);
2608
2609
7
    payload_length = tvb_reported_length_remaining(tvb, offset) - pad_length;
2610
7
    if (payload_length < 0) {
2611
0
        payload_length = 0;
2612
0
    }
2613
7
    parsed.datalen = (unsigned)payload_length;
2614
7
    proto_tree_add_uint(tree_acf_can, hf_1722_can_len, tvb, offset, 1, parsed.datalen);
2615
2616
7
    if (payload_length > 0)
2617
7
        col_append_str(pinfo->cinfo, COL_INFO, tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, payload_length, ' '));
2618
2619
7
    if (parsed.is_fd && !is_valid_canfd_payload_length(payload_length))
2620
1
    {
2621
1
        expert_add_info(pinfo, ti_acf_can, &ei_1722_canfd_invalid_payload_length);
2622
1
    }
2623
6
    else if (!parsed.is_fd && !is_valid_can_payload_length(payload_length))
2624
5
    {
2625
5
        expert_add_info(pinfo, ti_acf_can, &ei_1722_can_invalid_payload_length);
2626
5
    }
2627
2628
    /* Add payload to parent tree */
2629
2630
    /*
2631
    * CAN sub-dissectors expect several flags to be merged into ID that is passed
2632
    * to dissector_try_payload_with_data. Add them
2633
    */
2634
7
    can_info.id = parsed.id;
2635
7
    if (parsed.is_xtd)
2636
2
    {
2637
2
        can_info.id |= CAN_EFF_FLAG;
2638
2
    }
2639
2640
7
    if (parsed.is_rtr)
2641
3
    {
2642
3
        can_info.id |= CAN_RTR_FLAG;
2643
3
    }
2644
2645
7
    can_info.len = (uint32_t)parsed.datalen;
2646
7
    can_info.fd = parsed.is_fd ? CAN_TYPE_CAN_FD : CAN_TYPE_CAN_CLASSIC;
2647
2648
    /* for practical reasons a remapping might be needed in the future */
2649
7
    can_info.bus_id = (uint16_t)parsed.bus_id;
2650
2651
7
    next_tvb = tvb_new_subset_length(tvb, offset, parsed.datalen);
2652
2653
7
    if (!socketcan_call_subdissectors(next_tvb, pinfo, tree, &can_info, can_heuristic_first)) {
2654
7
        call_data_dissector(next_tvb, pinfo, tree);
2655
7
    }
2656
2657
    /* Add padding bytes to ACF-CAN tree if any */
2658
7
    if (pad_length > 0 && tvb_reported_length_remaining(tvb, offset) >= pad_length)
2659
3
    {
2660
3
        proto_tree_add_item(tree_acf_can, hf_1722_can_padding, tvb, offset, pad_length, ENC_NA);
2661
3
    }
2662
2663
7
    return captured_length;
2664
14
}
2665
2666
static int dissect_1722_acf_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2667
13
{
2668
13
    return dissect_1722_acf_can_common(tvb, pinfo, tree, data, false);
2669
13
}
2670
2671
static int dissect_1722_acf_can_brief(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2672
1
{
2673
1
    return dissect_1722_acf_can_common(tvb, pinfo, tree, data, true);
2674
1
}
2675
2676
void proto_register_1722_acf_can(void)
2677
15
{
2678
15
    static hf_register_info hf[] = {
2679
        /* ACF-CAN, ACF-CAN-BRIEF and CAN fields */
2680
15
        { &hf_1722_can_flags,
2681
15
            { "Flags", "acf-can.flags",
2682
15
              FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
2683
15
        },
2684
15
        { &hf_1722_can_pad,
2685
15
            { "Padding Length", "acf-can.flags.pad",
2686
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_CAN_PAD_MASK, NULL, HFILL }
2687
15
        },
2688
15
        { &hf_1722_can_len,
2689
15
            { "Frame-Length", "can.len",
2690
15
              FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
2691
15
        },
2692
15
        { &hf_1722_can_mtvfield,
2693
15
            { "Message Timestamp Valid", "acf-can.flags.mtv",
2694
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_MTV_MASK, NULL, HFILL }
2695
15
        },
2696
15
        { &hf_1722_can_fdffield,
2697
15
            { "CAN Flexible Data-rate Format", "acf-can.flags.fdf",
2698
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_FDF_MASK, NULL, HFILL }
2699
15
        },
2700
15
        { &hf_1722_can_rtrfield,
2701
15
            { "Remote Transmission Request Flag", "can.flags.rtr",
2702
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_RTR_MASK, NULL, HFILL }
2703
15
        },
2704
15
        { &hf_1722_can_efffield,
2705
15
            { "Extended Flag", "can.flags.xtd",
2706
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_EFF_MASK, NULL, HFILL }
2707
15
        },
2708
15
        { &hf_1722_can_brsfield,
2709
15
            { "Bit Rate Setting", "canfd.flags.brs",
2710
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_BRS_MASK, NULL, HFILL }
2711
15
        },
2712
15
        { &hf_1722_can_esifield,
2713
15
            { "Error Message Flag", "canfd.flags.esi",
2714
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_ESI_MASK, NULL, HFILL }
2715
15
        },
2716
15
        { &hf_1722_can_rsv1,
2717
15
            { "Reserved Bits", "acf-can.rsv1",
2718
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_ACF_CAN_RSV1_MASK, NULL, HFILL }
2719
15
        },
2720
15
        { &hf_1722_can_bus_id,
2721
15
            { "CAN Bus Identifier", "acf-can.bus_id",
2722
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_CAN_BUS_ID_MASK, NULL, HFILL }
2723
15
        },
2724
15
        { &hf_1722_can_message_timestamp,
2725
15
            { "Message Timestamp", "acf-can.message_timestamp",
2726
15
              FT_UINT64, BASE_HEX, NULL, IEEE_1722_ACF_CAN_MSG_TIMESTAMP_MASK, NULL, HFILL }
2727
15
        },
2728
15
        { &hf_1722_can_rsv2,
2729
15
            { "Reserved", "acf-can.rsv2",
2730
15
              FT_UINT32, BASE_HEX, NULL, IEEE_1722_ACF_CAN_RSV2_MASK, NULL, HFILL }
2731
15
        },
2732
15
        { &hf_1722_can_identifier,
2733
15
            { "CAN Message Identifier", "can.id",
2734
15
              FT_UINT32, BASE_HEX, NULL, IEEE_1722_ACF_CAN_IDENTIFIER_MASK, NULL, HFILL }
2735
15
        },
2736
15
        { &hf_1722_can_padding,
2737
15
            { "Padding", "can.padding",
2738
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
2739
15
        },
2740
15
    };
2741
2742
15
    static int *ett[] =
2743
15
    {
2744
15
        &ett_1722_can,
2745
15
        &ett_1722_can_flags,
2746
15
        &ett_1722_can_bus_id,
2747
15
        &ett_1722_can_msg_id,
2748
15
        &ett_can
2749
15
    };
2750
2751
15
    static ei_register_info ei[] = {
2752
15
        { &ei_1722_can_header_cropped,          { "acf-can.expert.header_cropped",  PI_PROTOCOL, PI_WARN,
2753
15
                                                  "Message is cropped, no space for header", EXPFILL }},
2754
15
        { &ei_1722_can_invalid_message_id,      { "acf-can.expert.incorrect_can_id", PI_PROTOCOL, PI_WARN,
2755
15
                                                  "Incorrect msg id, shall be 0..1FF when EFF flag is not set", EXPFILL }},
2756
15
        { &ei_1722_can_invalid_payload_length,  { "acf-can.expert.incorrect_datalen", PI_PROTOCOL, PI_WARN,
2757
15
                                                  "Incorrect payload length, shall be [0..8] when FDF flag is not set", EXPFILL }},
2758
15
        { &ei_1722_canfd_invalid_payload_length,{ "acf-can.expert.incorrect_fd_datalen", PI_PROTOCOL, PI_WARN,
2759
15
                                                  "Incorrect FD payload length, shall be [0..8, 12, 16, 20, 32, 48, 64] when FDF flag is set", EXPFILL }},
2760
15
    };
2761
2762
15
    module_t*        module_acf_can;
2763
15
    expert_module_t* expert_1722_acf_can;
2764
2765
    /* Register the protocol name and description */
2766
15
    proto_1722_acf_can = proto_register_protocol("ACF CAN", "CAN over AVTP", "acf-can");
2767
15
    avb1722_can_handle = register_dissector("acf-can", dissect_1722_acf_can, proto_1722_acf_can);
2768
15
    avb1722_can_brief_handle = register_dissector("acf-can-brief", dissect_1722_acf_can_brief, proto_1722_acf_can);
2769
2770
    /* Required function calls to register the header fields and subtrees used */
2771
15
    proto_register_field_array(proto_1722_acf_can, hf, array_length(hf));
2772
15
    proto_register_subtree_array(ett, array_length(ett));
2773
2774
15
    expert_1722_acf_can = expert_register_protocol(proto_1722_acf_can);
2775
15
    expert_register_field_array(expert_1722_acf_can, ei, array_length(ei));
2776
2777
    /* register preferences */
2778
15
    module_acf_can = prefs_register_protocol(proto_1722_acf_can, NULL);
2779
2780
15
    prefs_register_obsolete_preference(module_acf_can, "protocol");
2781
15
    prefs_register_bool_preference(
2782
15
        module_acf_can, "try_heuristic_first",
2783
15
        "Try heuristic sub-dissectors first",
2784
15
        "Try to decode a packet using an heuristic sub-dissector"
2785
15
        " before using a sub-dissector registered to \"decode as\"",
2786
15
        &can_heuristic_first
2787
15
    );
2788
2789
15
}
2790
2791
void proto_reg_handoff_1722_acf_can(void)
2792
15
{
2793
15
    dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_CAN, avb1722_can_handle);
2794
15
    dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_CAN_BRIEF, avb1722_can_brief_handle);
2795
2796
15
    register_depend_dissector("acf-can", "can");
2797
15
    register_depend_dissector("acf-can", "canfd");
2798
2799
15
    proto_can = proto_get_id_by_filter_name("can");
2800
15
    proto_canfd = proto_get_id_by_filter_name("canfd");
2801
15
}
2802
2803
/**************************************************************************************************/
2804
/* ACF LIN Message dissector implementation                                                       */
2805
/*                                                                                                */
2806
/**************************************************************************************************/
2807
static void describe_lin_message(proto_item *dst, uint32_t bus_id, uint32_t lin_id)
2808
6
{
2809
6
    proto_item_append_text(dst, ": bus_id=%u, id=0x%02X", bus_id, lin_id);
2810
6
}
2811
2812
static int dissect_1722_acf_lin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2813
3
{
2814
3
    proto_item *ti;
2815
3
    proto_item *ti_lin;
2816
3
    proto_tree *tree_lin;
2817
3
    proto_tree *tree_flags;
2818
3
    unsigned    offset = 0;
2819
3
    unsigned    captured_length = tvb_captured_length(tvb);
2820
3
    uint32_t    pad_length;
2821
3
    bool        mtv;
2822
3
    uint32_t    bus_id;
2823
3
    uint32_t    lin_id;
2824
3
    int         payload_length;
2825
2826
3
    ti_lin = proto_tree_add_item(tree, proto_1722_acf_lin, tvb, offset, -1, ENC_NA);
2827
3
    tree_lin = proto_item_add_subtree(ti_lin, ett_1722_lin);
2828
2829
3
    if (captured_length < IEEE_1722_ACF_LIN_HEADER_SIZE) {
2830
0
        expert_add_info(pinfo, ti_lin, &ei_1722_lin_header_cropped);
2831
0
        return captured_length;
2832
0
    }
2833
2834
3
    tree_flags = proto_tree_add_subtree(tree_lin, tvb, offset, 1, ett_1722_lin_flags, &ti, "Flags and BusID");
2835
3
    proto_tree_add_item_ret_uint(tree_flags, hf_1722_lin_pad, tvb, offset, 1, ENC_BIG_ENDIAN, &pad_length);
2836
3
    proto_tree_add_item_ret_boolean(tree_flags, hf_1722_lin_mtv, tvb, offset, 1, ENC_BIG_ENDIAN, &mtv);
2837
3
    proto_tree_add_item_ret_uint(tree_flags, hf_1722_lin_bus_id, tvb, offset, 1, ENC_BIG_ENDIAN, &bus_id);
2838
3
    proto_item_append_text(ti, ": pad=%u, mtv=%u, bus_id=%u", pad_length, (unsigned)mtv, bus_id);
2839
3
    offset += 1;
2840
2841
3
    proto_tree_add_item_ret_uint(tree_lin, hf_1722_lin_identifier, tvb, offset, 1, ENC_BIG_ENDIAN, &lin_id);
2842
3
    offset += 1;
2843
2844
3
    proto_tree_add_item(tree_lin, hf_1722_lin_message_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
2845
3
    offset += 8;
2846
2847
3
    describe_lin_message(ti_lin, bus_id, lin_id);
2848
3
    describe_lin_message(proto_tree_get_parent(tree), bus_id, lin_id);
2849
3
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACF-LIN");
2850
3
    col_clear(pinfo->cinfo, COL_INFO);
2851
3
    col_add_fstr(pinfo->cinfo, COL_INFO, "ACF-LIN(%u): 0x%02x   ", bus_id, lin_id);
2852
2853
3
    payload_length = tvb_reported_length_remaining(tvb, offset) - pad_length;
2854
2855
3
    if (payload_length < 0 || payload_length > 8)
2856
2
    {
2857
2
        expert_add_info(pinfo, ti_lin, &ei_1722_lin_invalid_payload_length);
2858
2
    }
2859
1
    else if (payload_length > 0)
2860
1
    {
2861
1
        tvbuff_t*   next_tvb = tvb_new_subset_length(tvb, offset, payload_length);
2862
2863
1
        col_append_str(pinfo->cinfo, COL_INFO, tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, payload_length, ' '));
2864
2865
        /* at the moment, there's no global LIN sub-protocols support. Use our own. */
2866
1
        if (dissector_try_payload_with_data(avb1722_acf_lin_dissector_table, next_tvb, pinfo, tree, true, &lin_id) <= 0)
2867
1
        {
2868
1
            call_data_dissector(next_tvb, pinfo, tree);
2869
1
        }
2870
2871
1
        offset += payload_length;
2872
1
    }
2873
2874
3
    if (pad_length > 0 && tvb_reported_length_remaining(tvb, offset) >= pad_length)
2875
1
    {
2876
1
        proto_tree_add_item(tree_lin, hf_1722_lin_padding, tvb, offset, pad_length, ENC_NA);
2877
1
    }
2878
2879
3
    return captured_length;
2880
3
}
2881
2882
void proto_register_1722_acf_lin(void)
2883
15
{
2884
15
    static hf_register_info hf[] = {
2885
15
        { &hf_1722_lin_pad,
2886
15
            { "Padding Length", "acf-lin.flags.pad",
2887
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_LIN_PAD_MASK, NULL, HFILL }
2888
15
        },
2889
15
        { &hf_1722_lin_mtv,
2890
15
            { "Message Timestamp Valid", "acf-lin.flags.mtv",
2891
15
              FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_LIN_MTV_MASK, NULL, HFILL }
2892
15
        },
2893
15
        { &hf_1722_lin_bus_id,
2894
15
            { "LIN Bus Identifier", "acf-lin.bus_id",
2895
15
              FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_LIN_BUS_ID_MASK, NULL, HFILL }
2896
15
        },
2897
15
        { &hf_1722_lin_identifier,
2898
15
            { "LIN Message Identifier", "acf-lin.id",
2899
15
              FT_UINT8, BASE_HEX, NULL, IEEE_1722_ACF_LIN_IDENTIFIER_MASK, NULL, HFILL }
2900
15
        },
2901
15
        { &hf_1722_lin_message_timestamp,
2902
15
            { "Message Timestamp", "acf-lin.message_timestamp",
2903
15
              FT_UINT64, BASE_HEX, NULL, IEEE_1722_ACF_LIN_MSG_TIMESTAMP_MASK, NULL, HFILL }
2904
15
        },
2905
15
        { &hf_1722_lin_padding,
2906
15
            { "Padding", "acf-lin.padding",
2907
15
              FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
2908
15
        },
2909
15
    };
2910
2911
15
    static int *ett[] =
2912
15
    {
2913
15
        &ett_1722_lin,
2914
15
        &ett_1722_lin_flags,
2915
15
    };
2916
2917
15
    static ei_register_info ei[] = {
2918
15
        { &ei_1722_lin_header_cropped,          { "acf-lin.expert.header_cropped",  PI_PROTOCOL, PI_WARN,
2919
15
                                                  "Message is cropped, no space for header", EXPFILL }},
2920
15
        { &ei_1722_lin_invalid_payload_length,  { "acf-lin.expert.incorrect_datalen", PI_PROTOCOL, PI_WARN,
2921
15
                                                  "Incorrect payload length, shall be [0..8]", EXPFILL }},
2922
15
    };
2923
2924
15
    expert_module_t* expert_1722_acf_lin;
2925
2926
    /* Register the protocol name and description */
2927
15
    proto_1722_acf_lin = proto_register_protocol("ACF LIN", "LIN over AVTP", "acf-lin");
2928
2929
    /* Required function calls to register the header fields and subtrees used */
2930
15
    proto_register_field_array(proto_1722_acf_lin, hf, array_length(hf));
2931
15
    proto_register_subtree_array(ett, array_length(ett));
2932
2933
15
    expert_1722_acf_lin = expert_register_protocol(proto_1722_acf_lin);
2934
15
    expert_register_field_array(expert_1722_acf_lin, ei, array_length(ei));
2935
2936
15
    avb1722_acf_lin_dissector_table = register_decode_as_next_proto(proto_1722_acf_lin, "acf-lin.subdissector", "ACF-LIN next level dissector", NULL);
2937
2938
15
    avb1722_acf_lin_handle = register_dissector("acf-lin", dissect_1722_acf_lin, proto_1722_acf_lin);
2939
15
}
2940
2941
void proto_reg_handoff_1722_acf_lin(void)
2942
15
{
2943
15
    dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_LIN, avb1722_acf_lin_handle);
2944
15
}
2945
2946
/*
2947
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2948
 *
2949
 * Local variables:
2950
 * c-basic-offset: 4
2951
 * tab-width: 8
2952
 * indent-tabs-mode: nil
2953
 * End:
2954
 *
2955
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2956
 * :indentSize=4:tabSize=8:noTabs=true:
2957
 */