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/
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>
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
{
95 } ieee1722_seq_data_t
;
97 /**************************************************************************************************/
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 */
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 /**************************************************************************************************/
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 /**************************************************************************************************/
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 /**************************************************************************************************/
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 /**************************************************************************************************/
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 /**************************************************************************************************/
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 */
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 */
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 */
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 /**************************************************************************************************/
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" },
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 */
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 */
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"},
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"},
390 static const value_string fraction_number_vals
[] = {
392 {1, "Divided into 2 datablocks"},
393 {2, "Divided into 4 datablocks"},
394 {3, "Divided into 8 datablocks"},
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"},
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"},
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 /**************************************************************************************************/
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"},
520 static const range_string aaf_nominal_sample_rate_range_rvals
[] = {
521 {0, 0, "User specified"},
532 {0xb, 0xf, "Reserved"},
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"},
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 /**************************************************************************************************/
576 /**************************************************************************************************/
577 static const range_string crf_pull_range_rvals
[] = {
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"},
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 /**************************************************************************************************/
623 /**************************************************************************************************/
624 static const range_string cvf_format_range_rvals
[] = {
626 {2, 2, "RFC payload type"},
627 {3, 0xff, "Reserved"},
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"},
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 /**************************************************************************************************/
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 /**************************************************************************************************/
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 */
715 /**************************************************************************************************/
717 static const range_string acf_msg_type_range_rvals
[] = {
718 {0x00, 0x00, "FlexRay"},
720 {0x02, 0x02, "CAN Brief"},
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"},
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 */
755 /**************************************************************************************************/
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 */
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 */
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 */
834 /**************************************************************************************************/
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
);
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
);
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
)
868 proto_tree
*ieee1722_tree
;
869 uint32_t encap_seqnum
, encap_seqnum_exp
;
870 unsigned subtype
= 0;
873 static int * const fields
[] = {
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
);
893 expert_add_info(pinfo
, ti
, &ei_1722_encap_seqnum_ooo
);
897 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
902 proto_tree_add_item_ret_uint(ieee1722_tree
, hf_1722_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &subtype
);
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
}
936 { "AVTP Subtype", "ieee1722.subtype",
937 FT_UINT8
, BASE_HEX
| BASE_RANGE_STRING
, RVALS(subtype_range_rvals
), 0x0, NULL
, HFILL
}
940 { "AVTP Stream ID Valid", "ieee1722.svfield",
941 FT_BOOLEAN
, 8, NULL
, IEEE_1722_SV_MASK
, NULL
, HFILL
}
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
[] = {
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 */
987 /**************************************************************************************************/
988 static int dissect_1722_61883(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
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
;
1003 uint8_t cip_dbs
= 0;
1005 uint8_t channel
= 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;
1014 unsigned datalen
= 0;
1015 unsigned db_size
= 0;
1016 unsigned numSourcePackets
= 0;
1019 static int * const fields
[] = {
1020 &hf_1722_61883_mrfield
,
1021 &hf_1722_61883_gvfield
,
1022 &hf_1722_61883_tvfield
,
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
);
1031 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1033 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_tufield
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1035 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1038 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_avtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1040 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_gateway_info
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
);
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
;
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");
1063 proto_item_append_text(ti_channel
, ": Originating source is on AVTP network (native AVTP)");
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
;
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
);
1078 case IEEE_1722_61883_TAG_NO_CIP
:
1079 proto_item_prepend_text(ti
, "IIDC 1394 video payload:");
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
;
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
);
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
);
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
);
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
) {
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
;
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
;
1144 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_cip_dbc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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
;
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
);
1163 proto_tree_add_item(ti_61883_tree
, hf_1722_61883_cip_syt
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
);
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
;
1190 case IEEE_1722_61883_6
:
1193 expert_add_info(pinfo
, ti_cip_fn
, &ei_1722_61883_6_incorrect_cip_fn
);
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
);
1217 proto_tree_add_item(ti_sample_tree
, hf_1722_61883_sample
, tvb
, offset
, 3, ENC_NA
);
1223 case IEEE_1722_61883_4
:
1226 expert_add_info(pinfo
, ti_cip_dbs
, &ei_1722_61883_4_incorrect_cip_dbs
);
1230 expert_add_info(pinfo
, ti_cip_fn
, &ei_1722_61883_4_incorrect_cip_fn
);
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
;
1256 expert_add_info(pinfo
, ti_cip_fmt
, &ei_1722_61883_unknown_format
);
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
[] = {
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 */
1457 /**************************************************************************************************/
1458 static int dissect_1722_aaf (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
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
;
1467 unsigned datalen
= 0;
1468 unsigned channels_per_frame
= 0;
1469 unsigned bit_depth
= 0;
1470 unsigned sample_width
= 0;
1471 unsigned format
= 0;
1474 static int * const fields
[] = {
1475 &hf_1722_aaf_mrfield
,
1476 &hf_1722_aaf_tvfield
,
1479 static int * const fields_pcm
[] = {
1480 &hf_1722_aaf_sparse_timestamp
,
1481 &hf_1722_aaf_evtfield
,
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
);
1490 proto_tree_add_item(ti_aaf_tree
, hf_1722_aaf_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1492 proto_tree_add_item(ti_aaf_tree
, hf_1722_aaf_tufield
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1494 proto_tree_add_item(ti_aaf_tree
, hf_1722_aaf_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1496 proto_tree_add_item(ti_aaf_tree
, hf_1722_aaf_avtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1499 ti_format
= proto_tree_add_item_ret_uint(ti_aaf_tree
, hf_1722_aaf_format
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &format
);
1503 case IEEE_1722_AAF_FORMAT_USER
:
1505 case IEEE_1722_AAF_FORMAT_FLOAT_32_BIT
:
1508 case IEEE_1722_AAF_FORMAT_INT_32_BIT
:
1511 case IEEE_1722_AAF_FORMAT_INT_24_BIT
:
1514 case IEEE_1722_AAF_FORMAT_INT_16_BIT
:
1517 case IEEE_1722_AAF_FORMAT_AES3_32_BIT
:
1524 if (format
< IEEE_1722_AAF_FORMAT_AES3_32_BIT
)
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
);
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
);
1542 proto_tree_add_item_ret_uint(ti_aaf_tree
, hf_1722_aaf_stream_data_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &datalen
);
1545 proto_tree_add_bitmask_list(ti_aaf_tree
, tvb
, offset
, 1, fields_pcm
, ENC_BIG_ENDIAN
);
1548 proto_tree_add_item(ti_aaf_tree
, hf_1722_aaf_reserved
, tvb
, offset
, 1, ENC_NA
);
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
);
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
);
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
}}
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 */
1695 /**************************************************************************************************/
1696 static int dissect_1722_cvf (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1699 proto_tree
*ti_cvf_tree
;
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
,
1712 static int * const fields_cvf
[] = {
1713 &hf_1722_cvf_marker_bit
,
1714 &hf_1722_cvf_evtfield
,
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
,
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
);
1733 proto_tree_add_item(ti_cvf_tree
, hf_1722_cvf_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1735 proto_tree_add_item(ti_cvf_tree
, hf_1722_cvf_tufield
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1737 proto_tree_add_item(ti_cvf_tree
, hf_1722_cvf_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1739 proto_tree_add_item(ti_cvf_tree
, hf_1722_cvf_avtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
) {
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
);
1747 expert_add_info(pinfo
, ti_format
, &ei_cvf_reserved_format
);
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
);
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
);
1756 proto_tree_add_bitmask_list(ti_cvf_tree
, tvb
, offset
, 1, fields_cvf
, ENC_BIG_ENDIAN
);
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
);
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
);
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
);
1784 expert_add_info(pinfo
, ti_format
, &ei_cvf_reserved_format
);
1785 call_data_dissector(next_tvb
, pinfo
, tree
);
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
}}
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 */
1891 /**************************************************************************************************/
1892 static int dissect_1722_crf (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1895 proto_tree
*ti_crf_tree
;
1896 proto_tree
*timestamp_tree
;
1898 unsigned datalen
= 0;
1900 static int * const fields
[] = {
1901 &hf_1722_crf_mrfield
,
1902 &hf_1722_crf_fsfield
,
1903 &hf_1722_crf_tufield
,
1906 static int * const pull_frequency
[] = {
1908 &hf_1722_crf_base_frequency
,
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
);
1917 proto_tree_add_item(ti_crf_tree
, hf_1722_crf_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1919 proto_tree_add_item(ti_crf_tree
, hf_1722_crf_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1921 proto_tree_add_item(ti_crf_tree
, hf_1722_crf_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
1923 proto_tree_add_bitmask_list(ti_crf_tree
, tvb
, offset
, 4, pull_frequency
, ENC_NA
);
1925 proto_tree_add_item_ret_uint(ti_crf_tree
, hf_1722_crf_data_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &datalen
);
1927 proto_tree_add_item(ti_crf_tree
, hf_1722_crf_timestamp_interval
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
);
1936 expert_add_info(pinfo
, ti
, &ei_crf_datalen
);
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
}}
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 */
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
;
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
,
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
);
2068 proto_tree_add_item(tree_ntscf
, hf_1722_ntscf_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2070 proto_tree_add_item(tree_ntscf
, hf_1722_ntscf_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
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
2084 while(datalen
> 0) {
2085 unsigned processed_bytes
;
2088 next_tvb
= tvb_new_subset_length(tvb
, offset
, datalen
);
2089 if (call_dissector(avb1722_acf_handle
, next_tvb
, pinfo
, tree
) <= 0) {
2093 processed_bytes
= tvb_reported_length(next_tvb
);
2095 offset
+= processed_bytes
;
2096 if (processed_bytes
< datalen
) {
2097 datalen
-= processed_bytes
;
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
}
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 */
2165 /**************************************************************************************************/
2166 static int dissect_1722_tscf (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2169 proto_item
*ti_tscf
;
2170 proto_tree
*tree_tscf
;
2171 proto_tree
*tree_flags
;
2172 proto_tree
*tree_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
);
2199 proto_tree_add_item(tree_tscf
, hf_1722_tscf_seqnum
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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
);
2208 proto_tree_add_item(tree_tscf
, hf_1722_tscf_stream_id
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
2211 proto_tree_add_item(tree_tscf
, hf_1722_tscf_avtp_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2214 proto_tree_add_item(tree_tscf
, hf_1722_tscf_rsv3
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
);
2224 proto_tree_add_item(tree_tscf
, hf_1722_tscf_rsv4
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2227 if ((int)datalen
> captured_payload_length
) {
2228 datalen
= captured_payload_length
> 0
2229 ? captured_payload_length
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) {
2239 processed_bytes
= tvb_reported_length(next_tvb
);
2241 offset
+= processed_bytes
;
2242 if (processed_bytes
< datalen
) {
2243 datalen
-= processed_bytes
;
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
[] =
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
}
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
}
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
}
2318 &ett_1722_tscf_flags
,
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 */
2350 /**************************************************************************************************/
2351 static int dissect_1722_acf (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2355 proto_item
*ti_header
;
2356 proto_tree
*tree_acf
;
2357 proto_tree
*tree_header
;
2359 uint32_t msg_length
;
2360 uint32_t payload_length
;
2361 unsigned captured_length
= tvb_captured_length(tvb
);
2362 const char *msg_type_str
;
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
}
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 */
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",
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
) ||
2502 static int dissect_1722_acf_can_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
, const bool is_brief
)
2505 uint32_t pad_length
;
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
;
2516 proto_tree
*tree_can
;
2517 proto_tree
*tree_can_id
;
2519 int * const *can_flags
;
2520 struct can_info can_info
;
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
,
2536 static int * const can_std_flags
[] = {
2537 &hf_1722_can_rtrfield
,
2538 &hf_1722_can_efffield
,
2542 static int * const can_fd_flags
[] = {
2543 &hf_1722_can_efffield
,
2544 &hf_1722_can_brsfield
,
2545 &hf_1722_can_esifield
,
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
);
2555 proto_item_append_text(ti_acf_can
, " Brief");
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
);
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
);
2596 /* Add message_timestamp to ACF_CAN if present */
2598 proto_tree_add_item(tree_acf_can
, hf_1722_can_message_timestamp
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
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
);
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) {
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
;
2648 can_info
.id
|= CAN_EFF_FLAG
;
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
},
2696 { "Padding Length", "acf-can.flags.pad",
2697 FT_UINT8
, BASE_DEC
, NULL
, IEEE_1722_ACF_CAN_PAD_MASK
, NULL
, HFILL
}
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
}
2756 &ett_1722_can_flags
,
2757 &ett_1722_can_bus_id
,
2758 &ett_1722_can_msg_id
,
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 */
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_
)
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
;
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
);
2852 proto_tree_add_item_ret_uint(tree_lin
, hf_1722_lin_identifier
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &lin_id
);
2855 proto_tree_add_item(tree_lin
, hf_1722_lin_message_timestamp
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
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
[] = {
2897 { "Padding Length", "acf-lin.flags.pad",
2898 FT_UINT8
, BASE_DEC
, NULL
, IEEE_1722_ACF_LIN_PAD_MASK
, NULL
, HFILL
}
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
}
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
2963 * indent-tabs-mode: nil
2966 * vi: set shiftwidth=4 tabstop=8 expandtab:
2967 * :indentSize=4:tabSize=8:noTabs=true: