2 * Routines for FlexRay dissection
3 * Copyright 2016, Roman Leonhartsberger <ro.leonhartsberger@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/decode_as.h>
16 #include <epan/prefs.h>
17 #include <wiretap/wtap.h>
18 #include <epan/expert.h>
22 #include "packet-flexray.h"
25 void proto_reg_handoff_flexray(void);
26 void proto_register_flexray(void);
28 static dissector_handle_t flexray_handle
;
30 static bool prefvar_try_heuristic_first
;
32 static dissector_table_t subdissector_table
;
33 static dissector_table_t flexrayid_subdissector_table
;
35 static heur_dissector_list_t heur_subdissector_list
;
36 static heur_dtbl_entry_t
*heur_dtbl_entry
;
38 static int proto_flexray
;
39 static int hf_flexray_measurement_header_field
;
40 static int hf_flexray_error_flags_field
;
41 static int hf_flexray_frame_header
;
43 static int hf_flexray_ti
;
44 static int hf_flexray_ch
;
45 static int hf_flexray_fcrc_err
;
46 static int hf_flexray_hcrc_err
;
47 static int hf_flexray_fes_err
;
48 static int hf_flexray_cod_err
;
49 static int hf_flexray_tss_viol
;
50 static int hf_flexray_res
;
51 static int hf_flexray_ppi
;
52 static int hf_flexray_nfi
;
53 static int hf_flexray_sfi
;
54 static int hf_flexray_stfi
;
55 static int hf_flexray_fid
;
56 static int hf_flexray_pl
;
57 static int hf_flexray_hcrc
;
58 static int hf_flexray_cc
;
59 static int hf_flexray_sl
;
60 static int hf_flexray_flexray_id
;
62 static int ett_flexray
;
63 static int ett_flexray_measurement_header
;
64 static int ett_flexray_error_flags
;
65 static int ett_flexray_frame
;
67 static int * const error_fields
[] = {
76 static expert_field ei_flexray_frame_payload_truncated
;
77 static expert_field ei_flexray_symbol_frame
;
78 static expert_field ei_flexray_error_flag
;
79 static expert_field ei_flexray_stfi_flag
;
81 #define FLEXRAY_FRAME 0x01
82 #define FLEXRAY_SYMBOL 0x02
84 #define FLEXRAY_HEADER_LENGTH 5
86 static const value_string flexray_type_names
[] = {
87 { FLEXRAY_FRAME
, "FRAME" },
88 { FLEXRAY_SYMBOL
, "SYMB" },
92 static const true_false_string flexray_channel_tfs
= {
97 static const true_false_string flexray_nfi_tfs
= {
102 /* Senders and Receivers UAT */
103 typedef struct _sender_receiver_config
{
110 } sender_receiver_config_t
;
112 #define DATAFILE_FR_SENDER_RECEIVER "FR_senders_receivers"
114 static GHashTable
*data_sender_receiver
;
115 static sender_receiver_config_t
*sender_receiver_configs
;
116 static unsigned sender_receiver_config_num
;
118 UAT_HEX_CB_DEF(sender_receiver_configs
, bus_id
, sender_receiver_config_t
)
119 UAT_HEX_CB_DEF(sender_receiver_configs
, channel
, sender_receiver_config_t
)
120 UAT_HEX_CB_DEF(sender_receiver_configs
, cycle
, sender_receiver_config_t
)
121 UAT_HEX_CB_DEF(sender_receiver_configs
, frame_id
, sender_receiver_config_t
)
122 UAT_CSTRING_CB_DEF(sender_receiver_configs
, sender_name
, sender_receiver_config_t
)
123 UAT_CSTRING_CB_DEF(sender_receiver_configs
, receiver_name
, sender_receiver_config_t
)
126 copy_sender_receiver_config_cb(void *n
, const void *o
, size_t size _U_
) {
127 sender_receiver_config_t
*new_rec
= (sender_receiver_config_t
*)n
;
128 const sender_receiver_config_t
*old_rec
= (const sender_receiver_config_t
*)o
;
130 new_rec
->bus_id
= old_rec
->bus_id
;
131 new_rec
->channel
= old_rec
->channel
;
132 new_rec
->cycle
= old_rec
->cycle
;
133 new_rec
->frame_id
= old_rec
->frame_id
;
134 new_rec
->sender_name
= g_strdup(old_rec
->sender_name
);
135 new_rec
->receiver_name
= g_strdup(old_rec
->receiver_name
);
140 update_sender_receiver_config(void *r
, char **err
) {
141 sender_receiver_config_t
*rec
= (sender_receiver_config_t
*)r
;
143 if (rec
->channel
> 0x1) {
144 *err
= ws_strdup_printf("We currently only support 0 and 1 for Channels (Channel: %i Frame ID: %i)", rec
->channel
, rec
->frame_id
);
148 if (rec
->cycle
> 0xff) {
149 *err
= ws_strdup_printf("We currently only support 8 bit Cycles (Cycle: %i Frame ID: %i)", rec
->cycle
, rec
->frame_id
);
153 if (rec
->frame_id
> 0xffff) {
154 *err
= ws_strdup_printf("We currently only support 16 bit Frame IDs (Cycle: %i Frame ID: %i)", rec
->cycle
, rec
->frame_id
);
158 if (rec
->bus_id
> 0xffff) {
159 *err
= ws_strdup_printf("We currently only support 16 bit bus identifiers (Bus ID: 0x%x)", rec
->bus_id
);
167 free_sender_receiver_config_cb(void *r
) {
168 sender_receiver_config_t
*rec
= (sender_receiver_config_t
*)r
;
169 /* freeing result of g_strdup */
170 g_free(rec
->sender_name
);
171 rec
->sender_name
= NULL
;
172 g_free(rec
->receiver_name
);
173 rec
->receiver_name
= NULL
;
177 sender_receiver_key(uint16_t bus_id
, uint8_t channel
, uint8_t cycle
, uint16_t frame_id
) {
178 return ((uint64_t)bus_id
<< 32) | ((uint64_t)channel
<< 24) | ((uint64_t)cycle
<< 16) | frame_id
;
181 static sender_receiver_config_t
*
182 ht_lookup_sender_receiver_config(flexray_info_t
*flexray_info
) {
183 sender_receiver_config_t
*tmp
= NULL
;
186 if (sender_receiver_configs
== NULL
) {
190 key
= sender_receiver_key(flexray_info
->bus_id
, flexray_info
->ch
, flexray_info
->cc
, flexray_info
->id
);
191 tmp
= (sender_receiver_config_t
*)g_hash_table_lookup(data_sender_receiver
, &key
);
194 key
= sender_receiver_key(0, flexray_info
->ch
, flexray_info
->cc
, flexray_info
->id
);
195 tmp
= (sender_receiver_config_t
*)g_hash_table_lookup(data_sender_receiver
, &key
);
202 sender_receiver_free_key(void *key
) {
203 wmem_free(wmem_epan_scope(), key
);
207 post_update_sender_receiver_cb(void) {
209 uint64_t *key_id
= NULL
;
211 /* destroy old hash table, if it exist */
212 if (data_sender_receiver
) {
213 g_hash_table_destroy(data_sender_receiver
);
214 data_sender_receiver
= NULL
;
217 /* create new hash table */
218 data_sender_receiver
= g_hash_table_new_full(g_int64_hash
, g_int64_equal
, &sender_receiver_free_key
, NULL
);
220 if (data_sender_receiver
== NULL
|| sender_receiver_configs
== NULL
|| sender_receiver_config_num
== 0) {
224 for (i
= 0; i
< sender_receiver_config_num
; i
++) {
225 key_id
= wmem_new(wmem_epan_scope(), uint64_t);
226 *key_id
= sender_receiver_key(sender_receiver_configs
[i
].bus_id
, sender_receiver_configs
[i
].channel
,
227 sender_receiver_configs
[i
].cycle
, sender_receiver_configs
[i
].frame_id
);
228 g_hash_table_insert(data_sender_receiver
, key_id
, &sender_receiver_configs
[i
]);
233 flexray_set_source_and_destination_columns(packet_info
*pinfo
, flexray_info_t
*flexray_info
) {
234 sender_receiver_config_t
*tmp
= ht_lookup_sender_receiver_config(flexray_info
);
237 /* remove all addresses to support FlexRay as payload (e.g., TECMP) */
238 clear_address(&pinfo
->net_src
);
239 clear_address(&pinfo
->dl_src
);
240 clear_address(&pinfo
->src
);
241 clear_address(&pinfo
->net_dst
);
242 clear_address(&pinfo
->dl_dst
);
243 clear_address(&pinfo
->dst
);
245 col_add_str(pinfo
->cinfo
, COL_DEF_SRC
, tmp
->sender_name
);
246 col_add_str(pinfo
->cinfo
, COL_DEF_DST
, tmp
->receiver_name
);
253 flexray_calc_flexrayid(uint16_t bus_id
, uint8_t channel
, uint16_t frame_id
, uint8_t cycle
) {
254 /* Bus-ID 4bit->4bit | Channel 1bit->4bit | Frame ID 11bit->16bit | Cycle 6bit->8bit */
256 return (uint32_t)(bus_id
& 0xf) << 28 |
257 (uint32_t)(channel
& 0x0f) << 24 |
258 (uint32_t)(frame_id
& 0xffff) << 8 |
259 (uint32_t)(cycle
& 0xff);
263 flexray_flexrayinfo_to_flexrayid(flexray_info_t
*flexray_info
) {
264 return flexray_calc_flexrayid(flexray_info
->bus_id
, flexray_info
->ch
, flexray_info
->id
, flexray_info
->cc
);
268 flexray_call_subdissectors(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, flexray_info_t
*flexray_info
, const bool use_heuristics_first
) {
269 uint32_t flexray_id
= flexray_flexrayinfo_to_flexrayid(flexray_info
);
271 /* lets try an exact match first */
272 if (dissector_try_uint_with_data(flexrayid_subdissector_table
, flexray_id
, tvb
, pinfo
, tree
, true, flexray_info
)) {
276 /* lets try with BUS-ID = 0 (any) */
277 if (dissector_try_uint_with_data(flexrayid_subdissector_table
, flexray_id
& ~FLEXRAY_ID_BUS_ID_MASK
, tvb
, pinfo
, tree
, true, flexray_info
)) {
281 /* lets try with cycle = 0xff (any) */
282 if (dissector_try_uint_with_data(flexrayid_subdissector_table
, flexray_id
| FLEXRAY_ID_CYCLE_MASK
, tvb
, pinfo
, tree
, true, flexray_info
)) {
286 /* lets try with BUS-ID = 0 (any) and cycle = 0xff (any) */
287 if (dissector_try_uint_with_data(flexrayid_subdissector_table
, (flexray_id
& ~FLEXRAY_ID_BUS_ID_MASK
) | FLEXRAY_ID_CYCLE_MASK
, tvb
, pinfo
, tree
, true, flexray_info
)) {
291 if (!use_heuristics_first
) {
292 if (!dissector_try_payload_with_data(subdissector_table
, tvb
, pinfo
, tree
, false, flexray_info
)) {
293 if (!dissector_try_heuristic(heur_subdissector_list
, tvb
, pinfo
, tree
, &heur_dtbl_entry
, flexray_info
)) {
298 if (!dissector_try_heuristic(heur_subdissector_list
, tvb
, pinfo
, tree
, &heur_dtbl_entry
, flexray_info
)) {
299 if (!dissector_try_payload_with_data(subdissector_table
, tvb
, pinfo
, tree
, false, flexray_info
)) {
309 dissect_flexray(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
311 proto_tree
*flexray_tree
, *measurement_tree
;
313 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "FLEXRAY");
314 col_clear(pinfo
->cinfo
, COL_INFO
);
316 ti
= proto_tree_add_item(tree
, proto_flexray
, tvb
, 0, -1, ENC_NA
);
317 flexray_tree
= proto_item_add_subtree(ti
, ett_flexray
);
319 /* Measurement Header [1 Byte] */
320 ti
= proto_tree_add_item(flexray_tree
, hf_flexray_measurement_header_field
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
321 measurement_tree
= proto_item_add_subtree(ti
, ett_flexray_measurement_header
);
323 bool flexray_channel_is_b
;
324 proto_tree_add_item_ret_boolean(measurement_tree
, hf_flexray_ch
, tvb
, 0, 1, ENC_BIG_ENDIAN
, &flexray_channel_is_b
);
327 proto_tree_add_item_ret_uint(measurement_tree
, hf_flexray_ti
, tvb
, 0, 1, ENC_BIG_ENDIAN
, &frame_type
);
328 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s:", val_to_str(frame_type
, flexray_type_names
, "Unknown (0x%02x)"));
330 if (frame_type
== FLEXRAY_FRAME
) {
331 proto_tree
*error_flags_tree
, *flexray_frame_tree
;
332 bool call_subdissector
= true;
334 /* Error Flags [1 Byte] */
335 ti
= proto_tree_add_bitmask(flexray_tree
, tvb
, 1, hf_flexray_error_flags_field
, ett_flexray_error_flags
, error_fields
, ENC_BIG_ENDIAN
);
336 error_flags_tree
= proto_item_add_subtree(ti
, ett_flexray_error_flags
);
338 uint8_t error_flags
= tvb_get_uint8(tvb
, 1) & 0x1f;
340 expert_add_info(pinfo
, error_flags_tree
, &ei_flexray_error_flag
);
341 call_subdissector
= false;
344 /* FlexRay Frame [5 Bytes + Payload]*/
345 int flexray_frame_length
= tvb_captured_length(tvb
) - 2;
347 proto_item
*ti_header
= proto_tree_add_item(flexray_tree
, hf_flexray_frame_header
, tvb
, 2, -1, ENC_NA
);
348 flexray_frame_tree
= proto_item_add_subtree(ti_header
, ett_flexray_frame
);
351 proto_tree_add_item(flexray_frame_tree
, hf_flexray_res
, tvb
, 2, 1, ENC_NA
);
352 proto_tree_add_item(flexray_frame_tree
, hf_flexray_ppi
, tvb
, 2, 1, ENC_NA
);
353 proto_tree_add_item_ret_boolean(flexray_frame_tree
, hf_flexray_nfi
, tvb
, 2, 1, ENC_NA
, &nfi
);
354 proto_tree_add_item_ret_boolean(flexray_frame_tree
, hf_flexray_sfi
, tvb
, 2, 1, ENC_NA
, &sfi
);
355 proto_tree_add_item_ret_boolean(flexray_frame_tree
, hf_flexray_stfi
, tvb
, 2, 1, ENC_NA
, &stfi
);
358 expert_add_info(pinfo
, flexray_frame_tree
, &ei_flexray_stfi_flag
);
359 call_subdissector
= false;
363 proto_tree_add_item_ret_uint(flexray_frame_tree
, hf_flexray_fid
, tvb
, 2, 2, ENC_BIG_ENDIAN
, &flexray_id
);
364 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ID %4d", flexray_id
);
366 if (flexray_id
== 0) {
367 call_subdissector
= false;
371 proto_tree_add_item_ret_uint(flexray_frame_tree
, hf_flexray_pl
, tvb
, 4, 1, ENC_BIG_ENDIAN
, &flexray_pl
);
372 int flexray_reported_payload_length
= 2 * flexray_pl
;
373 int flexray_current_payload_length
= flexray_frame_length
- FLEXRAY_HEADER_LENGTH
;
374 bool payload_truncated
= flexray_reported_payload_length
> flexray_current_payload_length
;
376 if (flexray_reported_payload_length
< flexray_current_payload_length
) {
377 flexray_current_payload_length
= MAX(0, flexray_reported_payload_length
);
380 proto_tree_add_item(flexray_frame_tree
, hf_flexray_hcrc
, tvb
, 4, 3, ENC_BIG_ENDIAN
);
383 proto_tree_add_item_ret_uint(flexray_frame_tree
, hf_flexray_cc
, tvb
, 6, 1, ENC_BIG_ENDIAN
, &flexray_cc
);
384 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " CC %2d", flexray_cc
);
387 if (payload_truncated
) {
388 expert_add_info(pinfo
, flexray_frame_tree
, &ei_flexray_frame_payload_truncated
);
389 call_subdissector
= false;
392 if (tvb
!= NULL
&& flexray_current_payload_length
> 0) {
393 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", tvb_bytes_to_str_punct(pinfo
->pool
, tvb
, 7, flexray_current_payload_length
, ' '));
397 call_subdissector
= false;
398 col_append_str(pinfo
->cinfo
, COL_INFO
, " NF");
400 /* Payload is optional on Null Frames */
401 if (payload_truncated
&& flexray_current_payload_length
!= 0) {
402 expert_add_info(pinfo
, flexray_frame_tree
, &ei_flexray_frame_payload_truncated
);
406 proto_item_set_end(ti_header
, tvb
, 2 + FLEXRAY_HEADER_LENGTH
);
408 /* Only supporting single bus id right now */
409 flexray_info_t flexray_info
= { .id
= (uint16_t)flexray_id
,
410 .cc
= (uint8_t)flexray_cc
,
411 .ch
= flexray_channel_is_b
? 1 : 0,
414 ti
= proto_tree_add_uint(flexray_frame_tree
, hf_flexray_flexray_id
, tvb
, 0, 7, flexray_flexrayinfo_to_flexrayid(&flexray_info
));
415 proto_item_set_hidden(ti
);
416 flexray_set_source_and_destination_columns(pinfo
, &flexray_info
);
418 if (flexray_current_payload_length
> 0) {
419 tvbuff_t
*next_tvb
= tvb_new_subset_length(tvb
, 7, flexray_current_payload_length
);
420 if (!call_subdissector
|| !flexray_call_subdissectors(next_tvb
, pinfo
, tree
, &flexray_info
, prefvar_try_heuristic_first
)) {
421 call_data_dissector(next_tvb
, pinfo
, tree
);
424 } else if (frame_type
== FLEXRAY_SYMBOL
) {
425 /* FlexRay Symbol [1 Byte] */
426 expert_add_info(pinfo
, flexray_tree
, &ei_flexray_symbol_frame
);
428 uint32_t symbol_length
;
429 proto_tree_add_item_ret_uint(flexray_tree
, hf_flexray_sl
, tvb
, 1, 1, ENC_BIG_ENDIAN
, &symbol_length
);
430 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " SL %3d", symbol_length
);
433 return tvb_captured_length(tvb
);
437 proto_register_flexray(void) {
438 module_t
*flexray_module
;
439 expert_module_t
*expert_flexray
;
440 uat_t
*sender_receiver_uat
= NULL
;
442 static hf_register_info hf
[] = {
443 { &hf_flexray_measurement_header_field
, {
444 "Measurement Header", "flexray.mhf", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
446 "Type Index", "flexray.ti", FT_UINT8
, BASE_HEX
, VALS(flexray_type_names
), 0x7f, NULL
, HFILL
} },
448 "Channel", "flexray.ch", FT_BOOLEAN
, 8, TFS(&flexray_channel_tfs
), 0x80, NULL
, HFILL
} },
449 { &hf_flexray_error_flags_field
, {
450 "Error Flags", "flexray.eff", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
451 { &hf_flexray_fcrc_err
, {
452 "Frame CRC error", "flexray.fcrc_err", FT_BOOLEAN
, 8, NULL
, 0x10, NULL
, HFILL
} },
453 { &hf_flexray_hcrc_err
, {
454 "Header CRC error", "flexray.hcrc_err", FT_BOOLEAN
, 8, NULL
, 0x08, NULL
, HFILL
} },
455 { &hf_flexray_fes_err
, {
456 "Frame End Sequence error", "flexray.fes_err", FT_BOOLEAN
, 8, NULL
, 0x04, NULL
, HFILL
} },
457 { &hf_flexray_cod_err
, {
458 "Coding error", "flexray.cod_err", FT_BOOLEAN
, 8, NULL
, 0x02, NULL
, HFILL
} },
459 { &hf_flexray_tss_viol
, {
460 "TSS violation", "flexray.tss_viol", FT_BOOLEAN
, 8, NULL
, 0x01, NULL
, HFILL
} },
461 { &hf_flexray_frame_header
, {
462 "FlexRay Frame Header", "flexray.frame_header", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
464 "Reserved", "flexray.res", FT_BOOLEAN
, 8, NULL
, 0x80, NULL
, HFILL
} },
466 "Payload Preamble Indicator", "flexray.ppi", FT_BOOLEAN
, 8, NULL
, 0x40, NULL
, HFILL
} },
468 "Null Frame Indicator", "flexray.nfi", FT_BOOLEAN
, 8, TFS(&flexray_nfi_tfs
), 0x20, NULL
, HFILL
} },
470 "Sync Frame Indicator", "flexray.sfi", FT_BOOLEAN
, 8, NULL
, 0x10, NULL
, HFILL
} },
471 { &hf_flexray_stfi
, {
472 "Startup Frame Indicator", "flexray.stfi", FT_BOOLEAN
, 8, NULL
, 0x08, NULL
, HFILL
} },
474 "Frame ID", "flexray.fid", FT_UINT16
, BASE_DEC
, NULL
, 0x07ff, NULL
, HFILL
} },
476 "Payload length", "flexray.pl", FT_UINT8
, BASE_DEC
, NULL
, 0xfe, NULL
, HFILL
} },
477 { &hf_flexray_hcrc
, {
478 "Header CRC", "flexray.hcrc", FT_UINT24
, BASE_DEC
, NULL
, 0x01ffc0, NULL
, HFILL
} },
480 "Cycle Counter", "flexray.cc", FT_UINT8
, BASE_DEC
, NULL
, 0x3f, NULL
, HFILL
} },
482 "Symbol length", "flexray.sl", FT_UINT8
, BASE_DEC
, NULL
, 0x7f, NULL
, HFILL
} },
483 { &hf_flexray_flexray_id
, {
484 "FlexRay ID (combined)", "flexray.combined_id", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
487 static int *ett
[] = {
489 &ett_flexray_measurement_header
,
490 &ett_flexray_error_flags
,
494 static ei_register_info ei
[] = {
495 { &ei_flexray_frame_payload_truncated
, {
496 "flexray.malformed_frame_payload_truncated", PI_MALFORMED
, PI_ERROR
, "Truncated Frame Payload", EXPFILL
} },
497 { &ei_flexray_symbol_frame
, {
498 "flexray.symbol_frame", PI_SEQUENCE
, PI_CHAT
, "Packet is a Symbol Frame", EXPFILL
} },
499 { &ei_flexray_error_flag
, {
500 "flexray.error_flag", PI_PROTOCOL
, PI_WARN
, "One or more Error Flags set", EXPFILL
} },
501 { &ei_flexray_stfi_flag
, {
502 "flexray.stfi_flag", PI_PROTOCOL
, PI_WARN
, "A startup frame must always be a sync frame", EXPFILL
} }
505 proto_flexray
= proto_register_protocol("FlexRay Protocol", "FLEXRAY", "flexray");
507 flexray_module
= prefs_register_protocol(proto_flexray
, NULL
);
509 proto_register_field_array(proto_flexray
, hf
, array_length(hf
));
510 proto_register_subtree_array(ett
, array_length(ett
));
512 expert_flexray
= expert_register_protocol(proto_flexray
);
513 expert_register_field_array(expert_flexray
, ei
, array_length(ei
));
515 flexray_handle
= register_dissector("flexray", dissect_flexray
, proto_flexray
);
517 prefs_register_bool_preference(flexray_module
, "try_heuristic_first", "Try heuristic sub-dissectors first",
518 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to \"decode as\"",
519 &prefvar_try_heuristic_first
522 static uat_field_t sender_receiver_mapping_uat_fields
[] = {
523 UAT_FLD_HEX(sender_receiver_configs
, bus_id
, "Bus ID", "Bus ID of the Interface with 0 meaning any(hex uint16 without leading 0x)."),
524 UAT_FLD_HEX(sender_receiver_configs
, channel
, "Channel", "Channel (8bit hex without leading 0x)"),
525 UAT_FLD_HEX(sender_receiver_configs
, cycle
, "Cycle", "Cycle (8bit hex without leading 0x)"),
526 UAT_FLD_HEX(sender_receiver_configs
, frame_id
, "Frame ID", "Frame ID (16bit hex without leading 0x)"),
527 UAT_FLD_CSTRING(sender_receiver_configs
, sender_name
, "Sender Name", "Name of Sender(s)"),
528 UAT_FLD_CSTRING(sender_receiver_configs
, receiver_name
, "Receiver Name", "Name of Receiver(s)"),
532 sender_receiver_uat
= uat_new("Sender Receiver Config",
533 sizeof(sender_receiver_config_t
), /* record size */
534 DATAFILE_FR_SENDER_RECEIVER
, /* filename */
535 true, /* from profile */
536 (void**)&sender_receiver_configs
, /* data_ptr */
537 &sender_receiver_config_num
, /* numitems_ptr */
538 UAT_AFFECTS_DISSECTION
, /* but not fields */
540 copy_sender_receiver_config_cb
, /* copy callback */
541 update_sender_receiver_config
, /* update callback */
542 free_sender_receiver_config_cb
, /* free callback */
543 post_update_sender_receiver_cb
, /* post update callback */
544 NULL
, /* reset callback */
545 sender_receiver_mapping_uat_fields
/* UAT field definitions */
548 prefs_register_uat_preference(flexray_module
, "_sender_receiver_config", "Sender Receiver Config",
549 "A table to define the mapping between Bus ID and CAN ID to Sender and Receiver.", sender_receiver_uat
);
551 subdissector_table
= register_decode_as_next_proto(proto_flexray
, "flexray.subdissector", "FLEXRAY next level dissector", NULL
);
552 flexrayid_subdissector_table
= register_dissector_table("flexray.combined_id", "FlexRay ID (combined)", proto_flexray
, FT_UINT32
, BASE_HEX
);
553 heur_subdissector_list
= register_heur_dissector_list_with_description("flexray", "FlexRay info", proto_flexray
);
557 proto_reg_handoff_flexray(void) {
558 dissector_add_uint("wtap_encap", WTAP_ENCAP_FLEXRAY
, flexray_handle
);
562 * Editor modelines - https://www.wireshark.org/tools/modelines.html
567 * indent-tabs-mode: nil
570 * vi: set shiftwidth=4 tabstop=8 expandtab:
571 * :indentSize=4:tabSize=8:noTabs=true: