Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-tecmp.c
Line
Count
Source
1
/* packet-tecmp.c
2
 * Technically Enhanced Capture Module Protocol (TECMP) dissector.
3
 * By <lars.voelker@technica-engineering.de>
4
 * Copyright 2019-2025 Dr. Lars Völker
5
 * Copyright 2020      Ayoub Kaanich
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
 /*
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.
20
  *
21
  * See
22
  *
23
  *    https://github.com/Technica-Engineering/libtecmp/tree/master/docs
24
  *
25
  * for specifications for the protocol.
26
  */
27
28
#include <config.h>
29
#include <epan/packet.h>
30
#include <epan/etypes.h>
31
#include <epan/expert.h>
32
#include <epan/uat.h>
33
#include <epan/proto_data.h>
34
#include <epan/tfs.h>
35
#include <epan/unit_strings.h>
36
37
#include <wsutil/array.h>
38
#include <wsutil/utf8_entities.h>
39
40
#include "packet-tecmp.h"
41
#include "packet-socketcan.h"
42
#include "packet-flexray.h"
43
#include "packet-lin.h"
44
45
46
void proto_register_tecmp(void);
47
void proto_reg_handoff_tecmp(void);
48
void proto_register_tecmp_payload(void);
49
void proto_reg_handoff_tecmp_payload(void);
50
51
static dissector_handle_t tecmp_handle;
52
53
static int proto_tecmp;
54
static int proto_tecmp_payload;
55
56
static dissector_handle_t eth_handle;
57
58
static bool heuristic_first;
59
static bool analog_samples_are_signed_int = true;
60
static bool show_ethernet_in_tecmp_tree;
61
static bool detect_asam_cmp = true;
62
static bool detect_asam_cmp_ignore_user_defined = true;
63
64
static dissector_table_t data_subdissector_table;
65
static dissector_table_t data_type_subdissector_table;
66
static dissector_handle_t text_lines_handle;
67
68
/* Header fields */
69
/* TECMP */
70
static int hf_tecmp_device_id;
71
static int hf_tecmp_counter;
72
static int hf_tecmp_version;
73
static int hf_tecmp_msgtype;
74
static int hf_tecmp_data_type;
75
static int hf_tecmp_res;
76
77
static int hf_tecmp_flags;
78
static int hf_tecmp_flags_eos;
79
static int hf_tecmp_flags_sos;
80
static int hf_tecmp_flags_spy;
81
static int hf_tecmp_flags_multi_frame;
82
static int hf_tecmp_flags_dev_overflow;
83
84
/* TECMP Payload */
85
static int hf_tecmp_payload_interface_id;
86
static int hf_tecmp_payload_interface_name;
87
static int hf_tecmp_payload_timestamp;
88
static int hf_tecmp_payload_timestamp_ns;
89
static int hf_tecmp_payload_timestamp_async;
90
static int hf_tecmp_payload_timestamp_res;
91
static int hf_tecmp_payload_length;
92
static int hf_tecmp_payload_data;
93
static int hf_tecmp_payload_data_length;
94
static int hf_tecmp_payload_samples;
95
96
/* TECMP Payload flags */
97
/* Generic */
98
static int hf_tecmp_payload_data_flags;
99
static int hf_tecmp_payload_data_flags_crc;
100
static int hf_tecmp_payload_data_flags_checksum;
101
static int hf_tecmp_payload_data_flags_tx;
102
static int hf_tecmp_payload_data_flags_overflow;
103
104
/* ILaS*/
105
static int hf_tecmp_payload_data_flags_crc_enabled;
106
static int hf_tecmp_payload_data_flags_direction;
107
108
/* Ethernet Raw */
109
static int hf_tecmp_payload_data_ethernet_raw_data;
110
static int hf_tecmp_payload_data_ethernet_raw_preamble;
111
static int hf_tecmp_payload_data_ethernet_raw_sfd;
112
static int hf_tecmp_payload_data_ethernet_raw_eth_frame;
113
114
/* Ethernet 10BASE-T1S */
115
static int hf_tecmp_payload_data_flags_phy_event_error;
116
117
/* LIN */
118
static int hf_tecmp_payload_data_flags_coll;
119
static int hf_tecmp_payload_data_flags_parity;
120
static int hf_tecmp_payload_data_flags_no_resp;
121
static int hf_tecmp_payload_data_flags_wup;
122
static int hf_tecmp_payload_data_flags_short_wup;
123
static int hf_tecmp_payload_data_flags_sleep;
124
125
/* CAN and CAN-FD DATA */
126
static int hf_tecmp_payload_data_flags_ack;
127
static int hf_tecmp_payload_data_flags_rtr;  /* CAN DATA only */
128
static int hf_tecmp_payload_data_flags_esi;  /* CAN-FD DATA only */
129
static int hf_tecmp_payload_data_flags_ide;
130
static int hf_tecmp_payload_data_flags_err;
131
static int hf_tecmp_payload_data_flags_brs;  /* CAN-FD DATA only */
132
133
static int hf_tecmp_payload_data_flags_can_bit_stuff_err;
134
static int hf_tecmp_payload_data_flags_can_crc_del_err;
135
static int hf_tecmp_payload_data_flags_can_ack_del_err;
136
static int hf_tecmp_payload_data_flags_can_eof_err;
137
static int hf_tecmp_payload_data_flags_canfd_bit_stuff_err;
138
static int hf_tecmp_payload_data_flags_canfd_crc_del_err;
139
static int hf_tecmp_payload_data_flags_canfd_ack_del_err;
140
static int hf_tecmp_payload_data_flags_canfd_eof_err;
141
142
/* FlexRay */
143
static int hf_tecmp_payload_data_flags_nf;
144
static int hf_tecmp_payload_data_flags_sf;
145
static int hf_tecmp_payload_data_flags_sync;
146
static int hf_tecmp_payload_data_flags_wus;
147
static int hf_tecmp_payload_data_flags_ppi;
148
static int hf_tecmp_payload_data_flags_cas;
149
static int hf_tecmp_payload_data_flags_header_crc_err;
150
static int hf_tecmp_payload_data_flags_frame_crc_err;
151
152
/* UART/RS232 ASCII*/
153
static int hf_tecmp_payload_data_flags_dl;
154
static int hf_tecmp_payload_data_flags_parity_error;
155
156
/* Analog */
157
static int hf_tecmp_payload_data_flags_sample_time;
158
static int hf_tecmp_payload_data_flags_factor;
159
static int hf_tecmp_payload_data_flags_unit;
160
static int hf_tecmp_payload_data_flags_threshold_u;
161
static int hf_tecmp_payload_data_flags_threshold_o;
162
163
/* Special TX Data Flags */
164
static int hf_tecmp_payload_data_flags_use_crc_value;
165
static int hf_tecmp_payload_data_flags_use_header_crc_value;
166
static int hf_tecmp_payload_data_flags_use_checksum_value;
167
static int hf_tecmp_payload_data_flags_use_parity_bits;
168
static int hf_tecmp_payload_data_flags_tx_mode;
169
170
static const unit_name_string tecmp_units_amp_hour = { "Ah", NULL };
171
172
14
#define TECMP_DATAFLAGS_FACTOR_MASK         0x0180
173
0
#define TECMP_DATAFLAGS_FACTOR_SHIFT        7
174
14
#define TECMP_DATAFLAGS_UNIT_MASK           0x001c
175
0
#define TECMP_DATAFLAGS_UNIT_SHIFT          2
176
177
/* TECMP Payload Fields */
178
/* Ethernet 10BASE-T1S */
179
static int hf_tecmp_payload_data_beacon_timestamp;
180
static int hf_tecmp_payload_data_beacon_timestamp_ns;
181
static int hf_tecmp_payload_data_beacon_to_timestamp_ns;
182
183
/* LIN */
184
static int hf_tecmp_payload_data_id_field_8bit;
185
static int hf_tecmp_payload_data_id_field_6bit;
186
static int hf_tecmp_payload_data_parity_bits;
187
static int hf_tecmp_payload_data_checksum_8bit;
188
189
/* CAN DATA / CAN-FD DATA */
190
static int hf_tecmp_payload_data_id_field_32bit;
191
static int hf_tecmp_payload_data_id_type;
192
static int hf_tecmp_payload_data_id_11;
193
static int hf_tecmp_payload_data_id_29;
194
static int hf_tecmp_payload_data_crc15;
195
static int hf_tecmp_payload_data_crc17;
196
static int hf_tecmp_payload_data_crc21;
197
198
/* FlexRay DATA */
199
static int hf_tecmp_payload_data_cycle;
200
static int hf_tecmp_payload_data_frame_id;
201
static int hf_tecmp_payload_data_header_crc;
202
static int hf_tecmp_payload_data_frame_crc;
203
204
/* Analog */
205
static int hf_tecmp_payload_data_analog_value_raw;
206
static int hf_tecmp_payload_data_analog_value_raw_signed;
207
static int hf_tecmp_payload_data_analog_value_volt;
208
static int hf_tecmp_payload_data_analog_value_amp;
209
static int hf_tecmp_payload_data_analog_value_watt;
210
static int hf_tecmp_payload_data_analog_value_amp_hour;
211
static int hf_tecmp_payload_data_analog_value_celsius;
212
213
/* Analog Alt */
214
static int hf_tecmp_payload_analog_alt_flags;
215
static int hf_tecmp_payload_analog_alt_flag_sample_dt;
216
static int hf_tecmp_payload_analog_alt_flag_reserved;
217
218
static int hf_tecmp_payload_analog_alt_reserved;
219
static int hf_tecmp_payload_analog_alt_unit;
220
static int hf_tecmp_payload_analog_alt_sample_interval;
221
static int hf_tecmp_payload_analog_alt_sample_offset;
222
static int hf_tecmp_payload_analog_alt_sample_scalar;
223
static int hf_tecmp_payload_analog_alt_sample_raw;
224
static int hf_tecmp_payload_analog_alt_sample;
225
226
/* GPIO */
227
/* define 32 GPIOs for now */
228
static int hf_tecmp_payload_data_gpio_0;
229
static int hf_tecmp_payload_data_gpio_1;
230
static int hf_tecmp_payload_data_gpio_2;
231
static int hf_tecmp_payload_data_gpio_3;
232
static int hf_tecmp_payload_data_gpio_4;
233
static int hf_tecmp_payload_data_gpio_5;
234
static int hf_tecmp_payload_data_gpio_6;
235
static int hf_tecmp_payload_data_gpio_7;
236
237
static int hf_tecmp_payload_data_gpio_8;
238
static int hf_tecmp_payload_data_gpio_9;
239
static int hf_tecmp_payload_data_gpio_10;
240
static int hf_tecmp_payload_data_gpio_11;
241
static int hf_tecmp_payload_data_gpio_12;
242
static int hf_tecmp_payload_data_gpio_13;
243
static int hf_tecmp_payload_data_gpio_14;
244
static int hf_tecmp_payload_data_gpio_15;
245
246
static int hf_tecmp_payload_data_gpio_16;
247
static int hf_tecmp_payload_data_gpio_17;
248
static int hf_tecmp_payload_data_gpio_18;
249
static int hf_tecmp_payload_data_gpio_19;
250
static int hf_tecmp_payload_data_gpio_20;
251
static int hf_tecmp_payload_data_gpio_21;
252
static int hf_tecmp_payload_data_gpio_22;
253
static int hf_tecmp_payload_data_gpio_23;
254
255
static int hf_tecmp_payload_data_gpio_24;
256
static int hf_tecmp_payload_data_gpio_25;
257
static int hf_tecmp_payload_data_gpio_26;
258
static int hf_tecmp_payload_data_gpio_27;
259
static int hf_tecmp_payload_data_gpio_28;
260
static int hf_tecmp_payload_data_gpio_29;
261
static int hf_tecmp_payload_data_gpio_30;
262
static int hf_tecmp_payload_data_gpio_31;
263
264
/* ILaS */
265
static int hf_tecmp_payload_data_ilas_decoded_command;
266
static int hf_tecmp_payload_data_ilas_decoded_address;
267
static int hf_tecmp_payload_data_ilas_decoded_data;
268
static int hf_tecmp_payload_data_ilas_raw_sdu;
269
static int hf_tecmp_payload_data_ilas_raw_crc;
270
271
/* I2C */
272
static int hf_tecmp_payload_data_i2c_address_7bit;
273
static int hf_tecmp_payload_data_i2c_address_10bit;
274
static int hf_tecmp_payload_data_i2c_address1;
275
static int hf_tecmp_payload_data_i2c_address2;
276
static int hf_tecmp_payload_data_i2c_direction;
277
static int hf_tecmp_payload_data_i2c_control_char;
278
static int hf_tecmp_payload_data_i2c_data_byte;
279
280
/* TECMP Status Messages */
281
/* Status Device */
282
static int hf_tecmp_payload_status_vendor_id;
283
static int hf_tecmp_payload_status_dev_version;
284
static int hf_tecmp_payload_status_dev_type;
285
static int hf_tecmp_payload_status_res;
286
static int hf_tecmp_payload_status_length_vendor_data;
287
static int hf_tecmp_payload_status_device_id;
288
static int hf_tecmp_payload_status_sn;
289
static int hf_tecmp_payload_status_vendor_data;
290
291
/* Status Bus */
292
static int hf_tecmp_payload_status_bus_data;
293
static int hf_tecmp_payload_status_bus_data_entry;
294
static int hf_tecmp_payload_status_bus_interface_id;
295
static int hf_tecmp_payload_status_bus_total;
296
static int hf_tecmp_payload_status_bus_errors;
297
298
/* Status Device Vendor Data Technica Engineering */
299
static int hf_tecmp_payload_status_dev_vendor_technica_res;
300
static int hf_tecmp_payload_status_dev_vendor_technica_sw;
301
static int hf_tecmp_payload_status_dev_vendor_technica_hw;
302
static int hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level;
303
static int hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow;
304
static int hf_tecmp_payload_status_dev_vendor_technica_buffer_size;
305
static int hf_tecmp_payload_status_dev_vendor_technica_lifecycle;
306
static int hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start;
307
static int hf_tecmp_payload_status_dev_vendor_technica_voltage;
308
static int hf_tecmp_payload_status_dev_vendor_technica_temperature;
309
static int hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis;
310
static int hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon;
311
static int hf_tecmp_payload_status_dev_vendor_technica_lifecycle_counter;
312
static int hf_tecmp_payload_status_dev_vendor_technica_error_flags;
313
static int hf_tecmp_payload_status_dev_vendor_technica_error_flags_port1;
314
static int hf_tecmp_payload_status_dev_vendor_technica_error_flags_port2;
315
static int hf_tecmp_payload_status_dev_vendor_technica_error_flags_port3;
316
static int hf_tecmp_payload_status_dev_vendor_technica_error_flags_port4;
317
static int hf_tecmp_payload_status_dev_vendor_technica_sfpa_tx_frames;
318
static int hf_tecmp_payload_status_dev_vendor_technica_sfpb_tx_frames;
319
static int hf_tecmp_payload_status_dev_vendor_technica_sfpc_tx_frames;
320
static int hf_tecmp_payload_status_dev_vendor_technica_sfpd_tx_frames;
321
322
0
#define VENDOR_TECHNICA_TEMP_MAX 127
323
0
#define VENDOR_TECHNICA_TEMP_NA  -128
324
325
/* Status Bus Vendor Data Technica Engineering */
326
static int hf_tecmp_payload_status_bus_vendor_technica_link_status;
327
static int hf_tecmp_payload_status_bus_vendor_technica_link_quality;
328
static int hf_tecmp_payload_status_bus_vendor_technica_linkup_time;
329
330
static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags;
331
static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beac_rcvd;
332
static int hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_en;
333
static int hf_tecmp_payload_status_bus_vendor_technica_res0;
334
static int hf_tecmp_payload_status_bus_vendor_technica_beacon_counter;
335
static int hf_tecmp_payload_status_bus_vendor_technica_res1;
336
static int hf_tecmp_payload_status_bus_vendor_technica_res2;
337
static int hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt;
338
static int hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt;
339
static int hf_tecmp_payload_status_bus_vendor_technica_plca_symb_dtct_cnt;
340
static int hf_tecmp_payload_status_bus_vendor_technica_plca_symb_miss_cnt;
341
static int hf_tecmp_payload_status_bus_vendor_technica_plca_symb_empty_cnt;
342
343
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_err;
344
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_err_no_ack;
345
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_err_crc;
346
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_1bit;
347
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_2bit;
348
static int hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved;
349
350
/* Status Configuration Data Technica Engineering */
351
static int hf_tecmp_payload_status_cfg_vendor_technica_version;
352
static int hf_tecmp_payload_status_cfg_vendor_technica_reserved;
353
static int hf_tecmp_payload_status_cfg_vendor_technica_msg_id;
354
static int hf_tecmp_payload_status_cfg_vendor_technica_total_length;
355
static int hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg;
356
static int hf_tecmp_payload_status_cfg_vendor_technica_segment_num;
357
static int hf_tecmp_payload_status_cfg_vendor_technica_segment_length;
358
static int hf_tecmp_payload_status_cfg_vendor_technica_segment_data;
359
360
/* TECMP Control Message */
361
static int hf_tecmp_payload_ctrl_msg_device_id;
362
static int hf_tecmp_payload_ctrl_msg_id;
363
static int hf_tecmp_payload_ctrl_msg_unparsed_bytes;
364
static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level;
365
static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow;
366
static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size;
367
static int hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_length;
368
static int hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id;
369
static int hf_tecmp_payload_ctrl_msg_flexray_poc_state;
370
static int hf_tecmp_payload_ctrl_msg_10baset1s_interface_id;
371
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags;
372
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received;
373
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled;
374
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved;
375
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events;
376
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error;
377
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error;
378
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detect;
379
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_miss;
380
static int hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle;
381
382
/* Counter Event */
383
static int hf_tecmp_payload_counter_event_device_id;
384
static int hf_tecmp_payload_counter_event_interface_id;
385
static int hf_tecmp_payload_counter_event_counter_last;
386
static int hf_tecmp_payload_counter_event_counter_cur;
387
388
/* TimeSync Event */
389
static int hf_tecmp_payload_timesync_event_device_id;
390
static int hf_tecmp_payload_timesync_event_interface_id;
391
static int hf_tecmp_payload_timesync_event_reserved;
392
static int hf_tecmp_payload_timesync_event_async;
393
static int hf_tecmp_payload_timesync_event_time_delta;
394
395
396
/* protocol tree items */
397
static int ett_tecmp;
398
static int ett_tecmp_flags;
399
400
static int ett_tecmp_payload;
401
static int ett_tecmp_payload_interface_id;
402
static int ett_tecmp_payload_data;
403
static int ett_tecmp_payload_timestamp;
404
static int ett_tecmp_payload_dataflags;
405
static int ett_tecmp_payload_instruction_address;
406
static int ett_tecmp_payload_data_id;
407
static int ett_tecmp_payload_lin_id;
408
static int ett_tecmp_payload_analog_alt_flags;
409
static int ett_tecmp_payload_analog_alt_sample;
410
static int ett_tecmp_payload_eth_raw;
411
static int ett_tecmp_payload_eth_raw_frame;
412
static int ett_tecmp_payload_i2c_operation;
413
static int ett_tecmp_status_bus_data;
414
static int ett_tecmp_status_bus_data_entry;
415
static int ett_tecmp_status_dev_vendor_data;
416
static int ett_tecmp_status_dev_vendor_data_error_flags;
417
static int ett_tecmp_status_bus_vendor_data;
418
static int ett_tecmp_status_bus_vendor_data_flags;
419
static int ett_tecmp_status_bus_vendor_data_bus_errors;
420
static int ett_tecmp_ctrl_message_10baset1s_flags;
421
static int ett_tecmp_ctrl_message_10baset1s_events_errors;
422
423
/* dissector handle to hand off to ASAM CMP (successor protocol) */
424
static dissector_handle_t asam_cmp_handle;
425
426
/*** expert info items ***/
427
static expert_field ei_tecmp_payload_length_mismatch;
428
static expert_field ei_tecmp_payload_header_crc_overflow;
429
430
/* TECMP Message Type Names */
431
/* Updated by ID Registry */
432
98
#define TECMP_MSG_TYPE_CTRL_MSG            0x00
433
245
#define TECMP_MSG_TYPE_STATUS_DEV          0x01
434
291
#define TECMP_MSG_TYPE_STATUS_BUS          0x02
435
267
#define TECMP_MSG_TYPE_LOG_STREAM          0x03
436
286
#define TECMP_MSG_TYPE_CFG_CM              0x04
437
211
#define TECMP_MSG_TYPE_REPLAY_DATA         0x0A
438
164
#define TECMP_MSG_TYPE_COUNTER_EVENT       0x0B
439
165
#define TECMP_MSG_TYPE_TIMESYNC_EVENT      0x0C
440
441
static const value_string tecmp_msg_type_names[] = {
442
    {TECMP_MSG_TYPE_CTRL_MSG,              "Control Message"},
443
    {TECMP_MSG_TYPE_STATUS_DEV,            "Status Device"},
444
    {TECMP_MSG_TYPE_STATUS_BUS,            "Status Bus"},
445
    {TECMP_MSG_TYPE_LOG_STREAM,            "Logging Stream"},
446
    {TECMP_MSG_TYPE_CFG_CM,                "Status Configuration"},
447
    {TECMP_MSG_TYPE_REPLAY_DATA,           "Replay Data"},
448
    {TECMP_MSG_TYPE_COUNTER_EVENT,         "Counter Event"},
449
    {TECMP_MSG_TYPE_TIMESYNC_EVENT,        "TimeSync Event"},
450
    {0, NULL}
451
};
452
453
/* TECMP Data Type Names */
454
/* Updated by ID Registry */
455
#define TECMP_DATA_TYPE_NONE               0x0000
456
#define TECMP_DATA_TYPE_CAN_RAW            0x0001
457
40
#define TECMP_DATA_TYPE_CAN_DATA           0x0002
458
13
#define TECMP_DATA_TYPE_CAN_FD_DATA        0x0003
459
33
#define TECMP_DATA_TYPE_LIN                0x0004
460
#define TECMP_DATA_TYPE_FR_RAW             0x0007
461
0
#define TECMP_DATA_TYPE_FR_DATA            0x0008
462
0
#define TECMP_DATA_TYPE_GPIO               0x000A
463
0
#define TECMP_DATA_TYPE_ILAS               0x000E
464
3
#define TECMP_DATA_TYPE_RS232_ASCII        0x0010
465
#define TECMP_DATA_TYPE_RS232_RAW          0x0011
466
#define TECMP_DATA_TYPE_RS232_SLA          0x0012
467
0
#define TECMP_DATA_TYPE_ANALOG             0x0020
468
#define TECMP_DATA_TYPE_ANALOG_SLA         0x0021
469
8
#define TECMP_DATA_TYPE_ANALOG_ALT         0x0028
470
0
#define TECMP_DATA_TYPE_ETH                0x0080
471
0
#define TECMP_DATA_TYPE_ETH_RAW            0x0081
472
0
#define TECMP_DATA_TYPE_ETH_10BASE_T1S     0x0082
473
#define TECMP_DATA_TYPE_XCP_DATA           0x00A0
474
#define TECMP_DATA_TYPE_MIPI_CSI2_V        0x0101
475
#define TECMP_DATA_TYPE_MIPI_CSI2_L        0x0102
476
#define TECMP_DATA_TYPE_SPI                0x0103
477
47
#define TECMP_DATA_TYPE_I2C                0x0104
478
#define TECMP_DATA_TYPE_I2C_10BIT          0x0106
479
#define TECMP_DATA_TYPE_TAPI               0x0200
480
#define TECMP_DATA_TYPE_TAPI_INIT_STATE    0x0201
481
#define TECMP_DATA_TYPE_TAPI_CORE_DUMP     0x0202
482
#define TECMP_DATA_TYPE_R                  0x0400
483
#define TECMP_DATA_TYPE_TECMP_RAW          0xA000
484
#define TECMP_DATA_TYPE_PRE_LABEL          0xB000
485
486
static const value_string tecmp_data_type_names[] = {
487
    {TECMP_DATA_TYPE_NONE,                 "None (Undefined)"},
488
    {TECMP_DATA_TYPE_CAN_RAW,              "CAN(-FD) Raw"},
489
    {TECMP_DATA_TYPE_CAN_DATA,             "CAN Data"},
490
    {TECMP_DATA_TYPE_CAN_FD_DATA,          "CAN-FD Data"},
491
    {TECMP_DATA_TYPE_LIN,                  "LIN"},
492
    {TECMP_DATA_TYPE_FR_RAW,               "Flexray Raw"},
493
    {TECMP_DATA_TYPE_FR_DATA,              "Flexray Data"},
494
    {TECMP_DATA_TYPE_GPIO,                 "GPIO"},
495
    {TECMP_DATA_TYPE_ILAS,                 "ILaS"},
496
    {TECMP_DATA_TYPE_RS232_ASCII,          "UART/RS232_ASCII"},
497
    {TECMP_DATA_TYPE_RS232_RAW,            "UART/RS232_RAW"},
498
    {TECMP_DATA_TYPE_RS232_SLA,            "UART/RS232_SLA"},
499
    {TECMP_DATA_TYPE_ANALOG,               "Analog"},
500
    {TECMP_DATA_TYPE_ANALOG_SLA,           "Analog_SLA"},
501
    {TECMP_DATA_TYPE_ANALOG_ALT,           "Analog Alternative"},
502
    {TECMP_DATA_TYPE_ETH,                  "Ethernet II"},
503
    {TECMP_DATA_TYPE_ETH_RAW,              "Ethernet Raw"},
504
    {TECMP_DATA_TYPE_ETH_10BASE_T1S,       "Ethernet 10BASE-T1S"},
505
    {TECMP_DATA_TYPE_XCP_DATA,             "XCP-Data"},
506
    {TECMP_DATA_TYPE_MIPI_CSI2_V,          "MIPI-CSI2 V"},
507
    {TECMP_DATA_TYPE_MIPI_CSI2_L,          "MIPI-CSI2 L"},
508
    {TECMP_DATA_TYPE_SPI,                  "SPI"},
509
    {TECMP_DATA_TYPE_I2C,                  "I2C"},
510
    {TECMP_DATA_TYPE_I2C_10BIT,            "I2C 10 Bit"},
511
    {TECMP_DATA_TYPE_TAPI,                 "TAPI"},
512
    {TECMP_DATA_TYPE_TAPI_INIT_STATE,      "TAPI Initial State"},
513
    {TECMP_DATA_TYPE_TAPI_CORE_DUMP,       "TAPI Core Dump"},
514
    {TECMP_DATA_TYPE_R,                    "R"},
515
    {TECMP_DATA_TYPE_TECMP_RAW,            "TECMP_Raw"},
516
    {TECMP_DATA_TYPE_PRE_LABEL,            "PreLabel"},
517
    {0, NULL}
518
};
519
520
/* Vendor IDs */
521
/* Updated by ID Registry */
522
281
#define TECMP_VENDOR_ID_TECHNICA           0x0c
523
static const value_string tecmp_vendor_ids[] = {
524
    {TECMP_VENDOR_ID_TECHNICA,             "Technica Engineering"},
525
    {0, NULL}
526
};
527
528
/* Device IDs */
529
/* Can be overwritten/extended by config */
530
static const value_string tecmp_device_id_prefixes[] = {
531
    {0x0030, "CM LIN Combo"},
532
    {0x0040, "CM CAN Combo"},
533
    {0x0060, "CM 100 High"},
534
    {0x0080, "CM Eth Combo"},
535
    {0x0090, "CM 1000 High"},
536
    {0x00c0, "CM SerDes"},
537
    {0x00e0, "CM MultiGigabit"},
538
    {0, NULL}
539
};
540
541
static const value_string tecmp_device_ids_specific[] = {
542
    {0x0050, "CM Sense 0"},
543
    {0x0051, "CM Sense 1"},
544
    {0x0052, "CM Sense 2"},
545
    {0x0053, "CM Sense 3"},
546
    {0x0054, "CM Sense 4"},
547
    {0x0055, "CM Sense 5"},
548
    {0x0056, "CM Sense 6"},
549
    {0x0057, "CM Sense 7"},
550
    {0x0070, "CM 10BASE-T1S 0"},
551
    {0x0071, "CM 10BASE-T1S 1"},
552
    {0x0072, "CM 10BASE-T1S 2"},
553
    {0x0073, "CM 10BASE-T1S 3"},
554
    {0x0074, "CM 10BASE-T1S 4"},
555
    {0x0075, "CM 10BASE-T1S 5"},
556
    {0x0076, "CM 10BASE-T1S 6"},
557
    {0x0077, "CM 10BASE-T1S 7"},
558
    {0x0078, "CM 10BASE-T1S 8"},
559
    {0x0079, "CM 10BASE-T1S 9"},
560
    {0x007a, "ILaS Sniffer 0"},
561
    {0x007b, "ILaS Sniffer 1"},
562
    {0x007c, "ILaS Sniffer 2"},
563
    {0x007d, "ILaS Sniffer 3"},
564
    {0x007e, "ILaS Sniffer 4"},
565
    {0x007f, "ILaS Sniffer 5"},
566
    {0x00b8, "Network Interfacer 10BASE-T1S 0"},
567
    {0x00b9, "Network Interfacer 10BASE-T1S 1"},
568
    {0x00ba, "Network Interfacer 10BASE-T1S 2"},
569
    {0x00bb, "Network Interfacer 10BASE-T1S 3"},
570
    {0, NULL}
571
};
572
573
0
#define TECMP_DEVICE_TYPE_CM_LIN_COMBO      0x02
574
34
#define TECMP_DEVICE_TYPE_CM_CAN_COMBO      0x04
575
0
#define TECMP_DEVICE_TYPE_CM_100_HIGH       0x06
576
1
#define TECMP_DEVICE_TYPE_CM_100_HIGH_TC10  0x07
577
0
#define TECMP_DEVICE_TYPE_CM_ETH_COMBO      0x08
578
0
#define TECMP_DEVICE_TYPE_CM_1000_HIGH      0x0a
579
298
#define TECMP_DEVICE_TYPE_CM_10BASE_T1S     0x0c
580
1.12k
#define TECMP_DEVICE_TYPE_CM_ILAS_SNIFFER   0x0e
581
309
#define TECMP_DEVICE_TYPE_CM_SERDES_GMSL23  0x40
582
#define TECMP_DEVICE_TYPE_CM_MULTIGIGABIT   0x42
583
281
#define TECMP_DEVICE_TYPE_CM_SERDES_ASAML   0x48
584
585
/* Device Types */
586
/* Updated by ID Registry */
587
static const value_string tecmp_device_types[] = {
588
    {TECMP_DEVICE_TYPE_CM_LIN_COMBO,        "CM LIN Combo"},
589
    {TECMP_DEVICE_TYPE_CM_CAN_COMBO,        "CM CAN Combo"},
590
    {TECMP_DEVICE_TYPE_CM_100_HIGH,         "CM 100 High"},
591
    {TECMP_DEVICE_TYPE_CM_100_HIGH_TC10,    "CM 100 High TC10"},
592
    {TECMP_DEVICE_TYPE_CM_ETH_COMBO,        "CM Eth Combo"},
593
    {TECMP_DEVICE_TYPE_CM_1000_HIGH,        "CM 1000 High"},
594
    {TECMP_DEVICE_TYPE_CM_10BASE_T1S,       "CM 10BASE-T1S"},
595
    {TECMP_DEVICE_TYPE_CM_ILAS_SNIFFER,     "ILaS Sniffer"},
596
    {0x10,                                  "Sensor specific"},
597
    {0x20,                                  "Logger"},
598
    {TECMP_DEVICE_TYPE_CM_SERDES_GMSL23,    "CM SerDes GMSL2/3"},
599
    {TECMP_DEVICE_TYPE_CM_MULTIGIGABIT,     "CM MultiGigabit"},
600
    {0x44,                                  "EES"},
601
    {0x46,                                  "CM Sense"},
602
    {TECMP_DEVICE_TYPE_CM_SERDES_ASAML,     "CM SerDes ASA ML"},
603
    {0x50,                                  "BTS Revo"},
604
    {0x52,                                  "Network Interfacer 10BASE-T1S"},
605
    {0, NULL}
606
};
607
608
/* Control Message IDs */
609
/* Updated by ID Registry */
610
#define TECMP_CTRL_MSG_LOGGER_READY        0x0002
611
0
#define TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL 0x00E0
612
0
#define TECMP_CTRL_MSG_FR_POC_STATE        0x00E1
613
0
#define TECMP_CTRL_MSG_10BASE_T1S          0x00E2
614
615
static const value_string tecmp_ctrl_msg_ids_types[] = {
616
    {TECMP_CTRL_MSG_LOGGER_READY,          "Logger Ready"},
617
    {TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL,   "CAN Replay Fill Level"},
618
    {TECMP_CTRL_MSG_FR_POC_STATE,          "FlexRay POC State"},
619
    {TECMP_CTRL_MSG_10BASE_T1S,            "10BASE-T1S"},
620
    {0, NULL}
621
};
622
623
static const value_string tecmp_ctrl_msg_fr_poc_state[] = {
624
    {0, "Config"},
625
    {1, "Default Config"},
626
    {2, "Halt"},
627
    {3, "Normal Active"},
628
    {4, "Normal Passive"},
629
    {5, "Ready"},
630
    {6, "Startup"},
631
    {7, "Wakeup"},
632
    {0, NULL}
633
};
634
635
static const true_false_string tfs_tecmp_payload_timestamp_async_type = {
636
    "Not synchronized",
637
    "Synchronized or Master"
638
};
639
640
static const true_false_string tfs_tecmp_technica_bufferoverflow = {
641
    "Buffer Overflow occurred",
642
    "No Buffer Overflow occurred"
643
};
644
645
static const true_false_string tfs_tecmp_payload_data_crc_received = {
646
    "CRC present in received message",
647
    "CRC not present in received message"
648
};
649
650
static const true_false_string tfs_tecmp_payload_data_direction = {
651
    "Upstream (response)",
652
    "Downstream (command)"
653
};
654
655
static const true_false_string tfs_tecmp_payload_data_id_type = {
656
    "29bit CAN Identifier",
657
    "11bit CAN Identifier"
658
};
659
660
static const value_string tecmp_payload_rs232_uart_dl_types[] = {
661
    {0x2, "RS232 with 7 bit"},
662
    {0x3, "RS232 with 8 bit"},
663
    {0, NULL}
664
};
665
666
static const value_string tecmp_payload_analog_sample_time_types[] = {
667
    {0x0, "Reserved"},
668
    {0x1, "2500 ms"},
669
    {0x2, "1000 ms"},
670
    {0x3, "500 ms"},
671
    {0x4, "250 ms"},
672
    {0x5, "100 ms"},
673
    {0x6, "50 ms"},
674
    {0x7, "25 ms"},
675
    {0x8, "10 ms"},
676
    {0x9, "5 ms"},
677
    {0xa, "2.5 ms"},
678
    {0xb, "1 ms"},
679
    {0xc, "0.5 ms"},
680
    {0xd, "0.25 ms"},
681
    {0xe, "0.1 ms"},
682
    {0xf, "0.05 ms"},
683
    {0, NULL}
684
};
685
686
static const double tecmp_payload_analog_scale_factor_values[] = {
687
    0.1,
688
    0.01,
689
    0.001,
690
    0.0001,
691
};
692
693
static const value_string tecmp_payload_analog_scale_factor_types[] = {
694
    {0x0, "0.1"},
695
    {0x1, "0.01"},
696
    {0x2, "0.001"},
697
    {0x3, "0.0001"},
698
    {0, NULL}
699
};
700
701
static const value_string tecmp_payload_analog_unit_types[] = {
702
    {0x0, "V"},
703
    {0x1, "A"},
704
    {0x2, "W"},
705
    {0x3, "Ah"},
706
    {0x4, UTF8_DEGREE_SIGN "C"},
707
    {0x5, "undefined value"},
708
    {0x6, "undefined value"},
709
    {0x7, "undefined value"},
710
    {0, NULL}
711
};
712
713
static const value_string analog_alt_units[] = {
714
    {0x04, "A"},
715
    {0x0e, "W"},
716
    {0x0f, "C"},
717
    {0x10, "V"},
718
    {0x17, "°C"},
719
    {0, NULL}
720
};
721
722
/* TECMP Analog Alt Data Message DT Values */
723
#define TECMP_ANALOG_ALT_DATA_MSG_DL_16     0x00
724
#define TECMP_ANALOG_ALT_DATA_MSG_DL_32     0x01
725
726
static const value_string analog_alt_sample_dt[] = {
727
    {TECMP_ANALOG_ALT_DATA_MSG_DL_16,       "A_INT16"},
728
    {TECMP_ANALOG_ALT_DATA_MSG_DL_32,       "A_INT32"},
729
    {0, NULL}
730
};
731
732
static const value_string tecmp_ilas_command_types[] = {
733
    {0, "Unknown Command"},
734
    {1, "ILas_Reset"},
735
    {2, "ILaS_Set_Config"},
736
    {3, "ILaS_Set_PWM_Max_High_Ch2"},
737
    {4, "ILaS_Set_PWM_Max_High_Ch1"},
738
    {5, "ILaS_Set_PWM_Max_High_Ch0"},
739
    {6, "ILaS_Set_Cur_Ch1"},
740
    {7, "ILaS_Set_Cur_Ch0"},
741
    {8, "ILaS_Set_Temp_Offset"},
742
    {9, "ILaS_Trig_ADC_Cal"},
743
    {11, "ILaS_Set_Bias"},
744
    {12, "ILaS_Set_TC_Base"},
745
    {13, "ILaS_Set_TC_Offset"},
746
    {14, "ILaS_Set_Sig_High"},
747
    {15, "ILaS_Set_ADC_DAC"},
748
    {16, "ILaS_Burn_Item (part 1)"},
749
    {17, "ILaS_Burn_Sig"},
750
    {18, "ILaS_Burn_Item (part 2)"},
751
    {19, "ILaS_Set_TC_LUT"},
752
    {20, "ILaS_Define_Mcast"},
753
    {21, "ILaS_Set_PWM_Max_Low_Ch2"},
754
    {22, "ILaS_Set_PWM_Max_Low_Ch1"},
755
    {23, "ILaS_Set_PWM_Max_Low_Ch0"},
756
    {24, "ILaS_Set_Cur_Ch3"},
757
    {25, "ILaS_Burn_Item (part 3)"},
758
    {26, "ILaS_Set_Port"},
759
    {27, "ILaS_Branch_Read_Temp"},
760
    {28, "ILaS_Branch_Read_Status"},
761
    {29, "ILaS_Branch_Read_ADC"},
762
    {30, "ILaS_Branch_Read_Item (part 1)"},
763
    {31, "ILaS_Branch_Read_PWM"},
764
    {32, "ILaS_Branch_Read_Item (part 2)"},
765
    {33, "ILaS_Network_Init"},
766
    {34, "ILaS_Branch_Init"},
767
    {35, "ILaS_Network_Ping"},
768
    {36, "ILaS_Branch_Ping"},
769
    {37, "ILaS_Read_Register"},
770
    {38, "ILaS_BranchDevices_Read"},
771
    {39, "ILaS_Read_Event"},
772
    {40, "ILaS_Set_Fw_Mode"},
773
    {41, "ILaS_Set_Ps_Mode"},
774
    {42, "ILaS_Burn_Sniff_Mode"},
775
    {43, "ILaS_NOP"},
776
    {44, "ILaS_Trg_ADC_Meas"},
777
    {45, "ILaS_Set_3PWM_Low"},
778
    {46, "ILaS_Set_3PWM_High"},
779
    {47, "ILaS_Set_DIM"},
780
    {48, "ILaS_Set_PWM_Ch3"},
781
    {49, "ILaS_Write_Register"},
782
    {50, "ILaS_Burn_Register"},
783
    {51, "ILaS_Branch_Read_Item (config)"},
784
    {52, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch2)"},
785
    {53, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch1)"},
786
    {54, "ILaS_Branch_Read_Item (PWM_Max_Hi_Ch0)"},
787
    {55, "ILaS_Branch_Read_Item (Peak_Ch1)"},
788
    {56, "ILaS_Branch_Read_Item (Peak_Ch0)"},
789
    {57, "ILaS_Branch_Read_Item (Temp_Offset)"},
790
    {58, "ILaS_Branch_Read_Item (ADC_offset + ADC_ref)"},
791
    {59, "ILaS_Branch_Read_Item (Bias)"},
792
    {60, "ILaS_Branch_Read_Item (TC_Base_Ch2)"},
793
    {61, "ILaS_Branch_Read_Item (TC_Offset_Ch2)"},
794
    {62, "ILaS_Branch_Read_Item (last_fuse)"},
795
    {63, "ILaS_Branch_Read_PWM (Hi_Ch2)"},
796
    {64, "ILaS_Branch_Read_PWM (Hi_Ch1)"},
797
    {65, "ILaS_Branch_Read_PWM (Hi_Ch0)"},
798
    {66, "ILaS_Set_Fw_Mode (M0)"},
799
    {67, "ILaS_Set_Fw_Mode (M1)"},
800
    {68, "ILaS_Set_Fw_Mode (M2)"},
801
    {69, "ILaS_Set_Fw_Mode (M3)"},
802
    {70, "ILaS_Trg_ADC_Meas (Temperature)"},
803
    {71, "ILaS_Trg_ADC_Meas (5V_PRG)"},
804
    {72, "ILaS_Trg_ADC_Meas (1V5_DIG)"},
805
    {73, "ILaS_Trg_ADC_Meas (RED)"},
806
    {74, "ILaS_Trg_ADC_Meas (GREEN)"},
807
    {75, "ILaS_Trg_ADC_Meas (BLUE)"},
808
    {76, "ILaS_Trg_ADC_Meas (BG)"},
809
    {77, "ILaS_Trg_ADC_Meas (VSUP)"},
810
    {78, "ILaS_Trg_ADC_Meas (VCCA)"},
811
    {79, "ILaS_Trg_ADC_Meas (1V5_AN)"},
812
    {80, "ILaS_Trg_ADC_Meas (VSENSE)"},
813
    {0, NULL}
814
};
815
816
static const value_string tecmp_payload_flexray_tx_mode[] = {
817
    {0x0, "Reserved"},
818
    {0x1, "Single Shot Transmission"},
819
    {0x2, "Continuous Transmission"},
820
    {0x3, "TX None"},
821
    {0, NULL}
822
};
823
824
static const true_false_string tfs_tecmp_i2c_direction = {
825
    "Read",
826
    "Write"
827
};
828
829
9.22k
#define TECMP_I2C_CONTROL_ACK_REPEATED_START 3
830
4.44k
#define TECMP_I2C_CONTROL_NACK_REPEATED_START 5
831
static const value_string tecmp_i2c_control[] = {
832
    {0x0, "NACK"},
833
    {0x1, "ACK"},
834
    {0x2, "ACK + STOP"},
835
    {TECMP_I2C_CONTROL_ACK_REPEATED_START, "ACK + repeated START"},
836
    {0x4, "NACK + STOP"},
837
    {TECMP_I2C_CONTROL_NACK_REPEATED_START, "NACK + repeated START"},
838
    {0, NULL}
839
};
840
841
static const value_string tecmp_bus_status_link_status[] = {
842
    {0x0, "Down"},
843
    {0x1, "Up"},
844
    {0, NULL}
845
};
846
847
static const value_string tecmp_bus_status_link_quality[] = {
848
    {0x0, "Unacceptable or Down (0/5)"},
849
    {0x1, "Poor (1/5)"},
850
    {0x2, "Marginal (2/5)"},
851
    {0x3, "Good (3/5)"},
852
    {0x4, "Very good (4/5)"},
853
    {0x5, "Excellent (5/5)"},
854
    {0, NULL}
855
};
856
857
static const value_string tecmp_timesync_event_flags[] = {
858
    {0x0, "No error occurred"},
859
    {0x1, "Error occurred"},
860
    {0, NULL}
861
};
862
863
864
14
#define DATA_FLAG_CAN_ACK               0x0001
865
20
#define DATA_FLAG_CAN_RTR               0x0002
866
14
#define DATA_FLAG_CANFD_ESI             0x0002
867
14
#define DATA_FLAG_CAN_IDE               0x0004
868
20
#define DATA_FLAG_CAN_ERR               0x0008
869
14
#define DATA_FLAG_CAN_BIT_STUFF_ERR     0x0010
870
14
#define DATA_FLAG_CAN_CRC_DEL_ERR       0x0020
871
14
#define DATA_FLAG_CAN_ACK_DEL_ERR       0x0040
872
14
#define DATA_FLAG_CAN_EOF_ERR           0x0080
873
14
#define DATA_FLAG_CANFD_BRS             0x0010
874
14
#define DATA_FLAG_CANFD_BIT_STUFF_ERR   0x0020
875
14
#define DATA_FLAG_CANFD_CRC_DEL_ERR     0x0040
876
14
#define DATA_FLAG_CANFD_ACK_DEL_ERR     0x0080
877
14
#define DATA_FLAG_CANFD_EOF_ERR         0x0100
878
879
14
#define DATA_FLAG_FR_NF                 0x0001
880
14
#define DATA_FLAG_FR_ST                 0x0002
881
14
#define DATA_FLAG_FR_SYNC               0x0004
882
14
#define DATA_FLAG_FR_WUS                0x0008
883
14
#define DATA_FLAG_FR_PPI                0x0010
884
14
#define DATA_FLAG_FR_CAS                0x0020
885
28
#define DATA_FLAG_FR_HDR_CRC_ERR        0x1000
886
14
#define DATA_FLAG_FR_FRAME_CRC_ERR      0x2000
887
888
27
#define DATA_LIN_ID_MASK                0x3F
889
0
#define DATA_FR_HEADER_CRC_MAX          0x07FF
890
891
0
#define TECMP_ETH_RAW_PREAMBLE          0x55
892
0
#define TECMP_ETH_RAW_SFD_ORIG          0xD5
893
#define TECMP_ETH_RAW_SFD_SMD_V         0x07
894
#define TECMP_ETH_RAW_SFD_SMD_R         0x19
895
#define TECMP_ETH_RAW_SFD_SMD_S0        0xE6
896
#define TECMP_ETH_RAW_SFD_SMD_S1        0x4C
897
#define TECMP_ETH_RAW_SFD_SMD_S2        0x7F
898
#define TECMP_ETH_RAW_SFD_SMD_S3        0xB3
899
#define TECMP_ETH_RAW_SFD_SMD_C0        0x61
900
#define TECMP_ETH_RAW_SFD_SMD_C1        0x52
901
#define TECMP_ETH_RAW_SFD_SMD_C2        0x9E
902
#define TECMP_ETH_RAW_SFD_SMD_C3        0x2A
903
904
static const value_string tecmp_eth_raw_sfd[] = {
905
    {TECMP_ETH_RAW_SFD_ORIG, "SFD/SMD-E"},
906
    {TECMP_ETH_RAW_SFD_SMD_V, "SMD-V"},
907
    {TECMP_ETH_RAW_SFD_SMD_R, "SMD-R"},
908
    {TECMP_ETH_RAW_SFD_SMD_S0, "SMD-S0"},
909
    {TECMP_ETH_RAW_SFD_SMD_S1, "SMD-S1"},
910
    {TECMP_ETH_RAW_SFD_SMD_S2, "SMD-S2"},
911
    {TECMP_ETH_RAW_SFD_SMD_S3, "SMD-S3"},
912
    {TECMP_ETH_RAW_SFD_SMD_C0, "SMD-C0"},
913
    {TECMP_ETH_RAW_SFD_SMD_C1, "SMD-C1"},
914
    {TECMP_ETH_RAW_SFD_SMD_C2, "SMD-C2"},
915
    {TECMP_ETH_RAW_SFD_SMD_C3, "SMD-C3"},
916
    {0, NULL}
917
};
918
919
/* Default Interface Names */
920
static const value_string tecmp_default_iface_names_lin[] = {
921
    {1, "LIN-A"},
922
    {2, "LIN-B"},
923
    {3, "LIN-C"},
924
    {4, "LIN-D"},
925
    {5, "LIN-E"},
926
    {6, "LIN-F"},
927
    {7, "LIN-G"},
928
    {8, "LIN-H"},
929
    {9, "LIN-I"},
930
    {10, "LIN-J"},
931
    {11, "ANA-1"},
932
    {12, "ANA-2"},
933
    {13, "ANA-3"},
934
    {14, "ANA-4"},
935
    {15, "ANADIFF-1"},
936
    {16, "ANADIFF-1"},
937
    {0, NULL}
938
};
939
940
static const value_string tecmp_default_iface_names_can[] = {
941
    {1, "CAN-A"},
942
    {2, "CAN-B"},
943
    {3, "CAN-C"},
944
    {4, "CAN-D"},
945
    {5, "CAN-E"},
946
    {6, "CAN-F"},
947
    {7, "FlexRay"},
948
    {8, "RS-232-A"},
949
    {9, "RS-232-B"},
950
    {0, NULL}
951
};
952
953
static const value_string tecmp_default_iface_names_100_high[] = {
954
    {1, "100BASE-T1-1A"},
955
    {2, "100BASE-T1-1B"},
956
    {3, "100BASE-T1-2A"},
957
    {4, "100BASE-T1-2B"},
958
    {5, "100BASE-T1-3A"},
959
    {6, "100BASE-T1-3B"},
960
    {7, "100BASE-T1-4A"},
961
    {8, "100BASE-T1-4B"},
962
    {9, "100BASE-T1-5A"},
963
    {10, "100BASE-T1-5B"},
964
    {11, "100BASE-T1-6A"},
965
    {12, "100BASE-T1-6B"},
966
    {0, NULL}
967
};
968
969
static const value_string tecmp_default_iface_names_eth_combo[] = {
970
    {1, "100BASE-T1-1A"},
971
    {2, "100BASE-T1-1B"},
972
    {3, "100BASE-T1-2A"},
973
    {4, "100BASE-T1-2B"},
974
    {5, "1000BASE-T1-3A"},
975
    {6, "1000BASE-T1-3B"},
976
    {0, NULL}
977
};
978
979
static const value_string tecmp_default_iface_names_1000_high[] = {
980
    {1, "1000BASE-T1-1A"},
981
    {2, "1000BASE-T1-1B"},
982
    {3, "1000BASE-T1-2A"},
983
    {4, "1000BASE-T1-2B"},
984
    {5, "1000BASE-T1-3A"},
985
    {6, "1000BASE-T1-3B"},
986
    {7, "1000BASE-T1-4A"},
987
    {8, "1000BASE-T1-4B"},
988
    {9, "1000BASE-T1-5A"},
989
    {10, "1000BASE-T1-5B"},
990
    {11, "1000BASE-T1-6A"},
991
    {12, "1000BASE-T1-6B"},
992
    {0, NULL}
993
};
994
995
static const value_string tecmp_default_iface_names_10base_t1s[] = {
996
    {1, "10BASE-T1S-1"},
997
    {2, "10BASE-T1S-2"},
998
    {3, "10BASE-T1S-3"},
999
    {4, "10BASE-T1S-4"},
1000
    {5, "10BASE-T1S-5"},
1001
    {6, "10BASE-T1S-6"},
1002
    {0, NULL}
1003
};
1004
1005
static const value_string tecmp_default_iface_names_ilas_sniffer[] = {
1006
    {1, "ILaS-1"},
1007
    {2, "ILaS-2"},
1008
    {3, "ILaS-3"},
1009
    {4, "ILaS-4"},
1010
    {5, "10BASE-T1S"},
1011
    {6, "ADC1"},
1012
    {0, NULL}
1013
};
1014
1015
static const value_string tecmp_default_iface_names_serdes_gsml[] = {
1016
    {1, "SerDes-Port-1-I2C-1"},
1017
    {2, "SerDes-Port-1-I2C-2"},
1018
    {3, "SerDes-Port-1-GPIO"},
1019
    {4, "SerDes-Port-1-Virtual-Channel-1"},
1020
    {5, "SerDes-Port-1-Virtual-Channel-2"},
1021
    {6, "SerDes-Port-1-Virtual-Channel-3"},
1022
    {7, "SerDes-Port-1-Virtual-Channel-4"},
1023
1024
    {8, "SerDes-Port-2-I2C-1"},
1025
    {9, "SerDes-Port-2-I2C-2"},
1026
    {10, "SerDes-Port-2-GPIO"},
1027
    {11, "SerDes-Port-2-Virtual-Channel-1"},
1028
    {12, "SerDes-Port-2-Virtual-Channel-2"},
1029
    {13, "SerDes-Port-2-Virtual-Channel-3"},
1030
    {14, "SerDes-Port-2-Virtual-Channel-4"},
1031
1032
    {15, "SerDes-Port-3-I2C-1"},
1033
    {16, "SerDes-Port-3-I2C-2"},
1034
    {17, "SerDes-Port-3-GPIO"},
1035
    {18, "SerDes-Port-3-Virtual-Channel-1"},
1036
    {19, "SerDes-Port-3-Virtual-Channel-2"},
1037
    {20, "SerDes-Port-3-Virtual-Channel-3"},
1038
    {21, "SerDes-Port-3-Virtual-Channel-4"},
1039
1040
    {22, "SerDes-Port-4-I2C-1"},
1041
    {23, "SerDes-Port-4-I2C-2"},
1042
    {24, "SerDes-Port-4-GPIO"},
1043
    {25, "SerDes-Port-4-Virtual-Channel-1"},
1044
    {26, "SerDes-Port-4-Virtual-Channel-2"},
1045
    {27, "SerDes-Port-4-Virtual-Channel-3"},
1046
    {28, "SerDes-Port-4-Virtual-Channel-4"},
1047
    {0, NULL}
1048
};
1049
1050
static const value_string tecmp_default_iface_names_serdes_asaml[] = {
1051
    {1, "SerDes-Port-1-I2C-1"},
1052
    {2, "SerDes-Port-1-I2C-2"},
1053
    {3, "SerDes-Port-1-I2C-3"},
1054
    {4, "SerDes-Port-1-I2C-4"},
1055
    {5, "SerDes-Port-1-GPIO"},
1056
    {6, "SerDes-Port-1-Virtual-Channel-1"},
1057
    {7, "SerDes-Port-1-Virtual-Channel-2"},
1058
    {8, "SerDes-Port-1-Virtual-Channel-3"},
1059
    {9, "SerDes-Port-1-Virtual-Channel-4"},
1060
    {0, NULL}
1061
};
1062
1063
1064
/********* UATs *********/
1065
1066
typedef struct _generic_one_id_string {
1067
    unsigned   id;
1068
    char   *name;
1069
} generic_one_id_string_t;
1070
1071
/* Interface UAT */
1072
typedef struct _interface_config {
1073
    unsigned  id;
1074
    unsigned  bus_id;
1075
    char     *name;
1076
} interface_config_t;
1077
1078
14
#define DATAFILE_TECMP_DEVICE_IDS "TECMP_device_identifiers"
1079
14
#define DATAFILE_TECMP_INTERFACE_IDS "TECMP_interface_identifiers"
1080
14
#define DATAFILE_TECMP_CONTROL_MSG_IDS "TECMP_control_message_identifiers"
1081
1082
static GHashTable *data_tecmp_devices;
1083
static generic_one_id_string_t *tecmp_devices;
1084
static unsigned tecmp_devices_num;
1085
1086
0
UAT_HEX_CB_DEF(tecmp_devices, id, generic_one_id_string_t)
Unexecuted instantiation: packet-tecmp.c:tecmp_devices_id_set_cb
Unexecuted instantiation: packet-tecmp.c:tecmp_devices_id_tostr_cb
1087
UAT_CSTRING_CB_DEF(tecmp_devices, name, generic_one_id_string_t)
1088
1089
static GHashTable *data_tecmp_interfaces;
1090
static interface_config_t *tecmp_interfaces;
1091
static unsigned tecmp_interfaces_num;
1092
1093
0
UAT_HEX_CB_DEF(tecmp_interfaces, id, interface_config_t)
Unexecuted instantiation: packet-tecmp.c:tecmp_interfaces_id_set_cb
Unexecuted instantiation: packet-tecmp.c:tecmp_interfaces_id_tostr_cb
1094
UAT_CSTRING_CB_DEF(tecmp_interfaces, name, interface_config_t)
1095
0
UAT_HEX_CB_DEF(tecmp_interfaces, bus_id, interface_config_t)
Unexecuted instantiation: packet-tecmp.c:tecmp_interfaces_bus_id_set_cb
Unexecuted instantiation: packet-tecmp.c:tecmp_interfaces_bus_id_tostr_cb
1096
1097
static GHashTable *data_tecmp_ctrlmsgids;
1098
static generic_one_id_string_t *tecmp_ctrl_msgs;
1099
static unsigned tecmp_ctrl_msg_num;
1100
1101
0
UAT_HEX_CB_DEF(tecmp_ctrl_msgs, id, generic_one_id_string_t)
Unexecuted instantiation: packet-tecmp.c:tecmp_ctrl_msgs_id_set_cb
Unexecuted instantiation: packet-tecmp.c:tecmp_ctrl_msgs_id_tostr_cb
1102
UAT_CSTRING_CB_DEF(tecmp_ctrl_msgs, name, generic_one_id_string_t)
1103
1104
/* ID -> Name */
1105
static void *
1106
0
copy_generic_one_id_string_cb(void *n, const void *o, size_t size _U_) {
1107
0
    generic_one_id_string_t *new_rec = (generic_one_id_string_t *)n;
1108
0
    const generic_one_id_string_t *old_rec = (const generic_one_id_string_t *)o;
1109
1110
0
    new_rec->name = g_strdup(old_rec->name);
1111
0
    new_rec->id = old_rec->id;
1112
0
    return new_rec;
1113
0
}
1114
1115
static bool
1116
0
update_generic_one_identifier_16bit(void *r, char **err) {
1117
0
    generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
1118
1119
0
    if (rec->id > 0xffff) {
1120
0
        *err = ws_strdup_printf("We currently only support 16 bit identifiers (ID: %i  Name: %s)", rec->id, rec->name);
1121
0
        return false;
1122
0
    }
1123
1124
0
    if (rec->name == NULL || rec->name[0] == 0) {
1125
0
        *err = g_strdup("Name cannot be empty");
1126
0
        return false;
1127
0
    }
1128
1129
0
    return true;
1130
0
}
1131
1132
static void
1133
0
free_generic_one_id_string_cb(void *r) {
1134
0
    generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
1135
    /* freeing result of g_strdup */
1136
0
    g_free(rec->name);
1137
0
    rec->name = NULL;
1138
0
}
1139
1140
/* ID -> ID, Name */
1141
static void *
1142
0
copy_interface_config_cb(void *n, const void *o, size_t size _U_) {
1143
0
    interface_config_t *new_rec = (interface_config_t *)n;
1144
0
    const interface_config_t *old_rec = (const interface_config_t *)o;
1145
1146
0
    new_rec->id = old_rec->id;
1147
0
    new_rec->name = g_strdup(old_rec->name);
1148
0
    new_rec->bus_id = old_rec->bus_id;
1149
0
    return new_rec;
1150
0
}
1151
1152
static bool
1153
0
update_interface_config(void *r, char **err) {
1154
0
    interface_config_t *rec = (interface_config_t *)r;
1155
1156
0
    if (rec->id > 0xffffffff) {
1157
0
        *err = ws_strdup_printf("We currently only support 32 bit identifiers (ID: %i  Name: %s)", rec->id, rec->name);
1158
0
        return false;
1159
0
    }
1160
1161
0
    if (rec->name == NULL || rec->name[0] == 0) {
1162
0
        *err = g_strdup("Name cannot be empty");
1163
0
        return false;
1164
0
    }
1165
1166
0
    if (rec->bus_id > 0xffff) {
1167
0
        *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);
1168
0
        return false;
1169
0
    }
1170
1171
0
    return true;
1172
0
}
1173
1174
static void
1175
0
free_interface_config_cb(void *r) {
1176
0
    interface_config_t *rec = (interface_config_t *)r;
1177
    /* freeing result of g_strdup */
1178
0
    g_free(rec->name);
1179
0
    rec->name = NULL;
1180
0
}
1181
1182
static char *
1183
947
ht_interface_config_to_string(unsigned int identifier) {
1184
947
    if (data_tecmp_interfaces == NULL) {
1185
0
        return NULL;
1186
0
    }
1187
1188
947
    interface_config_t *tmp = g_hash_table_lookup(data_tecmp_interfaces, GUINT_TO_POINTER(identifier));
1189
947
    if (tmp == NULL) {
1190
947
        return NULL;
1191
947
    }
1192
1193
0
    return tmp->name;
1194
947
}
1195
1196
static uint16_t
1197
16
ht_interface_config_to_bus_id(unsigned int identifier) {
1198
16
    if (data_tecmp_interfaces == NULL) {
1199
0
        return 0;
1200
0
    }
1201
1202
16
    interface_config_t *tmp = g_hash_table_lookup(data_tecmp_interfaces, GUINT_TO_POINTER(identifier));
1203
16
    if (tmp == NULL) {
1204
        /* 0 means basically any or none */
1205
16
        return 0;
1206
16
    }
1207
1208
0
    return tmp->bus_id;
1209
16
}
1210
1211
/*** UAT TECMP_DEVICE_IDs ***/
1212
1213
static void
1214
14
reset_tecmp_devices_cb(void) {
1215
    /* destroy hash table, if it exists */
1216
14
    if (data_tecmp_devices) {
1217
0
        g_hash_table_destroy(data_tecmp_devices);
1218
0
        data_tecmp_devices = NULL;
1219
0
    }
1220
14
}
1221
1222
static void
1223
14
post_update_tecmp_devices_cb(void) {
1224
14
    reset_tecmp_devices_cb();
1225
1226
    /* create new hash table */
1227
14
    data_tecmp_devices = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
1228
1229
14
    for (unsigned i = 0; i < tecmp_devices_num; i++) {
1230
0
        g_hash_table_insert(data_tecmp_devices, GUINT_TO_POINTER(tecmp_devices[i].id), tecmp_devices[i].name);
1231
0
    }
1232
14
}
1233
1234
static void
1235
560
add_device_id_text(proto_item *ti, uint16_t device_id) {
1236
    /* lets check configured entries first */
1237
560
    const char *descr = NULL;
1238
1239
560
    if (data_tecmp_devices != NULL) {
1240
560
        descr = g_hash_table_lookup(data_tecmp_devices, GUINT_TO_POINTER(device_id));
1241
560
    }
1242
1243
560
    if (descr == NULL) {
1244
        /* lets check specific  */
1245
560
        descr = try_val_to_str(device_id, tecmp_device_ids_specific);
1246
560
    }
1247
1248
560
    if (descr == NULL) {
1249
        /* lets check ranged prefixes */
1250
557
        descr = try_val_to_str((device_id & 0xfff0), tecmp_device_id_prefixes);
1251
557
        if (descr != NULL) {
1252
54
            if ((device_id & 0x000f) == 0) {
1253
16
                proto_item_append_text(ti, " (%s %d (Default))", descr, (device_id & 0x000f));
1254
38
            } else {
1255
38
                proto_item_append_text(ti, " (%s %d)", descr, (device_id & 0x000f));
1256
38
            }
1257
54
            return;
1258
54
        }
1259
557
    }
1260
1261
    /* if, we found nothing before */
1262
506
    if (descr == NULL) {
1263
503
        descr = "Unknown/Unconfigured CM";
1264
503
    }
1265
1266
506
    proto_item_append_text(ti, " (%s)", descr);
1267
506
}
1268
1269
/*** UAT TECMP_INTERFACE_IDs ***/
1270
1271
static void
1272
14
reset_tecmp_interfaces_cb(void) {
1273
    /* destroy hash table, if it exists */
1274
14
    if (data_tecmp_interfaces) {
1275
0
        g_hash_table_destroy(data_tecmp_interfaces);
1276
0
        data_tecmp_interfaces = NULL;
1277
0
    }
1278
14
}
1279
1280
static void
1281
14
post_update_tecmp_interfaces_cb(void) {
1282
14
    reset_tecmp_interfaces_cb();
1283
1284
    /* create new hash table */
1285
14
    data_tecmp_interfaces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
1286
1287
14
    for (unsigned i = 0; i < tecmp_interfaces_num; i++) {
1288
0
        g_hash_table_insert(data_tecmp_interfaces, GUINT_TO_POINTER(tecmp_interfaces[i].id), &tecmp_interfaces[i]);
1289
0
    }
1290
14
}
1291
1292
static void
1293
415
add_interface_id_text_and_name(proto_item *ti, uint32_t interface_id, tvbuff_t *tvb, int offset) {
1294
415
    const char *descr = ht_interface_config_to_string(interface_id);
1295
1296
415
    if (descr != NULL) {
1297
0
        proto_item_append_text(ti, " (%s)", descr);
1298
0
        proto_tree *subtree = proto_item_add_subtree(ti, ett_tecmp_payload_interface_id);
1299
0
        proto_tree_add_string(subtree, hf_tecmp_payload_interface_name, tvb, offset, 4, descr);
1300
0
    }
1301
415
}
1302
1303
/*** UAT TECMP_CONTROL_MESSAGE_IDs ***/
1304
1305
static void
1306
14
reset_tecmp_control_messages_cb(void) {
1307
    /* destroy hash table, if it exists */
1308
14
    if (data_tecmp_ctrlmsgids) {
1309
0
        g_hash_table_destroy(data_tecmp_ctrlmsgids);
1310
0
        data_tecmp_ctrlmsgids = NULL;
1311
0
    }
1312
14
}
1313
1314
static void
1315
14
post_update_tecmp_control_messages_cb(void) {
1316
14
    reset_tecmp_control_messages_cb();
1317
1318
    /* create new hash table */
1319
14
    data_tecmp_ctrlmsgids = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
1320
1321
14
    for (unsigned i = 0; i < tecmp_ctrl_msg_num; i++) {
1322
0
        g_hash_table_insert(data_tecmp_ctrlmsgids, GUINT_TO_POINTER(tecmp_ctrl_msgs[i].id), tecmp_ctrl_msgs[i].name);
1323
0
    }
1324
14
}
1325
1326
static const char*
1327
96
resolve_control_message_id(wmem_allocator_t* allocator, uint16_t control_message_id) {
1328
96
    const char *tmp = NULL;
1329
1330
96
    if (data_tecmp_ctrlmsgids != NULL) {
1331
96
        tmp = g_hash_table_lookup(data_tecmp_ctrlmsgids, GUINT_TO_POINTER(control_message_id));
1332
96
    }
1333
1334
    /* lets look at the static values, if nothing is configured */
1335
96
    if (tmp == NULL) {
1336
96
        tmp = try_val_to_str(control_message_id, tecmp_ctrl_msg_ids_types);
1337
96
    }
1338
1339
    /* no configured or standardized name known */
1340
96
    if (tmp != NULL) {
1341
3
        return wmem_strdup_printf(allocator, "%s (0x%04x)", tmp, control_message_id);
1342
3
    }
1343
1344
    /* just give back unknown */
1345
93
    return wmem_strdup_printf(allocator, "Unknown (0x%04x)", control_message_id);
1346
96
}
1347
1348
1349
1350
static bool
1351
257
tecmp_entry_header_present(tvbuff_t *tvb, unsigned offset) {
1352
257
    uint32_t chan_id = 0;
1353
257
    uint64_t tstamp  = 0;
1354
257
    uint16_t length  = 0;
1355
1356
257
    chan_id = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1357
257
    tstamp  = tvb_get_uint64(tvb, offset + 4, ENC_BIG_ENDIAN);
1358
257
    length  = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
1359
1360
257
    if (chan_id == 0 && tstamp == 0 && length == 0) {
1361
        /* 0 is not valid and therefore we assume padding. */
1362
9
        return false;
1363
9
    }
1364
248
    return true;
1365
257
}
1366
1367
static unsigned
1368
dissect_tecmp_entry_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, unsigned tecmp_msg_type, uint16_t data_type,
1369
411
                           bool first, uint16_t *dataflags, uint32_t *interface_id, uint64_t *timestamp_ns) {
1370
411
    proto_item *ti;
1371
411
    proto_tree *subtree = NULL;
1372
411
    unsigned offset = offset_orig;
1373
1374
411
    nstime_t timestamp;
1375
411
    uint64_t ns = 0;
1376
411
    bool async = false;
1377
411
    unsigned tmp;
1378
1379
411
    static int * const dataflags_generic[] = {
1380
411
        &hf_tecmp_payload_data_flags_overflow,
1381
411
        &hf_tecmp_payload_data_flags_tx,
1382
411
        &hf_tecmp_payload_data_flags_crc,
1383
411
        NULL
1384
411
    };
1385
1386
411
    static int * const dataflags_ethernet_10base_t1s[] = {
1387
411
        &hf_tecmp_payload_data_flags_overflow,
1388
411
        &hf_tecmp_payload_data_flags_tx,
1389
411
        &hf_tecmp_payload_data_flags_crc,
1390
411
        &hf_tecmp_payload_data_flags_phy_event_error,
1391
411
        NULL
1392
411
    };
1393
1394
411
    static int * const dataflags_lin[] = {
1395
411
        &hf_tecmp_payload_data_flags_overflow,
1396
411
        &hf_tecmp_payload_data_flags_tx,
1397
411
        &hf_tecmp_payload_data_flags_checksum,
1398
1399
411
        &hf_tecmp_payload_data_flags_sleep,
1400
411
        &hf_tecmp_payload_data_flags_short_wup,
1401
411
        &hf_tecmp_payload_data_flags_wup,
1402
411
        &hf_tecmp_payload_data_flags_no_resp,
1403
411
        &hf_tecmp_payload_data_flags_parity,
1404
411
        &hf_tecmp_payload_data_flags_coll,
1405
411
        NULL
1406
411
    };
1407
1408
411
    static int * const dataflags_lin_tx[] = {
1409
411
        &hf_tecmp_payload_data_flags_use_checksum_value,
1410
1411
411
        &hf_tecmp_payload_data_flags_short_wup,
1412
411
        &hf_tecmp_payload_data_flags_wup,
1413
411
        &hf_tecmp_payload_data_flags_use_parity_bits,
1414
411
        NULL
1415
411
    };
1416
1417
411
    static int * const dataflags_can_data[] = {
1418
411
        &hf_tecmp_payload_data_flags_overflow,
1419
411
        &hf_tecmp_payload_data_flags_tx,
1420
411
        &hf_tecmp_payload_data_flags_crc,
1421
1422
411
        &hf_tecmp_payload_data_flags_can_eof_err,
1423
411
        &hf_tecmp_payload_data_flags_can_ack_del_err,
1424
411
        &hf_tecmp_payload_data_flags_can_crc_del_err,
1425
411
        &hf_tecmp_payload_data_flags_can_bit_stuff_err,
1426
411
        &hf_tecmp_payload_data_flags_err,
1427
411
        &hf_tecmp_payload_data_flags_ide,
1428
411
        &hf_tecmp_payload_data_flags_rtr,
1429
411
        &hf_tecmp_payload_data_flags_ack,
1430
411
        NULL
1431
411
    };
1432
1433
411
    static int * const dataflags_can_tx_data[] = {
1434
411
        &hf_tecmp_payload_data_flags_use_crc_value,
1435
1436
411
        &hf_tecmp_payload_data_flags_can_eof_err,
1437
411
        &hf_tecmp_payload_data_flags_can_ack_del_err,
1438
411
        &hf_tecmp_payload_data_flags_can_crc_del_err,
1439
411
        &hf_tecmp_payload_data_flags_can_bit_stuff_err,
1440
411
        NULL
1441
411
    };
1442
1443
411
    static int * const dataflags_can_fd_data[] = {
1444
411
        &hf_tecmp_payload_data_flags_overflow,
1445
411
        &hf_tecmp_payload_data_flags_tx,
1446
411
        &hf_tecmp_payload_data_flags_crc,
1447
1448
411
        &hf_tecmp_payload_data_flags_canfd_eof_err,
1449
411
        &hf_tecmp_payload_data_flags_canfd_ack_del_err,
1450
411
        &hf_tecmp_payload_data_flags_canfd_crc_del_err,
1451
411
        &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,
1452
411
        &hf_tecmp_payload_data_flags_brs,
1453
411
        &hf_tecmp_payload_data_flags_err,
1454
411
        &hf_tecmp_payload_data_flags_ide,
1455
411
        &hf_tecmp_payload_data_flags_esi,
1456
411
        &hf_tecmp_payload_data_flags_ack,
1457
411
        NULL
1458
411
    };
1459
1460
411
    static int * const dataflags_can_fd_tx_data[] = {
1461
411
        &hf_tecmp_payload_data_flags_use_crc_value,
1462
1463
411
        &hf_tecmp_payload_data_flags_canfd_eof_err,
1464
411
        &hf_tecmp_payload_data_flags_canfd_ack_del_err,
1465
411
        &hf_tecmp_payload_data_flags_canfd_crc_del_err,
1466
411
        &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,
1467
411
        &hf_tecmp_payload_data_flags_brs,
1468
411
        NULL
1469
411
    };
1470
1471
411
    static int * const dataflags_flexray_data[] = {
1472
411
        &hf_tecmp_payload_data_flags_overflow,
1473
411
        &hf_tecmp_payload_data_flags_tx,
1474
1475
411
        &hf_tecmp_payload_data_flags_frame_crc_err,
1476
411
        &hf_tecmp_payload_data_flags_header_crc_err,
1477
411
        &hf_tecmp_payload_data_flags_cas,
1478
411
        &hf_tecmp_payload_data_flags_ppi,
1479
411
        &hf_tecmp_payload_data_flags_wus,
1480
411
        &hf_tecmp_payload_data_flags_sync,
1481
411
        &hf_tecmp_payload_data_flags_sf,
1482
411
        &hf_tecmp_payload_data_flags_nf,
1483
411
        NULL
1484
411
    };
1485
1486
411
    static int * const dataflags_flexray_tx_data[] = {
1487
1488
411
        &hf_tecmp_payload_data_flags_use_header_crc_value,
1489
411
        &hf_tecmp_payload_data_flags_tx_mode,
1490
411
        NULL
1491
411
    };
1492
1493
411
    static int * const dataflags_gpio[] = {
1494
411
        &hf_tecmp_payload_data_flags_overflow,
1495
411
        &hf_tecmp_payload_data_flags_tx,
1496
411
        NULL
1497
411
    };
1498
1499
411
    static int * const dataflags_ilas[] = {
1500
411
        &hf_tecmp_payload_data_flags_crc,
1501
1502
411
        &hf_tecmp_payload_data_flags_direction,
1503
411
        &hf_tecmp_payload_data_flags_crc_enabled,
1504
411
        NULL
1505
411
    };
1506
1507
411
    static int * const dataflags_rs232_uart_ascii[] = {
1508
411
        &hf_tecmp_payload_data_flags_tx,
1509
1510
411
        &hf_tecmp_payload_data_flags_dl,
1511
411
        &hf_tecmp_payload_data_flags_parity_error,
1512
411
        NULL
1513
411
    };
1514
1515
411
    static int * const dataflags_analog[] = {
1516
411
        &hf_tecmp_payload_data_flags_overflow,
1517
1518
411
        &hf_tecmp_payload_data_flags_sample_time,
1519
411
        &hf_tecmp_payload_data_flags_factor,
1520
411
        &hf_tecmp_payload_data_flags_unit,
1521
411
        &hf_tecmp_payload_data_flags_threshold_u,
1522
411
        &hf_tecmp_payload_data_flags_threshold_o,
1523
411
        NULL
1524
411
    };
1525
1526
    /* Can't use col_append_sep_str because we already set something before. */
1527
411
    if (!first) {
1528
124
        col_append_str(pinfo->cinfo, COL_INFO, ", ");
1529
124
    }
1530
411
    col_append_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, data_type, tecmp_data_type_names, "Unknown (%d)"));
1531
1532
411
    ti = proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN, &tmp);
1533
411
    add_interface_id_text_and_name(ti, tmp, tvb, offset);
1534
411
    if (interface_id != NULL) {
1535
248
        *interface_id = tmp;
1536
248
    }
1537
1538
411
    ns = tvb_get_uint64(tvb, offset + 4, ENC_BIG_ENDIAN) & 0x3fffffffffffffff;
1539
1540
411
    if (timestamp_ns != NULL) {
1541
375
        *timestamp_ns = ns;
1542
375
    }
1543
1544
411
    timestamp.secs = (time_t)(ns / 1000000000);
1545
411
    timestamp.nsecs = (int)(ns % 1000000000);
1546
411
    ti = proto_tree_add_time(tree, hf_tecmp_payload_timestamp, tvb, offset + 4, 8, &timestamp);
1547
411
    subtree = proto_item_add_subtree(ti, ett_tecmp_payload_timestamp);
1548
411
    proto_tree_add_item_ret_boolean(subtree, hf_tecmp_payload_timestamp_async, tvb, offset + 4, 1, ENC_NA, &async);
1549
411
    proto_tree_add_item(subtree, hf_tecmp_payload_timestamp_res, tvb, offset + 4, 1, ENC_NA);
1550
1551
411
    if (async) {
1552
87
        proto_item_append_text(ti, " (not synchronized)");
1553
324
    } else {
1554
324
        proto_item_append_text(ti, " (synchronized or master)");
1555
324
    }
1556
411
    ti = proto_tree_add_uint64(tree, hf_tecmp_payload_timestamp_ns, tvb, offset + 4, 8, ns);
1557
411
    proto_item_set_hidden(ti);
1558
1559
411
    proto_tree_add_item(tree, hf_tecmp_payload_length, tvb, offset+12, 2, ENC_BIG_ENDIAN);
1560
411
    offset += 14;
1561
1562
411
    if (dataflags != NULL) {
1563
248
        *dataflags = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1564
248
    }
1565
1566
411
    switch (tecmp_msg_type) {
1567
176
    case TECMP_MSG_TYPE_LOG_STREAM:
1568
176
        switch (data_type) {
1569
20
        case TECMP_DATA_TYPE_LIN:
1570
20
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_lin, ENC_BIG_ENDIAN);
1571
20
            break;
1572
1573
22
        case TECMP_DATA_TYPE_CAN_DATA:
1574
22
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_data, ENC_BIG_ENDIAN);
1575
22
            break;
1576
1577
0
        case TECMP_DATA_TYPE_CAN_FD_DATA:
1578
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_fd_data, ENC_BIG_ENDIAN);
1579
0
            break;
1580
1581
0
        case TECMP_DATA_TYPE_FR_DATA:
1582
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_flexray_data, ENC_BIG_ENDIAN);
1583
0
            break;
1584
1585
0
        case TECMP_DATA_TYPE_GPIO:
1586
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_gpio, ENC_BIG_ENDIAN);
1587
0
            break;
1588
1589
0
        case TECMP_DATA_TYPE_ILAS:
1590
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_ilas, ENC_BIG_ENDIAN);
1591
0
            break;
1592
1593
0
        case TECMP_DATA_TYPE_RS232_ASCII:
1594
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_rs232_uart_ascii, ENC_BIG_ENDIAN);
1595
0
            break;
1596
1597
0
        case TECMP_DATA_TYPE_ANALOG:
1598
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_analog, ENC_BIG_ENDIAN);
1599
0
            break;
1600
1601
0
        case TECMP_DATA_TYPE_ETH_10BASE_T1S:
1602
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_ethernet_10base_t1s, ENC_BIG_ENDIAN);
1603
0
            break;
1604
1605
0
        case TECMP_DATA_TYPE_ETH_RAW:
1606
0
        case TECMP_DATA_TYPE_ETH:
1607
134
        default:
1608
134
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_generic, ENC_BIG_ENDIAN);
1609
176
        }
1610
176
        break;
1611
1612
176
    case TECMP_MSG_TYPE_REPLAY_DATA:
1613
72
        switch (data_type) {
1614
0
        case TECMP_DATA_TYPE_LIN:
1615
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_lin_tx, ENC_BIG_ENDIAN);
1616
0
            break;
1617
1618
0
        case TECMP_DATA_TYPE_CAN_DATA:
1619
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_tx_data, ENC_BIG_ENDIAN);
1620
0
            break;
1621
1622
0
        case TECMP_DATA_TYPE_CAN_FD_DATA:
1623
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_can_fd_tx_data, ENC_BIG_ENDIAN);
1624
0
            break;
1625
1626
0
        case TECMP_DATA_TYPE_FR_DATA:
1627
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_flexray_tx_data, ENC_BIG_ENDIAN);
1628
0
            break;
1629
1630
0
        case TECMP_DATA_TYPE_RS232_ASCII:
1631
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_rs232_uart_ascii, ENC_BIG_ENDIAN);
1632
0
            break;
1633
1634
0
        case TECMP_DATA_TYPE_ANALOG:
1635
0
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_analog, ENC_BIG_ENDIAN);
1636
0
            break;
1637
1638
0
        case TECMP_DATA_TYPE_ETH_RAW:
1639
0
        case TECMP_DATA_TYPE_ETH:
1640
72
        default:
1641
72
            proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_data_flags, ett_tecmp_payload_dataflags, dataflags_generic, ENC_BIG_ENDIAN);
1642
72
        }
1643
72
        break;
1644
1645
72
    case TECMP_MSG_TYPE_CTRL_MSG:
1646
67
    case TECMP_MSG_TYPE_STATUS_DEV:
1647
139
    case TECMP_MSG_TYPE_STATUS_BUS:
1648
159
    case TECMP_MSG_TYPE_CFG_CM:
1649
161
    case TECMP_MSG_TYPE_COUNTER_EVENT:
1650
163
    case TECMP_MSG_TYPE_TIMESYNC_EVENT:
1651
163
    default:
1652
163
        proto_tree_add_item(tree, hf_tecmp_payload_data_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
1653
163
        break;
1654
411
    }
1655
1656
411
    offset += 2;
1657
1658
411
    return offset - offset_orig;
1659
411
}
1660
1661
static void
1662
12
dissect_tecmp_status_config_vendor_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti_root, uint8_t device_type _U_, uint8_t vendor_id) {
1663
12
    proto_tree *tree = NULL;
1664
12
    int offset = 0;
1665
12
    unsigned data_length = 0;
1666
1667
12
    proto_item_append_text(ti_root, " (%s)", val_to_str(pinfo->pool, vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1668
12
    tree = proto_item_add_subtree(ti_root, ett_tecmp_status_bus_vendor_data);
1669
1670
12
    switch (vendor_id) {
1671
0
    case TECMP_VENDOR_ID_TECHNICA:
1672
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_version, tvb, offset, 1, ENC_NA);
1673
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_reserved, tvb, offset + 1, 1, ENC_NA);
1674
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_msg_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1675
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_total_length, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
1676
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg, tvb, offset + 8, 2, ENC_BIG_ENDIAN);
1677
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_num, tvb, offset + 10, 2, ENC_BIG_ENDIAN);
1678
0
        proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_length, tvb, offset + 12, 2, ENC_BIG_ENDIAN, &data_length);
1679
1680
0
        offset += 14;
1681
0
        if (tvb_captured_length_remaining(tvb, offset) >= data_length) {
1682
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_data, tvb, offset, data_length, ENC_NA);
1683
0
        } else {
1684
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_cfg_vendor_technica_segment_data, tvb, offset,
1685
0
                                tvb_captured_length_remaining(tvb, offset), ENC_NA);
1686
0
        }
1687
1688
0
        break;
1689
12
    }
1690
12
}
1691
1692
static void
1693
dissect_tecmp_status_bus_vendor_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti_root,
1694
324
                                     uint8_t entry_number, uint8_t device_type, uint8_t vendor_id) {
1695
324
    proto_tree *tree = NULL;
1696
324
    proto_item *ti = NULL;
1697
324
    int offset = 0;
1698
324
    int bytes_remaining = 0;
1699
324
    unsigned tmp = 0;
1700
1701
324
    static int * const error_flags_i2c[] = {
1702
324
    &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_no_ack,
1703
324
    NULL
1704
324
    };
1705
1706
324
    static int * const error_flags_serdes[] = {
1707
324
        &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_crc,
1708
324
        &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_1bit,
1709
324
        &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_2bit,
1710
324
        NULL
1711
324
    };
1712
1713
324
    proto_item_append_text(ti_root, " (%s)", val_to_str(pinfo->pool, vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1714
324
    tree = proto_item_add_subtree(ti_root, ett_tecmp_status_bus_vendor_data);
1715
1716
324
    switch (vendor_id) {
1717
281
    case TECMP_VENDOR_ID_TECHNICA:
1718
281
        bytes_remaining = tvb_captured_length_remaining(tvb, offset);
1719
1720
281
        if (device_type == TECMP_DEVICE_TYPE_CM_ILAS_SNIFFER && entry_number < 5) {
1721
            /* Currently no parameters for this format but might be specified in a later specification. */
1722
281
        } else if ((device_type == TECMP_DEVICE_TYPE_CM_ILAS_SNIFFER && entry_number == 5) || device_type == TECMP_DEVICE_TYPE_CM_10BASE_T1S) {
1723
0
            static int * const vendor_data_flags_10BASE_T1S[] = {
1724
0
                &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_en,
1725
0
                &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beac_rcvd,
1726
0
                NULL
1727
0
            };
1728
1729
0
            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);
1730
0
            offset += 1;
1731
1732
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res0, tvb, offset, 1, ENC_NA);
1733
0
            offset += 1;
1734
1735
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_beacon_counter, tvb, offset, 4, ENC_BIG_ENDIAN);
1736
0
            offset += 4;
1737
1738
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_quality, tvb, offset, 1, ENC_NA);
1739
0
            offset += 1;
1740
1741
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res1, tvb, offset, 1, ENC_NA);
1742
0
            offset += 1;
1743
1744
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_res2, tvb, offset, 2, ENC_BIG_ENDIAN);
1745
0
            offset += 2;
1746
1747
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
1748
0
            offset += 2;
1749
1750
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
1751
0
            offset += 2;
1752
1753
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symb_dtct_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
1754
0
            offset += 2;
1755
1756
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symb_miss_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
1757
0
            offset += 2;
1758
1759
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_plca_symb_empty_cnt, tvb, offset, 2, ENC_BIG_ENDIAN);
1760
281
        } else if (device_type == TECMP_DEVICE_TYPE_CM_SERDES_GMSL23 ) {
1761
0
            switch ((entry_number - 1) % 7) {
1762
0
            case 0:
1763
0
            case 1:
1764
                /* 0, 1: I2C */
1765
0
                proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_bus_vendor_technica_serdes_err, ett_tecmp_status_bus_vendor_data_bus_errors, error_flags_i2c, ENC_NA);
1766
0
                offset += 1;
1767
1768
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1769
                // offset += 1;
1770
0
                break;
1771
1772
0
            case 2:
1773
                /* 2: GPIO */
1774
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1775
0
                offset += 1;
1776
1777
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1778
                // offset += 1;
1779
0
                break;
1780
1781
0
            default:
1782
                /* 3, 4, 5, 6: SerDes streams */
1783
0
                proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_bus_vendor_technica_serdes_err, ett_tecmp_status_bus_vendor_data_bus_errors, error_flags_serdes, ENC_NA);
1784
0
                offset += 1;
1785
1786
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1787
                // offset += 1;
1788
0
            }
1789
281
        } else if (device_type == TECMP_DEVICE_TYPE_CM_SERDES_ASAML) {
1790
0
            switch ((entry_number - 1)) {
1791
0
            case 0:
1792
0
            case 1:
1793
0
            case 2:
1794
0
            case 3:
1795
                /* 0, 1, 2, 3: I2C */
1796
0
                proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_bus_vendor_technica_serdes_err, ett_tecmp_status_bus_vendor_data_bus_errors, error_flags_i2c, ENC_NA);
1797
0
                offset += 1;
1798
1799
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1800
                // offset += 1;
1801
0
                break;
1802
1803
0
            case 4:
1804
                /* 4: GPIO */
1805
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1806
0
                offset += 1;
1807
1808
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1809
                // offset += 1;
1810
0
                break;
1811
1812
0
            case 5:
1813
0
            case 6:
1814
0
            case 7:
1815
0
            case 8:
1816
                /* 5, 6, 7, 8: SerDes streams */
1817
0
                proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_bus_vendor_technica_serdes_err, ett_tecmp_status_bus_vendor_data_bus_errors, error_flags_serdes, ENC_NA);
1818
0
                offset += 1;
1819
1820
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved, tvb, offset, 1, ENC_NA);
1821
                // offset += 1;
1822
0
            }
1823
281
        } else {
1824
281
            if (bytes_remaining >= 1) {
1825
280
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_status, tvb, offset, 1, ENC_NA);
1826
280
                offset += 1;
1827
280
            }
1828
281
            if (bytes_remaining >= 2) {
1829
279
                proto_tree_add_item(tree, hf_tecmp_payload_status_bus_vendor_technica_link_quality, tvb, offset, 1, ENC_NA);
1830
279
                offset += 1;
1831
279
            }
1832
281
            if (bytes_remaining >= 4) {
1833
278
                ti = proto_tree_add_item_ret_uint(tree, hf_tecmp_payload_status_bus_vendor_technica_linkup_time, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
1834
278
                if (tmp == 0) {
1835
34
                    proto_item_append_text(ti, " %s", "(no linkup detected yet)");
1836
244
                } else if (tmp == 0xffff) {
1837
33
                    proto_item_append_text(ti, " %s", "(no linkup detected and timeout occurred)");
1838
33
                }
1839
278
            }
1840
281
        }
1841
281
        break;
1842
324
    }
1843
324
}
1844
1845
static void
1846
10
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) {
1847
10
    proto_tree *tree = NULL;
1848
10
    proto_item *ti = NULL;
1849
10
    int offset = 0;
1850
10
    unsigned tmp = 0;
1851
10
    uint64_t tmp64 = 0;
1852
10
    nstime_t timestamp;
1853
10
    int temperature = 0;
1854
1855
10
    proto_item_append_text(ti_root, " (%s)", val_to_str(pinfo->pool, vendor_id, tecmp_vendor_ids, "(Unknown Vendor: %d)"));
1856
10
    tree = proto_item_add_subtree(ti_root, ett_tecmp_status_dev_vendor_data);
1857
1858
10
    switch (vendor_id) {
1859
0
    case TECMP_VENDOR_ID_TECHNICA:
1860
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_res, tvb, offset, 1, ENC_NA);
1861
0
        offset += 1;
1862
0
        tmp = tvb_get_uint24(tvb, offset, ENC_BIG_ENDIAN);
1863
0
        proto_tree_add_string_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_sw, tvb, offset, 3, NULL,
1864
0
                                     "v%d.%d.%d", (tmp&0x00ff0000)>>16, (tmp&0x0000ff00)>>8, tmp&0x000000ff);
1865
0
        offset += 3;
1866
1867
0
        tmp = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1868
0
        proto_tree_add_string_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_hw, tvb, offset, 2, NULL,
1869
0
                                     "v%d.%x", (tmp & 0x0000ff00) >> 8, tmp & 0x000000ff);
1870
0
        offset += 2;
1871
1872
0
        ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level, tvb, offset, 1, ENC_NA);
1873
0
        proto_item_append_text(ti, "%s", "%");
1874
0
        offset += 1;
1875
1876
0
        proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow, tvb, offset, 1, ENC_NA);
1877
0
        offset += 1;
1878
1879
0
        tmp = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1880
0
        proto_tree_add_uint_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_buffer_size, tvb, offset,
1881
0
                                         4, tmp * 128, "%d MB", tmp * 128);
1882
0
        offset += 4;
1883
1884
0
        ti = proto_tree_add_item_ret_uint64(tree, hf_tecmp_payload_status_dev_vendor_technica_lifecycle, tvb, offset, 8, ENC_BIG_ENDIAN, &tmp64);
1885
1886
0
        uint64_t nanos = tmp64 % 1000000000;
1887
0
        uint64_t secs = tmp64 / 1000000000;
1888
0
        uint64_t mins = secs / 60;
1889
0
        secs -= mins * 60;
1890
0
        uint64_t hours = mins / 60;
1891
0
        mins -= hours * 60;
1892
0
        proto_item_append_text(ti, " ns (%d:%02d:%02d.%09d)", (uint32_t)hours, (uint32_t)mins, (uint32_t)secs, (uint32_t)nanos);
1893
1894
0
        if (tmp64 < timestamp_ns) {
1895
0
            timestamp_ns -= tmp64;
1896
0
            timestamp.secs = (time_t)(timestamp_ns / 1000000000);
1897
0
            timestamp.nsecs = (int)(timestamp_ns % 1000000000);
1898
0
            ti = proto_tree_add_time(tree, hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start, tvb, offset, 8, &timestamp);
1899
0
            proto_item_set_generated(ti);
1900
0
        }
1901
0
        offset += 8;
1902
1903
0
        tmp = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1904
1905
0
        double voltage_value = (double)((tmp & 0x0000ff00) >> 8) + (tmp & 0x000000ff) / 100.0;
1906
0
        proto_tree_add_double(tree, hf_tecmp_payload_status_dev_vendor_technica_voltage, tvb, offset, 2, voltage_value);
1907
0
        offset += 2;
1908
1909
0
        if (tvb_captured_length_remaining(tvb, offset) == 1) {
1910
0
            proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature, tvb, offset, 1, ENC_NA);
1911
0
        } else if (tvb_captured_length_remaining(tvb, offset) > 1) {
1912
            /* TECMP 1.5 and later */
1913
0
            temperature = tvb_get_int8(tvb, offset);
1914
0
            if (temperature == VENDOR_TECHNICA_TEMP_NA) {
1915
0
                proto_tree_add_int_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis, tvb, offset, 1, temperature, "%s", "Not Available");
1916
0
            } else {
1917
0
                ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis, tvb, offset, 1, ENC_NA);
1918
0
                if (temperature == VENDOR_TECHNICA_TEMP_MAX) {
1919
0
                    proto_item_append_text(ti, " %s", "or more");
1920
0
                }
1921
0
            }
1922
0
            offset += 1;
1923
1924
0
            temperature = tvb_get_int8(tvb, offset);
1925
0
            if ( temperature == VENDOR_TECHNICA_TEMP_NA) {
1926
0
                proto_tree_add_int_format_value(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon, tvb, offset, 1, temperature, "%s", "Not Available");
1927
0
                offset += 1;
1928
0
            } else {
1929
0
                ti = proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon, tvb, offset, 1, ENC_NA);
1930
0
                if (temperature == VENDOR_TECHNICA_TEMP_MAX) {
1931
0
                    proto_item_append_text(ti, " %s", "or more");
1932
0
                }
1933
0
                offset += 1;
1934
0
            }
1935
1936
0
            if (device_type == TECMP_DEVICE_TYPE_CM_SERDES_GMSL23 || device_type == TECMP_DEVICE_TYPE_CM_SERDES_ASAML) {
1937
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_lifecycle_counter, tvb, offset, 2, ENC_BIG_ENDIAN);
1938
0
                offset += 2;
1939
1940
0
                static int * const error_flags[] = {
1941
0
                    &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port1,
1942
0
                    &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port2,
1943
0
                    &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port3,
1944
0
                    &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port4,
1945
0
                    NULL
1946
0
                };
1947
1948
0
                proto_tree_add_bitmask(tree, tvb, offset, hf_tecmp_payload_status_dev_vendor_technica_error_flags, ett_tecmp_status_dev_vendor_data_error_flags, error_flags, ENC_BIG_ENDIAN);
1949
0
                offset += 2;
1950
1951
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_sfpa_tx_frames, tvb, offset, 4, ENC_BIG_ENDIAN);
1952
0
                offset += 4;
1953
1954
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_sfpb_tx_frames, tvb, offset, 4, ENC_BIG_ENDIAN);
1955
0
                offset += 4;
1956
1957
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_sfpc_tx_frames, tvb, offset, 4, ENC_BIG_ENDIAN);
1958
0
                offset += 4;
1959
1960
0
                proto_tree_add_item(tree, hf_tecmp_payload_status_dev_vendor_technica_sfpd_tx_frames, tvb, offset, 4, ENC_BIG_ENDIAN);
1961
                //offset += 4;
1962
0
            }
1963
0
        }
1964
1965
0
        break;
1966
10
    }
1967
10
}
1968
1969
static const char *
1970
532
default_interface_name(uint8_t device_type, uint32_t entry_number) {
1971
532
    switch (device_type) {
1972
0
    case TECMP_DEVICE_TYPE_CM_LIN_COMBO:
1973
0
        return val_to_str_const(entry_number, tecmp_default_iface_names_lin, "LIN_COMBO_Unknown");
1974
0
        break;
1975
1976
34
    case TECMP_DEVICE_TYPE_CM_CAN_COMBO:
1977
34
        return val_to_str_const(entry_number, tecmp_default_iface_names_can, "CAN_COMBO_Unknown");
1978
0
        break;
1979
1980
0
    case TECMP_DEVICE_TYPE_CM_100_HIGH:
1981
1
    case TECMP_DEVICE_TYPE_CM_100_HIGH_TC10:
1982
1
        return val_to_str_const(entry_number, tecmp_default_iface_names_100_high, "100_HIGH_Unknown");
1983
0
        break;
1984
1985
0
    case TECMP_DEVICE_TYPE_CM_ETH_COMBO:
1986
0
        return val_to_str_const(entry_number, tecmp_default_iface_names_eth_combo, "ETH_COMBO_Unknown");
1987
0
        break;
1988
1989
0
    case TECMP_DEVICE_TYPE_CM_1000_HIGH:
1990
0
        return val_to_str_const(entry_number, tecmp_default_iface_names_1000_high, "1000_HIGH_Unknown");
1991
0
        break;
1992
1993
17
    case TECMP_DEVICE_TYPE_CM_10BASE_T1S:
1994
17
        return val_to_str_const(entry_number, tecmp_default_iface_names_10base_t1s, "10BASE_T1S_Unknown");
1995
0
        break;
1996
1997
0
    case TECMP_DEVICE_TYPE_CM_ILAS_SNIFFER:
1998
0
        return val_to_str_const(entry_number, tecmp_default_iface_names_ilas_sniffer, "ILaS_Sniffer_Unknown");
1999
0
        break;
2000
2001
28
    case TECMP_DEVICE_TYPE_CM_SERDES_GMSL23:
2002
28
        return val_to_str_const(entry_number, tecmp_default_iface_names_serdes_gsml, "SerDes_GSML_Unknown");
2003
0
        break;
2004
2005
0
    case TECMP_DEVICE_TYPE_CM_SERDES_ASAML:
2006
0
        return val_to_str_const(entry_number, tecmp_default_iface_names_serdes_asaml, "SerDes_ASAML_Unknown");
2007
0
        break;
2008
532
    }
2009
2010
452
    return NULL;
2011
532
}
2012
2013
static int
2014
66
dissect_tecmp_control_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t msg_type, unsigned tecmp_msg_type) {
2015
66
    proto_item *root_ti = NULL;
2016
66
    proto_item *ti = NULL;
2017
66
    proto_tree *tecmp_tree = NULL;
2018
66
    uint16_t length = 0;
2019
66
    unsigned offset = offset_orig;
2020
66
    unsigned device_id = 0;
2021
66
    unsigned interface_id = 0;
2022
66
    unsigned ctrl_msg_id = 0;
2023
2024
66
    if (tvb_captured_length_remaining(tvb, offset) >= (16 + 4)) {
2025
32
        length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2026
32
        root_ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2027
32
        proto_item_append_text(root_ti, " Control Message");
2028
32
        tecmp_tree = proto_item_add_subtree(root_ti, ett_tecmp_payload);
2029
2030
32
        offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, msg_type, true, NULL, NULL, NULL);
2031
2032
32
        col_set_str(pinfo->cinfo, COL_INFO, "TECMP Control Message");
2033
2034
32
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_ctrl_msg_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &device_id);
2035
32
        add_device_id_text(ti, (uint16_t)device_id);
2036
32
        ctrl_msg_id = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN);
2037
32
        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(pinfo->pool, ctrl_msg_id));
2038
32
        offset += 4;
2039
2040
32
        proto_item_append_text(root_ti, ", %s", resolve_control_message_id(pinfo->pool, ctrl_msg_id));
2041
32
        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", resolve_control_message_id(pinfo->pool, ctrl_msg_id));
2042
2043
        /* offset includes 16 byte header, while length is only for payload */
2044
32
        int bytes_left = length + (unsigned)16 - (offset - offset_orig);
2045
32
        if (bytes_left > 0) {
2046
15
            int i;
2047
2048
15
            switch (ctrl_msg_id) {
2049
0
            case TECMP_CTRL_MSG_CAN_REPLAY_FILL_LVL:
2050
0
                ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level, tvb, offset, 1, ENC_NA);
2051
0
                proto_item_append_text(ti, "%%");
2052
0
                offset += 1;
2053
2054
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow, tvb, offset, 1, ENC_NA);
2055
0
                offset += 1;
2056
2057
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size, tvb, offset, 1, ENC_NA);
2058
0
                offset += 1;
2059
2060
0
                for (i = 0; i < bytes_left - 3; i++) {
2061
0
                    uint8_t queue_level = tvb_get_uint8(tvb, offset);
2062
0
                    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);
2063
0
                    offset += 1;
2064
0
                }
2065
0
                offset += 1;
2066
2067
0
                break;
2068
2069
0
            case TECMP_CTRL_MSG_FR_POC_STATE:
2070
0
                ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2071
0
                add_interface_id_text_and_name(ti, interface_id, tvb, offset);
2072
0
                offset += 4;
2073
2074
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_flexray_poc_state, tvb, offset, 1, ENC_NA);
2075
0
                offset += 1;
2076
2077
0
                break;
2078
2079
0
            case TECMP_CTRL_MSG_10BASE_T1S:
2080
0
                ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_10baset1s_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2081
0
                add_interface_id_text_and_name(ti, interface_id, tvb, offset);
2082
0
                offset += 4;
2083
2084
0
                static int * const data_flags_10BASE_T1S[] = {
2085
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled,
2086
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received,
2087
0
                    NULL
2088
0
                };
2089
2090
0
                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);
2091
0
                offset += 1;
2092
2093
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved, tvb, offset, 1, ENC_NA);
2094
0
                offset += 1;
2095
2096
0
                static int * const events_10BASE_T1S[] = {
2097
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle,
2098
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_miss,
2099
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detect,
2100
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error,
2101
0
                    &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error,
2102
0
                    NULL
2103
0
                };
2104
2105
0
                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);
2106
0
                offset += 2;
2107
2108
0
                break;
2109
15
            }
2110
2111
15
            if (length + (unsigned)16 - (offset - offset_orig) > 0) {
2112
15
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_ctrl_msg_unparsed_bytes, tvb, offset, length + (unsigned)16 - (offset - offset_orig), ENC_NA);
2113
2114
15
                col_append_str(pinfo->cinfo, COL_INFO, ": ");
2115
15
                col_set_fence(pinfo->cinfo, COL_INFO);
2116
15
                tvbuff_t *sub_tvb = tvb_new_subset_length(tvb, offset, length + (unsigned)16 - (offset - offset_orig));
2117
15
                call_data_dissector(sub_tvb, pinfo, tree);
2118
15
            }
2119
15
        }
2120
32
    }
2121
2122
66
    return offset - offset_orig;
2123
66
}
2124
2125
static int
2126
147
dissect_tecmp_status_device(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t msg_type, unsigned tecmp_msg_type) {
2127
147
    proto_item *ti = NULL;
2128
147
    proto_item *ti_tecmp_payload = NULL;
2129
147
    proto_item *ti_tecmp_vendor_data = NULL;
2130
147
    proto_item *ti_tecmp_bus = NULL;
2131
147
    proto_tree *tecmp_tree = NULL;
2132
147
    proto_tree *tecmp_tree_bus = NULL;
2133
147
    tvbuff_t *sub_tvb = NULL;
2134
147
    uint16_t length = 0;
2135
147
    uint16_t vendor_data_len = 0;
2136
147
    unsigned vendor_id = 0;
2137
147
    unsigned device_type = 0;
2138
147
    unsigned offset = offset_orig;
2139
147
    uint32_t i = 0;
2140
147
    unsigned tmp = 0;
2141
147
    const char *descr;
2142
147
    uint64_t timestamp_ns;
2143
2144
147
    if (tvb_captured_length_remaining(tvb, offset) >= 12) {
2145
127
        length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2146
127
        ti_tecmp_payload = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2147
127
        tecmp_tree = proto_item_add_subtree(ti_tecmp_payload, ett_tecmp_payload);
2148
2149
127
        offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, msg_type, true, NULL, NULL, &timestamp_ns);
2150
2151
127
        proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_vendor_id, tvb, offset, 1, ENC_NA, &vendor_id);
2152
127
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_dev_version, tvb, offset + 1, 1, ENC_NA);
2153
127
        proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_dev_type, tvb, offset + 2, 1, ENC_NA, &device_type);
2154
127
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_res, tvb, offset + 3, 1, ENC_NA);
2155
127
        offset += 4;
2156
2157
127
        proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_length_vendor_data, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2158
127
        vendor_data_len = (uint16_t)tmp;
2159
127
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_status_device_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &tmp);
2160
127
        add_device_id_text(ti, (uint16_t)tmp);
2161
127
        offset += 4;
2162
2163
127
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_sn, tvb, offset, 4, ENC_BIG_ENDIAN);
2164
127
        offset += 4;
2165
2166
127
        switch (tecmp_msg_type) {
2167
31
        case TECMP_MSG_TYPE_STATUS_DEV:
2168
31
            col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Device");
2169
31
            proto_item_append_text(ti_tecmp_payload, " Status Device");
2170
2171
31
            if (vendor_data_len > 0) {
2172
10
                sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
2173
10
                ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_vendor_data, tvb, offset, (int)vendor_data_len, ENC_NA);
2174
2175
10
                dissect_tecmp_status_device_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, (uint8_t)device_type, (uint8_t)vendor_id, timestamp_ns);
2176
10
                offset += vendor_data_len;
2177
10
            }
2178
31
            break;
2179
2180
64
        case TECMP_MSG_TYPE_STATUS_BUS:
2181
64
            col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Bus");
2182
64
            proto_item_append_text(ti_tecmp_payload, " Status Bus");
2183
2184
            /* bytes left - entry header (16 bytes) */
2185
64
            length = length - (uint16_t)(offset - offset_orig - 16);
2186
2187
64
            ti_tecmp_bus = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_bus_data, tvb, offset, length, ENC_NA);
2188
64
            tecmp_tree = proto_item_add_subtree(ti_tecmp_bus, ett_tecmp_status_bus_data);
2189
64
            i = 1; /* we start the numbering of the entries with 1. */
2190
633
            while (length >= (12 + vendor_data_len)) {
2191
569
                ti_tecmp_bus = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_bus_data_entry, tvb, offset, 12 + vendor_data_len, ENC_NA);
2192
569
                proto_item_append_text(ti_tecmp_bus, " %d", i);
2193
569
                tecmp_tree_bus = proto_item_add_subtree(ti_tecmp_bus, ett_tecmp_status_bus_data_entry);
2194
2195
569
                ti = proto_tree_add_item_ret_uint(tecmp_tree_bus, hf_tecmp_payload_status_bus_interface_id, tvb, offset, 4, ENC_BIG_ENDIAN, &tmp);
2196
569
                descr = ht_interface_config_to_string(tmp);
2197
2198
569
                if (descr == NULL) {
2199
532
                    descr = default_interface_name(device_type, i);
2200
532
                }
2201
2202
569
                if (descr != NULL) {
2203
80
                    proto_item_append_text(ti, " (%s)", descr);
2204
80
                    proto_item_append_text(ti_tecmp_bus, ": (Interface ID: 0x%08x, %s)", tmp, descr);
2205
489
                } else {
2206
489
                    proto_item_append_text(ti_tecmp_bus, ": (Interface ID: 0x%08x)", tmp);
2207
489
                }
2208
2209
569
                proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_bus_total, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
2210
569
                proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_bus_errors, tvb, offset + 8, 4, ENC_BIG_ENDIAN);
2211
569
                offset += 12;
2212
2213
569
                if (vendor_data_len > 0) {
2214
324
                    sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
2215
324
                    ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree_bus, hf_tecmp_payload_status_vendor_data,
2216
324
                                                               tvb, offset, (int)vendor_data_len, ENC_NA);
2217
2218
324
                    dissect_tecmp_status_bus_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, i, (uint8_t)device_type, (uint8_t)vendor_id);
2219
324
                    offset += vendor_data_len;
2220
324
                }
2221
2222
569
                i++;
2223
569
                length -= (12 + vendor_data_len);
2224
569
            }
2225
64
            break;
2226
2227
17
        case TECMP_MSG_TYPE_CFG_CM:
2228
17
            col_set_str(pinfo->cinfo, COL_INFO, "TECMP Status Configuration");
2229
17
            proto_item_append_text(ti_tecmp_payload, " Status Configuration");
2230
2231
17
            if (vendor_data_len > 0) {
2232
12
                sub_tvb = tvb_new_subset_length(tvb, offset, (int)vendor_data_len);
2233
12
                ti_tecmp_vendor_data = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_status_vendor_data, tvb,
2234
12
                                                           offset, (int)vendor_data_len, ENC_NA);
2235
2236
12
                dissect_tecmp_status_config_vendor_data(sub_tvb, pinfo, ti_tecmp_vendor_data, (uint8_t)device_type, (uint8_t)vendor_id);
2237
12
                offset += vendor_data_len;
2238
12
            }
2239
17
            break;
2240
2241
0
        default:
2242
0
            proto_item_append_text(ti_tecmp_payload, " Status Device");
2243
127
        }
2244
2245
127
    } else {
2246
20
        return tvb_captured_length_remaining(tvb, offset);
2247
20
    }
2248
2249
59
    return offset - offset_orig;
2250
147
}
2251
2252
static int
2253
3
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) {
2254
3
    tecmp_info_t tecmp_info;
2255
3
    int          dissected_bytes;
2256
2257
3
    tecmp_info.interface_id = interface_id;
2258
3
    tecmp_info.device_id = device_id;
2259
3
    tecmp_info.data_type = data_type;
2260
3
    tecmp_info.msg_type = msg_type;
2261
2262
2263
3
    dissector_handle_t handle = dissector_get_uint_handle(data_subdissector_table, interface_id);
2264
3
    if (handle != NULL) {
2265
0
        dissected_bytes = call_dissector_only(handle, tvb, pinfo, tree, &tecmp_info);
2266
0
        if (dissected_bytes > 0) {
2267
0
            return dissected_bytes;
2268
0
        }
2269
0
    }
2270
2271
3
    if (tecmp_info.data_type == TECMP_DATA_TYPE_RS232_ASCII) {
2272
0
        return call_dissector(text_lines_handle, tvb, pinfo, tree);
2273
3
    } else {
2274
3
        return call_data_dissector(tvb, pinfo, tree);
2275
3
    }
2276
3
}
2277
2278
static void
2279
0
dissect_ethernet_payload(tvbuff_t *sub_tvb, uint32_t offset, uint32_t length, packet_info *pinfo, proto_tree *tree, proto_tree *tecmp_tree) {
2280
2281
0
    tvbuff_t *payload_tvb = tvb_new_subset_length(sub_tvb, offset, length);
2282
2283
0
    int32_t len_saved = pinfo->fd->pkt_len;
2284
0
    pinfo->fd->pkt_len = length;
2285
2286
0
    if (show_ethernet_in_tecmp_tree) {
2287
0
        call_dissector(eth_handle, payload_tvb, pinfo, tecmp_tree);
2288
0
    } else {
2289
0
        call_dissector(eth_handle, payload_tvb, pinfo, tree);
2290
0
    }
2291
2292
0
    pinfo->fd->pkt_len = len_saved;
2293
0
}
2294
2295
static int
2296
dissect_tecmp_log_or_replay_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig,
2297
139
                                   uint16_t data_type, uint8_t tecmp_msg_type, uint16_t device_id) {
2298
139
    proto_item *ti = NULL;
2299
139
    proto_item *ti_tecmp = NULL;
2300
139
    proto_tree *tecmp_tree = NULL;
2301
139
    uint16_t length = 0;
2302
139
    uint32_t length2 = 0;
2303
139
    unsigned offset = offset_orig;
2304
139
    unsigned offset2 = 0;
2305
139
    uint16_t dataflags = 0;
2306
139
    uint32_t tmp = 0;
2307
139
    tvbuff_t *sub_tvb;
2308
139
    tvbuff_t *payload_tvb;
2309
139
    bool first = true;
2310
139
    uint32_t interface_id = 0;
2311
139
    uint64_t timestamp_ns = 0;
2312
2313
139
    double analog_value_scale_factor;
2314
2315
139
    struct can_info can_info;
2316
139
    flexray_info_t fr_info;
2317
139
    lin_info_t lin_info;
2318
2319
139
    static int * const tecmp_payload_id_flags_can_11[] = {
2320
139
        &hf_tecmp_payload_data_id_type,
2321
139
        &hf_tecmp_payload_data_id_11,
2322
139
        NULL
2323
139
    };
2324
2325
139
    static int * const tecmp_payload_id_flags_can_29[] = {
2326
139
        &hf_tecmp_payload_data_id_type,
2327
139
        &hf_tecmp_payload_data_id_29,
2328
139
        NULL
2329
139
    };
2330
2331
139
    static int * const tecmp_payload_id_flags_lin[] = {
2332
139
        &hf_tecmp_payload_data_parity_bits,
2333
139
        &hf_tecmp_payload_data_id_field_6bit,
2334
139
        NULL
2335
139
    };
2336
2337
139
    col_set_str(pinfo->cinfo, COL_INFO, "TECMP Payload: ");
2338
2339
307
    while (tvb_captured_length_remaining(tvb, offset) >= 16) {
2340
2341
257
        if (!tecmp_entry_header_present(tvb, offset)) {
2342
            /* header not valid, we leave */
2343
9
            break;
2344
9
        }
2345
2346
248
        length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2347
248
        ti_tecmp = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2348
248
        proto_item_append_text(ti_tecmp, " (%s)", val_to_str(pinfo->pool, data_type, tecmp_data_type_names, "Unknown (%d)"));
2349
248
        tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload);
2350
2351
248
        offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, first, &dataflags, &interface_id, &timestamp_ns);
2352
2353
248
        first = false;
2354
2355
248
        if (length > 0) {
2356
155
            sub_tvb = tvb_new_subset_length(tvb, offset, (int)length);
2357
155
            offset2 = 0;
2358
2359
155
            switch (data_type) {
2360
13
            case TECMP_DATA_TYPE_LIN:
2361
13
                lin_info.id = tvb_get_uint8(sub_tvb, offset2) & DATA_LIN_ID_MASK;
2362
2363
13
                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);
2364
13
                lin_info.bus_id = ht_interface_config_to_bus_id(interface_id);
2365
13
                ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 1, 1, ENC_NA, &length2);
2366
13
                offset2 += 2;
2367
2368
13
                lin_set_source_and_destination_columns(pinfo, &lin_info);
2369
2370
13
                if (length2 > 0 && tvb_captured_length_remaining(sub_tvb, offset2) < (length2 + 1)) {
2371
8
                    expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
2372
8
                    length2 = MIN(length2, tvb_captured_length_remaining(sub_tvb, offset2 + 1));
2373
8
                }
2374
2375
13
                if (length2 > 0) {
2376
6
                    lin_info.len = tvb_captured_length_remaining(sub_tvb, offset2);
2377
6
                    payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
2378
2379
2380
6
                    dissect_lin_message(payload_tvb, pinfo, tree, &lin_info);
2381
6
                    offset2 += length2;
2382
6
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_checksum_8bit, sub_tvb, offset2, 1, ENC_NA);
2383
6
                }
2384
2385
13
                break;
2386
2387
4
            case TECMP_DATA_TYPE_CAN_DATA:
2388
4
            case TECMP_DATA_TYPE_CAN_FD_DATA:
2389
4
                tmp = tvb_get_uint32(sub_tvb, offset2, ENC_BIG_ENDIAN);
2390
4
                if ((tmp & 0x80000000) == 0x80000000) {
2391
2
                    proto_tree_add_bitmask_with_flags(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_data_id_field_32bit,
2392
2
                        ett_tecmp_payload_data_id, tecmp_payload_id_flags_can_29, ENC_BIG_ENDIAN, BMT_NO_APPEND);
2393
2
                } else {
2394
2
                    proto_tree_add_bitmask_with_flags(tecmp_tree, sub_tvb, offset2, hf_tecmp_payload_data_id_field_32bit,
2395
2
                        ett_tecmp_payload_data_id, tecmp_payload_id_flags_can_11, ENC_BIG_ENDIAN, BMT_NO_APPEND);
2396
2
                }
2397
4
                ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 4, 1, ENC_NA,
2398
4
                                                  &length2);
2399
4
                offset2 += 5;
2400
2401
4
                if (tvb_captured_length_remaining(sub_tvb, offset2) < length2) {
2402
3
                    expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
2403
3
                    length2 = MIN(length2, tvb_captured_length_remaining(sub_tvb, offset2));
2404
3
                }
2405
2406
4
                if (length2 > 0) {
2407
3
                    payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
2408
3
                    offset2 += length2;
2409
2410
3
                    can_info.fd = (data_type == TECMP_DATA_TYPE_CAN_FD_DATA) ? CAN_TYPE_CAN_FD : CAN_TYPE_CAN_CLASSIC;
2411
3
                    can_info.len = length2;
2412
3
                    can_info.bus_id = ht_interface_config_to_bus_id(interface_id);
2413
2414
                    /* luckily TECMP and SocketCAN share the first bit as indicator for 11 vs 29bit Identifiers */
2415
3
                    can_info.id = tmp;
2416
2417
3
                    if (data_type == TECMP_DATA_TYPE_CAN_DATA && (dataflags & DATA_FLAG_CAN_RTR) == DATA_FLAG_CAN_RTR) {
2418
1
                        can_info.id |= CAN_RTR_FLAG;
2419
1
                    }
2420
2421
3
                    if ((dataflags & DATA_FLAG_CAN_ERR) == DATA_FLAG_CAN_ERR) {
2422
1
                        can_info.id |= CAN_ERR_FLAG;
2423
1
                    }
2424
2425
3
                    socketcan_set_source_and_destination_columns(pinfo, &can_info);
2426
2427
3
                    if (!socketcan_call_subdissectors(payload_tvb, pinfo, tree, &can_info, heuristic_first)) {
2428
3
                        dissect_data(payload_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2429
3
                    }
2430
3
                }
2431
2432
                /* new for TECMP 1.6 */
2433
4
                if (data_type == TECMP_DATA_TYPE_CAN_DATA && tvb_captured_length_remaining(sub_tvb, offset2) >= 2) {
2434
1
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc15, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2435
3
                } else if (data_type == TECMP_DATA_TYPE_CAN_FD_DATA && tvb_captured_length_remaining(sub_tvb, offset2) >= 3) {
2436
0
                    if (length2 <= 16) {
2437
0
                        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc17, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2438
0
                    } else {
2439
0
                        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_crc21, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2440
0
                    }
2441
0
                }
2442
4
                break;
2443
2444
0
            case TECMP_DATA_TYPE_FR_DATA:
2445
                /* lets set it based on config */
2446
0
                fr_info.bus_id = ht_interface_config_to_bus_id(interface_id);
2447
2448
                /* we assume "FlexRay Channel A" since we cannot know */
2449
0
                fr_info.ch = 0;
2450
2451
0
                proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_cycle, sub_tvb, offset2, 1, ENC_NA, &tmp);
2452
0
                fr_info.cc = (uint8_t)tmp;
2453
2454
0
                proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_frame_id, sub_tvb, offset2 + 1, 2, ENC_BIG_ENDIAN, &tmp);
2455
0
                fr_info.id = (uint16_t)tmp;
2456
2457
0
                ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_length, sub_tvb, offset2 + 3, 1, ENC_NA, &length2);
2458
0
                offset2 += 4;
2459
2460
0
                flexray_set_source_and_destination_columns(pinfo, &fr_info);
2461
2462
0
                if (tvb_captured_length_remaining(sub_tvb, offset2) < length2) {
2463
0
                    expert_add_info(pinfo, ti, &ei_tecmp_payload_length_mismatch);
2464
0
                    length2 = MAX(0, MIN(length2, tvb_captured_length_remaining(sub_tvb, offset2)));
2465
0
                }
2466
2467
0
                if (length2 > 0) {
2468
0
                    payload_tvb = tvb_new_subset_length(sub_tvb, offset2, length2);
2469
0
                    offset2 += length2;
2470
2471
0
                    if ((dataflags & DATA_FLAG_FR_NF) != 0 || !flexray_call_subdissectors(payload_tvb, pinfo, tree, &fr_info, heuristic_first)) {
2472
0
                        dissect_data(payload_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2473
0
                    }
2474
0
                }
2475
2476
                /* new for TECMP 1.6 */
2477
0
                if (tvb_captured_length_remaining(sub_tvb, offset2) >= 5) {
2478
0
                    uint32_t header_crc = 0;
2479
0
                    ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_data_header_crc, sub_tvb, offset2, 2, ENC_BIG_ENDIAN, &header_crc);
2480
0
                    if (header_crc > DATA_FR_HEADER_CRC_MAX) {
2481
0
                        expert_add_info(pinfo, ti, &ei_tecmp_payload_header_crc_overflow);
2482
0
                    }
2483
0
                    offset2 += 2;
2484
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_frame_crc, sub_tvb, offset2, 3, ENC_BIG_ENDIAN);
2485
0
                }
2486
0
                break;
2487
2488
0
            case TECMP_DATA_TYPE_GPIO:
2489
0
                if (1 <= length) {
2490
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_0, sub_tvb, offset2, 1, ENC_NA);
2491
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_1, sub_tvb, offset2, 1, ENC_NA);
2492
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_2, sub_tvb, offset2, 1, ENC_NA);
2493
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_3, sub_tvb, offset2, 1, ENC_NA);
2494
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_4, sub_tvb, offset2, 1, ENC_NA);
2495
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_5, sub_tvb, offset2, 1, ENC_NA);
2496
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_6, sub_tvb, offset2, 1, ENC_NA);
2497
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_7, sub_tvb, offset2, 1, ENC_NA);
2498
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tvb_get_uint8(sub_tvb, offset2));
2499
0
                    offset2 += 1;
2500
0
                }
2501
2502
0
                if (2 <= length) {
2503
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_8, sub_tvb, offset2, 1, ENC_NA);
2504
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_9, sub_tvb, offset2, 1, ENC_NA);
2505
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_10, sub_tvb, offset2, 1, ENC_NA);
2506
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_11, sub_tvb, offset2, 1, ENC_NA);
2507
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_12, sub_tvb, offset2, 1, ENC_NA);
2508
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_13, sub_tvb, offset2, 1, ENC_NA);
2509
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_14, sub_tvb, offset2, 1, ENC_NA);
2510
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_15, sub_tvb, offset2, 1, ENC_NA);
2511
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tvb_get_uint8(sub_tvb, offset2));
2512
0
                    offset2 += 1;
2513
0
                }
2514
2515
0
                if (3 <= length) {
2516
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_16, sub_tvb, offset2, 1, ENC_NA);
2517
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_17, sub_tvb, offset2, 1, ENC_NA);
2518
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_18, sub_tvb, offset2, 1, ENC_NA);
2519
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_19, sub_tvb, offset2, 1, ENC_NA);
2520
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_20, sub_tvb, offset2, 1, ENC_NA);
2521
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_21, sub_tvb, offset2, 1, ENC_NA);
2522
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_22, sub_tvb, offset2, 1, ENC_NA);
2523
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_23, sub_tvb, offset2, 1, ENC_NA);
2524
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tvb_get_uint8(sub_tvb, offset2));
2525
0
                    offset2 += 1;
2526
0
                }
2527
2528
0
                if (4 <= length) {
2529
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_24, sub_tvb, offset2, 1, ENC_NA);
2530
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_25, sub_tvb, offset2, 1, ENC_NA);
2531
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_26, sub_tvb, offset2, 1, ENC_NA);
2532
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_27, sub_tvb, offset2, 1, ENC_NA);
2533
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_28, sub_tvb, offset2, 1, ENC_NA);
2534
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_29, sub_tvb, offset2, 1, ENC_NA);
2535
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_30, sub_tvb, offset2, 1, ENC_NA);
2536
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_gpio_31, sub_tvb, offset2, 1, ENC_NA);
2537
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tvb_get_uint8(sub_tvb, offset2));
2538
                    // offset2 += 1;
2539
0
                }
2540
0
                break;
2541
2542
0
            case TECMP_DATA_TYPE_ILAS:
2543
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_command, sub_tvb, offset2, 1, ENC_NA);
2544
0
                offset2 += 1;
2545
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_address, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2546
0
                offset2 += 2;
2547
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_decoded_data, sub_tvb, offset2, 3, ENC_NA);
2548
0
                offset2 += 3;
2549
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_raw_sdu, sub_tvb, offset2, 7, ENC_NA);
2550
0
                offset2 += 7;
2551
0
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ilas_raw_crc, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2552
0
                break;
2553
2554
0
            case TECMP_DATA_TYPE_RS232_ASCII:
2555
0
                dissect_data(sub_tvb, pinfo, tree, device_id, tecmp_msg_type, data_type, interface_id);
2556
0
                break;
2557
2558
0
            case TECMP_DATA_TYPE_ANALOG:
2559
0
                ti_tecmp = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_samples, sub_tvb, offset2, length, ENC_NA);
2560
0
                tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload_data);
2561
2562
0
                analog_value_scale_factor = tecmp_payload_analog_scale_factor_values[((dataflags & TECMP_DATAFLAGS_FACTOR_MASK) >> TECMP_DATAFLAGS_FACTOR_SHIFT)];
2563
2564
0
                tmp = offset2 + length;
2565
0
                while (offset2 + 2 <= tmp) {
2566
0
                    double scaled_value;
2567
2568
0
                    if (analog_samples_are_signed_int) {
2569
0
                        scaled_value = analog_value_scale_factor * tvb_get_int16(sub_tvb, offset2, ENC_BIG_ENDIAN);
2570
0
                    } else {
2571
0
                        scaled_value = analog_value_scale_factor * tvb_get_uint16(sub_tvb, offset2, ENC_BIG_ENDIAN);
2572
0
                    }
2573
2574
0
                    switch ((dataflags & TECMP_DATAFLAGS_UNIT_MASK) >> TECMP_DATAFLAGS_UNIT_SHIFT) {
2575
0
                    case 0x0:
2576
0
                        proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_volt, sub_tvb, offset2, 2, scaled_value);
2577
0
                        break;
2578
0
                    case 0x01:
2579
0
                        proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_amp, sub_tvb, offset2, 2, scaled_value);
2580
0
                        break;
2581
0
                    case 0x02:
2582
0
                        proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_watt, sub_tvb, offset2, 2, scaled_value);
2583
0
                        break;
2584
0
                    case 0x03:
2585
0
                        proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_amp_hour, sub_tvb, offset2, 2, scaled_value);
2586
0
                        break;
2587
0
                    case 0x04:
2588
0
                        proto_tree_add_double(tecmp_tree, hf_tecmp_payload_data_analog_value_celsius, sub_tvb, offset2, 2, scaled_value);
2589
0
                        break;
2590
0
                    default:
2591
0
                        if (analog_samples_are_signed_int) {
2592
0
                            ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_analog_value_raw_signed, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2593
0
                        } else {
2594
0
                            ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_analog_value_raw, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2595
0
                        }
2596
0
                        proto_item_append_text(ti, "%s", " (raw)");
2597
0
                    }
2598
0
                    offset2 += 2;
2599
0
                }
2600
0
                break;
2601
2602
8
            case TECMP_DATA_TYPE_ANALOG_ALT:
2603
8
            {
2604
                /* TECMP_DATA_TYPE_ANALOG_ALT is a backport of packet-asam-cmp.c CMP_DATA_MSG_ANALOG */
2605
2606
8
                static int * const analog_alt_flags[] = {
2607
8
                    &hf_tecmp_payload_analog_alt_flag_reserved,
2608
8
                    &hf_tecmp_payload_analog_alt_flag_sample_dt,
2609
8
                    NULL
2610
8
                };
2611
2612
8
                uint64_t flags;
2613
8
                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);
2614
8
                offset2 += 2;
2615
2616
8
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_reserved, sub_tvb, offset2, 1, ENC_NA);
2617
8
                offset2 += 1;
2618
2619
8
                unsigned analog_unit;
2620
8
                proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_analog_alt_unit, sub_tvb, offset2, 1, ENC_NA, &analog_unit);
2621
8
                const char *unit_symbol;
2622
8
                unit_symbol = try_val_to_str(analog_unit, analog_alt_units);
2623
8
                offset2 += 1;
2624
2625
8
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_interval, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2626
8
                offset2 += 4;
2627
2628
8
                float sample_offset;
2629
8
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_offset, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2630
8
                sample_offset = tvb_get_ieee_float(sub_tvb, offset2, ENC_BIG_ENDIAN);
2631
8
                offset2 += 4;
2632
2633
8
                float sample_scalar;
2634
8
                proto_tree_add_item(tecmp_tree, hf_tecmp_payload_analog_alt_sample_scalar, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2635
8
                sample_scalar = tvb_get_ieee_float(sub_tvb, offset2, ENC_BIG_ENDIAN);
2636
8
                offset2 += 4;
2637
2638
8
                ti_tecmp = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_samples, sub_tvb, offset2, length - offset2, ENC_NA);
2639
8
                tecmp_tree = proto_item_add_subtree(ti_tecmp, ett_tecmp_payload_data);
2640
2641
8
                int data_left = length - offset2;
2642
8
                if (data_left > 0) {
2643
2644
8
                    switch (flags & 0x03) {
2645
6
                    case 0: /* INT16 */
2646
144
                        while (data_left >= 2) {
2647
138
                            double sample_value = ((double)tvb_get_int16(sub_tvb, offset2, ENC_BIG_ENDIAN) * sample_scalar + sample_offset);
2648
138
                            ti = proto_tree_add_double(tecmp_tree, hf_tecmp_payload_analog_alt_sample, sub_tvb, offset2, 2, sample_value);
2649
138
                            if (unit_symbol == NULL) {
2650
87
                                proto_item_append_text(ti, " (%.9f)", sample_value);
2651
87
                            } else {
2652
51
                                proto_item_append_text(ti, "%s (%.9f%s)", unit_symbol, sample_value, unit_symbol);
2653
51
                            }
2654
138
                            PROTO_ITEM_SET_GENERATED(ti);
2655
2656
138
                            proto_tree *sample_tree = proto_item_add_subtree(ti, ett_tecmp_payload_analog_alt_sample);
2657
138
                            proto_tree_add_item(sample_tree, hf_tecmp_payload_analog_alt_sample_raw, sub_tvb, offset2, 2, ENC_BIG_ENDIAN);
2658
138
                            PROTO_ITEM_SET_HIDDEN(ti);
2659
2660
138
                            data_left -= 2;
2661
138
                            offset2 += 2;
2662
138
                        }
2663
6
                        break;
2664
1
                    case 1: /* INT32 */
2665
11
                        while (data_left >= 4) {
2666
10
                            double sample_value = ((double)tvb_get_int32(sub_tvb, offset2, ENC_BIG_ENDIAN) * sample_scalar + sample_offset);
2667
10
                            ti = proto_tree_add_double(tecmp_tree, hf_tecmp_payload_analog_alt_sample, sub_tvb, offset2, 4, sample_value);
2668
10
                            if (unit_symbol == NULL) {
2669
9
                                proto_item_append_text(ti, " (%.9f)", sample_value);
2670
9
                            } else {
2671
1
                                proto_item_append_text(ti, "%s (%.9f%s)", unit_symbol, sample_value, unit_symbol);
2672
1
                            }
2673
10
                            PROTO_ITEM_SET_GENERATED(ti);
2674
2675
10
                            proto_tree *sample_tree = proto_item_add_subtree(ti, ett_tecmp_payload_analog_alt_sample);
2676
10
                            ti = proto_tree_add_item(sample_tree, hf_tecmp_payload_analog_alt_sample_raw, sub_tvb, offset2, 4, ENC_BIG_ENDIAN);
2677
10
                            PROTO_ITEM_SET_HIDDEN(ti);
2678
2679
10
                            data_left -= 4;
2680
10
                            offset2 += 4;
2681
10
                        }
2682
1
                        break;
2683
8
                    }
2684
8
                }
2685
8
            }
2686
1
            break;
2687
2688
1
            case TECMP_DATA_TYPE_ETH_RAW:
2689
0
            {
2690
0
                length2 = length;
2691
0
                uint32_t sub_tvb_end = offset2 + length2;
2692
2693
0
                ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_data, sub_tvb, offset2, length2, ENC_NA);
2694
0
                tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload_eth_raw);
2695
2696
0
                uint32_t preamble_length = 0;
2697
0
                while ((preamble_length < length2) && (TECMP_ETH_RAW_PREAMBLE == tvb_get_uint8(sub_tvb, offset2 + preamble_length))) {
2698
0
                    preamble_length += 1;
2699
0
                }
2700
2701
0
                if (preamble_length > 0) {
2702
0
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_preamble, sub_tvb, offset2, preamble_length, ENC_NA);
2703
0
                    offset2 += preamble_length;
2704
2705
0
                    if (offset2 < sub_tvb_end) {
2706
0
                        uint8_t sfd_candidate = tvb_get_uint8(sub_tvb, offset2);
2707
2708
0
                        if (try_val_to_str(sfd_candidate, tecmp_eth_raw_sfd) != NULL) {
2709
0
                            proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_sfd, sub_tvb, offset2, 1, ENC_NA);
2710
0
                            offset2 += 1;
2711
2712
0
                            if (offset2 < sub_tvb_end) {
2713
0
                                ti = proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data_ethernet_raw_eth_frame, sub_tvb, offset2, sub_tvb_end - offset2, ENC_NA);
2714
0
                                if (sfd_candidate == TECMP_ETH_RAW_SFD_ORIG) {
2715
0
                                    tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload_eth_raw_frame);
2716
2717
0
                                    dissect_ethernet_payload(sub_tvb, offset2, sub_tvb_end - offset2, pinfo, tree, tecmp_tree);
2718
0
                                }
2719
0
                            }
2720
0
                        }
2721
0
                    }
2722
0
                }
2723
0
            }
2724
0
            break;
2725
2726
0
            case TECMP_DATA_TYPE_ETH_10BASE_T1S:
2727
0
            case TECMP_DATA_TYPE_ETH:
2728
0
            {
2729
0
                length2 = length;
2730
2731
0
                if (data_type == TECMP_DATA_TYPE_ETH_10BASE_T1S) {
2732
0
                    uint64_t ns = tvb_get_uint64(sub_tvb, offset2, ENC_BIG_ENDIAN);
2733
2734
0
                    nstime_t timestamp;
2735
0
                    timestamp.secs = (time_t)(ns / 1000000000);
2736
0
                    timestamp.nsecs = (int)(ns % 1000000000);
2737
0
                    proto_tree_add_time(tecmp_tree, hf_tecmp_payload_data_beacon_timestamp, sub_tvb, offset2, 8, &timestamp);
2738
0
                    ti = proto_tree_add_uint64(tecmp_tree, hf_tecmp_payload_data_beacon_timestamp_ns, sub_tvb, offset2, 8, ns);
2739
0
                    proto_item_set_hidden(ti);
2740
2741
0
                    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);
2742
0
                    proto_item_set_generated(ti);
2743
0
                    proto_item_set_hidden(ti);
2744
2745
0
                    offset2 += 8;
2746
0
                    length2 -= 8;
2747
0
                }
2748
0
                dissect_ethernet_payload(sub_tvb, offset2, length2, pinfo, tree, tecmp_tree);
2749
0
            }
2750
0
                break;
2751
2752
47
            case TECMP_DATA_TYPE_I2C:
2753
47
            {
2754
47
                col_append_str(pinfo->cinfo, COL_INFO, ":");
2755
2756
47
                uint32_t i2c_tmp;
2757
2758
47
                proto_item *ti_op = NULL;
2759
47
                proto_tree *op_tree;
2760
293
                while (length - offset2 > 0) {
2761
251
                    if (ti_op != NULL) {
2762
204
                        proto_item_set_end(ti_op, sub_tvb, offset2);
2763
204
                    }
2764
2765
251
                    op_tree = proto_tree_add_subtree_format(tecmp_tree, sub_tvb, offset2, -1, ett_tecmp_payload_i2c_operation, &ti_op, "Operation:");
2766
251
                    uint32_t first_address_byte = tvb_get_uint8(sub_tvb, offset2) & 0xFE;
2767
2768
251
                    if ((first_address_byte & 0xF8) != 0xF0) {
2769
                        /* 7bit Addressing */
2770
2771
180
                        uint32_t i2c_addr;
2772
180
                        bool write_read;
2773
180
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_address_7bit, sub_tvb, offset2, 1, ENC_NA, &i2c_addr);
2774
180
                        proto_tree_add_item_ret_boolean(op_tree, hf_tecmp_payload_data_i2c_direction, sub_tvb, offset2, 1, ENC_NA, &write_read);
2775
180
                        offset2 += 1;
2776
2777
180
                        col_append_fstr(pinfo->cinfo, COL_INFO, " %s at 0x%02x (7 Bit): ", write_read ? "Read" : "Write", i2c_addr);
2778
180
                        proto_item_append_text(ti_op, " %s at 0x%02x (7 Bit):", write_read ? " Read" : "Write", i2c_addr);
2779
2780
180
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_control_char, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2781
180
                        offset2 += 1;
2782
180
                        if (i2c_tmp == TECMP_I2C_CONTROL_ACK_REPEATED_START || i2c_tmp == TECMP_I2C_CONTROL_NACK_REPEATED_START) {
2783
3
                            break;
2784
3
                        }
2785
2786
180
                    } else {
2787
                        /* 10bit Addressing */
2788
2789
                        /* Expected sequences for 10bit Addressing (see NXP UM10204):
2790
                           Write: S 1111 0xxW ACK yyyyyyyy ACK ...              for Address xx yyyy yyyy (W = Write, 0)
2791
                           Read:  S 1111 0xxW ACK yyyyyyyy ACK Sr 1111 0xxR ... for Address xx yyyy yyyy (R = Read, 1)
2792
                         */
2793
2794
71
                        uint32_t i2c_addr;
2795
71
                        bool write_read;
2796
71
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_address1, sub_tvb, offset2, 1, ENC_NA, &i2c_addr);
2797
71
                        proto_tree_add_item_ret_boolean(op_tree, hf_tecmp_payload_data_i2c_direction, sub_tvb, offset2, 1, ENC_NA, &write_read);
2798
71
                        offset2 += 1;
2799
2800
71
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_control_char, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2801
71
                        offset2 += 1;
2802
71
                        if (i2c_tmp == TECMP_I2C_CONTROL_ACK_REPEATED_START || i2c_tmp == TECMP_I2C_CONTROL_NACK_REPEATED_START) {
2803
0
                            break;
2804
0
                        }
2805
2806
71
                        uint32_t addr_10bit_addr_byte2;
2807
71
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_address2, sub_tvb, offset2, 1, ENC_NA, &addr_10bit_addr_byte2);
2808
71
                        offset2 += 1;
2809
2810
71
                        proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_control_char, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2811
71
                        offset2 += 1;
2812
2813
71
                        if (i2c_tmp == TECMP_I2C_CONTROL_NACK_REPEATED_START) {
2814
1
                            break;
2815
70
                        } else if (i2c_tmp == TECMP_I2C_CONTROL_ACK_REPEATED_START) {
2816
                            /* lets peak into the next byte, if we have repeated start with same address and read ... */
2817
13
                            if (tvb_get_uint8(sub_tvb, offset2) == (first_address_byte | 0x01)) {
2818
12
                                proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_address1, sub_tvb, offset2, 1, ENC_NA, &i2c_addr);
2819
12
                                proto_tree_add_item_ret_boolean(op_tree, hf_tecmp_payload_data_i2c_direction, sub_tvb, offset2, 1, ENC_NA, &write_read);
2820
12
                                offset2 += 1;
2821
2822
12
                                proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_control_char, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2823
12
                                offset2 += 1;
2824
12
                                if (i2c_tmp == TECMP_I2C_CONTROL_ACK_REPEATED_START || i2c_tmp == TECMP_I2C_CONTROL_NACK_REPEATED_START) {
2825
0
                                    break;
2826
0
                                }
2827
12
                            } else {
2828
                                /* just repeated start in the middle of operation ... */
2829
1
                                break;
2830
1
                            }
2831
13
                        }
2832
2833
69
                        uint32_t i2c_addr_10bit = (first_address_byte & 0x06) << 7 | addr_10bit_addr_byte2;
2834
69
                        uint32_t addr_len = write_read ? 6 : 4;
2835
69
                        proto_tree_add_uint_format_value(op_tree, hf_tecmp_payload_data_i2c_address_10bit, sub_tvb, offset2 - addr_len, addr_len, i2c_addr_10bit, "0x%03x", i2c_addr_10bit);
2836
69
                        col_append_fstr(pinfo->cinfo, COL_INFO, " %s at 0x%03x (10 Bit): ", write_read ? "Read" : "Write", i2c_addr_10bit);
2837
69
                        proto_item_append_text(ti_op, " %s at 0x%03x (10 Bit):", write_read ? " Read" : "Write", i2c_addr_10bit);
2838
69
                    }
2839
2840
246
                    unsigned count = length - offset2;
2841
246
                    if (count % 2 != 0) {
2842
                        /* lets remove a padding byte */
2843
135
                        count -= 1;
2844
135
                    }
2845
2846
                    /* and now the payload */
2847
8.69k
                    for (unsigned i = 0; i < count; i++) {
2848
8.65k
                        if ((i % 2 == 0)) {
2849
4.33k
                            proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_data_byte, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2850
4.33k
                            offset2 += 1;
2851
2852
4.33k
                            col_append_fstr(pinfo->cinfo, COL_INFO, "0x%02x ", i2c_tmp);
2853
4.33k
                            proto_item_append_text(ti_op, " 0x%02x", i2c_tmp);
2854
4.33k
                        } else {
2855
4.31k
                            proto_tree_add_item_ret_uint(op_tree, hf_tecmp_payload_data_i2c_control_char, sub_tvb, offset2, 1, ENC_NA, &i2c_tmp);
2856
4.31k
                            offset2 += 1;
2857
2858
4.31k
                            if (i2c_tmp == TECMP_I2C_CONTROL_ACK_REPEATED_START || i2c_tmp == TECMP_I2C_CONTROL_NACK_REPEATED_START) {
2859
203
                                proto_item_set_end(ti_op, sub_tvb, offset2);
2860
203
                                break;
2861
203
                            }
2862
4.31k
                        }
2863
8.65k
                    }
2864
246
                }
2865
47
                proto_item_set_end(ti_op, sub_tvb, offset2);
2866
47
            }
2867
47
                break;
2868
2869
83
            default:
2870
83
            {
2871
83
                tecmp_info_t tecmp_info;
2872
83
                tecmp_info.interface_id = interface_id;
2873
83
                tecmp_info.device_id = device_id;
2874
83
                tecmp_info.data_type = data_type;
2875
83
                tecmp_info.data_flags = tvb_get_uint16(tvb, offset - 2, ENC_BIG_ENDIAN);
2876
83
                tecmp_info.msg_type = tecmp_msg_type;
2877
2878
83
                dissector_handle_t handle = dissector_get_uint_handle(data_type_subdissector_table, data_type);
2879
83
                if (handle != NULL) {
2880
0
                    call_dissector_only(handle, sub_tvb, pinfo, tecmp_tree, &tecmp_info);
2881
83
                } else {
2882
83
                    proto_tree_add_item(tecmp_tree, hf_tecmp_payload_data, sub_tvb, 0, length, ENC_NA);
2883
83
                }
2884
83
            }
2885
155
            }
2886
2887
75
            offset += length;
2888
75
        }
2889
248
    }
2890
2891
59
    return offset - offset_orig;
2892
139
}
2893
2894
static int
2895
3
dissect_tecmp_counter_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t data_type, unsigned tecmp_msg_type) {
2896
3
    proto_item *ti = NULL;
2897
3
    proto_tree *tecmp_tree = NULL;
2898
3
    uint16_t length = 0;
2899
3
    unsigned offset = offset_orig;
2900
3
    unsigned tmp = 0;
2901
2902
3
    if (tvb_captured_length_remaining(tvb, offset) >= (16 + 8)) {
2903
2
        length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2904
2
        ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2905
2
        proto_item_append_text(ti, " Counter Event");
2906
2
        tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload);
2907
2908
2
        offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, true, NULL, NULL, NULL);
2909
2910
2
        col_set_str(pinfo->cinfo, COL_INFO, "TECMP Counter Event");
2911
2912
2
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_counter_event_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2913
2
        add_device_id_text(ti, (uint16_t)tmp);
2914
2
        offset += 2;
2915
2916
2
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_counter_event_interface_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2917
2
        add_interface_id_text_and_name(ti, tmp, tvb, offset);
2918
2
        offset += 2;
2919
2920
2
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_counter_event_counter_last, tvb, offset, 2, ENC_BIG_ENDIAN);
2921
2
        offset += 2;
2922
2923
2
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_counter_event_counter_cur, tvb, offset, 2, ENC_BIG_ENDIAN);
2924
2
        offset += 2;
2925
2
    }
2926
2927
3
    return offset - offset_orig;
2928
3
}
2929
2930
static int
2931
2
dissect_tecmp_timesync_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset_orig, uint16_t data_type, unsigned tecmp_msg_type) {
2932
2
    proto_item *ti = NULL;
2933
2
    proto_tree *tecmp_tree = NULL;
2934
2
    uint16_t length = 0;
2935
2
    unsigned offset = offset_orig;
2936
2
    unsigned tmp = 0;
2937
2938
2
    if (tvb_captured_length_remaining(tvb, offset) >= (16 + 8)) {
2939
2
        length = tvb_get_uint16(tvb, offset + 12, ENC_BIG_ENDIAN);
2940
2
        ti = proto_tree_add_item(tree, proto_tecmp_payload, tvb, offset, (int)length + 16, ENC_NA);
2941
2
        proto_item_append_text(ti, " TimeSync Event");
2942
2
        tecmp_tree = proto_item_add_subtree(ti, ett_tecmp_payload);
2943
2944
2
        offset += dissect_tecmp_entry_header(tvb, pinfo, tecmp_tree, offset, tecmp_msg_type, data_type, true, NULL, NULL, NULL);
2945
2946
2
        col_set_str(pinfo->cinfo, COL_INFO, "TECMP TimeSync Event");
2947
2948
2
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_timesync_event_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2949
2
        add_device_id_text(ti, (uint16_t)tmp);
2950
2
        offset += 2;
2951
2952
2
        ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_payload_timesync_event_interface_id, tvb, offset, 2, ENC_BIG_ENDIAN, &tmp);
2953
2
        add_interface_id_text_and_name(ti, tmp, tvb, offset);
2954
2
        offset += 2;
2955
2956
2
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
2957
2
        offset += 2;
2958
2959
2
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_async, tvb, offset, 1, ENC_NA);
2960
2
        offset += 1;
2961
2962
2
        proto_tree_add_item(tecmp_tree, hf_tecmp_payload_timesync_event_time_delta, tvb, offset, 1, ENC_NA);
2963
2
        offset += 1;
2964
2
    }
2965
2966
2
    return offset - offset_orig;
2967
2
}
2968
2969
static int
2970
695
dissect_tecmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
2971
695
    proto_item *ti = NULL;
2972
695
    proto_item *ti_root = NULL;
2973
695
    proto_tree *tecmp_tree = NULL;
2974
695
    unsigned offset = 0;
2975
695
    unsigned tecmp_type = 0;
2976
695
    unsigned data_type = 0;
2977
695
    unsigned device_id = 0;
2978
2979
695
    static int * const tecmp_flags[] = {
2980
695
        &hf_tecmp_flags_eos,
2981
695
        &hf_tecmp_flags_sos,
2982
695
        &hf_tecmp_flags_spy,
2983
695
        &hf_tecmp_flags_multi_frame,
2984
695
        &hf_tecmp_flags_dev_overflow,
2985
695
        NULL
2986
695
    };
2987
2988
    /* ASAM CMP is the successor of TECMP and uses the same EtherType.
2989
     *
2990
     * How to detect what the message is:
2991
     * The first byte in TECMP 1.7 and later is always 0.
2992
     * The first byte in TECMP 1.6 and older allowed 0xff for user-defined IDs.
2993
     * The first byte in ASAM CMP is defined as version and is required to be > 0.
2994
     * If the first byte is not 0, we pass it be ASAM CMP.
2995
     * For backward compatibility: If 0xff allow as TECMP.
2996
     */
2997
695
    if ( (detect_asam_cmp && asam_cmp_handle != 0 && tvb_get_uint8(tvb, offset) != 0) &&
2998
298
         (!detect_asam_cmp_ignore_user_defined || tvb_get_uint8(tvb, offset) != 0xff) ) {
2999
283
        return call_dissector_with_data(asam_cmp_handle, tvb, pinfo, tree, data);
3000
283
    }
3001
3002
412
    col_clear(pinfo->cinfo, COL_INFO);
3003
412
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "TECMP");
3004
412
    ti_root = proto_tree_add_item(tree, proto_tecmp, tvb, 0, -1, ENC_NA);
3005
412
    tecmp_tree = proto_item_add_subtree(ti_root, ett_tecmp);
3006
3007
412
    if (!proto_field_is_referenced(tree, proto_tecmp)) {
3008
5
        tecmp_tree = NULL;
3009
5
    }
3010
3011
412
    ti = proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_device_id, tvb, offset, 2, ENC_BIG_ENDIAN, &device_id);
3012
412
    add_device_id_text(ti, (uint16_t)device_id);
3013
412
    offset += 2;
3014
3015
412
    proto_tree_add_item(tecmp_tree, hf_tecmp_counter, tvb, offset, 2, ENC_BIG_ENDIAN);
3016
412
    offset += 2;
3017
3018
412
    proto_tree_add_item(tecmp_tree, hf_tecmp_version, tvb, offset, 1, ENC_NA);
3019
412
    offset += 1;
3020
3021
412
    proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_msgtype, tvb, offset, 1, ENC_NA, &tecmp_type);
3022
412
    offset += 1;
3023
3024
412
    proto_tree_add_item_ret_uint(tecmp_tree, hf_tecmp_data_type, tvb, offset, 2, ENC_BIG_ENDIAN, &data_type);
3025
412
    offset += 2;
3026
3027
412
    proto_tree_add_item(tecmp_tree, hf_tecmp_res, tvb, offset, 2, ENC_BIG_ENDIAN);
3028
412
    offset += 2;
3029
3030
412
    proto_tree_add_bitmask(tecmp_tree, tvb, offset, hf_tecmp_flags, ett_tecmp_flags, tecmp_flags,
3031
412
                           ENC_BIG_ENDIAN);
3032
412
    offset += 2;
3033
3034
412
    switch (tecmp_type) {
3035
66
    case TECMP_MSG_TYPE_CTRL_MSG:
3036
66
        offset += dissect_tecmp_control_msg(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
3037
66
        break;
3038
3039
88
    case TECMP_MSG_TYPE_STATUS_BUS:
3040
110
    case TECMP_MSG_TYPE_CFG_CM:
3041
147
    case TECMP_MSG_TYPE_STATUS_DEV:
3042
147
        offset += dissect_tecmp_status_device(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
3043
147
        break;
3044
3045
91
    case TECMP_MSG_TYPE_LOG_STREAM:
3046
139
    case TECMP_MSG_TYPE_REPLAY_DATA:
3047
139
        offset += dissect_tecmp_log_or_replay_stream(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type, (uint16_t)device_id);
3048
139
        break;
3049
3050
3
    case TECMP_MSG_TYPE_COUNTER_EVENT:
3051
3
        offset += dissect_tecmp_counter_event(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
3052
3
        break;
3053
3054
2
    case TECMP_MSG_TYPE_TIMESYNC_EVENT:
3055
2
        offset += dissect_tecmp_timesync_event(tvb, pinfo, tree, offset, (uint16_t)data_type, (uint8_t)tecmp_type);
3056
2
        break;
3057
3058
412
    }
3059
3060
246
    proto_item_set_end(ti_root, tvb, offset);
3061
246
    return offset;
3062
412
}
3063
3064
void
3065
14
proto_register_tecmp_payload(void) {
3066
14
    expert_module_t *expert_module_tecmp_payload;
3067
3068
14
    static hf_register_info hf[] = {
3069
14
        { &hf_tecmp_payload_interface_id,                                   { "Interface ID", "tecmp.payload.interface_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3070
14
        { &hf_tecmp_payload_interface_name,                                 { "Interface Name", "tecmp.payload.interface_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3071
14
        { &hf_tecmp_payload_timestamp,                                      { "Timestamp", "tecmp.payload.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
3072
14
        { &hf_tecmp_payload_timestamp_async,                                { "Timestamp Synchronisation Status", "tecmp.payload.timestamp_synch_status", FT_BOOLEAN, 8, TFS(&tfs_tecmp_payload_timestamp_async_type), 0x80, NULL, HFILL } },
3073
14
        { &hf_tecmp_payload_timestamp_res,                                  { "Timestamp Synchronisation reserved", "tecmp.payload.timestamp_reserved", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL } },
3074
14
        { &hf_tecmp_payload_timestamp_ns,                                   { "Timestamp ns", "tecmp.payload.timestamp_ns", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3075
3076
14
        { &hf_tecmp_payload_length,                                         { "Length", "tecmp.payload.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3077
14
        { &hf_tecmp_payload_data,                                           { "Data", "tecmp.payload.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3078
14
        { &hf_tecmp_payload_samples,                                        { "Samples", "tecmp.payload.samples", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3079
3080
14
        { &hf_tecmp_payload_data_ethernet_raw_data,                         { "Raw Data", "tecmp.payload.ethernet_raw.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3081
14
        { &hf_tecmp_payload_data_ethernet_raw_preamble,                     { "Preamble", "tecmp.payload.ethernet_raw.preamble", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3082
14
        { &hf_tecmp_payload_data_ethernet_raw_sfd,                          { "SFD", "tecmp.payload.ethernet_raw.sfd", FT_UINT8, BASE_HEX, VALS(tecmp_eth_raw_sfd), 0x0, NULL, HFILL } },
3083
14
        { &hf_tecmp_payload_data_ethernet_raw_eth_frame,                    { "Ethernet Frame", "tecmp.payload.ethernet_raw.ethernet_frame", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3084
3085
14
        { &hf_tecmp_payload_data_beacon_timestamp,                          { "Beacon Timestamp", "tecmp.payload.beacon_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
3086
14
        { &hf_tecmp_payload_data_beacon_timestamp_ns,                       { "Beacon Timestamp ns", "tecmp.payload.beacon_timestamp_ns", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3087
14
        { &hf_tecmp_payload_data_beacon_to_timestamp_ns,                    { "Beacon to Timestamp ns", "tecmp.payload.beacon_to_timestamp_ns", FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3088
14
        { &hf_tecmp_payload_data_id_field_8bit,                             { "ID", "tecmp.payload.data.lin_id_with_parity", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
3089
14
        { &hf_tecmp_payload_data_id_field_6bit,                             { "LIN ID", "tecmp.payload.data.lin_id", FT_UINT8, BASE_HEX_DEC, NULL, DATA_LIN_ID_MASK, NULL, HFILL } },
3090
14
        { &hf_tecmp_payload_data_parity_bits,                               { "Parity Bits", "tecmp.payload.data.lin_parity_bits", FT_UINT8, BASE_HEX_DEC, NULL, 0xc0, NULL, HFILL } },
3091
14
        { &hf_tecmp_payload_data_checksum_8bit,                             { "Checksum", "tecmp.payload.data.checksum", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3092
3093
14
        { &hf_tecmp_payload_data_id_field_32bit,                            { "ID Field", "tecmp.payload.data.can_id_field", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
3094
14
        { &hf_tecmp_payload_data_id_type,                                   { "CAN ID Type", "tecmp.payload.data.can_id_type", FT_BOOLEAN, 32, TFS(&tfs_tecmp_payload_data_id_type), 0x80000000, NULL, HFILL } },
3095
14
        { &hf_tecmp_payload_data_id_11,                                     { "ID (11bit)", "tecmp.payload.data.can_id_11", FT_UINT32, BASE_HEX_DEC, NULL, 0x000007FF, NULL, HFILL } },
3096
14
        { &hf_tecmp_payload_data_id_29,                                     { "ID (29bit)", "tecmp.payload.data.can_id_29", FT_UINT32, BASE_HEX_DEC, NULL, 0x1FFFFFFF, NULL, HFILL } },
3097
14
        { &hf_tecmp_payload_data_crc15,                                     { "CRC15", "tecmp.payload.data.crc15", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3098
14
        { &hf_tecmp_payload_data_crc17,                                     { "CRC17", "tecmp.payload.data.crc17", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3099
14
        { &hf_tecmp_payload_data_crc21,                                     { "CRC21", "tecmp.payload.data.crc21", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3100
14
        { &hf_tecmp_payload_data_cycle,                                     { "Cycle", "tecmp.payload.data.cycle", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
3101
14
        { &hf_tecmp_payload_data_frame_id,                                  { "Frame ID", "tecmp.payload.data.frame_id", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
3102
14
        { &hf_tecmp_payload_data_header_crc,                                { "Header CRC", "tecmp.payload.data.header_crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3103
14
        { &hf_tecmp_payload_data_frame_crc,                                 { "Frame CRC", "tecmp.payload.data.frame_crc", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3104
3105
14
        { &hf_tecmp_payload_data_length,                                    { "Payload Length", "tecmp.payload.data.payload_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3106
3107
14
        { &hf_tecmp_payload_data_flags,                                     { "Data Flags", "tecmp.payload.data_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3108
14
        { &hf_tecmp_payload_data_flags_crc,                                 { "CRC Error", "tecmp.payload.data_flags.crc_error", FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL } },
3109
14
        { &hf_tecmp_payload_data_flags_checksum,                            { "Checksum Error", "tecmp.payload.data_flags.checksum_error", FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL } },
3110
14
        { &hf_tecmp_payload_data_flags_tx,                                  { "TX (sent by Device)", "tecmp.payload.data_flags.tx", FT_BOOLEAN, 16, NULL, 0x4000, NULL, HFILL } },
3111
14
        { &hf_tecmp_payload_data_flags_overflow,                            { "Overflow (lost data)", "tecmp.payload.data_flags.Overflow", FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL } },
3112
3113
3114
        /* Control Message */
3115
14
        { &hf_tecmp_payload_ctrl_msg_device_id,                             { "Device ID", "tecmp.payload.ctrl_msg.device_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3116
14
        { &hf_tecmp_payload_ctrl_msg_id,                                    { "Control Message ID", "tecmp.payload.ctrl_msg.id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3117
14
        { &hf_tecmp_payload_ctrl_msg_unparsed_bytes,                        { "Unparsed Bytes", "tecmp.payload.ctrl_msg.unparsed", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3118
3119
        /* Control Message: CAN Replay Fill Level */
3120
14
        { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_fill_level,      { "Fill Level RAM", "tecmp.payload.ctrl_msg.can_replay_fill_level.fill_level_ram", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3121
14
        { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_buffer_overflow, { "Buffer Overflow RAM", "tecmp.payload.ctrl_msg.can_replay_fill_level.buffer_overflow_ram", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3122
14
        { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_size,      { "Queue Size", "tecmp.payload.ctrl_msg.can_replay_fill_level.queue_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3123
14
        { &hf_tecmp_payload_ctrl_msg_can_replay_fill_level_queue_length,    { "Queue Fill Level", "tecmp.payload.ctrl_msg.can_replay_fill_level.queue_fill_level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3124
3125
        /* Control Message: FlexRay POC State */
3126
14
        { &hf_tecmp_payload_ctrl_msg_flexray_poc_interface_id,              { "Interface ID", "tecmp.payload.ctrl_msg.flexray_poc.interface_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3127
14
        { &hf_tecmp_payload_ctrl_msg_flexray_poc_state,                     { "Protocol Operation Control State", "tecmp.payload.ctrl_msg.flexray_poc.state",FT_UINT8, BASE_DEC, VALS(tecmp_ctrl_msg_fr_poc_state), 0x0, NULL, HFILL } },
3128
3129
        /* Control Message: 10BASE-T1S */
3130
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_interface_id,                { "Interface ID", "tecmp.payload.ctrl_msg.10baset1s.interface_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3131
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags,                   { "Flags", "tecmp.payload.ctrl_msg.10baset1s.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3132
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_beacons_received,  { "Beacons Received", "tecmp.payload.ctrl_msg.10baset1s.flags.beacons_received", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL } },
3133
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_flags_plca_enabled,      { "PLCA Enabled", "tecmp.payload.ctrl_msg.10baset1s.flags.plca_enabled", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, NULL, HFILL } },
3134
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_reserved,                { "Reserved", "tecmp.payload.ctrl_msg.10baset1s.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3135
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events,                  { "Events/Errors", "tecmp.payload.ctrl_msg.10baset1s.events", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3136
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_5b_decode_error,  { "5B Decode Error", "tecmp.payload.ctrl_msg.10baset1s.events.5b_decode_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001, NULL, HFILL } },
3137
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_eos_delim_error,  { "End of Stream Delimiter Error", "tecmp.payload.ctrl_msg.10baset1s.events.end_of_stream_delimiter_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002, NULL, HFILL } },
3138
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_detect, { "PLCA Symbols Detected", "tecmp.payload.ctrl_msg.10baset1s.events.plca_symbols_detected", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004, NULL, HFILL } },
3139
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_symb_miss,   { "PLCA Symbols Missing", "tecmp.payload.ctrl_msg.10baset1s.events.plca_symbols_missing", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008, NULL, HFILL } },
3140
14
        { &hf_tecmp_payload_ctrl_msg_10baset1s_10m_events_plca_empty_cycle, { "PLCA Empty Cycle", "tecmp.payload.ctrl_msg.10baset1s.events.plca_empty_cycle", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0010, NULL, HFILL } },
3141
3142
        /* Status Device / Status Bus / Status Configuration */
3143
14
        { &hf_tecmp_payload_status_vendor_id,                               { "Vendor ID", "tecmp.payload.status.vendor_id", FT_UINT8, BASE_HEX, VALS(tecmp_vendor_ids), 0x0, NULL, HFILL } },
3144
14
        { &hf_tecmp_payload_status_dev_version,                             { "Device Version", "tecmp.payload.status.device_version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3145
14
        { &hf_tecmp_payload_status_dev_type,                                { "Device Type", "tecmp.payload.status.device_type", FT_UINT8, BASE_HEX, VALS(tecmp_device_types), 0x0, NULL, HFILL } },
3146
14
        { &hf_tecmp_payload_status_res,                                     { "Reserved", "tecmp.payload.status.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3147
14
        { &hf_tecmp_payload_status_length_vendor_data,                      { "Length of Vendor Data", "tecmp.payload.status.vdata_len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3148
14
        { &hf_tecmp_payload_status_device_id,                               { "Device ID", "tecmp.payload.status.device_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3149
14
        { &hf_tecmp_payload_status_sn,                                      { "Serial Number", "tecmp.payload.status.sn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3150
14
        { &hf_tecmp_payload_status_vendor_data,                             { "Vendor Data", "tecmp.payload.status.vendor_data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3151
14
        { &hf_tecmp_payload_status_bus_data,                                { "Bus Data", "tecmp.payload.status.bus_data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3152
14
        { &hf_tecmp_payload_status_bus_data_entry,                          { "Bus Data Entry", "tecmp.payload.status.bus_data_entry", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3153
14
        { &hf_tecmp_payload_status_bus_interface_id,                        { "Interface ID", "tecmp.payload.status.bus.interface_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3154
14
        { &hf_tecmp_payload_status_bus_total,                               { "Messages Total", "tecmp.payload.status.bus.total", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3155
14
        { &hf_tecmp_payload_status_bus_errors,                              { "Errors Total", "tecmp.payload.status.bus.errors", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3156
3157
3158
        /* Status Device Vendor Data */
3159
14
        { &hf_tecmp_payload_status_dev_vendor_technica_res,                 { "Reserved", "tecmp.payload.status_dev.vendor_technica.res", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3160
14
        { &hf_tecmp_payload_status_dev_vendor_technica_sw,                  { "Software Version", "tecmp.payload.status_dev.vendor_technica.sw_version", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3161
14
        { &hf_tecmp_payload_status_dev_vendor_technica_hw,                  { "Hardware Version", "tecmp.payload.status_dev.vendor_technica.hw_version", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3162
14
        { &hf_tecmp_payload_status_dev_vendor_technica_buffer_fill_level,   { "Buffer Fill Level", "tecmp.payload.status_dev.vendor_technica.buffer_fill_level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3163
14
        { &hf_tecmp_payload_status_dev_vendor_technica_buffer_overflow,     { "Buffer Overflow", "tecmp.payload.status_dev.vendor_technica.buffer_overflow", FT_BOOLEAN, BASE_NONE, TFS(&tfs_tecmp_technica_bufferoverflow), 0x0, NULL, HFILL } },
3164
14
        { &hf_tecmp_payload_status_dev_vendor_technica_buffer_size,         { "Buffer Size", "tecmp.payload.status_dev.vendor_technica.buffer_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3165
14
        { &hf_tecmp_payload_status_dev_vendor_technica_lifecycle,           { "Lifecycle", "tecmp.payload.status_dev.vendor_technica.lifecycle", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3166
14
        { &hf_tecmp_payload_status_dev_vendor_technica_lifecycle_start,     { "Lifecycle Start", "tecmp.payload.status_dev.vendor_technica.lifecycle.start", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
3167
14
        { &hf_tecmp_payload_status_dev_vendor_technica_voltage,             { "Voltage", "tecmp.payload.status_dev.vendor_technica.voltage", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL } },
3168
14
        { &hf_tecmp_payload_status_dev_vendor_technica_temperature,         { "Temperature", "tecmp.payload.status_dev.vendor_technica.temperature", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL } },
3169
14
        { &hf_tecmp_payload_status_dev_vendor_technica_temperature_chassis, { "Temperature Chassis", "tecmp.payload.status_dev.vendor_technica.temperature_chassis", FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL } },
3170
14
        { &hf_tecmp_payload_status_dev_vendor_technica_temperature_silicon, { "Temperature Silicon", "tecmp.payload.status_dev.vendor_technica.temperature_silicon", FT_INT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL } },
3171
14
        { &hf_tecmp_payload_status_dev_vendor_technica_lifecycle_counter,   { "Lifecycle Counter [hours]", "tecmp.payload.status_dev.vendor_technica.lifecycle_counter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3172
14
        { &hf_tecmp_payload_status_dev_vendor_technica_error_flags,         { "Error Flags", "tecmp.payload.status_dev.vendor_technica.error_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3173
14
        { &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port1,   { "Port 1 Initialization Error", "tecmp.payload.status_dev.vendor_technica.error_flags.port1_init_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0001, NULL, HFILL } },
3174
14
        { &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port2,   { "Port 2 Initialization Error", "tecmp.payload.status_dev.vendor_technica.error_flags.port2_init_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0002, NULL, HFILL } },
3175
14
        { &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port3,   { "Port 3 Initialization Error", "tecmp.payload.status_dev.vendor_technica.error_flags.port3_init_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0004, NULL, HFILL } },
3176
14
        { &hf_tecmp_payload_status_dev_vendor_technica_error_flags_port4,   { "Port 4 Initialization Error", "tecmp.payload.status_dev.vendor_technica.error_flags.port4_init_error", FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x0008, NULL, HFILL } },
3177
14
        { &hf_tecmp_payload_status_dev_vendor_technica_sfpa_tx_frames,      { "SFP+ A TX Frames", "tecmp.payload.status_dev.vendor_technica.sfpa_tx_frames", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3178
14
        { &hf_tecmp_payload_status_dev_vendor_technica_sfpb_tx_frames,      { "SFP+ B TX Frames", "tecmp.payload.status_dev.vendor_technica.sfpb_tx_frames", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3179
14
        { &hf_tecmp_payload_status_dev_vendor_technica_sfpc_tx_frames,      { "SFP+ C TX Frames", "tecmp.payload.status_dev.vendor_technica.sfpc_tx_frames", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3180
14
        { &hf_tecmp_payload_status_dev_vendor_technica_sfpd_tx_frames,      { "SFP+ D TX Frames", "tecmp.payload.status_dev.vendor_technica.sfpd_tx_frames", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3181
3182
        /* Status Bus Vendor Data */
3183
14
        { &hf_tecmp_payload_status_bus_vendor_technica_link_status,         { "Link Status", "tecmp.payload.status.bus.vendor_technica.link_status", FT_UINT8, BASE_DEC, VALS(tecmp_bus_status_link_status), 0x0, NULL, HFILL } },
3184
14
        { &hf_tecmp_payload_status_bus_vendor_technica_link_quality,        { "Link Quality", "tecmp.payload.status.bus.vendor_technica.link_quality", FT_UINT8, BASE_DEC, VALS(tecmp_bus_status_link_quality), 0x0, NULL, HFILL } },
3185
14
        { &hf_tecmp_payload_status_bus_vendor_technica_linkup_time,         { "Linkup Time", "tecmp.payload.status.bus.vendor_technica.linkup_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3186
3187
14
        { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags,           { "Flags", "tecmp.payload.status.bus.vendor_technica.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3188
14
        { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_beac_rcvd, { "Beacons Received", "tecmp.payload.status.bus.vendor_technica.flags.beacons_received",FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL } },
3189
14
        { &hf_tecmp_payload_status_bus_vendor_technica_10m_flags_plca_en,   { "PLCA Enabled", "tecmp.payload.status.bus.vendor_technica.flags.plca_enabled", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, NULL, HFILL } },
3190
14
        { &hf_tecmp_payload_status_bus_vendor_technica_res0,                { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_0", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3191
14
        { &hf_tecmp_payload_status_bus_vendor_technica_beacon_counter,      { "Beacon Counter", "tecmp.payload.status.bus.vendor_technica.beacon_counter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3192
14
        { &hf_tecmp_payload_status_bus_vendor_technica_res1,                { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3193
14
        { &hf_tecmp_payload_status_bus_vendor_technica_res2,                { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved_2", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3194
14
        { &hf_tecmp_payload_status_bus_vendor_technica_5b_decode_err_cnt,   { "5B Decode Error Count", "tecmp.payload.status.bus.vendor_technica.5b_decode_err_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3195
14
        { &hf_tecmp_payload_status_bus_vendor_technica_eos_delim_err_cnt,   { "End of Stream Delimiter Error Count", "tecmp.payload.status.bus.vendor_technica.eos_delim_err_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3196
14
        { &hf_tecmp_payload_status_bus_vendor_technica_plca_symb_dtct_cnt,  { "PLCA Symbols Detected Count", "tecmp.payload.status.bus.vendor_technica.plca_symbols_detected_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3197
14
        { &hf_tecmp_payload_status_bus_vendor_technica_plca_symb_miss_cnt,  { "PLCA Symbols Missing Count", "tecmp.payload.status.bus.vendor_technica.plca_symbols_missing_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3198
14
        { &hf_tecmp_payload_status_bus_vendor_technica_plca_symb_empty_cnt, { "PLCA Empty Cycle Count", "tecmp.payload.status.bus.vendor_technica.plca_empty_cycle_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3199
3200
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_err,          { "Bus Error", "tecmp.payload.status.bus.vendor_technica.bus_error",FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3201
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_no_ack,   { "No Ack Error", "tecmp.payload.status.bus.vendor_technica.error.no_ack", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x1, NULL, HFILL } },
3202
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_crc,      { "CRC Error", "tecmp.payload.status.bus.vendor_technica.error.crc_error", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x1, NULL, HFILL } },
3203
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_1bit, { "ECC 1-bit Error", "tecmp.payload.status.bus.vendor_technica.error.ecc_error_1_bit", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x2, NULL, HFILL } },
3204
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_err_ecc_2bit, { "ECC 2-bit Error", "tecmp.payload.status.bus.vendor_technica.error.ecc_error_2_bit", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x4, NULL, HFILL } },
3205
14
        { &hf_tecmp_payload_status_bus_vendor_technica_serdes_reserved,     { "Reserved", "tecmp.payload.status.bus.vendor_technica.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3206
3207
3208
        /* Status Config Vendor Data */
3209
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_version,             { "Version", "tecmp.payload.status.config.vendor_technica.version",FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3210
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_reserved,            { "Reserved", "tecmp.payload.status.config.vendor_technica.res", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3211
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_msg_id,              { "Message ID", "tecmp.payload.status.config.vendor_technica.message_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3212
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_total_length,        { "Total Length", "tecmp.payload.status.config.vendor_technica.total_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3213
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_total_num_seg,       { "Total Number of Segments", "tecmp.payload.status.config.vendor_technica.total_number_segments", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3214
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_segment_num,         { "Segment Number", "tecmp.payload.status.config.vendor_technica.segment_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3215
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_segment_length,      { "Segment Length", "tecmp.payload.status.config.vendor_technica.segment_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3216
14
        { &hf_tecmp_payload_status_cfg_vendor_technica_segment_data,        { "Segment Data", "tecmp.payload.status.config.vendor_technica.segment_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3217
3218
        /* ILaS */
3219
14
        { &hf_tecmp_payload_data_flags_crc_enabled,                         { "CRC Received", "tecmp.payload.data_flags.crc_received", FT_BOOLEAN, 16, TFS(&tfs_tecmp_payload_data_crc_received), 0x0001, NULL, HFILL } },
3220
14
        { &hf_tecmp_payload_data_flags_direction,                           { "Direction", "tecmp.payload.data_flags.direction", FT_BOOLEAN, 16, TFS(&tfs_tecmp_payload_data_direction), 0x0002, NULL, HFILL } },
3221
3222
        /* Ethernet 10BASE-T1S */
3223
14
        { &hf_tecmp_payload_data_flags_phy_event_error,                     { "PHY Event/Error", "tecmp.payload.data_flags.phy_event_error", FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL } },
3224
3225
        /* LIN */
3226
14
        { &hf_tecmp_payload_data_flags_coll,                                { "Collision", "tecmp.payload.data_flags.collision", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL } },
3227
14
        { &hf_tecmp_payload_data_flags_parity,                              { "Parity Error", "tecmp.payload.data_flags.parity_error", FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL } },
3228
14
        { &hf_tecmp_payload_data_flags_no_resp,                             { "No Slave Response", "tecmp.payload.data_flags.no_resp", FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL } },
3229
14
        { &hf_tecmp_payload_data_flags_wup,                                 { "Wake Up Signal", "tecmp.payload.data_flags.wup", FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL } },
3230
14
        { &hf_tecmp_payload_data_flags_short_wup,                           { "Short Wake Up Signal", "tecmp.payload.data_flags.short_wup", FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL } },
3231
14
        { &hf_tecmp_payload_data_flags_sleep,                               { "Sleep Signal", "tecmp.payload.data_flags.sleep", FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL } },
3232
3233
        /* CAN DATA, CAN-FD Data */
3234
14
        { &hf_tecmp_payload_data_flags_ack,                                 { "Ack'ed", "tecmp.payload.data_flags.ack", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ACK, NULL, HFILL } },
3235
14
        { &hf_tecmp_payload_data_flags_rtr,                                 { "Remote Frame", "tecmp.payload.data_flags.rtr", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_RTR, NULL, HFILL } },
3236
14
        { &hf_tecmp_payload_data_flags_esi,                                 { "Error Node Active", "tecmp.payload.data_flags.esi", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_ESI, NULL, HFILL } },
3237
14
        { &hf_tecmp_payload_data_flags_ide,                                 { "Extended CAN-ID", "tecmp.payload.data_flags.ext_can_id", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_IDE, NULL, HFILL } },
3238
14
        { &hf_tecmp_payload_data_flags_err,                                 { "Error Frame", "tecmp.payload.data_flags.error_frame", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ERR, NULL, HFILL } },
3239
14
        { &hf_tecmp_payload_data_flags_brs,                                 { "Bit Rate Switch", "tecmp.payload.data_flags.bit_rate_switch", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_BRS, NULL, HFILL } },
3240
3241
14
        { &hf_tecmp_payload_data_flags_can_bit_stuff_err,                   { "Bit Stuff Error", "tecmp.payload.data_flags.bit_stuff_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_BIT_STUFF_ERR, NULL, HFILL } },
3242
14
        { &hf_tecmp_payload_data_flags_can_crc_del_err,                     { "CRC Delimiter Error", "tecmp.payload.data_flags.crc_del_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_CRC_DEL_ERR, NULL, HFILL } },
3243
14
        { &hf_tecmp_payload_data_flags_can_ack_del_err,                     { "Ack Delimiter Error", "tecmp.payload.data_flags.ack_del_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_ACK_DEL_ERR, NULL, HFILL } },
3244
14
        { &hf_tecmp_payload_data_flags_can_eof_err,                         { "End of Frame Field Error", "tecmp.payload.data_flags.eof_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CAN_EOF_ERR, NULL, HFILL } },
3245
14
        { &hf_tecmp_payload_data_flags_canfd_bit_stuff_err,                 { "Bit Stuff Error", "tecmp.payload.data_flags.bit_stuff_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_BIT_STUFF_ERR, NULL, HFILL } },
3246
14
        { &hf_tecmp_payload_data_flags_canfd_crc_del_err,                   { "CRC Delimiter Error", "tecmp.payload.data_flags.crc_del_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_CRC_DEL_ERR, NULL, HFILL } },
3247
14
        { &hf_tecmp_payload_data_flags_canfd_ack_del_err,                   { "Ack Delimiter Error", "tecmp.payload.data_flags.ack_del_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_ACK_DEL_ERR, NULL, HFILL } },
3248
14
        { &hf_tecmp_payload_data_flags_canfd_eof_err,                       { "End of Frame Field Error", "tecmp.payload.data_flags.eof_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_CANFD_EOF_ERR, NULL, HFILL } },
3249
3250
        /* FlexRay Data */
3251
14
        { &hf_tecmp_payload_data_flags_nf,                                  { "Null Frame", "tecmp.payload.data_flags.null_frame", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_NF, NULL, HFILL } },
3252
14
        { &hf_tecmp_payload_data_flags_sf,                                  { "Startup Frame", "tecmp.payload.data_flags.startup_frame", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_ST, NULL, HFILL } },
3253
14
        { &hf_tecmp_payload_data_flags_sync,                                { "Sync Frame", "tecmp.payload.data_flags.sync_frame", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_SYNC, NULL, HFILL } },
3254
14
        { &hf_tecmp_payload_data_flags_wus,                                 { "Wakeup Symbol", "tecmp.payload.data_flags.wakeup_symbol", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_WUS, NULL, HFILL } },
3255
14
        { &hf_tecmp_payload_data_flags_ppi,                                 { "Payload Preamble Indicator", "tecmp.payload.data_flags.payload_preamble_indicator", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_PPI, NULL, HFILL } },
3256
14
        { &hf_tecmp_payload_data_flags_cas,                                 { "Collision Avoidance Symbol", "tecmp.payload.data_flags.collision_avoidance_symbol", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_CAS, NULL, HFILL } },
3257
14
        { &hf_tecmp_payload_data_flags_header_crc_err,                      { "Header CRC Error", "tecmp.payload.data_flags.header_crc_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_HDR_CRC_ERR, NULL, HFILL } },
3258
14
        { &hf_tecmp_payload_data_flags_frame_crc_err,                       { "Frame CRC Error", "tecmp.payload.data_flags.frame_crc_error", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_FRAME_CRC_ERR, NULL, HFILL } },
3259
3260
        /* UART/RS232 ASCII */
3261
14
        { &hf_tecmp_payload_data_flags_dl,                                  { "DL", "tecmp.payload.data_flags.dl", FT_UINT16, BASE_DEC, VALS(tecmp_payload_rs232_uart_dl_types), 0x000e, NULL, HFILL } },
3262
14
        { &hf_tecmp_payload_data_flags_parity_error,                        { "Parity Error", "tecmp.payload.data_flags.parity_error", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL } },
3263
3264
        /* Analog */
3265
14
        { &hf_tecmp_payload_data_flags_sample_time,                         { "Sample Time", "tecmp.payload.data_flags.sample_time", FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_sample_time_types), 0x7800, NULL, HFILL } },
3266
14
        { &hf_tecmp_payload_data_flags_factor,                              { "Factor", "tecmp.payload.data_flags.factor", FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_scale_factor_types), TECMP_DATAFLAGS_FACTOR_MASK, NULL, HFILL } },
3267
14
        { &hf_tecmp_payload_data_flags_unit,                                { "Unit", "tecmp.payload.data_flags.unit", FT_UINT16, BASE_DEC, VALS(tecmp_payload_analog_unit_types), TECMP_DATAFLAGS_UNIT_MASK, NULL, HFILL } },
3268
14
        { &hf_tecmp_payload_data_flags_threshold_u,                         { "Threshold Undershot (deprecated)", "tecmp.payload.data_flags.threshold_undershot", FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL } },
3269
14
        { &hf_tecmp_payload_data_flags_threshold_o,                         { "Threshold Exceeded (deprecated)", "tecmp.payload.data_flags.threshold_exceeded", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL } },
3270
14
        { &hf_tecmp_payload_data_analog_value_raw,                          { "Analog Value", "tecmp.payload.data.analog_value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3271
14
        { &hf_tecmp_payload_data_analog_value_raw_signed,                   { "Analog Value", "tecmp.payload.data.analog_value_signed", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3272
14
        { &hf_tecmp_payload_data_analog_value_volt,                         { "Analog Value", "tecmp.payload.data.analog_value_volt", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL } },
3273
14
        { &hf_tecmp_payload_data_analog_value_amp,                          { "Analog Value", "tecmp.payload.data.analog_value_amp", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_amp), 0x0, NULL, HFILL } },
3274
14
        { &hf_tecmp_payload_data_analog_value_watt,                         { "Analog Value", "tecmp.payload.data.analog_value_watt", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_watt), 0x0, NULL, HFILL } },
3275
14
        { &hf_tecmp_payload_data_analog_value_amp_hour,                     { "Analog Value", "tecmp.payload.data.analog_value_amp_hour", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&tecmp_units_amp_hour), 0x0, NULL, HFILL } },
3276
14
        { &hf_tecmp_payload_data_analog_value_celsius,                      { "Analog Value", "tecmp.payload.data.analog_value_celsius", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL } },
3277
3278
        /* Analog Alt */
3279
14
        { &hf_tecmp_payload_analog_alt_flags,                               { "Flags", "tecmp.payload.analog_alt.flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3280
14
        { &hf_tecmp_payload_analog_alt_flag_sample_dt,                      { "Sample Datatype", "tecmp.payload.analog_alt.flags.sample_dt", FT_UINT16, BASE_HEX, VALS(analog_alt_sample_dt), 0x0003, NULL, HFILL } },
3281
14
        { &hf_tecmp_payload_analog_alt_flag_reserved,                       { "Reserved", "tecmp.payload.analog_alt.flags.reserved", FT_UINT16, BASE_HEX, NULL, 0xfffc, NULL, HFILL } },
3282
3283
14
        { &hf_tecmp_payload_analog_alt_reserved,                            { "Reserved", "tecmp.payload.analog_alt.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3284
14
        { &hf_tecmp_payload_analog_alt_unit,                                { "Unit", "tecmp.payload.analog_alt.unit", FT_UINT8, BASE_HEX, VALS(analog_alt_units), 0x0, NULL, HFILL } },
3285
14
        { &hf_tecmp_payload_analog_alt_sample_interval,                     { "Sample Interval", "tecmp.payload.analog_alt.sample_interval", FT_FLOAT, BASE_NONE | BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL } },
3286
14
        { &hf_tecmp_payload_analog_alt_sample_offset,                       { "Sample Offset", "tecmp.payload.analog_alt.sample_offset", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3287
14
        { &hf_tecmp_payload_analog_alt_sample_scalar,                       { "Sample Scalar", "tecmp.payload.analog_alt.sample_scalar", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3288
14
        { &hf_tecmp_payload_analog_alt_sample_raw,                          { "Sample Raw", "tecmp.payload.analog_alt.sample_raw", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3289
14
        { &hf_tecmp_payload_analog_alt_sample,                              { "Sample", "tecmp.payload.analog_alt.sample", FT_DOUBLE, BASE_EXP, NULL, 0x0, NULL, HFILL } },
3290
3291
        /* GPIO */
3292
14
        { &hf_tecmp_payload_data_gpio_0,                                    { "GPIO 0", "tecmp.payload.gpio_0", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x80, NULL, HFILL } },
3293
14
        { &hf_tecmp_payload_data_gpio_1,                                    { "GPIO 1", "tecmp.payload.gpio_1", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x40, NULL, HFILL } },
3294
14
        { &hf_tecmp_payload_data_gpio_2,                                    { "GPIO 2", "tecmp.payload.gpio_2", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x20, NULL, HFILL } },
3295
14
        { &hf_tecmp_payload_data_gpio_3,                                    { "GPIO 3", "tecmp.payload.gpio_3", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x10, NULL, HFILL } },
3296
14
        { &hf_tecmp_payload_data_gpio_4,                                    { "GPIO 4", "tecmp.payload.gpio_4", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x08, NULL, HFILL } },
3297
14
        { &hf_tecmp_payload_data_gpio_5,                                    { "GPIO 5", "tecmp.payload.gpio_5", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x04, NULL, HFILL } },
3298
14
        { &hf_tecmp_payload_data_gpio_6,                                    { "GPIO 6", "tecmp.payload.gpio_6", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x02, NULL, HFILL } },
3299
14
        { &hf_tecmp_payload_data_gpio_7,                                    { "GPIO 7", "tecmp.payload.gpio_7", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x01, NULL, HFILL } },
3300
3301
14
        { &hf_tecmp_payload_data_gpio_8,                                    { "GPIO 8", "tecmp.payload.gpio_8", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x80, NULL, HFILL } },
3302
14
        { &hf_tecmp_payload_data_gpio_9,                                    { "GPIO 9", "tecmp.payload.gpio_9", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x40, NULL, HFILL } },
3303
14
        { &hf_tecmp_payload_data_gpio_10,                                   { "GPIO 10", "tecmp.payload.gpio_10", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x20, NULL, HFILL } },
3304
14
        { &hf_tecmp_payload_data_gpio_11,                                   { "GPIO 11", "tecmp.payload.gpio_11", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x10, NULL, HFILL } },
3305
14
        { &hf_tecmp_payload_data_gpio_12,                                   { "GPIO 12", "tecmp.payload.gpio_12", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x08, NULL, HFILL } },
3306
14
        { &hf_tecmp_payload_data_gpio_13,                                   { "GPIO 13", "tecmp.payload.gpio_13", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x04, NULL, HFILL } },
3307
14
        { &hf_tecmp_payload_data_gpio_14,                                   { "GPIO 14", "tecmp.payload.gpio_14", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x02, NULL, HFILL } },
3308
14
        { &hf_tecmp_payload_data_gpio_15,                                   { "GPIO 15", "tecmp.payload.gpio_15", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x01, NULL, HFILL } },
3309
3310
14
        { &hf_tecmp_payload_data_gpio_16,                                   { "GPIO 16", "tecmp.payload.gpio_16", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x80, NULL, HFILL } },
3311
14
        { &hf_tecmp_payload_data_gpio_17,                                   { "GPIO 17", "tecmp.payload.gpio_17", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x40, NULL, HFILL } },
3312
14
        { &hf_tecmp_payload_data_gpio_18,                                   { "GPIO 18", "tecmp.payload.gpio_18", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x20, NULL, HFILL } },
3313
14
        { &hf_tecmp_payload_data_gpio_19,                                   { "GPIO 19", "tecmp.payload.gpio_19", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x10, NULL, HFILL } },
3314
14
        { &hf_tecmp_payload_data_gpio_20,                                   { "GPIO 20", "tecmp.payload.gpio_20", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x08, NULL, HFILL } },
3315
14
        { &hf_tecmp_payload_data_gpio_21,                                   { "GPIO 21", "tecmp.payload.gpio_21", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x04, NULL, HFILL } },
3316
14
        { &hf_tecmp_payload_data_gpio_22,                                   { "GPIO 22", "tecmp.payload.gpio_22", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x02, NULL, HFILL } },
3317
14
        { &hf_tecmp_payload_data_gpio_23,                                   { "GPIO 23", "tecmp.payload.gpio_23", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x01, NULL, HFILL } },
3318
3319
14
        { &hf_tecmp_payload_data_gpio_24,                                   { "GPIO 24", "tecmp.payload.gpio_24", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x80, NULL, HFILL } },
3320
14
        { &hf_tecmp_payload_data_gpio_25,                                   { "GPIO 25", "tecmp.payload.gpio_25", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x40, NULL, HFILL } },
3321
14
        { &hf_tecmp_payload_data_gpio_26,                                   { "GPIO 26", "tecmp.payload.gpio_26", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x20, NULL, HFILL } },
3322
14
        { &hf_tecmp_payload_data_gpio_27,                                   { "GPIO 27", "tecmp.payload.gpio_27", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x10, NULL, HFILL } },
3323
14
        { &hf_tecmp_payload_data_gpio_28,                                   { "GPIO 28", "tecmp.payload.gpio_28", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x08, NULL, HFILL } },
3324
14
        { &hf_tecmp_payload_data_gpio_29,                                   { "GPIO 29", "tecmp.payload.gpio_29", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x04, NULL, HFILL } },
3325
14
        { &hf_tecmp_payload_data_gpio_30,                                   { "GPIO 30", "tecmp.payload.gpio_30", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x02, NULL, HFILL } },
3326
14
        { &hf_tecmp_payload_data_gpio_31,                                   { "GPIO 31", "tecmp.payload.gpio_31", FT_BOOLEAN, 8, TFS(&tfs_high_low), 0x01, NULL, HFILL } },
3327
3328
        /* ILaS */
3329
14
        { &hf_tecmp_payload_data_ilas_decoded_command,                      { "Decoded API Command", "tecmp.payload.ilas_decoded_command", FT_UINT8, BASE_DEC, VALS(tecmp_ilas_command_types), 0x0, NULL, HFILL } },
3330
14
        { &hf_tecmp_payload_data_ilas_decoded_address,                      { "Decoded Address", "tecmp.payload.ilas_decoded_address", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3331
14
        { &hf_tecmp_payload_data_ilas_decoded_data,                         { "Decoded Data", "tecmp.payload.ilas_decoded_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3332
14
        { &hf_tecmp_payload_data_ilas_raw_sdu,                              { "Raw SDU", "tecmp.payload.ilas_raw_sdu", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3333
14
        { &hf_tecmp_payload_data_ilas_raw_crc,                              { "Raw CRC", "tecmp.payload.ilas_raw_crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3334
3335
        /* I2C */
3336
14
        { &hf_tecmp_payload_data_i2c_address_7bit,                          { "Address 7bit", "tecmp.payload.i2c_address", FT_UINT8, BASE_HEX_DEC, NULL, 0xfe, NULL, HFILL} },
3337
14
        { &hf_tecmp_payload_data_i2c_address_10bit,                         { "Address 10bit", "tecmp.payload.i2c_address_10bit", FT_UINT16, BASE_HEX_DEC, NULL, 0, NULL, HFILL}},
3338
14
        { &hf_tecmp_payload_data_i2c_address1,                              { "Address (first part of 10bit address)", "tecmp.payload.i2c_10bit_address_first_byte", FT_UINT8, BASE_HEX_DEC, NULL, 0xfe, NULL, HFILL} },
3339
14
        { &hf_tecmp_payload_data_i2c_address2,                              { "Address (last 8bit of 10bit address)", "tecmp.payload.i2c_10bit_address_second_byte", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL} },
3340
14
        { &hf_tecmp_payload_data_i2c_direction,                             { "Direction", "tecmp.payload.i2c_direction", FT_BOOLEAN, 8, TFS(&tfs_tecmp_i2c_direction), 0x01, NULL, HFILL } },
3341
14
        { &hf_tecmp_payload_data_i2c_control_char,                          { "Control Char", "tecmp.payload.i2c_control", FT_UINT8, BASE_HEX_DEC, VALS(tecmp_i2c_control), 0x0, NULL, HFILL} },
3342
14
        { &hf_tecmp_payload_data_i2c_data_byte,                             { "Data Byte", "tecmp.payload.i2c_data", FT_UINT8, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } },
3343
3344
        /* TX Data Flags */
3345
14
        { &hf_tecmp_payload_data_flags_use_crc_value,                       { "Use CRC Value", "tecmp.payload.data_flags.use_crc_value", FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL } },
3346
14
        { &hf_tecmp_payload_data_flags_use_header_crc_value,                { "Use Header CRC Value", "tecmp.payload.data_flags.use_header_crc_value", FT_BOOLEAN, 16, NULL, DATA_FLAG_FR_HDR_CRC_ERR, NULL, HFILL } },
3347
14
        { &hf_tecmp_payload_data_flags_use_checksum_value,                  { "Use Checksum Value", "tecmp.payload.data_flags.use_checksum_value", FT_BOOLEAN, 16, NULL, 0x2000, NULL, HFILL } },
3348
14
        { &hf_tecmp_payload_data_flags_use_parity_bits,                     { "Use Parity Bits", "tecmp.payload.data_flags.use_parity_bits", FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL } },
3349
14
        { &hf_tecmp_payload_data_flags_tx_mode,                             { "TX Mode", "tecmp.payload.data_flags.set_tx_mode", FT_UINT16, BASE_DEC, VALS(tecmp_payload_flexray_tx_mode), 0x0380, NULL, HFILL } },
3350
3351
        /* Counter Event */
3352
14
        { &hf_tecmp_payload_counter_event_device_id,                        { "Device ID", "tecmp.payload.counter_event.device_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3353
14
        { &hf_tecmp_payload_counter_event_interface_id,                     { "Interface ID", "tecmp.payload.counter_event.interface_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3354
14
        { &hf_tecmp_payload_counter_event_counter_last,                     { "Last Counter", "tecmp.payload.counter_event.counter_last", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3355
14
        { &hf_tecmp_payload_counter_event_counter_cur,                      { "Current Counter", "tecmp.payload.counter_event.counter_current", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3356
3357
        /* TimeSync Event */
3358
14
        { &hf_tecmp_payload_timesync_event_device_id,                       { "Device ID", "tecmp.payload.timesync_event.device_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3359
14
        { &hf_tecmp_payload_timesync_event_interface_id,                    { "Interface ID", "tecmp.payload.timesync_event.interface_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3360
14
        { &hf_tecmp_payload_timesync_event_reserved,                        { "Reserved", "tecmp.payload.timesync_event.reserved", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3361
14
        { &hf_tecmp_payload_timesync_event_async,                           { "Async", "tecmp.payload.timesync_event.async", FT_UINT8, BASE_HEX, VALS(tecmp_timesync_event_flags), 0x0, NULL, HFILL } },
3362
14
        { &hf_tecmp_payload_timesync_event_time_delta,                      { "TimeDelta", "tecmp.payload.timesync_event.time_delta", FT_UINT8, BASE_HEX, VALS(tecmp_timesync_event_flags), 0x0, NULL, HFILL } },
3363
14
    };
3364
3365
14
    static int *ett[] = {
3366
14
        &ett_tecmp_payload,
3367
14
        &ett_tecmp_payload_interface_id,
3368
14
        &ett_tecmp_payload_data,
3369
14
        &ett_tecmp_payload_timestamp,
3370
14
        &ett_tecmp_payload_dataflags,
3371
14
        &ett_tecmp_payload_instruction_address,
3372
14
        &ett_tecmp_payload_data_id,
3373
14
        &ett_tecmp_payload_lin_id,
3374
14
        &ett_tecmp_payload_analog_alt_flags,
3375
14
        &ett_tecmp_payload_analog_alt_sample,
3376
14
        &ett_tecmp_payload_eth_raw,
3377
14
        &ett_tecmp_payload_eth_raw_frame,
3378
14
        &ett_tecmp_payload_i2c_operation,
3379
14
        &ett_tecmp_status_dev_vendor_data,
3380
14
        &ett_tecmp_status_dev_vendor_data_error_flags,
3381
14
        &ett_tecmp_status_bus_data,
3382
14
        &ett_tecmp_status_bus_data_entry,
3383
14
        &ett_tecmp_status_bus_vendor_data,
3384
14
        &ett_tecmp_status_bus_vendor_data_flags,
3385
14
        &ett_tecmp_status_bus_vendor_data_bus_errors,
3386
14
        &ett_tecmp_ctrl_message_10baset1s_flags,
3387
14
        &ett_tecmp_ctrl_message_10baset1s_events_errors,
3388
14
    };
3389
3390
14
    static ei_register_info ei[] = {
3391
14
         { &ei_tecmp_payload_length_mismatch, { "tecmp.payload.payload_length_mismatch",
3392
14
           PI_PROTOCOL, PI_WARN, "Payload Length and the length of Payload present in packet do not match!", EXPFILL }},
3393
14
         { &ei_tecmp_payload_header_crc_overflow, { "tecmp.payload.header_crc_overflow",
3394
14
           PI_PROTOCOL, PI_WARN, "Header CRC may only be up to 0x07ff!", EXPFILL }},
3395
14
    };
3396
3397
14
    proto_tecmp_payload = proto_register_protocol("Technically Enhanced Capture Module Protocol Payload", "TECMP Payload", "tecmp.payload");
3398
14
    proto_register_field_array(proto_tecmp_payload, hf, array_length(hf));
3399
14
    proto_register_subtree_array(ett, array_length(ett));
3400
14
    expert_module_tecmp_payload = expert_register_protocol(proto_tecmp_payload);
3401
14
    expert_register_field_array(expert_module_tecmp_payload, ei, array_length(ei));
3402
3403
3404
    /*
3405
     * Dissectors can register themselves in this table.
3406
     */
3407
14
    data_subdissector_table = register_dissector_table(TECMP_PAYLOAD_INTERFACE_ID, "TECMP Interface ID", proto_tecmp_payload, FT_UINT32, BASE_HEX);
3408
14
    data_type_subdissector_table = register_dissector_table(TECMP_DATA_TYPE, "TECMP Data Type", proto_tecmp_payload, FT_UINT16, BASE_HEX);
3409
3410
14
}
3411
3412
void
3413
14
proto_reg_handoff_tecmp_payload(void) {
3414
14
    eth_handle = find_dissector("eth_withfcs");
3415
14
}
3416
3417
void
3418
14
proto_register_tecmp(void) {
3419
14
    module_t *tecmp_module = NULL;
3420
14
    uat_t *tecmp_device_id_uat = NULL;
3421
14
    uat_t *tecmp_interface_id_uat = NULL;
3422
14
    uat_t *tecmp_control_message_id_uat = NULL;
3423
3424
14
    static hf_register_info hf[] = {
3425
14
        { &hf_tecmp_device_id,          { "Device ID", "tecmp.device_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3426
14
        { &hf_tecmp_counter,            { "Counter", "tecmp.counter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3427
14
        { &hf_tecmp_version,            { "Version", "tecmp.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3428
14
        { &hf_tecmp_msgtype,            { "Message Type", "tecmp.message_type", FT_UINT8, BASE_HEX, VALS(tecmp_msg_type_names), 0x0, NULL, HFILL } },
3429
14
        { &hf_tecmp_data_type,          { "Data Type", "tecmp.data_type", FT_UINT16, BASE_HEX, VALS(tecmp_data_type_names), 0x0, NULL, HFILL } },
3430
14
        { &hf_tecmp_res,                { "Reserved", "tecmp.reserved", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3431
14
        { &hf_tecmp_flags,              { "Device Flags", "tecmp.dev_flags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3432
14
        { &hf_tecmp_flags_eos,          { "End of Segment", "tecmp.dev_flags.eos", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL } },
3433
14
        { &hf_tecmp_flags_sos,          { "Start of Segment", "tecmp.dev_flags.sos", FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL } },
3434
14
        { &hf_tecmp_flags_spy,          { "Spy", "tecmp.dev_flags.spy", FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL } },
3435
14
        { &hf_tecmp_flags_multi_frame,  { "Multi Frame", "tecmp.dev_flags.multi_frame", FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL } },
3436
14
        { &hf_tecmp_flags_dev_overflow, { "Device Overflow", "tecmp.dev_flags.device_overflow", FT_BOOLEAN, 16, NULL, 0x8000, NULL, HFILL } },
3437
14
    };
3438
3439
14
    static int *ett[] = {
3440
14
        &ett_tecmp,
3441
14
        &ett_tecmp_flags,
3442
14
    };
3443
3444
    /* UATs for user_data fields */
3445
14
    static uat_field_t tecmp_device_id_uat_fields[] = {
3446
14
        UAT_FLD_HEX(tecmp_devices, id, "ID", "ID of the Device (hex uint16 without leading 0x)"),
3447
14
        UAT_FLD_CSTRING(tecmp_devices, name, "Device Name", "Name of the Device (string)"),
3448
14
        UAT_END_FIELDS
3449
14
    };
3450
3451
14
    static uat_field_t tecmp_interface_id_uat_fields[] = {
3452
14
        UAT_FLD_HEX(tecmp_interfaces, id, "ID", "ID of the Interface (hex uint32 without leading 0x)"),
3453
14
        UAT_FLD_CSTRING(tecmp_interfaces, name, "Interface Name", "Name of the Interface (string)"),
3454
14
        UAT_FLD_HEX(tecmp_interfaces, bus_id, "Bus ID", "Bus ID of the Interface (hex uint16 without leading 0x)"),
3455
14
        UAT_END_FIELDS
3456
14
    };
3457
3458
14
    static uat_field_t tecmp_control_message_id_uat_fields[] = {
3459
14
        UAT_FLD_HEX(tecmp_ctrl_msgs, id, "ID", "ID of the Control Message"),
3460
14
        UAT_FLD_CSTRING(tecmp_ctrl_msgs, name, "Control Message Name", "Name of the Control Message"),
3461
14
        UAT_END_FIELDS
3462
14
    };
3463
3464
14
    proto_tecmp = proto_register_protocol("Technically Enhanced Capture Module Protocol", "TECMP", "tecmp");
3465
14
    proto_register_field_array(proto_tecmp, hf, array_length(hf));
3466
14
    proto_register_subtree_array(ett, array_length(ett));
3467
14
    tecmp_handle = register_dissector("tecmp", dissect_tecmp, proto_tecmp);
3468
14
    tecmp_module = prefs_register_protocol(proto_tecmp, NULL);
3469
3470
    /* UATs */
3471
14
    tecmp_device_id_uat = uat_new("TECMP Devices",
3472
14
        sizeof(generic_one_id_string_t),        /* record size           */
3473
14
        DATAFILE_TECMP_DEVICE_IDS,              /* filename              */
3474
14
        true,                                   /* from profile          */
3475
14
        (void**)&tecmp_devices,                 /* data_ptr              */
3476
14
        &tecmp_devices_num,                     /* numitems_ptr          */
3477
14
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
3478
14
        NULL,                                   /* help                  */
3479
14
        copy_generic_one_id_string_cb,          /* copy callback         */
3480
14
        update_generic_one_identifier_16bit,    /* update callback       */
3481
14
        free_generic_one_id_string_cb,          /* free callback         */
3482
14
        post_update_tecmp_devices_cb,           /* post update callback  */
3483
14
        reset_tecmp_devices_cb,                 /* reset callback        */
3484
14
        tecmp_device_id_uat_fields              /* UAT field definitions */
3485
14
    );
3486
3487
14
    prefs_register_uat_preference(tecmp_module, "_udf_tecmp_devicess", "Devices",
3488
14
        "A table to define names of Devices, which override default names.", tecmp_device_id_uat);
3489
3490
14
    tecmp_interface_id_uat = uat_new("TECMP Interfaces",
3491
14
        sizeof(interface_config_t),             /* record size           */
3492
14
        DATAFILE_TECMP_INTERFACE_IDS,           /* filename              */
3493
14
        true,                                   /* from profile          */
3494
14
        (void**)&tecmp_interfaces,              /* data_ptr              */
3495
14
        &tecmp_interfaces_num,                  /* numitems_ptr          */
3496
14
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
3497
14
        NULL,                                   /* help                  */
3498
14
        copy_interface_config_cb,               /* copy callback         */
3499
14
        update_interface_config,                /* update callback       */
3500
14
        free_interface_config_cb,               /* free callback         */
3501
14
        post_update_tecmp_interfaces_cb,        /* post update callback  */
3502
14
        reset_tecmp_interfaces_cb,              /* reset callback        */
3503
14
        tecmp_interface_id_uat_fields           /* UAT field definitions */
3504
14
    );
3505
3506
14
    prefs_register_uat_preference(tecmp_module, "_udf_tecmp_interfaces", "Interfaces",
3507
14
        "A table to define names of Interfaces.", tecmp_interface_id_uat);
3508
3509
14
    tecmp_control_message_id_uat = uat_new("TECMP Control Messages",
3510
14
        sizeof(generic_one_id_string_t),        /* record size           */
3511
14
        DATAFILE_TECMP_CONTROL_MSG_IDS,         /* filename              */
3512
14
        true,                                   /* from profile          */
3513
14
        (void**)&tecmp_ctrl_msgs,               /* data_ptr              */
3514
14
        &tecmp_ctrl_msg_num,                    /* numitems_ptr          */
3515
14
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
3516
14
        NULL,                                   /* help                  */
3517
14
        copy_generic_one_id_string_cb,          /* copy callback         */
3518
14
        update_generic_one_identifier_16bit,    /* update callback       */
3519
14
        free_generic_one_id_string_cb,          /* free callback         */
3520
14
        post_update_tecmp_control_messages_cb,  /* post update callback  */
3521
14
        NULL,                                   /* reset callback        */
3522
14
        tecmp_control_message_id_uat_fields     /* UAT field definitions */
3523
14
    );
3524
3525
14
    prefs_register_uat_preference(tecmp_module, "_udf_tecmp_control_msg_id", "Control Messages",
3526
14
        "A table to define names of Control Messages.", tecmp_control_message_id_uat);
3527
3528
14
    prefs_register_bool_preference(tecmp_module, "try_heuristic_first",
3529
14
        "Try heuristic sub-dissectors first",
3530
14
        "Try to decode a packet using an heuristic sub-dissector"
3531
14
        " before using a sub-dissector registered to \"decode as\"",
3532
14
        &heuristic_first);
3533
3534
14
    prefs_register_bool_preference(tecmp_module, "analog_samples_sint",
3535
14
        "Decode Analog Samples as Signed Integer",
3536
14
        "Treat the analog samples as signed integers and decode them accordingly.",
3537
14
        &analog_samples_are_signed_int);
3538
3539
14
    prefs_register_bool_preference(tecmp_module, "move_ethernet_in_tecmp_tree",
3540
14
        "More compact Ethernet representation (move into TECMP Tree)",
3541
14
        "Move Ethernet into the TECMP Tree to be more space efficient.",
3542
14
        &show_ethernet_in_tecmp_tree);
3543
3544
14
    prefs_register_bool_preference(tecmp_module, "detect_asam_cmp",
3545
14
        "Detect ASAM CMP",
3546
14
        "Detect ASAM CMP messages and the ASAM CMP dissector handle them.",
3547
14
        &detect_asam_cmp);
3548
3549
14
    prefs_register_bool_preference(tecmp_module, "detect_asam_cmp_ignore_user_defined",
3550
14
        "Ignore Device IDs 0xff00-0xffff for ASAM CMP Detection",
3551
14
        "Ignore Device IDs 0xff00-0xffff (user-defined range) for ASAM CMP Detection",
3552
14
        &detect_asam_cmp_ignore_user_defined);
3553
14
}
3554
3555
void
3556
14
proto_reg_handoff_tecmp(void) {
3557
14
    dissector_add_uint("ethertype", ETHERTYPE_TECMP, tecmp_handle);
3558
3559
14
    text_lines_handle = find_dissector_add_dependency("data-text-lines", proto_tecmp);
3560
14
    asam_cmp_handle = find_dissector("asam-cmp");
3561
14
}
3562
3563
/*
3564
 * Editor modelines
3565
 *
3566
 * Local Variables:
3567
 * c-basic-offset: 4
3568
 * tab-width: 8
3569
 * indent-tabs-mode: nil
3570
 * End:
3571
 *
3572
 * ex: set shiftwidth=4 tabstop=8 expandtab:
3573
 * :indentSize=4:tabSize=8:noTabs=true:
3574
 */