diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-ebhscr.c | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-ebhscr.c')
-rw-r--r-- | epan/dissectors/packet-ebhscr.c | 1864 |
1 files changed, 1864 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ebhscr.c b/epan/dissectors/packet-ebhscr.c new file mode 100644 index 00000000..e81536f2 --- /dev/null +++ b/epan/dissectors/packet-ebhscr.c @@ -0,0 +1,1864 @@ +/* packet-ebhscr.c + * Routines for EBHSCR dissection + * Copyright 2019, Ana Pantar <ana.pantar@gmail.com> for Elektrobit + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * For more information on this protocol see: + * https://www.elektrobit.com/ebhscr + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <config.h> +#include <epan/packet.h> +#include <epan/decode_as.h> +#include <epan/prefs.h> +#include <wiretap/wtap.h> +#include <epan/expert.h> + +void proto_reg_handoff_ebhscr(void); +void proto_register_ebhscr(void); + +static int proto_ebhscr = -1; + +static int hf_ebhscr_packet_header = -1; +static int hf_ebhscr_major_number = -1; +static int hf_ebhscr_slot = -1; +static int hf_ebhscr_channel = -1; +static int hf_ebhscr_status = -1; +static int hf_ebhscr_status_unused = -1; + +static int hf_can_proto_type = -1; +static int hf_can_status_available = -1; +static int hf_can_LEC = -1; +static int hf_can_ERRP = -1; +static int hf_can_ERRW = -1; +static int hf_can_BOFF = -1; +static int hf_can_DLEC = -1; +static int hf_can_TEC = -1; +static int hf_can_REC = -1; +static int hf_can_CEL = -1; +static int hf_can_reserved_bytes = -1; + +static int hf_eth_reserved_bytes = -1; +static int hf_eth_tx_trunc = -1; +static int hf_eth_trans_undrun = -1; +static int hf_eth_retrans_limit = -1; +static int hf_eth_late_collision = -1; +static int hf_eth_link_up_down = -1; +static int hf_eth_master_slave = -1; +static int hf_eth_fcs_unavailable = -1; +static int hf_eth_rsvd_bit = -1; +static int hf_eth_speed = -1; + +static int hf_eth_crc_error = -1; +static int hf_eth_mii_foe = -1; +static int hf_eth_payload_foe = -1; +static int hf_eth_hdr_foe = -1; +static int hf_eth_rcv_dec_err = -1; +static int hf_eth_sym_error = -1; +static int hf_eth_jabber_event = -1; +static int hf_eth_pol_ch_event = -1; +static int hf_eth_fls_carrier_event = -1; +static int hf_eth_rx_trunc = -1; +static int hf_eth_transmission_disc_err = -1; +static int hf_eth_wait_frame_sep_bit = -1; + +static int hf_ts_time_offset_valid = -1; +static int hf_ts_last_offset_change_valid = -1; +static int hf_ts_nano_seconds_last_jump_valid = -1; +static int hf_ts_UTC_leap_seconds_valid = -1; +static int hf_ts_sync_state_valid = -1; +static int hf_ts_time_source = -1; + +static int hf_ts_time_offset_ns = -1; +static int hf_ts_last_offset_ns = -1; +static int hf_ts_last_jump_ns = -1; +static int hf_ts_utc_leap_sec = -1; +static int hf_ts_sync_state = -1; + +static int hf_lin_1_3_classic_chksum = -1; +static int hf_lin_1_2_enhanced_chksum = -1; +static int hf_lin_wakeup = -1; +static int hf_lin_time_jump = -1; + +static int hf_lin_reserved_bytes = -1; +static int hf_lin_wakeup_length = -1; +static int hf_lin_sts_reserved = -1; +static int hf_lin_sts_syn = -1; +static int hf_lin_sts_par = -1; +static int hf_lin_sts_res = -1; +static int hf_lin_sts_dat = -1; +static int hf_lin_sts_chk = -1; +static int hf_lin_sts_sta = -1; +static int hf_lin_sts_sto = -1; +static int hf_lin_sts_emp = -1; +static int hf_lin_payload = -1; +static int hf_lin_payload_pid = -1; +static int hf_lin_payload_id_parity_0 = -1; +static int hf_lin_payload_id_parity_1 = -1; +static int hf_lin_payload_id = -1; +static int hf_lin_payload_data = -1; +static int hf_lin_payload_checksum = -1; + +static int hf_dio_overflow_mon_unit = -1; +static int hf_dio_jump_occurred = -1; +static int hf_dio_value_type = -1; +static int hf_dio_reserved_bytes = -1; + +static int hf_flexray_ch_a = -1; +static int hf_flexray_ch_b = -1; +static int hf_flexray_ctrl_id = -1; +static int hf_flexray_monitoring_bit = -1; +static int hf_flexray_sync_bit = -1; +static int hf_flexray_packet_type = -1; +static int hf_flexray_CODERR = -1; +static int hf_flexray_TSSVIOL = -1; +static int hf_flexray_HCRCERR = -1; +static int hf_flexray_FCRCERR = -1; +static int hf_flexray_FESERR = -1; +static int hf_flexray_FSSERR = -1; +static int hf_flexray_BSSERR = -1; +static int hf_flexray_jump_occurred = -1; +static int hf_flexray_slot_information = -1; +static int hf_flexray_SBV = -1; +static int hf_flexray_ACI = -1; +static int hf_flexray_CED = -1; +static int hf_flexray_SED = -1; +static int hf_flexray_VFR = -1; +static int hf_flexray_SID = -1; +static int hf_flexray_frame_status = -1; +static int hf_flexray_SPLERR = -1; +static int hf_flexray_CCERR = -1; +static int hf_flexray_FIDERR = -1; +static int hf_flexray_SSERR = -1; +static int hf_flexray_NERR = -1; +static int hf_flexray_SOVERR = -1; +static int hf_flexray_SWVIOL = -1; +static int hf_flexray_NITVIOL = -1; +static int hf_flexray_BVIOL = -1; +static int hf_flexray_PCD = -1; +static int hf_flexray_SYNCERR = -1; +static int hf_flexray_CP = -1; +static int hf_flexray_BRC = -1; +static int hf_flexray_symbol_length_and_status = -1; +static int hf_flexray_SYERR = -1; +static int hf_flexray_SL = -1; +static int hf_flexray_POC_state = -1; +static int hf_flexray_following_cycle_counter = -1; +static int hf_flexray_supercycle_counter = -1; + +static int hf_ebhscr_version = -1; +static int hf_ebhscr_length = -1; +static int hf_ebhscr_start_timestamp = -1; +static int hf_ebhscr_stop_timestamp = -1; +static int hf_ebhscr_mjr_hdr = -1; +static int hf_ebhscr_mjr_hdr_unused = -1; + +static gint ett_ebhscr = -1; +static gint ett_ebhscr_channel = -1; +static gint ett_ebhscr_packet_header = -1; +static gint ett_ebhscr_status = -1; +static gint ett_ebhscr_mjr_hdr = -1; + +static gint ett_lin_payload = -1; + +static int * const can_status_bits[] = { + &hf_can_proto_type, + &hf_can_status_available, + NULL +}; + +static int * const can_mjr_hdr_bits[] = { + & hf_can_reserved_bytes, + & hf_can_LEC, + & hf_can_ERRP, + & hf_can_ERRW, + & hf_can_BOFF, + & hf_can_DLEC, + & hf_can_TEC, + & hf_can_REC, + & hf_can_CEL, + NULL +}; + +static const value_string can_proto_type_strings[] = { + { 0, "Classical CAN" }, + { 1, "CAN FD data frame" }, + { 0, NULL }, +}; + +static const value_string can_status_available_strings[] = { + { 0, "CAN protocol status not available" }, + { 1, "CAN protocol status available" }, + { 0, NULL }, +}; + +static const val64_string can_last_err_code_strings[] = { + { 0, "No Error" }, + { 1, "Stuff Error" }, + { 2, "Form Error" }, + { 3, "Ack Error" }, + { 4, "Bit1 Error" }, + { 5, "Bit0 Error" }, + { 6, "CRC Error" }, + { 7, "Reserved" }, + { 0, NULL }, +}; + +static const val64_string can_ERRP_strings[] = { + { 0, "Error counters are below the error passive limit (128)" }, + { 1, "One of the error counters has reached the error passive limit (128)" }, + { 0, NULL }, +}; + +static const val64_string can_ERRW_strings[] = { + { 0, "Error counters are below the error warning limit (96)" }, + { 1, "One of the error counters has reached the error warning limit (96)" }, + { 0, NULL }, +}; +static const val64_string can_BOFF_strings[] = { + { 0, "Not in Bus Off state" }, + { 1, "In Bus Off state." }, + { 0, NULL }, +}; + + +static int * const eth_rx_error_bits[] = { + &hf_eth_crc_error, + &hf_eth_mii_foe, + &hf_eth_payload_foe, + &hf_eth_hdr_foe, + &hf_eth_rcv_dec_err, + &hf_eth_sym_error, + &hf_eth_jabber_event, + &hf_eth_pol_ch_event, + &hf_eth_fls_carrier_event, + &hf_eth_rx_trunc, + &hf_eth_transmission_disc_err, + &hf_eth_wait_frame_sep_bit, + NULL +}; + +static int * const eth_mjr_hdr_bits[] = { + &hf_eth_reserved_bytes, + &hf_eth_tx_trunc, + &hf_eth_trans_undrun, + &hf_eth_retrans_limit, + &hf_eth_late_collision, + &hf_eth_link_up_down, + &hf_eth_master_slave, + &hf_eth_fcs_unavailable, + &hf_eth_rsvd_bit, + &hf_eth_speed, + NULL +}; + +static const val64_string eth_link_strings[] = { + { 0, "Link Down" }, + { 1, "Link Up" }, + { 0, NULL }, +}; + +static const val64_string eth_master_strings[] = { + { 0, "Slave" }, + { 1, "Master" }, + { 0, NULL }, +}; + +static const val64_string eth_fcs_strings[] = { + { 0, "FCS appended to payload" }, + { 1, "FCS not appended to payload." }, + { 0, NULL }, +}; + +static const val64_string eth_speed_strings[] = { + { 0, "Speed 10M" }, + { 1, "Speed 100M" }, + { 2, "Speed 1000M" }, + { 3, "Speed 2.5G" }, + { 4, "Speed 5G" }, + { 5, "Speed 10G" }, + { 6, "Speed 25G" }, + { 7, "Speed 40G" }, + { 8, "Speed 100G" }, + { 9, "Reserved" }, + { 10, "Reserved" }, + { 11, "Reserved" }, + { 12, "Reserved" }, + { 13, "Reserved" }, + { 14, "Reserved" }, + { 15, "Speed unknown. This value can be used when the speed could not be detected." }, + { 0, NULL }, +}; + +static int * const ts_status_bits[] = { + &hf_ts_time_offset_valid, + &hf_ts_last_offset_change_valid, + &hf_ts_nano_seconds_last_jump_valid, + &hf_ts_UTC_leap_seconds_valid, + &hf_ts_sync_state_valid, + NULL +}; + +static const val64_string ts_time_source_strings[] = { + { 0x00, "TimeSourceNone" }, + { 0x01, "TimeSourceEBTimesyncHard" }, + { 0x02, "TimeSourceXTSS" }, + { 0x03, "TimeSourcePTPHW" }, + { 0x10, "TimeSourcePTPSW" }, + { 0x20, "TimeSourceGPS" }, + { 0x30, "TimeSourceEBTimesyncSoft" }, + { 0x40, "TimeSourceCAN" }, + { 0x50, "TimeSourceEBVirt" }, + { 0, NULL }, +}; +static const value_string ts_sync_state_strings[] = { + { 0, "Free running" }, + { 1, "Locked to master" }, + { 0, NULL }, +}; + +static int * const lin_status_bits[] = { + &hf_lin_time_jump, + &hf_lin_wakeup, + &hf_lin_1_2_enhanced_chksum, + &hf_lin_1_3_classic_chksum, + NULL +}; + +static int * const lin_mjr_hdr_bits[] = { + + &hf_lin_wakeup_length, + &hf_lin_sts_emp, + &hf_lin_sts_sto, + &hf_lin_sts_sta, + &hf_lin_sts_chk, + &hf_lin_sts_dat, + &hf_lin_sts_res, + &hf_lin_sts_par, + &hf_lin_sts_syn, + &hf_lin_sts_reserved, + &hf_lin_reserved_bytes, + NULL +}; + +static int * const lin_payload_pid_bits[] = { + &hf_lin_payload_id, + &hf_lin_payload_id_parity_0, + &hf_lin_payload_id_parity_1, + NULL +}; + +static int * const dio_status_bits[] = { + &hf_dio_overflow_mon_unit, + &hf_dio_jump_occurred, + NULL +}; + +static int * const dio_mjr_hdr_bits[] = { + &hf_dio_value_type, + &hf_dio_reserved_bytes, + NULL +}; + +static const val64_string dio_val_type_strings[] = { + { 0, "Event triggered falling edge" }, + { 1, "Event triggered rising edge" }, + { 0, NULL }, +}; + +static int * const flexray_channel_bits[] = { + &hf_flexray_ch_a, + &hf_flexray_ch_b, + &hf_flexray_ctrl_id, + NULL +}; + +static int * const flexray_status_bits[] = { + &hf_flexray_monitoring_bit, + &hf_flexray_sync_bit, + &hf_flexray_packet_type, + &hf_flexray_jump_occurred, + NULL +}; + +static int * const flexray_frame_status_bits[] = { + &hf_flexray_monitoring_bit, + &hf_flexray_sync_bit, + &hf_flexray_packet_type, + &hf_flexray_CODERR, + &hf_flexray_TSSVIOL, + &hf_flexray_HCRCERR, + &hf_flexray_FCRCERR, + &hf_flexray_FESERR, + &hf_flexray_FSSERR, + &hf_flexray_BSSERR, + &hf_flexray_jump_occurred, + NULL +}; + +static int * const flexray_mhdr_slot_information_bits[] = { + &hf_flexray_SBV, + &hf_flexray_ACI, + &hf_flexray_CED, + &hf_flexray_SED, + &hf_flexray_VFR, + &hf_flexray_SID, + NULL +}; + +static int * const flexray_mhdr_frame_status_bits[] = { + &hf_flexray_SPLERR, + &hf_flexray_CCERR, + &hf_flexray_FIDERR, + &hf_flexray_SSERR, + &hf_flexray_NERR, + &hf_flexray_SOVERR, + &hf_flexray_SWVIOL, + &hf_flexray_NITVIOL, + &hf_flexray_BVIOL, + &hf_flexray_PCD, + &hf_flexray_SYNCERR, + &hf_flexray_CP, + &hf_flexray_BRC, + NULL +}; + +static int * const flexray_mhdr_symbol_length_and_status_bits[] = { + &hf_flexray_SYERR, + &hf_flexray_SL, + NULL +}; + +static const value_string flexray_monitoring_bit_strings[] = { + { 0x00, "Packet was generated by asynchronous monitoring" }, + { 0x01, "Packet was generated by FlexRay synchronous monitoring" }, + { 0, NULL }, +}; + +#define FLEXRAY_FRAME_PACKET 0x00 +#define FLEXRAY_SYMBOL_PACKET 0x01 +#define FLEXRAY_SLOT_STATUS_PACKET 0x02 +#define FLEXRAY_START_OF_CYCLE_PACKET 0x03 + +#define FLEXRAY_CHANNEL_B_MASK 0x02 +#define FLEXRAY_TSSVIOL_MASK 0x0020 +#define FLEXRAY_CODERR_MASK 0x0010 +#define FLEXRAY_FESERR_MASK 0x0100 +#define FLEXRAY_HCRCERR_MASK 0x0040 +#define FLEXRAY_FCRCERR_MASK 0x0080 + +static const value_string flexray_packet_type_strings[] = { + { FLEXRAY_FRAME_PACKET, "Frame" }, + { FLEXRAY_SYMBOL_PACKET, "Symbol" }, + { FLEXRAY_SLOT_STATUS_PACKET, "Slot status" }, + { FLEXRAY_START_OF_CYCLE_PACKET, "Start of cycle" }, + { 0, NULL }, +}; + +static const value_string flexray_CP_strings[] = { + { 0x00, "Static part" }, + { 0x01, "Dynamic part" }, + { 0x02, "Symbol window" }, + { 0x03, "NIT" }, + { 0, NULL }, +}; + +static const value_string flexray_POC_state_strings[] = { + { 0x00, "DEFAULT_CONFIG state" }, + { 0x01, "READY state" }, + { 0x02, "NORMAL_ACTIVE state" }, + { 0x03, "NORMAL_PASSIVE state" }, + { 0x04, "HALT state" }, + { 0x05, "MONITOR_MODE state" }, + { 0x0F, "CONFIG state" }, + { 0x10, "WAKEUP_STANDBY state" }, + { 0x11, "WAKEUP_LISTEN state" }, + { 0x12, "WAKEUP_SEND state" }, + { 0x13, "WAKEUP_DETECT state" }, + { 0x20, "STARTUP_PREPARE state" }, + { 0x21, "COLDSTART_LISTEN state" }, + { 0x22, "COLDSTART_COLLISION_RESOLUTION state" }, + { 0x23, "COLDSTART_CONSISTENCY_CHECK state" }, + { 0x24, "COLDSTART_GAP state" }, + { 0x25, "COLDSTART_JOIN state" }, + { 0x26, "INTEGRATION_COLDSTART_CHECK state" }, + { 0x27, "INTEGRATION_LISTEN state" }, + { 0x28, "INTEGRATION_CONSISTENCY_CHECK state" }, + { 0x29, "INITIALIZE_SCHEDULE state" }, + { 0x2A, "ABORT_STARTUP state" }, + { 0x2B, "STARTUP_SUCCESS state" }, + { 0, NULL }, +}; + + +static expert_field ei_ebhscr_frame_header = EI_INIT; +static expert_field ei_ebhscr_err_status_flag = EI_INIT; +static expert_field ei_ebhscr_info_status_flag = EI_INIT; + +static dissector_handle_t ebhscr_handle; + +static dissector_handle_t can_handle; +static dissector_handle_t can_fd_handle; +static dissector_handle_t eth_withfcs_handle; +static dissector_handle_t eth_withoutfcs_handle; +static dissector_handle_t flexray_handle; +static dissector_handle_t ebhscr_user_handle; + +static dissector_table_t subdissector_table; + +#define EBHSCR_USER_FIRST 0X43 +#define EBHSCR_USER_LAST 0X4F + +#define ETHERNET_FRAME 0x50 +#define NMEA_FRAME 0x51 +#define TIME_STATE_FRAME 0x52 +#define CAN_FRAME 0x53 +#define LIN_FRAME 0x55 +#define DIO_FRAME 0x56 +#define FLEXRAY_FRAME 0x57 +#define EBHSCR_HEADER_LENGTH 32 + +static int dissect_ebhscr_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, + guint32 ebhscr_frame_length) +{ + guint16 can_proto_status, can_type; + guint32 ebhscr_current_payload_length; + tvbuff_t* next_tvb; + proto_item *ti; + + ti = proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 2, hf_ebhscr_status, ett_ebhscr_status, + can_status_bits, ENC_BIG_ENDIAN); + + can_proto_status = (ebhscr_status & 0x0002); + if (can_proto_status) { + proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 24, hf_ebhscr_mjr_hdr, ett_ebhscr_mjr_hdr, + can_mjr_hdr_bits, ENC_BIG_ENDIAN); + expert_add_info(pinfo, ti, &ei_ebhscr_info_status_flag); + } + else { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + } + + /* received hdr only and no data */ + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + return tvb_captured_length(tvb); + } + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + /* payload is CAN or CAN FD frame */ + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + + can_type = (ebhscr_status & 0x0001); + + if (can_type) { + call_dissector(can_fd_handle, next_tvb, pinfo, tree); + } + else { + call_dissector(can_handle, next_tvb, pinfo, tree); + } + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, + guint32 ebhscr_frame_length) +{ + tvbuff_t* next_tvb; + proto_item *ti; + guint8 channel; + guint32 ebhscr_current_payload_length; + guint64 major_hrd, fsc_not_present, link_up, link_speed; + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + ti = proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 2, hf_ebhscr_status, + ett_ebhscr_status, eth_rx_error_bits, ENC_BIG_ENDIAN); + + if (ebhscr_status) { + expert_add_info(pinfo, ti, &ei_ebhscr_err_status_flag); + } + + channel = (tvb_get_guint8(tvb, 1) & 0x1C) >> 2; + major_hrd = tvb_get_guint64(tvb, 24, ENC_BIG_ENDIAN); + + proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 24, hf_ebhscr_mjr_hdr, ett_ebhscr_mjr_hdr, + eth_mjr_hdr_bits, ENC_BIG_ENDIAN); + + fsc_not_present = (major_hrd & 0x0000000400000000); + link_up = (major_hrd & 0x0000000100000000) ? 1 : 0; + link_speed = (major_hrd & 0x00000000F0000000) >> 28U; + /* received hdr only and no data */ + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + col_append_fstr(pinfo->cinfo, COL_INFO, "Ethernet controller %d %s", channel, val64_to_str_const(link_up, eth_link_strings, "")); + if (link_up) + { + col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val64_to_str_const(link_speed, eth_speed_strings, "Speed unknown")); + } + return tvb_captured_length(tvb); + } + /* payload is 802.3 Ethernet frame */ + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + if (fsc_not_present) { + call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree); + } + else { + call_dissector(eth_withfcs_handle, next_tvb, pinfo, tree); + } + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_nmea(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint32 ebhscr_frame_length, + guint32 ebhscr_length) +{ + tvbuff_t* next_tvb; + guint8 *nmea_str; + guint32 ebhscr_current_payload_length; + + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + return tvb_captured_length(tvb); + } + + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status_unused, tvb, 2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr_unused, tvb, 24, 8, ENC_BIG_ENDIAN); + + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + call_data_dissector(next_tvb, pinfo, tree); + nmea_str = tvb_get_string_enc(pinfo->pool, tvb, 32, ebhscr_length, ENC_UTF_8); + col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", "NMEA:", nmea_str); + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_ts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, + guint32 ebhscr_frame_length) +{ + tvbuff_t* next_tvb; + guint32 ebhscr_current_payload_length; + guint64 time_source = 0; + proto_item *ti; + + col_set_str(pinfo->cinfo, COL_INFO, "TimeState "); + ti = proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 2, hf_ebhscr_status, ett_ebhscr_status, + ts_status_bits, ENC_BIG_ENDIAN); + + if (ebhscr_status) { + expert_add_info(pinfo, ti, &ei_ebhscr_info_status_flag); + } + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint64(ebhscr_packet_header_tree, hf_ts_time_source, tvb, 24, 8, ENC_BIG_ENDIAN, &time_source); + col_append_str(pinfo->cinfo, COL_INFO, val64_to_str_const(time_source, ts_time_source_strings, "Unknown Time Source")); + + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + return tvb_captured_length(tvb); + } + + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + if (ebhscr_current_payload_length < 28) { + return tvb_captured_length(tvb); + } + + /* display params only if the appropriate valid bit is set */ + if ((ebhscr_status & 0x001) != 0) { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ts_time_offset_ns, tvb, 32, 8, ENC_BIG_ENDIAN); + } + if ((ebhscr_status & 0x002) != 0) { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ts_last_offset_ns, tvb, 40, 8, ENC_BIG_ENDIAN); + } + if ((ebhscr_status & 0x004) != 0) { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ts_last_jump_ns, tvb, 48, 8, ENC_BIG_ENDIAN); + } + if ((ebhscr_status & 0x008) != 0) { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ts_utc_leap_sec, tvb, 56, 2, ENC_BIG_ENDIAN); + } + if ((ebhscr_status & 0x010) != 0) { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ts_sync_state, tvb, 58, 2, ENC_BIG_ENDIAN); + } + + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + call_data_dissector(next_tvb, pinfo, tree); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_lin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ebhscr_tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, guint32 ebhscr_frame_length) +{ + proto_item* ti; + proto_tree *lin_payload_tree, *lin_pid_tree; + guint32 ebhscr_current_payload_length; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "LIN (EBHSCR)"); + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + ti = proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 2, hf_ebhscr_status, + ett_ebhscr_status, lin_status_bits, ENC_BIG_ENDIAN); + + if (ebhscr_status) { + expert_add_info(pinfo, ti, &ei_ebhscr_info_status_flag); + } + + if ((ebhscr_status & 0x0010) != 0) { + col_set_str(pinfo->cinfo, COL_INFO, "LIN Wake-Up Packet"); + } + else { + col_set_str(pinfo->cinfo, COL_INFO, "LIN Frame"); + } + + proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 24, hf_ebhscr_mjr_hdr, ett_ebhscr_mjr_hdr, + lin_mjr_hdr_bits, ENC_BIG_ENDIAN); + + /* received hdr only and no data */ + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + return tvb_captured_length(tvb); + } + + ti = proto_tree_add_item(ebhscr_tree, hf_lin_payload, tvb, 32, ebhscr_current_payload_length, ENC_NA); + lin_payload_tree = proto_item_add_subtree(ti, ett_lin_payload); + + ti = proto_tree_add_item(lin_payload_tree, hf_lin_payload_pid, tvb, 32, 1, ENC_BIG_ENDIAN); + lin_pid_tree = proto_item_add_subtree(ti, ett_lin_payload); + proto_tree_add_bitmask_list(lin_pid_tree, tvb, 32, 1, lin_payload_pid_bits, ENC_BIG_ENDIAN); + + proto_tree_add_item(lin_payload_tree, hf_lin_payload_data, tvb, EBHSCR_HEADER_LENGTH + 1, ebhscr_current_payload_length - 2, ENC_NA); + proto_tree_add_item(lin_payload_tree, hf_lin_payload_checksum, tvb, EBHSCR_HEADER_LENGTH + ebhscr_current_payload_length - 1, 1, ENC_BIG_ENDIAN); + + return tvb_captured_length(tvb); +} + +static int +dissect_ebhscr_dio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, guint32 ebhscr_frame_length) +{ + tvbuff_t* next_tvb; + proto_item *ti; + guint32 ebhscr_current_payload_length; + + col_set_str(pinfo->cinfo, COL_INFO, "DIO"); + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + ti = proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 2, hf_ebhscr_status, + ett_ebhscr_status, dio_status_bits, ENC_BIG_ENDIAN); + + if (ebhscr_status) { + expert_add_info(pinfo, ti, &ei_ebhscr_err_status_flag); + } + proto_tree_add_bitmask(ebhscr_packet_header_tree, tvb, 24, hf_ebhscr_mjr_hdr, ett_ebhscr_mjr_hdr, + dio_mjr_hdr_bits, ENC_BIG_ENDIAN); + + if (ebhscr_frame_length == EBHSCR_HEADER_LENGTH) { + return tvb_captured_length(tvb); + } + + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + call_data_dissector(next_tvb, pinfo, tree); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_flexray_frame_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, guint16 ebhscr_status, + guint32 ebhscr_current_payload_length) +{ + proto_item *ti; + proto_tree *flexray_mhdr_tree, *flexray_mhdr_sub_tree, *flexray_status_tree; + tvbuff_t *fr_tvb, *hdr_tvb; + guint8 channel; + guint8 header_data[2U]; + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + flexray_status_tree = proto_item_add_subtree(ti, ett_ebhscr_status); + proto_tree_add_bitmask_list(flexray_status_tree, tvb, 2, 2, flexray_frame_status_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + flexray_mhdr_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_slot_information, tvb, 24, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 24, 2, flexray_mhdr_slot_information_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_frame_status, tvb, 26, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 26, 2, flexray_mhdr_frame_status_bits, ENC_BIG_ENDIAN); + + proto_tree_add_item(flexray_mhdr_tree, hf_flexray_supercycle_counter, tvb, 28, 4, ENC_BIG_ENDIAN); + + fr_tvb = tvb_new_composite(); + + header_data[0] = 0x01; + channel = tvb_get_guint8(tvb, 1); + + if ((channel & FLEXRAY_CHANNEL_B_MASK) != 0) { + header_data[0] |= 0x80; + } + + header_data[1] = 0x00; + + if ((ebhscr_status & FLEXRAY_TSSVIOL_MASK) != 0) { + header_data[1] |= 0x01; + } + if ((ebhscr_status & FLEXRAY_CODERR_MASK) != 0) { + header_data[1] |= 0x02; + } + if ((ebhscr_status & FLEXRAY_FESERR_MASK) != 0) { + header_data[1] |= 0x04; + } + if ((ebhscr_status & FLEXRAY_HCRCERR_MASK) != 0) { + header_data[1] |= 0x08; + } + if ((ebhscr_status & FLEXRAY_FCRCERR_MASK) != 0) { + header_data[1] |= 0x10; + } + + hdr_tvb = tvb_new_real_data(header_data, 2U, 2U); + + tvb_composite_append(fr_tvb, hdr_tvb); + tvb_composite_append(fr_tvb, tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length)); + + tvb_composite_finalize(fr_tvb); + call_dissector(flexray_handle, fr_tvb, pinfo, tree); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_flexray_symbol_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree) +{ + tvbuff_t* symbol_tvb; + proto_item *ti; + proto_tree *flexray_mhdr_tree, *flexray_mhdr_sub_tree, *flexray_status_tree; + guint8 symbol_length, channel; + guint8 flexray_symbol_packet[2U]; + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + flexray_status_tree = proto_item_add_subtree(ti, ett_ebhscr_status); + proto_tree_add_bitmask_list(flexray_status_tree, tvb, 2, 2, flexray_status_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + flexray_mhdr_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_slot_information, tvb, 24, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 24, 2, flexray_mhdr_slot_information_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_frame_status, tvb, 26, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 26, 2, flexray_mhdr_frame_status_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_symbol_length_and_status, tvb, 28, 1, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 28, 1, flexray_mhdr_symbol_length_and_status_bits, ENC_BIG_ENDIAN); + + symbol_length = tvb_get_guint8(tvb, 28) & 0x7F; + + flexray_symbol_packet[0] = 0x02; + + channel = tvb_get_guint8(tvb, 1); + + if ((channel & FLEXRAY_CHANNEL_B_MASK) != 0) { + flexray_symbol_packet[0] |= 0x80; + } + + flexray_symbol_packet[1] = symbol_length; + + symbol_tvb = tvb_new_real_data(flexray_symbol_packet, 2U, 2U); + call_dissector(flexray_handle, symbol_tvb, pinfo, tree); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_flexray_slot_status_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ebhscr_packet_header_tree) +{ + guint32 supercycle_counter; + proto_item *ti; + proto_tree *flexray_mhdr_tree, *flexray_mhdr_sub_tree, *flexray_status_tree; + + supercycle_counter = tvb_get_guint32(tvb, 28, ENC_BIG_ENDIAN); + col_append_fstr(pinfo->cinfo, COL_INFO, "SLSTS: SCC %d", supercycle_counter); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + flexray_status_tree = proto_item_add_subtree(ti, ett_ebhscr_status); + proto_tree_add_bitmask_list(flexray_status_tree, tvb, 2, 2, flexray_status_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + flexray_mhdr_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_slot_information, tvb, 24, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 24, 2, flexray_mhdr_slot_information_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(flexray_mhdr_tree, hf_flexray_frame_status, tvb, 26, 2, ENC_BIG_ENDIAN); + flexray_mhdr_sub_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + proto_tree_add_bitmask_list(flexray_mhdr_sub_tree, tvb, 26, 2, flexray_mhdr_frame_status_bits, ENC_BIG_ENDIAN); + + proto_tree_add_item(flexray_mhdr_tree, hf_flexray_supercycle_counter, tvb, 28, 4, ENC_BIG_ENDIAN); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_flexray_start_of_cycle_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ebhscr_packet_header_tree) +{ + guint8 cycle_counter; + guint32 supercycle_counter; + proto_item *ti; + proto_tree *flexray_mhdr_tree, *flexray_status_tree; + + cycle_counter = tvb_get_guint8(tvb, 25); + supercycle_counter = tvb_get_guint32(tvb, 28, ENC_BIG_ENDIAN); + + col_append_fstr(pinfo->cinfo, COL_INFO, "SOC: CC %2d SCC %d", cycle_counter, supercycle_counter); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + flexray_status_tree = proto_item_add_subtree(ti, ett_ebhscr_status); + proto_tree_add_bitmask_list(flexray_status_tree, tvb, 2, 2, flexray_status_bits, ENC_BIG_ENDIAN); + + ti = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + flexray_mhdr_tree = proto_item_add_subtree(ti, ett_ebhscr_mjr_hdr); + + proto_tree_add_item(flexray_mhdr_tree, hf_flexray_POC_state, tvb, 24, 1, ENC_BIG_ENDIAN); + + proto_tree_add_item(flexray_mhdr_tree, hf_flexray_following_cycle_counter, tvb, 25, 1, ENC_BIG_ENDIAN); + + proto_tree_add_item(flexray_mhdr_tree, hf_flexray_supercycle_counter, tvb, 28, 4, ENC_BIG_ENDIAN); + + return tvb_captured_length(tvb); +} + +static int dissect_ebhscr_flexray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + proto_tree *ebhscr_packet_header_tree, proto_item *ebhscr_channel, + guint16 ebhscr_status, guint32 ebhscr_frame_length) +{ + proto_tree *flexray_channel_tree; + guint32 flexray_packet_type; + guint32 ebhscr_current_payload_length; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "FLEXRAY (EBHSCR)"); + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + flexray_channel_tree = proto_item_add_subtree(ebhscr_channel, ett_ebhscr_channel); + proto_tree_add_bitmask_list(flexray_channel_tree, tvb, 1, 1, flexray_channel_bits, ENC_BIG_ENDIAN); + + flexray_packet_type = (ebhscr_status & 0xC) >> 2U; + + if (flexray_packet_type == FLEXRAY_FRAME_PACKET) { + dissect_ebhscr_flexray_frame_packet(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_current_payload_length); + } + else if (flexray_packet_type == FLEXRAY_SYMBOL_PACKET) { + dissect_ebhscr_flexray_symbol_packet(tvb, pinfo, tree, ebhscr_packet_header_tree); + } + else if (flexray_packet_type == FLEXRAY_SLOT_STATUS_PACKET) { + dissect_ebhscr_flexray_slot_status_packet(tvb, pinfo, ebhscr_packet_header_tree); + } + else if (flexray_packet_type == FLEXRAY_START_OF_CYCLE_PACKET) { + dissect_ebhscr_flexray_start_of_cycle_packet(tvb, pinfo, ebhscr_packet_header_tree); + } + + return tvb_captured_length(tvb); +} + +static int +dissect_ebhscr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_item *ti; + proto_tree *ebhscr_packet_header_tree; + proto_tree *ebhscr_tree; + proto_tree *proto_ebhscr_channel; + tvbuff_t* next_tvb; + guint32 ebhscr_frame_length, ebhscr_length; + gint ebhscr_current_payload_length; + guint8 ebhscr_major_num; + guint16 ebhscr_status = 0; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "EBHSCR"); + col_clear(pinfo->cinfo, COL_INFO); + + ebhscr_frame_length = tvb_captured_length(tvb); + + ti = proto_tree_add_item(tree, proto_ebhscr, tvb, 0, -1, ENC_NA); + ebhscr_tree = proto_item_add_subtree(ti, ett_ebhscr); + + if (ebhscr_frame_length < EBHSCR_HEADER_LENGTH) { + expert_add_info(pinfo, ebhscr_tree, &ei_ebhscr_frame_header); + return tvb_captured_length(tvb); + } + + ebhscr_major_num = tvb_get_guint8(tvb, 0); + ebhscr_status = tvb_get_guint16(tvb, 2, ENC_BIG_ENDIAN) & 0x0FFF; + + ti = proto_tree_add_item(ebhscr_tree, hf_ebhscr_packet_header, tvb, 0, 4, ENC_BIG_ENDIAN); + ebhscr_packet_header_tree = proto_item_add_subtree(ti, ett_ebhscr_packet_header); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_major_number, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_slot, tvb, 1, 1, ENC_BIG_ENDIAN); + proto_ebhscr_channel = proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_channel, tvb, 1, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_version, tvb, 2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint(ebhscr_packet_header_tree, hf_ebhscr_length, tvb, 4, 4, ENC_BIG_ENDIAN, &ebhscr_length); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_start_timestamp, tvb, 8, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_stop_timestamp, tvb, 16, 8, ENC_BIG_ENDIAN); + + ebhscr_current_payload_length = ebhscr_frame_length - EBHSCR_HEADER_LENGTH; + + if ((ebhscr_major_num >= EBHSCR_USER_FIRST) && (ebhscr_major_num <= EBHSCR_USER_LAST)) { + if (ebhscr_user_handle != NULL) { + next_tvb = tvb_new_subset_length(tvb, 0, ebhscr_frame_length); + call_dissector(ebhscr_user_handle, next_tvb, pinfo, ebhscr_tree); + } + else { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + call_data_dissector(next_tvb, pinfo, tree); + col_append_fstr(pinfo->cinfo, COL_INFO, " %s", tvb_bytes_to_str_punct(pinfo->pool, tvb, 32, + ebhscr_current_payload_length, ' ')); + } + return tvb_captured_length(tvb); + } + + /* each dissect function handles Status and Major number specific header bits */ + if (ebhscr_major_num == CAN_FRAME) { + dissect_ebhscr_can(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_frame_length); + } + + else if (ebhscr_major_num == ETHERNET_FRAME) { + dissect_ebhscr_eth(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_frame_length); + } + + else if (ebhscr_major_num == NMEA_FRAME) + { + dissect_ebhscr_nmea(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_frame_length, ebhscr_length); + } + + else if (ebhscr_major_num == TIME_STATE_FRAME) { + dissect_ebhscr_ts(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_frame_length); + } + else if (ebhscr_major_num == LIN_FRAME) { + dissect_ebhscr_lin(tvb, pinfo, ebhscr_tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_frame_length); + } + + else if (ebhscr_major_num == DIO_FRAME) { + dissect_ebhscr_dio(tvb, pinfo, tree, ebhscr_packet_header_tree, ebhscr_status, ebhscr_frame_length); + } + + else if (ebhscr_major_num == FLEXRAY_FRAME) { + dissect_ebhscr_flexray(tvb, pinfo, tree, ebhscr_packet_header_tree, proto_ebhscr_channel, ebhscr_status, ebhscr_frame_length); + } + + else { + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_status, tvb, 2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ebhscr_packet_header_tree, hf_ebhscr_mjr_hdr, tvb, 24, 8, ENC_BIG_ENDIAN); + next_tvb = tvb_new_subset_length(tvb, 32, ebhscr_current_payload_length); + call_data_dissector(next_tvb, pinfo, tree); + } + + return tvb_captured_length(tvb); +} + +void +proto_register_ebhscr(void) +{ + expert_module_t *expert_ebhscr; + + static hf_register_info hf[] = { + { &hf_ebhscr_packet_header, + { "Packet header", "ebhscr.hdr", + FT_UINT32, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_major_number, + { "Major number", "ebhscr.mjr", + FT_UINT8, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_slot, + { "Slot", "ebhscr.slot", + FT_UINT8, BASE_HEX, + NULL, 0xc0, + NULL, HFILL } + }, + { &hf_ebhscr_channel, + { "Channel", "ebhscr.channel", + FT_UINT8, BASE_HEX, + NULL, 0x3f, + NULL, HFILL } + }, + { &hf_ebhscr_status, + { "Status", "ebhscr.sts", + FT_UINT16, BASE_HEX, + NULL, 0x0FFF, + NULL, HFILL } + }, + { &hf_ebhscr_status_unused,{ + "Status [Unused]", "ebhscr.sts.unused", + FT_UINT32, BASE_HEX, + NULL, 0x0FFF, + NULL, HFILL } + }, + { &hf_ebhscr_version, + { "Version", "ebhscr.ver", + FT_UINT16, BASE_HEX, + NULL, 0xF000, + NULL, HFILL } + }, + { &hf_ebhscr_length, + { "Length", "ebhscr.len", + FT_UINT32, BASE_DEC, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_start_timestamp, + { "Start timestamp", "ebhscr.strt", + FT_UINT64, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_stop_timestamp, + { "Stop timestamp", "ebhscr.stpt", + FT_UINT64, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_mjr_hdr, + { "Major number specific header", "ebhscr.mjrhdr", + FT_UINT64, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_ebhscr_mjr_hdr_unused, + { "Major number specific header [Unused]", "ebhscr.mjrhdr.unused", + FT_UINT64, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_can_proto_type, + { "CAN FD flag", "ebhscr.can.type", + FT_UINT16, BASE_HEX, + VALS(can_proto_type_strings), 0x0001, + NULL, HFILL } + }, + { &hf_can_status_available, + { "CAN protocol status availability", "ebhscr.can.asts", + FT_UINT16, BASE_HEX, + VALS(can_status_available_strings), 0x0002, + NULL, HFILL } + }, + { &hf_can_LEC, + { "CAN Last error code", "ebhscr.can.LEC", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + VALS64(can_last_err_code_strings), 0x0000000700000000, + NULL, HFILL } + }, + { &hf_can_ERRP, + { "CAN Counters reached Error passive limit", "ebhscr.can.errp", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + VALS64(can_ERRP_strings), 0x0000002000000000, + NULL, HFILL } + }, + { &hf_can_ERRW, + { "CAN Counters reached Error warning limit", "ebhscr.can.errw", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + VALS64(can_ERRW_strings), 0x0000004000000000, + NULL, HFILL } + }, + { &hf_can_BOFF, + { "CAN Bus Off state", "ebhscr.can.boff", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + VALS64(can_BOFF_strings), 0x0000008000000000, + NULL, HFILL } + }, + { &hf_can_DLEC, + { "CAN Data phase of CAN FD frame (with BRS flag set) last error code.", "ebhscr.can.dlec", + FT_UINT64, BASE_HEX | BASE_VAL64_STRING, + VALS64(can_last_err_code_strings), 0x0000070000000000, + NULL, HFILL } + }, + { &hf_can_TEC, + { "CAN Transmit Error Counter", "ebhscr.can.tec", + FT_UINT64, BASE_HEX, + NULL, 0x00FF000000000000, + NULL, HFILL } + }, + { &hf_can_REC, + { "CAN Receive Error Counter", "ebhscr.can.rec", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + NULL, 0x7F00000000000000, + NULL, HFILL } + }, + { &hf_can_CEL, + { "Can Error Logging Counter", "ebhscr.can.cel", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + NULL, 0x00000000000000FF, + NULL, HFILL } + }, + { &hf_can_reserved_bytes, + { "Reserved Flags", "ebhscr.can.rsv", + FT_BOOLEAN, 64, NULL, + 0x00000000FFFFFF00, + NULL, HFILL } + }, + { &hf_eth_reserved_bytes, + { "Reserved Flags", "ebhscr.eth.rsv", + FT_BOOLEAN, 64, NULL, + 0xFFF0FF00FFFFFFFF, + NULL, HFILL } + }, + { &hf_eth_link_up_down, + { "Link Up or Down", "ebhscr.eth.lud", + FT_UINT64, BASE_HEX | BASE_VAL64_STRING, + VALS64(eth_link_strings), 0x0000000100000000, + NULL, HFILL } + }, + { &hf_eth_master_slave, + { "Master or Slave (if supported)", "ebhscr.eth.ms", + FT_UINT64, BASE_HEX | BASE_VAL64_STRING, + VALS64(eth_master_strings), 0x0000000200000000, + NULL, HFILL } + }, + { &hf_eth_fcs_unavailable, + { "FCS unavailable", "ebhscr.eth.fcsua", + FT_UINT64, BASE_HEX | BASE_VAL64_STRING, + VALS64(eth_fcs_strings), 0x0000000400000000, + NULL, HFILL } + }, + { &hf_eth_rsvd_bit, + { "Reserved", "ebhscr.eth.rsvd", + FT_BOOLEAN, 64, NULL, + 0x0000000800000000, + NULL, HFILL } + }, + { &hf_eth_speed, + { "Ethernet speed", "ebhscr.eth.spd", + FT_UINT64, BASE_HEX | BASE_VAL64_STRING, + VALS64(eth_speed_strings), 0x000000F000000000, + NULL, HFILL } + }, + { &hf_eth_crc_error, + { "Ethernet CRC Error", "ebhscr.eth.crc", + FT_BOOLEAN, 16, + NULL, 0x0001, + NULL, HFILL } + }, + { &hf_eth_mii_foe, + { "Media-independent interface FIFO Overflow Error", "ebhscr.eth.miifoe", + FT_BOOLEAN, 16, + NULL, 0x0002, + NULL, HFILL } + }, + { &hf_eth_payload_foe, + { "Payload FIFO Overflow Error", "ebhscr.eth.pfoe", + FT_BOOLEAN, 16, + NULL, 0x0004, + NULL, HFILL } + }, + { &hf_eth_hdr_foe, + { "Header FIFO Overflow Error", "ebhscr.eth.hfoe", + FT_BOOLEAN, 16, + NULL, 0x0008, + NULL, HFILL } + }, + { &hf_eth_rcv_dec_err, + { "Receiver Decoder Error", "ebhscr.eth.rde", + FT_BOOLEAN, 16, + NULL, 0x0010, + NULL, HFILL } + }, + { &hf_eth_sym_error, + { "Symbol Error", "ebhscr.eth.se", + FT_BOOLEAN, 16, + NULL, 0x0020, + NULL, HFILL } + }, + { &hf_eth_jabber_event, + { "Jabber", "ebhscr.eth.jbr", + FT_BOOLEAN, 16, + NULL, 0x0040, + NULL, HFILL } + }, + { &hf_eth_pol_ch_event, + { "Polarity Change", "ebhscr.eth.pche", + FT_BOOLEAN, 16, + NULL, 0x0080, + NULL, HFILL } + }, + { &hf_eth_fls_carrier_event, + { "False Carrier", "ebhscr.eth.flsc", + FT_BOOLEAN, 16, + NULL, 0x0100, + NULL, HFILL } + }, + { &hf_eth_rx_trunc, + { "Truncation", "ebhscr.eth.rxtrc", + FT_BOOLEAN, 16, + NULL, 0x0200, + NULL, HFILL } + }, + { &hf_eth_transmission_disc_err, + { "Capture: Transmission Discarded Error, Replay: Start Frame Separation Bit", "ebhscr.eth.trdis", + FT_BOOLEAN, 16, + NULL, 0x0400, + NULL, HFILL } + }, + { &hf_eth_wait_frame_sep_bit, + { "Wait Frame Separation Bit", "ebhscr.eth.wfsb", + FT_BOOLEAN, 16, + NULL, 0x0800, + NULL, HFILL } + }, + { &hf_eth_tx_trunc, + { "If value 1 then a Truncation occurred. The frame is sent truncated.", "ebhscr.eth.trc", + FT_BOOLEAN, 64, NULL, + 0x0001000000000000, + NULL, HFILL } + }, + { &hf_eth_trans_undrun, + { "If value 1 then a Transmitter Underrun occurred.", "ebhscr.eth.trudr", + FT_BOOLEAN, 64, NULL, + 0x0002000000000000, + NULL, HFILL } + }, + { &hf_eth_retrans_limit, + { "If value 1 then the Retransmission Limit was reached", "ebhscr.eth.rtrlmt", + FT_BOOLEAN, 64, NULL, + 0x0004000000000000, + NULL, HFILL } + }, + { &hf_eth_late_collision, + { "If value 1 then a Late collision was detected.", "ebhscr.eth.ltcls", + FT_BOOLEAN, 64, NULL, + 0x0008000000000000, + NULL, HFILL } + }, + { &hf_ts_time_offset_valid, + { "Time offset in ns valid (byte 0-7)", "ebhscr.ts.tov", + FT_BOOLEAN, 16, NULL, + 0x0001, + NULL, HFILL } + }, + { &hf_ts_last_offset_change_valid, + { "Last offset change in ns valid (byte 8-15)", "ebhscr.ts.locv", + FT_BOOLEAN, 16, + NULL, 0x0002, + NULL, HFILL } + }, + { &hf_ts_nano_seconds_last_jump_valid, + { "Nano seconds last jump valid (byte 16-23)", "ebhscr.ts.nsljv", + FT_BOOLEAN, 16, + NULL, 0x0004, + NULL, HFILL } + }, + { &hf_ts_UTC_leap_seconds_valid, + { "UTC leap seconds valid (byte 24-25)", "ebhscr.ts.utclsv", + FT_BOOLEAN, 16, + NULL, 0x0008, + NULL, HFILL } + }, + { &hf_ts_sync_state_valid, + { "Sync state valid (byte 26-27)", "ebhscr.ts.ssv", + FT_BOOLEAN, 16, + NULL, 0x0010, + NULL, HFILL } + }, + { &hf_ts_time_source, + { "Time source", "ebhscr.ts.tsrc", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, VALS64(ts_time_source_strings), 0x0, + NULL, HFILL } + }, + { &hf_ts_time_offset_ns, + { "Time offset in nanoseconds", "ebhscr.ts.off", FT_UINT64, BASE_HEX, + NULL, 0, "The offset is the difference of the zero-based capture counter to TAI", HFILL } + }, + { &hf_ts_last_offset_ns, + { "Last offset change in nano seconds", "ebhscr.ts.lstoff", FT_UINT64, BASE_HEX, + NULL, 0, "Point in time of last change of time offset.", HFILL } + }, + { &hf_ts_last_jump_ns, + { "Nano seconds last jump", "ebhscr.ts.lstjmp", FT_UINT64, BASE_HEX, + NULL, 0, "Point in time of last hard change/jump of time count after the jump.", HFILL } + }, + { &hf_ts_utc_leap_sec, + { "UTC leap-seconds", "ebhscr.ts.leap", FT_UINT16, BASE_HEX, + NULL, 0, NULL, HFILL } + }, + { &hf_ts_sync_state, + { "Sync state", "ebhscr.ts.syn", FT_UINT16, BASE_HEX, + VALS(ts_sync_state_strings), 0, NULL, HFILL } + }, + { &hf_lin_1_3_classic_chksum, + { "LIN 1.3 Classic Checksum received", "ebhscr.lin.clchksum", + FT_BOOLEAN, 16, + NULL, 0x0001, + "During reception the checksum is validated to determine this bit." + "If the received checksum is invalid this bit can not be evaluated." + "Version 1.3 checksum is calculated over data bytes.", HFILL } + }, + { &hf_lin_1_2_enhanced_chksum, + { "LIN 2.0 Enhanced Checksum received", "ebhscr.lin.enchksum", + FT_BOOLEAN, 16, + NULL, 0x0002, + "During reception the checksum is validated to determine this bit." + "If the received checksum is invalid this bit can not be evaluated." + "Version 2.0 checksum is calculated over ID and data byes.", HFILL } + }, + { &hf_lin_wakeup, + { "LIN Wake-Up Packet was received", "ebhscr.lin.wakeup", + FT_BOOLEAN, 16, + NULL, 0x0010, + "A wakeup packet contains no payload (Payload length field is set to 0)." + "The wakeup length field in the major number specific header is set.", HFILL } + }, + { &hf_lin_time_jump, + { "Time jump occurred near the edge and thus the timestamp was estimated", "ebhscr.lin.timejmp", + FT_BOOLEAN, 16, + NULL, 0x0400, + "Only relevant for capture, ignored for replay.", HFILL } + }, + { &hf_lin_reserved_bytes, + { "Reserved", "ebhscr.lin.rsv", + FT_BOOLEAN, 64, NULL, + 0x00000000FFFFFFFF, + NULL, HFILL } + }, + { &hf_lin_wakeup_length, + { "Wake-Up signal low phase length in us", "ebhscr.lin.wakeup.length", + FT_UINT64, BASE_DEC, NULL, + 0xFFFF000000000000, + "Only valid if wakeup bit in status header is set. Set to 0 otherwise.", HFILL } + }, + { &hf_lin_sts_reserved, + { "Reserved bit", "ebhscr.lin.bitrsv", + FT_BOOLEAN, 64, + NULL, 0x0000000100000000, + NULL, HFILL } + }, + { &hf_lin_sts_syn, + { "SYN - Received synchronization field is not 0x55", "ebhscr.lin.syn", + FT_BOOLEAN, 64, + NULL, 0x0000000200000000, + NULL, HFILL } + }, + { &hf_lin_sts_par, + { "PAR - Received parity does not match calculated parity", "ebhscr.lin.par", + FT_BOOLEAN, 64, + NULL, 0x0000000400000000, + NULL, HFILL } + }, + { &hf_lin_sts_res, + { "RES - No response detected after LIN header", "ebhscr.lin.res", + FT_BOOLEAN, 64, + NULL, 0x0000000800000000, + NULL, HFILL } + }, + { &hf_lin_sts_dat, + { "DAT - Too many data bytes received", "ebhscr.lin.dat", + FT_BOOLEAN, 64, + NULL, 0x0000001000000000, + NULL, HFILL } + }, + { &hf_lin_sts_chk, + { "CHK - Checksum is invalid", "ebhscr.lin.chk", + FT_BOOLEAN, 64, + NULL, 0x0000002000000000, + NULL, HFILL } + }, + { &hf_lin_sts_sta, + { "STA - Expected start bit, but detected recessive bus level", "ebhscr.lin.sta", + FT_BOOLEAN, 64, + NULL, 0x0000004000000000, + NULL, HFILL } + }, + { &hf_lin_sts_sto, + { "STO - Expected stop bit, but detected recessive bus level", "ebhscr.lin.sto", + FT_BOOLEAN, 64, + NULL, 0x0000008000000000, + NULL, HFILL } + }, + { &hf_lin_sts_emp, + { "EMP - Break and Sync received, but no further data", "ebhscr.lin.emp", + FT_BOOLEAN, 64, + NULL, 0x0000010000000000, + NULL, HFILL } + }, + { &hf_lin_payload, + { "Payload", "ebhscr.lin.payload", + FT_BYTES, SEP_SPACE, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_lin_payload_pid, + { "LIN protected identifier", "ebhscr.lin.payload.pid", + FT_UINT8, BASE_HEX, + NULL, 0, + NULL, HFILL } + }, + { &hf_lin_payload_id, + { "LIN identifier", "ebhscr.lin.payload.id", + FT_UINT8, BASE_HEX, + NULL, 0x3F, + NULL, HFILL } + }, + { &hf_lin_payload_id_parity_0, + { "LIN identifier parity bit 0", "ebhscr.lin.payload.id_parity0", + FT_UINT8, BASE_HEX, + NULL, 0x40, + NULL, HFILL } + }, + { &hf_lin_payload_id_parity_1, + { "LIN identifier parity bit 1", "ebhscr.lin.payload.id_parity1", + FT_UINT8, BASE_HEX, + NULL, 0x80, + NULL, HFILL } + }, + { &hf_lin_payload_data, + { "Data", "ebhscr.lin.payload.data", + FT_BYTES, SEP_SPACE, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_lin_payload_checksum, + { "Checksum", "ebhscr.lin.payload.checksum", + FT_UINT8, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_dio_overflow_mon_unit, + { "Overflow in the monitoring unit", "ebhscr.dio.ofw_mon", + FT_BOOLEAN, 16, + NULL, 0x0001, + "Set to 1 in case of an overflow in the monitoring unit. In this case all remaining fields are invalid.", HFILL } + }, + { &hf_dio_jump_occurred, + { "Time jump occurred", "ebhscr.dio.jump_occ", + FT_BOOLEAN, 16, + NULL, 0x0400, + "Set to 1 if a time jump occurred near the edge and thus the timestamp was estimated.", HFILL } + }, + { &hf_dio_value_type, + { "Digital IO value type", "ebhscr.dio.valtype", + FT_UINT64, BASE_DEC | BASE_VAL64_STRING, + VALS64(dio_val_type_strings), 0x0100000000000000, + NULL, HFILL } + }, + { &hf_dio_reserved_bytes, + { "Reserved Flags", "ebhscr.dio.rsv", + FT_BOOLEAN, 64, NULL, + 0x00FFFFFFFFFFFFFF, + NULL, HFILL } + }, + { &hf_flexray_ch_a, + { "Channel A", "ebhscr.flexray.cha", + FT_BOOLEAN, 8, NULL, + 0x01, + NULL, HFILL} + }, + { &hf_flexray_ch_b, + { "Channel B", "ebhscr.flexray.chb", + FT_BOOLEAN, 8, NULL, + FLEXRAY_CHANNEL_B_MASK, + NULL, HFILL} + }, + { &hf_flexray_ctrl_id, + { "Controller id", "ebhscr.flexray.ctrl", + FT_UINT8, BASE_HEX, + NULL, 0x1C, + NULL, HFILL} + }, + { &hf_flexray_monitoring_bit, + { "Synchronous monitoring packet", "ebhscr.flexray.syncmon", + FT_UINT16, BASE_HEX, + VALS(flexray_monitoring_bit_strings), 0x0001, + NULL, HFILL } + }, + { &hf_flexray_sync_bit, + { "If value 1 then FlexRay cluster is sync (only valid if bit 0 = 1).", "ebhscr.flexray.sync", + FT_BOOLEAN, 16, + NULL, 0x0002, + NULL, HFILL } + }, + { &hf_flexray_packet_type, + { "FlexRay packet type", "ebhscr.flexray.pkttype", + FT_UINT16, BASE_HEX, + VALS(flexray_packet_type_strings), 0x000C, + NULL, HFILL } + }, + { &hf_flexray_CODERR, + { "Coding error", "ebhscr.flexray.coderr", + FT_BOOLEAN, 16, + NULL, FLEXRAY_CODERR_MASK, + "Indicates if a Frame Start Sequence Error (FSSERR) or a Byte Start Sequence error (BSSERR)", HFILL } + }, + { &hf_flexray_TSSVIOL, + { "TSS violation", "ebhscr.flexray.tssviol", + FT_BOOLEAN, 16, + NULL, FLEXRAY_TSSVIOL_MASK, + NULL, HFILL } + }, + { &hf_flexray_HCRCERR, + { "Header CRC error", "ebhscr.flexray.hcrcerr", + FT_BOOLEAN, 16, + NULL, FLEXRAY_HCRCERR_MASK, + NULL, HFILL } + }, + { &hf_flexray_FCRCERR, + { "Frame CRC error", "ebhscr.flexray.fcrcerr", + FT_BOOLEAN, 16, + NULL, FLEXRAY_FCRCERR_MASK, + NULL, HFILL } + }, + { &hf_flexray_FESERR, + { "Frame end sequence error", "ebhscr.flexray.feserr", + FT_BOOLEAN, 16, + NULL, FLEXRAY_FESERR_MASK, + NULL, HFILL } + }, + { &hf_flexray_FSSERR, + { "Frame start sequence error", "ebhscr.flexray.fsserr", + FT_BOOLEAN, 16, + NULL, 0x0200, + NULL, HFILL } + }, + { &hf_flexray_BSSERR, + { "Byte start sequence error", "ebhscr.flexray.bsserr", + FT_BOOLEAN, 16, + NULL, 0x0400, + NULL, HFILL } + }, + { &hf_flexray_jump_occurred, + { "Time jump occurred", "ebhscr.flexray.jump_occ", + FT_BOOLEAN, 16, + NULL, 0x0800, + "Set to 1 if a time jump occurred near the edge and thus the timestamp was estimated.", HFILL } + }, + { &hf_flexray_slot_information, + { "Slot information", "ebhscr.flexray.slotinfo", + FT_UINT16, BASE_HEX, + NULL, 0, + NULL, HFILL } + }, + { &hf_flexray_SBV, + { "Slot boundary violation", "ebhscr.flexray.slotinfo.sbv", + FT_BOOLEAN, 16, + NULL, 0x8000, + NULL, HFILL } + }, + { &hf_flexray_ACI, + { "Additional communication indicator", "ebhscr.flexray.slotinfo.aci", + FT_BOOLEAN, 16, + NULL, 0x4000, + NULL, HFILL } + }, + { &hf_flexray_CED, + { "Content error detected", "ebhscr.flexray.slotinfo.ced", + FT_BOOLEAN, 16, + NULL, 0x2000, + NULL, HFILL } + }, + { &hf_flexray_SED, + { "Syntax error detected", "ebhscr.flexray.slotinfo.sed", + FT_BOOLEAN, 16, + NULL, 0x1000, + NULL, HFILL } + }, + { &hf_flexray_VFR, + { "Valid Frame Received", "ebhscr.flexray.slotinfo.vfr", + FT_BOOLEAN, 16, + NULL, 0x0800, + NULL, HFILL } + }, + { &hf_flexray_SID, + { "Slot ID", "ebhscr.flexray.slotinfo.sid", + FT_UINT16, BASE_HEX, + NULL, 0x07FF, + NULL, HFILL } + }, + { &hf_flexray_frame_status, + { "Frame status", "ebhscr.flexray.framests", + FT_UINT16, BASE_HEX, + NULL, 0, + NULL, HFILL } + }, + { &hf_flexray_SPLERR, + { "Static payload length error", "ebhscr.flexray.framests.splerr", + FT_BOOLEAN, 16, + NULL, 0x8000, + NULL, HFILL } + }, + { &hf_flexray_CCERR, + { "Cycle counter error", "ebhscr.flexray.framests.ccerr", + FT_BOOLEAN, 16, + NULL, 0x4000, + NULL, HFILL } + }, + { &hf_flexray_FIDERR, + { "Frame ID error", "ebhscr.flexray.framests.fiderr", + FT_BOOLEAN, 16, + NULL, 0x2000, + NULL, HFILL } + }, + { &hf_flexray_SSERR, + { "Sync or startup error", "ebhscr.flexray.framests.sserr", + FT_BOOLEAN, 16, + NULL, 0x1000, + NULL, HFILL } + }, + { &hf_flexray_NERR, + { "Null frame error", "ebhscr.flexray.framests.nerr", + FT_BOOLEAN, 16, + NULL, 0x0800, + NULL, HFILL } + }, + { &hf_flexray_SOVERR, + { "Slot overbooked error", "ebhscr.flexray.framests.soverr", + FT_BOOLEAN, 16, + NULL, 0x0400, + NULL, HFILL } + }, + { &hf_flexray_SWVIOL, + { "Symbol Window violation", "ebhscr.flexray.framests.swviol", + FT_BOOLEAN, 16, + NULL, 0x0200, + NULL, HFILL } + }, + { &hf_flexray_NITVIOL, + { "NIT violation", "ebhscr.flexray.framests.nitviol", + FT_BOOLEAN, 16, + NULL, 0x0100, + NULL, HFILL } + }, + { &hf_flexray_BVIOL, + { "Boundary violation", "ebhscr.flexray.framests.bviol", + FT_BOOLEAN, 16, + NULL, 0x0080, + NULL, HFILL } + }, + { &hf_flexray_PCD, + { "Prolonged channel idle detection", "ebhscr.flexray.framests.pcd", + FT_BOOLEAN, 16, + NULL, 0x0040, + "FES to CHIRP took longer than 11 bit times. This is always true for dynamic frames because of the DTS.", HFILL } + }, + { &hf_flexray_SYNCERR, + { "Sync and/or startup bit wrongly set", "ebhscr.flexray.framests.syncerr", + FT_BOOLEAN, 16, + NULL, 0x0020, + NULL, HFILL } + }, + { &hf_flexray_CP, + { "Communication cycle part", "ebhscr.flexray.framests.cp", + FT_UINT16, BASE_HEX, + VALS(flexray_CP_strings), 0x0018, + NULL, HFILL } + }, + { &hf_flexray_BRC, + { "Byte Received Counter", "ebhscr.flexray.framests.brc", + FT_UINT16, BASE_HEX, + NULL, 0x0007, + "Number of bytes received by the decoder without coding error. When more than 7 bytes are received, the counter is set to 7", HFILL } + }, + { &hf_flexray_symbol_length_and_status, + { "Symbol length and status", "ebhscr.flexray.slsts", + FT_UINT8, BASE_HEX, + NULL, 0, + NULL, HFILL } + }, + { &hf_flexray_SYERR, + { "The low phase was too long", "ebhscr.flexray.slsts.syerr", + FT_BOOLEAN, 8, + NULL, 0x80, + NULL, HFILL } + }, + { &hf_flexray_SL, + { "Symbol length in units of bit cells", "ebhscr.flexray.slsts.sl", + FT_UINT8, BASE_DEC, + NULL, 0x7F, + NULL, HFILL } + }, + { &hf_flexray_POC_state, + { "Protocol operation control state", "ebhscr.flexray.pocstate", + FT_UINT8, BASE_HEX, + VALS(flexray_POC_state_strings), 0, + NULL, HFILL } + }, + { &hf_flexray_following_cycle_counter, + { "Cycle counter of following cycle", "ebhscr.flexray.fcc", + FT_UINT8, BASE_DEC, + NULL, 0, + NULL, HFILL } + }, + { &hf_flexray_supercycle_counter, + { "Supercycle counter", "ebhscr.flexray.scc", + FT_UINT32, BASE_DEC, + NULL, 0, + NULL, HFILL } + }, + }; + + static gint *ett[] = { + &ett_ebhscr, + &ett_ebhscr_channel, + &ett_ebhscr_packet_header, + &ett_ebhscr_status, + &ett_ebhscr_mjr_hdr, + &ett_lin_payload, + }; + + static ei_register_info ei[] = { + { &ei_ebhscr_frame_header, + { "ebhscr.frame_header", PI_MALFORMED, PI_ERROR, + "Frame Header is malformed", EXPFILL } + }, + { &ei_ebhscr_err_status_flag, + { "ebhscr.sts.err.status", PI_PROTOCOL, PI_WARN, + "Status Flag is set", EXPFILL } + }, + { &ei_ebhscr_info_status_flag, + { "ebhscr.sts.info.status", PI_PROTOCOL, PI_CHAT, + "Status Flag is set", EXPFILL } + }, + }; + + proto_ebhscr = proto_register_protocol("EBHSCR Protocol", "EBHSCR", "ebhscr"); + + proto_register_field_array(proto_ebhscr, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + expert_ebhscr = expert_register_protocol(proto_ebhscr); + expert_register_field_array(expert_ebhscr, ei, array_length(ei)); + + ebhscr_handle = register_dissector("ebhscr", dissect_ebhscr, proto_ebhscr); + subdissector_table = register_decode_as_next_proto(proto_ebhscr, "ebhscr.subdissector", + "ebhscr next level dissector", NULL); +} + +void +proto_reg_handoff_ebhscr(void) +{ + can_handle = find_dissector_add_dependency("can-hostendian", proto_ebhscr); + can_fd_handle = find_dissector_add_dependency("canfd", proto_ebhscr); + + eth_withfcs_handle = find_dissector_add_dependency("eth_withfcs", proto_ebhscr); + eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_ebhscr); + ebhscr_user_handle = find_dissector_add_dependency("ebhscr_user", proto_ebhscr); + + flexray_handle = find_dissector_add_dependency("flexray", proto_ebhscr); + + dissector_add_uint("wtap_encap", WTAP_ENCAP_EBHSCR, ebhscr_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=false: + */ |