Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ieee1722.c
blob929be9082a720c7a60d97bc876ef5826721a7feb
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>
7 * Copyright 2011, Thomas Bottom <tom.bottom@labxtechnologies.com>
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.
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.
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
26 * Wireshark - Network traffic analyzer
27 * By Gerald Combs <gerald@wireshark.org>
28 * Copyright 1998 Gerald Combs
30 * SPDX-License-Identifier: GPL-2.0-or-later
32 * The 1722 Protocol specification can be found at the following:
33 * http://grouper.ieee.org/groups/1722/
37 #include "config.h"
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"
49 #include "packet-mp2t.h"
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);
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;
82 static dissector_handle_t jpeg_handle;
83 static dissector_handle_t h264_handle;
84 static dissector_handle_t mp2t_handle;
86 #define UDP_PORT_IEEE_1722 17220 /* One of two IANA registered ports */
88 enum IEEE_1722_TRANSPORT {
89 IEEE_1722_TRANSPORT_ETH,
90 IEEE_1722_TRANSPORT_UDP,
93 typedef struct _ieee1722_seq_data_t {
94 uint32_t seqnum_exp;
95 } ieee1722_seq_data_t;
97 /**************************************************************************************************/
98 /* 1722 */
99 /* */
100 /**************************************************************************************************/
101 #define IEEE_1722_SUBTYPE_61883 0x00
102 #define IEEE_1722_SUBTYPE_AAF 0x02
103 #define IEEE_1722_SUBTYPE_CVF 0x03
104 #define IEEE_1722_SUBTYPE_CRF 0x04
105 #define IEEE_1722_SUBTYPE_TSCF 0x05
106 #define IEEE_1722_SUBTYPE_NTSCF 0x82
108 /* Bit Field Masks */
109 #define IEEE_1722_SV_MASK 0x80
110 #define IEEE_1722_VER_MASK 0x70
112 /**************************************************************************************************/
113 /* subtype IEC 61883 */
114 /* */
115 /**************************************************************************************************/
116 #define IEEE_1722_CIP_HEADER_SIZE 8
117 #define IEEE_1722_61883_TAG_NO_CIP 0x00
118 #define IEEE_1722_61883_TAG_CIP 0x40
119 #define IEEE_1722_61883_CHANNEL_AVTP 31
120 #define IEEE_1722_61883_SID_AVTP 63
121 #define IEEE_1722_61883_4_LEN_SOURCE_PACKET 192
122 #define IEEE_1722_61883_4_LEN_SP_TIMESTAMP 4
123 #define IEEE_1722_61883_4 0x20
124 #define IEEE_1722_61883_6 0x10
126 /* Bit Field Masks */
127 #define IEEE_1722_MR_MASK 0x08
128 #define IEEE_1722_GV_MASK 0x02
129 #define IEEE_1722_TV_MASK 0x01
130 #define IEEE_1722_TU_MASK 0x01
131 #define IEEE_1722_TAG_MASK 0xc0
132 #define IEEE_1722_CHANNEL_MASK 0x3f
133 #define IEEE_1722_TCODE_MASK 0xf0
134 #define IEEE_1722_SY_MASK 0x0f
135 #define IEEE_1722_QI1_MASK 0xc0
136 #define IEEE_1722_SID_MASK 0x3f
137 #define IEEE_1722_FN_MASK 0xc0
138 #define IEEE_1722_QPC_MASK 0x38
139 #define IEEE_1722_SPH_MASK 0x04
140 #define IEEE_1722_QI2_MASK 0xc0
141 #define IEEE_1722_FMT_MASK 0x3f
142 #define IEEE_1722_FDF_TSF_MASK 0x80
143 #define IEEE_1722_FDF_MASK 0xff
145 /**************************************************************************************************/
146 /* subtype AAF */
147 /* */
148 /**************************************************************************************************/
149 #define IEEE_1722_AAF_FORMAT_USER 0x00
150 #define IEEE_1722_AAF_FORMAT_FLOAT_32_BIT 0x01
151 #define IEEE_1722_AAF_FORMAT_INT_32_BIT 0x02
152 #define IEEE_1722_AAF_FORMAT_INT_24_BIT 0x03
153 #define IEEE_1722_AAF_FORMAT_INT_16_BIT 0x04
154 #define IEEE_1722_AAF_FORMAT_AES3_32_BIT 0x05
156 /* Bit Field Masks */
157 #define IEEE_1722_MR_MASK 0x08
158 #define IEEE_1722_TV_MASK 0x01
159 #define IEEE_1722_SEQ_NUM_MASK 0x0
160 #define IEEE_1722_TU_MASK 0x01
161 #define IEEE_1722_STREAM_ID_MASK 0x0
162 #define IEEE_1722_TIMESTAMP_MASK 0x0
163 #define IEEE_1722_FORMAT_MASK 0x0
164 #define IEEE_1722_NOM_SAMPLE_RATE_MASK 0xf000
165 #define IEEE_1722_CHANNEL_PER_FRAME_MASK 0x03ff
166 #define IEEE_1722_BIT_DEPTH_MASK 0x0
167 #define IEEE_1722_AES3_DATA_TYPE_H_MASK 0x0
168 #define IEEE_1722_STREAM_DATA_LENGTH_MASK 0x0
169 #define IEEE_1722_AES3_DATA_TYPE_REFERENCE_MASK 0xe0
170 #define IEEE_1722_SP_MASK 0x10
171 #define IEEE_1722_EVT_MASK 0x0f
172 #define IEEE_1722_AES3_DATA_TYPE_L_MASK 0x0
173 #define IEEE_1722_DATA_MASK 0x0
174 #define IEEE_1722_SAMPLE_MASK 0x0
176 /**************************************************************************************************/
177 /* subtype CVF */
178 /* */
179 /**************************************************************************************************/
180 #define IEEE_1722_CVF_FORMAT_RFC 0x02
181 #define IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG 0x0
182 #define IEEE_1722_CVF_FORMAT_SUBTYPE_H264 0x01
183 #define IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000 0x02
185 /* More bit Field Masks */
186 #define IEEE_1722_FORMAT_SUBTYPE_MASK 0x0
187 #define IEEE_1722_CVF_H264_TIMESTAMP_MASK 0x0
188 #define IEEE_1722_H264_PTV_MASK 0x20
189 #define IEEE_1722_MARKER_BIT_MASK 0x10
191 /**************************************************************************************************/
192 /* subtype CRF */
193 /* */
194 /**************************************************************************************************/
195 #define IEEE_1722_CRF_TIMESTAMP_SIZE 8 /* size of the CRF timestamp in bytes */
197 /* Bit Field Masks */
198 #define IEEE_1722_MR_MASK 0x08
199 #define IEEE_1722_FS_MASK 0x02
200 #define IEEE_1722_TU_MASK 0x01
201 #define IEEE_1722_PULL_MASK 0xe0000000
202 #define IEEE_1722_BASE_FREQUENCY_MASK 0x1fffffff
204 /**************************************************************************************************/
205 /* subtype NTSCF */
206 /* */
207 /**************************************************************************************************/
208 #define IEEE_1722_NTSCF_HEADER_SIZE 12 /* including common header */
210 /* Bit Field Masks */
211 #define IEEE_1722_NTSCF_R_MASK 0x0800
212 #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
216 /**************************************************************************************************/
217 /* subtype TSCF */
218 /* */
219 /**************************************************************************************************/
220 #define IEEE_1722_TSCF_HEADER_SIZE 24 /* including common header */
222 /* Bit Field Masks */
223 #define IEEE_1722_TSCF_MR_MASK 0x08
224 #define IEEE_1722_TSCF_RSV1_MASK 0x06
225 #define IEEE_1722_TSCF_TV_MASK 0x01
226 #define IEEE_1722_TSCF_SEQNUM_MASK 0x0
227 #define IEEE_1722_TSCF_RSV2_MASK 0xFE
228 #define IEEE_1722_TSCF_TU_MASK 0x01
229 #define IEEE_1722_TSCF_STREAM_ID_MASK 0x0
230 #define IEEE_1722_TSCF_AVTP_TIMESTAMP_MASK 0x0
231 #define IEEE_1722_TSCF_RSV3_MASK 0x0
232 #define IEEE_1722_TSCF_DATA_LENGTH_MASK 0x0
233 #define IEEE_1722_TSCF_RSV4_MASK 0x0
235 /**************************************************************************************************/
236 /* AVTP Control Format (ACF) Message Header */
237 /* */
238 /**************************************************************************************************/
239 #define IEEE_1722_ACF_HEADER_SIZE 2
241 /* ACF message types */
242 #define IEEE_1722_ACF_TYPE_FLEXRAY 0x00
243 #define IEEE_1722_ACF_TYPE_CAN 0x01
244 #define IEEE_1722_ACF_TYPE_CAN_BRIEF 0x02
245 #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
263 /* Bit Field Masks */
264 #define IEEE_1722_ACF_MSG_TYPE_MASK 0xFE00
265 #define IEEE_1722_ACF_MSG_LENGTH_MASK 0x01FF
267 /**************************************************************************************************/
268 /* ACF CAN Message */
269 /* */
270 /**************************************************************************************************/
271 #define IEEE_1722_ACF_CAN_BRIEF_HEADER_SIZE 6
272 #define IEEE_1722_ACF_CAN_HEADER_SIZE 14
274 /* Bit Field Masks */
275 #define IEEE_1722_ACF_CAN_PAD_MASK 0xC0u
276 #define IEEE_1722_ACF_CAN_FLAGS_MASK 0x3Fu
277 #define IEEE_1722_ACF_CAN_MTV_MASK 0x20u
278 #define IEEE_1722_ACF_CAN_RTR_MASK 0x10u
279 #define IEEE_1722_ACF_CAN_EFF_MASK 0x08u
280 #define IEEE_1722_ACF_CAN_BRS_MASK 0x04u
281 #define IEEE_1722_ACF_CAN_FDF_MASK 0x02u
282 #define IEEE_1722_ACF_CAN_ESI_MASK 0x01u
283 #define IEEE_1722_ACF_CAN_RSV1_MASK 0xE0u
284 #define IEEE_1722_ACF_CAN_BUS_ID_MASK 0x1Fu
285 #define IEEE_1722_ACF_CAN_MSG_TIMESTAMP_MASK 0x00u
286 #define IEEE_1722_ACF_CAN_RSV2_MASK 0xE0000000u
287 #define IEEE_1722_ACF_CAN_IDENTIFIER_MASK 0x1FFFFFFFu
288 #define IEEE_1722_ACF_CAN_11BIT_ID_MASK 0x7FFu
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
301 /**************************************************************************************************/
302 /* ACF LIN Message */
303 /* */
304 /**************************************************************************************************/
305 #define IEEE_1722_ACF_LIN_HEADER_SIZE 10
307 /* Bit Field Masks */
308 #define IEEE_1722_ACF_LIN_PAD_MASK 0xC0
309 #define IEEE_1722_ACF_LIN_MTV_MASK 0x20
310 #define IEEE_1722_ACF_LIN_BUS_ID_MASK 0x1F
311 #define IEEE_1722_ACF_LIN_IDENTIFIER_MASK 0x0
312 #define IEEE_1722_ACF_LIN_MSG_TIMESTAMP_MASK 0x0
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 }
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;
355 /* Initialize the subtree pointers */
356 static int ett_1722;
358 static expert_field ei_1722_encap_seqnum_dup;
359 static expert_field ei_1722_encap_seqnum_ooo;
361 static dissector_table_t avb_dissector_table;
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}
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}
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}
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}
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}
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;
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;
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;
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}
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}
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}
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;
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;
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;
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}
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}
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;
613 /* Initialize the subtree pointers */
614 static int ett_1722_crf;
615 static int ett_1722_crf_timestamp;
617 /* Initialize expert fields */
618 static expert_field ei_crf_datalen;
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}
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}
639 /* Initialize the protocol and registered fields */
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;
656 /* Initialize the subtree pointers */
657 static int ett_1722_cvf;
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;
664 /**************************************************************************************************/
665 /* subtype NTSCF */
666 /* */
667 /**************************************************************************************************/
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;
676 /* Initialize the subtree pointers */
677 static int ett_1722_ntscf;
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;
683 /**************************************************************************************************/
684 /* subtype TSCF */
685 /* */
686 /**************************************************************************************************/
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;
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;
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;
712 /**************************************************************************************************/
713 /* AVTP Control Format (ACF) Message Header */
714 /* */
715 /**************************************************************************************************/
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}
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;
740 /* Initialize the subtree pointers */
741 static int ett_1722_acf;
742 static int ett_1722_acf_header;
744 /* Initialize expert fields */
745 static expert_field ei_1722_acf_invalid_msg_length;
746 static expert_field ei_1722_acf_message_is_cropped;
748 /* Dissector handles */
749 static dissector_handle_t avb1722_acf_handle;
750 static dissector_table_t avb1722_acf_dissector_table;
752 /**************************************************************************************************/
753 /* ACF CAN Message */
754 /* */
755 /**************************************************************************************************/
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;
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;
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;
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;
799 /* Dissector handles */
800 static dissector_handle_t avb1722_can_brief_handle;
801 static dissector_handle_t avb1722_can_handle;
803 static int proto_can;
804 static int proto_canfd;
805 static bool can_heuristic_first;
807 /**************************************************************************************************/
808 /* ACF LIN Message */
809 /* */
810 /**************************************************************************************************/
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;
821 /* Initialize the subtree pointers */
822 static int ett_1722_lin;
823 static int ett_1722_lin_flags;
825 /* Initialize expert fields */
826 static expert_field ei_1722_lin_header_cropped;
827 static expert_field ei_1722_lin_invalid_payload_length;
829 static dissector_table_t avb1722_acf_lin_dissector_table;
831 /**************************************************************************************************/
832 /* 1722 dissector implementation */
833 /* */
834 /**************************************************************************************************/
836 static uint32_t
837 get_seqnum_exp_1722_udp(packet_info *pinfo, const uint32_t seqnum)
839 conversation_t *conv;
840 ieee1722_seq_data_t *conv_seq_data, *p_seq_data;
842 if (!PINFO_FD_VISITED(pinfo)) {
843 conv = find_or_create_conversation(pinfo);
844 conv_seq_data = (ieee1722_seq_data_t *)conversation_get_proto_data(conv, proto_1722);
845 if (conv_seq_data == NULL) {
846 conv_seq_data = wmem_new(wmem_file_scope(), ieee1722_seq_data_t);
847 conv_seq_data->seqnum_exp = seqnum;
849 conversation_add_proto_data(conv, proto_1722, conv_seq_data);
850 } else {
851 conv_seq_data->seqnum_exp++;
853 p_seq_data = wmem_new(wmem_file_scope(), ieee1722_seq_data_t);
854 p_seq_data->seqnum_exp = conv_seq_data->seqnum_exp;
855 p_add_proto_data(wmem_file_scope(), pinfo, proto_1722, 0, p_seq_data);
857 } else {
858 p_seq_data = (ieee1722_seq_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_1722, 0);
860 DISSECTOR_ASSERT(p_seq_data != NULL);
861 return p_seq_data->seqnum_exp;
864 static int dissect_1722_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, enum IEEE_1722_TRANSPORT transport)
866 tvbuff_t *next_tvb;
867 proto_item *ti;
868 proto_tree *ieee1722_tree;
869 uint32_t encap_seqnum, encap_seqnum_exp;
870 unsigned subtype = 0;
871 int offset = 0;
872 int dissected_size;
873 static int * const fields[] = {
874 &hf_1722_svfield,
875 &hf_1722_verfield,
876 NULL
879 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE1722");
880 col_set_str(pinfo->cinfo, COL_INFO, "Audio Video Transport Protocol");
882 ti = proto_tree_add_item(tree, proto_1722, tvb, 0, -1, ENC_NA);
883 ieee1722_tree = proto_item_add_subtree(ti, ett_1722);
885 if (transport == IEEE_1722_TRANSPORT_UDP) {
886 /* IEEE 1722-2016 Annex J IP Encapsulation */
887 ti = proto_tree_add_item_ret_uint(ieee1722_tree, hf_1722_encap_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &encap_seqnum);
888 encap_seqnum_exp = get_seqnum_exp_1722_udp(pinfo, encap_seqnum);
889 if (encap_seqnum != encap_seqnum_exp) {
890 if ((encap_seqnum + 1) == encap_seqnum_exp) {
891 expert_add_info(pinfo, ti, &ei_1722_encap_seqnum_dup);
892 } else {
893 expert_add_info(pinfo, ti, &ei_1722_encap_seqnum_ooo);
896 offset += 4;
897 next_tvb = tvb_new_subset_remaining(tvb, offset);
898 } else {
899 next_tvb = tvb;
902 proto_tree_add_item_ret_uint(ieee1722_tree, hf_1722_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &subtype);
903 offset += 1;
904 proto_tree_add_bitmask_list(ieee1722_tree, tvb, offset, 1, fields, ENC_NA);
906 /* call any registered subtype dissectors which use only the common AVTPDU (e.g. 1722.1, MAAP, 61883, AAF, CRF or CVF) */
907 dissected_size = dissector_try_uint(avb_dissector_table, subtype, next_tvb, pinfo, tree);
908 if (dissected_size > 0) {
909 return dissected_size;
912 call_data_dissector(next_tvb, pinfo, ieee1722_tree);
913 return tvb_captured_length(tvb);
916 static int dissect_1722_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
918 return dissect_1722_common(tvb, pinfo, tree, IEEE_1722_TRANSPORT_ETH);
921 static int dissect_1722_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
923 return dissect_1722_common(tvb, pinfo, tree, IEEE_1722_TRANSPORT_UDP);
926 /* Register the protocol with Wireshark */
927 void proto_register_1722(void)
929 static hf_register_info hf[] = {
930 { &hf_1722_encap_seqnum,
931 { "Encapsulation Sequence Number", "ieee1722.encapsulation_sequence_num",
932 FT_UINT32, BASE_HEX, NULL, 0x0,
933 "Sequence number incremented for each AVTPDU on a 5-tuple", HFILL }
935 { &hf_1722_subtype,
936 { "AVTP Subtype", "ieee1722.subtype",
937 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(subtype_range_rvals), 0x0, NULL, HFILL }
939 { &hf_1722_svfield,
940 { "AVTP Stream ID Valid", "ieee1722.svfield",
941 FT_BOOLEAN, 8, NULL, IEEE_1722_SV_MASK, NULL, HFILL }
943 { &hf_1722_verfield,
944 { "AVTP Version", "ieee1722.verfield",
945 FT_UINT8, BASE_HEX, NULL, IEEE_1722_VER_MASK, NULL, HFILL }
949 static ei_register_info ei[] = {
950 { &ei_1722_encap_seqnum_dup, { "ieee1722.encapsulation_sequence_num.dup", PI_SEQUENCE, PI_NOTE, "Duplicate encapsulation_sequence_num (retransmission?)", EXPFILL }},
951 { &ei_1722_encap_seqnum_ooo, { "ieee1722.encapsulation_sequence_num.ooo", PI_SEQUENCE, PI_WARN, "Unexpected encapsulation_sequence_num (lost or out-of-order?)", EXPFILL }},
954 static int *ett[] = {
955 &ett_1722
958 expert_module_t *expert_1722;
960 /* Register the protocol name and description */
961 proto_1722 = proto_register_protocol("IEEE 1722 Audio Video Transport Protocol (AVTP)", "IEEE1722", "ieee1722");
963 /* Required function calls to register the header fields and subtrees used */
964 proto_register_field_array(proto_1722, hf, array_length(hf));
965 proto_register_subtree_array(ett, array_length(ett));
967 expert_1722 = expert_register_protocol(proto_1722);
968 expert_register_field_array(expert_1722, ei, array_length(ei));
970 /* Sub-dissector for 1722.1, 1722 AAF, 1722 CRF, 1722 61883, 1722 CVF */
971 avb_dissector_table = register_dissector_table("ieee1722.subtype",
972 "IEEE1722 AVTP Subtype", proto_1722, FT_UINT8, BASE_HEX);
974 avtp_handle_eth = register_dissector("ieee1722.eth", dissect_1722_eth, proto_1722);
975 avtp_handle_udp = register_dissector("ieee1722.udp", dissect_1722_udp, proto_1722);
978 void proto_reg_handoff_1722(void)
980 dissector_add_uint("ethertype", ETHERTYPE_AVTP, avtp_handle_eth);
981 dissector_add_uint_with_preference("udp.port", UDP_PORT_IEEE_1722, avtp_handle_udp);
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_)
990 proto_item *ti;
991 proto_tree *ti_61883_tree;
992 proto_tree *ti_channel;
993 proto_tree *ti_datalen;
994 proto_tree *ti_cip_fn;
995 proto_tree *ti_cip_dbs;
996 proto_tree *ti_cip_sph;
997 proto_tree *ti_cip_fmt;
998 proto_tree *ti_cip_fdf;
999 proto_tree *ti_audio_tree;
1000 proto_tree *ti_sample_tree;
1001 proto_tree *ti_video_tree;
1002 int offset = 1;
1003 uint8_t cip_dbs = 0;
1004 uint8_t tag = 0;
1005 uint8_t channel = 0;
1006 uint8_t tcode = 0;
1007 uint8_t cip_qi1 = 0;
1008 uint8_t cip_sid = 0;
1009 uint8_t cip_qpc = 0;
1010 uint8_t cip_qi2 = 0;
1011 uint8_t cip_fmt = 0;
1012 uint8_t cip_sph = 0;
1013 uint8_t cip_fn = 0;
1014 unsigned datalen = 0;
1015 unsigned db_size = 0;
1016 unsigned numSourcePackets = 0;
1017 unsigned i = 0;
1018 unsigned j = 0;
1019 static int * const fields[] = {
1020 &hf_1722_61883_mrfield,
1021 &hf_1722_61883_gvfield,
1022 &hf_1722_61883_tvfield,
1023 NULL
1026 ti = proto_tree_add_item(tree, proto_1722_61883, tvb, 0, -1, ENC_NA);
1027 ti_61883_tree = proto_item_add_subtree(ti, ett_1722_61883);
1029 proto_tree_add_bitmask_list(ti_61883_tree, tvb, offset, 1, fields, ENC_NA);
1030 offset += 1;
1031 proto_tree_add_item(ti_61883_tree, hf_1722_61883_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1032 offset += 1;
1033 proto_tree_add_item(ti_61883_tree, hf_1722_61883_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1034 offset += 1;
1035 proto_tree_add_item(ti_61883_tree, hf_1722_61883_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1036 offset += 8;
1038 proto_tree_add_item(ti_61883_tree, hf_1722_61883_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1039 offset += 4;
1040 proto_tree_add_item(ti_61883_tree, hf_1722_61883_gateway_info, tvb, offset, 4, ENC_BIG_ENDIAN);
1041 offset += 4;
1043 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 offset += 2;
1046 /* tag field defines if CIP header is included or not */
1047 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
1049 tag = tvb_get_uint8(tvb, offset) & IEEE_1722_TAG_MASK;
1050 if (tag > 0x40)
1052 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_tag);
1055 ti_channel = proto_tree_add_item(ti_61883_tree, hf_1722_61883_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
1056 channel = tvb_get_uint8(tvb, offset) & IEEE_1722_CHANNEL_MASK;
1057 if (channel != IEEE_1722_61883_CHANNEL_AVTP)
1059 proto_item_append_text(ti_channel, ": Originating Source ID from an IEEE 1394 serial bus");
1061 else
1063 proto_item_append_text(ti_channel, ": Originating source is on AVTP network (native AVTP)");
1065 offset += 1;
1067 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_tcode, tvb, offset, 1, ENC_BIG_ENDIAN);
1068 tcode = tvb_get_uint8(tvb, offset) & IEEE_1722_TCODE_MASK;
1069 if (tcode != 0xa0)
1071 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_tcode);
1074 proto_tree_add_item(ti_61883_tree, hf_1722_61883_sy, tvb, offset, 1, ENC_BIG_ENDIAN);
1075 offset += 1;
1077 switch (tag) {
1078 case IEEE_1722_61883_TAG_NO_CIP:
1079 proto_item_prepend_text(ti, "IIDC 1394 video payload:");
1080 break;
1081 case IEEE_1722_61883_TAG_CIP:
1082 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_qi1, tvb, offset, 1, ENC_BIG_ENDIAN);
1083 cip_qi1 = tvb_get_uint8(tvb, offset) & IEEE_1722_QI1_MASK;
1084 if (cip_qi1 != 0)
1086 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qi1);
1089 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_sid, tvb, offset, 1, ENC_BIG_ENDIAN);
1090 cip_sid = tvb_get_uint8(tvb, offset) & IEEE_1722_SID_MASK;
1091 if (cip_sid != IEEE_1722_61883_SID_AVTP)
1093 proto_item_append_text(ti, ": Originating Source ID from an IEEE 1394 serial bus");
1094 if (channel == IEEE_1722_61883_CHANNEL_AVTP)
1096 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_channel_sid);
1097 expert_add_info(pinfo, ti_channel, &ei_1722_61883_incorrect_channel_sid);
1101 else
1103 proto_item_append_text(ti, ": Originating source is on AVTP network");
1104 if (channel != IEEE_1722_61883_CHANNEL_AVTP)
1106 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_channel_sid);
1107 expert_add_info(pinfo, ti_channel, &ei_1722_61883_incorrect_channel_sid);
1110 offset += 1;
1112 ti_cip_dbs = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_dbs, tvb, offset, 1, ENC_BIG_ENDIAN);
1113 cip_dbs = tvb_get_uint8(tvb, offset);
1114 offset += 1;
1115 ti_cip_fn = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fn, tvb, offset, 1, ENC_BIG_ENDIAN);
1117 switch (tvb_get_uint8(tvb, offset) & IEEE_1722_FN_MASK) {
1118 case 0:
1119 cip_fn = 0;
1120 break;
1121 case 0x40:
1122 cip_fn = 2;
1123 break;
1124 case 0x80:
1125 cip_fn = 4;
1126 break;
1127 case 0xc0:
1128 cip_fn = 8;
1129 break;
1130 default:
1131 break;
1134 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_qpc, tvb, offset, 1, ENC_BIG_ENDIAN);
1135 cip_qpc = tvb_get_uint8(tvb, offset) & IEEE_1722_QPC_MASK;
1136 if (cip_qpc != 0)
1138 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qpc);
1141 ti_cip_sph = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_sph, tvb, offset, 1, ENC_BIG_ENDIAN);
1142 cip_sph = tvb_get_uint8(tvb, offset) & IEEE_1722_SPH_MASK;
1143 offset += 1;
1144 proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_dbc, tvb, offset, 1, ENC_BIG_ENDIAN);
1145 offset += 1;
1147 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_qi2, tvb, offset, 1, ENC_BIG_ENDIAN);
1148 cip_qi2 = tvb_get_uint8(tvb, offset) & IEEE_1722_QI2_MASK;
1149 if (cip_qi2 != 0x80)
1151 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_qi2);
1154 /* Check format field for 61883-4 MPEG-TS video or 61883-6 for audio */
1155 ti_cip_fmt = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fmt, tvb, offset, 1, ENC_BIG_ENDIAN);
1156 cip_fmt = tvb_get_uint8(tvb, offset) & IEEE_1722_FMT_MASK;
1157 offset += 1;
1159 if ((cip_fmt & 0x20) == 0)
1161 proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf, tvb, offset, 1, ENC_BIG_ENDIAN);
1162 offset += 1;
1163 proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_syt, tvb, offset, 2, ENC_BIG_ENDIAN);
1164 offset += 2;
1166 else
1168 ti_cip_fdf = proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf_no_syt, tvb, offset, 3, ENC_BIG_ENDIAN);
1169 if (((tvb_get_ntoh24(tvb, offset) & 0x7fffff) != 0))
1171 expert_add_info(pinfo, ti_cip_fdf, &ei_1722_61883_incorrect_cip_fdf);
1174 proto_tree_add_item(ti_61883_tree, hf_1722_61883_cip_fdf_tsf, tvb, offset, 3, ENC_BIG_ENDIAN);
1175 offset += 3;
1178 /* Calculate the remaining size by subtracting the CIP header size from the value in the packet data length field */
1179 datalen -= IEEE_1722_CIP_HEADER_SIZE;
1181 if (cip_dbs == 0) {
1182 db_size = 256;
1184 else
1186 db_size = cip_dbs;
1189 switch (cip_fmt) {
1190 case IEEE_1722_61883_6:
1191 if (cip_fn != 0)
1193 expert_add_info(pinfo, ti_cip_fn, &ei_1722_61883_6_incorrect_cip_fn);
1195 if (cip_sph != 0)
1197 expert_add_info(pinfo, ti_cip_sph, &ei_1722_61883_6_incorrect_cip_sph);
1200 /* Make the Audio sample tree. */
1201 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_audio_data, tvb, offset, datalen, ENC_NA);
1202 ti_audio_tree = proto_item_add_subtree(ti, ett_1722_61883_audio);
1203 if ((datalen % (db_size*4)) != 0)
1205 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_datalen);
1206 expert_add_info(pinfo, ti_datalen, &ei_1722_61883_incorrect_datalen);
1208 numSourcePackets = datalen / (db_size*4);
1210 if (ti_audio_tree) {
1211 /* Loop through all samples and add them to the audio tree. */
1212 for (j = 0; j < numSourcePackets; j++) {
1213 ti_sample_tree = proto_tree_add_subtree_format(ti_audio_tree, tvb, offset, 1, ett_1722_61883_sample, NULL, "Sample %d", j+1);
1214 for (i = 0; i < db_size; i++) {
1215 proto_tree_add_item(ti_sample_tree, hf_1722_61883_label, tvb, offset, 1, ENC_BIG_ENDIAN);
1216 offset += 1;
1217 proto_tree_add_item(ti_sample_tree, hf_1722_61883_sample, tvb, offset, 3, ENC_NA);
1218 offset += 3;
1222 break;
1223 case IEEE_1722_61883_4:
1224 if (db_size != 6)
1226 expert_add_info(pinfo, ti_cip_dbs, &ei_1722_61883_4_incorrect_cip_dbs);
1228 if (cip_fn != 8)
1230 expert_add_info(pinfo, ti_cip_fn, &ei_1722_61883_4_incorrect_cip_fn);
1232 if (cip_sph != 4)
1234 expert_add_info(pinfo, ti_cip_sph, &ei_1722_61883_4_incorrect_cip_sph);
1236 /* Make the video tree. */
1237 ti = proto_tree_add_item(ti_61883_tree, hf_1722_61883_video_data, tvb, offset, datalen, ENC_NA);
1238 ti_video_tree = proto_item_add_subtree(ti, ett_1722_61883_video);
1239 if ((datalen % IEEE_1722_61883_4_LEN_SOURCE_PACKET) != 0)
1241 expert_add_info(pinfo, ti, &ei_1722_61883_incorrect_datalen);
1242 expert_add_info(pinfo, ti_datalen, &ei_1722_61883_incorrect_datalen);
1244 numSourcePackets = datalen / IEEE_1722_61883_4_LEN_SOURCE_PACKET;
1246 /* if (ti_video_tree) - MP2T needs to be called regardless
1247 * for fragmentation handling */
1248 for (j = 0; j < numSourcePackets; j++) {
1249 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);
1250 offset += IEEE_1722_61883_4_LEN_SP_TIMESTAMP;
1251 call_dissector(mp2t_handle, tvb_new_subset_length(tvb, offset, MP2T_PACKET_SIZE), pinfo, ti_video_tree);
1252 offset += MP2T_PACKET_SIZE;
1254 break;
1255 default:
1256 expert_add_info(pinfo, ti_cip_fmt, &ei_1722_61883_unknown_format);
1257 break;
1259 break;
1260 default:
1261 break;
1263 return tvb_captured_length(tvb);
1266 void proto_register_1722_61883(void)
1268 static hf_register_info hf[] = {
1269 { &hf_1722_61883_mrfield,
1270 { "Media Clock Restart", "iec61883.mrfield",
1271 FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1273 { &hf_1722_61883_gvfield,
1274 { "Gateway Info Valid", "iec61883.gvfield",
1275 FT_BOOLEAN, 8, NULL, IEEE_1722_GV_MASK, NULL, HFILL }
1277 { &hf_1722_61883_tvfield,
1278 { "Timestamp Valid", "iec61883.tvfield",
1279 FT_BOOLEAN, 8, NULL, IEEE_1722_TV_MASK, NULL, HFILL }
1281 { &hf_1722_61883_seqnum,
1282 { "Sequence Number", "iec61883.seqnum",
1283 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1285 { &hf_1722_61883_tufield,
1286 { "Timestamp Uncertain", "iec61883.tufield",
1287 FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1289 { &hf_1722_61883_stream_id,
1290 { "Stream ID", "iec61883.stream_id",
1291 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1293 { &hf_1722_61883_avtp_timestamp,
1294 { "AVTP Timestamp", "iec61883.avtp_timestamp",
1295 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1297 { &hf_1722_61883_gateway_info,
1298 { "Gateway Info", "iec61883.gateway_info",
1299 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1301 { &hf_1722_61883_stream_data_length,
1302 { "1394 Stream Data Length", "iec61883.stream_data_len",
1303 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
1305 { &hf_1722_61883_tag,
1306 { "1394 Packet Format Tag", "iec61883.tag",
1307 FT_UINT8, BASE_HEX, VALS(tag_vals), IEEE_1722_TAG_MASK, NULL, HFILL }
1309 { &hf_1722_61883_channel,
1310 { "1394 Packet Channel", "iec61883.channel",
1311 FT_UINT8, BASE_DEC, NULL, IEEE_1722_CHANNEL_MASK, NULL, HFILL }
1313 { &hf_1722_61883_tcode,
1314 { "1394 Packet Tcode", "iec61883.tcode",
1315 FT_UINT8, BASE_HEX, NULL, IEEE_1722_TCODE_MASK, NULL, HFILL }
1317 { &hf_1722_61883_sy,
1318 { "1394 App-specific Control", "iec61883.sy",
1319 FT_UINT8, BASE_HEX, NULL, IEEE_1722_SY_MASK, NULL, HFILL }
1321 { &hf_1722_61883_cip_qi1,
1322 { "CIP Quadlet Indicator 1", "iec61883.qi1",
1323 FT_UINT8, BASE_HEX, NULL, IEEE_1722_QI1_MASK, NULL, HFILL }
1325 { &hf_1722_61883_cip_sid,
1326 { "CIP Source ID", "iec61883.sid",
1327 FT_UINT8, BASE_DEC, NULL, IEEE_1722_SID_MASK, NULL, HFILL }
1329 { &hf_1722_61883_cip_dbs,
1330 { "CIP Data Block Size", "iec61883.dbs",
1331 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1333 { &hf_1722_61883_cip_fn,
1334 { "CIP Fraction Number", "iec61883.fn",
1335 FT_UINT8, BASE_HEX, VALS(fraction_number_vals), IEEE_1722_FN_MASK, NULL, HFILL }
1337 { &hf_1722_61883_cip_qpc,
1338 { "CIP Quadlet Padding Count", "iec61883.qpc",
1339 FT_UINT8, BASE_HEX, NULL, IEEE_1722_QPC_MASK, NULL, HFILL }
1341 { &hf_1722_61883_cip_sph,
1342 { "CIP Source Packet Header", "iec61883.sph",
1343 FT_BOOLEAN, 8, NULL, IEEE_1722_SPH_MASK, NULL, HFILL }
1345 { &hf_1722_61883_cip_dbc,
1346 { "CIP Data Block Continuity", "iec61883.dbc",
1347 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1349 { &hf_1722_61883_cip_qi2,
1350 { "CIP Quadlet Indicator 2", "iec61883.qi2",
1351 FT_UINT8, BASE_HEX, NULL, IEEE_1722_QI2_MASK, NULL, HFILL }
1353 { &hf_1722_61883_cip_fmt,
1354 { "CIP Format ID", "iec61883.fmt",
1355 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(format_rvals), IEEE_1722_FMT_MASK, NULL, HFILL }
1357 { &hf_1722_61883_cip_fdf_no_syt,
1358 { "CIP Format Dependent Field", "iec61883.fdf_no_syt",
1359 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }
1361 { &hf_1722_61883_cip_fdf_tsf,
1362 { "Time shift flag", "iec61883.fdf_tsf",
1363 FT_BOOLEAN, 8, NULL, IEEE_1722_FDF_TSF_MASK, NULL, HFILL }
1365 { &hf_1722_61883_cip_fdf,
1366 { "CIP Format Dependent Field", "iec61883.fdf",
1367 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(fdf_rvals), IEEE_1722_FDF_MASK, NULL, HFILL }
1369 { &hf_1722_61883_cip_syt,
1370 { "CIP SYT", "iec61883.syt",
1371 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(syt_rvals), 0x0, NULL, HFILL }
1373 { &hf_1722_61883_audio_data,
1374 { "Audio Data", "iec61883.audiodata",
1375 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1377 { &hf_1722_61883_label,
1378 { "Label", "iec61883.audiodata.sample.label",
1379 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1381 { &hf_1722_61883_sample,
1382 { "Sample", "iec61883.audiodata.sample.sampledata",
1383 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1385 { &hf_1722_61883_video_data,
1386 { "Video Data", "iec61883.videodata",
1387 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1389 { &hf_1722_61883_source_packet_header_timestamp,
1390 { "Source Packet Header Timestamp", "iec61883.spht",
1391 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1395 static int *ett[] = {
1396 &ett_1722_61883,
1397 &ett_1722_61883_audio,
1398 &ett_1722_61883_sample,
1399 &ett_1722_61883_video
1402 static ei_register_info ei[] = {
1403 { &ei_1722_61883_incorrect_tag, { "iec61883.incorrect_tag", PI_PROTOCOL, PI_WARN,
1404 "Incorrect tag field, only 0x00 and 0x01 supported for AVTP", EXPFILL }},
1405 { &ei_1722_61883_incorrect_tcode, { "iec61883.incorrect_tcode", PI_PROTOCOL, PI_WARN,
1406 "Incorrect tcode, talker shall set this field to 0x0A", EXPFILL }},
1407 { &ei_1722_61883_incorrect_qi1, { "iec61883.incorrect_qi1", PI_PROTOCOL, PI_WARN,
1408 "Incorrect quadlet indicator 1 field, talker shall set this field to 0x00", EXPFILL }},
1409 { &ei_1722_61883_incorrect_qpc, { "iec61883.incorrect_qpc", PI_PROTOCOL, PI_WARN,
1410 "Incorrect quadlet padding count field, shall be set to 0", EXPFILL }},
1411 { &ei_1722_61883_incorrect_qi2, { "iec61883.incorrect_qi2", PI_PROTOCOL, PI_WARN,
1412 "Incorrect quadlet indicator 2 field, talker shall set this field to 0x02", EXPFILL }},
1413 { &ei_1722_61883_unknown_format, { "iec61883.unknown_format", PI_PROTOCOL, PI_NOTE,
1414 "IEC 61883 format not dissected yet", EXPFILL }},
1415 { &ei_1722_61883_incorrect_channel_sid, { "iec61883.incorrect_channel_sid", PI_PROTOCOL, PI_WARN,
1416 "1394 Packet Channel and Source ID don`t match", EXPFILL }},
1417 { &ei_1722_61883_incorrect_datalen, { "iec61883.incorrect_datalen", PI_PROTOCOL, PI_WARN,
1418 "Incorrect stream data length field, must be multiple of 192 plus 8 bytes CIP header", EXPFILL }},
1419 { &ei_1722_61883_4_incorrect_cip_fn, { "iec61883.4_incorrect_cip_fn", PI_PROTOCOL, PI_WARN,
1420 "Incorrect fraction number, shall be 8 for IEC 61883-4", EXPFILL }},
1421 { &ei_1722_61883_4_incorrect_cip_dbs, { "iec61883.4_incorrect_cip_dbs", PI_PROTOCOL, PI_WARN,
1422 "Incorrect data block size, shall be 6 for IEC 61883-4", EXPFILL }},
1423 { &ei_1722_61883_4_incorrect_cip_sph, { "iec61883.4_incorrect_cip_sph", PI_PROTOCOL, PI_WARN,
1424 "Incorrect source packet header value, shall be 1 for IEC 61883-4", EXPFILL }},
1425 { &ei_1722_61883_6_incorrect_cip_fn, { "iec61883.6_incorrect_cip_fn", PI_PROTOCOL, PI_WARN,
1426 "Incorrect fraction number, shall be 0 for IEC 61883-6", EXPFILL }},
1427 { &ei_1722_61883_6_incorrect_cip_sph, { "iec61883.6_incorrect_cip_sph", PI_PROTOCOL, PI_WARN,
1428 "Incorrect source packet header value, shall be 0 for IEC 61883-6", EXPFILL }},
1429 { &ei_1722_61883_incorrect_cip_fdf, { "iec61883.6_incorrect_cip_fdf", PI_PROTOCOL, PI_WARN,
1430 "Incorrect frame dependent field value, shall be 0", EXPFILL }}
1433 expert_module_t* expert_1722_61883;
1435 /* Register the protocol name and description */
1436 proto_1722_61883 = proto_register_protocol("IEC 61883 Protocol", "IEC 61883", "iec61883");
1438 /* Required function calls to register the header fields and subtrees used */
1439 proto_register_field_array(proto_1722_61883, hf, array_length(hf));
1440 proto_register_subtree_array(ett, array_length(ett));
1441 expert_1722_61883 = expert_register_protocol(proto_1722_61883);
1442 expert_register_field_array(expert_1722_61883, ei, array_length(ei));
1444 avb1722_61883_handle = register_dissector("iec61883", dissect_1722_61883, proto_1722_61883);
1447 void proto_reg_handoff_1722_61883(void)
1449 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_61883, avb1722_61883_handle);
1451 mp2t_handle = find_dissector_add_dependency("mp2t", proto_1722_61883);
1454 /**************************************************************************************************/
1455 /* 1722 AAF dissector implementation */
1456 /* */
1457 /**************************************************************************************************/
1458 static int dissect_1722_aaf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1460 proto_item *ti;
1461 proto_tree *ti_aaf_tree;
1462 proto_tree *ti_channels_per_frame;
1463 proto_tree *ti_format;
1464 proto_tree *ti_audio_tree;
1465 proto_tree *ti_sample_tree;
1466 int offset = 1;
1467 unsigned datalen = 0;
1468 unsigned channels_per_frame = 0;
1469 unsigned bit_depth = 0;
1470 unsigned sample_width = 0;
1471 unsigned format = 0;
1472 unsigned i = 0;
1473 unsigned j = 0;
1474 static int * const fields[] = {
1475 &hf_1722_aaf_mrfield,
1476 &hf_1722_aaf_tvfield,
1477 NULL
1479 static int * const fields_pcm[] = {
1480 &hf_1722_aaf_sparse_timestamp,
1481 &hf_1722_aaf_evtfield,
1482 NULL
1485 ti = proto_tree_add_item(tree, proto_1722_aaf, tvb, 0, -1, ENC_NA);
1486 ti_aaf_tree = proto_item_add_subtree(ti, ett_1722_aaf);
1488 proto_tree_add_bitmask_list(ti_aaf_tree, tvb, offset, 1, fields, ENC_NA);
1489 offset += 1;
1490 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1491 offset += 1;
1492 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1493 offset += 1;
1494 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1495 offset += 8;
1496 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1497 offset += 4;
1499 ti_format = proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_format, tvb, offset, 1, ENC_BIG_ENDIAN, &format);
1500 offset += 1;
1501 switch (format)
1503 case IEEE_1722_AAF_FORMAT_USER:
1504 break;
1505 case IEEE_1722_AAF_FORMAT_FLOAT_32_BIT:
1506 sample_width = 32;
1507 break;
1508 case IEEE_1722_AAF_FORMAT_INT_32_BIT:
1509 sample_width = 32;
1510 break;
1511 case IEEE_1722_AAF_FORMAT_INT_24_BIT:
1512 sample_width = 24;
1513 break;
1514 case IEEE_1722_AAF_FORMAT_INT_16_BIT:
1515 sample_width = 16;
1516 break;
1517 case IEEE_1722_AAF_FORMAT_AES3_32_BIT:
1518 sample_width = 32;
1519 break;
1520 default:
1521 break;
1524 if (format < IEEE_1722_AAF_FORMAT_AES3_32_BIT)
1526 /* PCM Format */
1527 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_nominal_sample_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
1528 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);
1529 if (channels_per_frame == 0)
1531 expert_add_info(pinfo, ti_channels_per_frame, &ei_aaf_channels_per_frame);
1533 else
1535 offset += 2;
1536 ti = proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_bit_depth, tvb, offset, 1, ENC_BIG_ENDIAN, &bit_depth);
1537 if ((bit_depth == 0) || (bit_depth > sample_width))
1539 expert_add_info(pinfo, ti, &ei_aaf_incorrect_bit_depth);
1541 offset += 1;
1542 proto_tree_add_item_ret_uint(ti_aaf_tree, hf_1722_aaf_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1543 offset += 2;
1545 proto_tree_add_bitmask_list(ti_aaf_tree, tvb, offset, 1, fields_pcm, ENC_BIG_ENDIAN);
1546 offset += 1;
1548 proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_reserved, tvb, offset, 1, ENC_NA);
1549 offset += 1;
1551 /* Make the Audio sample tree. */
1552 ti = proto_tree_add_item(ti_aaf_tree, hf_1722_aaf_data, tvb, offset, datalen, ENC_NA);
1553 ti_audio_tree = proto_item_add_subtree(ti, ett_1722_aaf_audio);
1555 if (sample_width == 0)
1557 expert_add_info(pinfo, ti, &ei_aaf_sample_width);
1559 else
1561 /* Loop through all samples and add them to the audio tree. */
1562 for (j = 0; j < ((datalen * 8) / (channels_per_frame * sample_width)); j++)
1564 ti_sample_tree = proto_tree_add_subtree_format(ti_audio_tree, tvb, offset, 1,
1565 ett_1722_aaf_sample, NULL, "Sample Chunk %d", j);
1566 for (i = 0; i < channels_per_frame; i++)
1568 ti = proto_tree_add_item(ti_sample_tree, hf_1722_aaf_sample, tvb, offset, sample_width / 8, ENC_NA);
1569 proto_item_prepend_text(ti, "Channel: %d ", i);
1570 offset += (sample_width / 8);
1576 else if (format == IEEE_1722_AAF_FORMAT_AES3_32_BIT)
1578 expert_add_info(pinfo, ti_format, &ei_aaf_aes3_format);
1580 else
1582 expert_add_info(pinfo, ti_format, &ei_aaf_reserved_format);
1584 return tvb_captured_length(tvb);
1587 void proto_register_1722_aaf (void)
1589 static hf_register_info hf[] =
1591 { &hf_1722_aaf_mrfield,
1592 { "Media Clock Restart", "aaf.mrfield",
1593 FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1595 { &hf_1722_aaf_tvfield,
1596 { "Source Timestamp Valid", "aaf.tvfield",
1597 FT_BOOLEAN, 8, NULL, IEEE_1722_TV_MASK, NULL, HFILL }
1599 { &hf_1722_aaf_seqnum,
1600 { "Sequence Number", "aaf.seqnum",
1601 FT_UINT8, BASE_DEC, NULL, IEEE_1722_SEQ_NUM_MASK, NULL, HFILL }
1603 { &hf_1722_aaf_tufield,
1604 { "Timestamp Uncertain", "aaf.tufield",
1605 FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1607 { &hf_1722_aaf_stream_id,
1608 { "Stream ID", "aaf.stream_id",
1609 FT_UINT64, BASE_HEX, NULL, IEEE_1722_STREAM_ID_MASK, NULL, HFILL }
1611 { &hf_1722_aaf_avtp_timestamp,
1612 { "AVTP Timestamp", "aaf.avtp_timestamp",
1613 FT_UINT32, BASE_DEC, NULL, IEEE_1722_TIMESTAMP_MASK, NULL, HFILL }
1615 { &hf_1722_aaf_format,
1616 { "Format", "aaf.format_info",
1617 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(aaf_format_range_rvals), IEEE_1722_FORMAT_MASK, NULL, HFILL }
1619 { &hf_1722_aaf_nominal_sample_rate,
1620 { "Nominal Sample Rate", "aaf.nominal_sample_rate",
1621 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(aaf_nominal_sample_rate_range_rvals), IEEE_1722_NOM_SAMPLE_RATE_MASK, NULL, HFILL }
1623 { &hf_1722_aaf_channels_per_frame,
1624 { "Channels per Frame", "aaf.channels_per_frame",
1625 FT_UINT16, BASE_DEC, NULL, IEEE_1722_CHANNEL_PER_FRAME_MASK, NULL, HFILL }
1627 { &hf_1722_aaf_bit_depth,
1628 { "Bit Depth", "aaf.bit_depth",
1629 FT_UINT8, BASE_DEC, NULL, IEEE_1722_BIT_DEPTH_MASK, NULL, HFILL }
1631 { &hf_1722_aaf_stream_data_length,
1632 { "Stream Data Length", "aaf.stream_data_len",
1633 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), IEEE_1722_STREAM_DATA_LENGTH_MASK, NULL, HFILL }
1635 { &hf_1722_aaf_sparse_timestamp,
1636 { "Sparse Timestamp Mode", "aaf.sparse_timestamp",
1637 FT_UINT8, BASE_DEC, VALS(aaf_sparse_timestamp_vals), IEEE_1722_SP_MASK, NULL, HFILL }
1639 { &hf_1722_aaf_evtfield,
1640 { "EVT", "aaf.evtfield",
1641 FT_UINT8, BASE_HEX, NULL, IEEE_1722_EVT_MASK, NULL, HFILL }
1643 { &hf_1722_aaf_reserved,
1644 { "Reserved", "aaf.reserved",
1645 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1647 { &hf_1722_aaf_data,
1648 { "Audio Data", "aaf.data",
1649 FT_BYTES, BASE_NONE, NULL, IEEE_1722_DATA_MASK, NULL, HFILL }
1651 { &hf_1722_aaf_sample,
1652 { "Sample Data", "aaf.data.sample",
1653 FT_BYTES, BASE_NONE, NULL, IEEE_1722_SAMPLE_MASK, NULL, HFILL }
1657 static ei_register_info ei[] = {
1658 { &ei_aaf_sample_width, { "aaf.expert.sample_width_zero", PI_PROTOCOL, PI_WARN, "Sample_width of 0 can`t be dissected", EXPFILL }},
1659 { &ei_aaf_reserved_format, { "aaf.expert.reserved_format", PI_PROTOCOL, PI_WARN, "Incorrect format, can`t be dissected", EXPFILL }},
1660 { &ei_aaf_aes3_format, { "aaf.expert.aes3_format", PI_PROTOCOL, PI_WARN, "AES3 format is currently not supported", EXPFILL }},
1661 { &ei_aaf_channels_per_frame, { "aaf.expert.channels_per_frame_zero", PI_PROTOCOL, PI_WARN, "Channels_per_frame value shall not be 0", EXPFILL }},
1662 { &ei_aaf_incorrect_bit_depth, { "aaf.expert.incorrect_bit_depth", PI_PROTOCOL, PI_WARN, "Incorrect bit_depth value", EXPFILL }}
1665 static int *ett[] =
1667 &ett_1722_aaf,
1668 &ett_1722_aaf_audio,
1669 &ett_1722_aaf_sample,
1672 expert_module_t *expert_1722_aaf;
1674 /* Register the protocol name and description */
1675 proto_1722_aaf = proto_register_protocol("AVTP Audio Format", "AAF", "aaf");
1677 /* Required function calls to register the header fields and subtrees used */
1678 proto_register_field_array(proto_1722_aaf, hf, array_length(hf));
1679 proto_register_subtree_array(ett, array_length(ett));
1681 expert_1722_aaf = expert_register_protocol(proto_1722_aaf);
1682 expert_register_field_array(expert_1722_aaf, ei, array_length(ei));
1684 avb1722_aaf_handle = register_dissector("aaf", dissect_1722_aaf, proto_1722_aaf);
1687 void proto_reg_handoff_1722_aaf(void)
1689 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_AAF, avb1722_aaf_handle);
1692 /**************************************************************************************************/
1693 /* 1722 CVF dissector implementation */
1694 /* */
1695 /**************************************************************************************************/
1696 static int dissect_1722_cvf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1698 proto_item *ti;
1699 proto_tree *ti_cvf_tree;
1700 tvbuff_t *next_tvb;
1701 int offset = 1;
1702 unsigned reported_len;
1703 uint32_t datalen, format, format_subtype = 0;
1704 proto_tree *ti_format, *ti_datalen;
1706 static int * const fields[] = {
1707 &hf_1722_cvf_mrfield,
1708 &hf_1722_cvf_tvfield,
1709 NULL
1712 static int * const fields_cvf[] = {
1713 &hf_1722_cvf_marker_bit,
1714 &hf_1722_cvf_evtfield,
1715 NULL
1718 /* The PTV field is only defined for the H264 subtype,
1719 * reserved for others.
1721 static int * const fields_h264[] = {
1722 &hf_1722_cvf_h264_ptvfield,
1723 &hf_1722_cvf_marker_bit,
1724 &hf_1722_cvf_evtfield,
1725 NULL
1728 ti = proto_tree_add_item(tree, proto_1722_cvf, tvb, 0, 24, ENC_NA);
1729 ti_cvf_tree = proto_item_add_subtree(ti, ett_1722_cvf);
1731 proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields, ENC_NA);
1732 offset += 1;
1733 proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1734 offset += 1;
1735 proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_tufield, tvb, offset, 1, ENC_BIG_ENDIAN);
1736 offset += 1;
1737 proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1738 offset += 8;
1739 proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1740 offset += 4;
1741 ti_format = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_format, tvb, offset, 1, ENC_BIG_ENDIAN, &format);
1742 if (format == IEEE_1722_CVF_FORMAT_RFC) {
1743 offset += 1;
1744 ti_format = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_format_subtype, tvb, offset, 1, ENC_BIG_ENDIAN, &format_subtype);
1745 offset += 3;
1746 } else {
1747 expert_add_info(pinfo, ti_format, &ei_cvf_reserved_format);
1748 offset += 4;
1750 ti_datalen = proto_tree_add_item_ret_uint(ti_cvf_tree, hf_1722_cvf_stream_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1751 offset += 2;
1752 if (format == IEEE_1722_CVF_FORMAT_RFC &&
1753 format_subtype == IEEE_1722_CVF_FORMAT_SUBTYPE_H264) {
1754 proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_h264, ENC_BIG_ENDIAN);
1755 } else {
1756 proto_tree_add_bitmask_list(ti_cvf_tree, tvb, offset, 1, fields_cvf, ENC_BIG_ENDIAN);
1758 offset += 2;
1760 reported_len = tvb_reported_length_remaining(tvb, offset);
1761 if (reported_len < datalen) {
1762 expert_add_info(pinfo, ti_datalen, &ei_cvf_invalid_data_length);
1763 datalen = reported_len;
1765 next_tvb = tvb_new_subset_length(tvb, offset, datalen);
1767 if (format == IEEE_1722_CVF_FORMAT_RFC) {
1768 switch(format_subtype) {
1769 case IEEE_1722_CVF_FORMAT_SUBTYPE_MJPEG:
1770 call_dissector(jpeg_handle, next_tvb, pinfo, tree);
1771 break;
1773 case IEEE_1722_CVF_FORMAT_SUBTYPE_H264:
1774 proto_tree_add_item(ti_cvf_tree, hf_1722_cvf_h264_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1775 call_dissector(h264_handle, tvb_new_subset_remaining(next_tvb, 4), pinfo, tree);
1776 break;
1778 case IEEE_1722_CVF_FORMAT_SUBTYPE_JPEG2000:
1779 expert_add_info(pinfo, ti_format, &ei_cvf_jpeg2000_format);
1780 call_data_dissector(next_tvb, pinfo, tree);
1781 break;
1783 default:
1784 expert_add_info(pinfo, ti_format, &ei_cvf_reserved_format);
1785 call_data_dissector(next_tvb, pinfo, tree);
1786 break;
1788 } else {
1789 call_data_dissector(next_tvb, pinfo, tree);
1791 return offset + datalen;
1794 void proto_register_1722_cvf (void)
1796 static hf_register_info hf[] =
1798 { &hf_1722_cvf_mrfield,
1799 { "Media Clock Restart", "cvf.mrfield",
1800 FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1802 { &hf_1722_cvf_tvfield,
1803 { "Source Timestamp Valid", "cvf.tvfield",
1804 FT_BOOLEAN, 8, TFS(&tfs_valid_invalid), IEEE_1722_TV_MASK,
1805 "Indicates whether avtp_timestamp contains a valid value", HFILL }
1807 { &hf_1722_cvf_seqnum,
1808 { "Sequence Number", "cvf.seqnum",
1809 FT_UINT8, BASE_DEC, NULL, IEEE_1722_SEQ_NUM_MASK, NULL, HFILL }
1811 { &hf_1722_cvf_tufield,
1812 { "Timestamp Uncertain", "cvf.tufield",
1813 FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1815 { &hf_1722_cvf_stream_id,
1816 { "Stream ID", "cvf.stream_id",
1817 FT_UINT64, BASE_HEX, NULL, IEEE_1722_STREAM_ID_MASK, NULL, HFILL }
1819 { &hf_1722_cvf_avtp_timestamp,
1820 { "AVTP Timestamp", "cvf.avtp_timestamp",
1821 FT_UINT32, BASE_DEC, NULL, IEEE_1722_TIMESTAMP_MASK, NULL, HFILL }
1823 { &hf_1722_cvf_format,
1824 { "Format", "cvf.format",
1825 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_range_rvals), IEEE_1722_FORMAT_MASK, NULL, HFILL }
1827 { &hf_1722_cvf_format_subtype,
1828 { "CVF Format Subtype", "cvf.format_subtype",
1829 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(cvf_format_subtype_range_rvals), IEEE_1722_FORMAT_SUBTYPE_MASK, NULL, HFILL }
1831 { &hf_1722_cvf_stream_data_length,
1832 { "Stream Data Length", "cvf.stream_data_len",
1833 FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_byte_bytes), IEEE_1722_STREAM_DATA_LENGTH_MASK, NULL, HFILL }
1835 { &hf_1722_cvf_h264_ptvfield,
1836 { "H264 Payload Timestamp Valid", "cvf.h264_ptvfield",
1837 FT_BOOLEAN, 8, TFS(&tfs_valid_invalid), IEEE_1722_H264_PTV_MASK,
1838 "Indicates whether h264_timestamp contains a valid value", HFILL }
1840 { &hf_1722_cvf_marker_bit,
1841 { "Marker Bit", "cvf.marker_bit",
1842 FT_BOOLEAN, 8, TFS(&tfs_set_notset), IEEE_1722_MARKER_BIT_MASK, NULL, HFILL }
1844 { &hf_1722_cvf_evtfield,
1845 { "EVT", "cvf.evtfield",
1846 FT_UINT8, BASE_HEX, NULL, IEEE_1722_EVT_MASK, NULL, HFILL }
1848 { &hf_1722_cvf_h264_timestamp,
1849 { "H264 Timestamp", "cvf.h264_timestamp",
1850 FT_UINT32, BASE_DEC, NULL, IEEE_1722_CVF_H264_TIMESTAMP_MASK, NULL, HFILL }
1854 static ei_register_info ei[] = {
1855 { &ei_cvf_jpeg2000_format, { "cvf.expert.jpeg2000_video", PI_UNDECODED, PI_WARN, "JPEG2000 format is currently not supported", EXPFILL }},
1856 { &ei_cvf_reserved_format, { "cvf.expert.reserved_format", PI_PROTOCOL, PI_WARN, "Incorrect format, can't be dissected", EXPFILL }},
1857 { &ei_cvf_invalid_data_length, { "cvf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
1860 static int *ett[] =
1862 &ett_1722_cvf,
1865 expert_module_t *expert_1722_cvf;
1867 /* Register the protocol name and description */
1868 proto_1722_cvf = proto_register_protocol("AVTP Compressed Video Format", "CVF", "cvf");
1870 /* Required function calls to register the header fields and subtrees used */
1871 proto_register_field_array(proto_1722_cvf, hf, array_length(hf));
1872 proto_register_subtree_array(ett, array_length(ett));
1874 expert_1722_cvf = expert_register_protocol(proto_1722_cvf);
1875 expert_register_field_array(expert_1722_cvf, ei, array_length(ei));
1877 avb1722_cvf_handle = register_dissector("cvf", dissect_1722_cvf, proto_1722_cvf);
1880 void proto_reg_handoff_1722_cvf(void)
1882 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_CVF, avb1722_cvf_handle);
1884 jpeg_handle = find_dissector_add_dependency("jpeg", proto_1722_cvf);
1885 h264_handle = find_dissector_add_dependency("h264", proto_1722_cvf);
1888 /**************************************************************************************************/
1889 /* 1722 CRF dissector implementation */
1890 /* */
1891 /**************************************************************************************************/
1892 static int dissect_1722_crf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1894 proto_item *ti;
1895 proto_tree *ti_crf_tree;
1896 proto_tree *timestamp_tree;
1897 int offset = 1;
1898 unsigned datalen = 0;
1899 unsigned j = 0;
1900 static int * const fields[] = {
1901 &hf_1722_crf_mrfield,
1902 &hf_1722_crf_fsfield,
1903 &hf_1722_crf_tufield,
1904 NULL
1906 static int * const pull_frequency[] = {
1907 &hf_1722_crf_pull,
1908 &hf_1722_crf_base_frequency,
1909 NULL
1912 ti = proto_tree_add_item(tree, proto_1722_crf, tvb, 0, -1, ENC_NA);
1913 ti_crf_tree = proto_item_add_subtree(ti, ett_1722_crf);
1915 proto_tree_add_bitmask_list(ti_crf_tree, tvb, offset, 1, fields, ENC_NA);
1916 offset += 1;
1917 proto_tree_add_item(ti_crf_tree, hf_1722_crf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1918 offset += 1;
1919 proto_tree_add_item(ti_crf_tree, hf_1722_crf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1920 offset += 1;
1921 proto_tree_add_item(ti_crf_tree, hf_1722_crf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
1922 offset += 8;
1923 proto_tree_add_bitmask_list(ti_crf_tree, tvb, offset, 4, pull_frequency, ENC_NA);
1924 offset += 4;
1925 proto_tree_add_item_ret_uint(ti_crf_tree, hf_1722_crf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
1926 offset += 2;
1927 proto_tree_add_item(ti_crf_tree, hf_1722_crf_timestamp_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
1928 offset += 2;
1930 /* Make the Timestamp tree. */
1931 ti = proto_tree_add_item(ti_crf_tree, hf_1722_crf_timestamp_data, tvb, offset, datalen, ENC_NA);
1932 timestamp_tree = proto_item_add_subtree(ti, ett_1722_crf_timestamp);
1934 if (datalen%8)
1936 expert_add_info(pinfo, ti, &ei_crf_datalen);
1938 else
1940 /* Loop through all timestamps and add them to the timestamp tree. */
1941 for (j = 0; j < (datalen / IEEE_1722_CRF_TIMESTAMP_SIZE); j++)
1943 ti = proto_tree_add_item(timestamp_tree, hf_1722_crf_timestamp, tvb, offset, IEEE_1722_CRF_TIMESTAMP_SIZE, ENC_BIG_ENDIAN);
1944 proto_item_prepend_text(ti, "Timestamp %d ", j);
1945 offset += IEEE_1722_CRF_TIMESTAMP_SIZE;
1949 return tvb_captured_length(tvb);
1952 void proto_register_1722_crf(void)
1954 static hf_register_info hf[] =
1956 { &hf_1722_crf_mrfield,
1957 { "Media Clock Restart", "crf.mrfield",
1958 FT_BOOLEAN, 8, NULL, IEEE_1722_MR_MASK, NULL, HFILL }
1960 { &hf_1722_crf_fsfield,
1961 { "Frame Sync", "crf.fsfield",
1962 FT_BOOLEAN, 8, NULL, IEEE_1722_FS_MASK, NULL, HFILL }
1964 { &hf_1722_crf_tufield,
1965 { "Timestamp Uncertain", "crf.tufield",
1966 FT_BOOLEAN, 8, NULL, IEEE_1722_TU_MASK, NULL, HFILL }
1968 { &hf_1722_crf_seqnum,
1969 { "Sequence Number", "crf.seqnum",
1970 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1972 { &hf_1722_crf_type,
1973 { "Type", "crf.type",
1974 FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(crf_type_range_rvals), 0x0, NULL, HFILL }
1976 { &hf_1722_crf_stream_id,
1977 { "Stream ID", "crf.stream_id",
1978 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1980 { &hf_1722_crf_pull,
1981 { "Pull", "crf.pull",
1982 FT_UINT32, BASE_HEX | BASE_RANGE_STRING, RVALS(crf_pull_range_rvals), IEEE_1722_PULL_MASK, NULL, HFILL }
1984 { &hf_1722_crf_base_frequency,
1985 { "Base Frequency", "crf.base_frequency",
1986 FT_UINT32, BASE_DEC, NULL, IEEE_1722_BASE_FREQUENCY_MASK, NULL, HFILL }
1988 { &hf_1722_crf_data_length,
1989 { "Data Length", "crf.data_len",
1990 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
1992 { &hf_1722_crf_timestamp_interval,
1993 { "Timestamp Interval", "crf.timestamp_interval",
1994 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1996 { &hf_1722_crf_timestamp_data,
1997 { "Timestamp Data", "crf.timestamp_data",
1998 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
2000 { &hf_1722_crf_timestamp,
2001 { "Data", "crf.timestamp",
2002 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
2006 static ei_register_info ei[] = {
2007 { &ei_crf_datalen, { "crf.expert.crf_datalen", PI_PROTOCOL, PI_WARN, "The CRF data length must be multiple of 8", EXPFILL }}
2010 static int *ett[] =
2012 &ett_1722_crf,
2013 &ett_1722_crf_timestamp
2016 expert_module_t *expert_1722_crf;
2018 /* Register the protocol name and description */
2019 proto_1722_crf = proto_register_protocol("Clock Reference Format", "CRF", "crf");
2021 /* Required function calls to register the header fields and subtrees used */
2022 proto_register_field_array(proto_1722_crf, hf, array_length(hf));
2023 proto_register_subtree_array(ett, array_length(ett));
2024 expert_1722_crf = expert_register_protocol(proto_1722_crf);
2025 expert_register_field_array(expert_1722_crf, ei, array_length(ei));
2027 avb1722_crf_handle = register_dissector("crf", dissect_1722_crf, proto_1722_crf);
2030 void proto_reg_handoff_1722_crf(void)
2032 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_CRF, avb1722_crf_handle);
2035 /**************************************************************************************************/
2036 /* 1722 NTSCF dissector implementation */
2037 /* */
2038 /**************************************************************************************************/
2039 static int dissect_1722_ntscf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2041 proto_item *ti_ntscf;
2042 proto_item *ti_data_length;
2043 proto_tree *tree_ntscf;
2044 int offset = 1;
2045 uint32_t datalen = 0;
2046 unsigned captured_length = tvb_captured_length(tvb);
2047 int captured_payload_length;
2049 static int * const fields[] = {
2050 &hf_1722_ntscf_rfield,
2051 NULL,
2054 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NTSCF");
2055 col_set_str(pinfo->cinfo, COL_INFO, "AVTP Non-Time-Synchronous Control Format");
2057 ti_ntscf = proto_tree_add_item(tree, proto_1722_ntscf, tvb, 0, -1, ENC_NA);
2058 tree_ntscf = proto_item_add_subtree(ti_ntscf, ett_1722_ntscf);
2060 if (captured_length < IEEE_1722_NTSCF_HEADER_SIZE) {
2061 expert_add_info(pinfo, ti_ntscf, &ei_1722_ntscf_no_space_for_header);
2062 return captured_length;
2065 proto_tree_add_bitmask_list(tree_ntscf, tvb, offset, 2, fields, ENC_BIG_ENDIAN);
2066 ti_data_length = proto_tree_add_item_ret_uint(tree_ntscf, hf_1722_ntscf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
2067 offset += 2;
2068 proto_tree_add_item(tree_ntscf, hf_1722_ntscf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
2069 offset += 1;
2070 proto_tree_add_item(tree_ntscf, hf_1722_ntscf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
2071 offset += 8;
2073 captured_payload_length = tvb_captured_length_remaining(tvb, offset);
2074 if (captured_payload_length < 0 || (int)datalen > captured_payload_length) {
2075 expert_add_info(pinfo, ti_data_length, &ei_1722_ntscf_invalid_data_length);
2078 if ((int)datalen > captured_payload_length) {
2079 datalen = captured_payload_length > 0
2080 ? captured_payload_length
2081 : 0;
2084 while(datalen > 0) {
2085 unsigned processed_bytes;
2086 tvbuff_t* next_tvb;
2088 next_tvb = tvb_new_subset_length(tvb, offset, datalen);
2089 if (call_dissector(avb1722_acf_handle, next_tvb, pinfo, tree) <= 0) {
2090 break;
2093 processed_bytes = tvb_reported_length(next_tvb);
2095 offset += processed_bytes;
2096 if (processed_bytes < datalen) {
2097 datalen -= processed_bytes;
2098 } else {
2099 datalen = 0;
2103 set_actual_length(tvb, offset);
2104 proto_item_set_len(ti_ntscf, offset);
2106 return tvb_captured_length(tvb);
2109 void proto_register_1722_ntscf(void)
2111 static hf_register_info hf[] =
2113 { &hf_1722_ntscf_rfield,
2114 { "Reserved bits", "ntscf.rfield",
2115 FT_UINT16, BASE_HEX, NULL, IEEE_1722_NTSCF_R_MASK, NULL, HFILL }
2117 { &hf_1722_ntscf_data_length,
2118 { "Data Length", "ntscf.data_len",
2119 FT_UINT16, BASE_DEC, NULL, IEEE_1722_NTSCF_DATA_LENGTH_MASK, NULL, HFILL }
2121 { &hf_1722_ntscf_seqnum,
2122 { "Sequence Number", "ntscf.seqnum",
2123 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
2125 { &hf_1722_ntscf_stream_id,
2126 { "Stream ID", "ntscf.stream_id",
2127 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
2131 static int *ett[] =
2133 &ett_1722_ntscf
2136 static ei_register_info ei[] = {
2137 { &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}},
2138 { &ei_1722_ntscf_invalid_data_length, { "ntscf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
2141 expert_module_t *expert_1722_ntscf;
2143 /* Register the protocol name and description */
2144 proto_1722_ntscf = proto_register_protocol("Non-Time-Synchronous Control Format", "NTSCF", "ntscf");
2146 /* Required function calls to register the header fields and subtrees used */
2147 proto_register_field_array(proto_1722_ntscf, hf, array_length(hf));
2148 proto_register_subtree_array(ett, array_length(ett));
2150 expert_1722_ntscf = expert_register_protocol(proto_1722_ntscf);
2151 expert_register_field_array(expert_1722_ntscf, ei, array_length(ei));
2153 avb1722_ntscf_handle = register_dissector("ntscf", dissect_1722_ntscf, proto_1722_ntscf);
2156 void proto_reg_handoff_1722_ntscf(void)
2158 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_NTSCF, avb1722_ntscf_handle);
2162 /**************************************************************************************************/
2163 /* 1722 TSCF dissector implementation */
2164 /* */
2165 /**************************************************************************************************/
2166 static int dissect_1722_tscf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2168 proto_item *ti;
2169 proto_item *ti_tscf;
2170 proto_tree *tree_tscf;
2171 proto_tree *tree_flags;
2172 proto_tree *tree_tu;
2173 int offset = 1;
2174 uint32_t mr;
2175 uint32_t tv;
2176 uint32_t tu;
2177 uint32_t datalen = 0;
2178 unsigned captured_length = tvb_captured_length(tvb);
2179 int captured_payload_length;
2181 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TSCF");
2182 col_set_str(pinfo->cinfo, COL_INFO, "AVTP Time-Synchronous Control Format");
2184 ti_tscf = proto_tree_add_item(tree, proto_1722_tscf, tvb, 0, -1, ENC_NA);
2185 tree_tscf = proto_item_add_subtree(ti_tscf, ett_1722_tscf);
2187 if (captured_length < IEEE_1722_TSCF_HEADER_SIZE) {
2188 expert_add_info(pinfo, ti_tscf, &ei_1722_tscf_no_space_for_header);
2189 return captured_length;
2192 tree_flags = proto_tree_add_subtree(tree_tscf, tvb, offset, 1, ett_1722_tscf_flags, &ti, "Flags");
2193 proto_tree_add_item_ret_uint(tree_flags, hf_1722_tscf_mr, tvb, offset, 1, ENC_BIG_ENDIAN, &mr);
2194 proto_tree_add_item(tree_flags, hf_1722_tscf_rsv1, tvb, offset, 1, ENC_BIG_ENDIAN);
2195 proto_tree_add_item_ret_uint(tree_flags, hf_1722_tscf_tv, tvb, offset, 1, ENC_BIG_ENDIAN, &tv);
2196 proto_item_append_text(ti, ": mr=%d, tv=%d", mr, tv);
2197 offset += 1;
2199 proto_tree_add_item(tree_tscf, hf_1722_tscf_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
2200 offset += 1;
2202 tree_tu = proto_tree_add_subtree(tree_tscf, tvb, offset, 1, ett_1722_tscf_tu, &ti, "Timestamp Uncertain");
2203 proto_tree_add_item(tree_tu, hf_1722_tscf_rsv2, tvb, offset, 1, ENC_BIG_ENDIAN);
2204 proto_tree_add_item_ret_uint(tree_tu, hf_1722_tscf_tu, tvb, offset, 1, ENC_BIG_ENDIAN, &tu);
2205 proto_item_append_text(ti, ": %d", tu);
2206 offset += 1;
2208 proto_tree_add_item(tree_tscf, hf_1722_tscf_stream_id, tvb, offset, 8, ENC_BIG_ENDIAN);
2209 offset += 8;
2211 proto_tree_add_item(tree_tscf, hf_1722_tscf_avtp_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
2212 offset += 4;
2214 proto_tree_add_item(tree_tscf, hf_1722_tscf_rsv3, tvb, offset, 4, ENC_BIG_ENDIAN);
2215 offset += 4;
2217 ti = proto_tree_add_item_ret_uint(tree_tscf, hf_1722_tscf_data_length, tvb, offset, 2, ENC_BIG_ENDIAN, &datalen);
2218 captured_payload_length = tvb_captured_length_remaining(tvb, offset);
2219 if (captured_payload_length < 0 || (int)datalen > captured_payload_length) {
2220 expert_add_info(pinfo, ti, &ei_1722_tscf_invalid_data_length);
2222 offset += 2;
2224 proto_tree_add_item(tree_tscf, hf_1722_tscf_rsv4, tvb, offset, 2, ENC_BIG_ENDIAN);
2225 offset += 2;
2227 if ((int)datalen > captured_payload_length) {
2228 datalen = captured_payload_length > 0
2229 ? captured_payload_length
2230 : 0;
2233 while(datalen > 0) {
2234 unsigned processed_bytes;
2235 tvbuff_t* next_tvb = tvb_new_subset_length(tvb, offset, datalen);
2236 if (call_dissector(avb1722_acf_handle, next_tvb, pinfo, tree) <= 0) {
2237 break;
2239 processed_bytes = tvb_reported_length(next_tvb);
2241 offset += processed_bytes;
2242 if (processed_bytes < datalen) {
2243 datalen -= processed_bytes;
2244 } else {
2245 datalen = 0;
2249 set_actual_length(tvb, offset);
2250 proto_item_set_len(ti_tscf, offset);
2252 return captured_length;
2255 void proto_register_1722_tscf(void)
2257 static hf_register_info hf[] =
2259 { &hf_1722_tscf_mr,
2260 { "Media Clock Restart", "tscf.flags.mr",
2261 FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_MR_MASK, NULL, HFILL }
2264 { &hf_1722_tscf_rsv1,
2265 { "Reserved bits", "tscf.flags.rsv1",
2266 FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_RSV1_MASK, NULL, HFILL }
2269 { &hf_1722_tscf_tv,
2270 { "Avtp Timestamp Valid", "tscf.flags.tv",
2271 FT_UINT8, BASE_HEX, NULL, IEEE_1722_TSCF_TV_MASK, NULL, HFILL }
2274 { &hf_1722_tscf_seqnum,
2275 { "Sequence Number", "tscf.seqnum",
2276 FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_SEQNUM_MASK, NULL, HFILL }
2279 { &hf_1722_tscf_rsv2,
2280 { "Reserved Bits", "tscf.rsv2",
2281 FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_RSV2_MASK, NULL, HFILL }
2284 { &hf_1722_tscf_tu,
2285 { "Timestamp Uncertain", "tscf.flags.tu",
2286 FT_UINT8, BASE_DEC, NULL, IEEE_1722_TSCF_TU_MASK, NULL, HFILL }
2289 { &hf_1722_tscf_stream_id,
2290 { "Stream ID", "tscf.stream_id",
2291 FT_UINT64, BASE_HEX, NULL, IEEE_1722_TSCF_STREAM_ID_MASK, NULL, HFILL }
2294 { &hf_1722_tscf_avtp_timestamp,
2295 { "AVTP Timestamp", "tscf.avtp_timestamp",
2296 FT_UINT32, BASE_HEX, NULL, IEEE_1722_TSCF_AVTP_TIMESTAMP_MASK, NULL, HFILL }
2299 { &hf_1722_tscf_rsv3,
2300 { "Reserved Bits", "tscf.rsv3",
2301 FT_UINT32, BASE_HEX, NULL, IEEE_1722_TSCF_RSV3_MASK, NULL, HFILL }
2304 { &hf_1722_tscf_data_length,
2305 { "Data Length", "tscf.data_len",
2306 FT_UINT16, BASE_DEC, NULL, IEEE_1722_TSCF_DATA_LENGTH_MASK, NULL, HFILL }
2309 { &hf_1722_tscf_rsv4,
2310 { "Reserved Bits", "tscf.rsv4",
2311 FT_UINT16, BASE_HEX, NULL, IEEE_1722_TSCF_RSV4_MASK, NULL, HFILL }
2315 static int *ett[] =
2317 &ett_1722_tscf,
2318 &ett_1722_tscf_flags,
2319 &ett_1722_tscf_tu,
2322 static ei_register_info ei[] = {
2323 { &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}},
2324 { &ei_1722_tscf_invalid_data_length, { "tscf.expert.data_len", PI_PROTOCOL, PI_WARN, "data_length is too large or frame is incomplete", EXPFILL }}
2327 expert_module_t *expert_1722_tscf;
2329 /* Register the protocol name and description */
2330 proto_1722_tscf = proto_register_protocol("Time-Synchronous Control Format", "TSCF", "tscf");
2332 /* Required function calls to register the header fields and subtrees used */
2333 proto_register_field_array(proto_1722_tscf, hf, array_length(hf));
2334 proto_register_subtree_array(ett, array_length(ett));
2336 expert_1722_tscf = expert_register_protocol(proto_1722_tscf);
2337 expert_register_field_array(expert_1722_tscf, ei, array_length(ei));
2339 avb1722_tscf_handle = register_dissector("tscf", dissect_1722_tscf, proto_1722_tscf);
2342 void proto_reg_handoff_1722_tscf(void)
2344 dissector_add_uint("ieee1722.subtype", IEEE_1722_SUBTYPE_TSCF, avb1722_tscf_handle);
2347 /**************************************************************************************************/
2348 /* AVTP Control Format (ACF) Message dissector implementation */
2349 /* */
2350 /**************************************************************************************************/
2351 static int dissect_1722_acf (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2353 proto_item *ti;
2354 proto_item *ti_acf;
2355 proto_item *ti_header;
2356 proto_tree *tree_acf;
2357 proto_tree *tree_header;
2358 uint32_t msg_type;
2359 uint32_t msg_length;
2360 uint32_t payload_length;
2361 unsigned captured_length = tvb_captured_length(tvb);
2362 const char *msg_type_str;
2363 tvbuff_t *next_tvb;
2365 if (captured_length < IEEE_1722_ACF_HEADER_SIZE) {
2366 return captured_length;
2369 ti_acf = proto_tree_add_item(tree, proto_1722_acf, tvb, 0, -1, ENC_NA);
2370 tree_acf = proto_item_add_subtree(ti_acf, ett_1722_acf);
2372 tree_header = proto_tree_add_subtree(tree_acf, tvb, 0, 2, ett_1722_acf_header, &ti_header, "ACF Header");
2373 proto_tree_add_item_ret_uint(tree_header, hf_1722_acf_msg_type, tvb, 0, 2, ENC_BIG_ENDIAN, &msg_type);
2374 ti = proto_tree_add_item_ret_uint(tree_header, hf_1722_acf_msg_length, tvb, 0, 2, ENC_BIG_ENDIAN, &msg_length);
2375 msg_length = msg_length * 4; /* msg_length is stored as number of quadlets */
2377 if (msg_length < IEEE_1722_ACF_HEADER_SIZE) {
2378 expert_add_info(pinfo, ti, &ei_1722_acf_invalid_msg_length);
2379 return captured_length;
2382 if (captured_length < msg_length) {
2383 expert_add_info_format(pinfo, ti, &ei_1722_acf_message_is_cropped,
2384 "expected: %u bytes, available: %u bytes",
2385 msg_length, tvb_captured_length(tvb));
2386 return captured_length;
2389 set_actual_length(tvb, msg_length);
2390 proto_item_set_len(ti_acf, msg_length);
2391 msg_type_str = rval_to_str_const(msg_type, acf_msg_type_range_rvals, "Unknown");
2392 proto_item_append_text(ti_header, ": %s (0x%02X), %d bytes with header",
2393 msg_type_str, msg_type, msg_length);
2394 proto_item_append_text(ti_acf, ": %s (0x%02X)", msg_type_str, msg_type);
2395 payload_length = msg_length - IEEE_1722_ACF_HEADER_SIZE;
2397 /* call any registered message dissectors */
2398 next_tvb = tvb_new_subset_length(tvb, IEEE_1722_ACF_HEADER_SIZE, payload_length);
2400 if (!dissector_try_uint(avb1722_acf_dissector_table, msg_type, next_tvb, pinfo, tree_acf)) {
2401 call_data_dissector(next_tvb, pinfo, tree_acf);
2404 return captured_length;
2407 void proto_register_1722_acf(void)
2409 static hf_register_info hf[] = {
2410 { &hf_1722_acf_msg_type,
2411 { "Message Type", "acf.msg_type",
2412 FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(acf_msg_type_range_rvals), IEEE_1722_ACF_MSG_TYPE_MASK, NULL, HFILL }
2414 { &hf_1722_acf_msg_length,
2415 { "Message Length (Quadlets)", "acf.msg_length",
2416 FT_UINT16, BASE_DEC, NULL, IEEE_1722_ACF_MSG_LENGTH_MASK, NULL, HFILL }
2420 static int *ett[] =
2422 &ett_1722_acf,
2423 &ett_1722_acf_header,
2427 static ei_register_info ei[] = {
2428 { &ei_1722_acf_invalid_msg_length, { "acf.expert.msg_length", PI_PROTOCOL, PI_WARN, "msg_length shall be at least 1 quadlet", EXPFILL }},
2429 { &ei_1722_acf_message_is_cropped, { "acf.expert.msg_cropped", PI_PROTOCOL, PI_WARN, "Message is cropped or msg_length is invalid", EXPFILL }},
2432 expert_module_t *expert_1722_acf;
2434 /* Register the protocol name and description */
2435 proto_1722_acf = proto_register_protocol("ACF Message", "ACF", "acf");
2436 avb1722_acf_handle = register_dissector("acf", dissect_1722_acf, proto_1722_acf);
2438 /* Required function calls to register the header fields and subtrees used */
2439 proto_register_field_array(proto_1722_acf, hf, array_length(hf));
2440 proto_register_subtree_array(ett, array_length(ett));
2442 /* Sub-dissector for ACF messages */
2443 avb1722_acf_dissector_table = register_dissector_table("acf.msg_type",
2444 "IEEE1722 AVTP Control Message Type", proto_1722_acf,
2445 FT_UINT8, BASE_HEX);
2447 expert_1722_acf = expert_register_protocol(proto_1722_acf);
2448 expert_register_field_array(expert_1722_acf, ei, array_length(ei));
2451 void proto_reg_handoff_1722_acf(void)
2453 register_depend_dissector("ntscf", "acf");
2454 register_depend_dissector("tscf", "acf");
2457 /**************************************************************************************************/
2458 /* ACF CAN Message dissector implementation */
2459 /* */
2460 /**************************************************************************************************/
2461 static void describe_can_message(proto_item* dst, unsigned bus_id, uint32_t can_id, uint8_t flags)
2463 /* Add text describing the CAN message to the parent item.
2464 * Example: ": bus_id=2, id=0x100, rtr=1, brs=1, esi=1" */
2465 const char* format_str = (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0
2466 ? ": bus_id=%u, id=0x%08X"
2467 : ": bus_id=%u, id=0x%03X";
2469 proto_item_append_text (dst, format_str, bus_id, can_id);
2472 static void describe_can_flags(proto_item* dst, uint8_t pad, uint8_t flags)
2474 proto_item_append_text(dst, ": pad=%u, mtv=%d, rtr=%d, eff=%d, brs=%d, fdf=%d, esi=%d",
2475 pad,
2476 (flags & IEEE_1722_ACF_CAN_MTV_MASK) != 0,
2477 (flags & IEEE_1722_ACF_CAN_RTR_MASK) != 0,
2478 (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0,
2479 (flags & IEEE_1722_ACF_CAN_BRS_MASK) != 0,
2480 (flags & IEEE_1722_ACF_CAN_FDF_MASK) != 0,
2481 (flags & IEEE_1722_ACF_CAN_ESI_MASK) != 0
2485 static int is_valid_can_payload_length(int len)
2487 return len >= 0 && len <= 8;
2490 static int is_valid_canfd_payload_length(int len)
2492 return is_valid_can_payload_length(len) ||
2493 len == 12 ||
2494 len == 16 ||
2495 len == 20 ||
2496 len == 24 ||
2497 len == 32 ||
2498 len == 48 ||
2499 len == 64;
2502 static int dissect_1722_acf_can_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_, const bool is_brief)
2504 acf_can_t parsed;
2505 uint32_t pad_length;
2506 int payload_length;
2507 uint8_t flags;
2508 proto_item *ti;
2510 proto_item *ti_acf_can;
2511 proto_tree *tree_acf_can;
2512 proto_tree *tree_acf_can_flags;
2513 proto_tree *tree_acf_can_bus_id;
2515 proto_item *ti_can;
2516 proto_tree *tree_can;
2517 proto_tree *tree_can_id;
2518 int can_protocol;
2519 int * const *can_flags;
2520 struct can_info can_info;
2522 tvbuff_t* next_tvb;
2523 int offset = 0;
2524 unsigned captured_length = tvb_captured_length(tvb);
2525 unsigned header_size = is_brief
2526 ? IEEE_1722_ACF_CAN_BRIEF_HEADER_SIZE
2527 : IEEE_1722_ACF_CAN_HEADER_SIZE;
2530 static int * const fields[] = {
2531 &hf_1722_can_mtvfield,
2532 &hf_1722_can_fdffield,
2533 NULL,
2536 static int * const can_std_flags[] = {
2537 &hf_1722_can_rtrfield,
2538 &hf_1722_can_efffield,
2539 NULL
2542 static int * const can_fd_flags[] = {
2543 &hf_1722_can_efffield,
2544 &hf_1722_can_brsfield,
2545 &hf_1722_can_esifield,
2546 NULL
2549 memset(&parsed, 0, sizeof(parsed));
2551 /* create tree for ACF-CAN-specific fields */
2552 ti_acf_can = proto_tree_add_item(tree, proto_1722_acf_can, tvb, offset, -1, ENC_NA);
2553 tree_acf_can = proto_item_add_subtree(ti_acf_can, ett_1722_can);
2554 if (is_brief) {
2555 proto_item_append_text(ti_acf_can, " Brief");
2558 /* parse flags */
2559 flags = tvb_get_uint8(tvb, offset);
2560 parsed.is_fd = (flags & IEEE_1722_ACF_CAN_FDF_MASK) != 0;
2561 parsed.is_xtd = (flags & IEEE_1722_ACF_CAN_EFF_MASK) != 0;
2562 parsed.is_rtr = (flags & IEEE_1722_ACF_CAN_RTR_MASK) != 0;
2563 parsed.is_brs = (flags & IEEE_1722_ACF_CAN_BRS_MASK) != 0;
2564 parsed.is_esi = (flags & IEEE_1722_ACF_CAN_ESI_MASK) != 0;
2566 /* create the tree for CAN-specific fields */
2567 can_protocol = parsed.is_fd ? proto_canfd : proto_can;
2568 can_flags = parsed.is_fd ? can_fd_flags : can_std_flags;
2569 ti_can = proto_tree_add_item(tree, can_protocol, tvb, offset, -1, ENC_NA);
2570 tree_can = proto_item_add_subtree(ti_can, ett_can);
2572 if (captured_length < header_size) {
2573 expert_add_info(pinfo, ti_acf_can, &ei_1722_can_header_cropped);
2574 return captured_length;
2577 /* Add flags subtree to ACF_CAN message */
2578 ti = proto_tree_add_item(tree_acf_can, hf_1722_can_flags, tvb, offset, 1, ENC_NA);
2579 tree_acf_can_flags = proto_item_add_subtree(ti, ett_1722_can_flags);
2581 proto_tree_add_item_ret_uint(tree_acf_can_flags, hf_1722_can_pad, tvb, offset, 1, ENC_BIG_ENDIAN, &pad_length);
2582 proto_tree_add_bitmask_list(tree_acf_can_flags, tvb, offset, 1, fields, ENC_BIG_ENDIAN);
2583 describe_can_flags(ti, pad_length, flags);
2585 /* Add flags to CAN message */
2586 proto_tree_add_bitmask_list(tree_can, tvb, offset, 1, can_flags, ENC_BIG_ENDIAN);
2587 offset += 1;
2589 /* Add bus id subtree to ACF_CAN message */
2590 tree_acf_can_bus_id = proto_tree_add_subtree(tree_acf_can, tvb, offset, 1, ett_1722_can_bus_id, &ti, "Bus Identifier");
2591 proto_tree_add_item(tree_acf_can_bus_id, hf_1722_can_rsv1, tvb, offset, 1, ENC_BIG_ENDIAN);
2592 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);
2593 proto_item_append_text(ti, ": %u", parsed.bus_id);
2594 offset += 1;
2596 /* Add message_timestamp to ACF_CAN if present */
2597 if (!is_brief) {
2598 proto_tree_add_item(tree_acf_can, hf_1722_can_message_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
2599 offset += 8;
2602 /* Add message id subtree to CAN message */
2603 tree_can_id = proto_tree_add_subtree(tree_can, tvb, offset, 4, ett_1722_can_msg_id, &ti, "Message Identifier");
2604 proto_tree_add_item(tree_can_id, hf_1722_can_rsv2, tvb, offset, 4, ENC_BIG_ENDIAN);
2605 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);
2606 proto_item_append_text(ti, parsed.is_xtd ? ": 0x%08X" : ": 0x%03X", parsed.id);
2607 if (!parsed.is_xtd && (parsed.id & ~IEEE_1722_ACF_CAN_11BIT_ID_MASK) != 0) {
2608 expert_add_info(pinfo, ti_id, &ei_1722_can_invalid_message_id);
2610 offset += 4;
2612 /* Add text description to tree items and info column*/
2613 describe_can_message(ti_acf_can, parsed.bus_id, parsed.id, flags);
2614 describe_can_message(proto_tree_get_parent(tree), parsed.bus_id, parsed.id, flags);
2616 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACF-CAN");
2617 col_clear(pinfo->cinfo, COL_INFO);
2618 col_add_fstr(pinfo->cinfo, COL_INFO, "ACF-CAN(%u): 0x%08x ", parsed.bus_id, parsed.id);
2620 payload_length = tvb_reported_length_remaining(tvb, offset) - pad_length;
2621 if (payload_length < 0) {
2622 payload_length = 0;
2624 parsed.datalen = (unsigned)payload_length;
2625 proto_tree_add_uint(tree_acf_can, hf_1722_can_len, tvb, offset, 1, parsed.datalen);
2627 if (payload_length > 0)
2628 col_append_str(pinfo->cinfo, COL_INFO, tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, payload_length, ' '));
2630 if (parsed.is_fd && !is_valid_canfd_payload_length(payload_length))
2632 expert_add_info(pinfo, ti_acf_can, &ei_1722_canfd_invalid_payload_length);
2634 else if (!parsed.is_fd && !is_valid_can_payload_length(payload_length))
2636 expert_add_info(pinfo, ti_acf_can, &ei_1722_can_invalid_payload_length);
2639 /* Add payload to parent tree */
2642 * CAN sub-dissectors expect several flags to be merged into ID that is passed
2643 * to dissector_try_payload_with_data. Add them
2645 can_info.id = parsed.id;
2646 if (parsed.is_xtd)
2648 can_info.id |= CAN_EFF_FLAG;
2651 if (parsed.is_rtr)
2653 can_info.id |= CAN_RTR_FLAG;
2656 can_info.len = (uint32_t)parsed.datalen;
2657 can_info.fd = parsed.is_fd ? CAN_TYPE_CAN_FD : CAN_TYPE_CAN_CLASSIC;
2659 /* for practical reasons a remapping might be needed in the future */
2660 can_info.bus_id = (uint16_t)parsed.bus_id;
2662 next_tvb = tvb_new_subset_length(tvb, offset, parsed.datalen);
2664 if (!socketcan_call_subdissectors(next_tvb, pinfo, tree, &can_info, can_heuristic_first)) {
2665 call_data_dissector(next_tvb, pinfo, tree);
2668 /* Add padding bytes to ACF-CAN tree if any */
2669 if (pad_length > 0 && tvb_reported_length_remaining(tvb, offset) >= (int)pad_length)
2671 proto_tree_add_item(tree_acf_can, hf_1722_can_padding, tvb, offset, pad_length, ENC_NA);
2674 return captured_length;
2677 static int dissect_1722_acf_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2679 return dissect_1722_acf_can_common(tvb, pinfo, tree, data, false);
2682 static int dissect_1722_acf_can_brief(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2684 return dissect_1722_acf_can_common(tvb, pinfo, tree, data, true);
2687 void proto_register_1722_acf_can(void)
2689 static hf_register_info hf[] = {
2690 /* ACF-CAN, ACF-CAN-BRIEF and CAN fields */
2691 { &hf_1722_can_flags,
2692 { "Flags", "acf-can.flags",
2693 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
2695 { &hf_1722_can_pad,
2696 { "Padding Length", "acf-can.flags.pad",
2697 FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_CAN_PAD_MASK, NULL, HFILL }
2699 { &hf_1722_can_len,
2700 { "Frame-Length", "can.len",
2701 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
2703 { &hf_1722_can_mtvfield,
2704 { "Message Timestamp Valid", "acf-can.flags.mtv",
2705 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_MTV_MASK, NULL, HFILL }
2707 { &hf_1722_can_fdffield,
2708 { "CAN Flexible Data-rate Format", "acf-can.flags.fdf",
2709 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_FDF_MASK, NULL, HFILL }
2711 { &hf_1722_can_rtrfield,
2712 { "Remote Transmission Request Flag", "can.flags.rtr",
2713 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_RTR_MASK, NULL, HFILL }
2715 { &hf_1722_can_efffield,
2716 { "Extended Flag", "can.flags.xtd",
2717 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_EFF_MASK, NULL, HFILL }
2719 { &hf_1722_can_brsfield,
2720 { "Bit Rate Setting", "canfd.flags.brs",
2721 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_BRS_MASK, NULL, HFILL }
2723 { &hf_1722_can_esifield,
2724 { "Error Message Flag", "canfd.flags.esi",
2725 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_CAN_ESI_MASK, NULL, HFILL }
2727 { &hf_1722_can_rsv1,
2728 { "Reserved Bits", "acf-can.rsv1",
2729 FT_UINT8, BASE_HEX, NULL, IEEE_1722_ACF_CAN_RSV1_MASK, NULL, HFILL }
2731 { &hf_1722_can_bus_id,
2732 { "CAN Bus Identifier", "acf-can.bus_id",
2733 FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_CAN_BUS_ID_MASK, NULL, HFILL }
2735 { &hf_1722_can_message_timestamp,
2736 { "Message Timestamp", "acf-can.message_timestamp",
2737 FT_UINT64, BASE_HEX, NULL, IEEE_1722_ACF_CAN_MSG_TIMESTAMP_MASK, NULL, HFILL }
2739 { &hf_1722_can_rsv2,
2740 { "Reserved", "can.reserved",
2741 FT_UINT32, BASE_HEX, NULL, IEEE_1722_ACF_CAN_RSV2_MASK, NULL, HFILL }
2743 { &hf_1722_can_identifier,
2744 { "CAN Message Identifier", "can.id",
2745 FT_UINT32, BASE_HEX, NULL, IEEE_1722_ACF_CAN_IDENTIFIER_MASK, NULL, HFILL }
2747 { &hf_1722_can_padding,
2748 { "Padding", "can.padding",
2749 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
2753 static int *ett[] =
2755 &ett_1722_can,
2756 &ett_1722_can_flags,
2757 &ett_1722_can_bus_id,
2758 &ett_1722_can_msg_id,
2759 &ett_can
2762 static ei_register_info ei[] = {
2763 { &ei_1722_can_header_cropped, { "acf-can.expert.header_cropped", PI_PROTOCOL, PI_WARN,
2764 "Message is cropped, no space for header", EXPFILL }},
2765 { &ei_1722_can_invalid_message_id, { "acf-can.expert.incorrect_can_id", PI_PROTOCOL, PI_WARN,
2766 "Incorrect msg id, shall be 0..1FF when EFF flag is not set", EXPFILL }},
2767 { &ei_1722_can_invalid_payload_length, { "acf-can.expert.incorrect_datalen", PI_PROTOCOL, PI_WARN,
2768 "Incorrect payload length, shall be [0..8] when FDF flag is not set", EXPFILL }},
2769 { &ei_1722_canfd_invalid_payload_length,{ "acf-can.expert.incorrect_fd_datalen", PI_PROTOCOL, PI_WARN,
2770 "Incorrect FD payload length, shall be [0..8, 12, 16, 20, 32, 48, 64] when FDF flag is set", EXPFILL }},
2773 module_t* module_acf_can;
2774 expert_module_t* expert_1722_acf_can;
2776 /* Register the protocol name and description */
2777 proto_1722_acf_can = proto_register_protocol("ACF CAN", "CAN over AVTP", "acf-can");
2778 avb1722_can_handle = register_dissector("acf-can", dissect_1722_acf_can, proto_1722_acf_can);
2779 avb1722_can_brief_handle = register_dissector("acf-can-brief", dissect_1722_acf_can_brief, proto_1722_acf_can);
2781 /* Required function calls to register the header fields and subtrees used */
2782 proto_register_field_array(proto_1722_acf_can, hf, array_length(hf));
2783 proto_register_subtree_array(ett, array_length(ett));
2785 expert_1722_acf_can = expert_register_protocol(proto_1722_acf_can);
2786 expert_register_field_array(expert_1722_acf_can, ei, array_length(ei));
2788 /* register preferences */
2789 module_acf_can = prefs_register_protocol(proto_1722_acf_can, NULL);
2791 prefs_register_obsolete_preference(module_acf_can, "protocol");
2792 prefs_register_bool_preference(
2793 module_acf_can, "try_heuristic_first",
2794 "Try heuristic sub-dissectors first",
2795 "Try to decode a packet using an heuristic sub-dissector"
2796 " before using a sub-dissector registered to \"decode as\"",
2797 &can_heuristic_first
2802 void proto_reg_handoff_1722_acf_can(void)
2804 dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_CAN, avb1722_can_handle);
2805 dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_CAN_BRIEF, avb1722_can_brief_handle);
2807 register_depend_dissector("acf-can", "can");
2808 register_depend_dissector("acf-can", "canfd");
2810 proto_can = proto_get_id_by_filter_name("can");
2811 proto_canfd = proto_get_id_by_filter_name("canfd");
2814 /**************************************************************************************************/
2815 /* ACF LIN Message dissector implementation */
2816 /* */
2817 /**************************************************************************************************/
2818 static void describe_lin_message(proto_item *dst, uint32_t bus_id, uint32_t lin_id)
2820 proto_item_append_text(dst, ": bus_id=%u, id=0x%02X", bus_id, lin_id);
2823 static int dissect_1722_acf_lin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2825 proto_item *ti;
2826 proto_item *ti_lin;
2827 proto_tree *tree_lin;
2828 proto_tree *tree_flags;
2829 unsigned offset = 0;
2830 unsigned captured_length = tvb_captured_length(tvb);
2831 uint32_t pad_length;
2832 bool mtv;
2833 uint32_t bus_id;
2834 uint32_t lin_id;
2835 int payload_length;
2837 ti_lin = proto_tree_add_item(tree, proto_1722_acf_lin, tvb, offset, -1, ENC_NA);
2838 tree_lin = proto_item_add_subtree(ti_lin, ett_1722_lin);
2840 if (captured_length < IEEE_1722_ACF_LIN_HEADER_SIZE) {
2841 expert_add_info(pinfo, ti_lin, &ei_1722_lin_header_cropped);
2842 return captured_length;
2845 tree_flags = proto_tree_add_subtree(tree_lin, tvb, offset, 1, ett_1722_lin_flags, &ti, "Flags and BusID");
2846 proto_tree_add_item_ret_uint(tree_flags, hf_1722_lin_pad, tvb, offset, 1, ENC_BIG_ENDIAN, &pad_length);
2847 proto_tree_add_item_ret_boolean(tree_flags, hf_1722_lin_mtv, tvb, offset, 1, ENC_BIG_ENDIAN, &mtv);
2848 proto_tree_add_item_ret_uint(tree_flags, hf_1722_lin_bus_id, tvb, offset, 1, ENC_BIG_ENDIAN, &bus_id);
2849 proto_item_append_text(ti, ": pad=%u, mtv=%u, bus_id=%u", pad_length, (unsigned)mtv, bus_id);
2850 offset += 1;
2852 proto_tree_add_item_ret_uint(tree_lin, hf_1722_lin_identifier, tvb, offset, 1, ENC_BIG_ENDIAN, &lin_id);
2853 offset += 1;
2855 proto_tree_add_item(tree_lin, hf_1722_lin_message_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
2856 offset += 8;
2858 describe_lin_message(ti_lin, bus_id, lin_id);
2859 describe_lin_message(proto_tree_get_parent(tree), bus_id, lin_id);
2860 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACF-LIN");
2861 col_clear(pinfo->cinfo, COL_INFO);
2862 col_add_fstr(pinfo->cinfo, COL_INFO, "ACF-LIN(%u): 0x%02x ", bus_id, lin_id);
2864 payload_length = tvb_reported_length_remaining(tvb, offset) - pad_length;
2866 if (payload_length < 0 || payload_length > 8)
2868 expert_add_info(pinfo, ti_lin, &ei_1722_lin_invalid_payload_length);
2870 else if (payload_length > 0)
2872 tvbuff_t* next_tvb = tvb_new_subset_length(tvb, offset, payload_length);
2874 col_append_str(pinfo->cinfo, COL_INFO, tvb_bytes_to_str_punct(pinfo->pool, tvb, offset, payload_length, ' '));
2876 /* at the moment, there's no global LIN sub-protocols support. Use our own. */
2877 if (dissector_try_payload_with_data(avb1722_acf_lin_dissector_table, next_tvb, pinfo, tree, true, &lin_id) <= 0)
2879 call_data_dissector(next_tvb, pinfo, tree);
2882 offset += payload_length;
2885 if (pad_length > 0 && tvb_reported_length_remaining(tvb, offset) >= (int)pad_length)
2887 proto_tree_add_item(tree_lin, hf_1722_lin_padding, tvb, offset, pad_length, ENC_NA);
2890 return captured_length;
2893 void proto_register_1722_acf_lin(void)
2895 static hf_register_info hf[] = {
2896 { &hf_1722_lin_pad,
2897 { "Padding Length", "acf-lin.flags.pad",
2898 FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_LIN_PAD_MASK, NULL, HFILL }
2900 { &hf_1722_lin_mtv,
2901 { "Message Timestamp Valid", "acf-lin.flags.mtv",
2902 FT_BOOLEAN, 8, NULL, IEEE_1722_ACF_LIN_MTV_MASK, NULL, HFILL }
2904 { &hf_1722_lin_bus_id,
2905 { "LIN Bus Identifier", "acf-lin.bus_id",
2906 FT_UINT8, BASE_DEC, NULL, IEEE_1722_ACF_LIN_BUS_ID_MASK, NULL, HFILL }
2908 { &hf_1722_lin_identifier,
2909 { "LIN Message Identifier", "acf-lin.id",
2910 FT_UINT8, BASE_HEX, NULL, IEEE_1722_ACF_LIN_IDENTIFIER_MASK, NULL, HFILL }
2912 { &hf_1722_lin_message_timestamp,
2913 { "Message Timestamp", "acf-lin.message_timestamp",
2914 FT_UINT64, BASE_HEX, NULL, IEEE_1722_ACF_LIN_MSG_TIMESTAMP_MASK, NULL, HFILL }
2916 { &hf_1722_lin_padding,
2917 { "Padding", "acf-lin.padding",
2918 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
2922 static int *ett[] =
2924 &ett_1722_lin,
2925 &ett_1722_lin_flags,
2928 static ei_register_info ei[] = {
2929 { &ei_1722_lin_header_cropped, { "acf-lin.expert.header_cropped", PI_PROTOCOL, PI_WARN,
2930 "Message is cropped, no space for header", EXPFILL }},
2931 { &ei_1722_lin_invalid_payload_length, { "acf-lin.expert.incorrect_datalen", PI_PROTOCOL, PI_WARN,
2932 "Incorrect payload length, shall be [0..8]", EXPFILL }},
2935 expert_module_t* expert_1722_acf_lin;
2937 /* Register the protocol name and description */
2938 proto_1722_acf_lin = proto_register_protocol("ACF LIN", "LIN over AVTP", "acf-lin");
2940 /* Required function calls to register the header fields and subtrees used */
2941 proto_register_field_array(proto_1722_acf_lin, hf, array_length(hf));
2942 proto_register_subtree_array(ett, array_length(ett));
2944 expert_1722_acf_lin = expert_register_protocol(proto_1722_acf_lin);
2945 expert_register_field_array(expert_1722_acf_lin, ei, array_length(ei));
2947 avb1722_acf_lin_dissector_table = register_decode_as_next_proto(proto_1722_acf_lin, "acf-lin.subdissector", "ACF-LIN next level dissector", NULL);
2949 avb1722_acf_lin_handle = register_dissector("acf-lin", dissect_1722_acf_lin, proto_1722_acf_lin);
2952 void proto_reg_handoff_1722_acf_lin(void)
2954 dissector_add_uint("acf.msg_type", IEEE_1722_ACF_TYPE_LIN, avb1722_acf_lin_handle);
2958 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2960 * Local variables:
2961 * c-basic-offset: 4
2962 * tab-width: 8
2963 * indent-tabs-mode: nil
2964 * End:
2966 * vi: set shiftwidth=4 tabstop=8 expandtab:
2967 * :indentSize=4:tabSize=8:noTabs=true: