Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-cola.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-cola.c
2
 * Routines for SICK CoLA A and CoLA B protocols
3
 *
4
 * Copyright 2024 Michael Mann
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/prefs.h>
17
#include <epan/expert.h>
18
#include <epan/to_str.h>
19
#include <wsutil/strtoi.h>
20
#include <epan/tfs.h>
21
#include <epan/unit_strings.h>
22
#include <wsutil/utf8_entities.h>
23
#include <epan/dissectors/packet-tcp.h>
24
25
void proto_register_sick_cola(void);
26
void proto_reg_handoff_sick_cola(void);
27
28
static int proto_sick_cola_a;
29
static int proto_sick_cola_b;
30
31
static int hf_sick_cola_b_magic_number;
32
static int hf_sick_cola_b_length;
33
static int hf_sick_cola_b_checksum;
34
static int hf_sick_cola_b_checksum_status;
35
static int hf_sick_cola_command;
36
static int hf_sick_cola_method_name;
37
static int hf_sick_cola_set_access_mode_user_level;
38
static int hf_sick_cola_set_access_mode_password;
39
static int hf_sick_cola_answer_name;
40
static int hf_sick_cola_set_access_mode_change_level;
41
static int hf_sick_cola_set_scan_cfg_scan_frequency;
42
static int hf_sick_cola_set_scan_cfg_num_active_scanners;
43
static int hf_sick_cola_set_scan_cfg_angular_resolution;
44
static int hf_sick_cola_set_scan_cfg_start_angle;
45
static int hf_sick_cola_set_scan_cfg_stop_angle;
46
static int hf_sick_cola_set_scan_cfg_status_code;
47
static int hf_sick_cola_set_scan_cfg_mode;
48
static int hf_sick_cola_read_name;
49
static int hf_sick_cola_write_name;
50
static int hf_sick_cola_mm_alignment_node_layer_activation;
51
static int hf_sick_cola_standby_status_code;
52
static int hf_sick_cola_startmeas_status_code;
53
static int hf_sick_cola_stopmeas_status_code;
54
static int hf_sick_cola_autostartmeas_enable;
55
static int hf_sick_cola_clapplication_mode;
56
static int hf_sick_cola_set_active_app_count;
57
static int hf_sick_cola_set_active_app_id;
58
static int hf_sick_cola_set_active_app_active;
59
static int hf_sick_cola_set_password_user_level;
60
static int hf_sick_cola_set_password_hash;
61
static int hf_sick_cola_set_password_status_code;
62
static int hf_sick_cola_check_password_user_level;
63
static int hf_sick_cola_check_password_hash;
64
static int hf_sick_cola_check_password_status_code;
65
static int hf_sick_cola_lcm_cfg_strategy;
66
static int hf_sick_cola_lcm_cfg_response_time;
67
static int hf_sick_cola_lcm_cfg_threshold_warning;
68
static int hf_sick_cola_lcm_cfg_threshold_error;
69
static int hf_sick_cola_cm_cont_lvlm_availability;
70
static int hf_sick_cola_ee_write_all_status_code;
71
static int hf_sick_cola_run_status_code;
72
static int hf_sick_cola_scan_data_cfg_data_channel;
73
static int hf_sick_cola_scan_data_cfg_remission;
74
static int hf_sick_cola_scan_data_cfg_resolution;
75
static int hf_sick_cola_scan_data_cfg_unit;
76
static int hf_sick_cola_scan_data_cfg_encoder;
77
static int hf_sick_cola_scan_data_cfg_position;
78
static int hf_sick_cola_scan_data_cfg_device_name;
79
static int hf_sick_cola_scan_data_cfg_comment;
80
static int hf_sick_cola_scan_data_cfg_time;
81
static int hf_sick_cola_scan_data_cfg_output_rate;
82
static int hf_sick_cola_change_output_range_status_code;
83
static int hf_sick_cola_change_output_range_angular_resolution;
84
static int hf_sick_cola_change_output_range_start_angle;
85
static int hf_sick_cola_change_output_range_stop;
86
static int hf_sick_cola_output_range_num_sectors;
87
static int hf_sick_cola_output_range_angular_resolution;
88
static int hf_sick_cola_output_range_start_angle;
89
static int hf_sick_cola_output_range_stop;
90
static int hf_sick_cola_event_name;
91
static int hf_sick_cola_scan_data_start_stop;
92
static int hf_sick_cola_scan_data_version;
93
static int hf_sick_cola_scan_data_device_number;
94
static int hf_sick_cola_scan_data_serial_number;
95
static int hf_sick_cola_scan_data_device_status;
96
static int hf_sick_cola_scan_data_telegram_counter;
97
static int hf_sick_cola_scan_data_scan_counter;
98
static int hf_sick_cola_scan_data_time_since_startup;
99
static int hf_sick_cola_scan_data_transmission_time;
100
static int hf_sick_cola_scan_data_di_status;
101
static int hf_sick_cola_scan_data_do_status;
102
static int hf_sick_cola_scan_data_layer_angle;
103
static int hf_sick_cola_scan_data_scan_frequency;
104
static int hf_sick_cola_scan_data_measurement_frequency;
105
static int hf_sick_cola_scan_data_encoder_amount;
106
static int hf_sick_cola_scan_data_encoder_position;
107
static int hf_sick_cola_scan_data_encoder_speed;
108
static int hf_sick_cola_scan_data_num_16bit_channels;
109
static int hf_sick_cola_scan_data_output_channel_content;
110
static int hf_sick_cola_scan_data_output_channel_scale_factor;
111
static int hf_sick_cola_scan_data_output_channel_scale_factor_offset;
112
static int hf_sick_cola_scan_data_output_channel_start_angle;
113
static int hf_sick_cola_scan_data_output_channel_size_single_angular_step;
114
static int hf_sick_cola_scan_data_num_data_points;
115
static int hf_sick_cola_scan_data_16bit_output_channel_data;
116
static int hf_sick_cola_scan_data_num_8bit_channels;
117
static int hf_sick_cola_scan_data_8bit_output_channel_data;
118
static int hf_sick_cola_scan_data_position_present;
119
static int hf_sick_cola_scan_data_position_x;
120
static int hf_sick_cola_scan_data_position_y;
121
static int hf_sick_cola_scan_data_position_z;
122
static int hf_sick_cola_scan_data_rotation_x;
123
static int hf_sick_cola_scan_data_rotation_y;
124
static int hf_sick_cola_scan_data_rotation_z;
125
static int hf_sick_cola_scan_data_rotation_type;
126
static int hf_sick_cola_scan_data_transmit_device_name;
127
static int hf_sick_cola_scan_data_device_name_present;
128
static int hf_sick_cola_scan_data_device_name;
129
static int hf_sick_cola_scan_data_comment_present;
130
static int hf_sick_cola_scan_data_comment;
131
static int hf_sick_cola_scan_data_time_present;
132
static int hf_sick_cola_scan_data_time;
133
static int hf_sick_cola_scan_data_display_event_info;
134
static int hf_sick_cola_scan_data_event_info_type;
135
static int hf_sick_cola_scan_data_event_info_encoder_position;
136
static int hf_sick_cola_scan_data_event_info_encosder_timestamp;
137
static int hf_sick_cola_scan_data_event_info_encoder_angle;
138
static int hf_sick_cola_set_date_time;
139
static int hf_sick_cola_set_date_time_status_code;
140
static int hf_sick_cola_stims_status_code;
141
static int hf_sick_cola_stims_temp_out_of_range;
142
static int hf_sick_cola_stims_time_length;
143
static int hf_sick_cola_stims_time;
144
static int hf_sick_cola_stims_date_length;
145
static int hf_sick_cola_stims_date;
146
static int hf_sick_cola_stims_led1;
147
static int hf_sick_cola_stims_led2;
148
static int hf_sick_cola_stims_led3;
149
static int hf_sick_cola_stims_reserved;
150
static int hf_sick_cola_device_time;
151
static int hf_sick_cola_ntp_tsc_role;
152
static int hf_sick_cola_ntp_interface_data;
153
static int hf_sick_cola_ntp_ipaddress;
154
static int hf_sick_cola_ntp_gmt_timezone_offset;
155
static int hf_sick_cola_ntp_timesync;
156
static int hf_sick_cola_ntp_max_offset_time;
157
static int hf_sick_cola_particle_filter_status;
158
static int hf_sick_cola_particle_filter_threshold;
159
static int hf_sick_cola_mean_filter_status;
160
static int hf_sick_cola_mean_filter_num_scans;
161
static int hf_sick_cola_mean_filter_final_part;
162
static int hf_sick_cola_nto1_filter_status;
163
static int hf_sick_cola_echo_filter_status;
164
static int hf_sick_cola_fog_filter_status;
165
static int hf_sick_cola_fog_filter_enable;
166
static int hf_sick_cola_fog_filter_sensitivity_level;
167
static int hf_sick_cola_digital_nearfield_filter_status;
168
static int hf_sick_cola_digital_nearfield_filter_active_sector_vector;
169
static int hf_sick_cola_encoder_increment_source;
170
static int hf_sick_cola_encoder_setting;
171
static int hf_sick_cola_encoder_resolution;
172
static int hf_sick_cola_encoder_fixed_speed;
173
static int hf_sick_cola_encoder_speed_threshold;
174
static int hf_sick_cola_encoder_speed;
175
static int hf_sick_cola_output_do3_func;
176
static int hf_sick_cola_output_do1_func;
177
static int hf_sick_cola_output_do1_logic;
178
static int hf_sick_cola_output_do2_func;
179
static int hf_sick_cola_output_do2_logic;
180
static int hf_sick_cola_output_sync_mode_data;
181
static int hf_sick_cola_output_sync_phase_data;
182
static int hf_sick_cola_input_do3and4_func;
183
static int hf_sick_cola_input_debounce_time_data;
184
static int hf_sick_cola_set_output_state_number;
185
static int hf_sick_cola_set_output_state_state;
186
static int hf_sick_cola_output_state_start_stop;
187
static int hf_sick_cola_output_state_status_version;
188
static int hf_sick_cola_output_state_status_system_counter;
189
static int hf_sick_cola_output_state_state;
190
static int hf_sick_cola_output_state_count;
191
static int hf_sick_cola_output_state_ext_state;
192
static int hf_sick_cola_output_state_ext_count;
193
static int hf_sick_cola_output_state_time_present;
194
static int hf_sick_cola_output_state_time;
195
static int hf_sick_cola_input_sync_status_data;
196
static int hf_sick_cola_input_signal_frequency;
197
static int hf_sick_cola_set_output_state_status_code;
198
static int hf_sick_cola_b_sopas_command;
199
static int hf_sick_cola_b_sopas_command_data;
200
static int hf_sick_cola_a_stx;
201
static int hf_sick_cola_a_etx;
202
static int hf_sick_cola_a_sopas_command;
203
static int hf_sick_cola_a_sopas_command_data;
204
static int hf_sick_cola_sopas_error_code;
205
206
207
static int ett_sick_cola_a;
208
static int ett_sick_cola_b;
209
static int ett_scan_data_device;
210
static int ett_scan_data_status_info;
211
static int ett_scan_data_frequency;
212
static int ett_scan_data_16bit_output_channels;
213
static int ett_scan_data_16bit_output_channel;
214
static int ett_scan_data_16bit_output_data;
215
static int ett_scan_data_8bit_output_channels;
216
static int ett_scan_data_8bit_output_channel;
217
static int ett_scan_data_8bit_output_data;
218
static int ett_scan_data_position;
219
static int ett_scan_data_time;
220
static int ett_scan_data_event_info;
221
static int ett_output_state_status;
222
static int ett_output_state;
223
static int ett_output_state_x;
224
static int ett_ext_output_state;
225
static int ett_ext_output_state_x;
226
static int ett_output_state_time;
227
228
static expert_field ei_sick_cola_command;
229
static expert_field ei_sick_cola_command_name;
230
static expert_field ei_sick_cola_command_parameter;
231
static expert_field ei_sick_cola_b_checksum;
232
233
//Preferences
234
static uint32_t g_number_of_outputs = 1;
235
236
30
#define SICK_COLA_B_HEADER_SIZE     8
237
2.86k
#define SICK_COLA_B_MAGIC_NUMBER    0x02020202
238
239
2.58k
#define SICK_COLA_A_STX         0x02
240
0
#define SICK_COLA_A_ETX         0x03
241
0
#define SICK_COLA_DELIMITER       0x20    //space character
242
2.79k
#define SICK_COLA_A_MIN_LENGTH      6
243
244
0
#define SICK_COLA_COMMAND_READ      0x73524E20  //sRN
245
0
#define SICK_COLA_COMMAND_WRITE     0x73574E20  //sWN
246
0
#define SICK_COLA_COMMAND_METHOD    0x734D4E20  //sMN
247
0
#define SICK_COLA_COMMAND_EVENT     0x73454E20  //sEN
248
249
0
#define SICK_COLA_COMMAND_SOPAS_BINARY  0x73524900  //sRI
250
0
#define SICK_COLA_COMMAND_SOPAS_ASCII 0x73524920  //sRI
251
252
0
#define SICK_COLA_COMMAND_ANSWER_sRA  0x73524120
253
0
#define SICK_COLA_COMMAND_ANSWER_sWA  0x73574120
254
0
#define SICK_COLA_COMMAND_ANSWER_sAN  0x73414E20
255
0
#define SICK_COLA_COMMAND_ANSWER_sEA  0x73454120
256
0
#define SICK_COLA_COMMAND_ANSWER_sSN  0x73534E20
257
0
#define SICK_COLA_COMMAND_ANSWER_sFA  0x73464120
258
0
#define SICK_COLA_COMMAND_ANSWER_sFA_NULL 0x73464100
259
260
0
#define SICK_COLA_COMMAND_ANSWER_SOPAS_BINARY 0x73524100  //sRA
261
262
263
static const value_string cola_command_vals[] = {
264
  { SICK_COLA_COMMAND_READ,   "Read" },
265
  { SICK_COLA_COMMAND_WRITE,   "Write" },
266
  { SICK_COLA_COMMAND_METHOD,   "Method" },
267
  { SICK_COLA_COMMAND_EVENT,   "Event" },
268
  { SICK_COLA_COMMAND_ANSWER_sRA,   "Answer (sRA)" },
269
  { SICK_COLA_COMMAND_ANSWER_sWA,   "Answer (sWA)" },
270
  { SICK_COLA_COMMAND_ANSWER_sAN,   "Answer (sAN)" },
271
  { SICK_COLA_COMMAND_ANSWER_sEA,   "Answer (sEA)" },
272
  { SICK_COLA_COMMAND_ANSWER_sSN,   "Answer (sSN)" },
273
  { SICK_COLA_COMMAND_ANSWER_sFA,   "Answer (sFA)" },
274
  { SICK_COLA_COMMAND_ANSWER_sFA_NULL,   "Answer (sFA)" },
275
  { SICK_COLA_COMMAND_SOPAS_BINARY,   "SOPAS Specific (Binary)" },
276
  { SICK_COLA_COMMAND_SOPAS_ASCII,   "SOPAS Specific (ASCII)" },
277
  { SICK_COLA_COMMAND_ANSWER_SOPAS_BINARY,   "Answer (SOPAS Binary)" },
278
  { 0, NULL }
279
};
280
281
static const value_string sick_cola_return_vals[] = {
282
  { 0,  "Error" },
283
  { 1,  "Success" },
284
  { 0,  NULL }
285
};
286
287
288
289
static const value_string access_mode_user_level_vals[] = {
290
  { 2,  "Maintenance" },
291
  { 3,  "Authorized client" },
292
  { 4,  "Service" },
293
  { 0xFFFFFFFF, "Invalid number" },
294
  { 0,  NULL }
295
};
296
297
static const value_string set_scan_cfg_status_code_vals[] = {
298
  { 0,  "No Error" },
299
  { 1,  "Frequency error" },
300
  { 2,  "Resolution error" },
301
  { 3,  "Resolution and scan area error" },
302
  { 4,  "Scan area error" },
303
  { 5,  "Other error" },
304
  { 0,  NULL }
305
};
306
307
//values are in ascii
308
static const value_string layer_activation_vals[] = {
309
  { '0',  "All layers" },
310
  { '1',  "Red layer -2,5" },
311
  { '2',  "Blue layer 0" },
312
  { '3',  "Green layer +2,5" },
313
  { '4',  "Yellow layer +5" },
314
  { 0,  NULL }
315
};
316
317
static const value_string start_stop_measure_status_code_vals[] = {
318
  { 0,  "No error" },
319
  { 1,  "Not allowed" },
320
  { 0,  NULL }
321
};
322
323
static const value_string autostartmeas_enable_vals[] = {
324
  { 0,  "OFF" },
325
  { 1,  "ON" },
326
  { 0,  NULL }
327
};
328
329
static const value_string clapplication_mode_vals[] = {
330
  { 0,  "Scan only" },
331
  { 0x11, "Field application" },
332
  { 0,  NULL }
333
};
334
335
static const value_string lcm_cfg_strategy_vals[] = {
336
  { 0,  "Inactive" },
337
  { 1,  "High available" },
338
  { 2,  "Available" },
339
  { 3,  "Sensitive" },
340
  { 4,  "Semi-sensitive" },
341
  { 0,  NULL }
342
};
343
344
static const value_string sick_cola_resolution_vals[] = {
345
  { 0,  "8 bit" },
346
  { 1,  "16 bit" },
347
  { 0, NULL }
348
};
349
350
static const value_string sick_cola_stop_start_vals[] = {
351
  { 0,  "Stop" },
352
  { 1,  "Start" },
353
  { 0, NULL }
354
};
355
356
static const value_string sick_cola_device_status_vals[] = {
357
  { 0,  "Ok" },
358
  { 1,  "Error" },
359
  { 2,  "Pollution Warning" },
360
  { 5,  "Pollution Error" },
361
  { 0, NULL }
362
};
363
364
static const value_string sick_cola_position_present_vals[] = {
365
  { 0,  "No Position Data" },
366
  { 1,  "Position Data" },
367
  { 0, NULL }
368
};
369
370
static const value_string sick_cola_rotation_type_vals[] = {
371
  { 0,  "No Rotation" },
372
  { 1,  "Pitch" },
373
  { 2,  "Roll" },
374
  { 3,  "Free" },
375
  { 0, NULL }
376
};
377
378
static const value_string sick_cola_name_present_vals[] = {
379
  { 0,  "No Name" },
380
  { 1,  "Name" },
381
  { 0, NULL }
382
};
383
384
static const value_string sick_cola_comment_present_vals[] = {
385
  { 0,  "No Comment" },
386
  { 1,  "Comment" },
387
  { 0, NULL }
388
};
389
390
static const value_string sick_cola_time_present_vals[] = {
391
  { 0,  "No Timestamp" },
392
  { 1,  "Timestamp" },
393
  { 0, NULL }
394
};
395
396
static const value_string sick_cola_display_event_info_vals[] = {
397
  { 0,  "No information" },
398
  { 1,  "Transmit Information" },
399
  { 0, NULL }
400
};
401
402
static const value_string stims_status_vals[] = {
403
  { 0,  "Undefined" },
404
  { 1,  "Initialization" },
405
  { 2,  "Configuration" },
406
  { 3,  "Lower case" },
407
  { 4,  "Rotating" },
408
  { 5,  "In preparation" },
409
  { 6,  "Ready" },
410
  { 7,  "Measurement active" },
411
  { 0, NULL }
412
};
413
414
static const value_string sick_cola_led_vals[] = {
415
  { 0,  "Inactive" },
416
  { 1,  "Active" },
417
  { 0, NULL }
418
};
419
420
static const value_string ntp_tsc_role_vals[] = {
421
  { 0,  "None" },
422
  { 1,  "Client" },
423
  { 2,  "Server" },
424
  { 0, NULL }
425
};
426
427
static const value_string ntp_interface_data_vals[] = {
428
  { 0,  "Ethernet" },
429
  { 1,  "CAN" },
430
  { 0, NULL }
431
};
432
433
static const value_string echo_filter_status_vals[] = {
434
  { 0,  "First echo" },
435
  { 1,  "All echos" },
436
  { 2,  "Last echo" },
437
  { 0, NULL }
438
};
439
440
static const value_string fog_filter_status_vals[] = {
441
  { 0,  "Glitch" },
442
  { 1,  "Fog" },
443
  { 0, NULL }
444
};
445
446
static const value_string encoder_increment_source_vals[] = {
447
  { 0,  "Fixed Speed" },
448
  { 1,  "Encoder" },
449
  { 0, NULL }
450
};
451
452
static const value_string encoder_setting_vals[] = {
453
  { 0,  "Off" },
454
  { 1,  "Single increment/INC1" },
455
  { 2,  "Direction recognition (phase)" },
456
  { 3,  "Direction recognition (level)" },
457
  { 0, NULL }
458
};
459
460
static const value_string sick_cola_do3_func_vals[] = {
461
  { 0,  "No function" },
462
  { 1,  "SOPAS command" },
463
  { 2,  "Device Ready" },
464
  { 3,  "Application" },
465
  { 4,  "Application/Device Ready" },
466
  { 5,  "Device Ready/Contamination" },
467
  { 6,  "Contamination" },
468
  { 7,  "Master Synchronisation" },
469
  { 0, NULL }
470
};
471
472
static const value_string sick_cola_do1_func_vals[] = {
473
  { 0,  "No function" },
474
  { 1,  "Command" },
475
  { 2,  "Device Ready" },
476
  { 3,  "Application/Device Ready" },
477
  { 4,  "Sync pulse" },
478
  { 5,  "Sync index" },
479
  { 0, NULL }
480
};
481
482
static const value_string sick_cola_logic_state_vals[] = {
483
  { 0,   "Active High" },
484
  { 1,   "Active Low" },
485
  { 0, NULL }
486
};
487
488
static const value_string sick_cola_do2_func_vals[] = {
489
  { 0,  "No function" },
490
  { 1,  "Command" },
491
  { 2,  "Device Ready" },
492
  { 3,  "Application/Device Ready" },
493
  { 0, NULL }
494
};
495
496
static const value_string sick_cola_sync_mode_data_vals[] = {
497
  { 0,  "No sync" },
498
  { 1,  "Sync by wire" },
499
  { 2,  "Sync by CAN" },
500
  { 0, NULL }
501
};
502
503
static const value_string sick_cola_do3and4_func_vals[] = {
504
  { 0,  "No function" },
505
  { 1,  "Encoder" },
506
  { 2,  "Slave sync" },
507
  { 3,  "Digit Input" },
508
  { 0, NULL }
509
};
510
511
static const value_string sick_cola_sync_status_vals[] = {
512
  { 1,  "None" },
513
  { 2,  "Too slow" },
514
  { 4,  "Good" },
515
  { 8,  "Too fast" },
516
  { 0, NULL }
517
};
518
519
static const value_string sick_cola_sopas_error_vals[] = {
520
  { 0,  "No error" },
521
  { 1,  "Wrong userlevel, access to method not allowed" },
522
  { 2,  "Trying to access a method with an unknown Sopas index" },
523
  { 3,  "Trying to access a variable with an unknown Sopas index" },
524
  { 4,  "Local condition violated" },
525
  { 5,  "Invalid data given for variable (DEPRECATED)" },
526
  { 6,  "An error with unknown reason occurred (DEPRECATED)" },
527
  { 7,  "The communication buffer was too small for the amount of data that should be serialised." },
528
  { 8,  "More data was expected, the allocated buffer could not be filled." },
529
  { 9,  "The variable that shall be serialised has an unknown type." },
530
  { 10, "It is not allowed to write values to this variable." },
531
  { 11, "When using names instead of indices, a command was issued that the nameserver does not understand." },
532
  { 12, "The CoLa protocol specification does not define the given command, command is unknown." },
533
  { 13, "It is not possible to issue more than one command at a time to an SRT device." },
534
  { 14, "An array was accessed over its maximum length." },
535
  { 15, "The event you wanted to register for does not exist, the index is unknown." },
536
  { 16, "The value does not fit into the value field, it is too large." },
537
  { 17, "Character is unknown, probably not alphanumeric." },
538
  { 18, "No operating system message could be created for GET variable" },
539
  { 19, "No operating system message could be created for PUT variable" },
540
  { 20, "Internal error in the firmware" },
541
  { 21, "The Sopas Hubaddress is either too short or too long" },
542
  { 22, "The Sopas Hubaddress is invalid, it can not be decoded (Syntax)" },
543
  { 23, "Too many hubs in the address" },
544
  { 24, "When parsing a HubAddress an expected blank was not found. The HubAddress is not valid." },
545
  { 25, "An asynchronous method call was made although the device was built with 'AsyncMethodsSuppressed'" },
546
  { 26, "Complex Arrays not supported" },
547
548
  { 0, NULL }
549
};
550
551
/* Copied and renamed from proto.c because global value_strings don't work for plugins */
552
static const value_string plugin_proto_checksum_vals[] = {
553
  { PROTO_CHECKSUM_E_BAD,        "Bad"  },
554
  { PROTO_CHECKSUM_E_GOOD,       "Good" },
555
  { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
556
  { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
557
558
  { 0,        NULL }
559
};
560
561
static const unit_name_string sick_cola_units_ticks_mm = { "ticks/mm", NULL };
562
563
11
static uint8_t get_crc8_xor(tvbuff_t *p, uint8_t len, uint8_t offset) {
564
11
  uint8_t FCS = 0x00;
565
11
  uint8_t tmp;
566
567
483
  while (len--) {
568
472
    tmp = tvb_get_uint8(p,offset);
569
472
    FCS ^= tmp;
570
472
    offset++;
571
472
  }
572
573
11
  return FCS;
574
11
}
575
576
static uint8_t*
577
cola_get_ascii_parameter_string(packet_info *pinfo, tvbuff_t *tvb, int offset, int* new_offset)
578
0
{
579
0
  uint8_t* str_parameter;
580
0
  int parameter_end;
581
582
0
  parameter_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
583
0
  if (parameter_end < 0)
584
0
  {
585
0
    *new_offset = -1;
586
0
    return NULL;
587
0
  }
588
589
0
  str_parameter = tvb_get_string_enc(pinfo->pool, tvb, offset, parameter_end - offset, ENC_NA | ENC_ASCII);
590
0
  *new_offset = parameter_end;
591
0
  return str_parameter;
592
0
}
593
594
static bool
595
cola_ascii_add_parameter_U32(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name, uint32_t scale_factor)
596
0
{
597
0
  uint8_t* str_parameter;
598
0
  int parameter_end_offset;
599
0
  unsigned paramU32;
600
601
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
602
0
  if (str_parameter == NULL)
603
0
  {
604
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
605
0
    return false;
606
0
  }
607
608
0
  if (!ws_hexstrtou32(str_parameter, NULL, &paramU32))
609
0
    return false;
610
611
0
  proto_tree_add_uint(tree, hf_parameter, tvb, *offset, parameter_end_offset - *offset, paramU32/scale_factor);
612
613
0
  *offset = parameter_end_offset+1;
614
0
  return true;
615
0
}
616
617
static bool
618
cola_ascii_add_parameter_REAL(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name)
619
0
{
620
0
  uint8_t* str_parameter;
621
0
  int parameter_end_offset;
622
0
  unsigned paramU32;
623
0
  float paramFloat;
624
625
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
626
0
  if (str_parameter == NULL)
627
0
  {
628
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
629
0
    return false;
630
0
  }
631
632
0
  if (!ws_hexstrtou32(str_parameter, NULL, &paramU32))
633
0
    return false;
634
635
0
  memcpy(&paramFloat, &paramU32, 4);
636
0
  proto_tree_add_float(tree, hf_parameter, tvb, *offset, parameter_end_offset - *offset, paramFloat);
637
638
0
  *offset = parameter_end_offset+1;
639
0
  return true;
640
0
}
641
642
static bool
643
cola_ascii_add_parameter_I32(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name, int scale_factor)
644
0
{
645
0
  uint8_t* str_parameter;
646
0
  int parameter_end_offset;
647
0
  unsigned paramU32;
648
649
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
650
0
  if (str_parameter == NULL)
651
0
  {
652
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
653
0
    return false;
654
0
  }
655
656
0
  if (!ws_hexstrtou32(str_parameter, NULL, &paramU32))
657
0
    return false;
658
659
0
  proto_tree_add_int(tree, hf_parameter, tvb, *offset, parameter_end_offset - *offset, ((int32_t)paramU32)/scale_factor);
660
661
0
  *offset = parameter_end_offset+1;
662
0
  return true;
663
0
}
664
665
static bool
666
cola_ascii_add_parameter_I16(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name)
667
0
{
668
0
  uint8_t* str_parameter;
669
0
  int parameter_end_offset;
670
0
  uint16_t paramU16;
671
672
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
673
0
  if (str_parameter == NULL)
674
0
  {
675
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
676
0
    return false;
677
0
  }
678
679
0
  if (!ws_hexstrtou16(str_parameter, NULL, &paramU16))
680
0
    return false;
681
682
0
  proto_tree_add_int(tree, hf_parameter, tvb, *offset, parameter_end_offset - *offset, (int16_t)paramU16);
683
684
0
  *offset = parameter_end_offset+1;
685
0
  return true;
686
0
}
687
static bool
688
cola_ascii_add_parameter_2U8(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name)
689
0
{
690
0
  uint8_t* str_parameter;
691
0
  int parameter_end_offset, start_offset = *offset;
692
0
  uint16_t param1, param2, paramU16;
693
694
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
695
0
  if (str_parameter == NULL)
696
0
  {
697
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
698
0
    return false;
699
0
  }
700
701
0
  if (!ws_hexstrtou16(str_parameter, NULL, &param1))
702
0
    return false;
703
704
0
  *offset = parameter_end_offset+1;
705
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
706
0
  if (str_parameter == NULL)
707
0
  {
708
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
709
0
    return false;
710
0
  }
711
712
0
  if (!ws_hexstrtou16(str_parameter, NULL, &param2))
713
0
    return false;
714
715
0
  paramU16 = ((param1 << 8) & 0xFF00) | (param2 & 0x00FF);
716
717
0
  proto_tree_add_uint(tree, hf_parameter, tvb, *offset, parameter_end_offset - start_offset, paramU16);
718
719
0
  *offset = parameter_end_offset+1;
720
0
  return true;
721
0
}
722
723
static bool
724
cola_ascii_add_parameter_string(proto_tree *tree, int hf_parameter, packet_info *pinfo, tvbuff_t *tvb, int* offset, char* field_name)
725
0
{
726
0
  uint8_t* str_parameter;
727
0
  int parameter_end_offset;
728
729
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, *offset, &parameter_end_offset);
730
0
  if (str_parameter == NULL)
731
0
  {
732
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for %s", field_name);
733
0
    return false;
734
0
  }
735
736
0
  proto_tree_add_string(tree, hf_parameter, tvb, *offset, parameter_end_offset - *offset, str_parameter);
737
738
0
  *offset = parameter_end_offset+1;
739
0
  return true;
740
0
}
741
742
743
static int
744
diplay_timestamp_field(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_field, bool binary)
745
0
{
746
0
  int time_offset = offset;
747
0
  struct tm time_info;
748
0
  time_t time_info_seconds;
749
0
  nstime_t ns_time_info;
750
751
0
  if (binary)
752
0
  {
753
0
    time_info.tm_year = tvb_get_ntohs(tvb, time_offset)-1900;
754
0
    time_offset += 2;
755
0
    time_info.tm_mon = tvb_get_uint8(tvb, time_offset)-1;
756
0
    time_offset += 1;
757
0
    time_info.tm_mday = tvb_get_uint8(tvb, time_offset);
758
0
    time_offset += 1;
759
0
    time_info.tm_hour = tvb_get_uint8(tvb, time_offset);
760
0
    time_offset += 1;
761
0
    time_info.tm_min = tvb_get_uint8(tvb, time_offset);
762
0
    time_offset += 1;
763
0
    time_info.tm_sec = tvb_get_uint8(tvb, time_offset);
764
0
    time_offset += 1;
765
766
0
    time_info_seconds = mktime(&time_info);
767
0
    ns_time_info.secs = time_info_seconds;
768
0
    ns_time_info.nsecs = tvb_get_ntohl(tvb, time_offset)*1000;
769
0
    proto_tree_add_time(tree, hf_field, tvb, offset, 11, &ns_time_info);
770
0
    offset += 11;
771
0
  }
772
773
0
  return offset;
774
0
}
775
776
static int
777
dissect_sick_cola_read(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary _U_)
778
0
{
779
0
  int offset = 0;
780
0
  const uint8_t* read_name;
781
782
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_read_name, tvb, offset, -1, ENC_NA | ENC_ASCII, pinfo->pool, &read_name);
783
0
  offset = tvb_reported_length(tvb);
784
785
0
  return offset;
786
0
}
787
788
static int
789
dissect_sick_cola_write(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
790
0
{
791
0
  int offset = 0;
792
0
  const uint8_t* write_name;
793
794
  //find the space character for method name
795
0
  int write_name_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
796
0
  if (write_name_end < 0)
797
0
  {
798
0
    expert_add_info(pinfo, tree, &ei_sick_cola_command_name);
799
0
    return tvb_reported_length(tvb);
800
0
  }
801
802
  //don't include the space delimiter in the string
803
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_write_name, tvb, offset, write_name_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &write_name);
804
0
  offset = write_name_end+1;
805
806
807
0
  if (strcmp(write_name, "MMAlignmentMode") == 0)
808
0
  {
809
0
    if (binary)
810
0
    {
811
0
      proto_tree_add_item(tree, hf_sick_cola_mm_alignment_node_layer_activation, tvb, offset, 1, ENC_BIG_ENDIAN);
812
0
      offset += 1;
813
0
    }
814
0
  }
815
0
  else if (strcmp(write_name, "LMPautostartmeas") == 0)
816
0
  {
817
0
    if (binary)
818
0
    {
819
0
      proto_tree_add_item(tree, hf_sick_cola_autostartmeas_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
820
0
      offset += 1;
821
0
    }
822
0
  }
823
0
  else if (strcmp(write_name, "CLApplication") == 0)
824
0
  {
825
0
    if (binary)
826
0
    {
827
0
      proto_tree_add_item(tree, hf_sick_cola_clapplication_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
828
0
      offset += 2;
829
0
    }
830
0
  }
831
0
  else if (strcmp(write_name, "SetActiveApplications") == 0)
832
0
  {
833
0
    uint32_t count;
834
835
0
    if (binary)
836
0
    {
837
0
      proto_tree_add_item_ret_uint(tree, hf_sick_cola_set_active_app_count, tvb, offset, 1, ENC_BIG_ENDIAN, &count);
838
0
      offset += 1;
839
0
      for (uint32_t i = 0; i < count; i++)
840
0
      {
841
0
        proto_tree_add_item(tree, hf_sick_cola_set_active_app_id, tvb, offset, 4, ENC_ASCII);
842
0
        offset += 4;
843
0
        proto_tree_add_item(tree, hf_sick_cola_set_active_app_active, tvb, offset, 1, ENC_BIG_ENDIAN);
844
0
        offset += 1;
845
0
      }
846
0
    }
847
0
  }
848
0
  else if (strcmp(write_name, "LCMcfg") == 0)
849
0
  {
850
0
    if (binary)
851
0
    {
852
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_strategy, tvb, offset, 1, ENC_BIG_ENDIAN);
853
0
      offset += 1;
854
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_response_time, tvb, offset, 4, ENC_BIG_ENDIAN);
855
0
      offset += 4;
856
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_threshold_warning, tvb, offset, 4, ENC_BIG_ENDIAN);
857
0
      offset += 4;
858
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_threshold_error, tvb, offset, 4, ENC_BIG_ENDIAN);
859
0
      offset += 4;
860
0
    }
861
0
  }
862
0
  else if (strcmp(write_name, "LMDscandatacfg") == 0)
863
0
  {
864
0
    if (binary)
865
0
    {
866
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_data_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
867
0
      offset += 2;
868
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_remission, tvb, offset, 1, ENC_BIG_ENDIAN);
869
0
      offset += 1;
870
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_resolution, tvb, offset, 1, ENC_BIG_ENDIAN);
871
0
      offset += 1;
872
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_unit, tvb, offset, 1, ENC_BIG_ENDIAN);
873
0
      offset += 1;
874
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_encoder, tvb, offset, 2, ENC_BIG_ENDIAN);
875
0
      offset += 2;
876
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_position, tvb, offset, 1, ENC_BIG_ENDIAN);
877
0
      offset += 1;
878
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_device_name, tvb, offset, 1, ENC_BIG_ENDIAN);
879
0
      offset += 1;
880
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_comment, tvb, offset, 1, ENC_BIG_ENDIAN);
881
0
      offset += 1;
882
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_time, tvb, offset, 1, ENC_BIG_ENDIAN);
883
0
      offset += 1;
884
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_cfg_output_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
885
0
      offset += 2;
886
0
    }
887
0
  }
888
0
  else if (strcmp(write_name, "LMPoutputRange") == 0)
889
0
  {
890
0
    if (binary)
891
0
    {
892
0
      proto_tree_add_item(tree, hf_sick_cola_change_output_range_status_code, tvb, offset, 2, ENC_BIG_ENDIAN);
893
0
      offset += 2;
894
0
      float angular_resolution = tvb_get_ntohl(tvb, offset) / 10000.f;
895
0
      proto_tree_add_float(tree, hf_sick_cola_change_output_range_angular_resolution, tvb, offset, 4, angular_resolution);
896
0
      offset += 4;
897
0
      int start_angle = (int)tvb_get_ntohl(tvb, offset);
898
0
      proto_tree_add_float(tree, hf_sick_cola_change_output_range_start_angle, tvb, offset, 4, start_angle/10000.f);
899
0
      offset += 4;
900
0
      int stop_angle = (int)tvb_get_ntohl(tvb, offset);
901
0
      proto_tree_add_float(tree, hf_sick_cola_change_output_range_stop, tvb, offset, 4, stop_angle/10000.f);
902
0
      offset += 4;
903
904
0
    }
905
0
  }
906
0
  else if (strcmp(write_name, "TSCRole") == 0)
907
0
  {
908
0
    if (binary)
909
0
    {
910
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_tsc_role, tvb, offset, 1, ENC_BIG_ENDIAN);
911
0
      offset += 1;
912
0
    }
913
0
  }
914
0
  else if (strcmp(write_name, "TSCTCInterface") == 0)
915
0
  {
916
0
    if (binary)
917
0
    {
918
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_interface_data, tvb, offset, 1, ENC_BIG_ENDIAN);
919
0
      offset += 1;
920
0
    }
921
0
  }
922
0
  else if (strcmp(write_name, "TSCTCSrvAddr") == 0)
923
0
  {
924
0
    if (binary)
925
0
    {
926
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_ipaddress, tvb, offset, 4, ENC_BIG_ENDIAN);
927
0
      offset += 4;
928
0
    }
929
0
  }
930
0
  else if (strcmp(write_name, "TSCTCtimezone") == 0)
931
0
  {
932
0
    if (binary)
933
0
    {
934
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_gmt_timezone_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
935
0
      offset += 1;
936
0
    }
937
0
  }
938
0
  else if (strcmp(write_name, "TSCTCupdatetime") == 0)
939
0
  {
940
0
    if (binary)
941
0
    {
942
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_timesync, tvb, offset, 4, ENC_BIG_ENDIAN);
943
0
      offset += 4;
944
0
    }
945
0
  }
946
0
  else if (strcmp(write_name, "LFPparticle") == 0)
947
0
  {
948
0
    if (binary)
949
0
    {
950
0
      proto_tree_add_item(tree, hf_sick_cola_particle_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
951
0
      offset += 1;
952
0
      proto_tree_add_item(tree, hf_sick_cola_particle_filter_threshold, tvb, offset, 2, ENC_BIG_ENDIAN);
953
0
      offset += 2;
954
0
    }
955
0
  }
956
0
  else if (strcmp(write_name, "LFPmeanfilter") == 0)
957
0
  {
958
0
    if (binary)
959
0
    {
960
0
      proto_tree_add_item(tree, hf_sick_cola_mean_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
961
0
      offset += 1;
962
0
      proto_tree_add_item(tree, hf_sick_cola_mean_filter_num_scans, tvb, offset, 2, ENC_BIG_ENDIAN);
963
0
      offset += 2;
964
0
      proto_tree_add_item(tree, hf_sick_cola_mean_filter_final_part, tvb, offset, 1, ENC_BIG_ENDIAN);
965
0
      offset += 1;
966
0
    }
967
0
  }
968
0
  else if (strcmp(write_name, "LFPnto1filter") == 0)
969
0
  {
970
0
    if (binary)
971
0
    {
972
0
      proto_tree_add_item(tree, hf_sick_cola_nto1_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
973
0
      offset += 1;
974
0
    }
975
0
  }
976
0
  else if (strcmp(write_name, "FREchoFilter") == 0)
977
0
  {
978
0
    if (binary)
979
0
    {
980
0
      proto_tree_add_item(tree, hf_sick_cola_echo_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
981
0
      offset += 1;
982
0
    }
983
0
  }
984
0
  else if (strcmp(write_name, "MSsuppmode") == 0)
985
0
  {
986
0
    if (binary)
987
0
    {
988
0
      proto_tree_add_item(tree, hf_sick_cola_fog_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
989
0
      offset += 1;
990
0
    }
991
0
  }
992
0
  else if (strcmp(write_name, "CLFogFilterEn") == 0)
993
0
  {
994
0
    if (binary)
995
0
    {
996
0
      proto_tree_add_item(tree, hf_sick_cola_fog_filter_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
997
0
      offset += 1;
998
0
    }
999
0
  }
1000
0
  else if (strcmp(write_name, "MCSenseLevel") == 0)
1001
0
  {
1002
0
    if (binary)
1003
0
    {
1004
0
      proto_tree_add_item(tree, hf_sick_cola_fog_filter_sensitivity_level, tvb, offset, 1, ENC_BIG_ENDIAN);
1005
0
      offset += 1;
1006
0
    }
1007
0
  }
1008
0
  else if (strcmp(write_name, "CLNFDigFilterEn") == 0)
1009
0
  {
1010
0
    if (binary)
1011
0
    {
1012
0
      proto_tree_add_item(tree, hf_sick_cola_digital_nearfield_filter_status, tvb, offset, 1, ENC_BIG_ENDIAN);
1013
0
      offset += 1;
1014
0
    }
1015
0
  }
1016
0
  else if (strcmp(write_name, "CLHWFilterSectEn") == 0)
1017
0
  {
1018
0
    if (binary)
1019
0
    {
1020
0
      proto_tree_add_item(tree, hf_sick_cola_digital_nearfield_filter_active_sector_vector, tvb, offset, 4, ENC_BIG_ENDIAN);
1021
0
      offset += 4;
1022
0
    }
1023
0
  }
1024
0
  else if (strcmp(write_name, "LICsrc") == 0)
1025
0
  {
1026
0
    if (binary)
1027
0
    {
1028
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_increment_source, tvb, offset, 1, ENC_BIG_ENDIAN);
1029
0
      offset += 1;
1030
0
    }
1031
0
  }
1032
0
  else if (strcmp(write_name, "LICencset") == 0)
1033
0
  {
1034
0
    if (binary)
1035
0
    {
1036
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_setting, tvb, offset, 1, ENC_BIG_ENDIAN);
1037
0
      offset += 1;
1038
0
    }
1039
0
  }
1040
0
  else if (strcmp(write_name, "LICencres") == 0)
1041
0
  {
1042
0
    if (binary)
1043
0
    {
1044
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_resolution, tvb, offset, 4, ENC_BIG_ENDIAN);
1045
0
      offset += 4;
1046
0
    }
1047
0
  }
1048
0
  else if (strcmp(write_name, "LICFixVel") == 0)
1049
0
  {
1050
0
    if (binary)
1051
0
    {
1052
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_fixed_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
1053
0
      offset += 4;
1054
0
    }
1055
0
  }
1056
0
  else if ((strcmp(write_name, "DO6Fnc") == 0) ||
1057
0
       (strcmp(write_name, "DO3Fnc") == 0))
1058
0
  {
1059
0
    if (binary)
1060
0
    {
1061
0
      proto_tree_add_item(tree, hf_sick_cola_output_do3_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1062
0
      offset += 1;
1063
0
    }
1064
0
  }
1065
0
  else if (strcmp(write_name, "DO1Fnc") == 0)
1066
0
  {
1067
0
    if (binary)
1068
0
    {
1069
0
      proto_tree_add_item(tree, hf_sick_cola_output_do1_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1070
0
      offset += 1;
1071
0
    }
1072
0
  }
1073
0
  else if (strcmp(write_name, "DO1Logic") == 0)
1074
0
  {
1075
0
    if (binary)
1076
0
    {
1077
0
      proto_tree_add_item(tree, hf_sick_cola_output_do1_logic, tvb, offset, 4, ENC_BIG_ENDIAN);
1078
0
      offset += 4;
1079
0
    }
1080
0
  }
1081
0
  else if (strcmp(write_name, "DO2Fnc") == 0)
1082
0
  {
1083
0
    if (binary)
1084
0
    {
1085
0
      proto_tree_add_item(tree, hf_sick_cola_output_do2_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1086
0
      offset += 1;
1087
0
    }
1088
0
  }
1089
0
  else if (strcmp(write_name, "DO2Logic") == 0)
1090
0
  {
1091
0
    if (binary)
1092
0
    {
1093
0
      proto_tree_add_item(tree, hf_sick_cola_output_do2_logic, tvb, offset, 4, ENC_BIG_ENDIAN);
1094
0
      offset += 4;
1095
0
    }
1096
0
  }
1097
0
  else if (strcmp(write_name, "SYMode") == 0)
1098
0
  {
1099
0
    if (binary)
1100
0
    {
1101
0
      proto_tree_add_item(tree, hf_sick_cola_output_sync_mode_data, tvb, offset, 1, ENC_BIG_ENDIAN);
1102
0
      offset += 1;
1103
0
    }
1104
0
  }
1105
0
  else if (strcmp(write_name, "SYPhase") == 0)
1106
0
  {
1107
0
    if (binary)
1108
0
    {
1109
0
      proto_tree_add_item(tree, hf_sick_cola_output_sync_phase_data, tvb, offset, 2, ENC_BIG_ENDIAN);
1110
0
      offset += 2;
1111
0
    }
1112
0
  }
1113
0
  else if (strcmp(write_name, "DO3And4Fnc") == 0)
1114
0
  {
1115
0
    if (binary)
1116
0
    {
1117
0
      proto_tree_add_item(tree, hf_sick_cola_input_do3and4_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1118
0
      offset += 1;
1119
0
    }
1120
0
  }
1121
0
  else if (strcmp(write_name, "DI3DebTim") == 0)
1122
0
  {
1123
0
    if (binary)
1124
0
    {
1125
0
      proto_tree_add_item(tree, hf_sick_cola_input_debounce_time_data, tvb, offset, 2, ENC_BIG_ENDIAN);
1126
0
      offset += 2;
1127
0
    }
1128
0
  }
1129
1130
0
  return offset;
1131
0
}
1132
1133
static int
1134
dissect_sick_cola_method(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
1135
0
{
1136
0
  int offset = 0;
1137
0
  const uint8_t* method_name;
1138
0
  int parameter_end;
1139
1140
  //find the space character for method name
1141
0
  int method_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
1142
0
  if (method_end < 0)
1143
0
  {
1144
    //The command must have no parameters
1145
0
    proto_tree_add_item(tree, hf_sick_cola_method_name, tvb, offset, -1, ENC_ASCII);
1146
0
    return tvb_reported_length(tvb);
1147
0
  }
1148
1149
  //don't include the space delimiter in the string
1150
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_method_name, tvb, offset, method_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &method_name);
1151
0
  offset = method_end+1;
1152
1153
0
  if (strcmp(method_name, "SetAccessMode") == 0)
1154
0
  {
1155
0
    uint32_t password;
1156
0
    char str_password[20];
1157
0
    if (binary)
1158
0
    {
1159
0
      proto_tree_add_item(tree, hf_sick_cola_set_access_mode_user_level, tvb, offset, 1, ENC_BIG_ENDIAN);
1160
0
      offset += 1;
1161
0
      password = tvb_get_ntohl(tvb, offset);
1162
0
      proto_tree_add_string(tree, hf_sick_cola_set_access_mode_password, tvb, offset, 4, dword_to_hex(str_password, password));
1163
0
      offset += 4;
1164
0
    }
1165
0
    else
1166
0
    {
1167
0
      parameter_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
1168
0
      if (parameter_end < 0)
1169
0
      {
1170
0
        expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for SetAccessMode user level");
1171
0
        return tvb_reported_length(tvb);
1172
0
      }
1173
1174
0
      uint32_t user_level;
1175
0
      uint8_t* str_user_level = tvb_get_string_enc(pinfo->pool, tvb, offset, parameter_end - offset, ENC_NA | ENC_ASCII);
1176
0
      if (ws_strtou32(str_user_level, NULL, &user_level))
1177
0
      {
1178
0
        proto_tree_add_uint(tree, hf_sick_cola_set_access_mode_user_level, tvb, offset, parameter_end - offset, user_level);
1179
0
      }
1180
0
      else
1181
0
      {
1182
0
        proto_tree_add_uint(tree, hf_sick_cola_set_access_mode_user_level, tvb, offset, parameter_end - offset, 0xFFFFFFFF);
1183
0
      }
1184
0
      offset = parameter_end+1;
1185
1186
0
      proto_tree_add_item(tree, hf_sick_cola_set_access_mode_password, tvb, offset, -1, ENC_ASCII);
1187
0
      offset = tvb_reported_length(tvb);
1188
0
    }
1189
0
  }
1190
0
  else if (strcmp(method_name, "mLMPsetscancfg") == 0)
1191
0
  {
1192
0
    if (binary)
1193
0
    {
1194
0
      uint32_t scan_frequency = tvb_get_ntohl(tvb, offset) / 100;
1195
0
      proto_tree_add_uint(tree, hf_sick_cola_set_scan_cfg_scan_frequency, tvb, offset, 4, scan_frequency);
1196
0
      offset += 4;
1197
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_num_active_scanners, tvb, offset, 2, ENC_BIG_ENDIAN);
1198
0
      offset += 2;
1199
0
      float angular_resolution = tvb_get_ntohl(tvb, offset) / 10000.f;
1200
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_angular_resolution, tvb, offset, 4, angular_resolution);
1201
0
      offset += 4;
1202
0
      int start_angle = (int)tvb_get_ntohl(tvb, offset);
1203
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_start_angle, tvb, offset, 4, start_angle/10000.f);
1204
0
      offset += 4;
1205
0
      int stop_angle = (int)tvb_get_ntohl(tvb, offset);
1206
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_stop_angle, tvb, offset, 4, stop_angle/10000.f);
1207
0
      offset += 4;
1208
0
    }
1209
0
  }
1210
0
  else if (strcmp(method_name, "mCLsetscancfglist") == 0)
1211
0
  {
1212
0
    if (binary)
1213
0
    {
1214
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_mode, tvb, offset, 1, ENC_NA);
1215
0
      offset += 1;
1216
0
    }
1217
0
  }
1218
0
  else if (strcmp(method_name, "SetPassword") == 0)
1219
0
  {
1220
0
    if (binary)
1221
0
    {
1222
0
      proto_tree_add_item(tree, hf_sick_cola_set_password_user_level, tvb, offset, 1, ENC_NA);
1223
0
      offset += 1;
1224
0
      proto_tree_add_item(tree, hf_sick_cola_set_password_hash, tvb, offset, 4, ENC_BIG_ENDIAN);
1225
0
      offset += 4;
1226
0
    }
1227
0
  }
1228
0
  else if (strcmp(method_name, "CheckPassword") == 0)
1229
0
  {
1230
0
    if (binary)
1231
0
    {
1232
0
      proto_tree_add_item(tree, hf_sick_cola_check_password_user_level, tvb, offset, 1, ENC_NA);
1233
0
      offset += 1;
1234
0
      proto_tree_add_item(tree, hf_sick_cola_check_password_hash, tvb, offset, 4, ENC_BIG_ENDIAN);
1235
0
      offset += 4;
1236
0
    }
1237
0
  }
1238
0
  else if (strcmp(method_name, "LSPsetdatetime") == 0)
1239
0
  {
1240
0
    if (binary)
1241
0
    {
1242
0
      offset = diplay_timestamp_field(tree, tvb, offset, hf_sick_cola_set_date_time, binary);
1243
0
    }
1244
0
  }
1245
0
  else if (strcmp(method_name, "mDOSetOutput") == 0)
1246
0
  {
1247
0
    if (binary)
1248
0
    {
1249
0
      proto_tree_add_item(tree, hf_sick_cola_set_output_state_number, tvb, offset, 1, ENC_NA);
1250
0
      offset += 1;
1251
0
      proto_tree_add_item(tree, hf_sick_cola_set_output_state_state, tvb, offset, 1, ENC_NA);
1252
0
      offset += 1;
1253
0
    }
1254
0
  }
1255
1256
1257
0
  return offset;
1258
0
}
1259
1260
static int
1261
dissect_sick_cola_event(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
1262
0
{
1263
0
  int offset = 0;
1264
0
  const uint8_t* event_name;
1265
1266
  //find the space character for method name
1267
0
  int event_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
1268
0
  if (event_end < 0)
1269
0
  {
1270
    //The command must have no parameters
1271
0
    proto_tree_add_item(tree, hf_sick_cola_event_name, tvb, offset, -1, ENC_ASCII);
1272
0
    return tvb_reported_length(tvb);
1273
0
  }
1274
1275
  //don't include the space delimiter in the string
1276
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_event_name, tvb, offset, event_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &event_name);
1277
0
  offset = event_end+1;
1278
1279
0
  if (strcmp(event_name, "LMDscandata") == 0)
1280
0
  {
1281
0
    if (binary)
1282
0
    {
1283
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_start_stop, tvb, offset, 1, ENC_BIG_ENDIAN);
1284
0
      offset += 1;
1285
0
    }
1286
0
  }
1287
0
  else if (strcmp(event_name, "LIDoutputstate") == 0)
1288
0
  {
1289
0
    if (binary)
1290
0
    {
1291
0
      proto_tree_add_item(tree, hf_sick_cola_output_state_start_stop, tvb, offset, 1, ENC_BIG_ENDIAN);
1292
0
      offset += 1;
1293
0
    }
1294
0
  }
1295
1296
0
  return offset;
1297
0
}
1298
1299
static int
1300
dissect_binary_scan_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1301
0
{
1302
0
  proto_tree *device_tree, *status_info_tree, *frequency_tree, *output_channel16_tree, *output_channel8_tree,
1303
0
        *data_tree, *channel_tree, *position_tree, *time_tree, *event_tree;
1304
0
  proto_item *output_channel16_item, *output_channel8_item, *channel_item;
1305
1306
0
  proto_tree_add_item(tree, hf_sick_cola_scan_data_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1307
0
  offset += 2;
1308
0
  device_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_scan_data_device, NULL, "Device");
1309
0
  proto_tree_add_item(device_tree, hf_sick_cola_scan_data_device_number, tvb, offset, 2, ENC_BIG_ENDIAN);
1310
0
  offset += 2;
1311
0
  proto_tree_add_item(device_tree, hf_sick_cola_scan_data_serial_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1312
0
  offset += 4;
1313
0
  proto_tree_add_item(device_tree, hf_sick_cola_scan_data_device_status, tvb, offset, 2, ENC_BIG_ENDIAN);
1314
0
  offset += 2;
1315
0
  status_info_tree = proto_tree_add_subtree(tree, tvb, offset, 18, ett_scan_data_status_info, NULL, "Status Info");
1316
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_telegram_counter, tvb, offset, 2, ENC_BIG_ENDIAN);
1317
0
  offset += 2;
1318
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_scan_counter, tvb, offset, 2, ENC_BIG_ENDIAN);
1319
0
  offset += 2;
1320
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_time_since_startup, tvb, offset, 4, ENC_BIG_ENDIAN);
1321
0
  offset += 4;
1322
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_transmission_time, tvb, offset, 4, ENC_BIG_ENDIAN);
1323
0
  offset += 4;
1324
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_di_status, tvb, offset, 2, ENC_BIG_ENDIAN);
1325
0
  offset += 2;
1326
0
  proto_tree_add_item(status_info_tree, hf_sick_cola_scan_data_do_status, tvb, offset, 2, ENC_BIG_ENDIAN);
1327
0
  offset += 2;
1328
0
  uint16_t layer_angle;
1329
0
  if (ws_hexstrtou16(tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII), NULL, &layer_angle))
1330
0
  {
1331
0
    proto_tree_add_int(status_info_tree, hf_sick_cola_scan_data_layer_angle, tvb, offset, 2, (int16_t)layer_angle);
1332
0
  }
1333
0
  else
1334
0
  {
1335
0
    proto_tree_add_int(status_info_tree, hf_sick_cola_scan_data_layer_angle, tvb, offset, 2, 0);
1336
0
  }
1337
0
  offset += 2;
1338
1339
0
  frequency_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_scan_data_frequency, NULL, "Frequencies");
1340
0
        uint32_t scan_frequency = tvb_get_ntohl(tvb, offset) / 100;
1341
0
  proto_tree_add_uint(frequency_tree, hf_sick_cola_scan_data_scan_frequency, tvb, offset, 4, scan_frequency);
1342
0
  offset += 4;
1343
0
  proto_tree_add_item(frequency_tree, hf_sick_cola_scan_data_measurement_frequency, tvb, offset, 4, ENC_BIG_ENDIAN);
1344
0
  offset += 4;
1345
1346
0
  uint32_t encoder_amount;
1347
0
  proto_tree_add_item_ret_uint(tree, hf_sick_cola_scan_data_encoder_amount, tvb, offset, 2, ENC_BIG_ENDIAN, &encoder_amount);
1348
0
  offset += 2;
1349
0
  if (encoder_amount != 0)
1350
0
  {
1351
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_encoder_position, tvb, offset, 4, ENC_BIG_ENDIAN);
1352
0
    offset += 4;
1353
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_encoder_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1354
0
    offset += 2;
1355
0
  }
1356
1357
0
  output_channel16_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_scan_data_16bit_output_channels, &output_channel16_item, "16-bit Channels");
1358
1359
0
  uint32_t num_channels, channel, datasize;
1360
0
  int start_offset = offset, channel_start;
1361
0
  proto_tree_add_item_ret_uint(output_channel16_tree, hf_sick_cola_scan_data_num_16bit_channels, tvb, offset, 2, ENC_BIG_ENDIAN, &num_channels);
1362
0
  offset += 2;
1363
0
  for (channel = 0; channel < num_channels; channel++)
1364
0
  {
1365
0
    channel_start = offset;
1366
0
    channel_tree = proto_tree_add_subtree_format(output_channel16_tree, tvb, offset, 2, ett_scan_data_16bit_output_channel, &channel_item, "Channel #%d", channel+1);
1367
1368
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_content, tvb, offset, 5, ENC_ASCII);
1369
0
    offset += 5;
1370
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor, tvb, offset, 4, ENC_BIG_ENDIAN);
1371
0
    offset += 4;
1372
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
1373
0
    offset += 4;
1374
0
    int start_angle = (int)tvb_get_ntohl(tvb, offset);
1375
0
    proto_tree_add_int(channel_tree, hf_sick_cola_scan_data_output_channel_start_angle, tvb, offset, 4, start_angle/10000);
1376
0
    offset += 4;
1377
0
                float angular_step = tvb_get_ntohs(tvb, offset) / 10000.0f;
1378
0
    proto_tree_add_float(channel_tree, hf_sick_cola_scan_data_output_channel_size_single_angular_step, tvb, offset, 2, angular_step);
1379
0
    offset += 2;
1380
0
    proto_tree_add_item_ret_uint(channel_tree, hf_sick_cola_scan_data_num_data_points, tvb, offset, 2, ENC_BIG_ENDIAN, &datasize);
1381
0
    offset += 2;
1382
0
    data_tree = proto_tree_add_subtree(channel_tree, tvb, offset, datasize*2, ett_scan_data_16bit_output_data, NULL, "Data");
1383
0
    for (uint32_t i = 0; i < datasize; i++)
1384
0
    {
1385
0
      proto_tree_add_item(data_tree, hf_sick_cola_scan_data_16bit_output_channel_data, tvb, offset, 2, ENC_BIG_ENDIAN);
1386
0
      offset += 2;
1387
0
    }
1388
0
    proto_item_set_len(channel_item, offset - channel_start);
1389
0
  }
1390
0
  proto_item_set_len(output_channel16_item, offset - start_offset);
1391
1392
0
  start_offset = offset;
1393
0
  output_channel8_tree = proto_tree_add_subtree(tree, tvb, offset, 2, ett_scan_data_8bit_output_channels, &output_channel8_item, "8-bit Channels");
1394
1395
0
  proto_tree_add_item_ret_uint(output_channel8_tree, hf_sick_cola_scan_data_num_8bit_channels, tvb, offset, 2, ENC_BIG_ENDIAN, &num_channels);
1396
0
  offset += 2;
1397
0
  for (channel = 0; channel < num_channels; channel++)
1398
0
  {
1399
0
    channel_start = offset;
1400
0
    channel_tree = proto_tree_add_subtree_format(output_channel8_tree, tvb, offset, 2, ett_scan_data_8bit_output_channel, &channel_item, "Channel #%d", channel+1);
1401
1402
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_content, tvb, offset, 5, ENC_ASCII);
1403
0
    offset += 5;
1404
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor, tvb, offset, 4, ENC_BIG_ENDIAN);
1405
0
    offset += 4;
1406
0
    proto_tree_add_item(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
1407
0
    offset += 4;
1408
0
    int start_angle = (int)tvb_get_ntohl(tvb, offset);
1409
0
    proto_tree_add_int(channel_tree, hf_sick_cola_scan_data_output_channel_start_angle, tvb, offset, 4, start_angle/10000);
1410
0
    offset += 4;
1411
0
                float angular_step = tvb_get_ntohs(tvb, offset) / 10000.0f;
1412
0
                proto_tree_add_float(channel_tree, hf_sick_cola_scan_data_output_channel_size_single_angular_step, tvb, offset, 2, angular_step);
1413
0
    offset += 2;
1414
0
    proto_tree_add_item_ret_uint(channel_tree, hf_sick_cola_scan_data_num_data_points, tvb, offset, 2, ENC_BIG_ENDIAN, &datasize);
1415
0
    offset += 2;
1416
0
    data_tree = proto_tree_add_subtree(channel_tree, tvb, offset, datasize, ett_scan_data_8bit_output_data, NULL, "Data");
1417
0
    for (uint32_t i = 0; i < datasize; i++)
1418
0
    {
1419
0
      proto_tree_add_item(data_tree, hf_sick_cola_scan_data_8bit_output_channel_data, tvb, offset, 1, ENC_BIG_ENDIAN);
1420
0
      offset += 1;
1421
0
    }
1422
0
    proto_item_set_len(channel_item, offset - channel_start);
1423
0
  }
1424
0
  proto_item_set_len(output_channel8_item, offset - start_offset);
1425
1426
0
  uint16_t position_present = tvb_get_ntohs(tvb, offset);
1427
0
  if (position_present)
1428
0
  {
1429
0
    position_tree = proto_tree_add_subtree(tree, tvb, offset, 28, ett_scan_data_position, NULL, "Position");
1430
1431
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_position_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1432
0
    offset += 2;
1433
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_position_x, tvb, offset, 4, ENC_BIG_ENDIAN);
1434
0
    offset += 4;
1435
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_position_y, tvb, offset, 4, ENC_BIG_ENDIAN);
1436
0
    offset += 4;
1437
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_position_z, tvb, offset, 4, ENC_BIG_ENDIAN);
1438
0
    offset += 4;
1439
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_rotation_x, tvb, offset, 4, ENC_BIG_ENDIAN);
1440
0
    offset += 4;
1441
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_rotation_y, tvb, offset, 4, ENC_BIG_ENDIAN);
1442
0
    offset += 4;
1443
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_rotation_z, tvb, offset, 4, ENC_BIG_ENDIAN);
1444
0
    offset += 4;
1445
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_rotation_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1446
0
    offset += 1;
1447
0
    proto_tree_add_item(position_tree, hf_sick_cola_scan_data_transmit_device_name, tvb, offset, 1, ENC_BIG_ENDIAN);
1448
0
    offset += 1;
1449
0
  }
1450
0
  else
1451
0
  {
1452
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_position_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1453
0
    offset += 2;
1454
0
  }
1455
1456
0
  uint16_t name_present = tvb_get_ntohs(tvb, offset);
1457
0
  proto_tree_add_item(tree, hf_sick_cola_scan_data_device_name_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1458
0
  offset += 2;
1459
0
  if (name_present)
1460
0
  {
1461
0
    uint16_t name_length = tvb_get_ntohs(tvb, offset);
1462
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_device_name, tvb, offset, 2, ENC_BIG_ENDIAN|ENC_ASCII);
1463
0
    offset += (name_length + 2);
1464
0
  }
1465
1466
0
  uint16_t comment_present = tvb_get_ntohs(tvb, offset);
1467
0
  proto_tree_add_item(tree, hf_sick_cola_scan_data_comment_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1468
0
  offset += 2;
1469
0
  if (comment_present)
1470
0
  {
1471
0
    uint16_t comment_length = tvb_get_ntohs(tvb, offset);
1472
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_comment, tvb, offset, 2, ENC_BIG_ENDIAN|ENC_ASCII);
1473
0
    offset += (comment_length + 2);
1474
0
  }
1475
1476
0
  uint16_t time_present = tvb_get_ntohs(tvb, offset);
1477
0
  if (time_present)
1478
0
  {
1479
0
    time_tree = proto_tree_add_subtree(tree, tvb, offset, 13, ett_scan_data_time, NULL, "Time");
1480
1481
0
    proto_tree_add_item(time_tree, hf_sick_cola_scan_data_time_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1482
0
    offset += 2;
1483
1484
0
    offset = diplay_timestamp_field(time_tree, tvb, offset, hf_sick_cola_scan_data_time, true);
1485
0
  }
1486
0
  else
1487
0
  {
1488
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_time_present, tvb, offset, 2, ENC_BIG_ENDIAN);
1489
0
    offset += 2;
1490
0
  }
1491
1492
0
  uint16_t event_present = tvb_get_ntohs(tvb, offset);
1493
0
  if (event_present )
1494
0
  {
1495
0
    event_tree = proto_tree_add_subtree(tree, tvb, offset, 13, ett_scan_data_event_info, NULL, "Event Info");
1496
0
    proto_tree_add_item(event_tree, hf_sick_cola_scan_data_display_event_info, tvb, offset, 2, ENC_BIG_ENDIAN);
1497
0
    offset += 2;
1498
0
    proto_tree_add_item(event_tree, hf_sick_cola_scan_data_event_info_type, tvb, offset, 4, ENC_ASCII);
1499
0
    offset += 4;
1500
0
    proto_tree_add_item(event_tree, hf_sick_cola_scan_data_event_info_encoder_position, tvb, offset, 4, ENC_BIG_ENDIAN);
1501
0
    offset += 4;
1502
0
    proto_tree_add_item(event_tree, hf_sick_cola_scan_data_event_info_encosder_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1503
0
    offset += 4;
1504
0
    proto_tree_add_item(event_tree, hf_sick_cola_scan_data_event_info_encoder_angle, tvb, offset, 4, ENC_BIG_ENDIAN);
1505
0
    offset += 4;
1506
1507
0
  }
1508
0
  else
1509
0
  {
1510
0
    proto_tree_add_item(tree, hf_sick_cola_scan_data_display_event_info, tvb, offset, 2, ENC_BIG_ENDIAN);
1511
0
    offset += 2;
1512
0
  }
1513
1514
0
  return offset;
1515
0
}
1516
1517
static int
1518
dissect_ascii_scan_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1519
0
{
1520
0
  proto_tree *device_tree, *status_info_tree, *frequency_tree, *output_channel16_tree, *output_channel8_tree,
1521
0
    *data_tree, *channel_tree;
1522
0
  proto_item *device_item, *status_info_item, *frequency_item, *output_channel16_item, *data_item, *output_channel8_item, *channel_item;
1523
0
  int save_offset, parameter_end_offset, data_start_offset;
1524
0
  uint8_t* str_parameter;
1525
1526
0
  if (!cola_ascii_add_parameter_U32(tree, hf_sick_cola_scan_data_version, pinfo, tvb, &offset, "ScanData version", 1))
1527
0
    return tvb_reported_length(tvb);
1528
1529
0
  save_offset = offset;
1530
0
  device_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_scan_data_device, &device_item, "Device");
1531
1532
0
  if (!cola_ascii_add_parameter_U32(device_tree, hf_sick_cola_scan_data_device_number, pinfo, tvb, &offset, "ScanData Device number", 1))
1533
0
    return tvb_reported_length(tvb);
1534
0
  if (!cola_ascii_add_parameter_U32(device_tree, hf_sick_cola_scan_data_serial_number, pinfo, tvb, &offset, "ScanData Serial Number", 1))
1535
0
    return tvb_reported_length(tvb);
1536
0
  if (!cola_ascii_add_parameter_2U8(device_tree, hf_sick_cola_scan_data_device_status, pinfo, tvb, &offset, "ScanData Device Status"))
1537
0
    return tvb_reported_length(tvb);
1538
1539
0
  proto_item_set_len(device_item, offset - save_offset);
1540
1541
0
  save_offset = offset;
1542
0
  status_info_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_scan_data_status_info, &status_info_item, "Status Info");
1543
1544
0
  if (!cola_ascii_add_parameter_U32(status_info_tree, hf_sick_cola_scan_data_telegram_counter, pinfo, tvb, &offset, "ScanData Telegram counter", 1))
1545
0
    return tvb_reported_length(tvb);
1546
1547
0
  if (!cola_ascii_add_parameter_U32(status_info_tree, hf_sick_cola_scan_data_scan_counter, pinfo, tvb, &offset, "ScanData Scan counter", 1))
1548
0
    return tvb_reported_length(tvb);
1549
1550
0
  if (!cola_ascii_add_parameter_U32(status_info_tree, hf_sick_cola_scan_data_time_since_startup, pinfo, tvb, &offset, "ScanData Time Since Startup", 1))
1551
0
    return tvb_reported_length(tvb);
1552
1553
0
  if (!cola_ascii_add_parameter_U32(status_info_tree, hf_sick_cola_scan_data_transmission_time, pinfo, tvb, &offset, "ScanData Transmission Time", 1))
1554
0
    return tvb_reported_length(tvb);
1555
1556
0
  if (!cola_ascii_add_parameter_2U8(status_info_tree, hf_sick_cola_scan_data_di_status, pinfo, tvb, &offset, "ScanData Digital Input Status"))
1557
0
    return tvb_reported_length(tvb);
1558
1559
0
  if (!cola_ascii_add_parameter_2U8(status_info_tree, hf_sick_cola_scan_data_do_status, pinfo, tvb, &offset, "ScanData Digital Output Status"))
1560
0
    return tvb_reported_length(tvb);
1561
1562
0
  if (!cola_ascii_add_parameter_I16(status_info_tree, hf_sick_cola_scan_data_layer_angle, pinfo, tvb, &offset, "ScanData Layer Angle"))
1563
0
    return tvb_reported_length(tvb);
1564
1565
0
  proto_item_set_len(status_info_item, offset - save_offset);
1566
1567
0
  save_offset = offset;
1568
0
  frequency_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_scan_data_frequency, &frequency_item, "Frequencies");
1569
1570
0
  if (!cola_ascii_add_parameter_U32(frequency_tree, hf_sick_cola_scan_data_scan_frequency, pinfo, tvb, &offset, "ScanData Scan Frequency", 100))
1571
0
    return tvb_reported_length(tvb);
1572
1573
0
  if (!cola_ascii_add_parameter_U32(frequency_tree, hf_sick_cola_scan_data_measurement_frequency, pinfo, tvb, &offset, "ScanData Measurement Frequency", 1))
1574
0
    return tvb_reported_length(tvb);
1575
1576
0
  proto_item_set_len(frequency_item, offset - save_offset);
1577
1578
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1579
0
  if (str_parameter == NULL)
1580
0
  {
1581
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData Amount of Encoder");
1582
0
    return false;
1583
0
  }
1584
1585
0
  uint32_t encoder_amount;
1586
0
  if (!ws_hexstrtou32(str_parameter, NULL, &encoder_amount))
1587
0
    return false;
1588
1589
0
  proto_tree_add_uint(tree, hf_sick_cola_scan_data_encoder_amount, tvb, offset, parameter_end_offset-offset, encoder_amount);
1590
0
  offset = parameter_end_offset + 1;
1591
0
  if (encoder_amount != 0)
1592
0
  {
1593
0
    if (!cola_ascii_add_parameter_U32(tree, hf_sick_cola_scan_data_encoder_position, pinfo, tvb, &offset, "ScanData Encoder Position", 1))
1594
0
      return tvb_reported_length(tvb);
1595
1596
0
    if (!cola_ascii_add_parameter_U32(tree, hf_sick_cola_scan_data_encoder_speed, pinfo, tvb, &offset, "ScanData Encoder Speed", 1))
1597
0
      return tvb_reported_length(tvb);
1598
0
  }
1599
1600
  //16-bit channels
1601
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1602
0
  if (str_parameter == NULL)
1603
0
  {
1604
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData Amount of 16-bit channels");
1605
0
    return false;
1606
0
  }
1607
1608
0
  uint32_t num_channels, channel, angular_step, datasize;
1609
0
  int channel_start;
1610
0
  if (!ws_hexstrtou32(str_parameter, NULL, &num_channels))
1611
0
    return false;
1612
1613
0
  save_offset = offset;
1614
0
  output_channel16_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_scan_data_16bit_output_channels, &output_channel16_item, "16-bit Channels");
1615
1616
0
  proto_tree_add_uint(output_channel16_tree, hf_sick_cola_scan_data_num_16bit_channels, tvb, parameter_end_offset-offset, 2, num_channels);
1617
0
  offset = parameter_end_offset + 1;
1618
1619
0
  for (channel = 0; channel < num_channels; channel++)
1620
0
  {
1621
0
    channel_start = offset;
1622
0
    channel_tree = proto_tree_add_subtree_format(output_channel16_tree, tvb, offset, 0, ett_scan_data_16bit_output_channel, &channel_item, "Channel #%d", channel+1);
1623
1624
0
    if (!cola_ascii_add_parameter_string(channel_tree, hf_sick_cola_scan_data_output_channel_content, pinfo, tvb, &offset, "ScanData 16-bit Channel Content"))
1625
0
      return tvb_reported_length(tvb);
1626
1627
0
    if (!cola_ascii_add_parameter_REAL(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor, pinfo, tvb, &offset, "ScanData Scale Factor"))
1628
0
      return tvb_reported_length(tvb);
1629
1630
0
    if (!cola_ascii_add_parameter_REAL(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor_offset, pinfo, tvb, &offset, "ScanData Scale Factor Offset"))
1631
0
      return tvb_reported_length(tvb);
1632
1633
0
    if (!cola_ascii_add_parameter_I32(channel_tree, hf_sick_cola_scan_data_output_channel_start_angle, pinfo, tvb, &offset, "ScanData Start Angle", 10000))
1634
0
      return tvb_reported_length(tvb);
1635
1636
0
    str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1637
0
    if (str_parameter == NULL)
1638
0
    {
1639
0
      expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData Size of Angular Step");
1640
0
      return false;
1641
0
    }
1642
1643
0
    if (!ws_hexstrtou32(str_parameter, NULL, &angular_step))
1644
0
      return false;
1645
1646
0
    proto_tree_add_float(channel_tree, hf_sick_cola_scan_data_output_channel_size_single_angular_step, tvb, offset, parameter_end_offset-offset, angular_step/10000.0f);
1647
0
    offset = parameter_end_offset + 1;
1648
1649
0
    str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1650
0
    if (str_parameter == NULL)
1651
0
    {
1652
0
      expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData 16-bit Channel Amount of Data");
1653
0
      return false;
1654
0
    }
1655
1656
0
    if (!ws_hexstrtou32(str_parameter, NULL, &datasize))
1657
0
      return false;
1658
1659
0
    proto_tree_add_uint(channel_tree, hf_sick_cola_scan_data_num_data_points, tvb, offset, parameter_end_offset-offset, datasize);
1660
0
    offset = parameter_end_offset + 1;
1661
1662
0
    data_start_offset = offset;
1663
0
    data_tree = proto_tree_add_subtree(channel_tree, tvb, offset, 0, ett_scan_data_16bit_output_data, &data_item, "Data");
1664
0
    for (uint32_t i = 0; i < datasize; i++)
1665
0
    {
1666
0
      if (!cola_ascii_add_parameter_U32(data_tree, hf_sick_cola_scan_data_16bit_output_channel_data, pinfo, tvb, &offset, "ScanData 16-bit Channel Data", 1))
1667
0
        return tvb_reported_length(tvb);
1668
0
    }
1669
0
    proto_item_set_len(data_item, offset - data_start_offset);
1670
0
    proto_item_set_len(channel_item, offset - channel_start);
1671
0
  }
1672
0
  proto_item_set_len(output_channel16_item, offset - save_offset);
1673
1674
  //8-bit channels
1675
0
  str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1676
0
  if (str_parameter == NULL)
1677
0
  {
1678
0
    expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData Amount of 8-bit channels");
1679
0
    return false;
1680
0
  }
1681
1682
0
  if (!ws_hexstrtou32(str_parameter, NULL, &num_channels))
1683
0
    return false;
1684
1685
0
  save_offset = offset;
1686
0
  output_channel8_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_scan_data_8bit_output_channels, &output_channel8_item, "8-bit Channels");
1687
1688
0
  proto_tree_add_uint(output_channel8_tree, hf_sick_cola_scan_data_num_8bit_channels, tvb, parameter_end_offset-offset, 2, num_channels);
1689
0
  offset = parameter_end_offset + 1;
1690
1691
0
  for (channel = 0; channel < num_channels; channel++)
1692
0
  {
1693
0
    channel_start = offset;
1694
0
    channel_tree = proto_tree_add_subtree_format(output_channel8_tree, tvb, offset, 2, ett_scan_data_8bit_output_channel, &channel_item, "Channel #%d", channel+1);
1695
1696
0
    if (!cola_ascii_add_parameter_string(channel_tree, hf_sick_cola_scan_data_output_channel_content, pinfo, tvb, &offset, "ScanData 16-bit Channel Content"))
1697
0
      return tvb_reported_length(tvb);
1698
1699
0
    if (!cola_ascii_add_parameter_REAL(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor, pinfo, tvb, &offset, "ScanData Scale Factor"))
1700
0
      return tvb_reported_length(tvb);
1701
1702
0
    if (!cola_ascii_add_parameter_REAL(channel_tree, hf_sick_cola_scan_data_output_channel_scale_factor_offset, pinfo, tvb, &offset, "ScanData Scale Factor Offset"))
1703
0
      return tvb_reported_length(tvb);
1704
1705
0
    if (!cola_ascii_add_parameter_I32(channel_tree, hf_sick_cola_scan_data_output_channel_start_angle, pinfo, tvb, &offset, "ScanData Start Angle", 10000))
1706
0
      return tvb_reported_length(tvb);
1707
1708
0
    str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1709
0
    if (str_parameter == NULL)
1710
0
    {
1711
0
      expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData Size of Angular Step");
1712
0
      return false;
1713
0
    }
1714
1715
0
    if (!ws_hexstrtou32(str_parameter, NULL, &angular_step))
1716
0
      return false;
1717
1718
0
    proto_tree_add_float(channel_tree, hf_sick_cola_scan_data_output_channel_size_single_angular_step, tvb, offset, parameter_end_offset-offset, angular_step/10000.0f);
1719
0
    offset = parameter_end_offset + 1;
1720
1721
0
    str_parameter = cola_get_ascii_parameter_string(pinfo, tvb, offset, &parameter_end_offset);
1722
0
    if (str_parameter == NULL)
1723
0
    {
1724
0
      expert_add_info_format(pinfo, tree, &ei_sick_cola_command_parameter, "Parse error for ScanData 16-bit Channel Amount of Data");
1725
0
      return false;
1726
0
    }
1727
1728
0
    if (!ws_hexstrtou32(str_parameter, NULL, &datasize))
1729
0
      return false;
1730
1731
0
    proto_tree_add_uint(channel_tree, hf_sick_cola_scan_data_num_data_points, tvb, offset, parameter_end_offset-offset, datasize);
1732
0
    offset = parameter_end_offset + 1;
1733
1734
0
    data_start_offset = offset;
1735
0
    data_tree = proto_tree_add_subtree(channel_tree, tvb, offset, 0, ett_scan_data_8bit_output_data, &data_item, "Data");
1736
0
    for (uint32_t i = 0; i < datasize; i++)
1737
0
    {
1738
0
      if (!cola_ascii_add_parameter_U32(data_tree, hf_sick_cola_scan_data_16bit_output_channel_data, pinfo, tvb, &offset, "ScanData 8-bit Channel Data", 1))
1739
0
        return tvb_reported_length(tvb);
1740
0
    }
1741
0
    proto_item_set_len(data_item, offset - data_start_offset);
1742
0
    proto_item_set_len(channel_item, offset - channel_start);
1743
0
  }
1744
1745
0
  proto_item_set_len(output_channel8_item, offset - save_offset);
1746
1747
1748
0
  return offset;
1749
0
}
1750
1751
static int
1752
dissect_output_state(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, int offset, bool binary)
1753
0
{
1754
0
  proto_tree *status_tree, *output_tree, *outX_tree, *time_tree;
1755
1756
0
  status_tree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_output_state_status, NULL, "Status code");
1757
0
  proto_tree_add_item(status_tree, hf_sick_cola_output_state_status_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1758
0
  offset += 2;
1759
0
  proto_tree_add_item(status_tree, hf_sick_cola_output_state_status_system_counter, tvb, offset, 4, ENC_BIG_ENDIAN);
1760
0
  offset += 4;
1761
1762
0
  output_tree = proto_tree_add_subtree(tree, tvb, offset, 5*g_number_of_outputs, ett_output_state, NULL, "Outputs");
1763
0
  for (uint32_t i = 0; i < g_number_of_outputs; i++)
1764
0
  {
1765
0
    outX_tree = proto_tree_add_subtree_format(output_tree, tvb, offset, 5, ett_output_state_x, NULL, "Output #%d", i+1);
1766
0
    proto_tree_add_item(outX_tree, hf_sick_cola_output_state_state, tvb, offset, 1, ENC_BIG_ENDIAN);
1767
0
    offset += 1;
1768
0
    proto_tree_add_item(outX_tree, hf_sick_cola_output_state_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1769
0
    offset += 4;
1770
0
  }
1771
1772
0
  output_tree = proto_tree_add_subtree(tree, tvb, offset, 5*g_number_of_outputs, ett_ext_output_state, NULL, "Ext. Outputs");
1773
0
  for (uint32_t i = 0; i < g_number_of_outputs; i++)
1774
0
  {
1775
0
    outX_tree = proto_tree_add_subtree_format(output_tree, tvb, offset, 5, ett_ext_output_state_x, NULL, "Ext. Output #%d", i+1);
1776
0
    proto_tree_add_item(outX_tree, hf_sick_cola_output_state_ext_state, tvb, offset, 1, ENC_BIG_ENDIAN);
1777
0
    offset += 1;
1778
0
    proto_tree_add_item(outX_tree, hf_sick_cola_output_state_ext_count, tvb, offset, 4, ENC_BIG_ENDIAN);
1779
0
    offset += 4;
1780
0
  }
1781
1782
0
  uint16_t time_present = tvb_get_ntohs(tvb, offset);
1783
0
  if (time_present)
1784
0
  {
1785
0
    time_tree = proto_tree_add_subtree(tree, tvb, offset, 12, ett_output_state_time, NULL, "Time");
1786
1787
0
    proto_tree_add_item(time_tree, hf_sick_cola_output_state_time_present, tvb, offset, 1, ENC_BIG_ENDIAN);
1788
0
    offset += 1;
1789
1790
0
    offset = diplay_timestamp_field(time_tree, tvb, offset, hf_sick_cola_output_state_time, binary);
1791
0
  }
1792
0
  else
1793
0
  {
1794
0
    proto_tree_add_item(tree, hf_sick_cola_output_state_time_present, tvb, offset, 1, ENC_BIG_ENDIAN);
1795
0
    offset += 1;
1796
0
  }
1797
0
  return offset;
1798
0
}
1799
1800
static int
1801
dissect_sick_cola_answer_sra(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
1802
0
{
1803
0
  int offset = 0;
1804
0
  const uint8_t* answer_name;
1805
1806
  //find the space character for read name
1807
0
  int answer_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
1808
0
  if (answer_end < 0)
1809
0
  {
1810
    //The command must have no parameters
1811
0
    proto_tree_add_item(tree, hf_sick_cola_answer_name, tvb, offset, -1, ENC_ASCII);
1812
0
    return tvb_reported_length(tvb);
1813
0
  }
1814
0
  else
1815
0
  {
1816
    //don't include the space delimiter in the string
1817
0
    proto_tree_add_item_ret_string(tree, hf_sick_cola_answer_name, tvb, offset, answer_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &answer_name);
1818
0
    offset = answer_end+1;
1819
0
  }
1820
1821
1822
0
  if (strcmp(answer_name, "LMPscancfg") == 0)
1823
0
  {
1824
0
    if (binary)
1825
0
    {
1826
0
      uint32_t scan_frequency = tvb_get_ntohl(tvb, offset) / 100;
1827
0
      proto_tree_add_uint(tree, hf_sick_cola_set_scan_cfg_scan_frequency, tvb, offset, 4, scan_frequency);
1828
0
      offset += 4;
1829
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_num_active_scanners, tvb, offset, 2, ENC_BIG_ENDIAN);
1830
0
      offset += 2;
1831
0
      float angular_resolution = tvb_get_ntohl(tvb, offset) / 10000.f;
1832
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_angular_resolution, tvb, offset, 4, angular_resolution);
1833
0
      offset += 4;
1834
0
      int start_angle = (int)tvb_get_ntohl(tvb, offset);
1835
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_start_angle, tvb, offset, 4, start_angle/10000.f);
1836
0
      offset += 4;
1837
0
      int stop_angle = (int)tvb_get_ntohl(tvb, offset);
1838
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_stop_angle, tvb, offset, 4, stop_angle/10000.f);
1839
0
      offset += 4;
1840
0
    }
1841
0
  }
1842
0
  else if (strcmp(answer_name, "LCMcfg") == 0)
1843
0
  {
1844
0
    if (binary)
1845
0
    {
1846
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_strategy, tvb, offset, 1, ENC_BIG_ENDIAN);
1847
0
      offset += 1;
1848
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_response_time, tvb, offset, 2, ENC_BIG_ENDIAN);
1849
0
      offset += 2;
1850
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_threshold_warning, tvb, offset, 2, ENC_BIG_ENDIAN);
1851
0
      offset += 2;
1852
0
      proto_tree_add_item(tree, hf_sick_cola_lcm_cfg_threshold_error, tvb, offset, 2, ENC_BIG_ENDIAN);
1853
0
      offset += 2;
1854
0
    }
1855
0
  }
1856
0
  else if (strcmp(answer_name, "CMContLvlM") == 0)
1857
0
  {
1858
0
    if (binary)
1859
0
    {
1860
0
      proto_tree_add_item(tree, hf_sick_cola_cm_cont_lvlm_availability, tvb, offset, 1, ENC_BIG_ENDIAN);
1861
0
      offset += 1;
1862
0
    }
1863
0
  }
1864
0
  else if (strcmp(answer_name, "LMPoutputRange") == 0)
1865
0
  {
1866
0
    if (binary)
1867
0
    {
1868
0
      proto_tree_add_item(tree, hf_sick_cola_output_range_num_sectors, tvb, offset, 2, ENC_BIG_ENDIAN);
1869
0
      offset += 2;
1870
0
      float angular_resolution = tvb_get_ntohl(tvb, offset) / 10000.f;
1871
0
      proto_tree_add_float(tree, hf_sick_cola_output_range_angular_resolution, tvb, offset, 4, angular_resolution);
1872
0
      offset += 4;
1873
0
      int start_angle = (int)tvb_get_ntohl(tvb, offset);
1874
0
      proto_tree_add_float(tree, hf_sick_cola_output_range_start_angle, tvb, offset, 4, start_angle/10000.f);
1875
0
      offset += 4;
1876
0
      int stop_angle = (int)tvb_get_ntohl(tvb, offset);
1877
0
      proto_tree_add_float(tree, hf_sick_cola_output_range_stop, tvb, offset, 4, stop_angle/10000.f);
1878
0
      offset += 4;
1879
0
    }
1880
0
  }
1881
0
  else if (strcmp(answer_name, "LMDscandata") == 0)
1882
0
  {
1883
0
    if (binary)
1884
0
    {
1885
0
      offset = dissect_binary_scan_data(tree, pinfo, tvb, offset);
1886
0
    }
1887
0
    else
1888
0
    {
1889
0
      offset = dissect_ascii_scan_data(tree, pinfo, tvb, offset);
1890
0
    }
1891
0
  }
1892
0
  else if (strcmp(answer_name, "STlms") == 0)
1893
0
  {
1894
0
    proto_tree_add_item(tree, hf_sick_cola_stims_status_code, tvb, offset, 2, ENC_BIG_ENDIAN);
1895
0
    offset += 2;
1896
0
    proto_tree_add_item(tree, hf_sick_cola_stims_temp_out_of_range, tvb, offset, 1, ENC_BIG_ENDIAN);
1897
0
    offset += 1;
1898
0
    proto_tree_add_item(tree, hf_sick_cola_stims_time_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1899
0
    offset += 2;
1900
    //manually format the time
1901
0
    uint16_t hour, minute, second, day, month, year;
1902
0
    hour = tvb_get_ntohs(tvb, offset);
1903
0
    minute = tvb_get_ntohs(tvb, offset+3);
1904
0
    second = tvb_get_ntohs(tvb, offset+6);
1905
0
    proto_tree_add_string(tree, hf_sick_cola_stims_time, tvb, offset, 8,
1906
0
      wmem_strdup_printf(pinfo->pool, "%d:%02d:%02d", hour, minute, second));
1907
0
    offset += 8;
1908
1909
0
    proto_tree_add_item(tree, hf_sick_cola_stims_date_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1910
0
    offset += 2;
1911
0
    day = tvb_get_ntohs(tvb, offset);
1912
0
    month = tvb_get_ntohs(tvb, offset+3);
1913
0
    year = tvb_get_ntohl(tvb, offset+6);
1914
0
    proto_tree_add_string(tree, hf_sick_cola_stims_date, tvb, offset, 10,
1915
0
      wmem_strdup_printf(pinfo->pool, "%02d/%02d/%04d", day, month, year));
1916
0
    offset += 10;
1917
1918
0
    proto_tree_add_item(tree, hf_sick_cola_stims_led1, tvb, offset, 2, ENC_BIG_ENDIAN);
1919
0
    offset += 2;
1920
0
    proto_tree_add_item(tree, hf_sick_cola_stims_led2, tvb, offset, 2, ENC_BIG_ENDIAN);
1921
0
    offset += 2;
1922
0
    proto_tree_add_item(tree, hf_sick_cola_stims_led3, tvb, offset, 2, ENC_BIG_ENDIAN);
1923
0
    offset += 2;
1924
0
    proto_tree_add_item(tree, hf_sick_cola_stims_reserved, tvb, offset, 6, ENC_NA);
1925
0
    offset += 6;
1926
0
  }
1927
0
  else if (strcmp(answer_name, "DeviceTime") == 0)
1928
0
  {
1929
0
    if (binary)
1930
0
    {
1931
0
      proto_tree_add_item(tree, hf_sick_cola_device_time, tvb, offset, 1, ENC_BIG_ENDIAN);
1932
0
      offset += 1;
1933
0
    }
1934
0
  }
1935
0
  else if (strcmp(answer_name, "TSCTCmaxoffset") == 0)
1936
0
  {
1937
0
    if (binary)
1938
0
    {
1939
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_max_offset_time, tvb, offset, 1, ENC_BIG_ENDIAN);
1940
0
      offset += 1;
1941
0
    }
1942
0
  }
1943
0
  else if (strcmp(answer_name, "TSCTCdelay") == 0)
1944
0
  {
1945
0
    if (binary)
1946
0
    {
1947
0
      proto_tree_add_item(tree, hf_sick_cola_ntp_max_offset_time, tvb, offset, 1, ENC_BIG_ENDIAN);
1948
0
      offset += 1;
1949
0
    }
1950
0
  }
1951
0
  else if (strcmp(answer_name, "CLFogFilterEn") == 0)
1952
0
  {
1953
0
    if (binary)
1954
0
    {
1955
0
      proto_tree_add_item(tree, hf_sick_cola_fog_filter_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
1956
0
      offset += 1;
1957
0
    }
1958
0
  }
1959
0
  else if (strcmp(answer_name, "LICSpTh") == 0)
1960
0
  {
1961
0
    if (binary)
1962
0
    {
1963
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_speed_threshold, tvb, offset, 1, ENC_BIG_ENDIAN);
1964
0
      offset += 1;
1965
0
    }
1966
0
  }
1967
0
  else if (strcmp(answer_name, "LICencsp") == 0)
1968
0
  {
1969
0
    if (binary)
1970
0
    {
1971
0
      proto_tree_add_item(tree, hf_sick_cola_encoder_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
1972
0
      offset += 4;
1973
0
    }
1974
0
  }
1975
0
  else if (strcmp(answer_name, "LIDoutputstate") == 0)
1976
0
  {
1977
0
    offset = dissect_output_state(tree, pinfo, tvb, offset, binary);
1978
0
  }
1979
0
  else if (strcmp(answer_name, "SYextmon") == 0)
1980
0
  {
1981
0
    if (binary)
1982
0
    {
1983
0
      proto_tree_add_item(tree, hf_sick_cola_input_sync_status_data, tvb, offset, 1, ENC_BIG_ENDIAN);
1984
0
      offset += 1;
1985
0
      proto_tree_add_item(tree, hf_sick_cola_input_signal_frequency, tvb, offset, 4, ENC_BIG_ENDIAN);
1986
0
      offset += 4;
1987
0
    }
1988
0
  }
1989
1990
0
  return offset;
1991
0
}
1992
1993
static int
1994
dissect_sick_cola_answer_swa(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary _U_)
1995
0
{
1996
0
  int offset = 0;
1997
0
  const uint8_t* answer_name;
1998
1999
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_answer_name, tvb, offset, -1, ENC_NA | ENC_ASCII, pinfo->pool, &answer_name);
2000
0
  offset = tvb_reported_length(tvb);
2001
2002
0
  return offset;
2003
0
}
2004
2005
static int
2006
dissect_sick_cola_answer_san(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
2007
0
{
2008
0
  int offset = 0;
2009
0
  const uint8_t* answer_name;
2010
0
  int parameter_length;
2011
2012
  //find the space character for answer name
2013
0
  int answer_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
2014
0
  if (answer_end < 0)
2015
0
  {
2016
    //The command must have no parameters
2017
0
    proto_tree_add_item(tree, hf_sick_cola_answer_name, tvb, offset, -1, ENC_ASCII);
2018
0
    return tvb_reported_length(tvb);
2019
0
  }
2020
2021
  //don't include the space delimiter in the string
2022
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_answer_name, tvb, offset, answer_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &answer_name);
2023
0
  offset = answer_end+1;
2024
2025
0
  if (strcmp(answer_name, "SetAccessMode") == 0)
2026
0
  {
2027
0
    if (binary)
2028
0
    {
2029
0
      proto_tree_add_item(tree, hf_sick_cola_set_access_mode_change_level, tvb, offset, 1, ENC_BIG_ENDIAN);
2030
0
      offset += 1;
2031
0
    }
2032
0
    else
2033
0
    {
2034
0
      parameter_length = tvb_reported_length_remaining(tvb, offset);
2035
0
      uint32_t change_level;
2036
0
      uint8_t* str_change_level = tvb_get_string_enc(pinfo->pool, tvb, offset, parameter_length, ENC_NA | ENC_ASCII);
2037
0
      if (ws_strtou32(str_change_level, NULL, &change_level))
2038
0
      {
2039
0
        proto_tree_add_uint(tree, hf_sick_cola_set_access_mode_change_level, tvb, offset, parameter_length, change_level);
2040
0
      }
2041
0
      else
2042
0
      {
2043
0
        proto_tree_add_uint(tree, hf_sick_cola_set_access_mode_change_level, tvb, offset, parameter_length, 0xFFFFFFFF);
2044
0
      }
2045
0
    }
2046
0
  }
2047
0
  else if (strcmp(answer_name, "mLMPsetscancfg") == 0)
2048
0
  {
2049
0
    if (binary)
2050
0
    {
2051
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2052
0
      offset += 1;
2053
0
      uint32_t scan_frequency = tvb_get_ntohl(tvb, offset) / 100;
2054
0
      proto_tree_add_uint(tree, hf_sick_cola_set_scan_cfg_scan_frequency, tvb, offset, 4, scan_frequency);
2055
0
      offset += 4;
2056
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_num_active_scanners, tvb, offset, 2, ENC_BIG_ENDIAN);
2057
0
      offset += 2;
2058
0
      float angular_resolution = tvb_get_ntohl(tvb, offset) / 10000.f;
2059
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_angular_resolution, tvb, offset, 4, angular_resolution);
2060
0
      offset += 4;
2061
0
      int start_angle = (int)tvb_get_ntohl(tvb, offset);
2062
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_start_angle, tvb, offset, 4, start_angle/10000.f);
2063
0
      offset += 4;
2064
0
      int stop_angle = (int)tvb_get_ntohl(tvb, offset);
2065
0
      proto_tree_add_float(tree, hf_sick_cola_set_scan_cfg_stop_angle, tvb, offset, 4, stop_angle/10000.f);
2066
0
      offset += 4;
2067
0
    }
2068
0
  }
2069
0
  else if (strcmp(answer_name, "mCLsetscancfglist") == 0)
2070
0
  {
2071
0
    if (binary)
2072
0
    {
2073
0
      proto_tree_add_item(tree, hf_sick_cola_set_scan_cfg_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2074
0
      offset += 1;
2075
0
    }
2076
0
  }
2077
0
  else if (strcmp(answer_name, "LMCstandby") == 0)
2078
0
  {
2079
0
    if (binary)
2080
0
    {
2081
0
      proto_tree_add_item(tree, hf_sick_cola_standby_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2082
0
      offset += 1;
2083
0
    }
2084
0
  }
2085
0
  else if (strcmp(answer_name, "LMCstartmeas") == 0)
2086
0
  {
2087
0
    if (binary)
2088
0
    {
2089
0
      proto_tree_add_item(tree, hf_sick_cola_startmeas_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2090
0
      offset += 1;
2091
0
    }
2092
0
    else
2093
0
    {
2094
      //status code should be rest of packet
2095
0
      parameter_length = tvb_reported_length_remaining(tvb, offset);
2096
0
      uint8_t* str_status_code = tvb_get_string_enc(pinfo->pool, tvb, offset, parameter_length, ENC_NA | ENC_ASCII);
2097
0
      uint32_t status_code;
2098
0
      if (ws_strtou32(str_status_code, NULL, &status_code))
2099
0
      {
2100
0
        proto_tree_add_uint(tree, hf_sick_cola_startmeas_status_code, tvb, offset, parameter_length, status_code);
2101
0
      }
2102
0
      else
2103
0
      {
2104
0
        proto_tree_add_uint(tree, hf_sick_cola_startmeas_status_code, tvb, offset, parameter_length, status_code);
2105
0
      }
2106
0
    }
2107
0
  }
2108
0
  else if (strcmp(answer_name, "LMCstopmeas") == 0)
2109
0
  {
2110
0
    if (binary)
2111
0
    {
2112
0
      proto_tree_add_item(tree, hf_sick_cola_stopmeas_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2113
0
      offset += 1;
2114
0
    }
2115
0
  }
2116
0
  else if (strcmp(answer_name, "SetPassword") == 0)
2117
0
  {
2118
0
    if (binary)
2119
0
    {
2120
0
      proto_tree_add_item(tree, hf_sick_cola_set_password_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2121
0
      offset += 1;
2122
0
    }
2123
0
  }
2124
0
  else if (strcmp(answer_name, "CheckPassword") == 0)
2125
0
  {
2126
0
    if (binary)
2127
0
    {
2128
0
      proto_tree_add_item(tree, hf_sick_cola_check_password_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2129
0
      offset += 1;
2130
0
    }
2131
0
  }
2132
0
  else if (strcmp(answer_name, "mEEwriteall") == 0)
2133
0
  {
2134
0
    if (binary)
2135
0
    {
2136
0
      proto_tree_add_item(tree, hf_sick_cola_ee_write_all_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2137
0
      offset += 1;
2138
0
    }
2139
0
  }
2140
0
  else if (strcmp(answer_name, "Run") == 0)
2141
0
  {
2142
0
    if (binary)
2143
0
    {
2144
0
      proto_tree_add_item(tree, hf_sick_cola_run_status_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2145
0
      offset += 1;
2146
0
    }
2147
0
  }
2148
0
  else if (strcmp(answer_name, "LSPsetdatetime") == 0)
2149
0
  {
2150
0
    if (binary)
2151
0
    {
2152
0
      offset = diplay_timestamp_field(tree, tvb, offset, hf_sick_cola_set_date_time_status_code, binary);
2153
0
    }
2154
0
  }
2155
0
  else if (strcmp(answer_name, "mDOSetOutput") == 0)
2156
0
  {
2157
0
    if (binary)
2158
0
    {
2159
0
      proto_tree_add_item(tree, hf_sick_cola_set_output_state_status_code, tvb, offset, 1, ENC_NA);
2160
0
      offset += 1;
2161
0
    }
2162
0
  }
2163
2164
0
  return offset;
2165
0
}
2166
2167
static int
2168
dissect_sick_cola_answer_sea(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
2169
0
{
2170
0
  int offset = 0;
2171
0
  const uint8_t* answer_name;
2172
2173
  //find the space character for answer name
2174
0
  int answer_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
2175
0
  if (answer_end < 0)
2176
0
  {
2177
    //The command must have no parameters
2178
0
    proto_tree_add_item(tree, hf_sick_cola_answer_name, tvb, offset, -1, ENC_ASCII);
2179
0
    return tvb_reported_length(tvb);
2180
0
  }
2181
2182
  //don't include the space delimiter in the string
2183
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_answer_name, tvb, offset, answer_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &answer_name);
2184
0
  offset = answer_end+1;
2185
2186
0
  if (strcmp(answer_name, "LMDscandata") == 0)
2187
0
  {
2188
0
    if (binary)
2189
0
    {
2190
0
      proto_tree_add_item(tree, hf_sick_cola_scan_data_start_stop, tvb, offset, 1, ENC_BIG_ENDIAN);
2191
0
      offset += 1;
2192
0
    }
2193
0
  }
2194
2195
0
  return offset;
2196
0
}
2197
2198
2199
static int
2200
dissect_sick_cola_answer_ssn(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
2201
0
{
2202
0
  int offset = 0;
2203
0
  const uint8_t* answer_name;
2204
2205
  //find the space character for answer name
2206
0
  int answer_end = tvb_find_uint8(tvb, offset, -1, SICK_COLA_DELIMITER);
2207
0
  if (answer_end < 0)
2208
0
  {
2209
    //The command must have no parameters
2210
0
    proto_tree_add_item(tree, hf_sick_cola_answer_name, tvb, offset, -1, ENC_ASCII);
2211
0
    return tvb_reported_length(tvb);
2212
0
  }
2213
2214
  //don't include the space delimiter in the string
2215
0
  proto_tree_add_item_ret_string(tree, hf_sick_cola_answer_name, tvb, offset, answer_end - offset, ENC_NA | ENC_ASCII, pinfo->pool, &answer_name);
2216
0
  offset = answer_end+1;
2217
2218
0
  if (strcmp(answer_name, "LMDscandata") == 0)
2219
0
  {
2220
0
    if (binary)
2221
0
    {
2222
0
      offset = dissect_binary_scan_data(tree, pinfo, tvb, offset);
2223
0
    }
2224
0
    else
2225
0
    {
2226
0
      offset = dissect_ascii_scan_data(tree, pinfo, tvb, offset);
2227
0
    }
2228
2229
0
  }
2230
0
  else if (strcmp(answer_name, "LIDoutputstate") == 0)
2231
0
  {
2232
0
    offset = dissect_output_state(tree, pinfo, tvb, offset, binary);
2233
0
  }
2234
2235
0
  return offset;
2236
0
}
2237
2238
static int
2239
dissect_sick_cola_answer_sfa(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, bool binary)
2240
0
{
2241
0
  int offset = 0;
2242
2243
0
  if (binary)
2244
0
  {
2245
0
    proto_tree_add_item(tree, hf_sick_cola_sopas_error_code, tvb, offset, 1, ENC_BIG_ENDIAN);
2246
0
    offset += 1;
2247
0
  }
2248
0
  else
2249
0
  {
2250
0
    uint8_t* str_error;
2251
0
    uint32_t error;
2252
0
    int length = tvb_reported_length_remaining(tvb, offset);
2253
2254
0
    str_error = tvb_get_string_enc(pinfo->pool, tvb, offset, length, ENC_NA | ENC_ASCII);
2255
0
    if (!ws_hexstrtou32(str_error, NULL, &error))
2256
0
      return 0;
2257
2258
0
    proto_tree_add_uint(tree, hf_sick_cola_sopas_error_code, tvb, offset, length, error);
2259
0
    offset = tvb_reported_length(tvb);
2260
0
  }
2261
2262
0
  return offset;
2263
0
}
2264
2265
static unsigned
2266
get_sick_cola_b_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2267
17
{
2268
17
  uint32_t len = 0;
2269
2270
17
  len = tvb_get_ntohl(tvb, offset+4);
2271
2272
17
  return len+SICK_COLA_B_HEADER_SIZE+1;
2273
17
}
2274
2275
static int
2276
dissect_sick_cola_b_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2277
17
{
2278
17
  proto_tree *cola_b_tree;
2279
17
  proto_item *ti, *command_item;
2280
17
  int       offset = 0, start_crc_offset;
2281
17
  uint32_t      command, length;
2282
17
  tvbuff_t    *command_tvb;
2283
2284
17
  if (tvb_get_ntohl(tvb, offset) != SICK_COLA_B_MAGIC_NUMBER)
2285
4
  {
2286
    //not our packet
2287
4
    return 0;
2288
4
  }
2289
2290
13
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "CoLa B");
2291
13
  col_clear(pinfo->cinfo, COL_INFO);
2292
2293
13
  ti = proto_tree_add_item(tree, proto_sick_cola_b, tvb, offset, -1, ENC_NA);
2294
13
  cola_b_tree = proto_item_add_subtree(ti, ett_sick_cola_b);
2295
2296
13
  proto_tree_add_item(cola_b_tree, hf_sick_cola_b_magic_number, tvb, offset, 4, ENC_BIG_ENDIAN);
2297
13
  offset += 4;
2298
2299
13
  proto_tree_add_item_ret_uint(cola_b_tree, hf_sick_cola_b_length, tvb, offset, 4, ENC_BIG_ENDIAN, &length);
2300
13
  offset += 4;
2301
2302
13
  start_crc_offset = offset;
2303
13
  command_item = proto_tree_add_item_ret_uint(cola_b_tree, hf_sick_cola_command, tvb, offset, 4, ENC_BIG_ENDIAN, &command);
2304
13
  col_set_str(pinfo->cinfo, COL_INFO, tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII));
2305
13
  offset += 4;
2306
2307
13
  command_tvb = tvb_new_subset_length(tvb, offset, length);
2308
13
  switch (command)
2309
13
  {
2310
0
  case SICK_COLA_COMMAND_READ:
2311
0
    dissect_sick_cola_read(cola_b_tree, pinfo, command_tvb, true);
2312
0
    break;
2313
0
  case SICK_COLA_COMMAND_WRITE:
2314
0
    dissect_sick_cola_write(cola_b_tree, pinfo, command_tvb, true);
2315
0
    break;
2316
0
  case SICK_COLA_COMMAND_METHOD:
2317
0
    dissect_sick_cola_method(cola_b_tree, pinfo, command_tvb, true);
2318
0
    break;
2319
0
  case SICK_COLA_COMMAND_EVENT:
2320
0
    dissect_sick_cola_event(cola_b_tree, pinfo, command_tvb, true);
2321
0
    break;
2322
0
  case SICK_COLA_COMMAND_ANSWER_sRA:
2323
0
    dissect_sick_cola_answer_sra(cola_b_tree, pinfo, command_tvb, true);
2324
0
    break;
2325
0
  case SICK_COLA_COMMAND_ANSWER_sWA:
2326
0
    dissect_sick_cola_answer_swa(cola_b_tree, pinfo, command_tvb, true);
2327
0
    break;
2328
0
  case SICK_COLA_COMMAND_ANSWER_sAN:
2329
0
    dissect_sick_cola_answer_san(cola_b_tree, pinfo, command_tvb, true);
2330
0
    break;
2331
0
  case SICK_COLA_COMMAND_ANSWER_sEA:
2332
0
    dissect_sick_cola_answer_sea(cola_b_tree, pinfo, command_tvb, true);
2333
0
    break;
2334
0
  case SICK_COLA_COMMAND_ANSWER_sSN:
2335
0
    dissect_sick_cola_answer_ssn(cola_b_tree, pinfo, command_tvb, true);
2336
0
    break;
2337
0
  case SICK_COLA_COMMAND_ANSWER_sFA:
2338
0
  case SICK_COLA_COMMAND_ANSWER_sFA_NULL:
2339
0
    dissect_sick_cola_answer_sfa(cola_b_tree, pinfo, command_tvb, true);
2340
0
    break;
2341
0
  case SICK_COLA_COMMAND_SOPAS_BINARY:
2342
0
  case SICK_COLA_COMMAND_ANSWER_SOPAS_BINARY:
2343
0
    proto_tree_add_item(cola_b_tree, hf_sick_cola_b_sopas_command, tvb, offset-4, 4, ENC_ASCII);
2344
0
    proto_tree_add_item(cola_b_tree, hf_sick_cola_b_sopas_command_data, tvb, offset, tvb_reported_length_remaining(tvb, offset)-1, ENC_NA);
2345
0
    break;
2346
2347
11
  default:
2348
11
    expert_add_info(pinfo, command_item, &ei_sick_cola_command);
2349
11
    break;
2350
13
  }
2351
2352
11
  offset += (length-4);
2353
2354
  //Add the checksum
2355
11
  proto_tree_add_checksum(cola_b_tree, tvb, offset,
2356
11
    hf_sick_cola_b_checksum, hf_sick_cola_b_checksum_status, &ei_sick_cola_b_checksum, pinfo,
2357
11
    get_crc8_xor(tvb, length, start_crc_offset), ENC_NA, PROTO_CHECKSUM_VERIFY);
2358
2359
11
  return tvb_captured_length(tvb);
2360
13
}
2361
2362
2363
static int
2364
dissect_sick_cola_b(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2365
13
{
2366
13
  tcp_dissect_pdus(tvb, pinfo, tree, true, SICK_COLA_B_HEADER_SIZE, get_sick_cola_b_pdu_len, dissect_sick_cola_b_pdu, data);
2367
13
  return tvb_captured_length(tvb);
2368
13
}
2369
2370
static bool
2371
dissect_sick_cola_b_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2372
2.98k
{
2373
2.98k
  if (tvb_captured_length(tvb) >= 4) { /* check of data is big enough for base header. */
2374
2.84k
    uint32_t magic_number = tvb_get_ntohl(tvb, 0);
2375
2376
2.84k
    if (magic_number == SICK_COLA_B_MAGIC_NUMBER)
2377
13
    {
2378
13
      dissect_sick_cola_b(tvb, pinfo, tree, data);
2379
13
      return true;
2380
13
    }
2381
2.84k
  }
2382
2.96k
  return false;
2383
2.98k
}
2384
2385
static int
2386
dissect_sick_cola_a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2387
0
{
2388
0
  proto_tree      *cola_a_tree;
2389
0
  proto_item      *ti, *command_item;
2390
0
  int       offset = 0;
2391
0
  uint32_t      command;
2392
0
  int     etxp = 0; /* ETX position */
2393
0
  tvbuff_t    *command_tvb;
2394
2395
  //Ensure there is a start and end delimiter
2396
0
  if (tvb_get_uint8(tvb, offset) != SICK_COLA_A_STX)
2397
0
    return 0;
2398
2399
0
  etxp = tvb_find_uint8(tvb, 1, -1, SICK_COLA_A_ETX);
2400
0
  if (etxp == -1)
2401
0
  {
2402
    //see if the next frame has it
2403
0
    pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2404
0
    pinfo->desegment_offset = 0;
2405
0
    return -1;
2406
0
  }
2407
2408
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "CoLa A");
2409
0
  col_clear(pinfo->cinfo, COL_INFO);
2410
2411
0
  ti = proto_tree_add_item(tree, proto_sick_cola_a, tvb, offset, -1, ENC_NA);
2412
0
  cola_a_tree = proto_item_add_subtree(ti, ett_sick_cola_a);
2413
2414
0
  proto_tree_add_item(cola_a_tree, hf_sick_cola_a_stx, tvb, offset, 1, ENC_BIG_ENDIAN);
2415
0
  offset += 1;
2416
2417
0
  command_item = proto_tree_add_item_ret_uint(cola_a_tree, hf_sick_cola_command, tvb, offset, 4, ENC_BIG_ENDIAN, &command);
2418
0
  col_set_str(pinfo->cinfo, COL_INFO, tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII));
2419
0
  offset += 4;
2420
2421
0
  command_tvb = tvb_new_subset_length(tvb, offset, etxp-offset);
2422
0
  switch (command)
2423
0
  {
2424
0
  case SICK_COLA_COMMAND_READ:
2425
0
    dissect_sick_cola_read(cola_a_tree, pinfo, command_tvb, false);
2426
0
    break;
2427
0
  case SICK_COLA_COMMAND_WRITE:
2428
0
    dissect_sick_cola_write(cola_a_tree, pinfo, command_tvb, false);
2429
0
    break;
2430
0
  case SICK_COLA_COMMAND_METHOD:
2431
0
    dissect_sick_cola_method(cola_a_tree, pinfo, command_tvb, false);
2432
0
    break;
2433
0
  case SICK_COLA_COMMAND_EVENT:
2434
0
    dissect_sick_cola_event(cola_a_tree, pinfo, command_tvb, false);
2435
0
    break;
2436
0
  case SICK_COLA_COMMAND_ANSWER_sRA:
2437
0
    dissect_sick_cola_answer_sra(cola_a_tree, pinfo, command_tvb, false);
2438
0
    break;
2439
0
  case SICK_COLA_COMMAND_ANSWER_sWA:
2440
0
    dissect_sick_cola_answer_swa(cola_a_tree, pinfo, command_tvb, false);
2441
0
    break;
2442
0
  case SICK_COLA_COMMAND_ANSWER_sAN:
2443
0
    dissect_sick_cola_answer_san(cola_a_tree, pinfo, command_tvb, false);
2444
0
    break;
2445
0
  case SICK_COLA_COMMAND_ANSWER_sEA:
2446
0
    dissect_sick_cola_answer_sea(cola_a_tree, pinfo, command_tvb, false);
2447
0
    break;
2448
0
  case SICK_COLA_COMMAND_ANSWER_sSN:
2449
0
    dissect_sick_cola_answer_ssn(cola_a_tree, pinfo, command_tvb, false);
2450
0
    break;
2451
0
  case SICK_COLA_COMMAND_ANSWER_sFA:
2452
0
  case SICK_COLA_COMMAND_ANSWER_sFA_NULL:
2453
0
    dissect_sick_cola_answer_sfa(cola_a_tree, pinfo, command_tvb, false);
2454
0
    break;
2455
0
  case SICK_COLA_COMMAND_SOPAS_ASCII:
2456
0
    proto_tree_add_item(cola_a_tree, hf_sick_cola_a_sopas_command, tvb, offset-4, 4, ENC_ASCII);
2457
0
    proto_tree_add_item(cola_a_tree, hf_sick_cola_a_sopas_command_data, tvb, offset, tvb_reported_length_remaining(tvb, offset)-1, ENC_NA);
2458
0
    break;
2459
2460
0
  default:
2461
0
    expert_add_info(pinfo, command_item, &ei_sick_cola_command);
2462
0
    break;
2463
0
  }
2464
2465
0
  proto_tree_add_item(cola_a_tree, hf_sick_cola_a_etx, tvb, etxp, 1, ENC_BIG_ENDIAN);
2466
2467
0
  return tvb_captured_length(tvb);
2468
0
}
2469
2470
static bool
2471
dissect_sick_cola_a_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2472
2.79k
{
2473
2.79k
  int etxp;
2474
2475
2.79k
  if (tvb_captured_length(tvb) < SICK_COLA_A_MIN_LENGTH)
2476
210
    return false;
2477
2478
2.58k
  if (tvb_get_uint8(tvb, 0) != SICK_COLA_A_STX)
2479
2.48k
    return false;
2480
2481
        /* Try getting the command */
2482
103
        uint32_t command = tvb_get_ntohl(tvb, 1);
2483
103
        if (try_val_to_str(command, cola_command_vals) == NULL)
2484
103
            return false;
2485
2486
0
  etxp = tvb_find_uint8(tvb, 1, -1, SICK_COLA_A_ETX);
2487
0
  if (etxp == -1)
2488
0
    return false;
2489
2490
  /* Ok, looks like a valid packet, go dissect. */
2491
0
  dissect_sick_cola_a(tvb, pinfo, tree, data);
2492
0
  return true;
2493
0
}
2494
2495
void
2496
proto_register_sick_cola(void)
2497
14
{
2498
14
  expert_module_t* expert_sick_cola;
2499
2500
14
  static hf_register_info hf[] = {
2501
14
    { &hf_sick_cola_b_magic_number,
2502
14
      { "Magic Number", "sick_cola.binary.magic_number", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2503
14
    { &hf_sick_cola_b_length,
2504
14
      { "Length", "sick_cola.binary.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2505
14
    { &hf_sick_cola_b_checksum,
2506
14
      { "Checksum", "sick_cola.binary.checksum", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2507
14
    { &hf_sick_cola_b_checksum_status,
2508
14
      { "CRC Status", "sick_cola.binary.checksum_status", FT_UINT8, BASE_NONE, &plugin_proto_checksum_vals, 0x0, NULL, HFILL } },
2509
14
    { &hf_sick_cola_a_stx,
2510
14
      { "STX", "sick_cola.ascii.stx", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2511
14
    { &hf_sick_cola_a_etx,
2512
14
      { "ETX", "sick_cola.ascii.etx", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2513
14
    { &hf_sick_cola_command,
2514
14
      { "Command", "sick_cola.command", FT_UINT32, BASE_NONE, VALS(cola_command_vals), 0x0, NULL, HFILL } },
2515
14
    { &hf_sick_cola_method_name,
2516
14
      { "Method Name", "sick_cola.method_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2517
14
    { &hf_sick_cola_set_access_mode_user_level,
2518
14
      { "User level", "sick_cola.set_access_mode.user_level", FT_UINT8, BASE_DEC, VALS(access_mode_user_level_vals), 0x0, NULL, HFILL } },
2519
14
    { &hf_sick_cola_set_access_mode_password,
2520
14
      { "Password", "sick_cola.set_access_mode.password", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2521
14
    { &hf_sick_cola_set_access_mode_change_level,
2522
14
      { "Change level", "sick_cola.set_access_mode.change_level", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2523
14
    { &hf_sick_cola_answer_name,
2524
14
      { "Answer Name", "sick_cola.answer_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2525
14
    { &hf_sick_cola_set_scan_cfg_scan_frequency,
2526
14
      { "Scan Frequency", "sick_cola.set_scan_cfg.scan_frequency", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_hz), 0x0, NULL, HFILL}},
2527
14
    { &hf_sick_cola_set_scan_cfg_num_active_scanners,
2528
14
      { "Number of Active Scanners", "sick_cola.set_scan_cfg.num_active_scanners", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2529
14
    { &hf_sick_cola_set_scan_cfg_angular_resolution,
2530
14
      { "Angular resolution", "sick_cola.set_scan_cfg.angular_resolution", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2531
14
    { &hf_sick_cola_set_scan_cfg_start_angle,
2532
14
      { "Start angle", "sick_cola.set_scan_cfg.start_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2533
14
    { &hf_sick_cola_set_scan_cfg_stop_angle,
2534
14
      { "Stop Angle", "sick_cola.set_scan_cfg.stop_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2535
14
    { &hf_sick_cola_set_scan_cfg_status_code,
2536
14
      { "Status code", "sick_cola.set_scan_cfg.status_code", FT_UINT8, BASE_DEC, VALS(set_scan_cfg_status_code_vals), 0x0, NULL, HFILL } },
2537
14
    { &hf_sick_cola_read_name,
2538
14
      { "Read Command", "sick_cola.read_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2539
14
    { &hf_sick_cola_write_name,
2540
14
      { "Write Command", "sick_cola.write_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2541
14
    { &hf_sick_cola_mm_alignment_node_layer_activation,
2542
14
      { "Layer activation", "sick_cola.mm_alignment_node.layer_activation", FT_UINT8, BASE_DEC, VALS(layer_activation_vals), 0x0, NULL, HFILL } },
2543
14
    { &hf_sick_cola_set_scan_cfg_mode,
2544
14
      { "Mode", "sick_cola.set_scan_cfg.mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2545
14
    { &hf_sick_cola_standby_status_code,
2546
14
      { "Status code", "sick_cola.standby.status_code", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2547
14
    { &hf_sick_cola_startmeas_status_code,
2548
14
      { "Status code", "sick_cola.startmeas.status_code", FT_UINT8, BASE_DEC, VALS(start_stop_measure_status_code_vals), 0x0, NULL, HFILL } },
2549
14
    { &hf_sick_cola_stopmeas_status_code,
2550
14
      { "Status code", "sick_cola.stopmeas.status_code", FT_UINT8, BASE_DEC, VALS(start_stop_measure_status_code_vals), 0x0, NULL, HFILL } },
2551
14
    { &hf_sick_cola_autostartmeas_enable,
2552
14
      { "Autostart", "sick_cola.autostartmeas.enable", FT_UINT8, BASE_DEC, VALS(autostartmeas_enable_vals), 0x0, NULL, HFILL } },
2553
14
    { &hf_sick_cola_clapplication_mode,
2554
14
      { "Mode", "sick_cola.clapplication.mode", FT_UINT16, BASE_DEC, VALS(clapplication_mode_vals), 0x0, NULL, HFILL } },
2555
14
    { &hf_sick_cola_set_active_app_count,
2556
14
      { "Array length", "sick_cola.set_active_app.count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2557
14
    { &hf_sick_cola_set_active_app_id,
2558
14
      { "Identifier", "sick_cola.set_active_app.id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2559
14
    { &hf_sick_cola_set_active_app_active,
2560
14
      { "Active", "sick_cola.set_active_app.active", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2561
14
    { &hf_sick_cola_set_password_user_level,
2562
14
      { "User level", "sick_cola.set_password.user_level", FT_UINT8, BASE_DEC, VALS(access_mode_user_level_vals), 0x0, NULL, HFILL } },
2563
14
    { &hf_sick_cola_set_password_hash,
2564
14
      { "Mode", "sick_cola.set_password.hash", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2565
14
    { &hf_sick_cola_set_password_status_code,
2566
14
      { "Status code", "sick_cola.set_password.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2567
14
    { &hf_sick_cola_check_password_user_level,
2568
14
      { "User level", "sick_cola.check_password.user_level", FT_UINT8, BASE_DEC, VALS(access_mode_user_level_vals), 0x0, NULL, HFILL } },
2569
14
    { &hf_sick_cola_check_password_hash,
2570
14
      { "Mode", "sick_cola.check_password.hash", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2571
14
    { &hf_sick_cola_check_password_status_code,
2572
14
      { "Status code", "sick_cola.check_password.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2573
14
    { &hf_sick_cola_lcm_cfg_strategy,
2574
14
      { "Strategy", "sick_cola.lcm_cfg.strategy", FT_UINT8, BASE_DEC, VALS(lcm_cfg_strategy_vals), 0x0, NULL, HFILL } },
2575
14
    { &hf_sick_cola_lcm_cfg_response_time,
2576
14
      { "Response Time", "sick_cola.lcm_cfg.response_time", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2577
14
    { &hf_sick_cola_lcm_cfg_threshold_warning,
2578
14
      { "Threshold Warning", "sick_cola.lcm_cfg.threshold_warning", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2579
14
    { &hf_sick_cola_lcm_cfg_threshold_error,
2580
14
      { "Threshold Error", "sick_cola.lcm_cfg.threshold_error", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2581
14
    { &hf_sick_cola_cm_cont_lvlm_availability,
2582
14
      { "Channel availability", "sick_cola.cm_cont_lvlm.availability", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL } },
2583
14
    { &hf_sick_cola_ee_write_all_status_code,
2584
14
      { "Status code", "sick_cola.ee_write_all.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2585
14
    { &hf_sick_cola_run_status_code,
2586
14
      { "Status code", "sick_cola.run.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2587
14
    { &hf_sick_cola_scan_data_cfg_data_channel,
2588
14
      { "Data channel", "sick_cola.scan_data_cfg.data_channel", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2589
14
    { &hf_sick_cola_scan_data_cfg_remission,
2590
14
      { "Remission", "sick_cola.scan_data_cfg.remission", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL } },
2591
14
    { &hf_sick_cola_scan_data_cfg_resolution,
2592
14
      { "Remission", "sick_cola.scan_data_cfg.resolution", FT_UINT8, BASE_DEC, VALS(sick_cola_resolution_vals), 0x0, NULL, HFILL } },
2593
14
    { &hf_sick_cola_scan_data_cfg_unit,
2594
14
      { "Unit (digits)", "sick_cola.scan_data_cfg.unit", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2595
14
    { &hf_sick_cola_scan_data_cfg_encoder,
2596
14
      { "Encoder", "sick_cola.scan_data_cfg.encoder", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2597
14
    { &hf_sick_cola_scan_data_cfg_position,
2598
14
      { "Position", "sick_cola.scan_data_cfg.position", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL } },
2599
14
    { &hf_sick_cola_scan_data_cfg_device_name,
2600
14
      { "Device name", "sick_cola.scan_data_cfg.device_name", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL } },
2601
14
    { &hf_sick_cola_scan_data_cfg_comment,
2602
14
      { "Comment", "sick_cola.scan_data_cfg.comment", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL } },
2603
14
    { &hf_sick_cola_scan_data_cfg_time,
2604
14
      { "Time", "sick_cola.scan_data_cfg.time", FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0, NULL, HFILL } },
2605
14
    { &hf_sick_cola_scan_data_cfg_output_rate,
2606
14
      { "Output rate", "sick_cola.scan_data_cfg.output_rate", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2607
14
    { &hf_sick_cola_change_output_range_status_code,
2608
14
      { "Status code", "sick_cola.change_output_range.status_code", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2609
14
    { &hf_sick_cola_change_output_range_angular_resolution,
2610
14
      { "Angular resolution", "sick_cola.change_output_range.angular_resolution", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2611
14
    { &hf_sick_cola_change_output_range_start_angle,
2612
14
      { "Start angle", "sick_cola.change_output_range.start_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2613
14
    { &hf_sick_cola_change_output_range_stop,
2614
14
      { "Stop Angle", "sick_cola.change_output_range.stop_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2615
14
    { &hf_sick_cola_output_range_num_sectors,
2616
14
      { "Number of sectors", "sick_cola.output_range.num_sectors", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2617
14
    { &hf_sick_cola_output_range_angular_resolution,
2618
14
      { "Angular resolution", "sick_cola.output_range.angular_resolution", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2619
14
    { &hf_sick_cola_output_range_start_angle,
2620
14
      { "Start angle", "sick_cola.output_range.start_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2621
14
    { &hf_sick_cola_output_range_stop,
2622
14
      { "Stop Angle", "sick_cola.output_range.stop_angle", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2623
14
    { &hf_sick_cola_event_name,
2624
14
      { "Event", "sick_cola.event_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2625
14
    { &hf_sick_cola_scan_data_start_stop,
2626
14
      { "Start/Stop", "sick_cola.scan_data.start_stop", FT_UINT8, BASE_DEC, VALS(sick_cola_stop_start_vals), 0x0, NULL, HFILL } },
2627
14
    { &hf_sick_cola_scan_data_version,
2628
14
      { "Version", "sick_cola.scan_data.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2629
14
    { &hf_sick_cola_scan_data_device_number,
2630
14
      { "Device Number", "sick_cola.scan_data.device_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2631
14
    { &hf_sick_cola_scan_data_serial_number,
2632
14
      { "Serial Number", "sick_cola.scan_data.serial_number", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2633
14
    { &hf_sick_cola_scan_data_device_status,
2634
14
      { "Device Status", "sick_cola.scan_data.device_status", FT_UINT16, BASE_DEC, VALS(sick_cola_device_status_vals), 0x0, NULL, HFILL } },
2635
14
    { &hf_sick_cola_scan_data_telegram_counter,
2636
14
      { "Telegram Counter", "sick_cola.scan_data.telegram_counter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2637
14
    { &hf_sick_cola_scan_data_scan_counter,
2638
14
      { "Scan Counter", "sick_cola.scan_data.scan_counter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2639
14
    { &hf_sick_cola_scan_data_time_since_startup,
2640
14
      { "Time since startup", "sick_cola.scan_data.time_since_startup", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, NULL, HFILL } },
2641
14
    { &hf_sick_cola_scan_data_transmission_time,
2642
14
      { "Transmission Time", "sick_cola.scan_data.transmission_time", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, NULL, HFILL } },
2643
14
    { &hf_sick_cola_scan_data_di_status,
2644
14
      { "Digital Input Status", "sick_cola.scan_data.di_status", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2645
14
    { &hf_sick_cola_scan_data_do_status,
2646
14
      { "Digital Output Status", "sick_cola.scan_data.do_status", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2647
14
    { &hf_sick_cola_scan_data_layer_angle,
2648
14
      { "Layer Angle", "sick_cola.scan_data.layer_angle", FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2649
14
    { &hf_sick_cola_scan_data_scan_frequency,
2650
14
      { "Frequency", "sick_cola.scan_data.frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2651
14
    { &hf_sick_cola_scan_data_measurement_frequency,
2652
14
      { "Measurement Frequency", "sick_cola.scan_data.measurement_frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2653
14
    { &hf_sick_cola_scan_data_encoder_amount,
2654
14
      { "Amount of encoder", "sick_cola.scan_data.encoder_amount", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2655
14
    { &hf_sick_cola_scan_data_encoder_position,
2656
14
      { "Encoder Position", "sick_cola.scan_data.encoder_position", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_tick_ticks), 0x0, NULL, HFILL } },
2657
14
    { &hf_sick_cola_scan_data_encoder_speed,
2658
14
      { "Encoder Speed", "sick_cola.scan_data.encoder_speed", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&sick_cola_units_ticks_mm), 0x0, NULL, HFILL } },
2659
14
    { &hf_sick_cola_scan_data_num_16bit_channels,
2660
14
      { "Number of 16-bit channels", "sick_cola.scan_data.num_16bit_channels", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2661
14
    { &hf_sick_cola_scan_data_output_channel_content,
2662
14
      { "Content", "sick_cola.scan_data.output_channel.content", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2663
14
    { &hf_sick_cola_scan_data_output_channel_scale_factor,
2664
14
      { "Scale Factor", "sick_cola.scan_data.output_channel.scale_factor", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2665
14
    { &hf_sick_cola_scan_data_output_channel_scale_factor_offset,
2666
14
      { "Scale Factor Offset", "sick_cola.scan_data.output_channel.scale_factor_offset", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2667
14
    { &hf_sick_cola_scan_data_output_channel_start_angle,
2668
14
      { "Start angle", "sick_cola.scan_data.output_channel.start_angle", FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL}},
2669
14
    { &hf_sick_cola_scan_data_output_channel_size_single_angular_step,
2670
14
      { "Size of single angular step", "sick_cola.scan_data.output_channel.size_single_angular_step", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL } },
2671
14
    { &hf_sick_cola_scan_data_num_data_points,
2672
14
      { "Number of data points", "sick_cola.scan_data.num_data_points", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2673
14
    { &hf_sick_cola_scan_data_16bit_output_channel_data,
2674
14
      { "16-bit data", "sick_cola.scan_data.output_channel.16bit_data", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2675
14
    { &hf_sick_cola_scan_data_8bit_output_channel_data,
2676
14
      { "8-bit data", "sick_cola.scan_data.output_channel.8bit_data", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2677
14
    { &hf_sick_cola_scan_data_num_8bit_channels,
2678
14
      { "Number of 8-bit channels", "sick_cola.scan_data.num_8bit_channels", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2679
14
    { &hf_sick_cola_scan_data_position_present,
2680
14
      { "Position Present", "sick_cola.scan_data.position_present", FT_UINT16, BASE_DEC, VALS(sick_cola_position_present_vals), 0x0, NULL, HFILL } },
2681
14
    { &hf_sick_cola_scan_data_position_x,
2682
14
      { "X Position", "sick_cola.scan_data.position_x", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2683
14
    { &hf_sick_cola_scan_data_position_y,
2684
14
      { "Y Position", "sick_cola.scan_data.position_y", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2685
14
    { &hf_sick_cola_scan_data_position_z,
2686
14
      { "Z Position", "sick_cola.scan_data.position_z", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2687
14
    { &hf_sick_cola_scan_data_rotation_x,
2688
14
      { "X Rotation", "sick_cola.scan_data.rotation_x", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2689
14
    { &hf_sick_cola_scan_data_rotation_y,
2690
14
      { "Y Rotation", "sick_cola.scan_data.rotation_y", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2691
14
    { &hf_sick_cola_scan_data_rotation_z,
2692
14
      { "Z Rotation", "sick_cola.scan_data.rotation_z", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2693
14
    { &hf_sick_cola_scan_data_rotation_type,
2694
14
      { "Rotation Type", "sick_cola.scan_data.rotation_type", FT_UINT16, BASE_DEC, VALS(sick_cola_rotation_type_vals), 0x0, NULL, HFILL } },
2695
14
    { &hf_sick_cola_scan_data_transmit_device_name,
2696
14
      { "Transmit Device Name", "sick_cola.scan_data.transmit_device_name", FT_UINT16, BASE_DEC, VALS(sick_cola_name_present_vals), 0x0, NULL, HFILL } },
2697
14
    { &hf_sick_cola_scan_data_device_name_present,
2698
14
      { "Device Name Present", "sick_cola.scan_data.device_name_present", FT_UINT16, BASE_DEC, VALS(sick_cola_name_present_vals), 0x0, NULL, HFILL } },
2699
14
    { &hf_sick_cola_scan_data_device_name,
2700
14
      { "Device Name", "sick_cola.scan_data.device_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2701
14
    { &hf_sick_cola_scan_data_comment_present,
2702
14
      { "Comment Present", "sick_cola.scan_data.comment_present", FT_UINT16, BASE_DEC, VALS(sick_cola_comment_present_vals), 0x0, NULL, HFILL } },
2703
14
    { &hf_sick_cola_scan_data_comment,
2704
14
      { "Comment", "sick_cola.scan_data.comment", FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2705
14
    { &hf_sick_cola_scan_data_time_present,
2706
14
      { "Time Present", "sick_cola.scan_data.time_present", FT_UINT16, BASE_DEC, VALS(sick_cola_time_present_vals), 0x0, NULL, HFILL } },
2707
14
    { &hf_sick_cola_scan_data_time,
2708
14
      { "Time", "sick_cola.scan_data.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
2709
14
    { &hf_sick_cola_scan_data_display_event_info,
2710
14
      { "Display Event Information", "sick_cola.scan_data.display_event_info", FT_UINT16, BASE_DEC, VALS(sick_cola_display_event_info_vals), 0x0, NULL, HFILL } },
2711
14
    { &hf_sick_cola_scan_data_event_info_type,
2712
14
      { "Type", "sick_cola.scan_data.event_info.type", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2713
14
    { &hf_sick_cola_scan_data_event_info_encoder_position,
2714
14
      { "Encoder Position", "sick_cola.scan_data.event_info.encoder_position", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2715
14
    { &hf_sick_cola_scan_data_event_info_encosder_timestamp,
2716
14
      { "Timestamp", "sick_cola.scan_data.event_info.timestamp", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, NULL, HFILL } },
2717
14
    { &hf_sick_cola_scan_data_event_info_encoder_angle,
2718
14
      { "Encoder Angle", "sick_cola.scan_data.event_info.encoder_angle", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2719
14
    { &hf_sick_cola_set_date_time,
2720
14
      { "Set timestamp", "sick_cola.set_date_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
2721
14
    { &hf_sick_cola_set_date_time_status_code,
2722
14
      { "Status code", "sick_cola.set_date_time.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2723
14
    { &hf_sick_cola_stims_status_code,
2724
14
      { "Status code", "sick_cola.stims.status_code", FT_UINT16, BASE_DEC, VALS(stims_status_vals), 0x0, NULL, HFILL } },
2725
14
    { &hf_sick_cola_stims_temp_out_of_range,
2726
14
      { "Temperature out of range", "sick_cola.stims.temp_out_of_range", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2727
14
    { &hf_sick_cola_stims_time_length,
2728
14
      { "Time length", "sick_cola.stims.time_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2729
14
    { &hf_sick_cola_stims_time,
2730
14
      { "Time", "sick_cola.stims.time", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2731
14
    { &hf_sick_cola_stims_date_length,
2732
14
      { "Date length", "sick_cola.stims.date_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2733
14
    { &hf_sick_cola_stims_date,
2734
14
      { "Date", "sick_cola.stims.date", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2735
14
    { &hf_sick_cola_stims_led1,
2736
14
      { "LED1", "sick_cola.stims.led1", FT_UINT16, BASE_DEC, VALS(sick_cola_led_vals), 0x0, NULL, HFILL } },
2737
14
    { &hf_sick_cola_stims_led2,
2738
14
      { "LED2", "sick_cola.stims.led2", FT_UINT16, BASE_DEC, VALS(sick_cola_led_vals), 0x0, NULL, HFILL } },
2739
14
    { &hf_sick_cola_stims_led3,
2740
14
      { "LED3", "sick_cola.stims.led3", FT_UINT16, BASE_DEC, VALS(sick_cola_led_vals), 0x0, NULL, HFILL } },
2741
14
    { &hf_sick_cola_stims_reserved,
2742
14
      { "Reserved", "sick_cola.stims.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2743
14
    { &hf_sick_cola_device_time,
2744
14
      { "Device time", "sick_cola.device_time", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2745
14
    { &hf_sick_cola_ntp_tsc_role,
2746
14
      { "TSC Role", "sick_cola.ntp.tsc_role", FT_UINT8, BASE_DEC, VALS(ntp_tsc_role_vals), 0x0, NULL, HFILL } },
2747
14
    { &hf_sick_cola_ntp_interface_data,
2748
14
      { "Timesync interface", "sick_cola.ntp.interface_data", FT_UINT8, BASE_DEC, VALS(ntp_interface_data_vals), 0x0, NULL, HFILL } },
2749
14
    { &hf_sick_cola_ntp_ipaddress,
2750
14
      { "NTP IP address", "sick_cola.ntp.ipaddress", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2751
14
    { &hf_sick_cola_ntp_gmt_timezone_offset,
2752
14
      { "GMT Timezone offset", "sick_cola.ntp.gmt_timezone_offset", FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2753
14
    { &hf_sick_cola_ntp_timesync,
2754
14
      { "Timesync", "sick_cola.ntp.timesync", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL } },
2755
14
    { &hf_sick_cola_ntp_max_offset_time,
2756
14
      { "Max offset Time", "sick_cola.ntp.max_offset_time", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2757
14
    { &hf_sick_cola_particle_filter_status,
2758
14
      { "Status code", "sick_cola.particle_filter.status", FT_BOOLEAN, BASE_NONE, TFS(&tfs_active_inactive), 0x0, NULL, HFILL } },
2759
14
    { &hf_sick_cola_particle_filter_threshold,
2760
14
      { "Filter Threshold", "sick_cola.particle_filter.threshold", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2761
14
    { &hf_sick_cola_mean_filter_status,
2762
14
      { "Status code", "sick_cola.mean_filter.status", FT_BOOLEAN, BASE_NONE, TFS(&tfs_active_inactive), 0x0, NULL, HFILL } },
2763
14
    { &hf_sick_cola_mean_filter_num_scans,
2764
14
      { "Number of scans", "sick_cola.mean_filter.num_scans", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2765
14
    { &hf_sick_cola_mean_filter_final_part,
2766
14
      { "Final part", "sick_cola.mean_filter.final_part", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2767
14
    { &hf_sick_cola_nto1_filter_status,
2768
14
      { "Status code", "sick_cola.nto1_filter.status", FT_BOOLEAN, BASE_NONE, TFS(&tfs_active_inactive), 0x0, NULL, HFILL } },
2769
14
    { &hf_sick_cola_echo_filter_status,
2770
14
      { "Status code", "sick_cola.echo_filter.status", FT_UINT8, BASE_DEC, VALS(echo_filter_status_vals), 0x0, NULL, HFILL } },
2771
14
    { &hf_sick_cola_fog_filter_status,
2772
14
      { "Status code", "sick_cola.fog_filter.status", FT_UINT8, BASE_DEC, VALS(fog_filter_status_vals), 0x0, NULL, HFILL } },
2773
14
    { &hf_sick_cola_fog_filter_enable,
2774
14
      { "Enable", "sick_cola.fog_filter.enable", FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x0, NULL, HFILL } },
2775
14
    { &hf_sick_cola_fog_filter_sensitivity_level,
2776
14
      { "Sensitivity Level", "sick_cola.fog_filter.sensitivity_level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2777
14
    { &hf_sick_cola_digital_nearfield_filter_status,
2778
14
      { "Status code", "sick_cola.digital_nearfield_filter.status", FT_UINT8, BASE_DEC, VALS(fog_filter_status_vals), 0x0, NULL, HFILL } },
2779
14
    { &hf_sick_cola_digital_nearfield_filter_active_sector_vector,
2780
14
      { "Active sector vector", "sick_cola.digital_nearfield_filter.active_sector_vector", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2781
14
    { &hf_sick_cola_encoder_increment_source,
2782
14
      { "Increment Source", "sick_cola.encoder.increment_source", FT_UINT8, BASE_DEC, VALS(encoder_increment_source_vals), 0x0, NULL, HFILL } },
2783
14
    { &hf_sick_cola_encoder_setting,
2784
14
      { "Encoder Setting", "sick_cola.encoder.setting", FT_UINT8, BASE_DEC, VALS(encoder_setting_vals), 0x0, NULL, HFILL } },
2785
14
    { &hf_sick_cola_encoder_resolution,
2786
14
      { "Encoder resolution", "sick_cola.encoder.resolution", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2787
14
    { &hf_sick_cola_encoder_fixed_speed,
2788
14
      { "Fixed speed", "sick_cola.encoder.fixed_speed", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2789
14
    { &hf_sick_cola_encoder_speed_threshold,
2790
14
      { "Speed Threshold", "sick_cola.encoder.speed_threshold", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL } },
2791
14
    { &hf_sick_cola_encoder_speed,
2792
14
      { "Encoder Speed", "sick_cola.encoder.speed", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_m_s), 0x0, NULL, HFILL } },
2793
14
    { &hf_sick_cola_output_state_start_stop,
2794
14
      { "Start/Stop", "sick_cola.output_state.start_stop", FT_UINT8, BASE_DEC, VALS(sick_cola_stop_start_vals), 0x0, NULL, HFILL } },
2795
14
    { &hf_sick_cola_output_state_status_version,
2796
14
      { "Number of scans", "sick_cola.output_state.status.version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2797
14
    { &hf_sick_cola_output_state_status_system_counter,
2798
14
      { "Number of scans", "sick_cola.output_state.status.system_counter", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, NULL, HFILL } },
2799
14
    { &hf_sick_cola_output_state_state,
2800
14
      { "State", "sick_cola.output_state.state", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2801
14
    { &hf_sick_cola_output_state_count,
2802
14
      { "Count", "sick_cola.output_state.count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2803
14
    { &hf_sick_cola_output_state_ext_state,
2804
14
      { "State", "sick_cola.output_state.ext_state", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2805
14
    { &hf_sick_cola_output_state_ext_count,
2806
14
      { "Count", "sick_cola.output_state.ext_count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2807
14
    { &hf_sick_cola_output_state_time_present,
2808
14
      { "Time Present", "sick_cola.output_state.time_present", FT_UINT16, BASE_DEC, VALS(sick_cola_time_present_vals), 0x0, NULL, HFILL } },
2809
14
    { &hf_sick_cola_output_state_time,
2810
14
      { "Time", "sick_cola.output_state.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
2811
14
    { &hf_sick_cola_set_output_state_number,
2812
14
      { "Output number", "sick_cola.set_output_state.number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2813
14
    { &hf_sick_cola_set_output_state_state,
2814
14
      { "Output state", "sick_cola.set_output_state.state", FT_BOOLEAN, BASE_NONE, TFS(&tfs_active_inactive), 0x0, NULL, HFILL } },
2815
14
    { &hf_sick_cola_set_output_state_status_code,
2816
14
      { "Status code", "sick_cola.set_output_state.status_code", FT_UINT8, BASE_DEC, VALS(sick_cola_return_vals), 0x0, NULL, HFILL } },
2817
14
    { &hf_sick_cola_output_do3_func,
2818
14
      { "Output state", "sick_cola.output.do3_func", FT_UINT8, BASE_DEC, VALS(sick_cola_do3_func_vals), 0x0, NULL, HFILL } },
2819
14
    { &hf_sick_cola_output_do1_func,
2820
14
      { "Output 1 function", "sick_cola.output.do1_func", FT_UINT8, BASE_DEC, VALS(sick_cola_do1_func_vals), 0x0, NULL, HFILL } },
2821
14
    { &hf_sick_cola_output_do1_logic,
2822
14
      { "Output 1 Logic State", "sick_cola.output.do1_logic", FT_UINT32, BASE_DEC, VALS(sick_cola_logic_state_vals), 0x0, NULL, HFILL } },
2823
14
    { &hf_sick_cola_output_do2_func,
2824
14
      { "Output 2 function", "sick_cola.output.do2_func", FT_UINT8, BASE_DEC, VALS(sick_cola_do2_func_vals), 0x0, NULL, HFILL } },
2825
14
    { &hf_sick_cola_output_do2_logic,
2826
14
      { "Output 2 Logic State", "sick_cola.output.do2_logic", FT_UINT32, BASE_DEC, VALS(sick_cola_logic_state_vals), 0x0, NULL, HFILL } },
2827
14
    { &hf_sick_cola_output_sync_mode_data,
2828
14
      { "Sync mode data", "sick_cola.output.sync_mode_data", FT_UINT8, BASE_DEC, VALS(sick_cola_sync_mode_data_vals), 0x0, NULL, HFILL } },
2829
14
    { &hf_sick_cola_output_sync_phase_data,
2830
14
      { "Sync phase data", "sick_cola.output.sync_phase_data", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2831
14
    { &hf_sick_cola_input_do3and4_func,
2832
14
      { "Input state", "sick_cola.input.do3and4_func", FT_UINT8, BASE_DEC, VALS(sick_cola_do3and4_func_vals), 0x0, NULL, HFILL } },
2833
14
    { &hf_sick_cola_input_debounce_time_data,
2834
14
      { "Debounce time data", "sick_cola.input.debounce_time_data", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
2835
14
    { &hf_sick_cola_input_sync_status_data,
2836
14
      { "Sync Status data", "sick_cola.input.sync_status_data", FT_UINT8, BASE_DEC, VALS(sick_cola_sync_status_vals), 0x0, NULL, HFILL } },
2837
14
    { &hf_sick_cola_input_signal_frequency,
2838
14
      { "Signal frequency", "sick_cola.input.signal_frequency", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2839
14
    { &hf_sick_cola_b_sopas_command,
2840
14
      { "SICK Command", "sick_cola.binary.sick_command", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2841
14
    { &hf_sick_cola_b_sopas_command_data,
2842
14
      { "Command Data", "sick_cola.binary.sick_command_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2843
14
    { &hf_sick_cola_a_sopas_command,
2844
14
      { "SICK Command", "sick_cola.ascii.sick_command", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2845
14
    { &hf_sick_cola_a_sopas_command_data,
2846
14
      { "Command Data", "sick_cola.ascii.sick_command_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2847
14
    { &hf_sick_cola_sopas_error_code,
2848
14
      { "Error code", "sick_cola.sopas_error_code", FT_UINT32, BASE_DEC, VALS(sick_cola_sopas_error_vals), 0x0, NULL, HFILL } },
2849
14
  };
2850
2851
14
  static int *ett[] = {
2852
14
    &ett_sick_cola_a,
2853
14
    &ett_sick_cola_b,
2854
14
    &ett_scan_data_device,
2855
14
    &ett_scan_data_status_info,
2856
14
    &ett_scan_data_frequency,
2857
14
    &ett_scan_data_16bit_output_channels,
2858
14
    &ett_scan_data_16bit_output_channel,
2859
14
    &ett_scan_data_16bit_output_data,
2860
14
    &ett_scan_data_8bit_output_channels,
2861
14
    &ett_scan_data_8bit_output_channel,
2862
14
    &ett_scan_data_8bit_output_data,
2863
14
    &ett_scan_data_position,
2864
14
    &ett_scan_data_time,
2865
14
    &ett_scan_data_event_info,
2866
14
    &ett_output_state_status,
2867
14
    &ett_output_state,
2868
14
    &ett_output_state_x,
2869
14
    &ett_ext_output_state,
2870
14
    &ett_ext_output_state_x,
2871
14
    &ett_output_state_time,
2872
14
  };
2873
2874
14
  static ei_register_info ei[] = {
2875
14
    { &ei_sick_cola_command, { "sick_cola.command.unknown", PI_PROTOCOL, PI_WARN, "Unknown command", EXPFILL }},
2876
14
    { &ei_sick_cola_command_name, { "sick_cola.command.name.missing", PI_MALFORMED, PI_ERROR, "Command name missing", EXPFILL }},
2877
14
    { &ei_sick_cola_command_parameter, { "sick_cola.command.parameter.error", PI_MALFORMED, PI_ERROR, "Command parameter parse error", EXPFILL }},
2878
14
    { &ei_sick_cola_b_checksum, { "sick_cola.binary.checksum.incorrect", PI_PROTOCOL, PI_WARN, "Checksum incorrect", EXPFILL }},
2879
14
  };
2880
2881
14
  proto_sick_cola_a = proto_register_protocol("SICK CoLA A", "CoLA A", "sick_cola.ascii");
2882
14
  proto_sick_cola_b = proto_register_protocol("SICK CoLA B", "CoLA B", "sick_cola.binary");
2883
2884
14
  proto_register_field_array(proto_sick_cola_a, hf, array_length(hf));
2885
14
  proto_register_subtree_array(ett, array_length(ett));
2886
14
  expert_sick_cola = expert_register_protocol(proto_sick_cola_a);
2887
14
  expert_register_field_array(expert_sick_cola, ei, array_length(ei));
2888
2889
14
}
2890
2891
void
2892
proto_reg_handoff_sick_cola(void)
2893
14
{
2894
14
  dissector_handle_t cola_a_handle, cola_b_handle;
2895
2896
14
  cola_a_handle = create_dissector_handle(dissect_sick_cola_a, proto_sick_cola_a);
2897
14
  dissector_add_for_decode_as("tcp.port", cola_a_handle);
2898
14
  cola_b_handle = create_dissector_handle(dissect_sick_cola_b, proto_sick_cola_b);
2899
14
  dissector_add_for_decode_as("tcp.port", cola_b_handle);
2900
2901
14
  heur_dissector_add("tcp", dissect_sick_cola_b_heur, "SICK CoLa B over TCP", "sick_cola_b_tcp", proto_sick_cola_b, HEURISTIC_ENABLE);
2902
14
  heur_dissector_add("tcp", dissect_sick_cola_a_heur, "SICK CoLa A over TCP", "sick_cola_a_tcp", proto_sick_cola_a, HEURISTIC_ENABLE);
2903
2904
14
}
2905
2906
/*
2907
* Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2908
*
2909
* Local variables:
2910
* c-basic-offset: 4
2911
* tab-width: 8
2912
* indent-tabs-mode: t
2913
* End:
2914
*
2915
* vi: set shiftwidth=4 tabstop=8 expandtab:
2916
* :indentSize=4:tabSize=8:noTabs=false:
2917
*/