Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-tecmp.c
blob2ca6ce30dbc43ead11476e6781d26885eb641b8b
1 /* packet-tecmp.c
2 * Technically Enhanced Capture Module Protocol (TECMP) dissector.
3 * By <lars.voelker@technica-engineering.de>
4 * Copyright 2019-2024 Dr. Lars Voelker
5 * Copyright 2020 Ayoub Kaanich
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 * This is a dissector for the Technically Enhanced Capture Module Protocol (TECMP).
16 * A new automotive protocol to carry data from a so called Capture Module (CM),
17 * which is somewhat similar to active network tap, towards a logger or PC to
18 * record or analyze the captured data.
19 * Capture Modules capture data of LIN, CAN, FlexRay, Ethernet, RS232, or other sources.
22 #include <config.h>
23 #include <epan/packet.h>
24 #include <epan/etypes.h>
25 #include <epan/expert.h>
26 #include <epan/uat.h>
27 #include <epan/proto_data.h>
28 #include <epan/tfs.h>
29 #include <epan/unit_strings.h>
31 #include <wsutil/array.h>
32 #include <wsutil/utf8_entities.h>
34 #include "packet-tecmp.h"
35 #include "packet-socketcan.h"
36 #include "packet-flexray.h"
37 #include "packet-lin.h"
40 void proto_register_tecmp(void);
41 void proto_reg_handoff_tecmp(void);
42 void proto_register_tecmp_payload(void);
43 void proto_reg_handoff_tecmp_payload(void);
45 static dissector_handle_t tecmp_handle;
47 static int proto_tecmp;
48 static int proto_tecmp_payload;
50 static dissector_handle_t eth_handle;
51 static int proto_vlan;
53 static bool heuristic_first;
54 static bool analog_samples_are_signed_int = true;
55 static bool show_ethernet_in_tecmp_tree;
56 static bool detect_asam_cmp = true;
57 static bool detect_asam_cmp_ignore_user_defined = true;
59 static dissector_table_t lin_subdissector_table;
60 static dissector_table_t data_subdissector_table;
61 static dissector_table_t data_type_subdissector_table;
62 static dissector_handle_t text_lines_handle;
64 /* Header fields */
65 /* TECMP */
66 static int hf_tecmp_device_id;
67 static int hf_tecmp_counter;
68 static int hf_tecmp_version;
69 static int hf_tecmp_msgtype;
70 static int hf_tecmp_data_type;
71 static int hf_tecmp_res;
73 static int hf_tecmp_flags;
74 static int hf_tecmp_flags_eos;
75 static int hf_tecmp_flags_sos;
76 static int hf_tecmp_flags_spy;
77 static int hf_tecmp_flags_multi_frame;
78 static int hf_tecmp_flags_dev_overflow;
80 /* TECMP Payload */
81 static int hf_tecmp_payload_interface_id;
82 static int hf_tecmp_payload_interface_name;
83 static int hf_tecmp_payload_timestamp;
84 static int hf_tecmp_payload_timestamp_ns;
85 static int hf_tecmp_payload_timestamp_async;
86 static int hf_tecmp_payload_timestamp_res;
87 static int hf_tecmp_payload_length;
88 static int hf_tecmp_payload_data;
89 static int hf_tecmp_payload_data_length;
90 static int hf_tecmp_payload_samples;
92 /* TECMP Payload flags */
93 /* Generic */
94 static int hf_tecmp_payload_data_flags;
95 static int hf_tecmp_payload_data_flags_crc;
96 static int hf_tecmp_payload_data_flags_checksum;
97 static int hf_tecmp_payload_data_flags_tx;
98 static int hf_tecmp_payload_data_flags_overflow;
100 /* ILaS*/
101 static int hf_tecmp_payload_data_flags_crc_enabled;
102 static int hf_tecmp_payload_data_flags_direction;
104 /* Ethernet Raw */
105 static int hf_tecmp_payload_data_ethernet_raw_data;
106 static int hf_tecmp_payload_data_ethernet_raw_preamble;
107 static int hf_tecmp_payload_data_ethernet_raw_sfd;
108 static int hf_tecmp_payload_data_ethernet_raw_eth_frame;
110 /* Ethernet 10BASE-T1S */
111 static int hf_tecmp_payload_data_flags_phy_event_error;
113 /* LIN */
114 static int hf_tecmp_payload_data_flags_coll;
115 static int hf_tecmp_payload_data_flags_parity;
116 static int hf_tecmp_payload_data_flags_no_resp;
117 static int hf_tecmp_payload_data_flags_wup;
118 static int hf_tecmp_payload_data_flags_short_wup;
119 static int hf_tecmp_payload_data_flags_sleep;
121 /* CAN and CAN-FD DATA */
122 static int hf_tecmp_payload_data_flags_ack;
123 static int hf_tecmp_payload_data_flags_rtr; /* CAN DATA only */
124 static int hf_tecmp_payload_data_flags_esi; /* CAN-FD DATA only */
125 static int hf_tecmp_payload_data_flags_ide;
126 static int hf_tecmp_payload_data_flags_err;
127 static int hf_tecmp_payload_data_flags_brs; /* CAN-FD DATA only */
129 static int hf_tecmp_payload_data_flags_can_bit_stuff_err;
130 static int hf_tecmp_payload_data_flags_can_crc_del_err;
131 static int hf_tecmp_payload_data_flags_can_ack_del_err;
132 static int hf_tecmp_payload_data_flags_can_eof_err;
133 static int hf_tecmp_payload_data_flags_canfd_bit_stuff_err;
134 static int hf_tecmp_payload_data_flags_canfd_crc_del_err;
135 static int hf_tecmp_payload_data_flags_canfd_ack_del_err;
136 static int hf_tecmp_payload_data_flags_canfd_eof_err;
138 /* FlexRay */
139 static int hf_tecmp_payload_data_flags_nf;
140 static int hf_tecmp_payload_data_flags_sf;
141 static int hf_tecmp_payload_data_flags_sync;
142 static int hf_tecmp_payload_data_flags_wus;
143 static int hf_tecmp_payload_data_flags_ppi;
144 static int hf_tecmp_payload_data_flags_cas;
145 static int hf_tecmp_payload_data_flags_header_crc_err;
146 static int hf_tecmp_payload_data_flags_frame_crc_err;
148 /* UART/RS232 ASCII*/
149 static int hf_tecmp_payload_data_flags_dl;
150 static int hf_tecmp_payload_data_flags_parity_error;
152 /* Analog */
153 static int hf_tecmp_payload_data_flags_sample_time;
154 static int hf_tecmp_payload_data_flags_factor;
155 static int hf_tecmp_payload_data_flags_unit;
156 static int hf_tecmp_payload_data_flags_threshold_u;
157 static int hf_tecmp_payload_data_flags_threshold_o;
159 /* Special TX Data Flags */
160 static int hf_tecmp_payload_data_flags_use_crc_value;
161 static int hf_tecmp_payload_data_flags_use_header_crc_value;
162 static int hf_tecmp_payload_data_flags_use_checksum_value;
163 static int hf_tecmp_payload_data_flags_use_parity_bits;
164 static int hf_tecmp_payload_data_flags_tx_mode;
166 static const unit_name_string tecmp_units_amp_hour = { "Ah", NULL };
168 #define TECMP_DATAFLAGS_FACTOR_MASK 0x0180
169 #define TECMP_DATAFLAGS_FACTOR_SHIFT 7
170 #define TECMP_DATAFLAGS_UNIT_MASK 0x001c
171 #define TECMP_DATAFLAGS_UNIT_SHIFT 2
173 /* TECMP Payload Fields */
174 /* Ethernet 10BASE-T1S */
175 static int hf_tecmp_payload_data_beacon_timestamp;
176 static int hf_tecmp_payload_data_beacon_timestamp_ns;
177 static int hf_tecmp_payload_data_beacon_to_timestamp_ns;
179 /* LIN */
180 static int hf_tecmp_payload_data_id_field_8bit;
181 static int hf_tecmp_payload_data_id_field_6bit;
182 static int hf_tecmp_payload_data_parity_bits;
183 static int hf_tecmp_payload_data_checksum_8bit;
185 /* CAN DATA / CAN-FD DATA */
186 static int hf_tecmp_payload_data_id_field_32bit;
187 static int hf_tecmp_payload_data_id_type;
188 static int hf_tecmp_payload_data_id_11;
189 static int hf_tecmp_payload_data_id_29;
190 static int hf_tecmp_payload_data_crc15;
191 static int hf_tecmp_payload_data_crc17;
192 static int hf_tecmp_payload_data_crc21;
194 /* FlexRay DATA */
195 static int hf_tecmp_payload_data_cycle;
196 static int hf_tecmp_payload_data_frame_id;
197 static int hf_tecmp_payload_data_header_crc;
198 static int hf_tecmp_payload_data_frame_crc;
200 /* Analog */
201 static int hf_tecmp_payload_data_analog_value_raw;
202 static int hf_tecmp_payload_data_analog_value_raw_signed;
203 static int hf_tecmp_payload_data_analog_value_volt;
204 static int hf_tecmp_payload_data_analog_value_amp;
205 static int hf_tecmp_payload_data_analog_value_watt;
206 static int hf_tecmp_payload_data_analog_value_amp_hour;
207 static int hf_tecmp_payload_data_analog_value_celsius;
209 /* Analog Alt */
210 static int hf_tecmp_payload_analog_alt_flags;
211 static int hf_tecmp_payload_analog_alt_flag_sample_dt;
212 static int hf_tecmp_payload_analog_alt_flag_reserved;
214 static int hf_tecmp_payload_analog_alt_reserved;
215 static int hf_tecmp_payload_analog_alt_unit;
216 static int hf_tecmp_payload_analog_alt_sample_interval;
217 static int hf_tecmp_payload_analog_alt_sample_offset;
218 static int hf_tecmp_payload_analog_alt_sample_scalar;
219 static int hf_tecmp_payload_analog_alt_sample_raw;
220 static int hf_tecmp_payload_analog_alt_sample;
222 /* ILaS */
223 static int hf_tecmp_payload_data_ilas_decoded_command;
224 static int hf_tecmp_payload_data_ilas_decoded_address;
225 static int hf_tecmp_payload_data_ilas_decoded_data;
226 static int hf_tecmp_payload_data_ilas_raw_sdu;
227 static int hf_tecmp_payload_data_ilas_raw_crc;
229 /* TECMP Status Messages */
230 /* Status Device */
231 static int hf_tecmp_payload_status_vendor_id;
232 static int hf_tecmp_payload_status_dev_version;
233 static int hf_tecmp_payload_status_dev_type;
234 static int hf_tecmp_payload_status_res;
235 static int hf_tecmp_payload_status_length_vendor_data;
236 static int hf_tecmp_payload_status_device_id;
237 static int hf_tecmp_payload_status_sn;
238 static int hf_tecmp_payload_status_vendor_data;
240 /* Status Bus */
241 static int hf_tecmp_payload_status_bus_data;
242 static int hf_tecmp_payload_status_bus_data_entry;
243 static int hf_tecmp_payload_status_bus_interface_id;
244 static int hf_tecmp_payload_status_bus_total;
245 static int hf_tecmp_payload_status_bus_errors;
247 /* Status Device Vendor Data Technica Engineering */
248 static int hf_tecmp_payload_status_dev_vendor_technica_res;
249 static int hf_tecmp_payload_status_dev_vendor_technica_sw;
250 static int hf_tecmp_payload_status_dev_vendor_technica_hw;
251 static int hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level;
252 static int hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow;
253 static int hf_tecmp_payload_status_dev_vendor_technica_buffer_size;
254 static int hf_tecmp_payload_status_dev_vendor_technica_lifecycle;
255 static int hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start;
256 static int hf_tecmp_payload_status_dev_vendor_technica_voltage;
257 static int hf_tecmp_payload_status_dev_vendor_technica_temperature;
258 static int hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis;
259 static int hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon;
261 #define VENDOR_TECHNICA_TEMP_MAX 127
262 #define VENDOR_TECHNICA_TEMP_NA -128
264 /* Status Bus Vendor Data Technica Engineering */
265 static int hf_tecmp_payload_status_bus_vendor_technica_link_status;
266 static int hf_tecmp_payload_status_bus_vendor_technica_link_quality;
267 static int hf_tecmp_payload_status_bus_vendor_technica_linkup_time;
269 static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags;
270 static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beacons_received;
271 static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_enabled;
272 static int hf_tecmp_payload_status_bus_vendor_technica_res0;
273 static int hf_tecmp_payload_status_bus_vendor_technica_beacon_counter;
274 static int hf_tecmp_payload_status_bus_vendor_technica_res1;
275 static int hf_tecmp_payload_status_bus_vendor_technica_res2;
276 static int hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt;
277 static int hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt;
278 static int hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_detected_cnt;
279 static int hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_missing_cnt;
280 static int hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_empty_cycle_cnt;
283 /* Status Configuration Data Technica Engineering */
284 static int hf_tecmp_payload_status_cfg_vendor_technica_version;
285 static int hf_tecmp_payload_status_cfg_vendor_technica_reserved;
286 static int hf_tecmp_payload_status_cfg_vendor_technica_msg_id;
287 static int hf_tecmp_payload_status_cfg_vendor_technica_total_length;
288 static int hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg;
289 static int hf_tecmp_payload_status_cfg_vendor_technica_segment_num;
290 static int hf_tecmp_payload_status_cfg_vendor_technica_segment_length;
291 static int hf_tecmp_payload_status_cfg_vendor_technica_segment_data;
293 /* TECMP Control Message */
294 static int hf_tecmp_payload_ctrl_msg_device_id;
295 static int hf_tecmp_payload_ctrl_msg_id;
296 static int hf_tecmp_payload_ctrl_msg_unparsed_bytes;
297 static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level;
298 static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow;
299 static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size;
300 static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_length;
301 static int hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id;
302 static int hf_tecmp_payload_ctrl_msg_flexray_poc_state;
303 static int hf_tecmp_payload_ctrl_msg_10baset1s_interface_id;
304 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags;
305 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received;
306 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled;
307 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved;
308 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events;
309 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error;
310 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error;
311 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detected;
312 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_missing;
313 static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle;
315 /* Counter Event */
316 static int hf_tecmp_payload_counter_event_device_id;
317 static int hf_tecmp_payload_counter_event_interface_id;
318 static int hf_tecmp_payload_counter_event_counter_last;
319 static int hf_tecmp_payload_counter_event_counter_cur;
321 /* TimeSync Event */
322 static int hf_tecmp_payload_timesync_event_device_id;
323 static int hf_tecmp_payload_timesync_event_interface_id;
324 static int hf_tecmp_payload_timesync_event_reserved;
325 static int hf_tecmp_payload_timesync_event_async;
326 static int hf_tecmp_payload_timesync_event_time_delta;
329 /* protocol tree items */
330 static int ett_tecmp;
331 static int ett_tecmp_flags;
333 static int ett_tecmp_payload;
334 static int ett_tecmp_payload_interface_id;
335 static int ett_tecmp_payload_data;
336 static int ett_tecmp_payload_timestamp;
337 static int ett_tecmp_payload_dataflags;
338 static int ett_tecmp_payload_instruction_address;
339 static int ett_tecmp_payload_data_id;
340 static int ett_tecmp_payload_lin_id;
341 static int ett_tecmp_payload_analog_alt_flags;
342 static int ett_tecmp_payload_analog_alt_sample;
343 static int ett_tecmp_payload_eth_raw;
344 static int ett_tecmp_payload_eth_raw_frame;
345 static int ett_tecmp_status_bus_data;
346 static int ett_tecmp_status_bus_data_entry;
347 static int ett_tecmp_status_dev_vendor_data;
348 static int ett_tecmp_status_bus_vendor_data;
349 static int ett_tecmp_status_bus_vendor_data_flags;
350 static int ett_tecmp_ctrl_message_10baset1s_flags;
351 static int ett_tecmp_ctrl_message_10baset1s_events_errors;
353 /* dissector handle to hand off to ASAM CMP (successor protocol) */
354 static dissector_handle_t asam_cmp_handle;
356 /*** expert info items ***/
357 static expert_field ei_tecmp_payload_length_mismatch;
358 static expert_field ei_tecmp_payload_header_crc_overflow;
360 /* TECMP Type Names */
362 #define TECMP_MSG_TYPE_CTRL_MSG 0x00
363 #define TECMP_MSG_TYPE_STATUS_DEV 0x01
364 #define TECMP_MSG_TYPE_STATUS_BUS 0x02
365 #define TECMP_MSG_TYPE_LOG_STREAM 0x03
366 #define TECMP_MSG_TYPE_CFG_CM 0x04
367 #define TECMP_MSG_TYPE_REPLAY_DATA 0x0A
368 #define TECMP_MSG_TYPE_COUNTER_EVENT 0x0B
369 #define TECMP_MSG_TYPE_TIMESYNC_EVENT 0x0C
372 /* TECMP Type Names */
373 /* Updated by ID Registry */
374 static const value_string msg_type_names[] = {
375 {TECMP_MSG_TYPE_CTRL_MSG, "Control Message"},
376 {TECMP_MSG_TYPE_STATUS_DEV, "Status Device"},
377 {TECMP_MSG_TYPE_STATUS_BUS, "Status Bus"},
378 {TECMP_MSG_TYPE_LOG_STREAM, "Logging Stream"},
379 {TECMP_MSG_TYPE_CFG_CM, "Status Configuration"},
380 {TECMP_MSG_TYPE_REPLAY_DATA, "Replay Data"},
381 {TECMP_MSG_TYPE_COUNTER_EVENT, "Counter Event"},
382 {TECMP_MSG_TYPE_TIMESYNC_EVENT, "TimeSync Event"},
383 {0, NULL}
386 /* TECMP Message Type Names */
387 /* Updated by ID Registry */
388 #define TECMP_DATA_TYPE_NONE 0x0000
389 #define TECMP_DATA_TYPE_CAN_RAW 0x0001
390 #define TECMP_DATA_TYPE_CAN_DATA 0x0002
391 #define TECMP_DATA_TYPE_CAN_FD_DATA 0x0003
392 #define TECMP_DATA_TYPE_LIN 0x0004
393 #define TECMP_DATA_TYPE_FR_RAW 0x0007
394 #define TECMP_DATA_TYPE_FR_DATA 0x0008
395 #define TECMP_DATA_TYPE_GPIO 0x000A
396 #define TECMP_DATA_TYPE_ILAS 0x000E
397 #define TECMP_DATA_TYPE_RS232_ASCII 0x0010
398 #define TECMP_DATA_TYPE_RS232_RAW 0x0011
399 #define TECMP_DATA_TYPE_RS232_SLA 0x0012
400 #define TECMP_DATA_TYPE_ANALOG 0x0020
401 #define TECMP_DATA_TYPE_ANALOG_SLA 0x0021
402 #define TECMP_DATA_TYPE_ANALOG_ALT 0x0028
403 #define TECMP_DATA_TYPE_ETH 0x0080
404 #define TECMP_DATA_TYPE_ETH_RAW 0x0081
405 #define TECMP_DATA_TYPE_ETH_10BASE_T1S 0x0082
406 #define TECMP_DATA_TYPE_XCP_DATA 0x00A0
407 #define TECMP_DATA_TYPE_MIPI_CSI2_V 0x0101
408 #define TECMP_DATA_TYPE_MIPI_CSI2_L 0x0102
409 #define TECMP_DATA_TYPE_SPI 0x0103
410 #define TECMP_DATA_TYPE_I2C_7BIT 0x0104
411 #define TECMP_DATA_TYPE_TAPI 0x0200
412 #define TECMP_DATA_TYPE_TAPI_INIT_STATE 0x0201
413 #define TECMP_DATA_TYPE_TAPI_CORE_DUMP 0x0202
414 #define TECMP_DATA_TYPE_R 0x0400
415 #define TECMP_DATA_TYPE_TECMP_RAW 0xA000
416 #define TECMP_DATA_TYPE_PRE_LABEL 0xB000
418 static const value_string tecmp_msgtype_names[] = {
419 {TECMP_DATA_TYPE_NONE, "None (Undefined)"},
420 {TECMP_DATA_TYPE_CAN_RAW, "CAN(-FD) Raw"},
421 {TECMP_DATA_TYPE_CAN_DATA, "CAN Data"},
422 {TECMP_DATA_TYPE_CAN_FD_DATA, "CAN-FD Data"},
423 {TECMP_DATA_TYPE_LIN, "LIN"},
424 {TECMP_DATA_TYPE_FR_RAW, "Flexray Raw"},
425 {TECMP_DATA_TYPE_FR_DATA, "Flexray Data"},
426 {TECMP_DATA_TYPE_GPIO, "GPIO"},
427 {TECMP_DATA_TYPE_ILAS, "ILaS"},
428 {TECMP_DATA_TYPE_RS232_ASCII, "UART/RS232_ASCII"},
429 {TECMP_DATA_TYPE_RS232_RAW, "UART/RS232_RAW"},
430 {TECMP_DATA_TYPE_RS232_SLA, "UART/RS232_SLA"},
431 {TECMP_DATA_TYPE_ANALOG, "Analog"},
432 {TECMP_DATA_TYPE_ANALOG_SLA, "Analog_SLA"},
433 {TECMP_DATA_TYPE_ANALOG_ALT, "Analog Alternative"},
434 {TECMP_DATA_TYPE_ETH, "Ethernet II"},
435 {TECMP_DATA_TYPE_ETH_RAW, "Ethernet Raw"},
436 {TECMP_DATA_TYPE_ETH_10BASE_T1S, "Ethernet 10BASE-T1S"},
437 {TECMP_DATA_TYPE_XCP_DATA, "XCP-Data"},
438 {TECMP_DATA_TYPE_MIPI_CSI2_V, "MIPI-CSI2 V"},
439 {TECMP_DATA_TYPE_MIPI_CSI2_L, "MIPI-CSI2 L"},
440 {TECMP_DATA_TYPE_SPI, "SPI"},
441 {TECMP_DATA_TYPE_I2C_7BIT, "I2C 7 Bit"},
442 {TECMP_DATA_TYPE_TAPI, "TAPI"},
443 {TECMP_DATA_TYPE_TAPI_INIT_STATE, "TAPI Initial State"},
444 {TECMP_DATA_TYPE_TAPI_CORE_DUMP, "TAPI Core Dump"},
445 {TECMP_DATA_TYPE_R, "R"},
446 {TECMP_DATA_TYPE_TECMP_RAW, "TECMP_Raw"},
447 {TECMP_DATA_TYPE_PRE_LABEL, "PreLabel"},
448 {0, NULL}
451 /* Vendor IDs */
452 /* Updated by ID Registry */
453 #define TECMP_VENDOR_ID_TECHNICA 0x0c
454 static const value_string tecmp_vendor_ids[] = {
455 {TECMP_VENDOR_ID_TECHNICA, "Technica Engineering"},
456 {0, NULL}
459 /* Device IDs */
460 /* Can be overwritten/extended by config */
461 static const value_string tecmp_device_id_prefixes[] = {
462 {0x0030, "CM LIN Combo"},
463 {0x0040, "CM CAN Combo"},
464 {0x0060, "CM 100 High"},
465 {0x0080, "CM Eth Combo"},
466 {0x0090, "CM 1000 High"},
467 {0x00e0, "CM MultiGigabit"},
468 {0, NULL}
471 static const value_string tecmp_device_ids_specific[] = {
472 {0x0050, "CM Sense 0"},
473 {0x0051, "CM Sense 1"},
474 {0x0052, "CM Sense 2"},
475 {0x0053, "CM Sense 3"},
476 {0x0054, "CM Sense 4"},
477 {0x0055, "CM Sense 5"},
478 {0x0056, "CM Sense 6"},
479 {0x0057, "CM Sense 7"},
480 {0x0070, "CM 10BASE-T1S 0"},
481 {0x0071, "CM 10BASE-T1S 1"},
482 {0x0072, "CM 10BASE-T1S 2"},
483 {0x0073, "CM 10BASE-T1S 3"},
484 {0x0074, "CM 10BASE-T1S 4"},
485 {0x0075, "CM 10BASE-T1S 5"},
486 {0x0076, "CM 10BASE-T1S 6"},
487 {0x0077, "CM 10BASE-T1S 7"},
488 {0x0078, "CM 10BASE-T1S 8"},
489 {0x0079, "CM 10BASE-T1S 9"},
490 {0x007a, "ILaS Sniffer 0"},
491 {0x007b, "ILaS Sniffer 1"},
492 {0x007c, "ILaS Sniffer 2"},
493 {0x007d, "ILaS Sniffer 3"},
494 {0x007e, "ILaS Sniffer 4"},
495 {0x007f, "ILaS Sniffer 5"},
496 {0, NULL}
499 #define TECMP_DEVICE_TYPE_CM_10BASE_T1S 0x0c
500 #define TECMP_DEVICE_TYPE_CM_ILAS_COMBO 0x0e
502 /* Device Types */
503 /* Updated by ID Registry */
504 static const value_string tecmp_device_types[] = {
505 {0x02, "CM LIN Combo"},
506 {0x04, "CM CAN Combo"},
507 {0x06, "CM 100 High"},
508 {0x07, "CM 100 High TC10"},
509 {0x08, "CM Eth Combo"},
510 {0x0a, "CM 1000 High"},
511 {TECMP_DEVICE_TYPE_CM_10BASE_T1S, "CM 10BASE-T1S"},
512 {TECMP_DEVICE_TYPE_CM_ILAS_COMBO, "ILaS Sniffer"},
513 {0x10, "Sensor specific"},
514 {0x20, "Logger"},
515 {0x42, "CM MultiGigabit"},
516 {0x46, "CM Sense"},
517 {0, NULL}
520 /* Control Message IDs */
521 /* Updated by ID Registry */
522 #define TECMP_CTRL_MSG_LOGGER_READY 0x0002
523 #define TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL 0x00E0
524 #define TECMP_CTRL_MSG_FR_POC_STATE 0x00E1
525 #define TECMP_CTRL_MSG_10BASE_T1S 0x00E2
527 static const value_string tecmp_ctrl_msg_ids_types[] = {
528 {TECMP_CTRL_MSG_LOGGER_READY, "Logger Ready"},
529 {TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL, "CAN Replay Fill Level"},
530 {TECMP_CTRL_MSG_FR_POC_STATE, "FlexRay POC State"},
531 {TECMP_CTRL_MSG_10BASE_T1S, "10BASE-T1S"},
532 {0, NULL}
535 static const value_string tecmp_ctrl_msg_fr_poc_state[] = {
536 {0, "Config"},
537 {1, "Default Config"},
538 {2, "Halt"},
539 {3, "Normal Active"},
540 {4, "Normal Passive"},
541 {5, "Ready"},
542 {6, "Startup"},
543 {7, "Wakeup"},
544 {0, NULL}
547 static const true_false_string tfs_tecmp_payload_timestamp_async_type = {
548 "Not synchronized",
549 "Synchronized or Master"
552 static const true_false_string tfs_tecmp_technica_bufferoverflow = {
553 "Buffer Overflow occurred",
554 "No Buffer Overflow occurred"
557 static const true_false_string tfs_tecmp_payload_data_crc_received = {
558 "CRC present in received message",
559 "CRC not present in received message"
562 static const true_false_string tfs_tecmp_payload_data_direction = {
563 "Upstream (response)",
564 "Downstream (command)"
567 static const true_false_string tfs_tecmp_payload_data_id_type = {
568 "29bit CAN Identifier",
569 "11bit CAN Identifier"
572 static const value_string tecmp_payload_rs232_uart_dl_types[] = {
573 {0x2, "RS232 with 7 bit"},
574 {0x3, "RS232 with 8 bit"},
575 {0, NULL}
578 static const value_string tecmp_payload_analog_sample_time_types[] = {
579 {0x0, "Reserved"},
580 {0x1, "2500 ms"},
581 {0x2, "1000 ms"},
582 {0x3, "500 ms"},
583 {0x4, "250 ms"},
584 {0x5, "100 ms"},
585 {0x6, "50 ms"},
586 {0x7, "25 ms"},
587 {0x8, "10 ms"},
588 {0x9, "5 ms"},
589 {0xa, "2.5 ms"},
590 {0xb, "1 ms"},
591 {0xc, "0.5 ms"},
592 {0xd, "0.25 ms"},
593 {0xe, "0.1 ms"},
594 {0xf, "0.05 ms"},
595 {0, NULL}
598 static const double tecmp_payload_analog_scale_factor_values[] = {
599 0.1,
600 0.01,
601 0.001,
602 0.0001,
605 static const value_string tecmp_payload_analog_scale_factor_types[] = {
606 {0x0, "0.1"},
607 {0x1, "0.01"},
608 {0x2, "0.001"},
609 {0x3, "0.0001"},
610 {0, NULL}
613 static const value_string tecmp_payload_analog_unit_types[] = {
614 {0x0, "V"},
615 {0x1, "A"},
616 {0x2, "W"},
617 {0x3, "Ah"},
618 {0x4, UTF8_DEGREE_SIGN "C"},
619 {0x5, "undefined value"},
620 {0x6, "undefined value"},
621 {0x7, "undefined value"},
622 {0, NULL}
625 static const value_string analog_alt_units[] = {
626 {0x04, "A"},
627 {0x0e, "W"},
628 {0x0f, "C"},
629 {0x10, "V"},
630 {0x17, "°C"},
631 {0, NULL}
634 /* TECMP Analog Alt Data Message DT Values */
635 #define TECMP_ANALOG_ALT_DATA_MSG_DL_16 0x00
636 #define TECMP_ANALOG_ALT_DATA_MSG_DL_32 0x01
638 static const value_string analog_alt_sample_dt[] = {
639 {TECMP_ANALOG_ALT_DATA_MSG_DL_16, "A_INT16"},
640 {TECMP_ANALOG_ALT_DATA_MSG_DL_32, "A_INT32"},
641 {0, NULL}
644 static const value_string tecmp_ilas_command_types[] = {
645 {0, "Unknown Command"},
646 {1, "ILas_Reset"},
647 {2, "ILaS_Set_Config"},
648 {3, "ILaS_Set_PWM_Max_High_Ch2"},
649 {4, "ILaS_Set_PWM_Max_High_Ch1"},
650 {5, "ILaS_Set_PWM_Max_High_Ch0"},
651 {6, "ILaS_Set_Cur_Ch1"},
652 {7, "ILaS_Set_Cur_Ch0"},
653 {8, "ILaS_Set_Temp_Offset"},
654 {9, "ILaS_Trig_ADC_Cal"},
655 {11, "ILaS_Set_Bias"},
656 {12, "ILaS_Set_TC_Base"},
657 {13, "ILaS_Set_TC_Offset"},
658 {14, "ILaS_Set_Sig_High"},
659 {15, "ILaS_Set_ADC_DAC"},
660 {16, "ILaS_Burn_Item (part 1)"},
661 {17, "ILaS_Burn_Sig"},
662 {18, "ILaS_Burn_Item (part 2)"},
663 {19, "ILaS_Set_TC_LUT"},
664 {20, "ILaS_Define_Mcast"},
665 {21, "ILaS_Set_PWM_Max_Low_Ch2"},
666 {22, "ILaS_Set_PWM_Max_Low_Ch1"},
667 {23, "ILaS_Set_PWM_Max_Low_Ch0"},
668 {24, "ILaS_Set_Cur_Ch3"},
669 {25, "ILaS_Burn_Item (part 3)"},
670 {26, "ILaS_Set_Port"},
671 {27, "ILaS_Branch_Read_Temp"},
672 {28, "ILaS_Branch_Read_Status"},
673 {29, "ILaS_Branch_Read_ADC"},
674 {30, "ILaS_Branch_Read_Item (part 1)"},
675 {31, "ILaS_Branch_Read_PWM"},
676 {32, "ILaS_Branch_Read_Item (part 2)"},
677 {33, "ILaS_Network_Init"},
678 {34, "ILaS_Branch_Init"},
679 {35, "ILaS_Network_Ping"},
680 {36, "ILaS_Branch_Ping"},
681 {37, "ILaS_Read_Register"},
682 {38, "ILaS_BranchDevices_Read"},
683 {39, "ILaS_Read_Event"},
684 {40, "ILaS_Set_Fw_Mode"},
685 {41, "ILaS_Set_Ps_Mode"},
686 {42, "ILaS_Burn_Sniff_Mode"},
687 {43, "ILaS_NOP"},
688 {44, "ILaS_Trg_ADC_Meas"},
689 {45, "ILaS_Set_3PWM_Low"},
690 {46, "ILaS_Set_3PWM_High"},
691 {47, "ILaS_Set_DIM"},
692 {48, "ILaS_Set_PWM_Ch3"},
693 {49, "ILaS_Write_Register"},
694 {50, "ILaS_Burn_Register"},
695 {51, "ILaS_Branch_Read_Item (config)"},
696 {52, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch2)"},
697 {53, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch1)"},
698 {54, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch0)"},
699 {55, "ILaS_Branch_Read_Item (Peak_Ch1)"},
700 {56, "ILaS_Branch_Read_Item (Peak_Ch0)"},
701 {57, "ILaS_Branch_Read_Item (Temp_Offset)"},
702 {58, "ILaS_Branch_Read_Item (ADC_offset + ADC_ref)"},
703 {59, "ILaS_Branch_Read_Item (Bias)"},
704 {60, "ILaS_Branch_Read_Item (TC_Base_Ch2)"},
705 {61, "ILaS_Branch_Read_Item (TC_Offset_Ch2)"},
706 {62, "ILaS_Branch_Read_Item (last_fuse)"},
707 {63, "ILaS_Branch_Read_PWM (Hi_Ch2)"},
708 {64, "ILaS_Branch_Read_PWM (Hi_Ch1)"},
709 {65, "ILaS_Branch_Read_PWM (Hi_Ch0)"},
710 {66, "ILaS_Set_Fw_Mode (M0)"},
711 {67, "ILaS_Set_Fw_Mode (M1)"},
712 {68, "ILaS_Set_Fw_Mode (M2)"},
713 {69, "ILaS_Set_Fw_Mode (M3)"},
714 {70, "ILaS_Trg_ADC_Meas (Temperature)"},
715 {71, "ILaS_Trg_ADC_Meas (5V_PRG)"},
716 {72, "ILaS_Trg_ADC_Meas (1V5_DIG)"},
717 {73, "ILaS_Trg_ADC_Meas (RED)"},
718 {74, "ILaS_Trg_ADC_Meas (GREEN)"},
719 {75, "ILaS_Trg_ADC_Meas (BLUE)"},
720 {76, "ILaS_Trg_ADC_Meas (BG)"},
721 {77, "ILaS_Trg_ADC_Meas (VSUP)"},
722 {78, "ILaS_Trg_ADC_Meas (VCCA)"},
723 {79, "ILaS_Trg_ADC_Meas (1V5_AN)"},
724 {80, "ILaS_Trg_ADC_Meas (VSENSE)"},
725 {0, NULL}
728 static const value_string tecmp_payload_flexray_tx_mode[] = {
729 {0x0, "Reserved"},
730 {0x1, "Single Shot Transmission"},
731 {0x2, "Continuous Transmission"},
732 {0x3, "TX None"},
733 {0, NULL}
736 static const value_string tecmp_bus_status_link_status[] = {
737 {0x0, "Down"},
738 {0x1, "Up"},
739 {0, NULL}
742 static const value_string tecmp_bus_status_link_quality[] = {
743 {0x0, "Unacceptable or Down (0/5)"},
744 {0x1, "Poor (1/5)"},
745 {0x2, "Marginal (2/5)"},
746 {0x3, "Good (3/5)"},
747 {0x4, "Very good (4/5)"},
748 {0x5, "Excellent (5/5)"},
749 {0, NULL}
752 static const value_string tecmp_timesync_event_flags[] = {
753 {0x0, "No error occurred"},
754 {0x1, "Error occurred"},
755 {0, NULL}
759 #define DATA_FLAG_CAN_ACK 0x0001
760 #define DATA_FLAG_CAN_RTR 0x0002
761 #define DATA_FLAG_CANFD_ESI 0x0002
762 #define DATA_FLAG_CAN_IDE 0x0004
763 #define DATA_FLAG_CAN_ERR 0x0008
764 #define DATA_FLAG_CAN_BIT_STUFF_ERR 0x0010
765 #define DATA_FLAG_CAN_CRC_DEL_ERR 0x0020
766 #define DATA_FLAG_CAN_ACK_DEL_ERR 0x0040
767 #define DATA_FLAG_CAN_EOF_ERR 0x0080
768 #define DATA_FLAG_CANFD_BRS 0x0010
769 #define DATA_FLAG_CANFD_BIT_STUFF_ERR 0x0020
770 #define DATA_FLAG_CANFD_CRC_DEL_ERR 0x0040
771 #define DATA_FLAG_CANFD_ACK_DEL_ERR 0x0080
772 #define DATA_FLAG_CANFD_EOF_ERR 0x0100
774 #define DATA_FLAG_FR_NF 0x0001
775 #define DATA_FLAG_FR_ST 0x0002
776 #define DATA_FLAG_FR_SYNC 0x0004
777 #define DATA_FLAG_FR_WUS 0x0008
778 #define DATA_FLAG_FR_PPI 0x0010
779 #define DATA_FLAG_FR_CAS 0x0020
780 #define DATA_FLAG_FR_HDR_CRC_ERR 0x1000
781 #define DATA_FLAG_FR_FRAME_CRC_ERR 0x2000
783 #define DATA_LIN_ID_MASK 0x3F
784 #define DATA_FR_HEADER_CRC_MAX 0x07FF
786 #define TECMP_ETH_RAW_PREAMBLE 0x55
787 #define TECMP_ETH_RAW_SFD_ORIG 0xD5
788 #define TECMP_ETH_RAW_SFD_SMD_V 0x07
789 #define TECMP_ETH_RAW_SFD_SMD_R 0x19
790 #define TECMP_ETH_RAW_SFD_SMD_S0 0xE6
791 #define TECMP_ETH_RAW_SFD_SMD_S1 0x4C
792 #define TECMP_ETH_RAW_SFD_SMD_S2 0x7F
793 #define TECMP_ETH_RAW_SFD_SMD_S3 0xB3
794 #define TECMP_ETH_RAW_SFD_SMD_C0 0x61
795 #define TECMP_ETH_RAW_SFD_SMD_C1 0x52
796 #define TECMP_ETH_RAW_SFD_SMD_C2 0x9E
797 #define TECMP_ETH_RAW_SFD_SMD_C3 0x2A
799 static const value_string tecmp_eth_raw_sfd[] = {
800 {TECMP_ETH_RAW_SFD_ORIG, "SFD/SMD-E"},
801 {TECMP_ETH_RAW_SFD_SMD_V, "SMD-V"},
802 {TECMP_ETH_RAW_SFD_SMD_R, "SMD-R"},
803 {TECMP_ETH_RAW_SFD_SMD_S0, "SMD-S0"},
804 {TECMP_ETH_RAW_SFD_SMD_S1, "SMD-S1"},
805 {TECMP_ETH_RAW_SFD_SMD_S2, "SMD-S2"},
806 {TECMP_ETH_RAW_SFD_SMD_S3, "SMD-S3"},
807 {TECMP_ETH_RAW_SFD_SMD_C0, "SMD-C0"},
808 {TECMP_ETH_RAW_SFD_SMD_C1, "SMD-C1"},
809 {TECMP_ETH_RAW_SFD_SMD_C2, "SMD-C2"},
810 {TECMP_ETH_RAW_SFD_SMD_C3, "SMD-C3"},
811 {0, NULL}
814 /********* UATs *********/
816 typedef struct _generic_one_id_string {
817 unsigned id;
818 char *name;
819 } generic_one_id_string_t;
821 /* Interface UAT */
822 typedef struct _interface_config {
823 unsigned id;
824 unsigned bus_id;
825 char *name;
826 } interface_config_t;
828 #define DATAFILE_TECMP_DEVICE_IDS "TECMP_device_identifiers"
829 #define DATAFILE_TECMP_INTERFACE_IDS "TECMP_interface_identifiers"
830 #define DATAFILE_TECMP_CONTROL_MSG_IDS "TECMP_control_message_identifiers"
832 static GHashTable *data_tecmp_devices;
833 static generic_one_id_string_t* tecmp_devices;
834 static unsigned tecmp_devices_num;
836 UAT_HEX_CB_DEF(tecmp_devices, id, generic_one_id_string_t)
837 UAT_CSTRING_CB_DEF(tecmp_devices, name, generic_one_id_string_t)
839 static GHashTable *data_tecmp_interfaces;
840 static interface_config_t* tecmp_interfaces;
841 static unsigned tecmp_interfaces_num;
843 UAT_HEX_CB_DEF(tecmp_interfaces, id, interface_config_t)
844 UAT_CSTRING_CB_DEF(tecmp_interfaces, name, interface_config_t)
845 UAT_HEX_CB_DEF(tecmp_interfaces, bus_id, interface_config_t)
847 static GHashTable *data_tecmp_ctrlmsgids;
848 static generic_one_id_string_t* tecmp_ctrl_msgs;
849 static unsigned tecmp_ctrl_msg_num;
851 UAT_HEX_CB_DEF(tecmp_ctrl_msgs, id, generic_one_id_string_t)
852 UAT_CSTRING_CB_DEF(tecmp_ctrl_msgs, name, generic_one_id_string_t)
854 /* ID -> Name */
855 static void *
856 copy_generic_one_id_string_cb(void *n, const void *o, size_t size _U_) {
857 generic_one_id_string_t *new_rec = (generic_one_id_string_t *)n;
858 const generic_one_id_string_t *old_rec = (const generic_one_id_string_t *)o;
860 new_rec->name = g_strdup(old_rec->name);
861 new_rec->id = old_rec->id;
862 return new_rec;
865 static bool
866 update_generic_one_identifier_16bit(void *r, char **err) {
867 generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
869 if (rec->id > 0xffff) {
870 *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i Name: %s)", rec->id, rec->name);
871 return false;
874 if (rec->name == NULL || rec->name[0] == 0) {
875 *err = g_strdup("Name cannot be empty");
876 return false;
879 return true;
882 static void
883 free_generic_one_id_string_cb(void* r) {
884 generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
885 /* freeing result of g_strdup */
886 g_free(rec->name);
887 rec->name = NULL;
890 /* ID -> ID, Name */
891 static void *
892 copy_interface_config_cb(void *n, const void *o, size_t size _U_) {
893 interface_config_t *new_rec = (interface_config_t *)n;
894 const interface_config_t *old_rec = (const interface_config_t *)o;
896 new_rec->id = old_rec->id;
897 new_rec->name = g_strdup(old_rec->name);
898 new_rec->bus_id = old_rec->bus_id;
899 return new_rec;
902 static bool
903 update_interface_config(void *r, char **err) {
904 interface_config_t *rec = (interface_config_t *)r;
906 if (rec->id > 0xffffffff) {
907 *err = ws_strdup_printf("We currently only support 32 bit identifiers (ID: %i Name: %s)", rec->id, rec->name);
908 return false;
911 if (rec->name == NULL || rec->name[0] == 0) {
912 *err = g_strdup("Name cannot be empty");
913 return false;
916 if (rec->bus_id > 0xffff) {
917 *err = ws_strdup_printf("We currently only support 16 bit bus identifiers (ID: %i Name: %s Bus-ID: %i)", rec->id, rec->name, rec->bus_id);
918 return false;
921 return true;
924 static void
925 free_interface_config_cb(void *r) {
926 interface_config_t *rec = (interface_config_t *)r;
927 /* freeing result of g_strdup */
928 g_free(rec->name);
929 rec->name = NULL;
932 static char *
933 ht_interface_config_to_string(unsigned int identifier) {
934 interface_config_t *tmp = g_hash_table_lookup(data_tecmp_interfaces, GUINT_TO_POINTER(identifier));
935 if (tmp == NULL) {
936 return NULL;
939 return tmp->name;
942 static uint16_t
943 ht_interface_config_to_bus_id(unsigned int identifier) {
944 interface_config_t *tmp = g_hash_table_lookup(data_tecmp_interfaces, GUINT_TO_POINTER(identifier));
945 if (tmp == NULL) {
946 /* 0 means basically any or none */
947 return 0;
950 return tmp->bus_id;
953 /*** UAT TECMP_DEVICE_IDs ***/
955 static void
956 post_update_tecmp_devices_cb(void) {
957 unsigned i;
959 /* destroy old hash table, if it exists */
960 if (data_tecmp_devices) {
961 g_hash_table_destroy(data_tecmp_devices);
964 /* create new hash table */
965 data_tecmp_devices = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
967 for (i = 0; i < tecmp_devices_num; i++) {
968 g_hash_table_insert(data_tecmp_devices, GUINT_TO_POINTER(tecmp_devices[i].id), tecmp_devices[i].name);
972 static void
973 add_device_id_text(proto_item *ti, uint16_t device_id) {
974 /* lets check configured entries first */
975 const char *descr = g_hash_table_lookup(data_tecmp_devices, GUINT_TO_POINTER(device_id));
977 if (descr == NULL) {
978 /* lets check specific */
979 descr = try_val_to_str(device_id, tecmp_device_ids_specific);
982 if (descr == NULL) {
983 /* lets check ranged prefixes */
984 descr = try_val_to_str((device_id & 0xfff0), tecmp_device_id_prefixes);
985 if (descr != NULL) {
986 if ((device_id & 0x000f) == 0) {
987 proto_item_append_text(ti, " (%s %d (Default))", descr, (device_id & 0x000f));
988 } else {
989 proto_item_append_text(ti, " (%s %d)", descr, (device_id & 0x000f));
991 return;
995 /* if, we found nothing before */
996 if (descr == NULL) {
997 descr = "Unknown/Unconfigured CM";
1000 proto_item_append_text(ti, " (%s)", descr);
1003 /*** UAT TECMP_INTERFACE_IDs ***/
1005 static void
1006 post_update_tecmp_interfaces_cb(void) {
1007 unsigned i;
1009 /* destroy old hash table, if it exists */
1010 if (data_tecmp_interfaces) {
1011 g_hash_table_destroy(data_tecmp_interfaces);
1014 /* create new hash table */
1015 data_tecmp_interfaces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
1017 for (i = 0; i < tecmp_interfaces_num; i++) {
1018 g_hash_table_insert(data_tecmp_interfaces, GUINT_TO_POINTER(tecmp_interfaces[i].id), &tecmp_interfaces[i]);
1022 static void
1023 add_interface_id_text_and_name(proto_item *ti, uint32_t interface_id, tvbuff_t *tvb, int offset) {
1024 const char *descr = ht_interface_config_to_string(interface_id);
1026 if (descr != NULL) {
1027 proto_item_append_text(ti, " (%s)", descr);
1028 proto_tree *subtree = proto_item_add_subtree(ti, ett_tecmp_payload_interface_id);
1029 proto_tree_add_string(subtree, hf_tecmp_payload_interface_name, tvb, offset, 4, descr);
1033 /*** UAT TECMP_CONTROL_MESSAGE_IDs ***/
1035 static void
1036 post_update_tecmp_control_messages_cb(void) {
1037 unsigned i;
1039 /* destroy old hash table, if it exists */
1040 if (data_tecmp_ctrlmsgids) {
1041 g_hash_table_destroy(data_tecmp_ctrlmsgids);
1044 /* create new hash table */
1045 data_tecmp_ctrlmsgids = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
1047 for (i = 0; i < tecmp_ctrl_msg_num; i++) {
1048 g_hash_table_insert(data_tecmp_ctrlmsgids, GUINT_TO_POINTER(tecmp_ctrl_msgs[i].id), tecmp_ctrl_msgs[i].name);
1052 static const char*
1053 resolve_control_message_id(uint16_t control_message_id)
1055 const char *tmp = g_hash_table_lookup(data_tecmp_ctrlmsgids, GUINT_TO_POINTER(control_message_id));
1057 /* lets look at the static values, if nothing is configured */
1058 if (tmp == NULL) {
1059 tmp = try_val_to_str(control_message_id, tecmp_ctrl_msg_ids_types);
1062 /* no configured or standardized name known */
1063 if (tmp != NULL) {
1064 return wmem_strdup_printf(wmem_packet_scope(), "%s (0x%04x)", tmp, control_message_id);
1067 /* just give back unknown */
1068 return wmem_strdup_printf(wmem_packet_scope(), "Unknown (0x%04x)", control_message_id);
1073 static bool
1074 tecmp_entry_header_present(tvbuff_t *tvb, unsigned offset) {
1075 uint32_t chan_id = 0;
1076 uint64_t tstamp = 0;
1077 uint16_t length = 0;
1079 chan_id = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1080 tstamp = tvb_get_uint64(tvb, offset + 4, ENC_BIG_ENDIAN);
1081 length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
1083 if (chan_id == 0 && tstamp == 0 && length == 0) {
1084 /* 0 is not valid and therefore we assume padding. */
1085 return false;
1087 return true;
1090 static unsigned
1091 dissect_tecmp_entry_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, unsigned tecmp_msg_type, uint16_t data_type,
1092 bool first, uint16_t *dataflags, uint32_t *interface_id, uint64_t *timestamp_ns) {
1093 proto_item *ti;
1094 proto_tree *subtree = NULL;
1095 unsigned offset = offset_orig;
1097 nstime_t timestamp;
1098 uint64_t ns = 0;
1099 bool async = false;
1100 unsigned tmp;
1102 static int * const dataflags_generic[] = {
1103 &hf_tecmp_payload_data_flags_overflow,
1104 &hf_tecmp_payload_data_flags_tx,
1105 &hf_tecmp_payload_data_flags_crc,
1106 NULL
1109 static int * const dataflags_ethernet_10base_t1s[] = {
1110 &hf_tecmp_payload_data_flags_overflow,
1111 &hf_tecmp_payload_data_flags_tx,
1112 &hf_tecmp_payload_data_flags_crc,
1113 &hf_tecmp_payload_data_flags_phy_event_error,
1114 NULL
1117 static int * const dataflags_lin[] = {
1118 &hf_tecmp_payload_data_flags_overflow,
1119 &hf_tecmp_payload_data_flags_tx,
1120 &hf_tecmp_payload_data_flags_checksum,
1122 &hf_tecmp_payload_data_flags_sleep,
1123 &hf_tecmp_payload_data_flags_short_wup,
1124 &hf_tecmp_payload_data_flags_wup,
1125 &hf_tecmp_payload_data_flags_no_resp,
1126 &hf_tecmp_payload_data_flags_parity,
1127 &hf_tecmp_payload_data_flags_coll,
1128 NULL
1131 static int * const dataflags_lin_tx[] = {
1132 &hf_tecmp_payload_data_flags_use_checksum_value,
1134 &hf_tecmp_payload_data_flags_short_wup,
1135 &hf_tecmp_payload_data_flags_wup,
1136 &hf_tecmp_payload_data_flags_use_parity_bits,
1137 NULL
1140 static int * const dataflags_can_data[] = {
1141 &hf_tecmp_payload_data_flags_overflow,
1142 &hf_tecmp_payload_data_flags_tx,
1143 &hf_tecmp_payload_data_flags_crc,
1145 &hf_tecmp_payload_data_flags_can_eof_err,
1146 &hf_tecmp_payload_data_flags_can_ack_del_err,
1147 &hf_tecmp_payload_data_flags_can_crc_del_err,
1148 &hf_tecmp_payload_data_flags_can_bit_stuff_err,
1149 &hf_tecmp_payload_data_flags_err,
1150 &hf_tecmp_payload_data_flags_ide,
1151 &hf_tecmp_payload_data_flags_rtr,
1152 &hf_tecmp_payload_data_flags_ack,
1153 NULL
1156 static int * const dataflags_can_tx_data[] = {
1157 &hf_tecmp_payload_data_flags_use_crc_value,
1159 &hf_tecmp_payload_data_flags_can_eof_err,
1160 &hf_tecmp_payload_data_flags_can_ack_del_err,
1161 &hf_tecmp_payload_data_flags_can_crc_del_err,
1162 &hf_tecmp_payload_data_flags_can_bit_stuff_err,
1163 NULL
1166 static int * const dataflags_can_fd_data[] = {
1167 &hf_tecmp_payload_data_flags_overflow,
1168 &hf_tecmp_payload_data_flags_tx,
1169 &hf_tecmp_payload_data_flags_crc,
1171 &hf_tecmp_payload_data_flags_canfd_eof_err,
1172 &hf_tecmp_payload_data_flags_canfd_ack_del_err,
1173 &hf_tecmp_payload_data_flags_canfd_crc_del_err,
1174 &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,
1175 &hf_tecmp_payload_data_flags_brs,
1176 &hf_tecmp_payload_data_flags_err,
1177 &hf_tecmp_payload_data_flags_ide,
1178 &hf_tecmp_payload_data_flags_esi,
1179 &hf_tecmp_payload_data_flags_ack,
1180 NULL
1183 static int * const dataflags_can_fd_tx_data[] = {
1184 &hf_tecmp_payload_data_flags_use_crc_value,
1186 &hf_tecmp_payload_data_flags_canfd_eof_err,
1187 &hf_tecmp_payload_data_flags_canfd_ack_del_err,
1188 &hf_tecmp_payload_data_flags_canfd_crc_del_err,
1189 &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,
1190 &hf_tecmp_payload_data_flags_brs,
1191 NULL
1194 static int * const dataflags_flexray_data[] = {
1195 &hf_tecmp_payload_data_flags_overflow,
1196 &hf_tecmp_payload_data_flags_tx,
1198 &hf_tecmp_payload_data_flags_frame_crc_err,
1199 &hf_tecmp_payload_data_flags_header_crc_err,
1200 &hf_tecmp_payload_data_flags_cas,
1201 &hf_tecmp_payload_data_flags_ppi,
1202 &hf_tecmp_payload_data_flags_wus,
1203 &hf_tecmp_payload_data_flags_sync,
1204 &hf_tecmp_payload_data_flags_sf,
1205 &hf_tecmp_payload_data_flags_nf,
1206 NULL
1209 static int * const dataflags_flexray_tx_data[] = {
1211 &hf_tecmp_payload_data_flags_use_header_crc_value,
1212 &hf_tecmp_payload_data_flags_tx_mode,
1213 NULL
1216 static int * const dataflags_ilas[] = {
1217 &hf_tecmp_payload_data_flags_crc,
1219 &hf_tecmp_payload_data_flags_direction,
1220 &hf_tecmp_payload_data_flags_crc_enabled,
1221 NULL
1224 static int * const dataflags_rs232_uart_ascii[] = {
1225 &hf_tecmp_payload_data_flags_tx,
1227 &hf_tecmp_payload_data_flags_dl,
1228 &hf_tecmp_payload_data_flags_parity_error,
1229 NULL
1232 static int * const dataflags_analog[] = {
1233 &hf_tecmp_payload_data_flags_overflow,
1235 &hf_tecmp_payload_data_flags_sample_time,
1236 &hf_tecmp_payload_data_flags_factor,
1237 &hf_tecmp_payload_data_flags_unit,
1238 &hf_tecmp_payload_data_flags_threshold_u,
1239 &hf_tecmp_payload_data_flags_threshold_o,
1240 NULL
1243 /* Can't use col_append_sep_str because we already set something before. */
1244 if (!first) {
1245 col_append_str(pinfo->cinfo, COL_INFO, ", ");
1247 col_append_str(pinfo->cinfo, COL_INFO, val_to_str(data_type, tecmp_msgtype_names, "Unknown (%d)"));
1249 ti = proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN, &tmp);
1250 add_interface_id_text_and_name(ti, tmp, tvb, offset);
1251 if (interface_id != NULL) {
1252 *interface_id = tmp;
1255 ns = tvb_get_uint64(tvb, offset + 4, ENC_BIG_ENDIAN) & 0x3fffffffffffffff;
1257 if (timestamp_ns != NULL) {
1258 *timestamp_ns = ns;
1261 timestamp.secs = (time_t)(ns / 1000000000);
1262 timestamp.nsecs = (int)(ns % 1000000000);
1263 ti = proto_tree_add_time(tree, hf_tecmp_payload_timestamp, tvb, offset + 4, 8, &timestamp);
1264 subtree = proto_item_add_subtree(ti, ett_tecmp_payload_timestamp);
1265 proto_tree_add_item_ret_boolean(subtree, hf_tecmp_payload_timestamp_async, tvb, offset + 4, 1, ENC_NA, &async);
1266 proto_tree_add_item(subtree, hf_tecmp_payload_timestamp_res, tvb, offset + 4, 1, ENC_NA);
1268 if (async) {
1269 proto_item_append_text(ti, " (not synchronized)");
1270 } else {
1271 proto_item_append_text(ti, " (synchronized or master)");
1273 ti = proto_tree_add_uint64(tree, hf_tecmp_payload_timestamp_ns, tvb, offset + 4, 8, ns);
1274 proto_item_set_hidden(ti);
1276 proto_tree_add_item(tree, hf_tecmp_payload_length, tvb, offset+12, 2, ENC_BIG_ENDIAN);
1277 offset += 14;
1279 if (dataflags != NULL) {
1280 *dataflags = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1283 switch (tecmp_msg_type) {
1284 case TECMP_MSG_TYPE_LOG_STREAM:
1285 switch (data_type) {
1286 case TECMP_DATA_TYPE_LIN:
1287 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_lin, ENC_BIG_ENDIAN);
1288 break;
1290 case TECMP_DATA_TYPE_CAN_DATA:
1291 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_data, ENC_BIG_ENDIAN);
1292 break;
1294 case TECMP_DATA_TYPE_CAN_FD_DATA:
1295 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_fd_data, ENC_BIG_ENDIAN);
1296 break;
1298 case TECMP_DATA_TYPE_FR_DATA:
1299 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_flexray_data, ENC_BIG_ENDIAN);
1300 break;
1302 case TECMP_DATA_TYPE_ILAS:
1303 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_ilas, ENC_BIG_ENDIAN);
1304 break;
1306 case TECMP_DATA_TYPE_RS232_ASCII:
1307 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_rs232_uart_ascii, ENC_BIG_ENDIAN);
1308 break;
1310 case TECMP_DATA_TYPE_ANALOG:
1311 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_analog, ENC_BIG_ENDIAN);
1312 break;
1314 case TECMP_DATA_TYPE_ETH_10BASE_T1S:
1315 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_ethernet_10base_t1s, ENC_BIG_ENDIAN);
1316 break;
1318 case TECMP_DATA_TYPE_ETH_RAW:
1319 case TECMP_DATA_TYPE_ETH:
1320 default:
1321 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_generic, ENC_BIG_ENDIAN);
1323 break;
1325 case TECMP_MSG_TYPE_REPLAY_DATA:
1326 switch (data_type) {
1327 case TECMP_DATA_TYPE_LIN:
1328 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_lin_tx, ENC_BIG_ENDIAN);
1329 break;
1331 case TECMP_DATA_TYPE_CAN_DATA:
1332 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_tx_data, ENC_BIG_ENDIAN);
1333 break;
1335 case TECMP_DATA_TYPE_CAN_FD_DATA:
1336 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_fd_tx_data, ENC_BIG_ENDIAN);
1337 break;
1339 case TECMP_DATA_TYPE_FR_DATA:
1340 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_flexray_tx_data, ENC_BIG_ENDIAN);
1341 break;
1343 case TECMP_DATA_TYPE_RS232_ASCII:
1344 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_rs232_uart_ascii, ENC_BIG_ENDIAN);
1345 break;
1347 case TECMP_DATA_TYPE_ANALOG:
1348 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_analog, ENC_BIG_ENDIAN);
1349 break;
1351 case TECMP_DATA_TYPE_ETH_RAW:
1352 case TECMP_DATA_TYPE_ETH:
1353 default:
1354 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_generic, ENC_BIG_ENDIAN);
1356 break;
1358 case TECMP_MSG_TYPE_CTRL_MSG:
1359 case TECMP_MSG_TYPE_STATUS_DEV:
1360 case TECMP_MSG_TYPE_STATUS_BUS:
1361 case TECMP_MSG_TYPE_CFG_CM:
1362 case TECMP_MSG_TYPE_COUNTER_EVENT:
1363 case TECMP_MSG_TYPE_TIMESYNC_EVENT:
1364 default:
1365 proto_tree_add_item(tree, hf_tecmp_payload_data_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
1366 break;
1369 offset += 2;
1371 return offset - offset_orig;
1374 static void
1375 dissect_tecmp_status_config_vendor_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti_root, uint8_t device_type _U_,
1376 uint8_t vendor_id) {
1377 proto_tree *tree = NULL;
1378 int offset = 0;
1379 unsigned data_length = 0;
1381 proto_item_append_text(ti_root, " (%s)", val_to_str(vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1382 tree = proto_item_add_subtree(ti_root, ett_tecmp_status_bus_vendor_data);
1384 switch (vendor_id) {
1385 case TECMP_VENDOR_ID_TECHNICA:
1386 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_version, tvb, offset, 1, ENC_NA);
1387 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_reserved, tvb, offset + 1, 1, ENC_NA);
1388 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_msg_id, tvb, offset + 2, 2,
1389 ENC_BIG_ENDIAN);
1390 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_total_length, tvb, offset + 4, 4,
1391 ENC_BIG_ENDIAN);
1392 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg, tvb, offset + 8, 2,
1393 ENC_BIG_ENDIAN);
1394 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_num, tvb, offset + 10, 2,
1395 ENC_BIG_ENDIAN);
1396 proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_length, tvb,
1397 offset + 12, 2, ENC_BIG_ENDIAN, &data_length);
1398 offset += 14;
1399 if (tvb_captured_length_remaining(tvb, offset) >= (int)data_length) {
1400 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_data, tvb, offset,
1401 data_length, ENC_NA);
1402 } else {
1403 proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_data, tvb, offset,
1404 tvb_captured_length_remaining(tvb, offset), ENC_NA);
1407 break;
1411 static void
1412 dissect_tecmp_status_bus_vendor_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti_root,
1413 uint8_t entry_number, uint8_t device_type, uint8_t vendor_id) {
1414 proto_tree *tree = NULL;
1415 proto_item *ti = NULL;
1416 int offset = 0;
1417 int bytes_remaining = 0;
1418 unsigned tmp = 0;
1420 proto_item_append_text(ti_root, " (%s)", val_to_str(vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1421 tree = proto_item_add_subtree(ti_root, ett_tecmp_status_bus_vendor_data);
1423 switch (vendor_id) {
1424 case TECMP_VENDOR_ID_TECHNICA:
1425 bytes_remaining = tvb_captured_length_remaining(tvb, offset);
1427 if (device_type == TECMP_DEVICE_TYPE_CM_ILAS_COMBO && entry_number < 5) {
1428 /* Currently no parameters for this format but might be specified in a later specification. */
1429 } else if ((device_type == TECMP_DEVICE_TYPE_CM_ILAS_COMBO && entry_number == 5) || device_type == TECMP_DEVICE_TYPE_CM_10BASE_T1S) {
1430 static int * const vendor_data_flags_10BASE_T1S[] = {
1431 &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_enabled,
1432 &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beacons_received,
1433 NULL
1436 proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_bus_vendor_technica_10m_flags, ett_tecmp_status_bus_vendor_data_flags, vendor_data_flags_10BASE_T1S, ENC_BIG_ENDIAN);
1437 offset += 1;
1439 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res0, tvb, offset, 1, ENC_NA);
1440 offset += 1;
1442 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_beacon_counter, tvb, offset, 4, ENC_NA);
1443 offset += 4;
1445 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_quality, tvb, offset, 1, ENC_NA);
1446 offset += 1;
1448 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res1, tvb, offset, 1, ENC_NA);
1449 offset += 1;
1451 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res2, tvb, offset, 2, ENC_NA);
1452 offset += 2;
1454 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt, tvb, offset, 2, ENC_NA);
1455 offset += 2;
1457 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt, tvb, offset, 2, ENC_NA);
1458 offset += 2;
1460 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_detected_cnt, tvb, offset, 2, ENC_NA);
1461 offset += 2;
1463 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_missing_cnt, tvb, offset, 2, ENC_NA);
1464 offset += 2;
1466 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_empty_cycle_cnt, tvb, offset, 2, ENC_NA);
1467 } else {
1468 if (bytes_remaining >= 1) {
1469 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_status, tvb, offset, 1, ENC_NA);
1470 offset += 1;
1472 if (bytes_remaining >= 2) {
1473 proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_quality, tvb, offset, 1,
1474 ENC_NA);
1475 offset += 1;
1477 if (bytes_remaining >= 4) {
1478 ti = proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_status_bus_vendor_technica_linkup_time, tvb,
1479 offset, 2, ENC_NA, &tmp);
1480 if (tmp == 0) {
1481 proto_item_append_text(ti, " %s", "(no linkup detected yet)");
1482 } else if (tmp == 0xffff) {
1483 proto_item_append_text(ti, " %s", "(no linkup detected and timeout occurred)");
1487 break;
1491 static void
1492 dissect_tecmp_status_device_vendor_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti_root, uint8_t device_type _U_, uint8_t vendor_id, uint64_t timestamp_ns) {
1493 proto_tree *tree = NULL;
1494 proto_item *ti = NULL;
1495 int offset = 0;
1496 unsigned tmp = 0;
1497 uint64_t tmp64 = 0;
1498 nstime_t timestamp;
1499 int temperature = 0;
1501 proto_item_append_text(ti_root, " (%s)", val_to_str(vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1502 tree = proto_item_add_subtree(ti_root, ett_tecmp_status_dev_vendor_data);
1504 switch (vendor_id) {
1505 case TECMP_VENDOR_ID_TECHNICA:
1506 proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_res, tvb, offset, 1, ENC_NA);
1507 offset += 1;
1508 tmp = tvb_get_uint24(tvb, offset, ENC_BIG_ENDIAN);
1509 proto_tree_add_string_format(tree, hf_tecmp_payload_status_dev_vendor_technica_sw, tvb, offset, 3, NULL,
1510 "Software Version: v%d.%d.%d", (tmp&0x00ff0000)>>16, (tmp&0x0000ff00)>>8, tmp&0x000000ff);
1511 offset += 3;
1513 tmp = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1514 proto_tree_add_string_format(tree, hf_tecmp_payload_status_dev_vendor_technica_hw, tvb, offset, 2, NULL,
1515 "Hardware Version: v%d.%x", (tmp & 0x0000ff00) >> 8, tmp & 0x000000ff);
1516 offset += 2;
1518 ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level, tvb, offset, 1, ENC_NA);
1519 proto_item_append_text(ti, "%s", "%");
1520 offset += 1;
1522 proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow, tvb, offset, 1, ENC_NA);
1523 offset += 1;
1525 tmp = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1526 proto_tree_add_uint_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_size, tvb, offset,
1527 4, tmp * 128, "%d MB", tmp * 128);
1528 offset += 4;
1530 ti = proto_tree_add_item_ret_uint64(tree, hf_tecmp_payload_status_dev_vendor_technica_lifecycle, tvb, offset, 8, ENC_BIG_ENDIAN, &tmp64);
1532 uint64_t nanos = tmp64 % 1000000000;
1533 uint64_t secs = tmp64 / 1000000000;
1534 uint64_t mins = secs / 60;
1535 secs -= mins * 60;
1536 uint64_t hours = mins / 24;
1537 mins -= hours * 24;
1538 proto_item_append_text(ti, " ns (%d:%02d:%02d.%09d)", (uint32_t)hours, (uint32_t)mins, (uint32_t)secs, (uint32_t)nanos);
1540 if (tmp64 < timestamp_ns) {
1541 timestamp_ns -= tmp64;
1542 timestamp.secs = (time_t)(timestamp_ns / 1000000000);
1543 timestamp.nsecs = (int)(timestamp_ns % 1000000000);
1544 ti = proto_tree_add_time(tree, hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start, tvb, offset, 8, &timestamp);
1545 proto_item_set_generated(ti);
1547 offset += 8;
1549 tmp = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1551 double voltage_value = (double)((tmp & 0x0000ff00) >> 8) + (tmp & 0x000000ff) / 100.0;
1552 proto_tree_add_double(tree, hf_tecmp_payload_status_dev_vendor_technica_voltage, tvb, offset, 2, voltage_value);
1553 offset += 2;
1555 if (tvb_captured_length_remaining(tvb, offset) == 1) {
1556 proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature, tvb, offset, 1, ENC_NA);
1557 } else if (tvb_captured_length_remaining(tvb, offset) > 1) {
1558 /* TECMP 1.5 and later */
1559 temperature = tvb_get_int8(tvb, offset);
1560 if (temperature == VENDOR_TECHNICA_TEMP_NA) {
1561 proto_tree_add_int_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis, tvb, offset, 1, temperature, "%s", "Not Available");
1562 } else {
1563 ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis, tvb, offset, 1, ENC_NA);
1564 if (temperature == VENDOR_TECHNICA_TEMP_MAX) {
1565 proto_item_append_text(ti, " %s", "or more");
1568 offset += 1;
1570 temperature = tvb_get_int8(tvb, offset);
1571 if ( temperature == VENDOR_TECHNICA_TEMP_NA) {
1572 proto_tree_add_int_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon, tvb, offset, 1, temperature, "%s", "Not Available");
1573 } else {
1574 ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon, tvb, offset, 1, ENC_NA);
1575 if (temperature == VENDOR_TECHNICA_TEMP_MAX) {
1576 proto_item_append_text(ti, " %s", "or more");
1581 break;
1585 static int
1586 dissect_tecmp_control_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t msg_type, unsigned tecmp_msg_type) {
1587 proto_item *root_ti = NULL;
1588 proto_item *ti = NULL;
1589 proto_tree *tecmp_tree = NULL;
1590 uint16_t length = 0;
1591 unsigned offset = offset_orig;
1592 unsigned device_id = 0;
1593 unsigned interface_id = 0;
1594 unsigned ctrl_msg_id = 0;
1596 if (tvb_captured_length_remaining(tvb, offset) >= (16 + 4)) {
1597 length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
1598 root_ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
1599 proto_item_append_text(root_ti, " Control Message");
1600 tecmp_tree = proto_item_add_subtree(root_ti, ett_tecmp_payload);
1602 offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, msg_type, true, NULL, NULL, NULL);
1604 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Control Message");
1606 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_ctrl_msg_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &device_id);
1607 add_device_id_text(ti, (uint16_t)device_id);
1608 ctrl_msg_id = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN);
1609 proto_tree_add_uint_format(tecmp_tree, hf_tecmp_payload_ctrl_msg_id, tvb, offset + 2, 2, ctrl_msg_id, "Type: %s", resolve_control_message_id(ctrl_msg_id));
1610 offset += 4;
1612 proto_item_append_text(root_ti, ", %s", resolve_control_message_id(ctrl_msg_id));
1613 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", resolve_control_message_id(ctrl_msg_id));
1615 /* offset includes 16 byte header, while length is only for payload */
1616 int bytes_left = length + (unsigned)16 - (offset - offset_orig);
1617 if (bytes_left > 0) {
1618 int i;
1620 switch (ctrl_msg_id) {
1621 case TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL:
1622 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level, tvb, offset, 1, ENC_NA);
1623 proto_item_append_text(ti, "%%");
1624 offset += 1;
1626 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow, tvb, offset, 1, ENC_NA);
1627 offset += 1;
1629 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size, tvb, offset, 1, ENC_NA);
1630 offset += 1;
1632 for (i = 0; i < bytes_left - 3; i++) {
1633 uint8_t queue_level = tvb_get_uint8(tvb, offset);
1634 proto_tree_add_uint_format(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_length, tvb, offset, 1, queue_level, "Queue %d Fill Level: %d", i, queue_level);
1635 offset += 1;
1637 offset += 1;
1639 break;
1641 case TECMP_CTRL_MSG_FR_POC_STATE:
1642 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1643 add_interface_id_text_and_name(ti, interface_id, tvb, offset);
1644 offset += 4;
1646 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_flexray_poc_state, tvb, offset, 1, ENC_NA);
1647 offset += 1;
1649 break;
1651 case TECMP_CTRL_MSG_10BASE_T1S:
1652 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_10baset1s_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1653 add_interface_id_text_and_name(ti, interface_id, tvb, offset);
1654 offset += 4;
1656 static int * const data_flags_10BASE_T1S[] = {
1657 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled,
1658 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received,
1659 NULL
1662 proto_tree_add_bitmask(tecmp_tree, tvb, offset, hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags, ett_tecmp_ctrl_message_10baset1s_flags, data_flags_10BASE_T1S, ENC_BIG_ENDIAN);
1663 offset += 1;
1665 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved, tvb, offset, 1, ENC_NA);
1666 offset += 1;
1668 static int * const events_10BASE_T1S[] = {
1669 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle,
1670 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_missing,
1671 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detected,
1672 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error,
1673 &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error,
1674 NULL
1677 proto_tree_add_bitmask(tecmp_tree, tvb, offset, hf_tecmp_payload_ctrl_msg_10baset1s_10m_events, ett_tecmp_ctrl_message_10baset1s_events_errors, events_10BASE_T1S, ENC_BIG_ENDIAN);
1678 offset += 2;
1680 break;
1683 if (length + (unsigned)16 - (offset - offset_orig) > 0) {
1684 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_unparsed_bytes, tvb, offset, length + (unsigned)16 - (offset - offset_orig), ENC_NA);
1689 return offset - offset_orig;
1692 static int
1693 dissect_tecmp_status_device(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t msg_type, unsigned tecmp_msg_type) {
1694 proto_item *ti = NULL;
1695 proto_item *ti_tecmp_payload = NULL;
1696 proto_item *ti_tecmp_vendor_data = NULL;
1697 proto_item *ti_tecmp_bus = NULL;
1698 proto_tree *tecmp_tree = NULL;
1699 proto_tree *tecmp_tree_bus = NULL;
1700 tvbuff_t *sub_tvb = NULL;
1701 uint16_t length = 0;
1702 uint16_t vendor_data_len = 0;
1703 unsigned vendor_id = 0;
1704 unsigned device_type = 0;
1705 unsigned offset = offset_orig;
1706 unsigned i = 0;
1707 unsigned tmp = 0;
1708 const char *descr;
1709 uint64_t timestamp_ns;
1711 if (tvb_captured_length_remaining(tvb, offset) >= 12) {
1712 length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
1713 ti_tecmp_payload = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
1714 tecmp_tree = proto_item_add_subtree(ti_tecmp_payload, ett_tecmp_payload);
1716 offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, msg_type, true, NULL, NULL, &timestamp_ns);
1718 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_vendor_id, tvb, offset, 1, ENC_NA, &vendor_id);
1719 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_dev_version, tvb, offset + 1, 1, ENC_NA);
1720 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_dev_type, tvb, offset + 2, 1, ENC_NA, &device_type);
1721 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_res, tvb, offset + 3, 1, ENC_NA);
1722 offset += 4;
1724 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_length_vendor_data, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
1725 vendor_data_len = (uint16_t)tmp;
1726 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_device_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &tmp);
1727 add_device_id_text(ti, (uint16_t)tmp);
1728 offset += 4;
1730 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_sn, tvb, offset, 4, ENC_BIG_ENDIAN);
1731 offset += 4;
1733 switch (tecmp_msg_type) {
1734 case TECMP_MSG_TYPE_STATUS_DEV:
1735 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Device");
1736 proto_item_append_text(ti_tecmp_payload, " Status Device");
1738 if (vendor_data_len > 0) {
1739 sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
1740 ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_vendor_data, tvb, offset, (int)vendor_data_len, ENC_NA);
1742 dissect_tecmp_status_device_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, (uint8_t)device_type, (uint8_t)vendor_id, timestamp_ns);
1743 offset += vendor_data_len;
1745 break;
1747 case TECMP_MSG_TYPE_STATUS_BUS:
1748 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Bus");
1749 proto_item_append_text(ti_tecmp_payload, " Status Bus");
1751 /* bytes left - entry header (16 bytes) */
1752 length = length - (uint16_t)(offset - offset_orig - 16);
1754 ti_tecmp_bus = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_bus_data, tvb, offset, length, ENC_NA);
1755 tecmp_tree = proto_item_add_subtree(ti_tecmp_bus, ett_tecmp_status_bus_data);
1756 i = 1; /* we start the numbering of the entries with 1. */
1757 while (length >= (12 + vendor_data_len)) {
1758 ti_tecmp_bus = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_bus_data_entry, tvb, offset, 12 + vendor_data_len, ENC_NA);
1759 proto_item_append_text(ti_tecmp_bus, " %d", i);
1760 tecmp_tree_bus = proto_item_add_subtree(ti_tecmp_bus, ett_tecmp_status_bus_data_entry);
1762 ti = proto_tree_add_item_ret_uint(tecmp_tree_bus, hf_tecmp_payload_status_bus_interface_id, tvb, offset, 4, ENC_NA, &tmp);
1763 descr = ht_interface_config_to_string(tmp);
1764 if (descr != NULL) {
1765 proto_item_append_text(ti, " (%s)", descr);
1766 proto_item_append_text(ti_tecmp_bus, ": (Interface ID: 0x%08x, %s)", tmp, descr);
1767 } else {
1768 proto_item_append_text(ti_tecmp_bus, ": (Interface ID: 0x%08x)", tmp);
1771 proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_bus_total, tvb, offset + 4, 4, ENC_NA);
1772 proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_bus_errors, tvb, offset + 8, 4, ENC_NA);
1773 offset += 12;
1775 if (vendor_data_len > 0) {
1776 sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
1777 ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_vendor_data,
1778 tvb, offset, (int)vendor_data_len, ENC_NA);
1780 dissect_tecmp_status_bus_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, i, (uint8_t)device_type, (uint8_t)vendor_id);
1781 offset += vendor_data_len;
1784 i++;
1785 length -= (12 + vendor_data_len);
1787 break;
1789 case TECMP_MSG_TYPE_CFG_CM:
1790 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Configuration");
1791 proto_item_append_text(ti_tecmp_payload, " Status Configuration");
1793 if (vendor_data_len > 0) {
1794 sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
1795 ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_vendor_data, tvb,
1796 offset, (int)vendor_data_len, ENC_NA);
1798 dissect_tecmp_status_config_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, (uint8_t)device_type, (uint8_t)vendor_id);
1799 offset += vendor_data_len;
1801 break;
1803 default:
1804 proto_item_append_text(ti_tecmp_payload, " Status Device");
1807 } else {
1808 return tvb_captured_length_remaining(tvb, offset);
1811 return offset - offset_orig;
1814 static int
1815 dissect_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint16_t device_id, uint8_t msg_type, uint16_t data_type, uint32_t interface_id) {
1816 tecmp_info_t tecmp_info;
1817 int dissected_bytes;
1819 tecmp_info.interface_id = interface_id;
1820 tecmp_info.device_id = device_id;
1821 tecmp_info.data_type = data_type;
1822 tecmp_info.msg_type = msg_type;
1825 dissector_handle_t handle = dissector_get_uint_handle(data_subdissector_table, interface_id);
1826 if (handle != NULL) {
1827 dissected_bytes = call_dissector_only(handle, tvb, pinfo, tree, &tecmp_info);
1828 if (dissected_bytes > 0) {
1829 return dissected_bytes;
1833 if (tecmp_info.data_type == TECMP_DATA_TYPE_RS232_ASCII) {
1834 return call_dissector(text_lines_handle, tvb, pinfo, tree);
1835 } else {
1836 return call_data_dissector(tvb, pinfo, tree);
1840 static void
1841 dissect_ethernet_payload(tvbuff_t *sub_tvb, uint32_t offset, uint32_t length, packet_info *pinfo, proto_tree *tree, proto_tree *tecmp_tree) {
1843 tvbuff_t *payload_tvb = tvb_new_subset_length(sub_tvb, offset, length);
1845 /* resetting VLAN count since this is another embedded Ethernet packet. */
1846 p_set_proto_depth(pinfo, proto_vlan, 0);
1848 int32_t len_saved = pinfo->fd->pkt_len;
1849 pinfo->fd->pkt_len = length;
1851 if (show_ethernet_in_tecmp_tree) {
1852 call_dissector(eth_handle, payload_tvb, pinfo, tecmp_tree);
1853 } else {
1854 call_dissector(eth_handle, payload_tvb, pinfo, tree);
1857 pinfo->fd->pkt_len = len_saved;
1860 static int
1861 dissect_tecmp_log_or_replay_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig,
1862 uint16_t data_type, uint8_t tecmp_msg_type, uint16_t device_id) {
1863 proto_item *ti = NULL;
1864 proto_item *ti_tecmp = NULL;
1865 proto_tree *tecmp_tree = NULL;
1866 uint16_t length = 0;
1867 uint32_t length2 = 0;
1868 unsigned offset = offset_orig;
1869 unsigned offset2 = 0;
1870 uint16_t dataflags = 0;
1871 uint32_t tmp = 0;
1872 tvbuff_t *sub_tvb;
1873 tvbuff_t *payload_tvb;
1874 bool first = true;
1875 uint32_t interface_id = 0;
1876 uint64_t timestamp_ns = 0;
1878 double analog_value_scale_factor;
1880 struct can_info can_info;
1881 flexray_info_t fr_info;
1882 lin_info_t lin_info;
1884 static int * const tecmp_payload_id_flags_can_11[] = {
1885 &hf_tecmp_payload_data_id_type,
1886 &hf_tecmp_payload_data_id_11,
1887 NULL
1890 static int * const tecmp_payload_id_flags_can_29[] = {
1891 &hf_tecmp_payload_data_id_type,
1892 &hf_tecmp_payload_data_id_29,
1893 NULL
1896 static int * const tecmp_payload_id_flags_lin[] = {
1897 &hf_tecmp_payload_data_parity_bits,
1898 &hf_tecmp_payload_data_id_field_6bit,
1899 NULL
1902 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Payload: ");
1904 while (tvb_captured_length_remaining(tvb, offset) >= 16) {
1906 if (!tecmp_entry_header_present(tvb, offset)) {
1907 /* header not valid, we leave */
1908 break;
1911 length = tvb_get_uint16(tvb, offset+12, ENC_BIG_ENDIAN);
1912 ti_tecmp = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
1913 proto_item_append_text(ti_tecmp, " (%s)", val_to_str(data_type, tecmp_msgtype_names, "Unknown (%d)"));
1914 tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload);
1916 offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, first, &dataflags, &interface_id, &timestamp_ns);
1918 first = false;
1920 if (length > 0) {
1921 sub_tvb = tvb_new_subset_length(tvb, offset, (int)length);
1922 offset2 = 0;
1924 switch (data_type) {
1925 case TECMP_DATA_TYPE_LIN:
1926 lin_info.id = tvb_get_uint8(sub_tvb, offset2) & DATA_LIN_ID_MASK;
1928 proto_tree_add_bitmask(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_data_id_field_8bit, ett_tecmp_payload_lin_id, tecmp_payload_id_flags_lin, ENC_BIG_ENDIAN);
1929 lin_info.bus_id = ht_interface_config_to_bus_id(interface_id);
1930 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 1, 1, ENC_NA, &length2);
1931 offset2 += 2;
1933 lin_set_source_and_destination_columns(pinfo, &lin_info);
1935 if (length2 > 0 && tvb_captured_length_remaining(sub_tvb, offset2) < (int)(length2 + 1)) {
1936 expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
1937 length2 = MAX(0, MIN((int)length2, tvb_captured_length_remaining(sub_tvb, offset2) - 1));
1940 if (length2 > 0) {
1941 lin_info.len = tvb_captured_length_remaining(sub_tvb, offset2);
1942 payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
1943 uint32_t bus_frame_id = lin_info.id | (lin_info.bus_id << 16);
1944 if (!dissector_try_uint_with_data(lin_subdissector_table, bus_frame_id, payload_tvb, pinfo, tree, false, &lin_info)) {
1945 if (!dissector_try_uint_with_data(lin_subdissector_table, lin_info.id, payload_tvb, pinfo, tree, false, &lin_info)) {
1946 dissect_data(payload_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
1949 offset2 += (int)length2;
1950 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_checksum_8bit, sub_tvb, offset2, 1, ENC_NA);
1953 break;
1955 case TECMP_DATA_TYPE_CAN_DATA:
1956 case TECMP_DATA_TYPE_CAN_FD_DATA:
1957 tmp = tvb_get_uint32(sub_tvb, offset2, ENC_BIG_ENDIAN);
1958 if ((tmp & 0x80000000) == 0x80000000) {
1959 proto_tree_add_bitmask_with_flags(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_data_id_field_32bit,
1960 ett_tecmp_payload_data_id, tecmp_payload_id_flags_can_29, ENC_BIG_ENDIAN, BMT_NO_APPEND);
1961 } else {
1962 proto_tree_add_bitmask_with_flags(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_data_id_field_32bit,
1963 ett_tecmp_payload_data_id, tecmp_payload_id_flags_can_11, ENC_BIG_ENDIAN, BMT_NO_APPEND);
1965 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 4, 1, ENC_NA,
1966 &length2);
1967 offset2 += 5;
1969 if (tvb_captured_length_remaining(sub_tvb, offset2) < (int)length2) {
1970 expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
1971 length2 = MAX(0, MIN((int)length2, tvb_captured_length_remaining(sub_tvb, offset2)));
1974 if (length2 > 0) {
1975 payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
1976 offset2 += length2;
1978 can_info.fd = (data_type == TECMP_DATA_TYPE_CAN_FD_DATA) ? CAN_TYPE_CAN_FD : CAN_TYPE_CAN_CLASSIC;
1979 can_info.len = length2;
1980 can_info.bus_id = ht_interface_config_to_bus_id(interface_id);
1982 /* luckily TECMP and SocketCAN share the first bit as indicator for 11 vs 29bit Identifiers */
1983 can_info.id = tmp;
1985 if (data_type == TECMP_DATA_TYPE_CAN_DATA && (dataflags & DATA_FLAG_CAN_RTR) == DATA_FLAG_CAN_RTR) {
1986 can_info.id |= CAN_RTR_FLAG;
1989 if ((dataflags & DATA_FLAG_CAN_ERR) == DATA_FLAG_CAN_ERR) {
1990 can_info.id |= CAN_ERR_FLAG;
1993 socketcan_set_source_and_destination_columns(pinfo, &can_info);
1995 if (!socketcan_call_subdissectors(payload_tvb, pinfo, tree, &can_info, heuristic_first)) {
1996 dissect_data(payload_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2000 /* new for TECMP 1.6 */
2001 if (data_type == TECMP_DATA_TYPE_CAN_DATA && tvb_captured_length_remaining(sub_tvb, offset2) >= 2) {
2002 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc15, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2003 } else if (data_type == TECMP_DATA_TYPE_CAN_FD_DATA && tvb_captured_length_remaining(sub_tvb, offset2) >= 3) {
2004 if (length2 <= 16) {
2005 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc17, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2006 } else {
2007 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc21, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2010 break;
2012 case TECMP_DATA_TYPE_FR_DATA:
2013 /* lets set it based on config */
2014 fr_info.bus_id = ht_interface_config_to_bus_id(interface_id);
2016 /* we assume "FlexRay Channel A" since we cannot know */
2017 fr_info.ch = 0;
2019 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_cycle, sub_tvb, offset2, 1, ENC_NA, &tmp);
2020 fr_info.cc = (uint8_t)tmp;
2022 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_frame_id, sub_tvb, offset2 + 1, 2, ENC_NA, &tmp);
2023 fr_info.id = (uint16_t)tmp;
2025 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 3, 1, ENC_NA, &length2);
2026 offset2 += 4;
2028 flexray_set_source_and_destination_columns(pinfo, &fr_info);
2030 if (tvb_captured_length_remaining(sub_tvb, offset2) < (int)length2) {
2031 expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
2032 length2 = MAX(0, MIN((int)length2, tvb_captured_length_remaining(sub_tvb, offset2)));
2035 if (length2 > 0) {
2036 payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
2037 offset2 += length2;
2039 if ((dataflags & DATA_FLAG_FR_NF) != 0 || !flexray_call_subdissectors(payload_tvb, pinfo, tree, &fr_info, heuristic_first)) {
2040 dissect_data(payload_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2044 /* new for TECMP 1.6 */
2045 if (tvb_captured_length_remaining(sub_tvb, offset2) >= 5) {
2046 uint32_t header_crc = 0;
2047 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_header_crc, sub_tvb, offset2, 2, ENC_BIG_ENDIAN, &header_crc);
2048 if (header_crc > DATA_FR_HEADER_CRC_MAX) {
2049 expert_add_info(pinfo, ti, &ei_tecmp_payload_header_crc_overflow);
2051 offset2 += 2;
2052 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_frame_crc, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2054 break;
2056 case TECMP_DATA_TYPE_ILAS:
2057 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_command, sub_tvb, offset2, 1, ENC_NA);
2058 offset2 += 1;
2059 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_address, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2060 offset2 += 2;
2061 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_data, sub_tvb, offset2, 3, ENC_NA);
2062 offset2 += 3;
2063 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_raw_sdu, sub_tvb, offset2, 7, ENC_NA);
2064 offset2 += 7;
2065 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_raw_crc, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2066 break;
2068 case TECMP_DATA_TYPE_RS232_ASCII:
2069 dissect_data(sub_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2070 break;
2072 case TECMP_DATA_TYPE_ANALOG:
2073 ti_tecmp = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_samples, sub_tvb, offset2, length, ENC_NA);
2074 tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload_data);
2076 analog_value_scale_factor = tecmp_payload_analog_scale_factor_values[((dataflags & TECMP_DATAFLAGS_FACTOR_MASK) >> TECMP_DATAFLAGS_FACTOR_SHIFT)];
2078 tmp = offset2 + length;
2079 while (offset2 + 2 <= tmp) {
2080 double scaled_value;
2082 if (analog_samples_are_signed_int) {
2083 scaled_value = analog_value_scale_factor * tvb_get_int16(sub_tvb, offset2, ENC_BIG_ENDIAN);
2084 } else {
2085 scaled_value = analog_value_scale_factor * tvb_get_uint16(sub_tvb, offset2, ENC_BIG_ENDIAN);
2088 switch ((dataflags & TECMP_DATAFLAGS_UNIT_MASK) >> TECMP_DATAFLAGS_UNIT_SHIFT) {
2089 case 0x0:
2090 proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_volt, sub_tvb, offset2, 2, scaled_value);
2091 break;
2092 case 0x01:
2093 proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_amp, sub_tvb, offset2, 2, scaled_value);
2094 break;
2095 case 0x02:
2096 proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_watt, sub_tvb, offset2, 2, scaled_value);
2097 break;
2098 case 0x03:
2099 proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_amp_hour, sub_tvb, offset2, 2, scaled_value);
2100 break;
2101 case 0x04:
2102 proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_celsius, sub_tvb, offset2, 2, scaled_value);
2103 break;
2104 default:
2105 if (analog_samples_are_signed_int) {
2106 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_analog_value_raw_signed, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2107 } else {
2108 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_analog_value_raw, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2110 proto_item_append_text(ti, "%s", " (raw)");
2112 offset2 += 2;
2114 break;
2116 case TECMP_DATA_TYPE_ANALOG_ALT:
2118 /* TECMP_DATA_TYPE_ANALOG_ALT is a backport of packet-asam-cmp.c CMP_DATA_MSG_ANALOG */
2120 static int * const analog_alt_flags[] = {
2121 &hf_tecmp_payload_analog_alt_flag_reserved,
2122 &hf_tecmp_payload_analog_alt_flag_sample_dt,
2123 NULL
2126 uint64_t flags;
2127 proto_tree_add_bitmask_ret_uint64(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_analog_alt_flags, ett_tecmp_payload_analog_alt_flags, analog_alt_flags, ENC_BIG_ENDIAN, &flags);
2128 offset2 += 2;
2130 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_reserved, sub_tvb, offset2, 1, ENC_NA);
2131 offset2 += 1;
2133 unsigned analog_unit;
2134 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_analog_alt_unit, sub_tvb, offset2, 1, ENC_NA, &analog_unit);
2135 const char *unit_symbol;
2136 unit_symbol = try_val_to_str(analog_unit, analog_alt_units);
2137 offset2 += 1;
2139 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_interval, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2140 offset2 += 4;
2142 float sample_offset;
2143 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_offset, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2144 sample_offset = tvb_get_ieee_float(sub_tvb, offset2, ENC_BIG_ENDIAN);
2145 offset2 += 4;
2147 float sample_scalar;
2148 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_scalar, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2149 sample_scalar = tvb_get_ieee_float(sub_tvb, offset2, ENC_BIG_ENDIAN);
2150 offset2 += 4;
2152 ti_tecmp = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_samples, sub_tvb, offset2, length - offset2, ENC_NA);
2153 tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload_data);
2155 int data_left = length - offset2;
2156 if (data_left > 0) {
2158 switch (flags & 0x03) {
2159 case 0: /* INT16 */
2160 while (data_left >= 2) {
2161 double sample_value = ((double)tvb_get_int16(sub_tvb, offset2, ENC_BIG_ENDIAN) * sample_scalar + sample_offset);
2162 ti = proto_tree_add_double(tecmp_tree, hf_tecmp_payload_analog_alt_sample, sub_tvb, offset2, 2, sample_value);
2163 if (unit_symbol == NULL) {
2164 proto_item_append_text(ti, " (%.9f)", sample_value);
2165 } else {
2166 proto_item_append_text(ti, "%s (%.9f%s)", unit_symbol, sample_value, unit_symbol);
2168 PROTO_ITEM_SET_GENERATED(ti);
2170 proto_tree *sample_tree = proto_item_add_subtree(ti, ett_tecmp_payload_analog_alt_sample);
2171 proto_tree_add_item(sample_tree, hf_tecmp_payload_analog_alt_sample_raw, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2172 PROTO_ITEM_SET_HIDDEN(ti);
2174 data_left -= 2;
2175 offset2 += 2;
2177 break;
2178 case 1: /* INT32 */
2179 while (data_left >= 4) {
2180 double sample_value = ((double)tvb_get_int32(sub_tvb, offset2, ENC_BIG_ENDIAN) * sample_scalar + sample_offset);
2181 ti = proto_tree_add_double(tecmp_tree, hf_tecmp_payload_analog_alt_sample, sub_tvb, offset2, 4, sample_value);
2182 if (unit_symbol == NULL) {
2183 proto_item_append_text(ti, " (%.9f)", sample_value);
2184 } else {
2185 proto_item_append_text(ti, "%s (%.9f%s)", unit_symbol, sample_value, unit_symbol);
2187 PROTO_ITEM_SET_GENERATED(ti);
2189 proto_tree *sample_tree = proto_item_add_subtree(ti, ett_tecmp_payload_analog_alt_sample);
2190 ti = proto_tree_add_item(sample_tree, hf_tecmp_payload_analog_alt_sample_raw, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2191 PROTO_ITEM_SET_HIDDEN(ti);
2193 data_left -= 4;
2194 offset2 += 4;
2196 break;
2200 break;
2202 case TECMP_DATA_TYPE_ETH_RAW:
2204 length2 = length;
2205 uint32_t sub_tvb_end = offset2 + length2;
2207 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_data, sub_tvb, offset2, length2, ENC_NA);
2208 tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload_eth_raw);
2210 uint32_t preamble_length = 0;
2211 while ((preamble_length < length2) && (TECMP_ETH_RAW_PREAMBLE == tvb_get_uint8(sub_tvb, offset2 + preamble_length))) {
2212 preamble_length += 1;
2215 if (preamble_length > 0) {
2216 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_preamble, sub_tvb, offset2, preamble_length, ENC_NA);
2217 offset2 += preamble_length;
2219 if (offset2 < sub_tvb_end) {
2220 uint8_t sfd_candidate = tvb_get_uint8(sub_tvb, offset2);
2222 if (try_val_to_str(sfd_candidate, tecmp_eth_raw_sfd) != NULL) {
2223 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_sfd, sub_tvb, offset2, 1, ENC_NA);
2224 offset2 += 1;
2226 if (offset2 < sub_tvb_end) {
2227 ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_eth_frame, sub_tvb, offset2, sub_tvb_end - offset2, ENC_NA);
2228 if (sfd_candidate == TECMP_ETH_RAW_SFD_ORIG) {
2229 tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload_eth_raw_frame);
2231 dissect_ethernet_payload(sub_tvb, offset2, sub_tvb_end - offset2, pinfo, tree, tecmp_tree);
2238 break;
2240 case TECMP_DATA_TYPE_ETH_10BASE_T1S:
2241 case TECMP_DATA_TYPE_ETH:
2243 length2 = length;
2245 if (data_type == TECMP_DATA_TYPE_ETH_10BASE_T1S) {
2246 uint64_t ns = tvb_get_uint64(sub_tvb, offset2, ENC_BIG_ENDIAN);
2248 nstime_t timestamp;
2249 timestamp.secs = (time_t)(ns / 1000000000);
2250 timestamp.nsecs = (int)(ns % 1000000000);
2251 proto_tree_add_time(tecmp_tree, hf_tecmp_payload_data_beacon_timestamp, sub_tvb, offset2, 8, &timestamp);
2252 ti = proto_tree_add_uint64(tecmp_tree, hf_tecmp_payload_data_beacon_timestamp_ns, sub_tvb, offset2, 8, ns);
2253 proto_item_set_hidden(ti);
2255 ti = proto_tree_add_int64(tecmp_tree, hf_tecmp_payload_data_beacon_to_timestamp_ns, sub_tvb, offset2, 8, (int64_t)timestamp_ns - (int64_t)ns);
2256 proto_item_set_generated(ti);
2257 proto_item_set_hidden(ti);
2259 offset2 += 8;
2260 length2 -= 8;
2262 dissect_ethernet_payload(sub_tvb, offset2, length2, pinfo, tree, tecmp_tree);
2264 break;
2266 default:
2268 tecmp_info_t tecmp_info;
2269 tecmp_info.interface_id = interface_id;
2270 tecmp_info.device_id = device_id;
2271 tecmp_info.data_type = data_type;
2272 tecmp_info.data_flags = tvb_get_uint16(tvb, offset - 2, ENC_BIG_ENDIAN);
2273 tecmp_info.msg_type = tecmp_msg_type;
2275 dissector_handle_t handle = dissector_get_uint_handle(data_type_subdissector_table, data_type);
2276 if (handle != NULL) {
2277 call_dissector_only(handle, sub_tvb, pinfo, tecmp_tree, &tecmp_info);
2278 } else {
2279 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data, sub_tvb, 0, length, ENC_NA);
2284 offset += length;
2288 return offset - offset_orig;
2291 static int
2292 dissect_tecmp_counter_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t data_type, unsigned tecmp_msg_type) {
2293 proto_item *ti = NULL;
2294 proto_tree *tecmp_tree = NULL;
2295 uint16_t length = 0;
2296 unsigned offset = offset_orig;
2297 unsigned tmp = 0;
2299 if (tvb_captured_length_remaining(tvb, offset) >= (16 + 8)) {
2300 length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2301 ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2302 proto_item_append_text(ti, " Counter Event");
2303 tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload);
2305 offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, true, NULL, NULL, NULL);
2307 col_set_str(pinfo->cinfo, COL_INFO, "TECMP Counter Event");
2309 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_counter_event_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2310 add_device_id_text(ti, (uint16_t)tmp);
2311 offset += 2;
2313 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_counter_event_interface_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2314 add_interface_id_text_and_name(ti, tmp, tvb, offset);
2315 offset += 2;
2317 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_counter_event_counter_last, tvb, offset, 2, ENC_BIG_ENDIAN);
2318 offset += 2;
2320 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_counter_event_counter_cur, tvb, offset, 2, ENC_BIG_ENDIAN);
2321 offset += 2;
2324 return offset - offset_orig;
2327 static int
2328 dissect_tecmp_timesync_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t data_type, unsigned tecmp_msg_type) {
2329 proto_item *ti = NULL;
2330 proto_tree *tecmp_tree = NULL;
2331 uint16_t length = 0;
2332 unsigned offset = offset_orig;
2333 unsigned tmp = 0;
2335 if (tvb_captured_length_remaining(tvb, offset) >= (16 + 8)) {
2336 length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2337 ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2338 proto_item_append_text(ti, " TimeSync Event");
2339 tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload);
2341 offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, true, NULL, NULL, NULL);
2343 col_set_str(pinfo->cinfo, COL_INFO, "TECMP TimeSync Event");
2345 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_timesync_event_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2346 add_device_id_text(ti, (uint16_t)tmp);
2347 offset += 2;
2349 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_timesync_event_interface_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2350 add_interface_id_text_and_name(ti, tmp, tvb, offset);
2351 offset += 2;
2353 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
2354 offset += 2;
2356 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_async, tvb, offset, 1, ENC_NA);
2357 offset += 1;
2359 proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_time_delta, tvb, offset, 1, ENC_NA);
2360 offset += 1;
2363 return offset - offset_orig;
2366 static int
2367 dissect_tecmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
2368 proto_item *ti = NULL;
2369 proto_item *ti_root = NULL;
2370 proto_tree *tecmp_tree = NULL;
2371 unsigned offset = 0;
2372 unsigned tecmp_type = 0;
2373 unsigned data_type = 0;
2374 unsigned device_id = 0;
2376 static int * const tecmp_flags[] = {
2377 &hf_tecmp_flags_eos,
2378 &hf_tecmp_flags_sos,
2379 &hf_tecmp_flags_spy,
2380 &hf_tecmp_flags_multi_frame,
2381 &hf_tecmp_flags_dev_overflow,
2382 NULL
2385 /* ASAM CMP is the successor of TECMP and uses the same EtherType.
2387 * How to detect what the message is:
2388 * The first byte in TECMP 1.7 and later is always 0.
2389 * The first byte in TECMP 1.6 and older allowed 0xff for user-defined IDs.
2390 * The first byte in ASAM CMP is defined as version and is required to be > 0.
2391 * If the first byte is not 0, we pass it be ASAM CMP.
2392 * For backward compatibility: If 0xff allow as TECMP.
2394 if ( (detect_asam_cmp && asam_cmp_handle != 0 && tvb_get_uint8(tvb, offset) != 0) &&
2395 (!detect_asam_cmp_ignore_user_defined || tvb_get_uint8(tvb, offset) != 0xff) ) {
2396 return call_dissector_with_data(asam_cmp_handle, tvb, pinfo, tree, data);
2399 col_clear(pinfo->cinfo, COL_INFO);
2400 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TECMP");
2401 ti_root = proto_tree_add_item(tree, proto_tecmp, tvb, 0, -1, ENC_NA);
2402 tecmp_tree = proto_item_add_subtree(ti_root, ett_tecmp);
2404 if (!proto_field_is_referenced(tree, proto_tecmp)) {
2405 tecmp_tree = NULL;
2408 ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &device_id);
2409 add_device_id_text(ti, (uint16_t)device_id);
2410 offset += 2;
2412 proto_tree_add_item(tecmp_tree, hf_tecmp_counter, tvb, offset, 2, ENC_BIG_ENDIAN);
2413 offset += 2;
2415 proto_tree_add_item(tecmp_tree, hf_tecmp_version, tvb, offset, 1, ENC_NA);
2416 offset += 1;
2418 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_msgtype, tvb, offset, 1, ENC_NA, &tecmp_type);
2419 offset += 1;
2421 proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_data_type, tvb, offset, 2, ENC_BIG_ENDIAN, &data_type);
2422 offset += 2;
2424 proto_tree_add_item(tecmp_tree, hf_tecmp_res, tvb, offset, 2, ENC_BIG_ENDIAN);
2425 offset += 2;
2427 proto_tree_add_bitmask(tecmp_tree, tvb, offset, hf_tecmp_flags, ett_tecmp_flags, tecmp_flags,
2428 ENC_BIG_ENDIAN);
2429 offset += 2;
2431 switch (tecmp_type) {
2432 case TECMP_MSG_TYPE_CTRL_MSG:
2433 offset += dissect_tecmp_control_msg(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
2434 break;
2436 case TECMP_MSG_TYPE_STATUS_BUS:
2437 case TECMP_MSG_TYPE_CFG_CM:
2438 case TECMP_MSG_TYPE_STATUS_DEV:
2439 offset += dissect_tecmp_status_device(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
2440 break;
2442 case TECMP_MSG_TYPE_LOG_STREAM:
2443 case TECMP_MSG_TYPE_REPLAY_DATA:
2444 offset += dissect_tecmp_log_or_replay_stream(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type, (uint16_t)device_id);
2445 break;
2447 case TECMP_MSG_TYPE_COUNTER_EVENT:
2448 offset += dissect_tecmp_counter_event(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
2449 break;
2451 case TECMP_MSG_TYPE_TIMESYNC_EVENT:
2452 offset += dissect_tecmp_timesync_event(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
2453 break;
2457 proto_item_set_end(ti_root, tvb, offset);
2458 return offset;
2461 void
2462 proto_register_tecmp_payload(void) {
2463 expert_module_t *expert_module_tecmp_payload;
2465 static hf_register_info hf[] = {
2466 { &hf_tecmp_payload_interface_id,
2467 { "Interface ID", "tecmp.payload.interface_id",
2468 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2469 { &hf_tecmp_payload_interface_name,
2470 { "Interface Name", "tecmp.payload.interface_name",
2471 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2472 { &hf_tecmp_payload_timestamp,
2473 { "Timestamp", "tecmp.payload.timestamp",
2474 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL }},
2475 { &hf_tecmp_payload_timestamp_async,
2476 { "Timestamp Synchronisation Status", "tecmp.payload.timestamp_synch_status",
2477 FT_BOOLEAN, 8, TFS(&tfs_tecmp_payload_timestamp_async_type), 0x80, NULL, HFILL }},
2478 { &hf_tecmp_payload_timestamp_res,
2479 { "Timestamp Synchronisation reserved", "tecmp.payload.timestamp_reserved",
2480 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
2481 { &hf_tecmp_payload_timestamp_ns,
2482 { "Timestamp ns", "tecmp.payload.timestamp_ns",
2483 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2485 { &hf_tecmp_payload_length,
2486 { "Length", "tecmp.payload.length",
2487 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2488 { &hf_tecmp_payload_data,
2489 { "Data", "tecmp.payload.data",
2490 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2491 { &hf_tecmp_payload_samples,
2492 { "Samples", "tecmp.payload.samples",
2493 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2495 { &hf_tecmp_payload_data_ethernet_raw_data,
2496 { "Raw Data", "tecmp.payload.ethernet_raw.data",
2497 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2498 { &hf_tecmp_payload_data_ethernet_raw_preamble,
2499 { "Preamble", "tecmp.payload.ethernet_raw.preamble",
2500 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2501 { &hf_tecmp_payload_data_ethernet_raw_sfd,
2502 { "SFD", "tecmp.payload.ethernet_raw.sfd",
2503 FT_UINT8, BASE_HEX, VALS(tecmp_eth_raw_sfd), 0x0, NULL, HFILL }},
2504 { &hf_tecmp_payload_data_ethernet_raw_eth_frame,
2505 { "Ethernet Frame", "tecmp.payload.ethernet_raw.ethernet_frame",
2506 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2508 { &hf_tecmp_payload_data_beacon_timestamp,
2509 { "Beacon Timestamp", "tecmp.payload.beacon_timestamp",
2510 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL }},
2511 { &hf_tecmp_payload_data_beacon_timestamp_ns,
2512 { "Beacon Timestamp ns", "tecmp.payload.beacon_timestamp_ns",
2513 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2514 { &hf_tecmp_payload_data_beacon_to_timestamp_ns,
2515 { "Beacon to Timestamp ns", "tecmp.payload.beacon_to_timestamp_ns",
2516 FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2517 { &hf_tecmp_payload_data_id_field_8bit,
2518 { "ID", "tecmp.payload.data.lin_id_with_parity",
2519 FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
2520 { &hf_tecmp_payload_data_id_field_6bit,
2521 { "LIN ID", "tecmp.payload.data.lin_id",
2522 FT_UINT8, BASE_HEX_DEC, NULL, DATA_LIN_ID_MASK, NULL, HFILL }},
2523 { &hf_tecmp_payload_data_parity_bits,
2524 { "Parity Bits", "tecmp.payload.data.lin_parity_bits",
2525 FT_UINT8, BASE_HEX_DEC, NULL, 0xc0, NULL, HFILL }},
2526 { &hf_tecmp_payload_data_checksum_8bit,
2527 { "Checksum", "tecmp.payload.data.checksum",
2528 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2530 { &hf_tecmp_payload_data_id_field_32bit,
2531 { "ID Field", "tecmp.payload.data.can_id_field",
2532 FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
2533 { &hf_tecmp_payload_data_id_type,
2534 { "CAN ID Type", "tecmp.payload.data.can_id_type",
2535 FT_BOOLEAN, 32, TFS(&tfs_tecmp_payload_data_id_type), 0x80000000, NULL, HFILL }},
2536 { &hf_tecmp_payload_data_id_11,
2537 { "ID (11bit)", "tecmp.payload.data.can_id_11",
2538 FT_UINT32, BASE_HEX_DEC, NULL, 0x000007FF, NULL, HFILL }},
2539 { &hf_tecmp_payload_data_id_29,
2540 { "ID (29bit)", "tecmp.payload.data.can_id_29",
2541 FT_UINT32, BASE_HEX_DEC, NULL, 0x1FFFFFFF, NULL, HFILL }},
2542 { &hf_tecmp_payload_data_crc15,
2543 { "CRC15", "tecmp.payload.data.crc15",
2544 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2545 { &hf_tecmp_payload_data_crc17,
2546 { "CRC17", "tecmp.payload.data.crc17",
2547 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2548 { &hf_tecmp_payload_data_crc21,
2549 { "CRC21", "tecmp.payload.data.crc21",
2550 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2552 { &hf_tecmp_payload_data_cycle,
2553 { "Cycle", "tecmp.payload.data.cycle",
2554 FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
2555 { &hf_tecmp_payload_data_frame_id,
2556 { "Frame ID", "tecmp.payload.data.frame_id",
2557 FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
2558 { &hf_tecmp_payload_data_header_crc,
2559 { "Header CRC", "tecmp.payload.data.header_crc",
2560 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2561 { &hf_tecmp_payload_data_frame_crc,
2562 { "Frame CRC", "tecmp.payload.data.frame_crc",
2563 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2565 { &hf_tecmp_payload_data_length,
2566 { "Payload Length", "tecmp.payload.data.payload_length",
2567 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2569 { &hf_tecmp_payload_data_flags,
2570 { "Data Flags", "tecmp.payload.data_flags",
2571 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2572 { &hf_tecmp_payload_data_flags_crc,
2573 { "CRC Error", "tecmp.payload.data_flags.crc_error",
2574 FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL }},
2575 { &hf_tecmp_payload_data_flags_checksum,
2576 { "Checksum Error", "tecmp.payload.data_flags.checksum_error",
2577 FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL }},
2578 { &hf_tecmp_payload_data_flags_tx,
2579 { "TX (sent by Device)", "tecmp.payload.data_flags.tx",
2580 FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL }},
2581 { &hf_tecmp_payload_data_flags_overflow,
2582 { "Overflow (lost data)", "tecmp.payload.data_flags.Overflow",
2583 FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL }},
2585 /* Control Message */
2586 { &hf_tecmp_payload_ctrl_msg_device_id,
2587 { "Device ID", "tecmp.payload.ctrl_msg.device_id",
2588 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2589 { &hf_tecmp_payload_ctrl_msg_id,
2590 { "Control Message ID", "tecmp.payload.ctrl_msg.id",
2591 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2592 { &hf_tecmp_payload_ctrl_msg_unparsed_bytes,
2593 { "Unparsed Bytes", "tecmp.payload.ctrl_msg.unparsed",
2594 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2596 /* Control Message: CAN Replay Fill Level */
2597 { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level,
2598 { "Fill Level RAM", "tecmp.payload.ctrl_msg.can_replay_fill_level.fill_level_ram",
2599 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2600 { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow,
2601 { "Buffer Overflow RAM", "tecmp.payload.ctrl_msg.can_replay_fill_level.buffer_overflow_ram",
2602 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2603 { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size,
2604 { "Queue Size", "tecmp.payload.ctrl_msg.can_replay_fill_level.queue_size",
2605 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2606 { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_length,
2607 { "Queue Fill Level", "tecmp.payload.ctrl_msg.can_replay_fill_level.queue_fill_level",
2608 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2610 /* Control Message: FlexRay POC State */
2611 { &hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id,
2612 { "Interface ID", "tecmp.payload.ctrl_msg.flexray_poc.interface_id",
2613 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2614 { &hf_tecmp_payload_ctrl_msg_flexray_poc_state,
2615 { "Protocol Operation Control State", "tecmp.payload.ctrl_msg.flexray_poc.state",
2616 FT_UINT8, BASE_DEC, VALS(tecmp_ctrl_msg_fr_poc_state), 0x0, NULL, HFILL } },
2618 /* Control Message: 10BASE-T1S */
2619 { &hf_tecmp_payload_ctrl_msg_10baset1s_interface_id,
2620 { "Interface ID", "tecmp.payload.ctrl_msg.10baset1s.interface_id",
2621 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2622 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags,
2623 { "Flags", "tecmp.payload.ctrl_msg.10baset1s.flags",
2624 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2625 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received,
2626 { "Beacons Received", "tecmp.payload.ctrl_msg.10baset1s.flags.beacons_received",
2627 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL } },
2628 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled,
2629 { "PLCA Enabled", "tecmp.payload.ctrl_msg.10baset1s.flags.plca_enabled",
2630 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, NULL, HFILL } },
2631 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved,
2632 { "Reserved", "tecmp.payload.ctrl_msg.10baset1s.reserved",
2633 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2634 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events,
2635 { "Events/Errors", "tecmp.payload.ctrl_msg.10baset1s.events",
2636 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2637 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error,
2638 { "5B Decode Error", "tecmp.payload.ctrl_msg.10baset1s.events.5b_decode_error",
2639 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001, NULL, HFILL } },
2640 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error,
2641 { "End of Stream Delimiter Error", "tecmp.payload.ctrl_msg.10baset1s.events.end_of_stream_delimiter_error",
2642 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002, NULL, HFILL } },
2643 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detected,
2644 { "PLCA Symbols Detected", "tecmp.payload.ctrl_msg.10baset1s.events.plca_symbols_detected",
2645 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004, NULL, HFILL } },
2646 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_missing,
2647 { "PLCA Symbols Missing", "tecmp.payload.ctrl_msg.10baset1s.events.plca_symbols_missing",
2648 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008, NULL, HFILL } },
2649 { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle,
2650 { "PLCA Empty Cycle", "tecmp.payload.ctrl_msg.10baset1s.events.plca_empty_cycle",
2651 FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0010, NULL, HFILL } },
2653 /* Status Device / Status Bus / Status Configuration */
2654 { &hf_tecmp_payload_status_vendor_id,
2655 { "Vendor ID", "tecmp.payload.status.vendor_id",
2656 FT_UINT8, BASE_HEX, VALS(tecmp_vendor_ids), 0x0, NULL, HFILL }},
2657 { &hf_tecmp_payload_status_dev_version,
2658 { "Device Version", "tecmp.payload.status.device_version",
2659 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2660 { &hf_tecmp_payload_status_dev_type,
2661 { "Device Type", "tecmp.payload.status.device_type",
2662 FT_UINT8, BASE_HEX, VALS(tecmp_device_types), 0x0, NULL, HFILL }},
2663 { &hf_tecmp_payload_status_res,
2664 { "Reserved", "tecmp.payload.status.reserved",
2665 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2666 { &hf_tecmp_payload_status_length_vendor_data,
2667 { "Length of Vendor Data", "tecmp.payload.status.vdata_len",
2668 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2669 { &hf_tecmp_payload_status_device_id,
2670 { "Device ID", "tecmp.payload.status.device_id",
2671 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2672 { &hf_tecmp_payload_status_sn,
2673 { "Serial Number", "tecmp.payload.status.sn",
2674 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2675 { &hf_tecmp_payload_status_vendor_data,
2676 { "Vendor Data", "tecmp.payload.status.vendor_data",
2677 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2678 { &hf_tecmp_payload_status_bus_data,
2679 { "Bus Data", "tecmp.payload.status.bus_data",
2680 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2681 { &hf_tecmp_payload_status_bus_data_entry,
2682 { "Bus Data Entry", "tecmp.payload.status.bus_data_entry",
2683 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2684 { &hf_tecmp_payload_status_bus_interface_id,
2685 { "Interface ID", "tecmp.payload.status.bus.interface_id",
2686 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2687 { &hf_tecmp_payload_status_bus_total,
2688 { "Messages Total", "tecmp.payload.status.bus.total",
2689 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2690 { &hf_tecmp_payload_status_bus_errors,
2691 { "Errors Total", "tecmp.payload.status.bus.errors",
2692 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2694 /* Status Device Vendor Data */
2695 { &hf_tecmp_payload_status_dev_vendor_technica_res,
2696 { "Reserved", "tecmp.payload.status_dev.vendor_technica.res",
2697 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2698 { &hf_tecmp_payload_status_dev_vendor_technica_sw,
2699 { "Software Version", "tecmp.payload.status_dev.vendor_technica.sw_version",
2700 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2701 { &hf_tecmp_payload_status_dev_vendor_technica_hw,
2702 { "Hardware Version", "tecmp.payload.status_dev.vendor_technica.hw_version",
2703 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2704 { &hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level,
2705 { "Buffer Fill Level", "tecmp.payload.status_dev.vendor_technica.buffer_fill_level",
2706 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2707 { &hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow,
2708 { "Buffer Overflow", "tecmp.payload.status_dev.vendor_technica.buffer_overflow",
2709 FT_BOOLEAN, BASE_NONE, TFS(&tfs_tecmp_technica_bufferoverflow), 0x0, NULL, HFILL }},
2710 { &hf_tecmp_payload_status_dev_vendor_technica_buffer_size,
2711 { "Buffer Size", "tecmp.payload.status_dev.vendor_technica.buffer_size",
2712 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2713 { &hf_tecmp_payload_status_dev_vendor_technica_lifecycle,
2714 { "Lifecycle", "tecmp.payload.status_dev.vendor_technica.lifecycle",
2715 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2716 { &hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start,
2717 { "Lifecycle Start", "tecmp.payload.status_dev.vendor_technica.lifecycle.start",
2718 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
2719 { &hf_tecmp_payload_status_dev_vendor_technica_voltage,
2720 { "Voltage", "tecmp.payload.status_dev.vendor_technica.voltage",
2721 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL } },
2722 { &hf_tecmp_payload_status_dev_vendor_technica_temperature,
2723 { "Temperature", "tecmp.payload.status_dev.vendor_technica.temperature",
2724 FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL }},
2725 { &hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis,
2726 { "Temperature Chassis", "tecmp.payload.status_dev.vendor_technica.temperature_chassis",
2727 FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL }},
2728 { &hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon,
2729 { "Temperature Silicon", "tecmp.payload.status_dev.vendor_technica.temperature_silicon",
2730 FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL }},
2732 /* Status Bus Vendor Data */
2733 { &hf_tecmp_payload_status_bus_vendor_technica_link_status,
2734 { "Link Status", "tecmp.payload.status.bus.vendor_technica.link_status",
2735 FT_UINT8, BASE_DEC, VALS(tecmp_bus_status_link_status), 0x0, NULL, HFILL }},
2736 { &hf_tecmp_payload_status_bus_vendor_technica_link_quality,
2737 { "Link Quality", "tecmp.payload.status.bus.vendor_technica.link_quality",
2738 FT_UINT8, BASE_DEC, VALS(tecmp_bus_status_link_quality), 0x0, NULL, HFILL }},
2739 { &hf_tecmp_payload_status_bus_vendor_technica_linkup_time,
2740 { "Linkup Time", "tecmp.payload.status.bus.vendor_technica.linkup_time",
2741 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2743 { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags,
2744 { "Flags", "tecmp.payload.status.bus.vendor_technica.flags",
2745 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2746 { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beacons_received,
2747 { "Beacons Received", "tecmp.payload.status.bus.vendor_technica.flags.beacons_received",
2748 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL } },
2749 { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_enabled,
2750 { "PLCA Enabled", "tecmp.payload.status.bus.vendor_technica.flags.plca_enabled",
2751 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, NULL, HFILL } },
2752 { &hf_tecmp_payload_status_bus_vendor_technica_res0,
2753 { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_0",
2754 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2755 { &hf_tecmp_payload_status_bus_vendor_technica_beacon_counter,
2756 { "Beacon Counter", "tecmp.payload.status.bus.vendor_technica.beacon_counter",
2757 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2758 { &hf_tecmp_payload_status_bus_vendor_technica_res1,
2759 { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_1",
2760 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2761 { &hf_tecmp_payload_status_bus_vendor_technica_res2,
2762 { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_2",
2763 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2764 { &hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt,
2765 { "5B Decode Error Count", "tecmp.payload.status.bus.vendor_technica.5b_decode_err_count",
2766 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2767 { &hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt,
2768 { "End of Stream Delimiter Error Count", "tecmp.payload.status.bus.vendor_technica.eos_delim_err_count",
2769 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2770 { &hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_detected_cnt,
2771 { "PLCA Symbols Detected Count", "tecmp.payload.status.bus.vendor_technica.plca_symbols_detected_count",
2772 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2773 { &hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_missing_cnt,
2774 { "PLCA Symbols Missing Count", "tecmp.payload.status.bus.vendor_technica.plca_symbols_missing_count",
2775 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2776 { &hf_tecmp_payload_status_bus_vendor_technica_plca_symbols_empty_cycle_cnt,
2777 { "PLCA Empty Cycle Count", "tecmp.payload.status.bus.vendor_technica.plca_empty_cycle_count",
2778 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2780 /* Status Config Vendor Data */
2781 { &hf_tecmp_payload_status_cfg_vendor_technica_version,
2782 { "Version", "tecmp.payload.status.config.vendor_technica.version",
2783 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2784 { &hf_tecmp_payload_status_cfg_vendor_technica_reserved,
2785 { "Reserved", "tecmp.payload.status.config.vendor_technica.res",
2786 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2787 { &hf_tecmp_payload_status_cfg_vendor_technica_msg_id,
2788 { "Message ID", "tecmp.payload.status.config.vendor_technica.message_id",
2789 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2790 { &hf_tecmp_payload_status_cfg_vendor_technica_total_length,
2791 { "Total Length", "tecmp.payload.status.config.vendor_technica.total_length",
2792 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2793 { &hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg,
2794 { "Total Number of Segments", "tecmp.payload.status.config.vendor_technica.total_number_segments",
2795 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2796 { &hf_tecmp_payload_status_cfg_vendor_technica_segment_num,
2797 { "Segment Number", "tecmp.payload.status.config.vendor_technica.segment_number",
2798 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2799 { &hf_tecmp_payload_status_cfg_vendor_technica_segment_length,
2800 { "Segment Length", "tecmp.payload.status.config.vendor_technica.segment_length",
2801 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2802 { &hf_tecmp_payload_status_cfg_vendor_technica_segment_data,
2803 { "Segment Data", "tecmp.payload.status.config.vendor_technica.segment_data",
2804 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2806 /* ILaS */
2807 { &hf_tecmp_payload_data_flags_crc_enabled,
2808 { "CRC Received", "tecmp.payload.data_flags.crc_received",
2809 FT_BOOLEAN, 16, TFS(&tfs_tecmp_payload_data_crc_received), 0x0001, NULL, HFILL } },
2810 { &hf_tecmp_payload_data_flags_direction,
2811 { "Direction", "tecmp.payload.data_flags.direction",
2812 FT_BOOLEAN, 16, TFS(&tfs_tecmp_payload_data_direction), 0x0002, NULL, HFILL } },
2814 /* Ethernet 10BASE-T1S */
2815 { &hf_tecmp_payload_data_flags_phy_event_error,
2816 { "PHY Event/Error", "tecmp.payload.data_flags.phy_event_error",
2817 FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL } },
2819 /* LIN */
2820 { &hf_tecmp_payload_data_flags_coll,
2821 { "Collision", "tecmp.payload.data_flags.collision",
2822 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
2823 { &hf_tecmp_payload_data_flags_parity,
2824 { "Parity Error", "tecmp.payload.data_flags.parity_error",
2825 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
2826 { &hf_tecmp_payload_data_flags_no_resp,
2827 { "No Slave Response", "tecmp.payload.data_flags.no_resp",
2828 FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }},
2829 { &hf_tecmp_payload_data_flags_wup,
2830 { "Wake Up Signal", "tecmp.payload.data_flags.wup",
2831 FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL }},
2832 { &hf_tecmp_payload_data_flags_short_wup,
2833 { "Short Wake Up Signal", "tecmp.payload.data_flags.short_wup",
2834 FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL }},
2835 { &hf_tecmp_payload_data_flags_sleep,
2836 { "Sleep Signal", "tecmp.payload.data_flags.sleep",
2837 FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL }},
2839 /* CAN DATA, CAN-FD Data */
2840 { &hf_tecmp_payload_data_flags_ack,
2841 { "Ack'ed", "tecmp.payload.data_flags.ack",
2842 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ACK, NULL, HFILL }},
2843 { &hf_tecmp_payload_data_flags_rtr,
2844 { "Remote Frame", "tecmp.payload.data_flags.rtr",
2845 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_RTR, NULL, HFILL }},
2846 { &hf_tecmp_payload_data_flags_esi,
2847 { "Error Node Active", "tecmp.payload.data_flags.esi",
2848 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_ESI, NULL, HFILL }},
2849 { &hf_tecmp_payload_data_flags_ide,
2850 { "Extended CAN-ID", "tecmp.payload.data_flags.ext_can_id",
2851 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_IDE, NULL, HFILL }},
2852 { &hf_tecmp_payload_data_flags_err,
2853 { "Error Frame", "tecmp.payload.data_flags.error_frame",
2854 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ERR, NULL, HFILL }},
2855 { &hf_tecmp_payload_data_flags_brs,
2856 { "Bit Rate Switch", "tecmp.payload.data_flags.bit_rate_switch",
2857 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_BRS, NULL, HFILL }},
2859 { &hf_tecmp_payload_data_flags_can_bit_stuff_err,
2860 { "Bit Stuff Error", "tecmp.payload.data_flags.bit_stuff_error",
2861 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_BIT_STUFF_ERR, NULL, HFILL }},
2862 { &hf_tecmp_payload_data_flags_can_crc_del_err,
2863 { "CRC Delimiter Error", "tecmp.payload.data_flags.crc_del_error",
2864 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_CRC_DEL_ERR, NULL, HFILL }},
2865 { &hf_tecmp_payload_data_flags_can_ack_del_err,
2866 { "Ack Delimiter Error", "tecmp.payload.data_flags.ack_del_error",
2867 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ACK_DEL_ERR, NULL, HFILL }},
2868 { &hf_tecmp_payload_data_flags_can_eof_err,
2869 { "End of Frame Field Error", "tecmp.payload.data_flags.eof_error",
2870 FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_EOF_ERR, NULL, HFILL }},
2871 { &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,
2872 { "Bit Stuff Error", "tecmp.payload.data_flags.bit_stuff_error",
2873 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_BIT_STUFF_ERR, NULL, HFILL }},
2874 { &hf_tecmp_payload_data_flags_canfd_crc_del_err,
2875 { "CRC Delimiter Error", "tecmp.payload.data_flags.crc_del_error",
2876 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_CRC_DEL_ERR, NULL, HFILL }},
2877 { &hf_tecmp_payload_data_flags_canfd_ack_del_err,
2878 { "Ack Delimiter Error", "tecmp.payload.data_flags.ack_del_error",
2879 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_ACK_DEL_ERR, NULL, HFILL }},
2880 { &hf_tecmp_payload_data_flags_canfd_eof_err,
2881 { "End of Frame Field Error", "tecmp.payload.data_flags.eof_error",
2882 FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_EOF_ERR, NULL, HFILL }},
2884 /* FlexRay Data */
2885 { &hf_tecmp_payload_data_flags_nf,
2886 { "Null Frame", "tecmp.payload.data_flags.null_frame",
2887 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_NF, NULL, HFILL }},
2888 { &hf_tecmp_payload_data_flags_sf,
2889 { "Startup Frame", "tecmp.payload.data_flags.startup_frame",
2890 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_ST, NULL, HFILL }},
2891 { &hf_tecmp_payload_data_flags_sync,
2892 { "Sync Frame", "tecmp.payload.data_flags.sync_frame",
2893 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_SYNC, NULL, HFILL }},
2894 { &hf_tecmp_payload_data_flags_wus,
2895 { "Wakeup Symbol", "tecmp.payload.data_flags.wakeup_symbol",
2896 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_WUS, NULL, HFILL }},
2897 { &hf_tecmp_payload_data_flags_ppi,
2898 { "Payload Preamble Indicator", "tecmp.payload.data_flags.payload_preamble_indicator",
2899 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_PPI, NULL, HFILL }},
2900 { &hf_tecmp_payload_data_flags_cas,
2901 { "Collision Avoidance Symbol", "tecmp.payload.data_flags.collision_avoidance_symbol",
2902 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_CAS, NULL, HFILL }},
2903 { &hf_tecmp_payload_data_flags_header_crc_err,
2904 { "Header CRC Error", "tecmp.payload.data_flags.header_crc_error",
2905 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_HDR_CRC_ERR, NULL, HFILL }},
2906 { &hf_tecmp_payload_data_flags_frame_crc_err,
2907 { "Frame CRC Error", "tecmp.payload.data_flags.frame_crc_error",
2908 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_FRAME_CRC_ERR, NULL, HFILL }},
2910 /* UART/RS232 ASCII */
2911 { &hf_tecmp_payload_data_flags_dl,
2912 { "DL", "tecmp.payload.data_flags.dl",
2913 FT_UINT16, BASE_DEC, VALS(tecmp_payload_rs232_uart_dl_types), 0x000e, NULL, HFILL }},
2914 { &hf_tecmp_payload_data_flags_parity_error,
2915 { "Parity Error", "tecmp.payload.data_flags.parity_error",
2916 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
2918 /* Analog */
2919 { &hf_tecmp_payload_data_flags_sample_time,
2920 { "Sample Time", "tecmp.payload.data_flags.sample_time",
2921 FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_sample_time_types), 0x7800, NULL, HFILL }},
2922 { &hf_tecmp_payload_data_flags_factor,
2923 { "Factor", "tecmp.payload.data_flags.factor",
2924 FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_scale_factor_types), TECMP_DATAFLAGS_FACTOR_MASK, NULL, HFILL }},
2925 { &hf_tecmp_payload_data_flags_unit,
2926 { "Unit", "tecmp.payload.data_flags.unit",
2927 FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_unit_types), TECMP_DATAFLAGS_UNIT_MASK, NULL, HFILL }},
2928 { &hf_tecmp_payload_data_flags_threshold_u,
2929 { "Threshold Undershot (deprecated)", "tecmp.payload.data_flags.threshold_undershot",
2930 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
2931 { &hf_tecmp_payload_data_flags_threshold_o,
2932 { "Threshold Exceeded (deprecated)", "tecmp.payload.data_flags.threshold_exceeded",
2933 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
2934 { &hf_tecmp_payload_data_analog_value_raw,
2935 { "Analog Value", "tecmp.payload.data.analog_value",
2936 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2937 { &hf_tecmp_payload_data_analog_value_raw_signed,
2938 { "Analog Value", "tecmp.payload.data.analog_value_signed",
2939 FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2940 { &hf_tecmp_payload_data_analog_value_volt,
2941 { "Analog Value", "tecmp.payload.data.analog_value_volt",
2942 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL }},
2943 { &hf_tecmp_payload_data_analog_value_amp,
2944 { "Analog Value", "tecmp.payload.data.analog_value_amp",
2945 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_amp), 0x0, NULL, HFILL }},
2946 { &hf_tecmp_payload_data_analog_value_watt,
2947 { "Analog Value", "tecmp.payload.data.analog_value_watt",
2948 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_watt), 0x0, NULL, HFILL }},
2949 { &hf_tecmp_payload_data_analog_value_amp_hour,
2950 { "Analog Value", "tecmp.payload.data.analog_value_amp_hour",
2951 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&tecmp_units_amp_hour), 0x0, NULL, HFILL }},
2952 { &hf_tecmp_payload_data_analog_value_celsius,
2953 { "Analog Value", "tecmp.payload.data.analog_value_celsius",
2954 FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL }},
2956 /* Analog Alt */
2957 { &hf_tecmp_payload_analog_alt_flags,
2958 { "Flags", "tecmp.payload.analog_alt.flags",
2959 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2960 { &hf_tecmp_payload_analog_alt_flag_sample_dt,
2961 { "Sample Datatype", "tecmp.payload.analog_alt.flags.sample_dt",
2962 FT_UINT16, BASE_HEX, VALS(analog_alt_sample_dt), 0x0003, NULL, HFILL } },
2963 { &hf_tecmp_payload_analog_alt_flag_reserved,
2964 { "Reserved", "tecmp.payload.analog_alt.flags.reserved",
2965 FT_UINT16, BASE_HEX, NULL, 0xfffc, NULL, HFILL } },
2967 { &hf_tecmp_payload_analog_alt_reserved,
2968 { "Reserved", "tecmp.payload.analog_alt.reserved",
2969 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2970 { &hf_tecmp_payload_analog_alt_unit,
2971 { "Unit", "tecmp.payload.analog_alt.unit",
2972 FT_UINT8, BASE_HEX, VALS(analog_alt_units), 0x0, NULL, HFILL } },
2973 { &hf_tecmp_payload_analog_alt_sample_interval,
2974 { "Sample Interval", "tecmp.payload.analog_alt.sample_interval",
2975 FT_FLOAT, BASE_NONE | BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL } },
2976 { &hf_tecmp_payload_analog_alt_sample_offset,
2977 { "Sample Offset", "tecmp.payload.analog_alt.sample_offset",
2978 FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2979 { &hf_tecmp_payload_analog_alt_sample_scalar,
2980 { "Sample Scalar", "tecmp.payload.analog_alt.sample_scalar",
2981 FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2982 { &hf_tecmp_payload_analog_alt_sample_raw,
2983 { "Sample Raw", "tecmp.payload.analog_alt.sample_raw",
2984 FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2985 { &hf_tecmp_payload_analog_alt_sample,
2986 { "Sample", "tecmp.payload.analog_alt.sample",
2987 FT_DOUBLE, BASE_EXP, NULL, 0x0, NULL, HFILL } },
2989 /* ILaS */
2990 { &hf_tecmp_payload_data_ilas_decoded_command,
2991 { "Decoded API Command", "tecmp.payload.ilas_decoded_command",
2992 FT_UINT8, BASE_DEC, VALS(tecmp_ilas_command_types), 0x0, NULL, HFILL } },
2993 { &hf_tecmp_payload_data_ilas_decoded_address,
2994 { "Decoded Address", "tecmp.payload.ilas_decoded_address",
2995 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2996 { &hf_tecmp_payload_data_ilas_decoded_data,
2997 { "Decoded Data", "tecmp.payload.ilas_decoded_data",
2998 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2999 { &hf_tecmp_payload_data_ilas_raw_sdu,
3000 { "Raw SDU", "tecmp.payload.ilas_raw_sdu",
3001 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3002 { &hf_tecmp_payload_data_ilas_raw_crc,
3003 { "Raw CRC", "tecmp.payload.ilas_raw_crc",
3004 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3006 /* TX Data Flags */
3007 { &hf_tecmp_payload_data_flags_use_crc_value,
3008 { "Use CRC Value", "tecmp.payload.data_flags.use_crc_value",
3009 FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL }},
3010 { &hf_tecmp_payload_data_flags_use_header_crc_value,
3011 { "Use Header CRC Value", "tecmp.payload.data_flags.use_header_crc_value",
3012 FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_HDR_CRC_ERR, NULL, HFILL }},
3013 { &hf_tecmp_payload_data_flags_use_checksum_value,
3014 { "Use Checksum Value", "tecmp.payload.data_flags.use_checksum_value",
3015 FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL }},
3016 { &hf_tecmp_payload_data_flags_use_parity_bits,
3017 { "Use Parity Bits", "tecmp.payload.data_flags.use_parity_bits",
3018 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
3019 { &hf_tecmp_payload_data_flags_tx_mode,
3020 { "TX Mode", "tecmp.payload.data_flags.set_tx_mode",
3021 FT_UINT16, BASE_DEC, VALS(tecmp_payload_flexray_tx_mode), 0x0380, NULL, HFILL }},
3023 /* Counter Event */
3024 { &hf_tecmp_payload_counter_event_device_id,
3025 { "Device ID", "tecmp.payload.counter_event.device_id",
3026 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3027 { &hf_tecmp_payload_counter_event_interface_id,
3028 { "Interface ID", "tecmp.payload.counter_event.interface_id",
3029 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3030 { &hf_tecmp_payload_counter_event_counter_last,
3031 { "Last Counter", "tecmp.payload.counter_event.counter_last",
3032 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3033 { &hf_tecmp_payload_counter_event_counter_cur,
3034 { "Current Counter", "tecmp.payload.counter_event.counter_current",
3035 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3037 /* TimeSync Event */
3038 { &hf_tecmp_payload_timesync_event_device_id,
3039 { "Device ID", "tecmp.payload.timesync_event.device_id",
3040 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3041 { &hf_tecmp_payload_timesync_event_interface_id,
3042 { "Interface ID", "tecmp.payload.timesync_event.interface_id",
3043 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3044 { &hf_tecmp_payload_timesync_event_reserved,
3045 { "Reserved", "tecmp.payload.timesync_event.reserved",
3046 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3047 { &hf_tecmp_payload_timesync_event_async,
3048 { "Async", "tecmp.payload.timesync_event.async",
3049 FT_UINT16, BASE_HEX, VALS(tecmp_timesync_event_flags), 0x0, NULL, HFILL } },
3050 { &hf_tecmp_payload_timesync_event_time_delta,
3051 { "TimeDelta", "tecmp.payload.timesync_event.time_delta",
3052 FT_UINT16, BASE_HEX, VALS(tecmp_timesync_event_flags), 0x0, NULL, HFILL } },
3055 static int *ett[] = {
3056 &ett_tecmp_payload,
3057 &ett_tecmp_payload_interface_id,
3058 &ett_tecmp_payload_data,
3059 &ett_tecmp_payload_timestamp,
3060 &ett_tecmp_payload_dataflags,
3061 &ett_tecmp_payload_instruction_address,
3062 &ett_tecmp_payload_data_id,
3063 &ett_tecmp_payload_lin_id,
3064 &ett_tecmp_payload_analog_alt_flags,
3065 &ett_tecmp_payload_analog_alt_sample,
3066 &ett_tecmp_payload_eth_raw,
3067 &ett_tecmp_payload_eth_raw_frame,
3068 &ett_tecmp_status_dev_vendor_data,
3069 &ett_tecmp_status_bus_data,
3070 &ett_tecmp_status_bus_data_entry,
3071 &ett_tecmp_status_bus_vendor_data,
3072 &ett_tecmp_status_bus_vendor_data_flags,
3073 &ett_tecmp_ctrl_message_10baset1s_flags,
3074 &ett_tecmp_ctrl_message_10baset1s_events_errors,
3077 static ei_register_info ei[] = {
3078 { &ei_tecmp_payload_length_mismatch, { "tecmp.payload.payload_length_mismatch",
3079 PI_PROTOCOL, PI_WARN, "Payload Length and the length of Payload present in packet do not match!", EXPFILL }},
3080 { &ei_tecmp_payload_header_crc_overflow, { "tecmp.payload.header_crc_overflow",
3081 PI_PROTOCOL, PI_WARN, "Header CRC may only be up to 0x07ff!", EXPFILL }},
3084 proto_tecmp_payload = proto_register_protocol("Technically Enhanced Capture Module Protocol Payload",
3085 "TECMP Payload", "tecmp.payload");
3086 proto_register_field_array(proto_tecmp_payload, hf, array_length(hf));
3087 proto_register_subtree_array(ett, array_length(ett));
3088 expert_module_tecmp_payload = expert_register_protocol(proto_tecmp_payload);
3089 expert_register_field_array(expert_module_tecmp_payload, ei, array_length(ei));
3093 * Dissectors can register themselves in this table.
3095 data_subdissector_table = register_dissector_table(TECMP_PAYLOAD_INTERFACE_ID, "TECMP Interface ID", proto_tecmp_payload, FT_UINT32, BASE_HEX);
3096 data_type_subdissector_table = register_dissector_table(TECMP_DATA_TYPE, "TECMP Data Type", proto_tecmp_payload, FT_UINT16, BASE_HEX);
3100 void
3101 proto_reg_handoff_tecmp_payload(void) {
3102 eth_handle = find_dissector("eth_withfcs");
3103 proto_vlan = proto_get_id_by_filter_name("vlan");
3106 void
3107 proto_register_tecmp(void) {
3108 module_t *tecmp_module = NULL;
3109 uat_t *tecmp_device_id_uat = NULL;
3110 uat_t *tecmp_interface_id_uat = NULL;
3111 uat_t *tecmp_control_message_id_uat = NULL;
3113 static hf_register_info hf[] = {
3114 { &hf_tecmp_device_id,
3115 { "Device ID", "tecmp.device_id",
3116 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3117 { &hf_tecmp_counter,
3118 { "Counter", "tecmp.counter",
3119 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3120 { &hf_tecmp_version,
3121 { "Version", "tecmp.version",
3122 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3123 { &hf_tecmp_msgtype,
3124 { "Message Type", "tecmp.message_type",
3125 FT_UINT8, BASE_HEX, VALS(msg_type_names), 0x0, NULL, HFILL }},
3126 { &hf_tecmp_data_type,
3127 { "Data Type", "tecmp.data_type",
3128 FT_UINT16, BASE_HEX, VALS(tecmp_msgtype_names), 0x0, NULL, HFILL }},
3129 { &hf_tecmp_res,
3130 { "Reserved", "tecmp.reserved",
3131 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3132 { &hf_tecmp_flags,
3133 { "Device Flags", "tecmp.dev_flags",
3134 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3135 { &hf_tecmp_flags_eos,
3136 { "End of Segment", "tecmp.dev_flags.eos",
3137 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
3138 { &hf_tecmp_flags_sos,
3139 { "Start of Segment", "tecmp.dev_flags.sos",
3140 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
3141 { &hf_tecmp_flags_spy,
3142 { "Spy", "tecmp.dev_flags.spy",
3143 FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }},
3144 { &hf_tecmp_flags_multi_frame,
3145 { "Multi Frame", "tecmp.dev_flags.multi_frame",
3146 FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL }},
3147 { &hf_tecmp_flags_dev_overflow,
3148 { "Device Overflow", "tecmp.dev_flags.device_overflow",
3149 FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL }},
3152 static int *ett[] = {
3153 &ett_tecmp,
3154 &ett_tecmp_flags,
3157 /* UATs for user_data fields */
3158 static uat_field_t tecmp_device_id_uat_fields[] = {
3159 UAT_FLD_HEX(tecmp_devices, id, "ID", "ID of the Device (hex uint16 without leading 0x)"),
3160 UAT_FLD_CSTRING(tecmp_devices, name, "Device Name", "Name of the Device (string)"),
3161 UAT_END_FIELDS
3164 static uat_field_t tecmp_interface_id_uat_fields[] = {
3165 UAT_FLD_HEX(tecmp_interfaces, id, "ID", "ID of the Interface (hex uint32 without leading 0x)"),
3166 UAT_FLD_CSTRING(tecmp_interfaces, name, "Interface Name", "Name of the Interface (string)"),
3167 UAT_FLD_HEX(tecmp_interfaces, bus_id, "Bus ID", "Bus ID of the Interface (hex uint16 without leading 0x)"),
3168 UAT_END_FIELDS
3171 static uat_field_t tecmp_control_message_id_uat_fields[] = {
3172 UAT_FLD_HEX(tecmp_ctrl_msgs, id, "ID", "ID of the Control Message"),
3173 UAT_FLD_CSTRING(tecmp_ctrl_msgs, name, "Control Message Name", "Name of the Control Message"),
3174 UAT_END_FIELDS
3177 proto_tecmp = proto_register_protocol("Technically Enhanced Capture Module Protocol", "TECMP", "tecmp");
3178 proto_register_field_array(proto_tecmp, hf, array_length(hf));
3179 proto_register_subtree_array(ett, array_length(ett));
3180 tecmp_handle = register_dissector("tecmp", dissect_tecmp, proto_tecmp);
3181 tecmp_module = prefs_register_protocol(proto_tecmp, NULL);
3183 /* UATs */
3184 tecmp_device_id_uat = uat_new("TECMP Devices",
3185 sizeof(generic_one_id_string_t), /* record size */
3186 DATAFILE_TECMP_DEVICE_IDS, /* filename */
3187 true, /* from profile */
3188 (void**)&tecmp_devices, /* data_ptr */
3189 &tecmp_devices_num, /* numitems_ptr */
3190 UAT_AFFECTS_DISSECTION, /* but not fields */
3191 NULL, /* help */
3192 copy_generic_one_id_string_cb, /* copy callback */
3193 update_generic_one_identifier_16bit, /* update callback */
3194 free_generic_one_id_string_cb, /* free callback */
3195 post_update_tecmp_devices_cb, /* post update callback */
3196 NULL, /* reset callback */
3197 tecmp_device_id_uat_fields /* UAT field definitions */
3200 prefs_register_uat_preference(tecmp_module, "_udf_tecmp_devicess", "Devices",
3201 "A table to define names of Devices, which override default names.", tecmp_device_id_uat);
3203 tecmp_interface_id_uat = uat_new("TECMP Interfaces",
3204 sizeof(interface_config_t), /* record size */
3205 DATAFILE_TECMP_INTERFACE_IDS, /* filename */
3206 true, /* from profile */
3207 (void**)&tecmp_interfaces, /* data_ptr */
3208 &tecmp_interfaces_num, /* numitems_ptr */
3209 UAT_AFFECTS_DISSECTION, /* but not fields */
3210 NULL, /* help */
3211 copy_interface_config_cb, /* copy callback */
3212 update_interface_config, /* update callback */
3213 free_interface_config_cb, /* free callback */
3214 post_update_tecmp_interfaces_cb, /* post update callback */
3215 NULL, /* reset callback */
3216 tecmp_interface_id_uat_fields /* UAT field definitions */
3219 prefs_register_uat_preference(tecmp_module, "_udf_tecmp_interfaces", "Interfaces",
3220 "A table to define names of Interfaces.", tecmp_interface_id_uat);
3222 tecmp_control_message_id_uat = uat_new("TECMP Control Messages",
3223 sizeof(generic_one_id_string_t), /* record size */
3224 DATAFILE_TECMP_CONTROL_MSG_IDS, /* filename */
3225 true, /* from profile */
3226 (void**)&tecmp_ctrl_msgs, /* data_ptr */
3227 &tecmp_ctrl_msg_num, /* numitems_ptr */
3228 UAT_AFFECTS_DISSECTION, /* but not fields */
3229 NULL, /* help */
3230 copy_generic_one_id_string_cb, /* copy callback */
3231 update_generic_one_identifier_16bit, /* update callback */
3232 free_generic_one_id_string_cb, /* free callback */
3233 post_update_tecmp_control_messages_cb, /* post update callback */
3234 NULL, /* reset callback */
3235 tecmp_control_message_id_uat_fields /* UAT field definitions */
3238 prefs_register_uat_preference(tecmp_module, "_udf_tecmp_control_msg_id", "Control Messages",
3239 "A table to define names of Control Messages.", tecmp_control_message_id_uat);
3241 prefs_register_bool_preference(tecmp_module, "try_heuristic_first",
3242 "Try heuristic sub-dissectors first",
3243 "Try to decode a packet using an heuristic sub-dissector"
3244 " before using a sub-dissector registered to \"decode as\"",
3245 &heuristic_first);
3247 prefs_register_bool_preference(tecmp_module, "analog_samples_sint",
3248 "Decode Analog Samples as Signed Integer",
3249 "Treat the analog samples as signed integers and decode them accordingly.",
3250 &analog_samples_are_signed_int);
3252 prefs_register_bool_preference(tecmp_module, "move_ethernet_in_tecmp_tree",
3253 "More compact Ethernet representation (move into TECMP Tree)",
3254 "Move Ethernet into the TECMP Tree to be more space efficient.",
3255 &show_ethernet_in_tecmp_tree);
3257 prefs_register_bool_preference(tecmp_module, "detect_asam_cmp",
3258 "Detect ASAM CMP",
3259 "Detect ASAM CMP messages and the ASAM CMP dissector handle them.",
3260 &detect_asam_cmp);
3262 prefs_register_bool_preference(tecmp_module, "detect_asam_cmp_ignore_user_defined",
3263 "Ignore Device IDs 0xff00-0xffff for ASAM CMP Detection",
3264 "Ignore Device IDs 0xff00-0xffff (user-defined range) for ASAM CMP Detection",
3265 &detect_asam_cmp_ignore_user_defined);
3268 void
3269 proto_reg_handoff_tecmp(void) {
3270 dissector_add_uint("ethertype", ETHERTYPE_TECMP, tecmp_handle);
3272 lin_subdissector_table = find_dissector_table("lin.frame_id");
3274 text_lines_handle = find_dissector_add_dependency("data-text-lines", proto_tecmp);
3275 asam_cmp_handle = find_dissector("asam-cmp");
3279 * Editor modelines
3281 * Local Variables:
3282 * c-basic-offset: 4
3283 * tab-width: 8
3284 * indent-tabs-mode: nil
3285 * End:
3287 * ex: set shiftwidth=4 tabstop=8 expandtab:
3288 * :indentSize=4:tabSize=8:noTabs=true: