HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / plugins / epan / gryphon / packet-gryphon.c
1 /* packet-gryphon.c
2  *
3  * Updated routines for Gryphon protocol packet dissection
4  * By Mark C. <markc@dgtech.com>
5  * Copyright (C) 2018 DG Technologies, Inc. (Dearborn Group, Inc.) USA
6  *
7  * Routines for Gryphon protocol packet disassembly
8  * By Steve Limkemann <stevelim@dgtech.com>
9  * Copyright 1998 Steve Limkemann
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * SPDX-License-Identifier: GPL-2.0-or-later
16  */
17
18 #include "config.h"
19
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
22 #include <epan/dissectors/packet-tcp.h>
23 #include "packet-gryphon.h"
24
25 /*
26  * See
27  *
28  *     http://www.dgtech.com/gryphon/sys/www/docs/html/
29  */
30
31 void proto_register_gryphon(void);
32 void proto_reg_handoff_gryphon(void);
33
34 #define GRYPHON_TCP_PORT 7000 /* Not IANA registed */
35
36 static int proto_gryphon = -1;
37
38 static int hf_gryphon_src = -1;
39 static int hf_gryphon_srcchan = -1;
40 static int hf_gryphon_srcchanclient = -1;
41 static int hf_gryphon_dest = -1;
42 static int hf_gryphon_destchan = -1;
43 static int hf_gryphon_destchanclient = -1;
44 static int hf_gryphon_type = -1;
45 static int hf_gryphon_cmd = -1;
46 static int hf_gryphon_cmd_context = -1;
47 static int hf_gryphon_data = -1;
48 static int hf_gryphon_data_length = -1;
49 static int hf_gryphon_reserved = -1;
50 static int hf_gryphon_padding = -1;
51 static int hf_gryphon_ignored = -1;
52 static int hf_gryphon_wait_flags = -1;
53 static int hf_gryphon_wait_resp = -1;
54 static int hf_gryphon_wait_prev_resp = -1;
55 static int hf_gryphon_status = -1;
56 static int hf_gryphon_data_header_length = -1;
57 static int hf_gryphon_data_header_length_bits = -1;
58 static int hf_gryphon_data_data_length = -1;
59 static int hf_gryphon_data_extra_data_length = -1;
60 static int hf_gryphon_data_mode = -1;
61 static int hf_gryphon_data_mode_transmitted = -1;
62 static int hf_gryphon_data_mode_receive = -1;
63 static int hf_gryphon_data_mode_local = -1;
64 static int hf_gryphon_data_mode_remote = -1;
65 static int hf_gryphon_data_mode_oneshot = -1;
66 static int hf_gryphon_data_mode_combined = -1;
67 static int hf_gryphon_data_mode_nomux = -1;
68 static int hf_gryphon_data_mode_internal = -1;
69 static int hf_gryphon_data_priority = -1;
70 static int hf_gryphon_data_error_status = -1;
71 static int hf_gryphon_data_time = -1;
72 static int hf_gryphon_data_context = -1;
73 static int hf_gryphon_data_header_data = -1;
74 static int hf_gryphon_data_data = -1;
75 static int hf_gryphon_data_extra_data = -1;
76 static int hf_gryphon_data_padding = -1;
77 static int hf_gryphon_event_id = -1;
78 static int hf_gryphon_event_context = -1;
79 static int hf_gryphon_event_time = -1;
80 static int hf_gryphon_event_data = -1;
81 static int hf_gryphon_event_padding = -1;
82 static int hf_gryphon_misc_text = -1;
83 static int hf_gryphon_misc_padding = -1;
84 static int hf_gryphon_eventnum = -1;
85 static int hf_gryphon_resp_time = -1;
86 static int hf_gryphon_setfilt = -1;
87 static int hf_gryphon_setfilt_length = -1;
88 static int hf_gryphon_setfilt_discard_data = -1;
89 static int hf_gryphon_setfilt_padding = -1;
90 static int hf_gryphon_ioctl = -1;
91 static int hf_gryphon_ioctl_nbytes = -1;
92 static int hf_gryphon_ioctl_data = -1;
93 static int hf_gryphon_addfilt_pass = -1;
94 static int hf_gryphon_addfilt_active = -1;
95 static int hf_gryphon_addfilt_blocks = -1;
96 static int hf_gryphon_addfilt_handle = -1;
97 static int hf_gryphon_modfilt = -1;
98 static int hf_gryphon_modfilt_action = -1;
99 static int hf_gryphon_filthan = -1;
100 static int hf_gryphon_filthan_id = -1;
101 static int hf_gryphon_filthan_padding = -1;
102 static int hf_gryphon_dfiltmode = -1;
103 static int hf_gryphon_filtmode = -1;
104 static int hf_gryphon_event_name = -1;
105 static int hf_gryphon_register_username = -1;
106 static int hf_gryphon_register_password = -1;
107 static int hf_gryphon_register_client_id = -1;
108 static int hf_gryphon_register_privileges = -1;
109 static int hf_gryphon_getspeeds_set_ioctl = -1;
110 static int hf_gryphon_getspeeds_get_ioctl = -1;
111 static int hf_gryphon_getspeeds_size = -1;
112 static int hf_gryphon_getspeeds_preset = -1;
113 static int hf_gryphon_getspeeds_data = -1;
114 static int hf_gryphon_cmd_sort = -1;
115 static int hf_gryphon_cmd_optimize = -1;
116 static int hf_gryphon_config_device_name = -1;
117 static int hf_gryphon_config_device_version = -1;
118 static int hf_gryphon_config_device_serial_number = -1;
119 static int hf_gryphon_config_num_channels = -1;
120 static int hf_gryphon_config_name_version_ext = -1;
121 static int hf_gryphon_config_driver_name = -1;
122 static int hf_gryphon_config_driver_version = -1;
123 static int hf_gryphon_config_device_security = -1;
124 static int hf_gryphon_config_max_data_length = -1;
125 static int hf_gryphon_config_min_data_length = -1;
126 static int hf_gryphon_config_hardware_serial_number = -1;
127 static int hf_gryphon_config_protocol_type = -1;
128 static int hf_gryphon_config_channel_id = -1;
129 static int hf_gryphon_config_card_slot_number = -1;
130 static int hf_gryphon_config_max_extra_data = -1;
131 static int hf_gryphon_config_min_extra_data = -1;
132 static int hf_gryphon_sched_num_iterations = -1;
133 static int hf_gryphon_sched_flags = -1;
134 static int hf_gryphon_sched_flags_scheduler = -1;
135 static int hf_gryphon_sched_sleep = -1;
136 static int hf_gryphon_sched_transmit_count = -1;
137 static int hf_gryphon_sched_transmit_period = -1;
138 static int hf_gryphon_sched_transmit_flags = -1;
139 static int hf_gryphon_sched_skip_transmit_period = -1;
140 static int hf_gryphon_sched_skip_sleep = -1;
141 static int hf_gryphon_sched_channel = -1;
142 static int hf_gryphon_sched_channel0 = -1;
143 static int hf_gryphon_sched_rep_id = -1;
144 static int hf_gryphon_sched_rep_message_index = -1;
145 static int hf_gryphon_blm_data_time = -1;
146 static int hf_gryphon_blm_data_bus_load = -1;
147 static int hf_gryphon_blm_data_current_bus_load = -1;
148 static int hf_gryphon_blm_data_peak_bus_load = -1;
149 static int hf_gryphon_blm_data_historic_peak_bus_load = -1;
150 static int hf_gryphon_blm_stat_receive_frame_count = -1;
151 static int hf_gryphon_blm_stat_transmit_frame_count = -1;
152 static int hf_gryphon_blm_stat_receive_dropped_frame_count = -1;
153 static int hf_gryphon_blm_stat_transmit_dropped_frame_count = -1;
154 static int hf_gryphon_blm_stat_receive_error_count = -1;
155 static int hf_gryphon_blm_stat_transmit_error_count = -1;
156 static int hf_gryphon_addresp_flags = -1;
157 static int hf_gryphon_addresp_flags_active = -1;
158 static int hf_gryphon_addresp_blocks = -1;
159 static int hf_gryphon_addresp_responses = -1;
160 static int hf_gryphon_addresp_old_handle = -1;
161 static int hf_gryphon_addresp_action = -1;
162 static int hf_gryphon_addresp_action_period = -1;
163 static int hf_gryphon_addresp_action_deact_on_event = -1;
164 static int hf_gryphon_addresp_action_deact_after_period = -1;
165 static int hf_gryphon_addresp_action_period_type = -1;
166 static int hf_gryphon_addresp_handle = -1;
167 static int hf_gryphon_ldf_list = -1;
168 static int hf_gryphon_ldf_number = -1;
169 static int hf_gryphon_ldf_nodenumber = -1;
170 static int hf_gryphon_ldf_remaining = -1;
171 static int hf_gryphon_ldf_name = -1;
172 static int hf_gryphon_ldf_info_pv = -1;
173 static int hf_gryphon_ldf_info_lv = -1;
174 static int hf_gryphon_ldf_ui = -1;
175 static int hf_gryphon_lin_nodename = -1;
176 static int hf_gryphon_lin_data_length = -1;
177 static int hf_gryphon_lin_slave_table_enable = -1;
178 static int hf_gryphon_lin_slave_table_cs = -1;
179 static int hf_gryphon_lin_slave_table_data = -1;
180 static int hf_gryphon_lin_slave_table_datacs = -1;
181 static int hf_gryphon_lin_masterevent = -1;
182 static int hf_gryphon_lin_numdata = -1;
183 static int hf_gryphon_lin_numextra = -1;
184 static int hf_gryphon_ldf_description = -1;
185 static int hf_gryphon_ldf_size = -1;
186 static int hf_gryphon_ldf_exists = -1;
187 static int hf_gryphon_ldf_blockn = -1;
188 static int hf_gryphon_ldf_file = -1;
189 static int hf_gryphon_ldf_desc_pad = -1;
190 static int hf_gryphon_ldf_restore_session = -1;
191 static int hf_gryphon_ldf_schedule_name = -1;
192 static int hf_gryphon_ldf_schedule_msg_dbytes = -1;
193 static int hf_gryphon_ldf_schedule_flags = -1;
194 static int hf_gryphon_ldf_schedule_event = -1;
195 static int hf_gryphon_ldf_schedule_sporadic = -1;
196 static int hf_gryphon_ldf_ioctl_setflags = -1;
197 static int hf_gryphon_ldf_numb_ids = -1;
198 static int hf_gryphon_ldf_bitrate = -1;
199 static int hf_gryphon_ldf_ioctl_setflags_flags = -1;
200 static int hf_gryphon_ldf_sched_size_place = -1;
201 static int hf_gryphon_ldf_sched_numb_place = -1;
202 static int hf_gryphon_ldf_sched_size = -1;
203 static int hf_gryphon_ldf_num_node_names = -1;
204 static int hf_gryphon_ldf_num_frames = -1;
205 static int hf_gryphon_ldf_num_signal_names = -1;
206 static int hf_gryphon_ldf_num_schedules = -1;
207 static int hf_gryphon_ldf_num_encodings = -1;
208 static int hf_gryphon_ldf_encoding_value = -1;
209 static int hf_gryphon_ldf_encoding_min = -1;
210 static int hf_gryphon_ldf_encoding_max = -1;
211 static int hf_gryphon_ldf_master_node_name = -1;
212 static int hf_gryphon_ldf_slave_node_name = -1;
213 static int hf_gryphon_ldf_node_name = -1;
214 static int hf_gryphon_ldf_signal_name = -1;
215 static int hf_gryphon_ldf_signal_encoding_name = -1;
216 static int hf_gryphon_ldf_signal_encoding_type = -1;
217 static int hf_gryphon_ldf_signal_encoding_logical = -1;
218 static int hf_gryphon_ldf_signal_offset = -1;
219 static int hf_gryphon_ldf_signal_length = -1;
220 static int hf_gryphon_ldf_get_frame = -1;
221 static int hf_gryphon_ldf_get_frame_num = -1;
222 static int hf_gryphon_ldf_get_frame_pub = -1;
223 static int hf_gryphon_ldf_get_frame_num_signals = -1;
224 static int hf_gryphon_cnvt_valuef = -1;
225 static int hf_gryphon_cnvt_valuei = -1;
226 static int hf_gryphon_cnvt_values = -1;
227 static int hf_gryphon_cnvt_units = -1;
228 static int hf_gryphon_cnvt_flags_getvalues = -1;
229 static int hf_gryphon_dd_stream = -1;
230 static int hf_gryphon_dd_value = -1;
231 static int hf_gryphon_dd_time = -1;
232 static int hf_gryphon_modresp_handle = -1;
233 static int hf_gryphon_modresp_action = -1;
234 static int hf_gryphon_num_resphan = -1;
235 static int hf_gryphon_handle = -1;
236 static int hf_gryphon_transmit_sched_id = -1;
237 static int hf_gryphon_desc_program_size = -1;
238 static int hf_gryphon_desc_program_name = -1;
239 static int hf_gryphon_desc_program_description = -1;
240 static int hf_gryphon_desc_flags = -1;
241 static int hf_gryphon_desc_flags_program = -1;
242 static int hf_gryphon_desc_handle = -1;
243 static int hf_gryphon_upload_block_number = -1;
244 static int hf_gryphon_upload_handle = -1;
245 static int hf_gryphon_upload_data = -1;
246 static int hf_gryphon_delete = -1;
247 static int hf_gryphon_list_block_number = -1;
248 static int hf_gryphon_list_num_programs = -1;
249 static int hf_gryphon_list_num_remain_programs = -1;
250 static int hf_gryphon_list_name = -1;
251 static int hf_gryphon_list_description = -1;
252 static int hf_gryphon_start_arguments = -1;
253 static int hf_gryphon_start_channel = -1;
254 static int hf_gryphon_status_num_running_copies = -1;
255 static int hf_gryphon_options_handle = -1;
256 static int hf_gryphon_files = -1;
257 static int hf_gryphon_usdt_flags_register = -1;
258 static int hf_gryphon_usdt_action_flags = -1;
259 static int hf_gryphon_usdt_action_flags_non_legacy = -1;
260 static int hf_gryphon_usdt_action_flags_register = -1;
261 static int hf_gryphon_usdt_action_flags_action = -1;
262 static int hf_gryphon_usdt_transmit_options_flags = -1;
263 static int hf_gryphon_usdt_transmit_options_flags_echo = -1;
264 static int hf_gryphon_usdt_transmit_options_done_event = -1;
265 static int hf_gryphon_usdt_transmit_options_echo_short = -1;
266 static int hf_gryphon_usdt_transmit_options_rx_nth_fc = -1;
267 static int hf_gryphon_usdt_transmit_options_action = -1;
268 static int hf_gryphon_usdt_transmit_options_send_done = -1;
269 static int hf_gryphon_usdt_receive_options_flags = -1;
270 static int hf_gryphon_usdt_receive_options_action = -1;
271 static int hf_gryphon_usdt_receive_options_firstframe_event = -1;
272 static int hf_gryphon_usdt_receive_options_lastframe_event = -1;
273 static int hf_gryphon_usdt_receive_options_tx_nth_fc = -1;
274 static int hf_gryphon_usdt_length_options_flags = -1;
275 static int hf_gryphon_usdt_length_control_j1939 = -1;
276 static int hf_gryphon_usdt_stmin_fc = -1;
277 static int hf_gryphon_usdt_bsmax_fc = -1;
278 static int hf_gryphon_usdt_stmin_override = -1;
279 static int hf_gryphon_usdt_stmin_override_active = -1;
280 static int hf_gryphon_usdt_stmin_override_activate = -1;
281 static int hf_gryphon_usdt_set_stmin_mul = -1;
282 static int hf_gryphon_usdt_receive_options_firstframe = -1;
283 static int hf_gryphon_usdt_receive_options_lastframe = -1;
284 static int hf_gryphon_usdt_ext_address = -1;
285 static int hf_gryphon_usdt_ext_address_id = -1;
286 static int hf_gryphon_usdt_block_size = -1;
287 static int hf_gryphon_bits_in_input1 = -1;
288 static int hf_gryphon_bits_in_input2 = -1;
289 static int hf_gryphon_bits_in_input3 = -1;
290 static int hf_gryphon_bits_in_pushbutton = -1;
291 static int hf_gryphon_bits_out_output1 = -1;
292 static int hf_gryphon_bits_out_output2 = -1;
293 static int hf_gryphon_init_strat_reset_limit = -1;
294 static int hf_gryphon_init_strat_delay = -1;
295 static int hf_gryphon_speed_baud_rate_index = -1;
296 static int hf_gryphon_filter_block_filter_start = -1;
297 static int hf_gryphon_filter_block_filter_length = -1;
298 static int hf_gryphon_filter_block_filter_type = -1;
299 static int hf_gryphon_filter_block_filter_operator = -1;
300 static int hf_gryphon_filter_block_filter_value1 = -1;
301 static int hf_gryphon_filter_block_filter_value2 = -1;
302 static int hf_gryphon_filter_block_filter_value4 = -1;
303 static int hf_gryphon_filter_block_filter_value_bytes = -1;
304 static int hf_gryphon_blm_mode = -1;
305 static int hf_gryphon_blm_mode_avg_period = -1;
306 static int hf_gryphon_blm_mode_avg_frames = -1;
307 static int hf_gryphon_command = -1;
308 static int hf_gryphon_cmd_mode = -1;
309 static int hf_gryphon_option = -1;
310 static int hf_gryphon_option_data = -1;
311 static int hf_gryphon_cmd_file = -1;
312 static int hf_gryphon_bit_in_digital_data = -1;
313 static int hf_gryphon_bit_out_digital_data = -1;
314 static int hf_gryphon_filter_block_pattern = -1;
315 static int hf_gryphon_filter_block_mask = -1;
316 static int hf_gryphon_usdt_request = -1;
317 static int hf_gryphon_usdt_request_ext = -1;
318 static int hf_gryphon_usdt_nids = -1;
319 static int hf_gryphon_usdt_response = -1;
320 static int hf_gryphon_usdt_response_ext = -1;
321 static int hf_gryphon_uudt_response = -1;
322 static int hf_gryphon_uudt_response_ext = -1;
323 static int hf_gryphon_more_filenames = -1;
324 static int hf_gryphon_filenames = -1;
325 static int hf_gryphon_program_channel_number = -1;
326 static int hf_gryphon_valid_header_length = -1;
327
328 static gint ett_gryphon = -1;
329 static gint ett_gryphon_header = -1;
330 static gint ett_gryphon_body = -1;
331 static gint ett_gryphon_command_data = -1;
332 static gint ett_gryphon_response_data = -1;
333 static gint ett_gryphon_data_header = -1;
334 static gint ett_gryphon_flags = -1;
335 static gint ett_gryphon_data_body = -1;
336 static gint ett_gryphon_cmd_filter_block = -1;
337 static gint ett_gryphon_cmd_events_data = -1;
338 static gint ett_gryphon_cmd_config_device = -1;
339 static gint ett_gryphon_cmd_sched_data = -1;
340 static gint ett_gryphon_cmd_sched_cmd = -1;
341 static gint ett_gryphon_cmd_response_block = -1;
342 static gint ett_gryphon_pgm_list = -1;
343 static gint ett_gryphon_pgm_status = -1;
344 static gint ett_gryphon_pgm_options = -1;
345 static gint ett_gryphon_valid_headers = -1;
346 static gint ett_gryphon_usdt_data = -1;
347 static gint ett_gryphon_usdt_action_flags = -1;
348 static gint ett_gryphon_usdt_tx_options_flags = -1;
349 static gint ett_gryphon_usdt_rx_options_flags = -1;
350 static gint ett_gryphon_usdt_len_options_flags = -1;
351 static gint ett_gryphon_usdt_data_block = -1;
352 static gint ett_gryphon_lin_emulate_node = -1;
353 static gint ett_gryphon_ldf_block = -1;
354 static gint ett_gryphon_ldf_schedule_name = -1;
355 static gint ett_gryphon_lin_schedule_msg = -1;
356 static gint ett_gryphon_cnvt_getflags = -1;
357 static gint ett_gryphon_digital_data = -1;
358 static gint ett_gryphon_blm_mode = -1;
359
360 /* desegmentation of Gryphon */
361 static gboolean gryphon_desegment = TRUE;
362
363 static int is_special_client(guint32);
364 static int dissect_gryphon_message_with_offset(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean is_msgresp_add);
365 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
366     proto_tree *tree, gboolean is_msgresp_add);
367 static int decode_command(tvbuff_t*, int, int, int, proto_tree*);
368 static int decode_response(tvbuff_t*, int, int, proto_tree*);
369 static int decode_data(tvbuff_t*, int, proto_tree*);
370 static int decode_event(tvbuff_t*, int, proto_tree*);
371 static int decode_misc(tvbuff_t*, int, proto_tree*);
372 static int decode_text(tvbuff_t*, int, int, proto_tree*);
373 static int cmd_init(tvbuff_t*, int, proto_tree*);
374 static int resp_time(tvbuff_t*, int, proto_tree*);
375 static int cmd_setfilt(tvbuff_t*, int, proto_tree*);
376 static int cmd_ioctl(tvbuff_t*, int, proto_tree*, guint32 ui_command);
377 static int cmd_ioctl_resp(tvbuff_t*, int, proto_tree*, guint32 ui_command);
378 static int cmd_addfilt(tvbuff_t*, int, proto_tree*);
379 static int resp_addfilt(tvbuff_t*, int, proto_tree*);
380 static int cmd_modfilt(tvbuff_t*, int, proto_tree*);
381 static int resp_filthan(tvbuff_t*, int, proto_tree*);
382 static int dfiltmode(tvbuff_t*, int, proto_tree*);
383 static int filtmode(tvbuff_t*, int, proto_tree*);
384 static int resp_events(tvbuff_t*, int, proto_tree*);
385 static int cmd_register(tvbuff_t*, int, proto_tree*);
386 static int resp_register(tvbuff_t*, int, proto_tree*);
387 static int resp_getspeeds(tvbuff_t*, int, proto_tree*);
388 static int cmd_sort(tvbuff_t*, int, proto_tree*);
389 static int cmd_optimize(tvbuff_t*, int, proto_tree*);
390 static int resp_config(tvbuff_t*, int, proto_tree*);
391 static int cmd_sched(tvbuff_t*, int, proto_tree*);
392 static int cmd_sched_rep(tvbuff_t*, int, proto_tree*);
393 static int resp_blm_data(tvbuff_t*, int, proto_tree*);
394 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
395 static int cmd_ldf_list(tvbuff_t*, int, proto_tree*);
396 static int resp_ldf_list(tvbuff_t*, int, proto_tree*);
397 static int cmd_ldf_delete(tvbuff_t*, int, proto_tree*);
398 static int cmd_ldf_desc(tvbuff_t*, int, proto_tree*);
399 static int resp_ldf_desc(tvbuff_t*, int, proto_tree*);
400 static int cmd_ldf_upload(tvbuff_t*, int, proto_tree*);
401 static int cmd_ldf_parse(tvbuff_t*, int, proto_tree*);
402 static int resp_get_ldf_info(tvbuff_t*, int, proto_tree*);
403 static int resp_ldf_get_node_names(tvbuff_t*, int, proto_tree*);
404 static int cmd_ldf_save_session(tvbuff_t*, int, proto_tree*);
405 static int cmd_ldf_emulate_nodes(tvbuff_t*, int, proto_tree*);
406 static int resp_ldf_get_schedules(tvbuff_t*, int, proto_tree*);
407 static int cmd_ldf_start_schedule(tvbuff_t*, int, proto_tree*);
408 static int cmd_ldf_get_node_signals(tvbuff_t*, int, proto_tree*);
409 static int resp_ldf_get_node_signals(tvbuff_t*, int, proto_tree*);
410 static int cmd_ldf_get_frames(tvbuff_t*, int, proto_tree*);
411 static int resp_ldf_get_frames(tvbuff_t*, int, proto_tree*);
412 static int cmd_ldf_get_frame_info(tvbuff_t*, int, proto_tree*);
413 static int resp_ldf_get_frame_info(tvbuff_t*, int, proto_tree*);
414 static int cmd_ldf_get_signal_info(tvbuff_t*, int, proto_tree*);
415 static int resp_ldf_get_signal_info(tvbuff_t*, int, proto_tree*);
416 static int cmd_ldf_get_signal_detail(tvbuff_t*, int, proto_tree*);
417 static int resp_ldf_get_signal_detail(tvbuff_t*, int, proto_tree*);
418 static int cmd_ldf_get_encoding_info(tvbuff_t*, int, proto_tree*);
419 static int resp_ldf_get_encoding_info(tvbuff_t*, int, proto_tree*);
420 static int cmd_cnvt_get_values(tvbuff_t*, int, proto_tree*);
421 static int resp_cnvt_get_values(tvbuff_t*, int, proto_tree*);
422 static int cmd_cnvt_get_units(tvbuff_t*, int, proto_tree*);
423 static int resp_cnvt_get_units(tvbuff_t*, int, proto_tree*);
424 static int cmd_cnvt_set_values(tvbuff_t*, int, proto_tree*);
425 static int cmd_cnvt_destroy_session(tvbuff_t*, int, proto_tree*);
426 static int cmd_restore_session(tvbuff_t*, int, proto_tree*);
427 static int resp_restore_session(tvbuff_t*, int, proto_tree*);
428 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
429 static int resp_addresp(tvbuff_t*, int, proto_tree*);
430 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
431 static int resp_resphan(tvbuff_t*, int, proto_tree*);
432 static int resp_sched(tvbuff_t*, int, proto_tree*);
433 static int cmd_desc(tvbuff_t*, int, proto_tree*);
434 static int resp_desc(tvbuff_t*, int, proto_tree*);
435 static int cmd_upload(tvbuff_t*, int, proto_tree*);
436 static int cmd_delete(tvbuff_t*, int, proto_tree*);
437 static int cmd_list(tvbuff_t*, int, proto_tree*);
438 static int resp_list(tvbuff_t*, int, proto_tree*);
439 static int cmd_start(tvbuff_t*, int, proto_tree*);
440 static int resp_start(tvbuff_t*, int, proto_tree*);
441 static int resp_status(tvbuff_t*, int, proto_tree*);
442 static int cmd_options(tvbuff_t*, int, proto_tree*);
443 static int cmd_files(tvbuff_t*, int, proto_tree*);
444 static int resp_files(tvbuff_t*, int, proto_tree*);
445 static int eventnum(tvbuff_t*, int, proto_tree*);
446 static int speed(tvbuff_t*, int, proto_tree*);
447 static int filter_block(tvbuff_t*, int, proto_tree*);
448 static int blm_mode(tvbuff_t*, int, proto_tree*);
449 static int cmd_usdt_register_non_legacy(tvbuff_t*, int, proto_tree*);
450 static int cmd_usdt_stmin_fc(tvbuff_t*, int, proto_tree*);
451 static int cmd_usdt_bsmax_fc(tvbuff_t*, int, proto_tree*);
452 static int cmd_usdt_stmin_override(tvbuff_t*, int, proto_tree*);
453 static int cmd_usdt_get_stmin_override(tvbuff_t*, int, proto_tree*);
454 static int cmd_usdt_stmin_override_activate(tvbuff_t*, int, proto_tree*);
455 static int cmd_usdt_set_stmin_mul(tvbuff_t*, int, proto_tree*);
456 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
457 static int cmd_bits_in(tvbuff_t*, int, proto_tree*);
458 static int cmd_bits_out(tvbuff_t*, int, proto_tree*);
459 static int cmd_init_strat(tvbuff_t*, int, proto_tree*);
460
461
462
463 static const value_string action_vals[] = {
464     { FR_RESP_AFTER_EVENT,
465         "Send response(s) for each conforming message" },
466     { FR_RESP_AFTER_PERIOD,
467         "Send response(s) after the specified period expires following a conforming message" },
468     { FR_IGNORE_DURING_PER,
469         "Send response(s) for a conforming message and ignore further messages until the specified period expires" },
470     { 0,
471         NULL }
472 };
473
474 static const value_string deact_on_event_vals[] = {
475     { FR_DEACT_ON_EVENT,
476         "Deactivate this response for a conforming message" },
477     { FR_DELETE|FR_DEACT_ON_EVENT,
478         "Delete this response for a conforming message" },
479     { 0,
480         NULL }
481 };
482
483 static const value_string deact_after_per_vals[] = {
484     { FR_DEACT_AFTER_PER,
485         "Deactivate this response after the specified period following a conforming message" },
486     { FR_DELETE|FR_DEACT_AFTER_PER,
487         "Delete this response after the specified period following a conforming message" },
488     { 0,
489         NULL }
490 };
491
492 static const value_string cmd_optimize_type[] = {
493     {0,         "Optimize for throughput (Nagle algorithm enabled)"},
494     {1,         "Optimize for latency (Nagle algorithm disabled)"},
495     {0,         NULL}
496 };
497
498 static const value_string usdt_action_vals[] = {
499     { 0, "Use 11 bit headers only" },
500     { 1, "Use 29 bit headers only" },
501     { 2, "Use both 11 & 29 bit headers" },
502     { 3, "undefined" },
503     { 0, NULL }
504 };
505
506 static const value_string xmit_opt_nth_fc_event[] = {
507     { 0, "Do not send a USDT_RX_NTH_FLOWCONTROL event when the 1st, 2nd, 3rd, etc. flow control message is received" },
508     { 1, "Send a USDT_RX_NTH_FLOWCONTROL event when the 1st, 2nd, 3rd, etc. flow control message is received" },
509     { 0, NULL }
510 };
511
512 static const value_string xmit_opt_echo_short[] = {
513     { 0, "Do not Echo short transmitted messages back to the client (message less than 8 bytes)" },
514     { 1, "Echo short transmitted messages back to the client (message less than 8 bytes)" },
515     { 0, NULL }
516 };
517
518 static const value_string xmit_opt_done[] = {
519     { 0, "Do not send a USDT_DONE event when the last frame of a multi-frame message is transmitted" },
520     { 1, "Send a USDT_DONE event when the last frame of a multi-frame message is transmitted" },
521     { 0, NULL }
522 };
523
524 static const value_string xmit_opt_vals[] = {
525     { 0, "Pad messages with less than 8 data bytes with 0x00's" },
526     { 1, "Pad messages with less than 8 data bytes with 0xFF's" },
527     { 2, "Do not pad messages with less than 8 data bytes" },
528     { 3, "undefined" },
529     { 0, NULL }
530 };
531
532 static const value_string xmit_opt_echo_long[] = {
533     { 0, "Do not Echo long transmitted messages back to the client (message longer than 6 or 7 bytes)" },
534     { 1, "Echo long transmitted messages back to the client (message longer than 6 or 7 bytes)" },
535     { 0, NULL }
536 };
537
538
539 static const value_string recv_opt_nth_fc_event[] = {
540     { 0, "Do not send a USDT_TX_NTH_FLOWCONTROL event when the 1st, 2nd, 3rd, etc. flow control message is sent" },
541     { 1, "Send a USDT_TX_NTH_FLOWCONTROL event when the 1st, 2nd, 3rd, etc. flow control message is sent" },
542     { 0, NULL }
543 };
544 static const value_string recv_opt_lastframe_event[] = {
545     { 0, "Do not send a USDT_LASTFRAME event when the last frame of a multi-frame message is received" },
546     { 1, "Send a USDT_LASTFRAME event when the last frame of a multi-frame message is received" },
547     { 0, NULL }
548 };
549 static const value_string recv_opt_firstframe_event[] = {
550     { 0, "Do not send a USDT_FIRSTFRAME event when the first frame of a multi-frame message is received" },
551     { 1, "Send a USDT_FIRSTFRAME event when the first frame of a multi-frame message is received" },
552     { 0, NULL }
553 };
554
555 static const value_string recv_opt_j1939[] = {
556     { 0, "Treat the length as a regular 4-byte size in calculating the multi-ID block range (not J1939-style)" },
557     { 1, "Use J1939-style length (the source and destination bytes are swapped in response (for 29-bit ID/headers only))" },
558     { 2, "undefined" },
559     { 0, NULL }
560 };
561
562 static const value_string recv_opt_vals[] = {
563     { 0, "Do not verify the integrity of long received messages and do not send them to the client" },
564     { 1, "Verify the integrity of long received messages and send them to the client" },
565     { 2, "Verify the integrity of long received messages but do not send them to the client" },
566     { 3, "undefined" },
567     { 0, NULL }
568 };
569
570 static const value_string register_unregister [] = {
571     { 0, "Unregister" },
572     { 1, "Register" },
573     { 0, NULL }
574 };
575
576 static const value_string ldf_exists[] = {
577     { 0, "Name is OK, does not already exist" },
578     { 1, "*** Warning ***: LDF file with same name already exists" },
579     { 0, NULL }
580 };
581
582 static const value_string lin_slave_table_enable[] = {
583     { 0, "Disabled" },
584     { 1, "Enabled" },
585     { 2, "One-shot enabled" },
586     { 0, NULL }
587 };
588
589 static const value_string lin_slave_table_cs[] = {
590     { 0, "Good" },
591     { 1, "Bad" },
592     { 0, NULL }
593 };
594
595 static const value_string lin_ldf_ioctl_setflags[] = {
596     {0,         "Clear all flags first"},
597     {1,         "Leave existing flags intact"},
598     {0,         NULL}
599 };
600 static const value_string lin_cnvt_getflags[] = {
601     {1,         "Float value"},
602     {2,         "Int value"},
603     {3,         "Float and Int value"},
604     {4,         "String value"},
605     {5,         "Float and String value"},
606     {6,         "Int and String value"},
607     {7,         "Float, Int, and String value"},
608     {0,         NULL}
609 };
610
611 static const value_string lin_ioctl_masterevent[] = {
612     {0,         "LIN driver will not send an event on master schedule start-of-cycle"},
613     {1,         "LIN driver will send an event on master schedule start-of-cycle"},
614     {0,         NULL}
615 };
616
617 static const value_string blm_mode_vals[] = {
618     { 0, "Off" },
619     { 1, "Average over time" },
620     { 2, "Average over frame count" },
621     { 0, NULL }
622 };
623
624 static const value_string dmodes[] = {
625     {DEFAULT_FILTER_BLOCK,          "Block"},
626     {DEFAULT_FILTER_PASS,           "Pass"},
627     {0,                 NULL},
628 };
629
630 static const value_string frame_type[] = {
631     {0,         ""},
632     {1,         "Command request"},
633     {2,         "Command response"},
634     {3,         "Network (vehicle) data"},
635     {4,         "Event"},
636     {5,         "Miscellaneous"},
637     {6,         "Text string"},
638     {7,         "Signal (vehicle) network"},
639     {0,         NULL}
640 };
641
642 static const value_string src_dest[] = {
643     {SD_CARD,       "Card"},
644     {SD_SERVER,     "Server"},
645     {SD_CLIENT,     "Client"},
646     {SD_SCHED,      "Scheduler"},
647     {SD_SCRIPT,     "Script Processor"},
648     {SD_PGM,        "Program Loader"},
649     {SD_USDT,       "USDT Server"},
650     {SD_BLM,        "Bus Load Monitoring"},
651     {SD_LIN,        "LIN LDF Server"}, /* 20171031 mc */
652     {SD_FLIGHT,     "Flight Recorder / Data Logger"},
653     {SD_RESP,       "Message Responder"},
654     {SD_IOPWR,      "I/O and power"},
655     {SD_UTIL,       "Utility/Miscellaneous"},
656     {SD_CNVT,       "Signal Conversion Utility"}, /* 20171031 mc */
657     {0,         NULL}
658 };
659
660 /* 20180305 use with BASE_SPECIAL_VALS */
661 static const value_string channel_or_broadcast[] = {
662     {CH_BROADCAST, "Broadcast"},
663     {0,            NULL}
664 };
665
666
667 /*
668  * These command functions include an extra parameter for the "context"
669  * The problem with the IOCTL responses is that the response does not contain the IOCTl number.
670  * This makes it difficult to match requests with responses. To better match these, this
671  * dissector will attempt to use the "context" byte as a reference to match requests and
672  * responses.
673  */
674 static guint32 ul_context_array[256];
675 static const val_str_dsp_with_context cmds_with_context_param[] = {
676     {CMD_CARD_IOCTL,                "IOCTL pass-through"                      , cmd_ioctl     , cmd_ioctl_resp, 0,0,0}
677 };
678
679 static const val_str_dsp cmds[] = {
680     {CMD_INIT,                      "Initialize"                              , cmd_init      , NULL},
681     {CMD_GET_STAT,                  "Get status"                              , NULL          , NULL},
682     {CMD_GET_CONFIG,                "Get configuration"                       , NULL          , resp_config},
683     {CMD_EVENT_ENABLE,              "Enable event"                            , eventnum      , NULL},
684     {CMD_EVENT_DISABLE,             "Disable event"                           , eventnum      , NULL},
685     {CMD_GET_TIME,                  "Get time"                                , NULL          , resp_time},
686     {CMD_SET_TIME,                  "Set time"                                , resp_time     , NULL},
687     {CMD_GET_RXDROP,                "Get number of dropped RX messages"       , NULL          , NULL},
688     {CMD_RESET_RXDROP,              "Clear number of dropped RX messages"     , NULL          , NULL},
689     {CMD_BCAST_ON,                  "Set broadcasts on"                       , NULL          , NULL},
690     {CMD_BCAST_OFF,                 "Set broadcasts off"                      , NULL          , NULL},
691     {CMD_CARD_SET_SPEED,            "Set channel baud rate"                   , speed         , NULL},
692     {CMD_CARD_GET_SPEED,            "Get channel baud rate"                   , NULL          , speed},
693     {CMD_CARD_SET_FILTER,           "Set filter (deprecated)"                 , cmd_setfilt   , NULL},
694     {CMD_CARD_GET_FILTER,           "Get filter"                              , resp_addfilt  , cmd_addfilt},
695     {CMD_CARD_TX,                   "Transmit message"                        , decode_data   , NULL},
696     {CMD_CARD_TX_LOOP_ON,           "Set transmit loopback on"                , NULL          , NULL},
697     {CMD_CARD_TX_LOOP_OFF,          "Set transmit loopback off"               , NULL          , NULL},
698     {CMD_CARD_ADD_FILTER,           "Add a filter"                            , cmd_addfilt   , resp_addfilt},
699     {CMD_CARD_MODIFY_FILTER,        "Modify a filter"                         , cmd_modfilt   , NULL},
700     {CMD_CARD_GET_FILTER_HANDLES,   "Get filter handles"                      , NULL          , resp_filthan},
701     {CMD_CARD_SET_DEFAULT_FILTER,   "Set default filter"                      , dfiltmode     , NULL},
702     {CMD_CARD_GET_DEFAULT_FILTER,   "Get default filter mode"                 , NULL          , dfiltmode},
703     {CMD_CARD_SET_FILTER_MODE,      "Set filter mode"                         , filtmode      , NULL},
704     {CMD_CARD_GET_FILTER_MODE,      "Get filter mode"                         , NULL          , filtmode},
705     {CMD_CARD_GET_EVNAMES,          "Get event names"                         , NULL          , resp_events},
706     {CMD_CARD_GET_SPEEDS,           "Get defined speeds"                      , NULL          , resp_getspeeds},
707     {CMD_SERVER_REG,                "Register with server"                    , cmd_register  , resp_register},
708     {CMD_SERVER_SET_SORT,           "Set the sorting behavior"                , cmd_sort      , NULL},
709     {CMD_SERVER_SET_OPT,            "Set the type of optimization"            , cmd_optimize  , NULL},
710     {CMD_BLM_SET_MODE,              "Set Bus Load Monitoring mode"            , blm_mode      , NULL},
711     {CMD_BLM_GET_MODE,              "Get Bus Load Monitoring mode"            , NULL          , blm_mode},
712     {CMD_BLM_GET_DATA,              "Get Bus Load data"                       , NULL          , resp_blm_data},
713     {CMD_BLM_GET_STATS,             "Get Bus Load statistics"                 , NULL          , resp_blm_stat},
714     /* 20171101 LIN LDF */
715     {CMD_LDF_LIST,                  "Get list of loaded LIN LDFs"             , cmd_ldf_list, resp_ldf_list},
716     {CMD_LDF_DELETE,                "Delete LIN LDF"                          , cmd_ldf_delete, NULL},
717     {CMD_LDF_DESC,                  "Set Name and description of LIN LDF file", cmd_ldf_desc, resp_ldf_desc},
718     {CMD_LDF_UPLOAD,                "Upload a LIN LDF file to the Gryphon"    , cmd_ldf_upload, NULL},
719     {CMD_LDF_PARSE,                 "Parse an uploaded LIN LDF file"          , cmd_ldf_parse, NULL},
720     /* 20180118 LIN LDF */
721     {CMD_GET_LDF_INFO,              "Get info of a parsed LDF file"            , NULL, resp_get_ldf_info},
722     {CMD_GET_NODE_NAMES,            "Get names of nodes defined in the LIN LDF file"  , NULL, resp_ldf_get_node_names},
723     {CMD_GET_NODE_SIGNALS,          "Get signal names of the node defined in the LIN LDF file"  , cmd_ldf_get_node_signals, resp_ldf_get_node_signals},
724     {CMD_GET_FRAMES,                "Get frames defined in the LIN LDF file"  , cmd_ldf_get_frames, resp_ldf_get_frames},
725     {CMD_GET_FRAME_INFO,            "Get info from a frame defined in the LIN LDF file"  , cmd_ldf_get_frame_info, resp_ldf_get_frame_info},
726     {CMD_GET_SIGNAL_INFO,           "Get info from a signal defined in the LIN LDF file"  , cmd_ldf_get_signal_info, resp_ldf_get_signal_info},
727     {CMD_GET_SIGNAL_DETAIL,         "Get details from a signal defined in the LIN LDF file"  , cmd_ldf_get_signal_detail, resp_ldf_get_signal_detail},
728     {CMD_GET_ENCODING_INFO,         "Get details from an encoding name defined in the LIN LDF file"  , cmd_ldf_get_encoding_info, resp_ldf_get_encoding_info},
729     {CMD_SAVE_SESSION,              "Save an internal representation of the LIN LDF file"  , cmd_ldf_save_session, NULL},
730     {CMD_EMULATE_NODES,             "Emulate LIN nodes"                       , cmd_ldf_emulate_nodes, NULL},
731     {CMD_GET_SCHEDULES,             "Get schedules of the LIN LDF file"  , NULL, resp_ldf_get_schedules},
732     {CMD_START_SCHEDULE,            "Start a LIN schedule from the LIN LDF file"  , cmd_ldf_start_schedule, NULL},
733     {CMD_RESTORE_SESSION,           "Restore a previously saved LIN LDF session"  , cmd_restore_session, resp_restore_session },
734     /* 20180122 LIN CNVT */
735     {CMD_CNVT_GET_VALUES,           "Read one or more signal values from LIN Signal Conversion"  , cmd_cnvt_get_values, resp_cnvt_get_values},
736     {CMD_CNVT_GET_UNITS,            "Read one or more signal units from LIN Signal Conversion"  , cmd_cnvt_get_units, resp_cnvt_get_units},
737     {CMD_CNVT_SET_VALUES,           "Write one or more signal values for LIN Signal Conversion"  , cmd_cnvt_set_values, NULL},
738     {CMD_CNVT_SAVE_SESSION,         "Save an internal representation of the LIN Signal Conversion"  , cmd_ldf_save_session, NULL},
739     {CMD_CNVT_RESTORE_SESSION,      "Restore a previously saved LIN Signal Conversion session"  , cmd_restore_session, resp_restore_session },
740     {CMD_CNVT_DESTROY_SESSION,      "Destroy internal LIN Signal Conversion info" , cmd_cnvt_destroy_session, NULL},
741     {CMD_CNVT_GET_NODE_SIGNALS,     "Get signal names of the node defined in the LIN Signal Conversion Session"  , cmd_ldf_get_node_signals, resp_ldf_get_node_signals},
742
743     {CMD_FLIGHT_GET_CONFIG,         "Get flight recorder channel info"        , NULL          , NULL},
744     {CMD_FLIGHT_START_MON,          "Start flight recorder monitoring"        , NULL          , NULL},
745     {CMD_FLIGHT_STOP_MON,           "Stop flight recorder monitoring"         , NULL          , NULL},
746     /* 20171017 fixed */
747     {CMD_MSGRESP_ADD,               "Add response message"                    , cmd_addresp   , resp_addresp},
748     {CMD_MSGRESP_GET,               "Get response message"                    , resp_addresp  , cmd_addresp},
749     {CMD_MSGRESP_MODIFY,            "Modify response message state"           , cmd_modresp   , NULL},
750     {CMD_MSGRESP_GET_HANDLES,       "Get response message handles"            , NULL          , resp_resphan},
751     {CMD_PGM_DESC,                  "Describe program to to uploaded"         , cmd_desc      , resp_desc},
752     {CMD_PGM_UPLOAD,                "Upload a program to the Gryphon"         , cmd_upload    , NULL},
753     {CMD_PGM_DELETE,                "Delete an uploaded program"              , cmd_delete    , NULL},
754     {CMD_PGM_LIST,                  "Get a list of uploaded programs"         , cmd_list      , resp_list},
755     {CMD_PGM_START,                 "Start an uploaded program"               , cmd_start     , resp_start},
756     {CMD_PGM_START2,                "Start an uploaded program"               , NULL          , resp_start},
757     {CMD_PGM_STOP,                  "Stop an uploaded program"                , resp_start    , NULL},
758     {CMD_PGM_STATUS,                "Get status of an uploaded program"       , cmd_delete    , resp_status},
759     {CMD_PGM_OPTIONS,               "Set program upload options"              , cmd_options   , resp_status},
760     {CMD_PGM_FILES,                 "Get a list of files & directories"       , cmd_files     , resp_files},
761     {CMD_SCHED_TX,                  "Schedule transmission of messages"       , cmd_sched     , resp_sched},
762     {CMD_SCHED_KILL_TX,             "Stop and destroy a message schedule transmission" , resp_sched    , NULL},
763     {CMD_SCHED_STOP_TX,             "Kill a message schedule transmission (deprecated)", resp_sched    , NULL},
764     {CMD_SCHED_MSG_REPLACE,         "Replace a scheduled message"             , cmd_sched_rep , NULL},
765     /* 20171012 added new commands for USDT ISO-15765-2 server */
766     {CMD_USDT_REGISTER,             "Register/Unregister with USDT server (deprecated)"    , cmd_usdt      , NULL},
767     {CMD_USDT_SET_FUNCTIONAL,       "Set IDs to use extended addressing (deprecated)"      , cmd_usdt      , NULL},
768     {CMD_USDT_SET_STMIN_MULT,       "Set USDT STMIN multiplier"      , cmd_usdt_set_stmin_mul      , NULL},
769     {CMD_USDT_REGISTER_NON_LEGACY,  "Register/Unregister with USDT (ISO-15765) server, non-legacy (new command July 2017)", cmd_usdt_register_non_legacy, NULL},
770     {CMD_USDT_SET_STMIN_FC,         "Set USDT STMIN flow control (new command July 2017)"      , cmd_usdt_stmin_fc      , NULL},
771     {CMD_USDT_GET_STMIN_FC,         "Get USDT STMIN flow control (new command July 2017)"      , NULL, cmd_usdt_stmin_fc},
772     {CMD_USDT_SET_BSMAX_FC,         "Set USDT BSMAX flow control (new command July 2017)"      , cmd_usdt_bsmax_fc      , NULL},
773     {CMD_USDT_GET_BSMAX_FC,         "Get USDT BSMAX flow control (new command July 2017)"      , NULL, cmd_usdt_bsmax_fc},
774     {CMD_USDT_SET_STMIN_OVERRIDE,   "Set USDT STMIN override (new command July 2017)"      , cmd_usdt_stmin_override      , NULL},
775     {CMD_USDT_GET_STMIN_OVERRIDE,   "Get USDT STMIN override (new command July 2017)"      , NULL, cmd_usdt_get_stmin_override},
776     {CMD_USDT_ACTIVATE_STMIN_OVERRIDE, "Activate/deactivate USDT STMIN override (new command July 2017)"      , cmd_usdt_stmin_override_activate, NULL},
777     {CMD_IOPWR_GETINP,              "Read current digital inputs"             , NULL          , cmd_bits_in},
778     {CMD_IOPWR_GETLATCH,            "Read latched digital inputs"             , NULL          , cmd_bits_in},
779     {CMD_IOPWR_CLRLATCH,            "Read & clear latched digital inputs"     , cmd_bits_in   , cmd_bits_in},
780     {CMD_IOPWR_GETOUT,              "Read digital outputs"                    , NULL          , cmd_bits_out},
781     {CMD_IOPWR_SETOUT,              "Write digital outputs"                   , cmd_bits_out  , NULL},
782     {CMD_IOPWR_SETBIT,              "Set indicated output bits"               , cmd_bits_out  , NULL},
783     {CMD_IOPWR_CLRBIT,              "Clear indicated output bits"             , cmd_bits_out  , NULL},
784     {CMD_IOPWR_GETPOWER,            "Read digital inputs at power on time"    , NULL          , cmd_bits_in},
785     {CMD_UTIL_SET_INIT_STRATEGY,    "Set initialization strategy"             , cmd_init_strat, NULL},
786     {CMD_UTIL_GET_INIT_STRATEGY,    "Get initialization strategy"             , NULL          , cmd_init_strat},
787     {-1,                            "- unknown -"                             , NULL          , NULL},
788 };
789
790 static const value_string responses_vs[] = {
791     {RESP_OK,                       "OK - no error"},
792     {RESP_UNKNOWN_ERR,              "Unknown error"},
793     {RESP_UNKNOWN_CMD,              "Unrecognised command"},
794     {RESP_UNSUPPORTED,              "Unsupported command"},
795     {RESP_INVAL_CHAN,               "Invalid channel specified"},
796     {RESP_INVAL_DST,                "Invalid destination"},
797     {RESP_INVAL_PARAM,              "Invalid parameter(s)"},
798     {RESP_INVAL_MSG,                "Invalid message"},
799     {RESP_INVAL_LEN,                "Invalid length field"},
800     {RESP_TX_FAIL,                  "Transmit failed"},
801     {RESP_RX_FAIL,                  "Receive failed"},
802     {RESP_AUTH_FAIL,                "Authorization failed"},
803     {RESP_MEM_ALLOC_ERR,            "Memory allocation error"},
804     {RESP_TIMEOUT,                  "Command timed out"},
805     {RESP_UNAVAILABLE,              "Unavailable"},
806     {RESP_BUF_FULL,                 "Buffer full"},
807     {RESP_NO_SUCH_JOB,              "No such job"},
808     {0,                 NULL},
809 };
810
811 static const value_string filter_data_types[] = {
812     {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
813     {FILTER_DATA_TYPE_HEADER,       "data message header"},
814     {FILTER_DATA_TYPE_DATA,         "data message data"},
815     {FILTER_DATA_TYPE_EXTRA_DATA,   "data message extra data"},
816     {FILTER_EVENT_TYPE_HEADER,      "event message header"},
817     {FILTER_EVENT_TYPE_DATA,        "event message"},
818     {0,                         NULL},
819 };
820
821 static const value_string operators[] = {
822     {BIT_FIELD_CHECK,               "Bit field check"},
823     {SVALUE_GT,                     "Greater than (signed)"},
824     {SVALUE_GE,                     "Greater than or equal to (signed)"},
825     {SVALUE_LT,                     "Less than (signed)"},
826     {SVALUE_LE,                     "Less than or equal to (signed)"},
827     {VALUE_EQ,                      "Equal to"},
828     {VALUE_NE,                      "Not equal to"},
829     {UVALUE_GT,                     "Greater than (unsigned)"},
830     {UVALUE_GE,                     "Greater than or equal to (unsigned)"},
831     {UVALUE_LT,                     "Less than (unsigned)"},
832     {UVALUE_LE,                     "Less than or equal to (unsigned)"},
833     {DIG_LOW_TO_HIGH,               "Digital, low to high transition"},
834     {DIG_HIGH_TO_LOW,               "Digital, high to low transition"},
835     {DIG_TRANSITION,                "Digital, change of state"},
836     {0,                 NULL},
837 };
838
839 static const value_string modes[] = {
840     {FILTER_OFF_PASS_ALL,           "Filter off, pass all messages"},
841     {FILTER_OFF_BLOCK_ALL,          "Filter off, block all messages"},
842     {FILTER_ON,                     "Filter on"},
843     {0,                 NULL},
844 };
845
846 static const value_string filtacts[] = {
847     {DELETE_FILTER,                 "Delete"},
848     {ACTIVATE_FILTER,               "Activate"},
849     {DEACTIVATE_FILTER,             "Deactivate"},
850     {0,                 NULL},
851 };
852
853 static const value_string ioctls[] = {
854     {GINIT,                         "GINIT: Initialize"},
855     {GLOOPON,                       "GLOOPON: Loop on"},
856     {GLOOPOFF,                      "GLOOPOFF: Loop off"},
857     {GGETHWTYPE,                    "GGETHWTYPE: Get hardware type"},
858     {GGETREG,                       "GGETREG: Get register"},
859     {GSETREG,                       "GSETREG: Set register"},
860     {GGETRXCOUNT,                   "GGETRXCOUNT: Get the receive message counter"},
861     {GSETRXCOUNT,                   "GSETRXCOUNT: Set the receive message counter"},
862     {GGETTXCOUNT,                   "GGETTXCOUNT: Get the transmit message counter"},
863     {GSETTXCOUNT,                   "GSETTXCOUNT: Set the transmit message counter"},
864     {GGETRXDROP,                    "GGETRXDROP: Get the number of dropped receive messages"},
865     {GSETRXDROP,                    "GSETRXDROP: Set the number of dropped receive messages"},
866     {GGETTXDROP,                    "GGETTXDROP: Get the number of dropped transmit messages"},
867     {GSETTXDROP,                    "GSETTXDROP: Set the number of dropped transmit messages"},
868     {GGETRXBAD,                     "GGETRXBAD: Get the number of bad receive messages"},
869     {GGETTXBAD,                     "GGETTXBAD: Get the number of bad transmit messages"},
870     {GGETCOUNTS,                    "GGETCOUNTS: Get total message counter"},
871     {GGETBLMON,                     "GGETBLMON: Get bus load monitoring status"},
872     {GSETBLMON,                     "GSETBLMON: Set bus load monitoring status (turn on/off)"},
873     {GGETERRLEV,                    "GGETERRLEV: Get error level"},
874     {GSETERRLEV,                    "GSETERRLEV: Set error level"},
875     {GGETBITRATE,                   "GGETBITRATE: Get bit rate"},
876     {GGETRAM,                       "GGETRAM: Read value from RAM"},
877     {GSETRAM,                       "GSETRAM: Write value to RAM"},
878     {GCANGETBTRS,                   "GCANGETBTRS: Read CAN bit timing registers"},
879     {GCANSETBTRS,                   "GCANSETBTRS: Write CAN bit timing registers"},
880     {GCANGETBC,                     "GCANGETBC: Read CAN bus configuration register"},
881     {GCANSETBC,                     "GCANSETBC: Write CAN bus configuration register"},
882     {GCANGETMODE,                   "GCANGETMODE"},
883     {GCANSETMODE,                   "GCANSETMODE"},
884     {GCANGETTRANS,                  "GCANGETTRANS"},
885     {GCANSETTRANS,                  "GCANSETTRANS"},
886     {GCANSENDERR,                   "GCANSENDERR"},
887     {GCANRGETOBJ,                   "GCANRGETOBJ"},
888     {GCANRSETSTDID,                 "GCANRSETSTDID"},
889     {GCANRSETEXTID,                 "GCANRSETEXTID"},
890     {GCANRSETDATA,                  "GCANRSETDATA"},
891     {GCANRENABLE,                   "GCANRENABLE"},
892     {GCANRDISABLE,                  "GCANRDISABLE"},
893     {GCANRGETMASKS,                 "GCANRGETMASKS"},
894     {GCANRSETMASKS,                 "GCANRSETMASKS"},
895     {GCANSWGETMODE,                 "GCANSWGETMODE"},
896     {GCANSWSETMODE,                 "GCANSWSETMODE"},
897     {GDLCGETFOURX,                  "GDLCGETFOURX"},
898     {GDLCSETFOURX,                  "GDLCSETFOURX"},
899     {GDLCGETLOAD,                   "GDLCGETLOAD"},
900     {GDLCSETLOAD,                   "GDLCSETLOAD"},
901     {GDLCSENDBREAK,                 "GDLCSENDBREAK"},
902     {GDLCABORTTX,                   "GDLCABORTTX"},
903     {GDLCGETHDRMODE,                "DLCGETHDRMODE"},
904     {GDLCSETHDRMODE,                "GDLCSETHDRMODE"},
905     {GHONSLEEP,                     "GHONSLEEP"},
906     {GHONSILENCE,                   "GHONSILENCE"},
907     {GKWPSETPTIMES,                 "GKWPSETPTIMES"},
908     {GKWPSETWTIMES,                 "GKWPSETWTIMES"},
909     {GKWPDOWAKEUP,                  "GKWPDOWAKEUP"},
910     {GKWPGETBITTIME,                "GKWPGETBITTIME"},
911     {GKWPSETBITTIME,                "GKWPSETBITTIME"},
912     {GKWPSETNODEADDR,               "GKWPSETNODEADDR"},
913     {GKWPGETNODETYPE,               "GKWPGETNODETYPE"},
914     {GKWPSETNODETYPE,               "GKWPSETNODETYPE"},
915     {GKWPSETWAKETYPE,               "GKWPSETWAKETYPE"},
916     {GKWPSETTARGADDR,               "GKWPSETTARGADDR"},
917     {GKWPSETKEYBYTES,               "GKWPSETKEYBYTES"},
918     {GKWPSETSTARTREQ,               "GKWPSETSTARTREQ"},
919     {GKWPSETSTARTRESP,              "GKWPSETSTARTRESP"},
920     {GKWPSETPROTOCOL,               "GKWPSETPROTOCOL"},
921     {GKWPGETLASTKEYBYTES,           "GKWPGETLASTKEYBYTES"},
922     {GKWPSETLASTKEYBYTES,           "GKWPSETLASTKEYBYTES"},
923     {GSCPGETBBR,                    "GSCPGETBBR"},
924     {GSCPSETBBR,                    "GSCPSETBBR"},
925     {GSCPGETID,                     "GSCPGETID"},
926     {GSCPSETID,                     "GSCPSETID"},
927     {GSCPADDFUNCID,                 "GSCPADDFUNCID"},
928     {GSCPCLRFUNCID,                 "GSCPCLRFUNCID"},
929     {GUBPGETBITRATE,                "GUBPGETBITRATE"},
930     {GUBPSETBITRATE,                "GUBPSETBITRATE"},
931     {GUBPGETINTERBYTE,              "GUBPGETINTERBYTE"},
932     {GUBPSETINTERBYTE,              "GUBPSETINTERBYTE"},
933     {GUBPGETNACKMODE,               "GUBPGETNACKMODE"},
934     {GUBPSETNACKMODE,               "GUBPSETNACKMODE"},
935     {GUBPGETRETRYDELAY,             "GUBPGETRETRYDELAY"},
936     {GUBPSETRETRYDELAY,             "GUBPSETRETRYDELAY"},
937     {GRESETHC08,                    "GRESETHC08: Reset the HC08 processor"},
938     {GTESTHC08COP,                  "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
939     {GSJAGETLISTEN,                 "GSJAGETLISTEN"},
940     {GSJASETLISTEN,                 "GSJASETLISTEN"},
941     {GSJAGETSELFTEST,               "GSJAGETSELFTEST"},
942     {GSJASETSELFTEST,               "GSJASETSELFTEST"},
943     {GSJAGETXMITONCE,               "GSJAGETXMITONCE"},
944     {GSJASETXMITONCE,               "GSJASETXMITONCE"},
945     {GSJAGETTRIGSTATE,              "GSJAGETTRIGSTATE"},
946     {GSJASETTRIGCTRL,               "GSJASETTRIGCTRL"},
947     {GSJAGETTRIGCTRL,               "GSJAGETTRIGCTRL"},
948     {GSJAGETOUTSTATE,               "GSJAGETOUTSTATE"},
949     {GSJASETOUTSTATE,               "GSJASETOUTSTATE"},
950     {GSJAGETFILTER,                 "GSJAGETFILTER"},
951     {GSJASETFILTER,                 "GSJASETFILTER"},
952     {GSJAGETMASK,                   "GSJAGETMASK"},
953     {GSJASETMASK,                   "GSJASETMASK"},
954     {GSJAGETINTTERM,                "GSJAGETINTTERM"},
955     {GSJASETINTTERM,                "GSJASETINTTERM"},
956     {GSJAGETFTTRANS,                "GSJAGETFTTRANS"},
957     {GSJASETFTTRANS,                "GSJASETFTTRANS"},
958     {GSJAGETFTERROR,                "GSJAGETFTERROR"},
959     {GLINGETBITRATE,                "GLINGETBITRATE: Get the current bit rate"},
960     {GLINSETBITRATE,                "GLINSETBITRATE: Set the bit rate"},
961     {GLINGETBRKSPACE,               "GLINGETBRKSPACE"},
962     {GLINSETBRKSPACE,               "GLINSETBRKSPACE"},
963     {GLINGETBRKMARK,                "GLINGETBRKMARK"},
964     {GLINSETBRKMARK,                "GLINSETBRKMARK"},
965     {GLINGETIDDELAY,                "GLINGETIDDELAY"},
966     {GLINSETIDDELAY,                "GLINSETIDDELAY"},
967     {GLINGETRESPDELAY,              "GLINGETRESPDELAY"},
968     {GLINSETRESPDELAY,              "GLINSETRESPDELAY"},
969     {GLINGETINTERBYTE,              "GLINGETINTERBYTE"},
970     {GLINSETINTERBYTE,              "GLINSETINTERBYTE"},
971     {GLINGETWAKEUPDELAY,            "GLINGETWAKEUPDELAY"},
972     {GLINSETWAKEUPDELAY,            "GLINSETWAKEUPDELAY"},
973     {GLINGETWAKEUPTIMEOUT,          "GLINGETWAKEUPTIMEOUT"},
974     {GLINSETWAKEUPTIMEOUT,          "GLINSETWAKEUPTIMEOUT"},
975     {GLINGETWUTIMOUT3BR,            "GLINGETWUTIMOUT3BR"},
976     {GLINSETWUTIMOUT3BR,            "GLINSETWUTIMOUT3BR"},
977     {GLINSENDWAKEUP,                "GLINSENDWAKEUP"},
978     {GLINGETMODE,                   "GLINGETMODE"},
979     {GLINSETMODE,                   "GLINSETMODE"},
980     /* 20171109 lin LDF */
981     {GLINGETSLEW,                   "GLINGETSLEW: get slew rate"},
982     {GLINSETSLEW,                   "GLINSETSLEW: set slew rate"},
983     {GLINADDSCHED,                  "GLINADDSCHED: add a LIN schedule"},
984     {GLINGETSCHED,                  "GLINGETSCHED: get a LIN schedule"},
985     {GLINGETSCHEDSIZE,              "GLINGETSCHEDSIZE: get schedule size"},
986     {GLINDELSCHED,                  "GLINDELSCHED: delete a LIN schedule"},
987     {GLINACTSCHED,                  "GLINACTSCHED: activate a LIN schedule"},
988     {GLINDEACTSCHED,                "GLINDEACTSCHED: deactivate a LIN schedule"},
989     {GLINGETACTSCHED,               "GLINGETACTSCHED: get active LIN schedule"},
990     {GLINGETNUMSCHEDS,              "GLINGETNUMSCHED: get number of LIN schedules"},
991     {GLINGETSCHEDNAMES,             "GLINGETSCHEDNAMES: get LIN schedule names"},
992     {GLINGETMASTEREVENTENABLE,      "GLINGETMASTEREVENTENABLE: get LIN master schedule event enable flag"},
993     {GLINSETMASTEREVENTENABLE,      "GLINSETMASTEREVENTENABLE: set LIN master schedule event enable flag"},
994     {GLINGETNSLAVETABLE,            "GLINGETNSLAVETABLE: set number of LIN slave table entries"},
995     {GLINGETSLAVETABLEPIDS,         "GLINGETSLAVETABLEPIDS: get list of LIN slave table PIDs"},
996     {GLINGETSLAVETABLE,             "GLINGETSLAVETABLE: get LIN slave table entry for this PID"},
997     {GLINSETSLAVETABLE,             "GLINSETSLAVETABLE: set LIN slave table entry for this PID"},
998     {GLINCLEARSLAVETABLE,           "GLINCLEARSLAVETABLE: clear LIN slave table entry for this PID"},
999     {GLINCLEARALLSLAVETABLE,        "GLINCLEARALLSLAVETABLE: clear all LIN slave table entries"},
1000     {GLINGETONESHOT,                "GLINGETONESHOT: get LIN one-shot entry"},
1001     {GLINSETONESHOT,                "GLINSETONESHOT: set LIN one-shot entry"},
1002     {GLINCLEARONESHOT,              "GLINCLEARONESHOT: clear LIN one-shot entry"},
1003     {GLINSETFLAGS,                  "GLINSETFLAGS"},
1004     {GLINGETAUTOCHECKSUM,           "GLINGETAUTOCHECKSUM: get LIN auto checksum"},
1005     {GLINSETAUTOCHECKSUM,           "GLINSETAUTOCHECKSUM: set LIN auto checksum"},
1006     {GLINGETAUTOPARITY,             "GLINGETAUTOPARITY: get LIN auto parity"},
1007     {GLINSETAUTOPARITY,             "GLINSETAUTOPARITY: set LIN auto parity"},
1008     {GLINGETSLAVETABLEENABLE,       "GLINGETSLAVETABLEENABLE: get LIN slave table enable"},
1009     {GLINSETSLAVETABLEENABLE,       "GLINSETSLAVETABLEENABLE: set LIN slave table enable"},
1010     {GLINGETFLAGS,                  "GLINGETFLAGS"},
1011     {GLINGETWAKEUPMODE,             "GLINGETWAKEUPMODE: get LIN wakeup mode"},
1012     {GLINSETWAKEUPMODE,             "GLINSETWAKEUPMODE: set LIN wakeup mode"},
1013     {GDLYGETHIVALUE,                "GDLYGETHIVALUE: get the high water value"},
1014     {GDLYSETHIVALUE,                "GDLYSETHIVALUE: set the high water value"},
1015     {GDLYGETLOVALUE,                "GDLYGETLOVALUE: get the low water value"},
1016     {GDLYSETLOVALUE,                "GDLYSETLOVALUE: set the low water value"},
1017     {GDLYGETHITIME,                 "GDLYGETHITIME: get the high water time"},
1018     {GDLYSETHITIME,                 "GDLYSETHITIME: set the high water time"},
1019     {GDLYGETLOTIME,                 "GDLYGETLOTIME: get the low water time"},
1020     {GDLYSETLOTIME,                 "GDLYSETLOTIME: set the low water time"},
1021     {GDLYGETLOREPORT,               "GDLYGETLOREPORT:get the low water report flag"},
1022     {GDLYFLUSHSTREAM,               "GDLYFLUSHSTREAM: flush the delay buffer"},
1023     {GDLYINITSTREAM,                "GDLYINITSTREAM: set default hi & lo water marks"},
1024     {GDLYPARTIALFLUSHSTREAM,        "GDLYPARTIALFLUSHSTREAM: flush the delay buffer"},
1025     {GINPGETINP,                    "GINPGETINP: Read current digital inputs"},
1026     {GINPGETLATCH,                  "GINPGETLATCH: Read latched digital inputs"},
1027     {GINPCLRLATCH,                  "GINPCLRLATCH: Read and clear latched digital inputs"},
1028     {GOUTGET,                       "GOUTGET: Read digital outputs"},
1029     {GOUTSET,                       "GOUTSET: Write digital outputs"},
1030     {GOUTSETBIT,                    "GOUTSETBIT: Set digital output bits"},
1031     {GOUTCLEARBIT,                  "GOUTCLEARBIT"},
1032     {GPWRGETWHICH,                  "GPWRGETWHICH"},
1033     {GPWROFF,                       "GPWROFF"},
1034     {GPWROFFRESET,                  "GPWROFFRESET"},
1035     {GPWRRESET,                     "GPWRRESET"},
1036     {0,                         NULL},
1037 };
1038
1039
1040 static const value_string cmd_sort_type[] = {
1041     {0,         "Do not sort messages"},
1042     {1,         "Sort into blocks of up to 16 messages"},
1043     {0,         NULL}
1044 };
1045
1046 static const value_string protocol_types[] = {
1047     {GDUMMY * 256 + GDGDMARKONE,              "Dummy device driver"},
1048     {GCAN * 256 + G82527,                     "CAN, 82527 subtype"},
1049     {GCAN * 256 + GSJA1000,                   "CAN, SJA1000 subtype"},
1050     {GCAN * 256 + G82527SW,                   "CAN, 82527 single wire subtype"},
1051     {GCAN * 256 + G82527ISO11992,             "CAN, 82527 ISO11992 subtype"},
1052     {GCAN * 256 + G82527_SINGLECHAN,          "CAN, Fiber Optic 82527 subtype"},
1053     {GCAN * 256 + G82527SW_SINGLECHAN,        "CAN, Fiber Optic 82527 single wire subtype"},
1054     {GCAN * 256 + G82527ISO11992_SINGLECHAN,  "CAN, Fiber Optic ISO11992 subtype"},
1055     {GCAN * 256 + GSJA1000FT,                 "CAN, SJA1000 Fault Tolerant subtype"},
1056     {GCAN * 256 + GSJA1000C,                  "CAN, SJA1000 onboard subtype"},
1057     {GCAN * 256 + GSJA1000FT_FO,              "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1058     {GCAN * 256 + GSJA1000_BEACON_CANFD,      "CAN, SJA1000 BEACON CAN-FD subtype"},
1059     {GCAN * 256 + GSJA1000_BEACON_SW,         "CAN, SJA1000 BEACON CAN single wire subtype"},
1060     {GCAN * 256 + GSJA1000_BEACON_FT,         "CAN, SJA1000 BEACON CAN Fault Tolerant subtype"},
1061     {GJ1850 * 256 + GHBCCPAIR,                "J1850, HBCC subtype"},
1062     {GJ1850 * 256 + GDLC,                     "J1850, GM DLC subtype"},
1063     {GJ1850 * 256 + GCHRYSLER,                "J1850, Chrysler subtype"},
1064     {GJ1850 * 256 + GDEHC12,                  "J1850, DE HC12 KWP/BDLC subtype"},
1065     {GKWP2000 * 256 + GDEHC12KWP,             "Keyword protocol 2000/ISO 9141"},
1066     {GHONDA * 256 + GDGHC08,                  "Honda UART, DG HC08 subtype"},
1067     {GFORDUBP * 256 + GDGUBP08,               "Ford UBP, DG HC08 subtype"},
1068     {GSCI * 256 + G16550SCI,                  "Chrysler SCI, UART subtype"},
1069     {GCCD * 256 + G16550CDP68HC68,            "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1070     {GLIN * 256 + GDGLIN08,                   "LIN, DG HC08 subtype"},
1071     {GLIN * 256 + GDGLIN_BEACON,              "LIN, BEACON LIN updated subtype"},
1072     {0,                             NULL},
1073 };
1074
1075 static const true_false_string tfs_wait_response = { "Wait", "Don't Wait" };
1076 static const true_false_string true_false = { "True", "False" };
1077 static const true_false_string register_unregister_action_flags = { "Register", "Unregister" };
1078 static const true_false_string tfs_passed_blocked = { "Pass", "Block" };
1079 static const true_false_string active_inactive = { "Active", "Inactive" };
1080 static const true_false_string critical_normal = { "Critical", "Normal" };
1081 static const true_false_string skip_not_skip = { "Skip", "Do not skip" };
1082 static const true_false_string frames_01seconds = { "Frames", "0.01 seconds" };
1083 static const true_false_string present_not_present = { "Present", "Not present" };
1084 static const true_false_string yes_no = { "Yes", "No" };
1085 static const true_false_string set_not_set = { "Set", "Not set" };
1086
1087 /*
1088  * Length of the frame header.
1089  */
1090 #define GRYPHON_FRAME_HEADER_LEN    8
1091
1092 static guint
1093 get_gryphon_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1094 {
1095     guint16 plen;
1096     int padded_len;
1097
1098     /*
1099      * Get the length of the Gryphon packet, and then get the length as
1100      * padded to a 4-byte boundary.
1101      */
1102     plen = tvb_get_ntohs(tvb, offset + 4);
1103     padded_len = plen + 3 - (plen + 3) % 4;
1104
1105     /*
1106      * That length doesn't include the fixed-length part of the header;
1107      * add that in.
1108      */
1109     return padded_len + GRYPHON_FRAME_HEADER_LEN;
1110 }
1111
1112 static int
1113 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1114 {
1115     dissect_gryphon_message(tvb, pinfo, tree, FALSE);
1116     return tvb_reported_length(tvb);
1117 }
1118
1119 static int
1120 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1121 {
1122     tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, GRYPHON_FRAME_HEADER_LEN,
1123                      get_gryphon_pdu_len, dissect_gryphon_pdu, data);
1124     return tvb_reported_length(tvb);
1125 }
1126
1127 /*
1128  * returns 1 if the ID is one of the special servers
1129  * return 0 otherwise
1130  */
1131 static int is_special_client(guint32 id)
1132 {
1133     if((id == SD_SERVER) || (id == SD_CLIENT)) {
1134         return 1;
1135     }
1136     return 0;
1137 }
1138
1139 /*
1140  * 20180221
1141  * This function exists because Gryphon Protocol MISC packets contain within them Gryphon Protocol packets.
1142  * So, this function will decode a packet and return the offset.
1143  */
1144 static int
1145 dissect_gryphon_message_with_offset(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean is_msgresp_add)
1146 {
1147     proto_tree      *gryphon_tree;
1148     proto_item      *ti;
1149     proto_tree      *header_tree, *body_tree;
1150     int             msgend;
1151     int             msglen, msgpad;
1152     unsigned int    src, dest, i, frmtyp;
1153     guint8          flags;
1154
1155     if (!is_msgresp_add) {
1156         col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
1157         col_clear(pinfo->cinfo, COL_INFO);
1158     }
1159
1160     if (!is_msgresp_add) {
1161         ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, ENC_NA);
1162         gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
1163     } else
1164         gryphon_tree = tree;
1165
1166     src = tvb_get_guint8(tvb, offset + 0);
1167     dest = tvb_get_guint8(tvb, offset + 2);
1168     msglen = tvb_get_ntohs(tvb, offset + 4);
1169     flags = tvb_get_guint8(tvb, offset + 6);
1170     frmtyp = flags & ~RESPONSE_FLAGS;
1171
1172     if (!is_msgresp_add) {
1173         /*
1174          * This tvbuff includes padding to make its length a multiple
1175          * of 4 bytes; set it to the actual length.
1176          */
1177
1178         /* TODO 20171011 this is not correct. can't use msglen here, because there is also padding in the msg? */
1179         msgpad = 3 - (msglen + 3) % 4;
1180         set_actual_length(tvb, msglen + msgpad + GRYPHON_FRAME_HEADER_LEN);
1181
1182         /*
1183          * Indicate what kind of message this is.
1184          */
1185         col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(frmtyp, frame_type, "- Invalid -"));
1186     }
1187
1188     if (tree == NULL)
1189         return offset;
1190
1191     if (try_val_to_str(frmtyp, frame_type) == NULL) {
1192         /*
1193          * Unknown message type.
1194          */
1195         proto_tree_add_item(gryphon_tree, hf_gryphon_data, tvb, offset, msglen, ENC_NA);
1196         offset += msglen;
1197         return offset;
1198     }
1199
1200     header_tree = proto_tree_add_subtree(gryphon_tree, tvb, offset, MSG_HDR_SZ, ett_gryphon_header, NULL, "Header");
1201
1202     /* src */
1203     proto_tree_add_item(header_tree, hf_gryphon_src, tvb, offset, 1, ENC_BIG_ENDIAN);
1204     /* 20180306 20171012 */
1205     /* srcchan */
1206     if(is_special_client(src)) {
1207         proto_tree_add_item(header_tree, hf_gryphon_srcchanclient, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1208     } else {
1209         proto_tree_add_item(header_tree, hf_gryphon_srcchan, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1210     }
1211
1212     /* dest */
1213     proto_tree_add_item(header_tree, hf_gryphon_dest, tvb, offset+2, 1, ENC_BIG_ENDIAN);
1214     /* 20180306 20171012 */
1215     /* destchan */
1216     if(is_special_client(dest)) {
1217             proto_tree_add_item(header_tree, hf_gryphon_destchanclient, tvb, offset+3, 1, ENC_BIG_ENDIAN);
1218     } else {
1219             proto_tree_add_item(header_tree, hf_gryphon_destchan, tvb, offset+3, 1, ENC_BIG_ENDIAN);
1220     }
1221
1222     proto_tree_add_item(header_tree, hf_gryphon_data_length, tvb, offset+4, 2, ENC_BIG_ENDIAN);
1223     proto_tree_add_item(header_tree, hf_gryphon_type, tvb, offset+6, 1, ENC_BIG_ENDIAN);
1224
1225     if (is_msgresp_add) {
1226         static const int * wait_flags[] = {
1227             &hf_gryphon_wait_resp,
1228             &hf_gryphon_wait_prev_resp,
1229             NULL
1230         };
1231
1232         proto_tree_add_bitmask(header_tree, tvb, offset+6, hf_gryphon_wait_flags, ett_gryphon_flags, wait_flags, ENC_NA);
1233     }
1234     proto_tree_add_item(header_tree, hf_gryphon_reserved, tvb, offset+7, 1, ENC_NA);
1235     offset += MSG_HDR_SZ;
1236
1237     msgpad = 3 - (msglen + 3) % 4;
1238     msgend = offset + msglen + msgpad;
1239
1240     body_tree = proto_tree_add_subtree(gryphon_tree, tvb, offset, msglen , ett_gryphon_body, NULL, "Body");
1241
1242     switch (frmtyp) {
1243     case GY_FT_CMD:
1244         offset = decode_command(tvb, msglen, offset, dest, body_tree);
1245         break;
1246     case GY_FT_RESP:
1247         offset = decode_response(tvb, offset, src, body_tree);
1248         break;
1249     case GY_FT_DATA:
1250         offset = decode_data(tvb, offset, body_tree);
1251         break;
1252     case GY_FT_EVENT:
1253         offset = decode_event(tvb, offset, body_tree);
1254         break;
1255     case GY_FT_MISC:
1256         offset = decode_misc (tvb, offset, body_tree);
1257         break;
1258     case GY_FT_TEXT:
1259         offset = decode_text (tvb, offset, msglen, body_tree);
1260         break;
1261     case GY_FT_SIG:
1262         break;
1263     default:
1264         break;
1265     }
1266
1267     /*debug*/
1268     /*i = msgend - offset;*/
1269     /*proto_tree_add_debug_text(gryphon_tree, "debug offset=%d msgend=%d i=%d",offset,msgend,i);*/
1270
1271     if (offset < msgend) {
1272         i = msgend - offset;
1273         /*
1274          * worked when msglen=4, offset=8, msgend=12, get i=4
1275          * did not work when msglen=5, offset=8, msgend=16, i is 8
1276          */
1277         proto_tree_add_item(gryphon_tree, hf_gryphon_padding, tvb, offset, i, ENC_NA);
1278         offset += i;
1279     }
1280     return offset;
1281 }
1282
1283 static void
1284 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_msgresp_add)
1285 {
1286     dissect_gryphon_message_with_offset(tvb, 0, pinfo, tree, is_msgresp_add);
1287 }
1288
1289 static int
1290 decode_command(tvbuff_t *tvb, int msglen, int offset, int dst, proto_tree *pt)
1291 {
1292     int             cmd;
1293     unsigned int    i;
1294     guint8 uc_context;
1295     guint32 ui_command;
1296     proto_tree      *ft;
1297     proto_item      *hi;
1298     static guint32 first_time=1;
1299     if(first_time) {
1300         first_time=0;
1301         memset(ul_context_array,0,sizeof(ul_context_array));
1302     }
1303
1304     cmd = tvb_get_guint8(tvb, offset);
1305     hi = proto_tree_add_uint(pt, hf_gryphon_cmd, tvb, offset, 1, cmd);
1306     proto_item_set_hidden(hi);
1307
1308     if (cmd > 0x3F)
1309         cmd += dst * 256;
1310
1311     for (i = 0; i < array_length(cmds_with_context_param); i++) {
1312         /*proto_tree_add_debug_text(pt, "decode_command() debug offset=%d msglen=%d index i=%d cmd=0x%x value=0x%x",offset,msglen,i,cmd, cmds_with_context_param[i].value);*/
1313         if (cmds_with_context_param[i].value == cmd) {
1314
1315             proto_tree_add_string(pt, hf_gryphon_command, tvb, offset, 1, cmds_with_context_param[i].strptr);
1316             uc_context = tvb_get_guint8(tvb, offset+1);
1317             /* we know this is an IOCTL command */
1318             /* save the IOCTL in the context array for use during the command response */
1319             ui_command = tvb_get_ntohl(tvb, offset+4);
1320             ul_context_array[uc_context] = ui_command;
1321
1322             proto_tree_add_item(pt, hf_gryphon_cmd_context, tvb, offset+1, 1, ENC_NA);
1323             proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
1324             offset += 4;
1325             msglen -= 4;
1326
1327             if (cmds_with_context_param[i].cmd_fnct && msglen > 0) {
1328                 ft = proto_tree_add_subtree_format(pt, tvb, offset, msglen, ett_gryphon_command_data, NULL,
1329                         "Data: (%d byte%s)", msglen, msglen == 1 ? "" : "s");
1330                 offset = (*(cmds_with_context_param[i].cmd_fnct)) (tvb, offset, ft, ui_command);
1331             }
1332
1333             return offset;
1334         }
1335     }
1336
1337     for (i = 0; i < array_length(cmds); i++) {
1338         if (cmds[i].value == cmd)
1339             break;
1340     }
1341     if (i >= array_length(cmds) && dst >= SD_KNOWN) {
1342         cmd = (cmd & 0xFF) + SD_CARD * 256;
1343         for (i = 0; i < array_length(cmds); i++) {
1344             if (cmds[i].value == cmd)
1345                 break;
1346         }
1347     }
1348     if (i >= array_length(cmds)) {
1349         i = array_length(cmds) - 1;
1350     }
1351
1352     proto_tree_add_string(pt, hf_gryphon_command, tvb, offset, 1, cmds[i].strptr);
1353     proto_tree_add_item(pt, hf_gryphon_cmd_context, tvb, offset+1, 1, ENC_NA);
1354     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
1355     offset += 4;
1356     msglen -= 4;
1357
1358     if (cmds[i].cmd_fnct && msglen > 0) {
1359         ft = proto_tree_add_subtree_format(pt, tvb, offset, msglen, ett_gryphon_command_data, NULL,
1360                 "Data: (%d byte%s)", msglen, msglen == 1 ? "" : "s");
1361         offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
1362     }
1363
1364     return offset;
1365 }
1366
1367 static int
1368 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1369 {
1370     int             cmd, msglen;
1371     unsigned int    i;
1372     unsigned int    j;
1373     proto_tree      *ft;
1374     guint8 uc_context;
1375     guint32 ui_command;
1376
1377     msglen = tvb_reported_length_remaining(tvb, offset);
1378     cmd = tvb_get_guint8(tvb, offset);
1379
1380     if (cmd > 0x3F)
1381         cmd += src * 256;
1382
1383     for (i = 0; i < array_length(cmds_with_context_param); i++) {
1384         if (cmds_with_context_param[i].value == cmd) {
1385
1386             uc_context = tvb_get_guint8(tvb, offset+1);
1387             /* retrieve the command from the context array, save in the command request */
1388             if(ul_context_array[uc_context] != 0) {
1389                 ui_command = ul_context_array[uc_context];
1390                 ul_context_array[uc_context] = 0; /* clear the context array */
1391                 /* linear search for ioctl string */
1392                 for(j=0; j < sizeof(ioctls) / sizeof(value_string); j++) {
1393                     if(ioctls[j].value == ui_command) {
1394                         proto_tree_add_string(pt, hf_gryphon_command, tvb, offset, 1, cmds_with_context_param[i].strptr);
1395                         /*proto_tree_add_debug_text(pt, "decode_response() debug index j=%d cmd=0x%x value=0x%x context=%d 0x%x",j,cmd, cmds_with_context_param[i].value,uc_context, ui_command);*/
1396                         proto_tree_add_uint_format_value(pt, hf_gryphon_cmd_context, tvb, offset+1, 1, uc_context, "%u IOCTL Response %s (0x%x)", uc_context, ioctls[j].strptr, ui_command);
1397                         break;
1398                     }
1399                 }
1400                 if(j == sizeof(ioctls) / sizeof(value_string)) {
1401                     /* this is the old original way of displaying */
1402                     proto_tree_add_string(pt, hf_gryphon_command, tvb, offset, 1, cmds_with_context_param[i].strptr);
1403                     proto_tree_add_item(pt, hf_gryphon_cmd_context, tvb, offset+1, 1, ENC_NA);
1404                 }
1405                 proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
1406                 offset += 4;
1407                 msglen -= 4;
1408
1409                 proto_tree_add_item(pt, hf_gryphon_status, tvb, offset, 4, ENC_BIG_ENDIAN);
1410                 offset += 4;
1411                 msglen -= 4;
1412
1413                 /* 20171012 debug */
1414                 /*proto_tree_add_debug_text(pt, "decode_response() debug offset=%d msglen=%d index i=%d",offset,msglen,i);*/
1415                 if (cmds_with_context_param[i].rsp_fnct && msglen > 0) {
1416                     ft = proto_tree_add_subtree_format(pt, tvb, offset, msglen, ett_gryphon_response_data, NULL,
1417                         "Data: (%d byte%s)", msglen, msglen == 1 ? "" : "s");
1418                     offset = (*(cmds_with_context_param[i].rsp_fnct)) (tvb, offset, ft, ui_command);
1419                 }
1420                 return offset;
1421             }
1422         }
1423     }
1424
1425     for (i = 0; i < array_length(cmds); i++) {
1426         if (cmds[i].value == cmd)
1427             break;
1428     }
1429     if (i >= array_length(cmds) && src >= SD_KNOWN) {
1430         cmd = (cmd & 0xFF) + SD_CARD * 256;
1431         for (i = 0; i < array_length(cmds); i++) {
1432             if (cmds[i].value == cmd)
1433                 break;
1434         }
1435     }
1436     if (i >= array_length(cmds)) {
1437         i = array_length(cmds) - 1;
1438     }
1439     /* this is the old original way of displaying */
1440     proto_tree_add_string(pt, hf_gryphon_command, tvb, offset, 1, cmds[i].strptr);
1441     proto_tree_add_item(pt, hf_gryphon_cmd_context, tvb, offset+1, 1, ENC_NA);
1442     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
1443     offset += 4;
1444     msglen -= 4;
1445
1446     proto_tree_add_item(pt, hf_gryphon_status, tvb, offset, 4, ENC_BIG_ENDIAN);
1447     offset += 4;
1448     msglen -= 4;
1449
1450     if (cmds[i].rsp_fnct && msglen > 0) {
1451         ft = proto_tree_add_subtree_format(pt, tvb, offset, msglen, ett_gryphon_response_data, NULL,
1452             "Data: (%d byte%s)", msglen, msglen == 1 ? "" : "s");
1453         offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
1454     }
1455
1456     return offset;
1457 }
1458
1459 static int
1460 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1461 {
1462     proto_tree  *tree;
1463     int         hdrsize, datasize, extrasize, msgsize, padding;
1464     nstime_t    timestamp;
1465     /*int       hdrbits;*/
1466
1467     static const int * data_mode_flags[] = {
1468         &hf_gryphon_data_mode_transmitted,
1469         &hf_gryphon_data_mode_receive,
1470         &hf_gryphon_data_mode_local,
1471         &hf_gryphon_data_mode_remote,
1472         &hf_gryphon_data_mode_oneshot,
1473         &hf_gryphon_data_mode_combined,
1474         &hf_gryphon_data_mode_nomux,
1475         &hf_gryphon_data_mode_internal,
1476         NULL
1477     };
1478
1479     hdrsize   = tvb_get_guint8(tvb, offset+0);
1480     /* hdrbits   = tvb_get_guint8(tvb, offset+1); */
1481     datasize  = tvb_get_ntohs(tvb, offset+2);
1482     extrasize = tvb_get_guint8(tvb, offset+4);
1483     padding   = 3 - (hdrsize + datasize + extrasize + 3) % 4;
1484     msgsize   = hdrsize + datasize + extrasize + padding + 16;
1485
1486     tree = proto_tree_add_subtree(pt, tvb, offset, 16, ett_gryphon_data_header, NULL, "Message header");
1487
1488     /* fixed major problem with header length, length is 1-byte not 2-bytes */
1489     proto_tree_add_item(tree, hf_gryphon_data_header_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1490     proto_tree_add_item(tree, hf_gryphon_data_header_length_bits, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1491     proto_tree_add_item(tree, hf_gryphon_data_data_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1492     proto_tree_add_item(tree, hf_gryphon_data_extra_data_length, tvb, offset+4, 1, ENC_BIG_ENDIAN);
1493
1494     /* 20171012 always display mode bits, not just conditionally */
1495     proto_tree_add_bitmask(tree, tvb, offset+5, hf_gryphon_data_mode, ett_gryphon_flags, data_mode_flags, ENC_BIG_ENDIAN);
1496
1497     proto_tree_add_item(tree, hf_gryphon_data_priority, tvb, offset+6, 1, ENC_BIG_ENDIAN);
1498     proto_tree_add_item(tree, hf_gryphon_data_error_status, tvb, offset+7, 1, ENC_BIG_ENDIAN);
1499
1500     timestamp.secs = tvb_get_ntohl(tvb, offset+8)/100000;
1501     timestamp.nsecs = (tvb_get_ntohl(tvb, offset+8)%100000)*1000;
1502     proto_tree_add_time(tree, hf_gryphon_data_time, tvb, offset+8, 4, &timestamp);
1503
1504     proto_tree_add_item(tree, hf_gryphon_data_context, tvb, offset+12, 1, ENC_BIG_ENDIAN);
1505     proto_tree_add_item(tree, hf_gryphon_reserved, tvb, offset+13, 3, ENC_NA);
1506     offset += 16;
1507
1508     tree = proto_tree_add_subtree(pt, tvb, offset, msgsize-16-padding, ett_gryphon_data_body, NULL, "Message Body");
1509     if (hdrsize) {
1510         proto_tree_add_item(tree, hf_gryphon_data_header_data, tvb, offset, hdrsize, ENC_NA);
1511         offset += hdrsize;
1512     }
1513     if (datasize) {
1514         proto_tree_add_item(tree, hf_gryphon_data_data, tvb, offset, datasize, ENC_NA);
1515         offset += datasize;
1516     }
1517     if (extrasize) {
1518         proto_tree_add_item(tree, hf_gryphon_data_extra_data, tvb, offset, extrasize, ENC_NA);
1519         offset += extrasize;
1520     }
1521     if (padding) {
1522         proto_tree_add_item(tree, hf_gryphon_data_padding, tvb, offset, padding, ENC_NA);
1523         offset += padding;
1524     }
1525     /*proto_tree_add_debug_text(pt, "decode_data() debug offset=%d msgsize=%d", offset, msgsize);*/
1526     return offset;
1527 }
1528
1529 static int
1530 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
1531 {
1532     int             msglen, msgend, padding, length;
1533     nstime_t        timestamp;
1534
1535     msglen = tvb_reported_length_remaining(tvb, offset);
1536     padding = 3 - (msglen + 3) % 4;
1537     msgend = offset + msglen;
1538
1539     proto_tree_add_item(pt, hf_gryphon_event_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1540     proto_tree_add_item(pt, hf_gryphon_event_context, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1541     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
1542     offset += 4;
1543
1544     timestamp.secs = tvb_get_ntohl(tvb, offset)/100000;
1545     timestamp.nsecs = (tvb_get_ntohl(tvb, offset)%100000)*1000;
1546     proto_tree_add_time(pt, hf_gryphon_event_time, tvb, offset, 4, &timestamp);
1547     offset += 4;
1548
1549     if (offset < msgend) {
1550         length = msgend - offset;
1551         proto_tree_add_item(pt, hf_gryphon_event_data, tvb, offset, length, ENC_NA);
1552         offset += length;
1553     }
1554     if (padding) {
1555         proto_tree_add_item(pt, hf_gryphon_event_padding, tvb, offset, padding, ENC_NA);
1556         offset += padding;
1557     }
1558     return offset;
1559 }
1560
1561 static int
1562 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
1563 {
1564     int             msglen;
1565
1566     msglen = tvb_reported_length_remaining(tvb, offset);
1567     /* proto_tree_add_debug_text(pt, "decode_misc() debug a offset=%d msglen=%d",offset, msglen); */
1568     while(msglen > 0) {
1569         /*
1570          * 20180221
1571          * This function is called because Gryphon Protocol MISC packets contain within
1572          * them Gryphon Protocol packets (including possibly MISC packets!). So, this
1573          * function decodes that packet and return the offset. Loop thru all such packets
1574          * in the MISC packet.
1575          */
1576         offset = dissect_gryphon_message_with_offset(tvb, offset, NULL, pt, TRUE);
1577         msglen = tvb_reported_length_remaining(tvb, offset);
1578     }
1579     return offset;
1580 }
1581
1582 static int
1583 decode_text (tvbuff_t *tvb, int offset, int msglen, proto_tree *pt)
1584 {
1585     int       padding, length;
1586     char      *string;
1587
1588     padding = 3 - (msglen + 3) % 4;
1589
1590     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1591
1592     proto_tree_add_string(pt, hf_gryphon_misc_text, tvb, offset, length, string);
1593     offset += length;
1594     if (padding) {
1595         proto_tree_add_item(pt, hf_gryphon_misc_padding, tvb, offset, padding, ENC_NA);
1596         offset += padding;
1597     }
1598     return offset;
1599 }
1600
1601 static int
1602 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
1603 {
1604     guint8 mode = tvb_get_guint8(tvb, offset);
1605
1606     if (mode == 0)
1607         proto_tree_add_uint_format_value(pt, hf_gryphon_cmd_mode, tvb, offset, 1, mode,  "Always initialize");
1608     else
1609         proto_tree_add_uint_format_value(pt, hf_gryphon_cmd_mode, tvb, offset, 1, mode,  "Initialize if not previously initialized");
1610     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
1611     offset += 4;
1612     return offset;
1613 }
1614 static int
1615 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
1616 {
1617     guint8 event = tvb_get_guint8(tvb, offset);
1618
1619     if (event)
1620         proto_tree_add_item(pt, hf_gryphon_eventnum, tvb, offset, 1, ENC_BIG_ENDIAN);
1621     else
1622         proto_tree_add_uint_format_value(pt, hf_gryphon_eventnum, tvb, offset, 1, 0, "All Events.");
1623     offset += 1;
1624     return offset;
1625 }
1626
1627 static int
1628 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
1629 {
1630     guint64         val;
1631     nstime_t        timestamp;
1632
1633     val = tvb_get_ntoh64(tvb, offset);
1634     timestamp.secs = (time_t)(val/100000);
1635     timestamp.nsecs = (int)((val%100000)*1000);
1636
1637     proto_tree_add_time(pt, hf_gryphon_resp_time, tvb, offset, 8, &timestamp);
1638     offset += 8;
1639
1640     return offset;
1641 }
1642
1643 static int
1644 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1645 {
1646     int    flag = tvb_get_ntohl(tvb, offset);
1647     int    length, padding;
1648
1649     length =  tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
1650         + tvb_get_ntohs(tvb, offset+6);
1651
1652     proto_tree_add_uint_format_value(pt, hf_gryphon_setfilt, tvb, offset, 4,
1653         flag, "%s%s", ((flag) ? "Pass" : "Block"), ((length == 0) ? " all" : ""));
1654     proto_tree_add_uint(pt, hf_gryphon_setfilt_length, tvb, offset+4, 4, length);
1655     offset += 8;
1656     if (length) {
1657         proto_tree_add_item(pt, hf_gryphon_setfilt_discard_data, tvb, offset, length * 2, ENC_NA);
1658         offset += length * 2;
1659     }
1660     padding = 3 - (length * 2 + 3) % 4;
1661     if (padding) {
1662         proto_tree_add_item(pt, hf_gryphon_setfilt_padding, tvb, offset, padding, ENC_NA);
1663         offset += padding;
1664     }
1665     return offset;
1666 }
1667
1668 static int
1669 cmd_ioctl_details(tvbuff_t *tvb, int offset, proto_tree *pt, guint32 ui_command, int msglen)
1670 {
1671     char *string;
1672     int length;
1673     gint32 nbytes;
1674     gint32 block_nbytes;
1675     gint16 us_stream;
1676     gint16 us_value;
1677     proto_tree  *tree;
1678     unsigned int msg;
1679     guint8 number_ids;
1680     guint8 number_bytes;
1681     guint8 number_extra_bytes;
1682     guint8 flags;
1683     guint8 pid;
1684     guint8 datalen;
1685     guint8 extralen;
1686     int i;
1687     guint32 mtime;
1688     guint16 us_nsched;
1689     float value;
1690     static const int * ldf_schedule_flags[] = {
1691         &hf_gryphon_ldf_schedule_event,
1692         &hf_gryphon_ldf_schedule_sporadic,
1693         NULL
1694     };
1695
1696     /* TODO Gryphon Protocol has LOTS more ioctls, for CANbus, etc. */
1697     /* 20171109 mc */
1698     switch(ui_command) {
1699     case GLINDEACTSCHED:
1700         {
1701             /* 20180104 done */
1702         }
1703         break;
1704     case GLINACTSCHED:
1705         {
1706             /* schedule name */
1707             string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1708             proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1709             offset += 32;
1710         }
1711         break;
1712     case GLINGETNUMSCHEDS:
1713         {
1714         /* 20180227 */
1715         us_nsched = tvb_get_letohs(tvb, offset);
1716         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_sched_numb_place, tvb, offset, 2, us_nsched, "%d", us_nsched);
1717         offset += 2;
1718         }
1719         break;
1720     case GLINGETSCHEDNAMES:
1721         {
1722         nbytes = tvb_reported_length_remaining(tvb, offset);
1723         while(nbytes > 0)
1724         {
1725             /* schedule name */
1726             string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1727             proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1728             offset += 32;
1729             nbytes -= 32;
1730         }
1731         }
1732         break;
1733     case GLINGETSCHED:
1734         {
1735         /* 20180227 */
1736         nbytes = tvb_get_letohl(tvb, offset);
1737         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_sched_size, tvb, offset, 4, nbytes, "%d", nbytes);
1738         offset += 4;
1739         /* schedule name */
1740         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1741         proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1742         offset += 32;
1743
1744         /* delay time */
1745         mtime = tvb_get_letohl(tvb, offset);
1746         value = (float)mtime / (float)10.0;
1747         proto_tree_add_float_format_value(pt, hf_gryphon_init_strat_delay, tvb, offset, 4, value, "%.1f milliseconds", value);
1748         offset += 4;
1749
1750         number_ids = tvb_get_guint8(tvb, offset);
1751
1752         /* header length, number of IDs to follow */
1753         proto_tree_add_item(pt, hf_gryphon_data_header_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1754         offset += 1;
1755
1756         number_bytes = tvb_get_guint8(tvb, offset);
1757         number_bytes &= 0x0F; /* bit0 thru bit3 */
1758
1759         /* data length, number data bytes to follow */
1760         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_schedule_msg_dbytes, tvb, offset, 1, number_bytes, "%d", number_bytes);
1761         /* sporadic, event-driven flags */
1762         proto_tree_add_bitmask(pt, tvb, offset, hf_gryphon_ldf_schedule_flags, ett_gryphon_flags, ldf_schedule_flags, ENC_BIG_ENDIAN);
1763         offset += 1;
1764
1765         /* id's */
1766         proto_tree_add_item(pt, hf_gryphon_data_header_data, tvb, offset, number_ids, ENC_NA);
1767         offset += number_ids;
1768         proto_tree_add_item(pt, hf_gryphon_data_data, tvb, offset, number_bytes, ENC_NA);
1769         offset += number_bytes;
1770         }
1771         break;
1772     case GLINGETSCHEDSIZE:
1773         {
1774         /* 20180227 */
1775         nbytes = tvb_get_letohl(tvb, offset);
1776         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_sched_size_place, tvb, offset, 4, nbytes, "%d", nbytes);
1777         offset += 4;
1778         /* schedule name */
1779         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1780         proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1781         offset += 32;
1782         }
1783         break;
1784     case GLINDELSCHED:
1785         {
1786         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1787         /*proto_tree_add_debug_text(pt, "cmd_ioctl_details() debug offset=%d length=%d string='%s'",offset,length,string); */
1788         if(string[0] == '\0') {
1789             proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, "All schedules");
1790         } else {
1791             proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1792         }
1793         offset += 32;
1794         }
1795         break;
1796     case GLINADDSCHED:
1797         {
1798         /* 20180227 */
1799         /* number of bytes to follow */
1800         nbytes = tvb_get_letohl(tvb, offset);
1801         /*proto_tree_add_item(pt, hf_gryphon_ioctl_nbytes, tvb, offset, 4, ENC_BIG_ENDIAN);*/
1802         proto_tree_add_uint_format_value(pt, hf_gryphon_ioctl_nbytes, tvb, offset, 4, nbytes, "%d", nbytes);
1803         offset += 4;
1804         nbytes -= 4;
1805         /* schedule name */
1806         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
1807         proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, 32, string);
1808         offset += 32;
1809         nbytes -= 32;
1810
1811         /* messages */
1812         msg = 1;
1813         while(nbytes > 0) {
1814
1815             /* calc the number of bytes in this block */
1816             number_ids = tvb_get_guint8(tvb, offset+4);
1817             number_bytes = tvb_get_guint8(tvb, offset+5);
1818
1819             number_bytes &= 0x0F; /* bit0 thru bit3 */
1820             block_nbytes = 4 + 1 + 1 + number_ids + number_bytes;
1821
1822             /* message number */
1823             tree = proto_tree_add_subtree_format(pt, tvb, offset, block_nbytes, ett_gryphon_lin_schedule_msg, NULL, "LIN message %u", msg);
1824
1825             /* delay time */
1826             /*mtime = tvb_get_ntohl(tvb, offset);*/
1827             mtime = tvb_get_letohl(tvb, offset);
1828             value = (float)mtime / (float)10.0;
1829             proto_tree_add_float_format_value(tree, hf_gryphon_init_strat_delay, tvb, offset, 4, value, "%.1f milliseconds", value);
1830             offset += 4;
1831
1832             /* header length, number of IDs to follow */
1833             proto_tree_add_item(tree, hf_gryphon_data_header_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1834             offset += 1;
1835
1836             /* data length, number data bytes to follow */
1837             /*proto_tree_add_item(tree, hf_gryphon_data_data_length, tvb, offset, 1, ENC_BIG_ENDIAN);*/
1838             proto_tree_add_uint_format_value(tree, hf_gryphon_ldf_schedule_msg_dbytes, tvb, offset, 1, number_bytes, "%d", number_bytes);
1839             /* sporadic, event-driven flags */
1840             proto_tree_add_bitmask(tree, tvb, offset, hf_gryphon_ldf_schedule_flags, ett_gryphon_flags, ldf_schedule_flags, ENC_BIG_ENDIAN);
1841             offset += 1;
1842
1843             /* id's */
1844             proto_tree_add_item(tree, hf_gryphon_data_header_data, tvb, offset, number_ids, ENC_NA);
1845             offset += number_ids;
1846             proto_tree_add_item(tree, hf_gryphon_data_data, tvb, offset, number_bytes, ENC_NA);
1847             offset += number_bytes;
1848
1849             nbytes -= block_nbytes;
1850             msg++;
1851             /* proto_tree_add_debug_text(pt, "cmd_ioctl_details() debug offset=%d msglen=%d nbytes=%d",offset,msglen,nbytes);*/
1852         }
1853         }
1854         break;
1855     case GLINSETFLAGS:
1856         {
1857             /* 20171113 */
1858             proto_tree_add_item(pt, hf_gryphon_ldf_ioctl_setflags, tvb, offset, 1, ENC_BIG_ENDIAN);
1859             offset += 1;
1860             number_ids = tvb_get_guint8(tvb, offset);
1861             proto_tree_add_item(pt, hf_gryphon_ldf_numb_ids, tvb, offset, 1, ENC_BIG_ENDIAN);
1862             offset += 1;
1863             for(i = 0; i < number_ids; i++) {
1864                 flags = tvb_get_guint8(tvb, offset);
1865                 proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, flags, "0x%x %s",i,flags==0 ? "Classic checksum" : (flags==0x80?"Enhanced checksum":(flags==0x40?"Event":"UNKNOWN")));
1866                 offset += 1;
1867             }
1868         }
1869         break;
1870     case GLINSETBITRATE:
1871         {
1872             /* 20180227 */
1873             /* 20171113 */
1874             mtime = tvb_get_letohl(tvb, offset);
1875             value = (float)mtime / (float)1000.0;
1876             proto_tree_add_float_format_value(pt, hf_gryphon_ldf_bitrate, tvb, offset, 4, value, "%.3f Kbps", value);
1877             offset += 4;
1878         }
1879         break;
1880     case GLINGETNSLAVETABLE:
1881         {
1882             /* 20180104 */
1883             proto_tree_add_item(pt, hf_gryphon_ldf_numb_ids, tvb, offset, 1, ENC_BIG_ENDIAN);
1884             offset += 1;
1885         }
1886         break;
1887     case GLINGETSLAVETABLEPIDS:
1888         {
1889             /* 20180104 */
1890             number_ids = tvb_get_guint8(tvb, offset);
1891             proto_tree_add_item(pt, hf_gryphon_ldf_numb_ids, tvb, offset, 1, ENC_BIG_ENDIAN);
1892             offset += 1;
1893             for(i = 0; i < number_ids; i++) {
1894                 pid = tvb_get_guint8(tvb, offset);
1895                 proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, pid, "0x%x ",pid);
1896                 offset += 1;
1897             }
1898         }
1899         break;
1900     case GLINGETSLAVETABLE:
1901         {
1902             /* 20180104 */
1903             /*
1904              * byte 0: PID
1905              * byte 1: datalen
1906              * byte 2: extralen
1907              * byte 3: enabled=1 or disabled=0, 2=has one-shot
1908              * byte 4: good cs=0 or bad cs=1
1909              * byte 5-13: data[datalen]
1910              * byte n: checksum
1911              */
1912             pid = tvb_get_guint8(tvb, offset);
1913             proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, pid, "0x%02x ",pid);
1914             offset += 1;
1915             datalen = tvb_get_guint8(tvb, offset);
1916             proto_tree_add_item(pt, hf_gryphon_lin_data_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1917             offset += 1;
1918             extralen = tvb_get_guint8(tvb, offset);
1919             proto_tree_add_item(pt, hf_gryphon_data_extra_data_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1920             offset += 1;
1921             proto_tree_add_item(pt, hf_gryphon_lin_slave_table_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
1922             offset += 1;
1923             proto_tree_add_item(pt, hf_gryphon_lin_slave_table_cs, tvb, offset, 1, ENC_BIG_ENDIAN);
1924             offset += 1;
1925             if(datalen != 0) {
1926                 proto_tree_add_item(pt, hf_gryphon_lin_slave_table_data, tvb, offset, datalen, ENC_NA);
1927                 offset += datalen;
1928             }
1929             if(extralen != 0) {
1930                 proto_tree_add_item(pt, hf_gryphon_lin_slave_table_datacs, tvb, offset, 1, ENC_NA);
1931                 offset += 1;
1932             }
1933         }
1934         break;
1935     case GLINSETSLAVETABLE:
1936         {
1937             /* 20180104 */
1938             /*
1939              * byte 0: PID
1940              * byte 1: datalen
1941              * byte 2: extralen
1942              * byte 3: enabled=1 or disabled=0
1943              * byte 4-12: data[datalen]
1944              * byte n: checksum
1945              */
1946             pid = tvb_get_guint8(tvb, offset);
1947             proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, pid, "0x%02x ",pid);
1948             offset += 1;
1949             datalen = tvb_get_guint8(tvb, offset);
1950             proto_tree_add_item(pt, hf_gryphon_lin_data_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1951             offset += 1;
1952             extralen = tvb_get_guint8(tvb, offset);
1953             proto_tree_add_item(pt, hf_gryphon_data_extra_data_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1954             offset += 1;
1955             proto_tree_add_item(pt, hf_gryphon_lin_slave_table_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
1956             offset += 1;
1957             if(datalen != 0) {
1958                 proto_tree_add_item(pt, hf_gryphon_lin_slave_table_data, tvb, offset, datalen, ENC_NA);
1959                 offset += datalen;
1960             }
1961             if(extralen != 0) {
1962                 proto_tree_add_item(pt, hf_gryphon_lin_slave_table_datacs, tvb, offset, 1, ENC_NA);
1963                 offset += 1;
1964             }
1965         }
1966         break;
1967     case GLINCLEARSLAVETABLE:
1968         {
1969             /* 20180104 done */
1970             pid = tvb_get_guint8(tvb, offset);
1971             proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, pid, "0x%02x ",pid);
1972             offset += 1;
1973         }
1974         break;
1975     case GLINCLEARALLSLAVETABLE:
1976         {
1977             /* 20180104 done */
1978         }
1979         break;
1980     case GLINGETMASTEREVENTENABLE:
1981     case GLINSETMASTEREVENTENABLE:
1982         {
1983             /* 20180227 */
1984             proto_tree_add_item(pt, hf_gryphon_lin_masterevent, tvb, offset, 1, ENC_BIG_ENDIAN);
1985             offset += 1;
1986         }
1987         break;
1988     case GLINGETONESHOT:
1989     case GLINSETONESHOT:
1990         {
1991             /* 20180104 */
1992             /* 20180228 */
1993             number_bytes = tvb_get_guint8(tvb, offset+1);
1994             number_extra_bytes = tvb_get_guint8(tvb, offset+2);
1995             /* id */
1996             proto_tree_add_item(pt, hf_gryphon_data_header_data, tvb, offset, 1, ENC_NA);
1997             offset += 1;
1998             proto_tree_add_item(pt, hf_gryphon_lin_numdata, tvb, offset, 1, ENC_BIG_ENDIAN);
1999             offset += 1;
2000             proto_tree_add_item(pt, hf_gryphon_lin_numextra, tvb, offset, 1, ENC_BIG_ENDIAN);
2001             offset += 1;
2002             if (number_bytes) {
2003                 proto_tree_add_item(pt, hf_gryphon_data_data, tvb, offset, number_bytes, ENC_NA);
2004                 offset += number_bytes;
2005             }
2006             if (number_extra_bytes) {
2007                 proto_tree_add_item(pt, hf_gryphon_data_extra_data, tvb, offset, number_extra_bytes, ENC_NA);
2008                 offset += number_extra_bytes;
2009             }
2010         }
2011         break;
2012     case GLINCLEARONESHOT:
2013         {
2014             /* 20180104 */
2015             /* 20180227 done */
2016         }
2017         break;
2018     case GDLYGETHIVALUE:
2019     case GDLYSETHIVALUE:
2020     case GDLYGETLOVALUE:
2021     case GDLYSETLOVALUE:
2022         {
2023             /* 20180227 */
2024             /* 20180104 */
2025             us_stream = tvb_get_letohs(tvb, offset);
2026             proto_tree_add_uint_format_value(pt, hf_gryphon_dd_stream, tvb, offset, 2, us_stream, "%d (0x%04X)", us_stream, us_stream);
2027             offset += 2;
2028             us_value = tvb_get_letohs(tvb, offset);
2029             /* proto_tree_add_item(pt, hf_gryphon_dd_value, tvb, offset, 2, ENC_BIG_ENDIAN);*/
2030             proto_tree_add_uint_format_value(pt, hf_gryphon_dd_value, tvb, offset, 2, us_value, "%d (0x%04X)", us_value, us_value);
2031             offset += 2;
2032         }
2033         break;
2034     case GDLYGETHITIME:
2035     case GDLYSETHITIME:
2036     case GDLYGETLOTIME:
2037     case GDLYSETLOTIME:
2038         {
2039             /* 20180227 */
2040             /* 20180104 */
2041             us_stream = tvb_get_letohs(tvb, offset);
2042             proto_tree_add_uint_format_value(pt, hf_gryphon_dd_stream, tvb, offset, 2, us_stream, "%d (0x%04X)", us_stream, us_stream);
2043             offset += 2;
2044             mtime = tvb_get_letohs(tvb, offset);
2045             proto_tree_add_uint_format_value(pt, hf_gryphon_dd_time, tvb, offset, 2, mtime, "%d", mtime);
2046             offset += 2;
2047         }
2048         break;
2049 /* TODO implement remaining delay driver ioctls */
2050 #if 0
2051     case GDLYGETLOREPORT: /*get the low water report flag*/
2052         break;
2053     case GDLYFLUSHSTREAM: /*flush the delay buffer*/
2054         break;
2055     case GDLYINITSTREAM: /*set default hi & lo water marks*/
2056         break;
2057     case GDLYPARTIALFLUSHSTREAM: /*flush the delay buffer */
2058         break;
2059 #endif
2060     default:
2061         proto_tree_add_item(pt, hf_gryphon_ioctl_data, tvb, offset, msglen, ENC_NA);
2062         offset += msglen;
2063         break;
2064     }
2065     return offset;
2066 }
2067
2068 /*
2069  * cmd_ioctl() performs the initial decode of the IOCTL command, then
2070  * calls cmd_ioctl_details()
2071  */
2072 static int
2073 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt, guint32 ui_command)
2074 {
2075     int  msglen;
2076     /*guint32 ioctl;*/
2077     int    padding;
2078
2079     msglen = tvb_reported_length_remaining(tvb, offset);
2080     /* 20171109 mc */
2081     /*ioctl = tvb_get_ntohl(tvb, offset);*/
2082
2083     /* 20171012 debug */
2084     /*proto_tree_add_debug_text(pt, "cmd_ioctl() debug offset=%d msglen=%d",offset,msglen);*/
2085     proto_tree_add_item(pt, hf_gryphon_ioctl, tvb, offset, 4, ENC_BIG_ENDIAN);
2086     offset += 4;
2087     msglen -= 4;
2088
2089     if (msglen > 0) {
2090         offset = cmd_ioctl_details(tvb, offset, pt, ui_command,  msglen);
2091     }
2092
2093     padding = tvb_reported_length_remaining(tvb, offset);
2094     /*proto_tree_add_debug_text(pt, "cmd_ioctl() debug offset=%d msglen=%d padding=%d",offset,msglen,padding);*/
2095     if (padding > 0) {
2096         proto_tree_add_item(pt, hf_gryphon_setfilt_padding, tvb, offset, padding, ENC_NA);
2097         offset += padding;
2098     }
2099     return offset;
2100 }
2101
2102 /*
2103  * cmd_ioctl_resp()
2104  * displays the IOCTL data in the IOCTL response to the IOCTL request
2105  * Here is an issue with the IOCTLs. The IOCTL request contains the IOCTL number,
2106  * but the IOCTL response does not contain the number. IOCTL response
2107  * contains the context byte of the request, so application software can match
2108  * the IOCTL response to the request.
2109  */
2110 static int
2111 cmd_ioctl_resp(tvbuff_t *tvb, int offset, proto_tree *pt, guint32 ui_command)
2112 {
2113     int  msglen = tvb_reported_length_remaining(tvb, offset);
2114
2115     /* 20171012 debug */
2116     /*proto_tree_add_debug_text(pt, "cmd_ioctl_resp() debug offset=%d msglen=%d",offset,msglen);*/
2117
2118     if (msglen > 0) {
2119         /*proto_tree_add_item(pt, hf_gryphon_ioctl_data, tvb, offset, msglen, ENC_NA);*/
2120         /*offset += msglen;*/
2121         offset = cmd_ioctl_details(tvb, offset, pt, ui_command,  msglen);
2122     }
2123     return offset;
2124 }
2125
2126 static int
2127 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
2128 {
2129     proto_tree  *tree;
2130     int         blocks, i, length;
2131     int padding;
2132
2133     tree = proto_tree_add_subtree(pt, tvb, offset, 1, ett_gryphon_flags, NULL, "Flags");
2134     proto_tree_add_item(tree, hf_gryphon_addfilt_pass, tvb, offset, 1, ENC_BIG_ENDIAN);
2135     proto_tree_add_item(tree, hf_gryphon_addfilt_active, tvb, offset, 1, ENC_BIG_ENDIAN);
2136     offset += 1;
2137
2138     blocks = tvb_get_guint8(tvb, offset);
2139     proto_tree_add_item(pt, hf_gryphon_addfilt_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
2140     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 6, ENC_NA);
2141     offset += 7;
2142
2143     for (i = 1; i <= blocks; i++) {
2144         length = tvb_get_ntohs(tvb, offset+2) + 8;
2145         /*length += 3 - (length + 3) % 4; */
2146         padding = 3 - (length + 3) % 4;
2147         tree = proto_tree_add_subtree_format(pt, tvb, offset, length + padding, ett_gryphon_cmd_filter_block, NULL, "Filter block %d", i);
2148         offset = filter_block(tvb, offset, tree);
2149     }
2150     return offset;
2151 }
2152
2153 static int
2154 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
2155 {
2156     proto_tree_add_item(pt, hf_gryphon_addfilt_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
2157     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
2158     offset += 4;
2159     return offset;
2160 }
2161
2162 static int
2163 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
2164 {
2165     guint8 filter_handle = tvb_get_guint8(tvb, offset);
2166
2167     if (filter_handle)
2168         proto_tree_add_item(pt, hf_gryphon_modfilt, tvb, offset, 1, ENC_BIG_ENDIAN);
2169     else
2170         proto_tree_add_uint_format_value(pt, hf_gryphon_modfilt, tvb, offset, 1,
2171                 0, "Filter handles: all");
2172
2173     proto_tree_add_item(pt, hf_gryphon_modfilt_action, tvb, offset+1, 1, ENC_BIG_ENDIAN);
2174     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
2175     offset += 4;
2176     return offset;
2177 }
2178
2179 static int
2180 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
2181 {
2182     int     handles = tvb_get_guint8(tvb, offset);
2183     int     i, padding, handle;
2184
2185     proto_tree_add_item(pt, hf_gryphon_filthan, tvb, offset, 1, ENC_BIG_ENDIAN);
2186     for (i = 1; i <= handles; i++){
2187         handle = tvb_get_guint8(tvb, offset+i);
2188         proto_tree_add_uint_format_value(pt, hf_gryphon_filthan_id, tvb, offset+i, 1,
2189         handle, "Handle %d: %u", i, handle);
2190     }
2191     padding = 3 - (handles + 1 + 3) % 4;
2192     if (padding)
2193         proto_tree_add_item(pt, hf_gryphon_filthan_padding, tvb, offset+1+handles, padding, ENC_NA);
2194     offset += 1+handles+padding;
2195     return offset;
2196 }
2197
2198 static int
2199 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
2200 {
2201     proto_tree_add_item(pt, hf_gryphon_dfiltmode, tvb, offset, 1, ENC_BIG_ENDIAN);
2202     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
2203     offset += 4;
2204     return offset;
2205 }
2206
2207 static int
2208 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
2209 {
2210     proto_tree_add_item(pt, hf_gryphon_filtmode, tvb, offset, 1, ENC_BIG_ENDIAN);
2211     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
2212     offset += 4;
2213     return offset;
2214 }
2215
2216 static int
2217 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
2218 {
2219     int             msglen;
2220     unsigned int    i;
2221     proto_tree      *tree;
2222
2223     msglen = tvb_reported_length_remaining(tvb, offset);
2224     i = 1;
2225     while (msglen != 0) {
2226         tree = proto_tree_add_subtree_format(pt, tvb, offset, 20, ett_gryphon_cmd_events_data, NULL, "Event %d:", i);
2227         proto_tree_add_item(tree, hf_gryphon_event_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2228         proto_tree_add_item(tree, hf_gryphon_event_name, tvb, offset+1, 19, ENC_NA|ENC_ASCII);
2229         offset += 20;
2230         msglen -= 20;
2231         i++;
2232     }
2233     return offset;
2234 }
2235
2236 static int
2237 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
2238 {
2239     proto_tree_add_item(pt, hf_gryphon_register_username, tvb, offset, 16, ENC_NA|ENC_ASCII);
2240     offset += 16;
2241     proto_tree_add_item(pt, hf_gryphon_register_password, tvb, offset, 32, ENC_NA|ENC_ASCII);
2242     offset += 32;
2243     return offset;
2244 }
2245
2246 static int
2247 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
2248 {
2249     proto_tree_add_item(pt, hf_gryphon_register_client_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2250     proto_tree_add_item(pt, hf_gryphon_register_privileges, tvb, offset+1, 1, ENC_BIG_ENDIAN);
2251     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
2252     offset += 4;
2253     return offset;
2254 }
2255
2256
2257 static int
2258 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
2259 {
2260     int indx,
2261         size = tvb_get_guint8(tvb, offset+8),
2262         number = tvb_get_guint8(tvb, offset+9);
2263
2264     proto_tree_add_item(pt, hf_gryphon_getspeeds_set_ioctl, tvb, offset, 4, ENC_BIG_ENDIAN);
2265     proto_tree_add_item(pt, hf_gryphon_getspeeds_get_ioctl, tvb, offset+4, 4, ENC_BIG_ENDIAN);
2266     proto_tree_add_item(pt, hf_gryphon_getspeeds_size, tvb, offset+8, 1, ENC_BIG_ENDIAN);
2267     proto_tree_add_item(pt, hf_gryphon_getspeeds_preset, tvb, offset+9, 1, ENC_BIG_ENDIAN);
2268     offset += 10;
2269
2270     for (indx = 1; indx <= number; indx++) {
2271         proto_tree_add_bytes_format(pt, hf_gryphon_getspeeds_data, tvb, offset, size,
2272                 tvb_get_ptr(tvb, offset, size), "Data for preset %d", indx);
2273         offset += size;
2274     }
2275     return offset;
2276 }
2277
2278 static int
2279 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
2280 {
2281     proto_tree_add_item(pt, hf_gryphon_cmd_sort, tvb, offset, 1, ENC_BIG_ENDIAN);
2282     return (offset+1);
2283 }
2284
2285 static int
2286 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
2287 {
2288     proto_tree_add_item(pt, hf_gryphon_cmd_optimize, tvb, offset, 1, ENC_BIG_ENDIAN);
2289     return (offset+1);
2290 }
2291
2292 static int
2293 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
2294 {
2295     proto_tree   *ft, *tree;
2296     int          devices;
2297     int          i;
2298     unsigned int j, x;
2299
2300     proto_tree_add_item(pt, hf_gryphon_config_device_name, tvb, offset, 20, ENC_NA|ENC_ASCII);
2301     offset += 20;
2302
2303     proto_tree_add_item(pt, hf_gryphon_config_device_version, tvb, offset, 8, ENC_NA|ENC_ASCII);
2304     offset += 8;
2305
2306     proto_tree_add_item(pt, hf_gryphon_config_device_serial_number, tvb, offset, 20, ENC_NA|ENC_ASCII);
2307     offset += 20;
2308
2309     devices = tvb_get_guint8(tvb, offset);
2310
2311     proto_tree_add_item(pt, hf_gryphon_config_num_channels, tvb, offset+1, 1, ENC_BIG_ENDIAN);
2312     proto_tree_add_item(pt, hf_gryphon_config_name_version_ext, tvb, offset+1, 11, ENC_NA|ENC_ASCII);
2313     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+12, 4, ENC_NA);
2314     offset += 16;
2315
2316     for (i = 1; i <= devices; i++) {
2317         ft = proto_tree_add_subtree_format(pt, tvb, offset, 80, ett_gryphon_cmd_config_device, NULL, "Channel %d:", i);
2318
2319         proto_tree_add_item(ft, hf_gryphon_config_driver_name, tvb, offset, 20, ENC_NA|ENC_ASCII);
2320         offset += 20;
2321
2322         proto_tree_add_item(ft, hf_gryphon_config_driver_version, tvb, offset, 8, ENC_NA|ENC_ASCII);
2323         offset += 8;
2324
2325         proto_tree_add_item(ft, hf_gryphon_config_device_security, tvb, offset, 16, ENC_NA|ENC_ASCII);
2326         offset += 16;
2327
2328         x = tvb_get_ntohl (tvb, offset);
2329         if (x) {
2330             tree = proto_tree_add_subtree(ft, tvb, offset, 4, ett_gryphon_valid_headers, NULL, "Valid Header lengths");
2331             for (j = 0; ; j++) {
2332                 if (x & 1) {
2333                     proto_tree_add_uint_format(tree, hf_gryphon_valid_header_length, tvb, offset, 4, j, "%d byte%s", j,
2334                     j == 1 ? "" : "s");
2335                 }
2336                 if ((x >>= 1) == 0)
2337                     break;
2338             }
2339         }
2340         offset += 4;
2341
2342         proto_tree_add_item(ft, hf_gryphon_config_max_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
2343         offset += 2;
2344
2345         proto_tree_add_item(ft, hf_gryphon_config_min_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
2346         offset += 2;
2347
2348         proto_tree_add_item(ft, hf_gryphon_config_hardware_serial_number, tvb, offset, 20, ENC_NA|ENC_ASCII);
2349         offset += 20;
2350
2351         proto_tree_add_item(ft, hf_gryphon_config_protocol_type, tvb, offset, 2, ENC_BIG_ENDIAN);
2352         offset += 2;
2353
2354         proto_tree_add_item(ft, hf_gryphon_config_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2355         offset++;
2356
2357         proto_tree_add_item(ft, hf_gryphon_config_card_slot_number, tvb, offset, 1, ENC_BIG_ENDIAN);
2358         offset ++;
2359
2360         proto_tree_add_item(ft, hf_gryphon_config_max_extra_data, tvb, offset, 2, ENC_BIG_ENDIAN);
2361         offset += 2;
2362
2363         proto_tree_add_item(ft, hf_gryphon_config_min_extra_data, tvb, offset, 2, ENC_BIG_ENDIAN);
2364         offset += 2;
2365
2366     }
2367     return offset;
2368 }
2369
2370 static int
2371 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
2372 {
2373     int             msglen;
2374     proto_item      *item, *item1;
2375     proto_tree      *tree, *tree1;
2376     int             save_offset;
2377     unsigned int    i, x, length;
2378     guint8 def_chan = tvb_get_guint8(tvb, offset-9);
2379
2380     msglen = tvb_reported_length_remaining(tvb, offset);
2381
2382     if (tvb_get_ntohl(tvb, offset) == 0xFFFFFFFF)
2383         proto_tree_add_uint_format_value(pt, hf_gryphon_sched_num_iterations, tvb, offset, 4,
2384                 0, "\"infinite\"");
2385     else
2386         proto_tree_add_item(pt, hf_gryphon_sched_num_iterations, tvb, offset, 4, ENC_BIG_ENDIAN);
2387     offset += 4;
2388     msglen -= 4;
2389
2390
2391     item = proto_tree_add_item(pt, hf_gryphon_sched_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
2392     tree = proto_item_add_subtree (item, ett_gryphon_flags);
2393     proto_tree_add_item(tree, hf_gryphon_sched_flags_scheduler, tvb, offset, 4, ENC_BIG_ENDIAN);
2394     offset += 4;
2395     msglen -= 4;
2396
2397     i = 1;
2398     while (msglen > 0) {
2399
2400         length = 16 + tvb_get_guint8(tvb, offset+16) + tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
2401         length += 3 - (length + 3) % 4;
2402
2403         tree = proto_tree_add_subtree_format(pt, tvb, offset, length, ett_gryphon_cmd_sched_data, NULL, "Message %d", i);
2404         proto_tree_add_item(tree, hf_gryphon_sched_sleep, tvb, offset, 4, ENC_BIG_ENDIAN);
2405         offset += 4;
2406         msglen -= 4;
2407
2408         proto_tree_add_item(tree, hf_gryphon_sched_transmit_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2409         offset += 4;
2410         msglen -= 4;
2411
2412         proto_tree_add_item(tree, hf_gryphon_sched_transmit_period, tvb, offset, 4, ENC_BIG_ENDIAN);
2413         offset += 4;
2414         msglen -= 4;
2415
2416         item1 = proto_tree_add_item(tree, hf_gryphon_sched_transmit_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
2417         tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
2418         proto_tree_add_item(tree1, hf_gryphon_sched_skip_transmit_period, tvb, offset, 2, ENC_BIG_ENDIAN);
2419         if (i == 1) {
2420             proto_tree_add_item(tree1, hf_gryphon_sched_skip_sleep, tvb, offset, 2, ENC_BIG_ENDIAN);
2421         }
2422
2423         x = tvb_get_guint8(tvb, offset+2);
2424         /* 20171026 */
2425         if (x == 0) {
2426             x = def_chan;
2427             proto_tree_add_uint(tree, hf_gryphon_sched_channel0, tvb, offset+2, 1, x);
2428         } else {
2429             proto_tree_add_uint(tree, hf_gryphon_sched_channel, tvb, offset+2, 1, x);
2430         }
2431
2432         proto_tree_add_item(tree, hf_gryphon_reserved, tvb, offset+3, 1, ENC_NA);
2433         offset += 4;
2434         msglen -= 4;
2435
2436         tree1 = proto_tree_add_subtree(tree, tvb, offset, msglen, ett_gryphon_cmd_sched_cmd, NULL, "Message");
2437         save_offset = offset;
2438         offset = decode_data(tvb, offset, tree1);
2439         msglen -= offset - save_offset;
2440         i++;
2441     }
2442     return offset;
2443 }
2444
2445 static int
2446 cmd_sched_rep(tvbuff_t *tvb, int offset, proto_tree *pt)
2447 {
2448     unsigned int    x;
2449     const char      *type;
2450
2451     x = tvb_get_ntohl(tvb, offset);
2452     if (x & 0x80000000)
2453         type = "Critical";
2454     else
2455         type = "Normal";
2456     proto_tree_add_uint_format_value(pt, hf_gryphon_sched_rep_id, tvb,
2457                 offset, 4, x, "%s schedule ID: %u", type, x);
2458     offset += 4;
2459
2460     proto_tree_add_item(pt, hf_gryphon_sched_rep_message_index, tvb, offset, 1, ENC_BIG_ENDIAN);
2461     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
2462     offset += 4;
2463     offset = decode_data(tvb, offset, pt);
2464     return offset;
2465 }
2466
2467 static int
2468 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
2469 {
2470     int               x;
2471
2472     nstime_t        timestamp;
2473
2474     timestamp.secs = tvb_get_ntohl(tvb, offset)/100000;
2475     timestamp.nsecs = (tvb_get_ntohl(tvb, offset)%100000)*1000;
2476     proto_tree_add_time(pt, hf_gryphon_blm_data_time, tvb, offset, 4, &timestamp);
2477     offset += 4;
2478
2479     x = tvb_get_ntohs(tvb, offset);
2480     proto_tree_add_uint_format_value(pt, hf_gryphon_blm_data_bus_load, tvb,
2481                 offset, 2, x, "%d.%02d%%", x / 100, x % 100);
2482     offset += 2;
2483     x = tvb_get_ntohs(tvb, offset);
2484     proto_tree_add_uint_format_value(pt, hf_gryphon_blm_data_current_bus_load, tvb,
2485                 offset, 2, x, "%d.%02d%%", x / 100, x % 100);
2486     offset += 2;
2487     x = tvb_get_ntohs(tvb, offset);
2488     proto_tree_add_uint_format_value(pt, hf_gryphon_blm_data_peak_bus_load, tvb,
2489                 offset, 2, x, "%d.%02d%%", x / 100, x % 100);
2490     offset += 2;
2491     x = tvb_get_ntohs(tvb, offset);
2492     proto_tree_add_uint_format_value(pt, hf_gryphon_blm_data_historic_peak_bus_load, tvb,
2493                 offset, 2, x, "%d.%02d%%", x / 100, x % 100);
2494     offset += 2;
2495
2496     return offset;
2497 }
2498
2499 static int
2500 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
2501 {
2502     offset = resp_blm_data(tvb, offset, pt);
2503
2504     proto_tree_add_item(pt, hf_gryphon_blm_stat_receive_frame_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2505     offset += 4;
2506     proto_tree_add_item(pt, hf_gryphon_blm_stat_transmit_frame_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2507     offset += 4;
2508     proto_tree_add_item(pt, hf_gryphon_blm_stat_receive_dropped_frame_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2509     offset += 4;
2510     proto_tree_add_item(pt, hf_gryphon_blm_stat_transmit_dropped_frame_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2511     offset += 4;
2512     proto_tree_add_item(pt, hf_gryphon_blm_stat_receive_error_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2513     offset += 4;
2514     proto_tree_add_item(pt, hf_gryphon_blm_stat_transmit_error_count, tvb, offset, 4, ENC_BIG_ENDIAN);
2515     offset += 4;
2516     return offset;
2517 }
2518
2519 /*
2520  * command to get a list of LDFs
2521  */
2522 static int
2523 cmd_ldf_list(tvbuff_t *tvb, int offset, proto_tree *pt)
2524 {
2525
2526     /* block index */
2527     proto_tree_add_item(pt, hf_gryphon_ldf_list, tvb, offset, 1, ENC_BIG_ENDIAN);
2528     offset += 1;
2529
2530     return offset;
2531 }
2532
2533 static int
2534 resp_ldf_list(tvbuff_t *tvb, int offset, proto_tree *pt)
2535 {
2536     int blocks;
2537     int i;
2538     proto_tree  *localTree;
2539
2540     /* block index */
2541     blocks = tvb_get_guint8(tvb, offset);
2542     proto_tree_add_item(pt, hf_gryphon_ldf_number, tvb, offset, 1, ENC_BIG_ENDIAN);
2543     offset += 1;
2544
2545     /* rsvd */
2546     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset, 1, ENC_NA);
2547     offset += 1;
2548
2549     /* number remaining */
2550     proto_tree_add_item(pt, hf_gryphon_ldf_remaining, tvb, offset, 2, ENC_BIG_ENDIAN);
2551     offset += 2;
2552
2553     /* LDF blocks */
2554     for(i=0;i<blocks;i++) {
2555         localTree = proto_tree_add_subtree_format(pt, tvb, offset, 32+80, ett_gryphon_ldf_block, NULL, "LDF %d",i+1);
2556         proto_tree_add_item(localTree, hf_gryphon_ldf_name, tvb, offset, 32, ENC_ASCII|ENC_NA);
2557         offset += 32;
2558         proto_tree_add_item(localTree, hf_gryphon_ldf_description, tvb, offset, 80, ENC_ASCII|ENC_NA);
2559         offset += 80;
2560     }
2561
2562     return offset;
2563 }
2564
2565 static int
2566 cmd_ldf_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
2567 {
2568     /* name */
2569     proto_tree_add_item(pt, hf_gryphon_ldf_name, tvb, offset, 32, ENC_ASCII|ENC_NA);
2570     offset += 32;
2571
2572     return offset;
2573 }
2574
2575 static int
2576 cmd_ldf_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
2577 {
2578     guint32 size;
2579
2580     /* size 4 bytes */
2581     size = tvb_get_ntohl(tvb, offset);
2582     proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_size, tvb, offset, 4, size, "%u", size);
2583     offset += 4;
2584     proto_tree_add_item(pt, hf_gryphon_ldf_name, tvb, offset, 32, ENC_ASCII|ENC_NA);
2585     offset += 32;
2586     proto_tree_add_item(pt, hf_gryphon_ldf_description, tvb, offset, 80, ENC_ASCII|ENC_NA);
2587     offset += 80;
2588     return offset;
2589 }
2590
2591 static int
2592 resp_ldf_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
2593 {
2594     proto_tree_add_item(pt, hf_gryphon_ldf_exists, tvb, offset, 1, ENC_BIG_ENDIAN);
2595     offset += 1;
2596     proto_tree_add_item(pt, hf_gryphon_ldf_desc_pad, tvb, offset, 2, ENC_NA);
2597     offset += 2;
2598     return offset;
2599 }
2600
2601 static int
2602 cmd_ldf_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
2603 {
2604     int msglen;
2605     /*int blockn;*/
2606
2607     msglen = tvb_reported_length_remaining(tvb, offset);
2608
2609     /* block number */
2610     /*blockn = tvb_get_ntohs(tvb, offset);*/
2611     /* 20171101 debug */
2612     /*proto_tree_add_debug_text(pt, "------------------debug offset=%d blockn=%d msglen=%d",offset,blockn,msglen);*/
2613     proto_tree_add_item(pt, hf_gryphon_ldf_blockn, tvb, offset, 2, ENC_BIG_ENDIAN);
2614     offset += 2;
2615
2616     /* 20171101 file string */
2617     proto_tree_add_item(pt, hf_gryphon_ldf_file, tvb, offset, msglen - 2, ENC_NA|ENC_ASCII);
2618     offset += msglen - 2;
2619     return offset;
2620 }
2621
2622 static int
2623 cmd_ldf_parse(tvbuff_t *tvb, int offset, proto_tree *pt)
2624 {
2625     proto_tree_add_item(pt, hf_gryphon_ldf_name, tvb, offset, 32, ENC_ASCII|ENC_NA);
2626     offset += 32;
2627     return offset;
2628 }
2629
2630 static int
2631 resp_get_ldf_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2632 {
2633     int length;
2634     char *string;
2635     guint32 bitrate;
2636     float value;
2637     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2638     proto_tree_add_string(pt, hf_gryphon_ldf_info_pv, tvb, offset, 16, string);
2639     offset += 16;
2640     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2641     proto_tree_add_string(pt, hf_gryphon_ldf_info_lv, tvb, offset, 16, string);
2642     offset += 16;
2643     bitrate = tvb_get_ntohl(tvb, offset);
2644     value = (float)bitrate / (float)1000.0;
2645     proto_tree_add_float_format_value(pt, hf_gryphon_ldf_bitrate, tvb, offset, 4, value, "%.3f Kbps", value);
2646     offset += 4;
2647     return offset;
2648 }
2649
2650 static int
2651 cmd_cnvt_get_values(tvbuff_t *tvb, int offset, proto_tree *pt)
2652 {
2653     guint8 num_signals;
2654     int length;
2655     char *string;
2656     int i;
2657     num_signals = tvb_get_guint8(tvb, offset);
2658     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2659     offset += 1;
2660     for(i=0;i< num_signals; i++) {
2661         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2662         proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2663         offset += length;
2664     }
2665     return offset;
2666 }
2667
2668 static int
2669 resp_cnvt_get_values(tvbuff_t *tvb, int offset, proto_tree *pt)
2670 {
2671     guint8 flag;
2672     guint8 num_signals;
2673     float fvalue;
2674     int i;
2675     int length;
2676     char *string;
2677     num_signals = tvb_get_guint8(tvb, offset);
2678     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2679     offset += 1;
2680     for(i=0;i< num_signals; i++) {
2681         /* flag */
2682         flag = tvb_get_guint8(tvb, offset);
2683         proto_tree_add_item(pt, hf_gryphon_cnvt_flags_getvalues, tvb, offset, 1, ENC_BIG_ENDIAN);
2684         offset += 1;
2685
2686         if(flag & 0x01) {
2687             /* float */
2688             fvalue = tvb_get_ntohieee_float (tvb, offset);
2689             proto_tree_add_float_format_value(pt, hf_gryphon_cnvt_valuef, tvb, offset, 4, fvalue, "%.1f", fvalue);
2690             offset += 4;
2691         }
2692         if(flag & 0x02) {
2693             /* int */
2694             proto_tree_add_item(pt, hf_gryphon_cnvt_valuei, tvb, offset, 4, ENC_BIG_ENDIAN);
2695             offset += 4;
2696         }
2697         if(flag & 0x04) {
2698             /* string */
2699             string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2700             proto_tree_add_string(pt, hf_gryphon_cnvt_values, tvb, offset, length, string);
2701             offset += length;
2702         }
2703
2704     }
2705     return offset;
2706 }
2707
2708 static int
2709 cmd_cnvt_get_units(tvbuff_t *tvb, int offset, proto_tree *pt)
2710 {
2711     guint8 num_signals;
2712     int length;
2713     char *string;
2714     int i;
2715     num_signals = tvb_get_guint8(tvb, offset);
2716     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2717     offset += 1;
2718     for(i=0;i< num_signals; i++) {
2719         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2720         proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2721         offset += length;
2722     }
2723     return offset;
2724 }
2725
2726 static int
2727 resp_cnvt_get_units(tvbuff_t *tvb, int offset, proto_tree *pt)
2728 {
2729     guint8 num_signals;
2730     int i;
2731     int length;
2732     char *string;
2733     num_signals = tvb_get_guint8(tvb, offset);
2734     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2735     offset += 1;
2736     for(i=0;i< num_signals; i++) {
2737         /* string */
2738         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2739         proto_tree_add_string(pt, hf_gryphon_cnvt_units, tvb, offset, length, string);
2740         offset += length;
2741     }
2742     return offset;
2743 }
2744
2745 static int
2746 cmd_cnvt_set_values(tvbuff_t *tvb, int offset, proto_tree *pt)
2747 {
2748     guint8 num_signals;
2749     int length;
2750     char *string;
2751     int i;
2752     float fvalue;
2753     num_signals = tvb_get_guint8(tvb, offset);
2754     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2755     offset += 1;
2756     for(i=0;i< num_signals; i++) {
2757         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2758         proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2759         offset += length;
2760
2761         fvalue = tvb_get_ntohieee_float (tvb, offset);
2762         proto_tree_add_float_format_value(pt, hf_gryphon_cnvt_valuef, tvb, offset, 4, fvalue, "%.2f", fvalue);
2763         offset += 4;
2764     }
2765     return offset;
2766 }
2767
2768 static int
2769 cmd_cnvt_destroy_session(tvbuff_t *tvb, int offset, proto_tree *pt)
2770 {
2771     int msglen;
2772     msglen = tvb_reported_length_remaining(tvb, offset);
2773     proto_tree_add_item(pt, hf_gryphon_ldf_ui, tvb, offset, msglen, ENC_NA);
2774     offset += msglen;
2775     return offset;
2776 }
2777
2778 static int
2779 resp_ldf_get_node_names(tvbuff_t *tvb, int offset, proto_tree *pt)
2780 {
2781     char *string;
2782     int length;
2783     guint16 us_num;
2784     /* number */
2785     us_num = tvb_get_ntohs(tvb, offset);
2786     proto_tree_add_item(pt, hf_gryphon_ldf_num_node_names, tvb, offset, 2, ENC_BIG_ENDIAN);
2787     offset += 2;
2788     /* master node name */
2789     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2790     proto_tree_add_string(pt, hf_gryphon_ldf_master_node_name, tvb, offset, length, string);
2791     offset += length;
2792     us_num -= 1;
2793     while(us_num > 0) {
2794         /* slave node names */
2795         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2796         proto_tree_add_string(pt, hf_gryphon_ldf_slave_node_name, tvb, offset, length, string);
2797         offset += length;
2798         us_num -= 1;
2799     }
2800     return offset;
2801 }
2802
2803 static int
2804 cmd_ldf_get_frames(tvbuff_t *tvb, int offset, proto_tree *pt)
2805 {
2806     char *string;
2807     int length;
2808     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2809     proto_tree_add_string(pt, hf_gryphon_ldf_get_frame, tvb, offset, length, string);
2810     offset += length;
2811     return offset;
2812 }
2813
2814 static int
2815 resp_ldf_get_frames(tvbuff_t *tvb, int offset, proto_tree *pt)
2816 {
2817     char *string;
2818     int length;
2819     guint16 us_num;
2820     guint8 pid;
2821     /* number */
2822     us_num = tvb_get_ntohs(tvb, offset);
2823     proto_tree_add_item(pt, hf_gryphon_ldf_num_frames, tvb, offset, 2, ENC_BIG_ENDIAN);
2824     offset += 2;
2825     while(us_num > 0) {
2826         /* id */
2827         pid = tvb_get_guint8(tvb, offset);
2828         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, pid, "0x%x ",pid);
2829         offset += 1;
2830         /* frame name */
2831         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2832         proto_tree_add_string(pt, hf_gryphon_ldf_get_frame, tvb, offset, length, string);
2833         offset += length;
2834         us_num -= 1;
2835     }
2836     return offset;
2837 }
2838
2839 static int
2840 cmd_ldf_get_frame_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2841 {
2842     char *string;
2843     int length;
2844     guint8 id;
2845     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2846     if(length > 1) {
2847         proto_tree_add_string(pt, hf_gryphon_ldf_get_frame, tvb, offset, length, string);
2848         offset += length;
2849         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, 0, "(Id not used)");
2850         offset += 1;
2851     } else {
2852         id = tvb_get_guint8(tvb, offset);
2853         proto_tree_add_uint_format_value(pt, hf_gryphon_ldf_ioctl_setflags_flags, tvb, offset, 1, id, "0x%x ",id);
2854         offset += 1;
2855     }
2856     return offset;
2857 }
2858
2859 static int
2860 resp_ldf_get_frame_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2861 {
2862     char *string;
2863     int length;
2864     guint8 count, i;
2865     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num, tvb, offset, 1, ENC_BIG_ENDIAN);
2866     offset += 1;
2867     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2868     proto_tree_add_string(pt, hf_gryphon_ldf_get_frame_pub, tvb, offset, length, string);
2869     offset += length;
2870     count = tvb_get_guint8(tvb, offset);
2871     proto_tree_add_item(pt, hf_gryphon_ldf_get_frame_num_signals, tvb, offset, 1, ENC_BIG_ENDIAN);
2872     offset += 1;
2873     for (i = 0; i < count; i++) {
2874         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2875         proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2876         offset += length;
2877     }
2878     return offset;
2879 }
2880
2881 static int
2882 cmd_ldf_get_signal_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2883 {
2884     char *string;
2885     int length;
2886     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2887     proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2888     offset += length;
2889     return offset;
2890 }
2891
2892 static int
2893 resp_ldf_get_signal_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2894 {
2895     char *string;
2896     int length;
2897 /* offset */
2898     proto_tree_add_item(pt, hf_gryphon_ldf_signal_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
2899     offset += 1;
2900
2901 /* length */
2902     proto_tree_add_item(pt, hf_gryphon_ldf_signal_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2903     offset += 1;
2904
2905 /* signal encoding name */
2906     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2907     proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_name, tvb, offset, length, string);
2908     offset += length;
2909     return offset;
2910 }
2911
2912 static int
2913 cmd_ldf_get_signal_detail(tvbuff_t *tvb, int offset, proto_tree *pt)
2914 {
2915     char *string;
2916     int length;
2917     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2918     proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
2919     offset += length;
2920     return offset;
2921 }
2922
2923 static int
2924 resp_ldf_do_encoding_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2925 {
2926     char *string;
2927     int length;
2928     /* encoding */
2929     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2930     proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_type, tvb, offset, 12, string);
2931     offset += 12;
2932     if(string[0] == 'l') {
2933         /* logical */
2934         proto_tree_add_item(pt, hf_gryphon_ldf_encoding_value, tvb, offset, 2, ENC_BIG_ENDIAN);
2935         offset += 2;
2936         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2937         proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_logical, tvb, offset, length, string);
2938         offset += length;
2939     } else if(string[0] == 'p') {
2940         /* physical */
2941         proto_tree_add_item(pt, hf_gryphon_ldf_encoding_min, tvb, offset, 2, ENC_BIG_ENDIAN);
2942         offset += 2;
2943         proto_tree_add_item(pt, hf_gryphon_ldf_encoding_max, tvb, offset, 2, ENC_BIG_ENDIAN);
2944         offset += 2;
2945         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2946         proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_logical, tvb, offset, length, string);
2947         offset += length;
2948         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2949         proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_logical, tvb, offset, length, string);
2950         offset += length;
2951         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2952         proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_logical, tvb, offset, length, string);
2953         offset += length;
2954     } else if(string[0] == 'b') {
2955         proto_tree_add_item(pt, hf_gryphon_ldf_encoding_value, tvb, offset, 2, ENC_BIG_ENDIAN);
2956         offset += 2;
2957         /* bcd */
2958     } else if(string[0] == 'a') {
2959         proto_tree_add_item(pt, hf_gryphon_ldf_encoding_value, tvb, offset, 2, ENC_BIG_ENDIAN);
2960         offset += 2;
2961         /* ascii */
2962     } else {
2963         /* error */
2964     }
2965     return(offset);
2966 }
2967
2968 static int
2969 resp_ldf_get_signal_detail(tvbuff_t *tvb, int offset, proto_tree *pt)
2970 {
2971     guint16 us_num;
2972 /* offset */
2973     proto_tree_add_item(pt, hf_gryphon_ldf_signal_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
2974     offset += 1;
2975
2976 /* length */
2977     proto_tree_add_item(pt, hf_gryphon_ldf_signal_length, tvb, offset, 1, ENC_BIG_ENDIAN);
2978     offset += 1;
2979
2980 /* number */
2981     us_num = tvb_get_ntohs(tvb, offset);
2982     proto_tree_add_item(pt, hf_gryphon_ldf_num_encodings, tvb, offset, 2, ENC_BIG_ENDIAN);
2983     offset += 2;
2984     while(us_num > 0) {
2985         offset = resp_ldf_do_encoding_block(tvb, offset, pt);
2986         us_num -= 1;
2987     }
2988
2989     return offset;
2990 }
2991
2992 static int
2993 cmd_ldf_get_encoding_info(tvbuff_t *tvb, int offset, proto_tree *pt)
2994 {
2995     char *string;
2996     int length;
2997     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
2998     proto_tree_add_string(pt, hf_gryphon_ldf_signal_encoding_name, tvb, offset, length, string);
2999     offset += length;
3000     return offset;
3001 }
3002
3003 static int
3004 resp_ldf_get_encoding_info(tvbuff_t *tvb, int offset, proto_tree *pt)
3005 {
3006     guint16 us_num;
3007     /* number */
3008     us_num = tvb_get_ntohs(tvb, offset);
3009     proto_tree_add_item(pt, hf_gryphon_ldf_num_encodings, tvb, offset, 2, ENC_BIG_ENDIAN);
3010     offset += 2;
3011     while(us_num > 0) {
3012         /* encoding data */
3013         offset = resp_ldf_do_encoding_block(tvb, offset, pt);
3014         us_num -= 1;
3015     }
3016     return offset;
3017 }
3018
3019 static int
3020 cmd_ldf_save_session(tvbuff_t *tvb, int offset, proto_tree *pt)
3021 {
3022     int msglen;
3023     msglen = tvb_reported_length_remaining(tvb, offset);
3024     proto_tree_add_item(pt, hf_gryphon_ldf_restore_session, tvb, offset, msglen, ENC_NA);
3025     offset += msglen;
3026     return offset;
3027 }
3028
3029 static int
3030 cmd_ldf_emulate_nodes(tvbuff_t *tvb, int offset, proto_tree *pt)
3031 {
3032     int nnodes;
3033     int node_numb=1;
3034     int i;
3035     unsigned int xchannel;
3036     char *string;
3037     int length;
3038     proto_tree  *tree2;
3039
3040     nnodes = tvb_get_guint8(tvb, offset);
3041     proto_tree_add_item(pt, hf_gryphon_ldf_nodenumber, tvb, offset, 1, ENC_BIG_ENDIAN);
3042     offset += 1;
3043
3044     for(i=0;i<nnodes;i++) {
3045         /* first, find the end of the string, then use that string len to build a subtree */
3046
3047         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset+1, &length, ENC_ASCII);
3048
3049         tree2 = proto_tree_add_subtree_format(pt, tvb, offset, 1+length, ett_gryphon_lin_emulate_node, NULL, "Node %u", node_numb);
3050
3051         xchannel = tvb_get_guint8(tvb, offset);
3052         proto_tree_add_uint(tree2, hf_gryphon_sched_channel, tvb, offset, 1, xchannel);
3053         offset += 1;
3054
3055         proto_tree_add_string(tree2, hf_gryphon_lin_nodename, tvb, offset, length, string);
3056         offset += length;
3057
3058         node_numb++;
3059     }
3060     return offset;
3061 }
3062
3063 static int
3064 resp_ldf_get_schedules(tvbuff_t *tvb, int offset, proto_tree *pt)
3065 {
3066     char *string;
3067     int length;
3068     guint16 us_num;
3069     /* number */
3070     us_num = tvb_get_ntohs(tvb, offset);
3071     proto_tree_add_item(pt, hf_gryphon_ldf_num_schedules, tvb, offset, 2, ENC_BIG_ENDIAN);
3072     offset += 2;
3073     while(us_num > 0) {
3074         /* slave node names */
3075         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
3076         proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, length, string);
3077         offset += length;
3078         us_num -= 1;
3079     }
3080     return offset;
3081 }
3082
3083 static int
3084 cmd_ldf_start_schedule(tvbuff_t *tvb, int offset, proto_tree *pt)
3085 {
3086     char *string;
3087     int length;
3088     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
3089     proto_tree_add_string(pt, hf_gryphon_ldf_schedule_name, tvb, offset, length, string);
3090     offset += length;
3091     return offset;
3092 }
3093
3094 static int
3095 cmd_ldf_get_node_signals(tvbuff_t *tvb, int offset, proto_tree *pt)
3096 {
3097     char *string;
3098     int length;
3099     string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
3100     proto_tree_add_string(pt, hf_gryphon_ldf_node_name, tvb, offset, length, string);
3101     offset += length;
3102     return offset;
3103 }
3104
3105 static int
3106 resp_ldf_get_node_signals(tvbuff_t *tvb, int offset, proto_tree *pt)
3107 {
3108     char *string;
3109     int length;
3110     guint16 us_num;
3111     /* number */
3112     us_num = tvb_get_ntohs(tvb, offset);
3113     proto_tree_add_item(pt, hf_gryphon_ldf_num_signal_names, tvb, offset, 2, ENC_BIG_ENDIAN);
3114     offset += 2;
3115     while(us_num > 0) {
3116         /* signal names */
3117         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
3118         proto_tree_add_string(pt, hf_gryphon_ldf_signal_name, tvb, offset, length, string);
3119         offset += length;
3120         us_num -= 1;
3121     }
3122     return offset;
3123 }
3124
3125 static int
3126 cmd_restore_session(tvbuff_t *tvb, int offset, proto_tree *pt)
3127 {
3128     int msglen;
3129     msglen = tvb_reported_length_remaining(tvb, offset);
3130     proto_tree_add_item(pt, hf_gryphon_ldf_restore_session, tvb, offset, msglen, ENC_NA);
3131     offset += msglen;
3132     return offset;
3133 }
3134
3135 static int
3136 resp_restore_session(tvbuff_t *tvb, int offset, proto_tree *pt)
3137 {
3138     proto_tree_add_item(pt, hf_gryphon_ldf_name, tvb, offset, 32, ENC_ASCII|ENC_NA);
3139     offset += 32;
3140     return offset;
3141 }
3142
3143 static int
3144 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
3145 {
3146     proto_item  *item;
3147     proto_tree  *tree;
3148     int         blocks, responses, i, msglen, length;
3149     int padding;
3150     int         action, actionType, actionValue;
3151     tvbuff_t    *next_tvb;
3152
3153     actionType = 0;
3154     /* flags */
3155     item = proto_tree_add_item(pt, hf_gryphon_addresp_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
3156     tree = proto_item_add_subtree (item, ett_gryphon_flags);
3157     /* 20171017 fixed display of filter flags */
3158     /* flags: active */
3159     proto_tree_add_item(tree, hf_gryphon_addresp_flags_active, tvb, offset, 1, ENC_BIG_ENDIAN);
3160
3161     offset += 1;
3162
3163     /* number of filter blocks */
3164     blocks = tvb_get_guint8(tvb, offset);
3165     proto_tree_add_item(pt, hf_gryphon_addresp_blocks, tvb, offset, 1, ENC_BIG_ENDIAN);
3166     offset += 1;
3167
3168     /* number of responses */
3169     responses = tvb_get_guint8(tvb, offset);
3170     proto_tree_add_item(pt, hf_gryphon_addresp_responses, tvb, offset, 1, ENC_BIG_ENDIAN);
3171     offset += 1;
3172
3173     /* old handle */
3174     proto_tree_add_item(pt, hf_gryphon_addresp_old_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
3175     offset += 1;
3176
3177     /* action */
3178     action = tvb_get_guint8(tvb, offset);
3179     item = proto_tree_add_item(pt, hf_gryphon_addresp_action, tvb, offset, 1, ENC_BIG_ENDIAN);
3180     tree = proto_item_add_subtree (item, ett_gryphon_flags);
3181     actionValue = tvb_get_ntohs(tvb, offset+2);
3182     if (actionValue) {
3183         if (action & FR_PERIOD_MSGS) {
3184             actionType = 1;
3185         } else {
3186             actionType = 0;
3187         }
3188
3189         proto_tree_add_item(tree, hf_gryphon_addresp_action_period, tvb, offset, 1, ENC_BIG_ENDIAN);
3190     }
3191
3192     proto_tree_add_item(tree, hf_gryphon_addresp_action_deact_on_event, tvb, offset, 1, ENC_BIG_ENDIAN);
3193     proto_tree_add_item(tree, hf_gryphon_addresp_action_deact_after_period, tvb, offset, 1, ENC_BIG_ENDIAN);
3194     offset += 1;
3195
3196     /* reserved */
3197     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset, 1, ENC_NA);
3198     offset += 1;
3199     if (actionValue) {
3200         if (actionType == 1) {
3201             proto_tree_add_uint_format_value(pt, hf_gryphon_addresp_action_period_type, tvb,
3202                     offset, 2, actionValue, "Period: %d messages", actionValue);
3203         } else {
3204             proto_tree_add_uint_format_value(pt, hf_gryphon_addresp_action_period_type, tvb,
3205                     offset, 2, actionValue, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
3206         }
3207     } else {
3208         /* 20171017 */
3209         /* value 2-bytes */
3210         proto_tree_add_uint_format_value(pt, hf_gryphon_addresp_action_period_type, tvb, offset, 2, actionValue, "(not used)");
3211     }
3212     offset += 2;
3213
3214     for (i = 1; i <= blocks; i++) {
3215         length = tvb_get_ntohs(tvb, offset+2) + 8;
3216         padding = 3 - (length + 3) % 4;
3217         tree = proto_tree_add_subtree_format(pt, tvb, offset, length + padding, ett_gryphon_cmd_filter_block, NULL, "Filter block %d", i);
3218         /* 20171017 fixed display of filter block padding */
3219         offset = filter_block(tvb, offset, tree);
3220     }
3221     for (i = 1; i <= responses; i++) {
3222         msglen = tvb_get_ntohs(tvb, offset+4) + 8;
3223         padding = 3 - (msglen + 3) % 4;
3224         tree = proto_tree_add_subtree_format(pt, tvb, offset, msglen + padding, ett_gryphon_cmd_response_block, NULL, "Response block %d", i);
3225         next_tvb = tvb_new_subset_length(tvb, offset, msglen + padding);
3226         offset = dissect_gryphon_message_with_offset(next_tvb, offset, NULL, tree, TRUE);
3227         /*offset += msglen + padding;*/
3228     }
3229     return offset;
3230 }
3231
3232 static int
3233 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
3234 {
3235     proto_tree_add_item(pt, hf_gryphon_addresp_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
3236     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
3237     offset += 4;
3238     return offset;
3239 }
3240
3241 static int
3242 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
3243 {
3244     guint8   dest = tvb_get_guint8(tvb, offset-5),
3245              resp_handle = tvb_get_guint8(tvb, offset);
3246
3247     if (resp_handle)
3248         proto_tree_add_item(pt, hf_gryphon_modresp_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
3249     else if (dest)
3250         proto_tree_add_uint_format_value(pt, hf_gryphon_modresp_handle, tvb,
3251                     offset, 1, dest, "Response handles: all on channel %c", dest);
3252     else
3253         proto_tree_add_uint_format_value(pt, hf_gryphon_modresp_handle, tvb, offset, 1,
3254                 0, "Response handles: all");
3255
3256     proto_tree_add_item(pt, hf_gryphon_modresp_action, tvb, offset+1, 1, ENC_BIG_ENDIAN);
3257     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
3258     offset += 4;
3259     return offset;
3260 }
3261
3262 static int
3263 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
3264 {
3265     int         handles = tvb_get_guint8(tvb, offset);
3266     int         i, padding, handle;
3267
3268     proto_tree_add_item(pt, hf_gryphon_num_resphan, tvb, offset, 1, ENC_BIG_ENDIAN);
3269     for (i = 1; i <= handles; i++){
3270         handle = tvb_get_guint8(tvb, offset+i);
3271         proto_tree_add_uint_format(pt, hf_gryphon_handle, tvb, offset+i, 1, handle, "Handle %d: %u", i,
3272             handle);
3273     }
3274     padding = 3 - (handles + 1 + 3) % 4;
3275     if (padding)
3276         proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset+1+handles, padding, ENC_NA);
3277     offset += 1+handles+padding;
3278     return offset;
3279 }
3280
3281 static int
3282 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
3283 {
3284     proto_tree_add_item(pt, hf_gryphon_transmit_sched_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3285     offset += 4;
3286     return offset;
3287 }
3288
3289 static int
3290 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
3291 {
3292     proto_tree_add_item(pt, hf_gryphon_desc_program_size, tvb, offset, 4, ENC_BIG_ENDIAN);
3293     offset += 4;
3294
3295     proto_tree_add_item(pt, hf_gryphon_desc_program_name, tvb, offset, 32, ENC_NA|ENC_ASCII);
3296     offset += 32;
3297
3298     proto_tree_add_item(pt, hf_gryphon_desc_program_description, tvb, offset, 80, ENC_NA|ENC_ASCII);
3299     offset += 80;
3300
3301     return offset;
3302 }
3303
3304 static int
3305 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
3306 {
3307     proto_item  *item;
3308     proto_tree  *tree;
3309
3310     item = proto_tree_add_item(pt, hf_gryphon_desc_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
3311     tree = proto_item_add_subtree (item, ett_gryphon_flags);
3312     proto_tree_add_item(tree, hf_gryphon_desc_flags_program, tvb, offset, 1, ENC_BIG_ENDIAN);
3313     proto_tree_add_item(pt, hf_gryphon_desc_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
3314     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+2, 2, ENC_NA);
3315     offset += 4;
3316     return offset;
3317 }
3318
3319 static int
3320 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
3321 {
3322     int             msglen;
3323     unsigned int    length;
3324
3325     msglen = tvb_reported_length_remaining(tvb, offset);
3326     proto_tree_add_item(pt, hf_gryphon_upload_block_number, tvb, offset, 2, ENC_BIG_ENDIAN);
3327     proto_tree_add_item(pt, hf_gryphon_upload_handle, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3328     offset += 3;
3329     msglen -= 3;
3330
3331     length = msglen;
3332     proto_tree_add_item(pt, hf_gryphon_upload_data, tvb, offset, length, ENC_NA);
3333     offset += length;
3334
3335     length = 3 - (length + 3) % 4;
3336     if (length) {
3337         proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset, length, ENC_NA);
3338         offset += length;
3339     }
3340     return offset;
3341 }
3342
3343 static int
3344 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
3345 {
3346     proto_tree_add_item(pt, hf_gryphon_delete, tvb, offset, 32, ENC_NA|ENC_ASCII);
3347     offset += 32;
3348     return offset;
3349 }
3350
3351 static int
3352 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
3353 {
3354     proto_tree_add_item(pt, hf_gryphon_list_block_number, tvb, offset, 1, ENC_BIG_ENDIAN);
3355     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
3356     offset += 4;
3357     return offset;
3358 }
3359
3360 static int
3361 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
3362 {
3363     proto_tree  *tree;
3364     unsigned int    i, count;
3365
3366     count = tvb_get_guint8(tvb, offset);
3367     proto_tree_add_item(pt, hf_gryphon_list_num_programs, tvb, offset, 1, ENC_BIG_ENDIAN);
3368     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 1, ENC_NA);
3369     offset += 2;
3370
3371     proto_tree_add_item(pt, hf_gryphon_list_num_remain_programs, tvb, offset, 2, ENC_BIG_ENDIAN);
3372     offset += 2;
3373
3374     for (i = 1; i <= count; i++) {
3375         tree = proto_tree_add_subtree_format(pt, tvb, offset, 112, ett_gryphon_pgm_list, NULL, "Program %u", i);
3376         proto_tree_add_item(tree, hf_gryphon_list_name, tvb, offset, 32, ENC_NA|ENC_ASCII);
3377         offset += 32;
3378
3379         proto_tree_add_item(tree, hf_gryphon_list_description, tvb, offset, 80, ENC_NA|ENC_ASCII);
3380         offset += 80;
3381     }
3382     return offset;
3383 }
3384
3385 static int
3386 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
3387 {
3388     char      *string;
3389     gint      length;
3390     int       msglen;
3391     int       hdr_stuff = offset;
3392
3393     msglen = tvb_reported_length_remaining(tvb, offset);
3394     offset = cmd_delete(tvb, offset, pt);       /* decode the name */
3395     if (offset < msglen + hdr_stuff) {
3396         string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &length, ENC_ASCII);
3397         if (length > 1) {
3398             proto_tree_add_string(pt, hf_gryphon_start_arguments, tvb, offset,
3399                 length, string);
3400             offset += length;
3401
3402             length = 3 - (length + 3) % 4;
3403             if (length) {
3404                 proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset, length, ENC_NA);
3405                 offset += length;
3406             }
3407         }
3408     }
3409     return offset;
3410 }
3411
3412 static int
3413 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
3414 {
3415     int             msglen;
3416
3417     msglen = tvb_reported_length_remaining(tvb, offset);
3418     if (msglen > 0) {
3419         proto_tree_add_item(pt, hf_gryphon_start_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
3420         proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
3421         offset += 4;
3422     }
3423     return offset;
3424 }
3425
3426 static int
3427 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
3428 {
3429     proto_item  *item;
3430     proto_tree  *tree;
3431     unsigned int   i, copies, length, channel;
3432
3433     copies = tvb_get_guint8(tvb, offset);
3434     item = proto_tree_add_item(pt, hf_gryphon_status_num_running_copies, tvb, offset, 1, ENC_BIG_ENDIAN);
3435     tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
3436     offset += 1;
3437     if (copies) {
3438         for (i = 1; i <= copies; i++) {
3439             channel = tvb_get_guint8(tvb, offset);
3440             proto_tree_add_uint_format(tree, hf_gryphon_program_channel_number, tvb, offset, 1, channel,
3441                     "Program %u channel (client) number %u", i, channel);
3442             offset += 1;
3443         }
3444     }
3445     length = 3 - (copies + 1 + 3) % 4;
3446     if (length) {
3447         proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset, length, ENC_NA);
3448         offset += length;
3449     }
3450     return offset;
3451 }
3452
3453 static int
3454 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
3455 {
3456     int             msglen;
3457     proto_tree      *tree;
3458     unsigned int    i, size, padding, option, option_length, option_value;
3459     const char      *string, *string1;
3460
3461     msglen = tvb_reported_length_remaining(tvb, offset);
3462     proto_tree_add_item(pt, hf_gryphon_options_handle, tvb, offset, 1, ENC_BIG_ENDIAN);
3463     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
3464     offset += 4;
3465     msglen -= 4;
3466
3467     for (i = 1; msglen > 0; i++) {
3468         option_length = tvb_get_guint8(tvb, offset+1);
3469         size = option_length + 2;
3470         padding = 3 - ((size + 3) %4);
3471         tree = proto_tree_add_subtree_format(pt, tvb, offset, size + padding, ett_gryphon_pgm_options, NULL, "Option number %u", i);
3472         option = tvb_get_guint8(tvb, offset);
3473         switch (option_length) {
3474         case 1:
3475             option_value = tvb_get_guint8(tvb, offset+2);
3476             break;
3477         case 2:
3478             option_value = tvb_get_ntohs(tvb, offset+2);
3479             break;
3480         case 4:
3481             option_value = tvb_get_ntohl(tvb, offset+2);
3482             break;
3483         default:
3484             option_value = 0;
3485         }
3486         string = "unknown option";
3487         string1 = "unknown option data";
3488         switch (option) {
3489         case PGM_CONV:
3490             string = "Type of data in the file";
3491             switch (option_value) {
3492             case PGM_BIN:
3493                 string1 = "Binary - Don't modify";
3494                 break;
3495             case PGM_ASCII:
3496                 string1 = "ASCII - Remove CR's";
3497                 break;
3498             }
3499             break;
3500         case PGM_TYPE:
3501             string = "Type of file";
3502             switch (option_value) {
3503             case PGM_PGM:
3504                 string1 = "Executable";
3505                 break;
3506             case PGM_DATA:
3507                 string1 = "Data";
3508                 break;
3509             }
3510             break;
3511         }
3512         proto_tree_add_uint_format_value(tree, hf_gryphon_option, tvb, offset, 1, option, "%s", string);
3513         proto_tree_add_bytes_format_value(tree, hf_gryphon_option_data, tvb, offset+2, option_length, NULL, "%s", string1);
3514         if (padding)
3515             proto_tree_add_item(tree, hf_gryphon_padding, tvb, offset+option_length+2, padding, ENC_NA);
3516         offset += size + padding;
3517         msglen -= size + padding;
3518     }
3519     return offset;
3520 }
3521
3522 static int
3523 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
3524 {
3525     int          msglen;
3526     guint8 file;
3527
3528     msglen = tvb_reported_length_remaining(tvb, offset);
3529     file = tvb_get_guint8(tvb, offset);
3530     if (file == 0)
3531         proto_tree_add_uint_format(pt, hf_gryphon_cmd_file, tvb, offset, 1, file, "First group of names");
3532     else
3533         proto_tree_add_uint_format(pt, hf_gryphon_cmd_file, tvb, offset, 1, file, "Subsequent group of names");
3534
3535     proto_tree_add_item(pt, hf_gryphon_files, tvb, offset+1, msglen-1, ENC_NA|ENC_ASCII);
3536     offset += msglen;
3537     return offset;
3538 }
3539
3540 static int
3541 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
3542 {
3543     int            msglen;
3544     guint8         flag;
3545
3546     msglen = tvb_reported_length_remaining(tvb, offset);
3547     flag = tvb_get_guint8(tvb, offset);
3548     proto_tree_add_uint_format_value(pt, hf_gryphon_more_filenames, tvb, offset, 1, flag, "%s", flag ? "Yes": "No");
3549     proto_tree_add_item(pt, hf_gryphon_filenames, tvb, offset+1, msglen-1, ENC_ASCII|ENC_NA);
3550     offset += msglen;
3551     return offset;
3552 }
3553
3554 /* 20171012 gryphon command for USDT */
3555 static int
3556 cmd_usdt_register_non_legacy(tvbuff_t *tvb, int offset, proto_tree *pt)
3557 {
3558     int         remain;
3559     unsigned int ui_block;
3560     guint32 ui_ids;
3561     int         id_usdtreq;
3562     int         id_usdtresp;
3563     int         id_uudtresp;
3564     guint8      u8_options;
3565     guint8      u8USDTReqExtAddr_bit;
3566     guint8      u8USDTRespExtAddr_bit;
3567     guint8      u8UUDTRespExtAddr_bit;
3568     guint8      u8USDTReqExtAddr;
3569     guint8      u8USDTRespExtAddr;
3570     guint8      u8UUDTRespExtAddr;
3571     guint8      u8USDTReqHeaderSize;
3572     guint8      u8USDTRespHeaderSize;
3573     guint8      u8UUDTRespHeaderSize;
3574     guint8      flags;
3575     proto_tree  *tree1;
3576     proto_tree  *tree2;
3577     proto_tree  *tree3;
3578     proto_tree  *tree4;
3579     proto_tree  *tree5;
3580     static const int * transmit_options_flags[] = {
3581         &hf_gryphon_usdt_transmit_options_flags_echo,
3582         &hf_gryphon_usdt_transmit_options_action,
3583         &hf_gryphon_usdt_transmit_options_done_event,
3584         &hf_gryphon_usdt_transmit_options_echo_short,
3585         &hf_gryphon_usdt_transmit_options_rx_nth_fc,
3586         NULL
3587     };
3588     static const int * receive_options_flags[] = {
3589         &hf_gryphon_usdt_receive_options_action,
3590         &hf_gryphon_usdt_receive_options_firstframe_event,
3591         &hf_gryphon_usdt_receive_options_lastframe_event,
3592         &hf_gryphon_usdt_receive_options_tx_nth_fc,
3593         NULL
3594     };
3595     static const int * length_options_flags[] = {
3596         &hf_gryphon_usdt_length_control_j1939,
3597         NULL
3598     };
3599     remain = tvb_reported_length_remaining(tvb, offset);
3600
3601     /* 20171012 */
3602     /* Action flags */
3603     flags = tvb_get_guint8(tvb, offset);
3604     tree1 = proto_tree_add_subtree_format(pt, tvb, offset, 1, ett_gryphon_usdt_action_flags, NULL, "Action flags 0x%02x", flags);
3605     proto_tree_add_item(tree1, hf_gryphon_usdt_action_flags_non_legacy, tvb, offset, 1, ENC_BIG_ENDIAN);
3606     offset += 1;
3607     remain -= 1;
3608
3609     /* tx options */
3610     flags = tvb_get_guint8(tvb, offset);
3611     tree2 = proto_tree_add_subtree_format(pt, tvb, offset, 1, ett_gryphon_usdt_tx_options_flags, NULL, "Transmit options 0x%02x", flags);
3612     proto_tree_add_bitmask(tree2, tvb, offset, hf_gryphon_usdt_transmit_options_flags, ett_gryphon_flags, transmit_options_flags, ENC_BIG_ENDIAN);
3613     offset += 1;
3614     remain -= 1;
3615
3616     /* rx options */
3617     flags = tvb_get_guint8(tvb, offset);
3618     tree3 = proto_tree_add_subtree_format(pt, tvb, offset, 1, ett_gryphon_usdt_rx_options_flags, NULL, "Receive options 0x%02x", flags);
3619     proto_tree_add_bitmask(tree3, tvb, offset, hf_gryphon_usdt_receive_options_flags, ett_gryphon_flags, receive_options_flags, ENC_BIG_ENDIAN);
3620     offset += 1;
3621     remain -= 1;
3622
3623     /* reserved */
3624     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset, 1, ENC_NA);
3625     offset += 1;
3626     remain -= 1;
3627
3628     /* blocks */
3629     ui_block = 1;
3630     while (remain > 0) {
3631         tree4 = proto_tree_add_subtree_format(pt, tvb, offset, 20, ett_gryphon_usdt_data_block, NULL, "Block %u", ui_block);
3632
3633         /* TODO implement J1939-style length address src and dst byte swap */
3634
3635         /* mask the upper bits of the long */
3636         /* number of IDs in the block */
3637         ui_ids = tvb_get_ntohl (tvb, offset);
3638         u8_options = ((ui_ids >> 24) & 0xE0);
3639         ui_ids &= 0x1FFFFFFF; /* mask the upper control bits */
3640         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_nids, tvb, offset, 4, ui_ids, "%u", ui_ids);
3641
3642         if(ui_ids == 0) {
3643             proto_item_set_len(tree4, 20);
3644         } else {
3645
3646
3647             /* display control bits */
3648             tree5 = proto_tree_add_subtree_format(tree4, tvb, offset, 1, ett_gryphon_usdt_len_options_flags, NULL, "Options 0x%02x", u8_options);
3649             proto_tree_add_bitmask(tree5, tvb, offset, hf_gryphon_usdt_length_options_flags, ett_gryphon_flags, length_options_flags, ENC_BIG_ENDIAN);
3650             offset += 4;
3651             remain -= 4;
3652
3653             u8UUDTRespExtAddr = tvb_get_guint8(tvb, offset+10);
3654             u8USDTRespExtAddr = tvb_get_guint8(tvb, offset+13);
3655             u8USDTReqExtAddr = tvb_get_guint8(tvb, offset+16);
3656             if(ui_ids == 1) {
3657                 /* single ID */
3658
3659                 /* add extended address display of the IDs */
3660                 /* mask the upper bits of the IDs */
3661                 /* usdt req */
3662                 id_usdtreq = tvb_get_ntohl (tvb, offset);
3663                 u8USDTReqExtAddr_bit = ((id_usdtreq >> 24) & 0x20);
3664                 u8USDTReqHeaderSize = ((id_usdtreq >> 24) & 0x80);
3665                 id_usdtreq &= 0x1FFFFFFF;
3666                 /* usdt req */
3667                 if(u8USDTReqExtAddr_bit == 0) {
3668                     if(u8USDTReqHeaderSize == 0) {
3669                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%02x (11-bit)", id_usdtreq);
3670                     } else {
3671                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%04x (29-bit)", id_usdtreq);
3672                     }
3673                 } else {
3674                     u8USDTReqExtAddr = tvb_get_guint8(tvb, offset+16);
3675                     if(u8USDTReqHeaderSize == 0) {
3676                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%02x (11-bit extended address %01x)", id_usdtreq, u8USDTReqExtAddr);
3677                     } else {
3678                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%04x (29-bit extended address %01x)", id_usdtreq, u8USDTReqExtAddr);
3679                     }
3680                 }
3681                 offset += 4;
3682                 remain -= 4;
3683
3684                 /* usdt resp */
3685                 id_usdtresp = tvb_get_ntohl (tvb, offset);
3686                 u8USDTRespExtAddr_bit = ((id_usdtresp >> 24) & 0x20);
3687                 u8USDTRespHeaderSize = ((id_usdtresp >> 24) & 0x80);
3688                 id_usdtresp &= 0x1FFFFFFF;
3689                 /* usdt resp */
3690                 if(u8USDTRespExtAddr_bit == 0) {
3691                     if(u8USDTRespHeaderSize == 0) {
3692                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%02x (11-bit)", id_usdtresp);
3693                     } else {
3694                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%04x (29-bit)", id_usdtresp);
3695                     }
3696                 } else {
3697                     u8USDTRespExtAddr = tvb_get_guint8(tvb, offset+13);
3698                     if(u8USDTRespHeaderSize == 0) {
3699                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%02x (11-bit extended address %01x)", id_usdtresp, u8USDTRespExtAddr);
3700                     } else {
3701                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%04x (29-bit extended address %01x)", id_usdtresp, u8USDTRespExtAddr);
3702                     }
3703                 }
3704                 offset += 4;
3705                 remain -= 4;
3706
3707
3708                 /* uudt resp */
3709                 id_uudtresp = tvb_get_ntohl (tvb, offset);
3710                 u8UUDTRespExtAddr_bit = ((id_uudtresp >> 24) & 0x20);
3711                 u8UUDTRespHeaderSize = ((id_uudtresp >> 24) & 0x80);
3712                 id_uudtresp &= 0x1FFFFFFF;
3713                 /* uudt resp */
3714                 if(u8UUDTRespExtAddr_bit == 0) {
3715                     if(u8UUDTRespHeaderSize == 0) {
3716                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%02x (11-bit)", id_uudtresp);
3717                     } else {
3718                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%04x (29-bit)", id_uudtresp);
3719                     }
3720                 } else {
3721                     u8UUDTRespExtAddr = tvb_get_guint8(tvb, offset+10);
3722                     if(u8UUDTRespHeaderSize == 0) {
3723                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%02x (11-bit extended address %01x)", id_uudtresp, u8UUDTRespExtAddr);
3724                     } else {
3725                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%04x (29-bit extended address %01x)", id_uudtresp, u8UUDTRespExtAddr);
3726                     }
3727                 }
3728                 offset += 4;
3729                 remain -= 4;
3730
3731
3732             } else {
3733                 /* multiple IDs */
3734
3735                 /* add extended address display of the IDs */
3736                 /* mask the upper bits of the IDs */
3737
3738                 /* usdt req */
3739                 id_usdtreq = tvb_get_ntohl (tvb, offset);
3740                 u8USDTReqExtAddr_bit = ((id_usdtreq >> 24) & 0x20);
3741                 u8USDTReqHeaderSize = ((id_usdtreq >> 24) & 0x80);
3742                 id_usdtreq &= 0x1FFFFFFF;
3743                 /* usdt req */
3744                 if(u8USDTReqExtAddr_bit == 0) {
3745                     if(u8USDTReqHeaderSize == 0) {
3746                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%02x through 0x%02x (11-bit)", id_usdtreq, id_usdtreq + ui_ids-1);
3747                     } else {
3748                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%04x through 0x%04x (29-bit)", id_usdtreq, id_usdtreq + ui_ids-1);
3749                     }
3750                 } else {
3751                     u8USDTReqExtAddr = tvb_get_guint8(tvb, offset+16);
3752                     if(u8USDTReqHeaderSize == 0) {
3753                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%02x through 0x%02x (11-bit extended address %0x)", id_usdtreq, id_usdtreq + ui_ids-1, u8USDTReqExtAddr);
3754                     } else {
3755                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request, tvb, offset, 4, id_usdtreq, "0x%04x through 0x%04x (29-bit extended address %0x)", id_usdtreq, id_usdtreq + ui_ids-1, u8USDTReqExtAddr);
3756                     }
3757                 }
3758                 offset += 4;
3759                 remain -= 4;
3760
3761                 /* usdt resp */
3762                 id_usdtresp = tvb_get_ntohl (tvb, offset);
3763                 u8USDTRespExtAddr_bit = ((id_usdtresp >> 24) & 0x20);
3764                 u8USDTRespHeaderSize = ((id_usdtresp >> 24) & 0x80);
3765                 id_usdtresp &= 0x1FFFFFFF;
3766                 /* usdt resp */
3767                 if(u8USDTRespExtAddr_bit == 0) {
3768                     if(u8USDTRespHeaderSize == 0) {
3769                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%02x through 0x%02x (11-bit)", id_usdtresp, id_usdtresp + ui_ids-1);
3770                     } else {
3771                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%04x through 0x%04x (29-bit)", id_usdtresp, id_usdtresp + ui_ids-1);
3772                     }
3773                 } else {
3774                     u8USDTRespExtAddr = tvb_get_guint8(tvb, offset+13);
3775                     if(u8USDTRespHeaderSize == 0) {
3776                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%02x through 0x%02x (11-bit extended address %01x)", id_usdtresp, id_usdtresp + ui_ids-1, u8USDTRespExtAddr);
3777                     } else {
3778                         proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response, tvb, offset, 4, id_usdtresp, "0x%04x through 0x%04x (29-bit extended address %01x)", id_usdtresp, id_usdtresp + ui_ids-1, u8USDTRespExtAddr);
3779                     }
3780                 }
3781                 offset += 4;
3782                 remain -= 4;
3783
3784                 /* uudt resp */
3785                 id_uudtresp = tvb_get_ntohl (tvb, offset);
3786                 u8UUDTRespExtAddr_bit = ((id_uudtresp >> 24) & 0x20);
3787                 u8UUDTRespHeaderSize = ((id_uudtresp >> 24) & 0x80);
3788                 id_uudtresp &= 0x1FFFFFFF;
3789                 /* uudt resp */
3790                 if(u8UUDTRespExtAddr_bit == 0) {
3791                     if(u8UUDTRespHeaderSize == 0) {
3792                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%02x through 0x%02x (11-bit)", id_uudtresp, id_uudtresp + ui_ids-1);
3793                     } else {
3794                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%04x through 0x%04x (29-bit)", id_uudtresp, id_uudtresp + ui_ids-1);
3795                     }
3796                 } else {
3797                     u8UUDTRespExtAddr = tvb_get_guint8(tvb, offset+10);
3798                     if(u8UUDTRespHeaderSize == 0) {
3799                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%02x through 0x%02x (11-bit extended address %01x)", id_uudtresp, id_uudtresp + ui_ids-1, u8UUDTRespExtAddr);
3800                     } else {
3801                         proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response, tvb, offset, 4, id_uudtresp, "0x%04x through 0x%04x (29-bit extended address %01x)", id_uudtresp, id_uudtresp + ui_ids-1, u8UUDTRespExtAddr);
3802                     }
3803                 }
3804                 offset += 4;
3805                 remain -= 4;
3806             }
3807
3808             if(u8USDTReqExtAddr_bit == 0) {
3809                 /* proto_tree_add_item(tree4, hf_gryphon_reserved, tvb, offset, 1, ENC_NA); */
3810                 proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request_ext, tvb, offset, 1, 0, "(no extended address)");
3811             } else {
3812                 proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_request_ext, tvb, offset, 1, u8USDTReqExtAddr, "0x%01x", u8USDTReqExtAddr);
3813             }
3814             offset += 1;
3815             remain -= 1;
3816
3817             if(u8USDTRespExtAddr_bit == 0) {
3818                 /* proto_tree_add_item(tree4, hf_gryphon_reserved, tvb, offset, 1, ENC_NA); */
3819                 proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response_ext, tvb, offset, 1, 0, "(no extended address)");
3820             } else {
3821                 proto_tree_add_uint_format_value(tree4, hf_gryphon_usdt_response_ext, tvb, offset, 1, u8USDTRespExtAddr, "0x%01x", u8USDTRespExtAddr);
3822             }
3823             offset += 1;
3824             remain -= 1;
3825
3826             if(u8UUDTRespExtAddr_bit == 0) {
3827                 /* proto_tree_add_item(tree4, hf_gryphon_reserved, tvb, offset, 1, ENC_NA); */
3828                 proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response_ext, tvb, offset, 1, 0, "(no extended address)");
3829             } else {
3830                 proto_tree_add_uint_format_value(tree4, hf_gryphon_uudt_response_ext, tvb, offset, 1, u8UUDTRespExtAddr, "0x%01x", u8UUDTRespExtAddr);
3831             }
3832             offset += 1;
3833             remain -= 1;
3834
3835             proto_tree_add_item(tree4, hf_gryphon_reserved, tvb, offset, 1, ENC_NA);
3836             offset += 1;
3837             remain -= 1;
3838         }
3839
3840
3841         ui_block += 1;
3842     }
3843
3844     return offset;
3845 }
3846
3847 /* 20171012 gryphon command for USDT */
3848 static int
3849 cmd_usdt_stmin_fc(tvbuff_t *tvb, int offset, proto_tree *pt)
3850 {
3851     proto_tree_add_item(pt, hf_gryphon_usdt_stmin_fc, tvb, offset, 1, ENC_NA);
3852     offset += 1;
3853
3854     return offset;
3855 }
3856
3857 /* 20171012 gryphon command for USDT */
3858 static int
3859 cmd_usdt_bsmax_fc(tvbuff_t *tvb, int offset, proto_tree *pt)
3860 {
3861     proto_tree_add_item(pt, hf_gryphon_usdt_bsmax_fc, tvb, offset, 1, ENC_NA);
3862     offset += 1;
3863
3864     return offset;
3865 }
3866
3867 /* 20171012 gryphon command for USDT */
3868 static int
3869 cmd_usdt_stmin_override(tvbuff_t *tvb, int offset, proto_tree *pt)
3870 {
3871     proto_tree_add_item(pt, hf_gryphon_usdt_stmin_override, tvb, offset, 1, ENC_NA);
3872     offset += 1;
3873
3874     return offset;
3875 }
3876
3877 /* 20171012 gryphon command for USDT */
3878 static int
3879 cmd_usdt_get_stmin_override(tvbuff_t *tvb, int offset, proto_tree *pt)
3880 {
3881     proto_tree_add_item(pt, hf_gryphon_usdt_stmin_override, tvb, offset, 1, ENC_NA);
3882     offset += 1;
3883     /* fixed this for get */
3884     proto_tree_add_item(pt, hf_gryphon_usdt_stmin_override_active, tvb, offset, 1, ENC_BIG_ENDIAN);
3885     offset += 1;
3886
3887     return offset;
3888 }
3889
3890 /* 20171012 gryphon command for USDT */
3891 static int
3892 cmd_usdt_stmin_override_activate(tvbuff_t *tvb, int offset, proto_tree *pt)
3893 {
3894     proto_tree_add_item(pt, hf_gryphon_usdt_stmin_override_activate, tvb, offset, 1, ENC_BIG_ENDIAN);
3895     offset += 1;
3896
3897     return offset;
3898 }
3899
3900 /* 20171012 gryphon command for USDT */
3901 static int
3902 cmd_usdt_set_stmin_mul(tvbuff_t *tvb, int offset, proto_tree *pt)
3903 {
3904     float value;
3905     /* TODO fix this float value? */
3906     value = tvb_get_ntohieee_float (tvb, offset);
3907     proto_tree_add_float_format_value(pt, hf_gryphon_usdt_set_stmin_mul, tvb, offset, 4,
3908                     value, "%.1f", value);
3909     offset += 4;
3910
3911     return offset;
3912 }
3913
3914 /*
3915  * legacy command for usdt register
3916  */
3917 static int
3918 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
3919 {
3920     int         ids, id, remain, size, i, bytes;
3921     guint8      flags;
3922     proto_tree  *localTree;
3923     proto_item  *localItem;
3924
3925     flags = tvb_get_guint8(tvb, offset);
3926     proto_tree_add_item(pt, hf_gryphon_usdt_flags_register, tvb, offset, 1, ENC_BIG_ENDIAN);
3927
3928     if (flags & 1) {
3929         static const int * action_flags[] = {
3930             &hf_gryphon_usdt_action_flags_register,
3931             &hf_gryphon_usdt_action_flags_action,
3932             NULL
3933         };
3934
3935         static const int * transmit_option_flags[] = {
3936             &hf_gryphon_usdt_transmit_options_flags_echo,
3937             &hf_gryphon_usdt_transmit_options_action,
3938             &hf_gryphon_usdt_transmit_options_send_done,
3939             NULL
3940         };
3941
3942         static const int * receive_option_flags[] = {
3943             &hf_gryphon_usdt_receive_options_action,
3944             &hf_gryphon_usdt_receive_options_firstframe,
3945             &hf_gryphon_usdt_receive_options_lastframe,
3946             NULL
3947         };
3948
3949         proto_tree_add_bitmask(pt, tvb, offset, hf_gryphon_usdt_action_flags, ett_gryphon_flags, action_flags, ENC_BIG_ENDIAN);
3950         proto_tree_add_bitmask(pt, tvb, offset+1, hf_gryphon_usdt_transmit_options_flags, ett_gryphon_flags, transmit_option_flags, ENC_BIG_ENDIAN);
3951         proto_tree_add_bitmask(pt, tvb, offset+2, hf_gryphon_usdt_receive_options_flags, ett_gryphon_flags, receive_option_flags, ENC_BIG_ENDIAN);
3952
3953         if ((ids = tvb_get_guint8(tvb, offset+3))) {
3954             localItem = proto_tree_add_item(pt, hf_gryphon_usdt_ext_address, tvb, offset+3, 1, ENC_BIG_ENDIAN);
3955             offset += 4;
3956
3957             localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
3958             while (ids) {
3959                 proto_tree_add_item(localTree, hf_gryphon_usdt_ext_address_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3960                 offset += 4;
3961                 ids--;
3962             }
3963         } else {
3964             proto_tree_add_uint_format_value(pt, hf_gryphon_usdt_ext_address, tvb, offset+3, 1,
3965                     0, "Using extended addressing for the single, internally defined, ID");
3966             offset += 4;
3967         }
3968         for (i = 0; i < 2; i++) {
3969             bytes = tvb_reported_length_remaining (tvb, offset);
3970             if (bytes <= 0)
3971                 break;
3972             localTree = proto_tree_add_subtree_format(pt, tvb, offset, 16, ett_gryphon_usdt_data, NULL, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
3973
3974             size = tvb_get_ntohl (tvb, offset);
3975             localItem = proto_tree_add_item(localTree, hf_gryphon_usdt_block_size, tvb, offset, 4, ENC_BIG_ENDIAN);
3976             localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data_block);
3977             if (size == 0) {
3978                 proto_item_set_len(localItem, 16);
3979             } else {
3980                 offset += 4;
3981                 id = tvb_get_ntohl (tvb, offset);
3982                 proto_tree_add_uint_format_value(localTree, hf_gryphon_usdt_request, tvb, offset, 4, id, "%04X through %04X", id, id+size-1);
3983                 offset += 4;
3984
3985                 id = tvb_get_ntohl (tvb, offset);
3986                 proto_tree_add_uint_format_value(localTree, hf_gryphon_usdt_response, tvb, offset, 4, id, "%04X through %04X", id, id+size-1);
3987                 offset += 4;
3988
3989                 id = tvb_get_ntohl (tvb, offset);
3990                 proto_tree_add_uint_format_value(localTree, hf_gryphon_uudt_response, tvb, offset, 4, id, "%04X through %04X", id, id+size-1);
3991                 offset += 4;
3992             }
3993         }
3994     } else {
3995         proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
3996         offset += 4;
3997     }
3998
3999     if ((remain = tvb_reported_length_remaining(tvb, offset))) {
4000         proto_tree_add_item(pt, hf_gryphon_ignored, tvb, offset, remain, ENC_NA);
4001         offset += remain;
4002     }
4003
4004     return offset;
4005 }
4006
4007 static int
4008 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
4009 {
4010     int          msglen, value;
4011
4012     msglen = tvb_reported_length_remaining(tvb, offset);
4013     value = tvb_get_guint8(tvb, offset);
4014     if (value) {
4015         static const int * digital_values[] = {
4016             &hf_gryphon_bits_in_input1,
4017             &hf_gryphon_bits_in_input2,
4018             &hf_gryphon_bits_in_input3,
4019             &hf_gryphon_bits_in_pushbutton,
4020             NULL
4021         };
4022         proto_tree_add_bitmask(pt, tvb, 1, hf_gryphon_bit_in_digital_data, ett_gryphon_digital_data, digital_values, ENC_NA);
4023     } else {
4024         proto_tree_add_uint_format(pt, hf_gryphon_bit_in_digital_data, tvb, offset, 1, value, "No digital values are set");
4025     }
4026
4027     offset++;
4028     msglen--;
4029     return offset;
4030 }
4031
4032 static int
4033 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
4034 {
4035     int          msglen, value;
4036
4037     msglen = tvb_reported_length_remaining(tvb, offset);
4038     value = tvb_get_guint8(tvb, offset);
4039     if (value) {
4040         static const int * digital_values[] = {
4041             &hf_gryphon_bits_out_output1,
4042             &hf_gryphon_bits_out_output2,
4043             NULL
4044         };
4045         proto_tree_add_bitmask(pt, tvb, 1, hf_gryphon_bit_out_digital_data, ett_gryphon_digital_data, digital_values, ENC_NA);
4046     } else {
4047         proto_tree_add_uint_format(pt, hf_gryphon_bit_out_digital_data, tvb, offset, 1, value, "No digital values are set");
4048     }
4049
4050     offset++;
4051     msglen--;
4052     return offset;
4053 }
4054
4055 static int
4056 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
4057 {
4058     guint32 reset_limit;
4059     int     msglen, indx;
4060     float   value;
4061
4062     msglen = tvb_reported_length_remaining(tvb, offset);
4063     reset_limit = tvb_get_ntohl(tvb, offset);
4064     proto_tree_add_uint_format_value(pt, hf_gryphon_init_strat_reset_limit, tvb, offset, 4,
4065         reset_limit, "Reset Limit = %u messages", reset_limit);
4066     offset += 4;
4067     msglen -= 4;
4068     for (indx = 1; msglen; indx++, offset++, msglen--) {
4069         value = tvb_get_guint8(tvb, offset);
4070         if (value)
4071             proto_tree_add_float_format_value(pt, hf_gryphon_init_strat_delay, tvb, offset, 1,
4072                     value/4, "Delay %d = %.2f seconds", indx, value/4);
4073         else
4074             proto_tree_add_float_format_value(pt, hf_gryphon_init_strat_delay, tvb, offset, 1,
4075                     0, "Delay %d = infinite", indx);
4076     }
4077
4078     return offset;
4079 }
4080
4081 static int
4082 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
4083 {
4084     proto_tree_add_item(pt, hf_gryphon_speed_baud_rate_index, tvb, offset, 1, ENC_BIG_ENDIAN);
4085     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset+1, 3, ENC_NA);
4086     offset += 4;
4087     return offset;
4088 }
4089
4090 static int
4091 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
4092 {
4093     unsigned int    op;
4094     int     length, padding;
4095
4096     /* 20171017 fixed display of filter block padding */
4097
4098     /* start 2bytes */
4099     proto_tree_add_item(pt, hf_gryphon_filter_block_filter_start, tvb, offset, 2, ENC_BIG_ENDIAN);
4100     offset += 2;
4101
4102     /* length 2bytes */
4103     length = tvb_get_ntohs(tvb, offset);
4104     proto_tree_add_item(pt, hf_gryphon_filter_block_filter_length, tvb, offset, 2, ENC_BIG_ENDIAN);
4105     offset += 2;
4106
4107     /* type 1byte */
4108     proto_tree_add_item(pt, hf_gryphon_filter_block_filter_type, tvb, offset, 1, ENC_BIG_ENDIAN);
4109     offset += 1;
4110
4111     /* operator 1byte */
4112     op = tvb_get_guint8(tvb, offset);
4113     proto_tree_add_item(pt, hf_gryphon_filter_block_filter_operator, tvb, offset, 1, ENC_BIG_ENDIAN);
4114     offset += 1;
4115
4116     /* rsvd 2bytes */
4117     proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset, 2, ENC_NA);
4118     offset += 2;
4119
4120     if (op == BIT_FIELD_CHECK) {
4121         proto_tree_add_item(pt, hf_gryphon_filter_block_pattern, tvb, offset, length, ENC_NA);
4122         proto_tree_add_item(pt, hf_gryphon_filter_block_mask, tvb, offset+length, length, ENC_NA);
4123
4124         offset += length * 2;
4125         padding = (length * 2) % 4;
4126         if (padding) {
4127             proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset, padding, ENC_NA);
4128             offset += padding;
4129         }
4130     } else {
4131         switch (length) {
4132         case 1:
4133             proto_tree_add_item(pt, hf_gryphon_filter_block_filter_value1, tvb, offset, 1, ENC_BIG_ENDIAN);
4134             offset += 1;
4135             break;
4136         case 2:
4137             proto_tree_add_item(pt, hf_gryphon_filter_block_filter_value2, tvb, offset, 2, ENC_BIG_ENDIAN);
4138             offset += 2;
4139             break;
4140         case 4:
4141             proto_tree_add_item(pt, hf_gryphon_filter_block_filter_value4, tvb, offset, 4, ENC_BIG_ENDIAN);
4142             offset += 4;
4143             break;
4144         default:
4145             proto_tree_add_item(pt, hf_gryphon_filter_block_filter_value_bytes, tvb, offset, length, ENC_NA);
4146             offset += length;
4147         }
4148
4149         padding = 3 - ((length + 3) % 4);
4150         if (padding) {
4151             proto_tree_add_item(pt, hf_gryphon_padding, tvb, offset, padding, ENC_NA);
4152             offset += padding;
4153         }
4154     }
4155     return offset;
4156 }
4157
4158 static int
4159 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
4160 {
4161     proto_item   *item;
4162     proto_tree   *tree;
4163     int     mode, milliseconds;
4164
4165     mode = tvb_get_ntohl(tvb, offset);
4166     item = proto_tree_add_item(pt, hf_gryphon_blm_mode, tvb, offset, 4, ENC_BIG_ENDIAN);
4167     offset += 4;
4168     switch (mode) {
4169     case 1:
4170         tree = proto_item_add_subtree (item, ett_gryphon_blm_mode);
4171         milliseconds = tvb_get_ntohl(tvb, offset);
4172
4173         proto_tree_add_uint_format_value(tree, hf_gryphon_blm_mode_avg_period, tvb, offset, 4,
4174             milliseconds, "Averaging period: %d.%03d seconds", milliseconds/1000, milliseconds%1000);
4175         break;
4176     case 2:
4177         tree = proto_item_add_subtree (item, ett_gryphon_blm_mode);
4178         proto_tree_add_item(tree, hf_gryphon_blm_mode_avg_frames, tvb, offset, 4, ENC_BIG_ENDIAN);
4179         break;
4180     default:
4181         proto_tree_add_item(pt, hf_gryphon_reserved, tvb, offset, 4, ENC_NA);
4182         break;
4183     }
4184
4185     offset += 4;
4186     return offset;
4187 }
4188
4189 void
4190 proto_register_gryphon(void)
4191 {
4192     static hf_register_info hf[] = {
4193         { &hf_gryphon_src,
4194           { "Source",           "gryphon.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
4195                 NULL, HFILL }},
4196         { &hf_gryphon_srcchan,
4197           { "Source channel",   "gryphon.srcchan", FT_UINT8,
4198                 BASE_DEC | BASE_SPECIAL_VALS, VALS(channel_or_broadcast), 0x0,
4199                 NULL, HFILL }},
4200         { &hf_gryphon_srcchanclient,
4201           { "Source client id",   "gryphon.srcchanclient", FT_UINT8,
4202                 BASE_DEC | BASE_SPECIAL_VALS, VALS(channel_or_broadcast), 0x0,
4203                 NULL, HFILL }},
4204         { &hf_gryphon_dest,
4205           { "Destination",      "gryphon.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
4206                 NULL, HFILL }},
4207         { &hf_gryphon_destchan,
4208           { "Destination channel", "gryphon.destchan", FT_UINT8,
4209                 BASE_DEC | BASE_SPECIAL_VALS, VALS(channel_or_broadcast), 0x0,
4210                 NULL, HFILL }},
4211         { &hf_gryphon_destchanclient,
4212           { "Destination client id", "gryphon.destchanclient", FT_UINT8,
4213                 BASE_DEC | BASE_SPECIAL_VALS, VALS(channel_or_broadcast), 0x0,
4214                 NULL, HFILL }},
4215         { &hf_gryphon_type,
4216           { "Frame type",       "gryphon.type", FT_UINT8, BASE_DEC, VALS(frame_type), 0x0,
4217                 NULL, HFILL }},
4218         { &hf_gryphon_cmd,
4219           { "Command",          "gryphon.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
4220                 NULL, HFILL }},
4221         { &hf_gryphon_cmd_context,
4222           { "Context",      "gryphon.cmd.context", FT_UINT8, BASE_DEC, NULL, 0x0,
4223                 NULL, HFILL }},
4224         { &hf_gryphon_data,
4225           { "Data",          "gryphon.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4226                 NULL, HFILL }},
4227         { &hf_gryphon_padding,
4228           { "Padding",          "gryphon.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4229                 NULL, HFILL }},
4230         { &hf_gryphon_ignored,
4231           { "Ignored",          "gryphon.ignored", FT_BYTES, BASE_NONE, NULL, 0x0,
4232                 NULL, HFILL }},
4233         { &hf_gryphon_data_length,
4234           { "Data length (bytes)",   "gryphon.data_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4235                 NULL, HFILL }},
4236         { &hf_gryphon_reserved,
4237           { "Reserved",          "gryphon.reserved", FT_BYTES, BASE_NONE, NULL, 0x0,
4238                 NULL, HFILL }},
4239         { &hf_gryphon_wait_flags,
4240           { "Flags",          "gryphon.wait_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4241                 NULL, HFILL }},
4242         { &hf_gryphon_wait_resp,
4243           { "Wait for response", "gryphon.wait_resp", FT_BOOLEAN, 8, TFS(&tfs_wait_response), DONT_WAIT_FOR_RESP,
4244                 NULL, HFILL }},
4245         { &hf_gryphon_wait_prev_resp,
4246           { "Wait for previous response", "gryphon.wait_prev_resp", FT_BOOLEAN, 8, TFS(&tfs_wait_response), WAIT_FOR_PREV_RESP,
4247                 NULL, HFILL }},
4248         { &hf_gryphon_status,
4249           { "Status",          "gryphon.status", FT_UINT32, BASE_HEX, VALS(responses_vs), 0x0,
4250                 NULL, HFILL }},
4251         { &hf_gryphon_data_header_length,
4252           { "Header length (bytes)",   "gryphon.data.header_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4253                 NULL, HFILL }},
4254         { &hf_gryphon_data_header_length_bits,
4255           { "Header length (bits)",   "gryphon.data.header_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4256                 NULL, HFILL }},
4257         { &hf_gryphon_data_data_length,
4258           { "Data length (bytes)",   "gryphon.data.data_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4259                 NULL, HFILL }},
4260         { &hf_gryphon_data_extra_data_length,
4261           { "Extra data length (bytes)",   "gryphon.data.extra_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4262                 NULL, HFILL }},
4263         { &hf_gryphon_data_mode,
4264           { "Mode",          "gryphon.data.mode", FT_UINT8, BASE_DEC, NULL, 0x0,
4265                 NULL, HFILL }},
4266         { &hf_gryphon_data_mode_transmitted,
4267           { "Transmitted message", "gryphon.data.mode.transmitted", FT_BOOLEAN, 8, TFS(&true_false), 0x80,
4268                 NULL, HFILL }},
4269         { &hf_gryphon_data_mode_receive,
4270           { "Received message", "gryphon.data.mode.receive", FT_BOOLEAN, 8, TFS(&true_false), 0x40,
4271                 NULL, HFILL }},
4272         { &hf_gryphon_data_mode_local,
4273           { "Local message", "gryphon.data.mode.local", FT_BOOLEAN, 8, TFS(&true_false), 0x20,
4274                 NULL, HFILL }},
4275         { &hf_gryphon_data_mode_remote,
4276           { "Remote message (LIN)", "gryphon.data.mode.remote", FT_BOOLEAN, 8, TFS(&true_false), 0x10,
4277                 NULL, HFILL }},
4278         /* 20171012 added additional mode bits */
4279         { &hf_gryphon_data_mode_oneshot,
4280           { "One-shot slave table message (LIN)", "gryphon.data.mode.oneshot", FT_BOOLEAN, 8, TFS(&true_false), 0x08,
4281                 NULL, HFILL }},
4282         { &hf_gryphon_data_mode_combined,
4283           { "Channel number is in context", "gryphon.data.mode.combined", FT_BOOLEAN, 8, TFS(&true_false), 0x04,
4284                 NULL, HFILL }},
4285         { &hf_gryphon_data_mode_nomux,
4286           { "Do not multiplex message", "gryphon.data.mode.nomux", FT_BOOLEAN, 8, TFS(&true_false), 0x02,
4287                 NULL, HFILL }},
4288         { &hf_gryphon_data_mode_internal,
4289           { "Internal message", "gryphon.data.mode.internal", FT_BOOLEAN, 8, TFS(&true_false), 0x01,
4290                 NULL, HFILL }},
4291         { &hf_gryphon_data_priority,
4292           { "Priority",         "gryphon.data.priority", FT_UINT8, BASE_DEC, NULL, 0x0,
4293                 NULL, HFILL }},
4294         { &hf_gryphon_data_error_status,
4295           { "Error status",     "gryphon.data.error_status", FT_UINT8, BASE_DEC, NULL, 0x0,
4296                 NULL, HFILL }},
4297         { &hf_gryphon_data_time,
4298           { "Timestamp",        "gryphon.data.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4299                 NULL, HFILL }},
4300         { &hf_gryphon_data_context,
4301           { "Context",      "gryphon.data.context", FT_UINT8, BASE_DEC, NULL, 0x0,
4302                 NULL, HFILL }},
4303         { &hf_gryphon_data_header_data,
4304           { "Header",          "gryphon.data.header_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4305                 NULL, HFILL }},
4306         { &hf_gryphon_data_data,
4307           { "Data",          "gryphon.data.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4308                 NULL, HFILL }},
4309         { &hf_gryphon_data_extra_data,
4310           { "Extra data",          "gryphon.data.extra_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4311                 NULL, HFILL }},
4312         { &hf_gryphon_data_padding,
4313           { "Padding",          "gryphon.data.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4314                 NULL, HFILL }},
4315         { &hf_gryphon_event_id,
4316           { "Event ID",      "gryphon.event.id", FT_UINT8, BASE_DEC, NULL, 0x0,
4317                 NULL, HFILL }},
4318         { &hf_gryphon_event_name,
4319           { "Event name",          "gryphon.event.name", FT_STRING, BASE_NONE, NULL, 0x0,
4320                 NULL, HFILL }},
4321         { &hf_gryphon_event_context,
4322           { "Event context",      "gryphon.event.context", FT_UINT8, BASE_DEC, NULL, 0x0,
4323                 NULL, HFILL }},
4324         { &hf_gryphon_event_time,
4325           { "Timestamp",        "gryphon.event.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4326                 NULL, HFILL }},
4327         { &hf_gryphon_event_data,
4328           { "Data",          "gryphon.event.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4329                 NULL, HFILL }},
4330         { &hf_gryphon_event_padding,
4331           { "Padding",       "gryphon.event.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4332                 NULL, HFILL }},
4333         { &hf_gryphon_misc_text,
4334           { "Text",          "gryphon.misc.text", FT_STRING, BASE_NONE, NULL, 0x0,
4335                 NULL, HFILL }},
4336         { &hf_gryphon_misc_padding,
4337           { "Padding",       "gryphon.misc.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4338                 NULL, HFILL }},
4339         { &hf_gryphon_eventnum,
4340           { "Event numbers", "gryphon.eventnum", FT_UINT8, BASE_DEC, NULL, 0x0,
4341                 NULL, HFILL }},
4342         { &hf_gryphon_resp_time,
4343           { "Date/Time",     "gryphon.resp_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
4344                 NULL, HFILL }},
4345         { &hf_gryphon_setfilt,
4346           { "Pass/Block flag", "gryphon.setfilt.flag", FT_UINT32, BASE_DEC, NULL, 0x0,
4347                 NULL, HFILL }},
4348         { &hf_gryphon_setfilt_length,
4349           { "Length of Pattern & Mask", "gryphon.setfilt.length", FT_UINT32, BASE_DEC, NULL, 0x0,
4350                 NULL, HFILL }},
4351         { &hf_gryphon_setfilt_discard_data,
4352           { "Discarded data", "gryphon.setfilt.discard_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4353                 NULL, HFILL }},
4354         { &hf_gryphon_setfilt_padding,
4355           { "Padding",        "gryphon.setfilt.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4356                 NULL, HFILL }},
4357         { &hf_gryphon_ioctl,
4358           { "IOCTL", "gryphon.ioctl", FT_UINT32, BASE_HEX, VALS(ioctls), 0x0,
4359                 NULL, HFILL }},
4360         { &hf_gryphon_ioctl_nbytes,
4361           { "Number of bytes to follow (bytes)", "gryphon.ioctl_nbytes", FT_UINT32, BASE_DEC, NULL, 0x0,
4362                 NULL, HFILL }},
4363         { &hf_gryphon_ioctl_data,
4364           { "Data",        "gryphon.ioctl.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4365                 NULL, HFILL }},
4366         { &hf_gryphon_addfilt_pass,
4367           { "Conforming messages", "gryphon.addfilt.pass", FT_BOOLEAN, 8, TFS(&tfs_passed_blocked), FILTER_PASS_FLAG,
4368                 NULL, HFILL }},
4369         { &hf_gryphon_addfilt_active,
4370           { "Filter", "gryphon.addfilt.active", FT_BOOLEAN, 8, TFS(&active_inactive), FILTER_ACTIVE_FLAG,
4371                 NULL, HFILL }},
4372         { &hf_gryphon_addfilt_blocks,
4373           { "Number of filter blocks", "gryphon.addfilt.blocks", FT_UINT8, BASE_DEC, NULL, 0x0,
4374                 NULL, HFILL }},
4375         { &hf_gryphon_addfilt_handle,
4376           { "Filter handle", "gryphon.addfilt.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4377                 NULL, HFILL }},
4378         { &hf_gryphon_modfilt,
4379           { "Filter handle", "gryphon.modfilt", FT_UINT8, BASE_DEC, NULL, 0x0,
4380                 NULL, HFILL }},
4381         { &hf_gryphon_modfilt_action,
4382           { "Action", "gryphon.modfilt.action", FT_UINT8, BASE_DEC, VALS(filtacts), 0x0,
4383                 NULL, HFILL }},
4384         { &hf_gryphon_filthan,
4385           { "Number of filter handles", "gryphon.filthan", FT_UINT8, BASE_DEC, NULL, 0x0,
4386                 NULL, HFILL }},
4387         { &hf_gryphon_filthan_id,
4388           { "Filter handle ID", "gryphon.filthan.id", FT_UINT8, BASE_DEC, NULL, 0x0,
4389                 NULL, HFILL }},
4390         { &hf_gryphon_filthan_padding,
4391           { "Padding",        "gryphon.filthan.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
4392                 NULL, HFILL }},
4393         { &hf_gryphon_dfiltmode,
4394           { "Filter mode", "gryphon.dfiltmode", FT_UINT8, BASE_DEC, VALS(dmodes), 0x0,
4395                 NULL, HFILL }},
4396         { &hf_gryphon_filtmode,
4397           { "Filter mode", "gryphon.filtmode", FT_UINT8, BASE_DEC, VALS(modes), 0x0,
4398                 NULL, HFILL }},
4399         { &hf_gryphon_register_username,
4400           { "Username",          "gryphon.register.username", FT_STRING, BASE_NONE, NULL, 0x0,
4401                 NULL, HFILL }},
4402         { &hf_gryphon_register_password,
4403           { "Password",          "gryphon.register.password", FT_STRING, BASE_NONE, NULL, 0x0,
4404                 NULL, HFILL }},
4405         { &hf_gryphon_register_client_id,
4406           { "Client ID", "gryphon.register.client_id", FT_UINT8, BASE_DEC, NULL, 0x0,
4407                 NULL, HFILL }},
4408         { &hf_gryphon_register_privileges,
4409           { "Privileges", "gryphon.register.privileges", FT_UINT8, BASE_DEC, NULL, 0x0,
4410                 NULL, HFILL }},
4411         { &hf_gryphon_getspeeds_set_ioctl,
4412           { "Set Speed IOCTL", "gryphon.getspeeds.set_ioctl", FT_UINT32, BASE_DEC, NULL, 0x0,
4413                 NULL, HFILL }},
4414         { &hf_gryphon_getspeeds_get_ioctl,
4415           { "Get Speed IOCTL", "gryphon.getspeeds.get_ioctl", FT_UINT32, BASE_DEC, NULL, 0x0,
4416                 NULL, HFILL }},
4417         { &hf_gryphon_getspeeds_size,
4418           { "Speed data size (bytes)", "gryphon.getspeeds.size", FT_UINT8, BASE_DEC, NULL, 0x0,
4419                 NULL, HFILL }},
4420         { &hf_gryphon_getspeeds_preset,
4421           { "Preset speed numbers", "gryphon.getspeeds.preset", FT_UINT8, BASE_DEC, NULL, 0x0,
4422                 NULL, HFILL }},
4423         { &hf_gryphon_getspeeds_data,
4424           { "Data for preset",      "gryphon.getspeeds.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4425                 NULL, HFILL }},
4426         { &hf_gryphon_cmd_sort,
4427           { "Set sorting", "gryphon.cmd_sort", FT_UINT8, BASE_DEC, VALS(cmd_sort_type), 0x0,
4428                 NULL, HFILL }},
4429         { &hf_gryphon_cmd_optimize,
4430           { "Set optimization", "gryphon.cmd_optimize", FT_UINT8, BASE_DEC, VALS(cmd_optimize_type), 0x0,
4431                 NULL, HFILL }},
4432         { &hf_gryphon_config_device_name,
4433           { "Device name",          "gryphon.config.device_name", FT_STRING, BASE_NONE, NULL, 0x0,
4434                 NULL, HFILL }},
4435         { &hf_gryphon_config_device_version,
4436           { "Device version",          "gryphon.config.device_version", FT_STRING, BASE_NONE, NULL, 0x0,
4437                 NULL, HFILL }},
4438         { &hf_gryphon_config_device_serial_number,
4439           { "Device serial number",    "gryphon.config.device_serial_number", FT_STRING, BASE_NONE, NULL, 0x0,
4440                 NULL, HFILL }},
4441         { &hf_gryphon_config_num_channels,
4442           { "Number of channels", "gryphon.config.num_channels", FT_UINT8, BASE_DEC, NULL, 0x0,
4443                 NULL, HFILL }},
4444         { &hf_gryphon_config_name_version_ext,
4445           { "Name & version extension",    "gryphon.config.name_version_ext", FT_STRING, BASE_NONE, NULL, 0x0,
4446                 NULL, HFILL }},
4447         { &hf_gryphon_config_driver_name,
4448           { "Driver name",          "gryphon.config.driver_name", FT_STRING, BASE_NONE, NULL, 0x0,
4449                 NULL, HFILL }},
4450         { &hf_gryphon_config_driver_version,
4451           { "Driver version",          "gryphon.config.driver_version", FT_STRING, BASE_NONE, NULL, 0x0,
4452                 NULL, HFILL }},
4453         { &hf_gryphon_config_device_security,
4454           { "Device security string",    "gryphon.config.device_security", FT_STRING, BASE_NONE, NULL, 0x0,
4455                 NULL, HFILL }},
4456         { &hf_gryphon_config_max_data_length,
4457           { "Maximum data length (bytes)", "gryphon.config.max_data_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4458                 NULL, HFILL }},
4459         { &hf_gryphon_config_min_data_length,
4460           { "Minimum data length (bytes)", "gryphon.config.min_data_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4461                 NULL, HFILL }},
4462         { &hf_gryphon_config_hardware_serial_number,
4463           { "Hardware serial number",    "gryphon.config.hardware_serial_number", FT_STRING, BASE_NONE, NULL, 0x0,
4464                 NULL, HFILL }},
4465         { &hf_gryphon_config_protocol_type,
4466           { "Protocol type & subtype", "gryphon.config.protocol_type", FT_UINT16, BASE_HEX, VALS(protocol_types), 0x0,
4467                 NULL, HFILL }},
4468         { &hf_gryphon_config_channel_id,
4469           { "Channel ID", "gryphon.config.channel_id", FT_UINT8, BASE_DEC, NULL, 0x0,
4470                 NULL, HFILL }},
4471         { &hf_gryphon_config_card_slot_number,
4472           { "Card slot number", "gryphon.config.card_slot_number", FT_UINT8, BASE_DEC, NULL, 0x0,
4473                 NULL, HFILL }},
4474         { &hf_gryphon_config_max_extra_data,
4475           { "Maximum extra data (bytes)", "gryphon.config.max_extra_data", FT_UINT16, BASE_DEC, NULL, 0x0,
4476                 NULL, HFILL }},
4477         { &hf_gryphon_config_min_extra_data,
4478           { "Minimum extra data (bytes)", "gryphon.config.min_extra_data", FT_UINT16, BASE_DEC, NULL, 0x0,
4479                 NULL, HFILL }},
4480         { &hf_gryphon_sched_num_iterations,
4481           { "Number of iterations", "gryphon.sched.num_iterations", FT_UINT32, BASE_DEC, NULL, 0x0,
4482                 NULL, HFILL }},
4483         { &hf_gryphon_sched_flags,
4484           { "Flags", "gryphon.sched.flags", FT_UINT32, BASE_HEX, NULL, 0x0,
4485                 NULL, HFILL }},
4486         { &hf_gryphon_sched_flags_scheduler,
4487           { "Scheduler", "gryphon.sched.flags.scheduler", FT_BOOLEAN, 32, TFS(&critical_normal), 0x01,
4488                 NULL, HFILL }},
4489         { &hf_gryphon_sched_sleep,
4490           { "Sleep (milliseconds)", "gryphon.sched.sleep", FT_UINT32, BASE_DEC, NULL, 0x0,
4491                 NULL, HFILL }},
4492         { &hf_gryphon_sched_transmit_count,
4493           { "Transmit count", "gryphon.sched.transmit_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4494                 NULL, HFILL }},
4495         { &hf_gryphon_sched_transmit_period,
4496           { "Transmit period (milliseconds)", "gryphon.sched.transmit_period", FT_UINT32, BASE_DEC, NULL, 0x0,
4497                 NULL, HFILL }},
4498         { &hf_gryphon_sched_transmit_flags,
4499           { "Flags", "gryphon.sched.transmit_flags", FT_UINT16, BASE_HEX, NULL, 0x0,
4500                 NULL, HFILL }},
4501         { &hf_gryphon_sched_skip_transmit_period,
4502           { "Last transmit period", "gryphon.sched.skip_transmit_period", FT_BOOLEAN, 16, TFS(&skip_not_skip), 0x01,
4503                 NULL, HFILL }},
4504         { &hf_gryphon_sched_skip_sleep,
4505           { "Last transmit period", "gryphon.sched.skip_transmit_period", FT_BOOLEAN, 16, TFS(&skip_not_skip), 0x01,
4506                 NULL, HFILL }},
4507         { &hf_gryphon_sched_channel,
4508           { "Channel", "gryphon.sched.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
4509                 NULL, HFILL }},
4510         { &hf_gryphon_sched_channel0,
4511           { "Channel (specified by the destination channel)", "gryphon.sched.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
4512                 NULL, HFILL }},
4513         { &hf_gryphon_sched_rep_id,
4514           { "Schedule ID", "gryphon.sched.rep_id", FT_UINT32, BASE_DEC, NULL, 0x0,
4515                 NULL, HFILL }},
4516         { &hf_gryphon_sched_rep_message_index,
4517           { "Message index", "gryphon.sched.rep_message_index", FT_UINT8, BASE_DEC, NULL, 0x0,
4518                 NULL, HFILL }},
4519         { &hf_gryphon_blm_data_time,
4520           { "Timestamp",        "gryphon.blm_data.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4521                 NULL, HFILL }},
4522         { &hf_gryphon_blm_data_bus_load,
4523           { "Bus load average (%)", "gryphon.blm_data.bus_load", FT_UINT16, BASE_DEC, NULL, 0x0,
4524                 NULL, HFILL }},
4525         { &hf_gryphon_blm_data_current_bus_load,
4526           { "Current bus load (%)", "gryphon.blm_data.current_bus_load", FT_UINT16, BASE_DEC, NULL, 0x0,
4527                 NULL, HFILL }},
4528         { &hf_gryphon_blm_data_peak_bus_load,
4529           { "Peak bus load (%)", "gryphon.blm_data.peak_bus_load", FT_UINT16, BASE_DEC, NULL, 0x0,
4530                 NULL, HFILL }},
4531         { &hf_gryphon_blm_data_historic_peak_bus_load,
4532           { "Historic peak bus load (%)", "gryphon.blm_data.historic_peak_bus_load", FT_UINT16, BASE_DEC, NULL, 0x0,
4533                 NULL, HFILL }},
4534         { &hf_gryphon_blm_stat_receive_frame_count,
4535           { "Receive frame count", "gryphon.blm_stat.receive_frame_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4536                 NULL, HFILL }},
4537         { &hf_gryphon_blm_stat_transmit_frame_count,
4538           { "Transmit frame count", "gryphon.blm_stat.transmit_frame_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4539                 NULL, HFILL }},
4540         { &hf_gryphon_blm_stat_receive_dropped_frame_count,
4541           { "Receive dropped frame count", "gryphon.blm_stat.receive_dropped_frame_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4542                 NULL, HFILL }},
4543         { &hf_gryphon_blm_stat_transmit_dropped_frame_count,
4544           { "Transmit dropped frame count", "gryphon.blm_stat.transmit_dropped_frame_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4545                 NULL, HFILL }},
4546         { &hf_gryphon_blm_stat_receive_error_count,
4547           { "Receive error count", "gryphon.blm_stat.receive_error_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4548                 NULL, HFILL }},
4549         { &hf_gryphon_blm_stat_transmit_error_count,
4550           { "Transmit error count", "gryphon.blm_stat.transmit_error_count", FT_UINT32, BASE_DEC, NULL, 0x0,
4551                 NULL, HFILL }},
4552         { &hf_gryphon_addresp_flags,
4553           { "Flags", "gryphon.addresp.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4554                 NULL, HFILL }},
4555         /* 20171017 fixed display of filter flags */
4556         { &hf_gryphon_addresp_flags_active,
4557           { "Filter active flag", "gryphon.addresp.flags.active", FT_BOOLEAN, 8, TFS(&active_inactive), FILTER_ACTIVE_FLAG,
4558                 NULL, HFILL }},
4559         { &hf_gryphon_addresp_blocks,
4560           { "Number of filter blocks", "gryphon.addresp.blocks", FT_UINT8, BASE_DEC, NULL, 0x0,
4561                 NULL, HFILL }},
4562         { &hf_gryphon_ldf_number,
4563           { "Number of LDF names", "gryphon.ldf.number", FT_UINT8, BASE_DEC, NULL, 0x0,
4564                 NULL, HFILL }},
4565         { &hf_gryphon_ldf_nodenumber,
4566           { "Number of nodes", "gryphon.ldf.nodenumber", FT_UINT8, BASE_DEC, NULL, 0x0,
4567                 NULL, HFILL }},
4568         { &hf_gryphon_ldf_list,
4569           { "LDF block index", "gryphon.ldf.list", FT_UINT8, BASE_DEC, NULL, 0x0,
4570                 NULL, HFILL }},
4571         { &hf_gryphon_ldf_remaining,
4572           { "Remaining LDF names", "gryphon.ldf.remaining", FT_UINT16, BASE_DEC, NULL, 0x0,
4573                 NULL, HFILL }},
4574         { &hf_gryphon_ldf_name,
4575           { "File Name",    "gryphon.ldf.name", FT_STRING, BASE_NONE, NULL, 0x0,
4576                 NULL, HFILL }},
4577         { &hf_gryphon_ldf_info_pv,
4578           { "Protocol version",    "gryphon.ldf.pv", FT_STRING, BASE_NONE, NULL, 0x0,
4579                 NULL, HFILL }},
4580         { &hf_gryphon_ldf_info_lv,
4581           { "Language version",    "gryphon.ldf.lv", FT_STRING, BASE_NONE, NULL, 0x0,
4582                 NULL, HFILL }},
4583         { &hf_gryphon_ldf_ui,
4584           { "Unique identifier",        "gryphon.ldf.ui", FT_BYTES, BASE_NONE, NULL, 0x0,
4585                 NULL, HFILL }},
4586         { &hf_gryphon_lin_nodename,
4587           { "Node Name",    "gryphon.lin.nodename", FT_STRING, BASE_NONE, NULL, 0x0,
4588                 NULL, HFILL }},
4589         { &hf_gryphon_lin_data_length,
4590           { "Data length (bytes)",   "gryphon.lin.data_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4591                 NULL, HFILL }},
4592         { &hf_gryphon_lin_slave_table_enable,
4593           { "Slave table entry",   "gryphon.lin.slave_table_enable", FT_UINT8, BASE_DEC, VALS(lin_slave_table_enable), 0x0,
4594                 NULL, HFILL }},
4595         { &hf_gryphon_lin_slave_table_cs,
4596           { "Slave table checksum",   "gryphon.lin.slave_table_cs", FT_UINT8, BASE_DEC, VALS(lin_slave_table_cs), 0x0,
4597                 NULL, HFILL }},
4598         { &hf_gryphon_lin_slave_table_data,
4599           { "Data",          "gryphon.lin.slave_table_data", FT_BYTES, BASE_NONE, NULL, 0x0,
4600                 NULL, HFILL }},
4601         { &hf_gryphon_lin_slave_table_datacs,
4602           { "Checksum",          "gryphon.lin.slave_table_datacs", FT_UINT8, BASE_HEX, NULL, 0x0,
4603                 NULL, HFILL }},
4604         { &hf_gryphon_lin_masterevent,
4605           { "Starting frame id", "gryphon.lin.masterevent", FT_UINT8, BASE_DEC, VALS(lin_ioctl_masterevent), 0x0,
4606                 NULL, HFILL }},
4607         { &hf_gryphon_lin_numdata,
4608           { "Number of data bytes", "gryphon.lin.numdata", FT_UINT8, BASE_DEC, NULL, 0x0,
4609                 NULL, HFILL }},
4610         { &hf_gryphon_lin_numextra,
4611           { "Number of extra bytes", "gryphon.lin.numextra", FT_UINT8, BASE_DEC, NULL, 0x0,
4612                 NULL, HFILL }},
4613         { &hf_gryphon_ldf_description,
4614           { "Description",    "gryphon.ldf.description", FT_STRING, BASE_NONE, NULL, 0x0,
4615                 NULL, HFILL }},
4616         { &hf_gryphon_ldf_size,
4617           { "Size of LDF to be uploaded", "gryphon.ldf.size", FT_UINT32, BASE_DEC, NULL, 0x0,
4618                 NULL, HFILL }},
4619         { &hf_gryphon_ldf_exists,
4620           { "LDF name existence check",       "gryphon.ldf.exists", FT_UINT8, BASE_DEC, VALS(ldf_exists), 0x0,
4621                 NULL, HFILL }},
4622         { &hf_gryphon_ldf_blockn,
4623           { "Block number",   "gryphon.ldf.blockn", FT_UINT16, BASE_DEC, NULL, 0x0,
4624                 NULL, HFILL }},
4625         { &hf_gryphon_ldf_file,
4626           { "Upload text block",    "gryphon.ldf.file", FT_STRING, BASE_NONE, NULL, 0x0,
4627                 NULL, HFILL }},
4628         { &hf_gryphon_ldf_desc_pad,
4629           { "Padding (TODO: need to fix response data length)",          "gryphon.ldf.desc_pad", FT_BYTES, BASE_NONE, NULL, 0x0,
4630                 NULL, HFILL }},
4631         { &hf_gryphon_ldf_restore_session,
4632           { "Session id",        "gryphon.ldf.restore_session", FT_BYTES, BASE_NONE, NULL, 0x0,
4633                 NULL, HFILL }},
4634         { &hf_gryphon_ldf_schedule_name,
4635           { "Schedule name",          "gryphon.ldf.schedule_name", FT_STRING, BASE_NONE, NULL, 0x0,
4636                 NULL, HFILL }},
4637         { &hf_gryphon_ldf_schedule_msg_dbytes,
4638           { "Data length (bytes)", "gryphon.ldf.schedule_msg_dbytes", FT_UINT8, BASE_DEC, NULL, 0x0,
4639                 NULL, HFILL }},
4640         { &hf_gryphon_ldf_schedule_flags,
4641           { "Flags",          "gryphon.ldf.schedule_flags", FT_UINT8, BASE_DEC, NULL, 0x0,
4642                 NULL, HFILL }},
4643         { &hf_gryphon_ldf_schedule_event,
4644           { "Event driven", "gryphon.ldf.schedule_event_ev", FT_BOOLEAN, 8, TFS(&true_false), 0x80,
4645                 NULL, HFILL }},
4646         { &hf_gryphon_ldf_schedule_sporadic,
4647           { "Sporadic", "gryphon.ldf.schedule_event_sp", FT_BOOLEAN, 8, TFS(&true_false), 0x40,
4648                 NULL, HFILL }},
4649         { &hf_gryphon_ldf_ioctl_setflags,
4650           { "Starting frame id", "gryphon.ldf.ioctl_setflags", FT_UINT8, BASE_DEC, VALS(lin_ldf_ioctl_setflags), 0x0,
4651                 NULL, HFILL }},
4652         { &hf_gryphon_ldf_ioctl_setflags_flags,
4653           { "Id", "gryphon.ldf.ioctl_setflags_flags", FT_UINT8, BASE_DEC, NULL, 0x0,
4654                 NULL, HFILL }},
4655         { &hf_gryphon_ldf_numb_ids,
4656           { "Number of ids", "gryphon.ldf.numb_ids", FT_UINT8, BASE_DEC, NULL, 0x0,
4657                 NULL, HFILL }},
4658         { &hf_gryphon_ldf_bitrate,
4659           { "Bitrate", "gryphon.ldf.bitrate", FT_FLOAT, BASE_NONE, NULL, 0x0,
4660                 NULL, HFILL }},
4661         { &hf_gryphon_ldf_sched_size_place,
4662           { "Placeholder for schedule size (bytes)", "gryphon.ldf.schedsize", FT_UINT32, BASE_DEC, NULL, 0x0,
4663                 NULL, HFILL }},
4664         { &hf_gryphon_ldf_sched_numb_place,
4665           { "Placeholder for number of schedules", "gryphon.ldf.numbsched", FT_UINT16, BASE_DEC, NULL, 0x0,
4666                 NULL, HFILL }},
4667         { &hf_gryphon_ldf_sched_size,
4668           { "Schedule size (bytes)", "gryphon.ldf.schedsize", FT_UINT32, BASE_DEC, NULL, 0x0,
4669                 NULL, HFILL }},
4670         { &hf_gryphon_ldf_num_node_names,
4671           { "Number of node names", "gryphon.ldf.num_node_names", FT_UINT16, BASE_DEC, NULL, 0x0,
4672                 NULL, HFILL }},
4673         { &hf_gryphon_ldf_num_frames,
4674           { "Number of frames", "gryphon.ldf.num_frames", FT_UINT16, BASE_DEC, NULL, 0x0,
4675                 NULL, HFILL }},
4676         { &hf_gryphon_ldf_get_frame,
4677           { "Frame",    "gryphon.ldf.get_frame", FT_STRING, BASE_NONE, NULL, 0x0,
4678                 NULL, HFILL }},
4679         { &hf_gryphon_ldf_get_frame_num,
4680           { "Number of data bytes in slave response", "gryphon.ldf.get_frame_num", FT_UINT8, BASE_DEC, NULL, 0x0,
4681                 NULL, HFILL }},
4682         { &hf_gryphon_ldf_get_frame_pub,
4683           { "Publisher",    "gryphon.ldf.get_frame_pub", FT_STRING, BASE_NONE, NULL, 0x0,
4684                 NULL, HFILL }},
4685         { &hf_gryphon_ldf_get_frame_num_signals,
4686           { "Number of signals", "gryphon.ldf.get_frame_num_signals", FT_UINT8, BASE_DEC, NULL, 0x0,
4687                 NULL, HFILL }},
4688         { &hf_gryphon_ldf_num_signal_names,
4689           { "Number of signal names", "gryphon.ldf.num_signal_names", FT_UINT16, BASE_DEC, NULL, 0x0,
4690                 NULL, HFILL }},
4691         { &hf_gryphon_ldf_num_schedules,
4692           { "Number of schedules", "gryphon.ldf.num_schedules", FT_UINT16, BASE_DEC, NULL, 0x0,
4693                 NULL, HFILL }},
4694         { &hf_gryphon_ldf_num_encodings,
4695           { "Number of encodings", "gryphon.ldf.num_encodings", FT_UINT16, BASE_DEC, NULL, 0x0,
4696                 NULL, HFILL }},
4697         { &hf_gryphon_ldf_encoding_value,
4698           { "Encoding value", "gryphon.ldf.encoding_value", FT_UINT16, BASE_DEC, NULL, 0x0,
4699                 NULL, HFILL }},
4700         { &hf_gryphon_ldf_encoding_min,
4701           { "Encoding min value", "gryphon.ldf.encoding_min", FT_UINT16, BASE_DEC, NULL, 0x0,
4702                 NULL, HFILL }},
4703         { &hf_gryphon_ldf_encoding_max,
4704           { "Encoding max value", "gryphon.ldf.encoding_max", FT_UINT16, BASE_DEC, NULL, 0x0,
4705                 NULL, HFILL }},
4706         { &hf_gryphon_ldf_master_node_name,
4707           { "Master node name",    "gryphon.ldf.master", FT_STRING, BASE_NONE, NULL, 0x0,
4708                 NULL, HFILL }},
4709         { &hf_gryphon_ldf_slave_node_name,
4710           { "Slave node name",    "gryphon.ldf.slave", FT_STRING, BASE_NONE, NULL, 0x0,
4711                 NULL, HFILL }},
4712         { &hf_gryphon_ldf_node_name,
4713           { "Node name",    "gryphon.ldf.node_name", FT_STRING, BASE_NONE, NULL, 0x0,
4714                 NULL, HFILL }},
4715         { &hf_gryphon_ldf_signal_name,
4716           { "Signal name",    "gryphon.ldf.signal_name", FT_STRING, BASE_NONE, NULL, 0x0,
4717                 NULL, HFILL }},
4718         { &hf_gryphon_ldf_signal_encoding_name,
4719           { "Signal encoding name",    "gryphon.ldf.signal_encoding_name", FT_STRING, BASE_NONE, NULL, 0x0,
4720                 NULL, HFILL }},
4721         { &hf_gryphon_ldf_signal_encoding_type,
4722           { "Signal encoding type",    "gryphon.ldf.signal_encoding_type", FT_STRING, BASE_NONE, NULL, 0x0,
4723                 NULL, HFILL }},
4724         { &hf_gryphon_ldf_signal_encoding_logical,
4725           { "Signal encoding string",    "gryphon.ldf.signal_encoding_logical", FT_STRING, BASE_NONE, NULL, 0x0,
4726                 NULL, HFILL }},
4727         { &hf_gryphon_ldf_signal_offset,
4728           { "Offset (bits)", "gryphon.ldf.signal_offset", FT_UINT8, BASE_DEC, NULL, 0x0,
4729                 NULL, HFILL }},
4730         { &hf_gryphon_ldf_signal_length,
4731           { "Length (bits)", "gryphon.ldf.signal_length", FT_UINT8, BASE_DEC, NULL, 0x0,
4732                 NULL, HFILL }},
4733         /* cnvt */
4734         { &hf_gryphon_cnvt_valuef,
4735           { "Float value", "gryphon.cnvt.valuef", FT_FLOAT, BASE_NONE, NULL, 0x0,
4736                 NULL, HFILL }},
4737         { &hf_gryphon_cnvt_valuei,
4738           { "Int value", "gryphon.cnvt.valuei", FT_UINT32, BASE_DEC, NULL, 0x0,
4739                 NULL, HFILL }},
4740         { &hf_gryphon_cnvt_values,
4741           { "String value",    "gryphon.cnvt.values", FT_STRING, BASE_NONE, NULL, 0x0,
4742                 NULL, HFILL }},
4743         { &hf_gryphon_cnvt_units,
4744           { "String units",    "gryphon.cnvt.units", FT_STRING, BASE_NONE, NULL, 0x0,
4745                 NULL, HFILL }},
4746         { &hf_gryphon_cnvt_flags_getvalues,
4747           { "Flags", "gryphon.cnvt.flags.getvalues", FT_UINT8, BASE_DEC, VALS(lin_cnvt_getflags), 0x0,
4748                 NULL, HFILL }},
4749         /* delay driver */
4750         { &hf_gryphon_dd_stream,
4751           { "Stream number", "gryphon.dd.stream", FT_UINT16, BASE_DEC, NULL, 0x0,
4752                 NULL, HFILL }},
4753         { &hf_gryphon_dd_value,
4754           { "Value (bytes)",   "gryphon.dd.value", FT_UINT16, BASE_DEC, NULL, 0x0,
4755                 NULL, HFILL }},
4756         { &hf_gryphon_dd_time,
4757           { "Time (msec)",   "gryphon.dd.time", FT_UINT16, BASE_DEC, NULL, 0x0,
4758                 NULL, HFILL }},
4759         { &hf_gryphon_addresp_responses,
4760           { "Number of response blocks", "gryphon.addresp.responses", FT_UINT8, BASE_DEC, NULL, 0x0,
4761                 NULL, HFILL }},
4762         { &hf_gryphon_addresp_old_handle,
4763           { "Old handle", "gryphon.addresp.old_handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4764                 NULL, HFILL }},
4765         { &hf_gryphon_addresp_action,
4766           { "Action", "gryphon.addresp.action", FT_UINT8, BASE_DEC, VALS(action_vals), 0x07,
4767                 NULL, HFILL }},
4768         { &hf_gryphon_addresp_action_period,
4769           { "Period", "gryphon.addresp.action_period", FT_BOOLEAN, 8, TFS(&frames_01seconds), FR_PERIOD_MSGS,
4770                 NULL, HFILL }},
4771         { &hf_gryphon_addresp_action_deact_on_event,
4772           { "Deact on event", "gryphon.addresp.action.deact_on_event", FT_UINT8, BASE_DEC, VALS(deact_on_event_vals), FR_DELETE|FR_DEACT_ON_EVENT,
4773                 NULL, HFILL }},
4774         { &hf_gryphon_addresp_action_deact_after_period,
4775           { "Deact on Period", "gryphon.addresp.action.deact_after_period", FT_UINT8, BASE_DEC, VALS(deact_after_per_vals), FR_DELETE|FR_DEACT_AFTER_PER,
4776                 NULL, HFILL }},
4777         { &hf_gryphon_addresp_action_period_type,
4778           { "Period", "gryphon.addresp.action_period_type", FT_UINT16, BASE_DEC, NULL, 0x0,
4779                 NULL, HFILL }},
4780         { &hf_gryphon_addresp_handle,
4781           { "Response handle", "gryphon.addresp.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4782                 NULL, HFILL }},
4783         { &hf_gryphon_modresp_handle,
4784           { "Response handle", "gryphon.modresp.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4785                 NULL, HFILL }},
4786         { &hf_gryphon_modresp_action,
4787           { "Action response", "gryphon.modresp.action", FT_UINT8, BASE_DEC, VALS(filtacts), 0x0,
4788                 NULL, HFILL }},
4789         { &hf_gryphon_num_resphan,
4790           { "Number of response handles", "gryphon.num_resphan", FT_UINT8, BASE_DEC, NULL, 0x0,
4791                 NULL, HFILL }},
4792         { &hf_gryphon_handle,
4793           { "Handle", "gryphon.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4794                 NULL, HFILL }},
4795         { &hf_gryphon_transmit_sched_id,
4796           { "Transmit schedule ID", "gryphon.transmit_sched_id", FT_UINT32, BASE_DEC, NULL, 0x0,
4797                 NULL, HFILL }},
4798         { &hf_gryphon_desc_program_size,
4799           { "Program size", "gryphon.desc.program_size", FT_UINT32, BASE_DEC, NULL, 0x0,
4800                 NULL, HFILL }},
4801         { &hf_gryphon_desc_program_name,
4802           { "Program name",    "gryphon.desc.program_name", FT_STRING, BASE_NONE, NULL, 0x0,
4803                 NULL, HFILL }},
4804         { &hf_gryphon_desc_program_description,
4805           { "Program description",    "gryphon.desc.program_description", FT_STRING, BASE_NONE, NULL, 0x0,
4806                 NULL, HFILL }},
4807         { &hf_gryphon_desc_flags,
4808           { "Flags", "gryphon.desc.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4809                 NULL, HFILL }},
4810         { &hf_gryphon_desc_flags_program,
4811           { "Period", "gryphon.desc.flags.program", FT_BOOLEAN, 8, TFS(&present_not_present), 0x01,
4812                 NULL, HFILL }},
4813         { &hf_gryphon_desc_handle,
4814           { "Handle", "gryphon.desc.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4815                 NULL, HFILL }},
4816         { &hf_gryphon_upload_block_number,
4817           { "Block number", "gryphon.upload.block_number", FT_UINT16, BASE_DEC, NULL, 0x0,
4818                 NULL, HFILL }},
4819         { &hf_gryphon_upload_handle,
4820           { "Handle", "gryphon.upload.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4821                 NULL, HFILL }},
4822         { &hf_gryphon_upload_data,
4823           { "Data",          "gryphon.upload.data", FT_BYTES, BASE_NONE, NULL, 0x0,
4824                 NULL, HFILL }},
4825         { &hf_gryphon_delete,
4826           { "Program name",    "gryphon.delete", FT_STRING, BASE_NONE, NULL, 0x0,
4827                 NULL, HFILL }},
4828         { &hf_gryphon_list_block_number,
4829           { "Block number", "gryphon.list.block_number", FT_UINT8, BASE_DEC, NULL, 0x0,
4830                 NULL, HFILL }},
4831         { &hf_gryphon_list_num_programs,
4832           { "Number of programs in this response", "gryphon.list.num_programs", FT_UINT8, BASE_DEC, NULL, 0x0,
4833                 NULL, HFILL }},
4834         { &hf_gryphon_list_num_remain_programs,
4835           { "Number of remaining programs", "gryphon.list.num_remain_programs", FT_UINT16, BASE_DEC, NULL, 0x0,
4836                 NULL, HFILL }},
4837         { &hf_gryphon_list_name,
4838           { "Name",    "gryphon.list.name", FT_STRING, BASE_NONE, NULL, 0x0,
4839                 NULL, HFILL }},
4840         { &hf_gryphon_list_description,
4841           { "Description",    "gryphon.list.description", FT_STRING, BASE_NONE, NULL, 0x0,
4842                 NULL, HFILL }},
4843         { &hf_gryphon_start_arguments,
4844           { "Arguments",    "gryphon.start.arguments", FT_STRINGZ, BASE_NONE, NULL, 0x0,
4845                 NULL, HFILL }},
4846         { &hf_gryphon_start_channel,
4847           { "Channel (Client) number", "gryphon.start.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
4848                 NULL, HFILL }},
4849         { &hf_gryphon_status_num_running_copies,
4850           { "Number of running copies", "gryphon.status.num_running_copies", FT_UINT8, BASE_DEC, NULL, 0x0,
4851                 NULL, HFILL }},
4852         { &hf_gryphon_options_handle,
4853           { "Handle", "gryphon.options.handle", FT_UINT8, BASE_DEC, NULL, 0x0,
4854                 NULL, HFILL }},
4855         { &hf_gryphon_files,
4856           { "Directory",    "gryphon.files", FT_STRING, BASE_NONE, NULL, 0x0,
4857                 NULL, HFILL }},
4858         { &hf_gryphon_usdt_flags_register,
4859           { "USDT", "gryphon.usdt.flags_register", FT_UINT8, BASE_DEC, VALS(register_unregister), 0x01,
4860                 NULL, HFILL }},
4861         { &hf_gryphon_usdt_action_flags,
4862           { "Action Flags", "gryphon.usdt.action_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4863                 NULL, HFILL }},
4864
4865         /* 20171012 added non legacy USDT */
4866         { &hf_gryphon_usdt_action_flags_non_legacy,
4867           { "Action Flags", "gryphon.usdt.action_flags.non_legacy", FT_BOOLEAN, 8, TFS(&register_unregister_action_flags), 0x01,
4868                 NULL, HFILL }},
4869
4870         { &hf_gryphon_usdt_action_flags_register,
4871           { "Register", "gryphon.usdt.action_flags.register", FT_UINT8, BASE_DEC, VALS(register_unregister), 0x01,
4872                 NULL, HFILL }},
4873         { &hf_gryphon_usdt_action_flags_action,
4874           { "Action", "gryphon.usdt.action_flags.action", FT_UINT8, BASE_DEC, VALS(usdt_action_vals), 0x06,
4875                 NULL, HFILL }},
4876         { &hf_gryphon_usdt_transmit_options_flags,
4877           { "Transmit options", "gryphon.usdt.transmit_options_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4878                 NULL, HFILL }},
4879         /* 20171012 USDT tx options */
4880         /* bit 0*/
4881         { &hf_gryphon_usdt_transmit_options_flags_echo,
4882           { "Echo long", "gryphon.usdt.transmit_options_flags.echo_long", FT_UINT8, BASE_DEC, VALS(xmit_opt_echo_long), 0x01, NULL, HFILL }},
4883         /* bits 1 & 2 */
4884         { &hf_gryphon_usdt_transmit_options_action,
4885           { "Transmit Action", "gryphon.usdt.transmit_options_flags.action", FT_UINT8, BASE_DEC, VALS(xmit_opt_vals), 0x06,
4886                 NULL, HFILL }},
4887         /* bit 3 */
4888         { &hf_gryphon_usdt_transmit_options_done_event,
4889           { "Done event", "gryphon.usdt.transmit_options_flags.done_event", FT_UINT8, BASE_DEC, VALS(xmit_opt_done), 0x08, NULL, HFILL }},
4890         /* bit 4 */
4891         { &hf_gryphon_usdt_transmit_options_echo_short,
4892           { "Echo short", "gryphon.usdt.transmit_options_flags.echo_log", FT_UINT8, BASE_DEC, VALS(xmit_opt_echo_short), 0x10, NULL, HFILL }},
4893         /* bit 5 */
4894         { &hf_gryphon_usdt_transmit_options_rx_nth_fc,
4895           { "Nth flowcontrol event", "gryphon.usdt.transmit_options_flags.nth_fc_event", FT_UINT8, BASE_DEC, VALS(xmit_opt_nth_fc_event), 0x20, NULL, HFILL }},
4896
4897         /* bit 5 */
4898         { &hf_gryphon_usdt_transmit_options_send_done,
4899           { "Send a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted",
4900                 "gryphon.usdt.transmit_options_flags.send_done", FT_BOOLEAN, 8, TFS(&yes_no), 0x08, NULL, HFILL }},
4901
4902         /* 20171012 USDT rx options */
4903         { &hf_gryphon_usdt_receive_options_flags,
4904           { "Receive options", "gryphon.usdt.receive_options_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4905                 NULL, HFILL }},
4906         /* bits 0 & 1 */
4907         { &hf_gryphon_usdt_receive_options_action, /* legacy */
4908           { "Receive Action", "gryphon.usdt.receive_options_flags.action", FT_UINT8, BASE_DEC, VALS(recv_opt_vals), 0x03, NULL, HFILL }},
4909         /* bit 2 */
4910         { &hf_gryphon_usdt_receive_options_firstframe_event,
4911           { "First frame event", "gryphon.usdt.receive_options_flags.firstframe_event", FT_UINT8, BASE_DEC, VALS(recv_opt_firstframe_event), 0x04, NULL, HFILL }},
4912         /* bit 3 */
4913         { &hf_gryphon_usdt_receive_options_lastframe_event,
4914           { "Last frame event", "gryphon.usdt.receive_options_flags.lastframe_event", FT_UINT8, BASE_DEC, VALS(recv_opt_lastframe_event), 0x08, NULL, HFILL }},
4915         /* bit 5 */
4916         { &hf_gryphon_usdt_receive_options_tx_nth_fc,
4917           { "Nth flowcontrol event", "gryphon.usdt.receive_options_flags.nth_fc_event", FT_UINT8, BASE_DEC, VALS(recv_opt_nth_fc_event), 0x20, NULL, HFILL }},
4918
4919         /* J1939 options */
4920         { &hf_gryphon_usdt_length_options_flags,
4921           { "Length options", "gryphon.usdt.length_options_flags", FT_UINT8, BASE_HEX, NULL, 0x0,
4922                 NULL, HFILL }},
4923         /* bit 6 */
4924         { &hf_gryphon_usdt_length_control_j1939,
4925           { "Length control bit", "gryphon.usdt.length_options_flags.j1939", FT_UINT8, BASE_DEC, VALS(recv_opt_j1939), 0x40, NULL, HFILL }},
4926
4927         /* 20171013 */
4928         { &hf_gryphon_usdt_stmin_fc,
4929           { "STMIN flow control time (milliseconds)", "gryphon.usdt.set_stmin_fc", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
4930         { &hf_gryphon_usdt_set_stmin_mul,
4931           { "STMIN multiplier", "gryphon.usdt.set_stmin_mul", FT_FLOAT, BASE_NONE, NULL, 0x0,
4932                 NULL, HFILL }},
4933         { &hf_gryphon_usdt_bsmax_fc,
4934           { "Block size max for flow control", "gryphon.usdt.set_bsmax_fc", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
4935         { &hf_gryphon_usdt_stmin_override,
4936           { "STMIN override time (milliseconds)", "gryphon.usdt.set_stmin_override", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
4937         { &hf_gryphon_usdt_stmin_override_active,
4938           { "STMIN override active", "gryphon.usdt.stmin_active", FT_BOOLEAN, 8, TFS(&active_inactive), FILTER_ACTIVE_FLAG,
4939                 NULL, HFILL }},
4940         { &hf_gryphon_usdt_stmin_override_activate,
4941           { "STMIN override activate", "gryphon.usdt.stmin_active", FT_BOOLEAN, 8, TFS(&active_inactive), FILTER_ACTIVE_FLAG,
4942                 NULL, HFILL }},
4943
4944         { &hf_gryphon_usdt_receive_options_firstframe,
4945           { "Send a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received",
4946             "gryphon.usdt.receive_options_flags.firstframe",  FT_BOOLEAN, 8, TFS(&yes_no), 0x04, NULL, HFILL }},
4947         { &hf_gryphon_usdt_receive_options_lastframe,
4948           { "Send a USDT_LASTFRAME event when the first frame of a multi-frame USDT message is received",
4949              "gryphon.usdt.receive_options_flags.lastframe", FT_BOOLEAN, 8, TFS(&yes_no), 0x08, NULL, HFILL }},
4950         { &hf_gryphon_usdt_ext_address,
4951           { "Using extended addressing for", "gryphon.usdt.ext_address", FT_UINT8, BASE_DEC, NULL, 0x0,
4952                 NULL, HFILL }},
4953         { &hf_gryphon_usdt_ext_address_id,
4954           { "ID", "gryphon.usdt.ext_address.id", FT_UINT32, BASE_HEX, NULL, 0x0,
4955                 NULL, HFILL }},
4956         { &hf_gryphon_usdt_block_size,
4957           { "Number of IDs in the block", "gryphon.usdt.block_size", FT_UINT32, BASE_DEC, NULL, 0x0,
4958                 NULL, HFILL }},
4959         { &hf_gryphon_bits_in_input1,
4960           { "Input 1", "gryphon.bits_in.input1", FT_BOOLEAN, 8, TFS(&set_not_set), 0x01,
4961                 NULL, HFILL }},
4962         { &hf_gryphon_bits_in_input2,
4963           { "Input 2", "gryphon.bits_in.input2", FT_BOOLEAN, 8, TFS(&set_not_set), 0x02,
4964                 NULL, HFILL }},
4965         { &hf_gryphon_bits_in_input3,
4966           { "Input 3", "gryphon.bits_in.input3", FT_BOOLEAN, 8, TFS(&set_not_set), 0x04,
4967                 NULL, HFILL }},
4968         { &hf_gryphon_bits_in_pushbutton,
4969           { "Pushbutton", "gryphon.bits_in.pushbutton", FT_BOOLEAN, 8, TFS(&set_not_set), 0x08,
4970                 NULL, HFILL }},
4971         { &hf_gryphon_bits_out_output1,
4972           { "Input 1", "gryphon.bits_out.output1", FT_BOOLEAN, 8, TFS(&set_not_set), 0x01,
4973                 NULL, HFILL }},
4974         { &hf_gryphon_bits_out_output2,
4975           { "Input 2", "gryphon.bits_out.output2", FT_BOOLEAN, 8, TFS(&set_not_set), 0x02,
4976                 NULL, HFILL }},
4977         { &hf_gryphon_init_strat_reset_limit,
4978           { "Reset Limit", "gryphon.init_strat.reset_limit", FT_UINT32, BASE_DEC, NULL, 0x0,
4979                 NULL, HFILL }},
4980         { &hf_gryphon_init_strat_delay,
4981           { "Delay", "gryphon.init_strat.strat_delay", FT_FLOAT, BASE_NONE, NULL, 0x0,
4982                 NULL, HFILL }},
4983         { &hf_gryphon_speed_baud_rate_index,
4984           { "Baud rate index", "gryphon.speed.baud_rate_index", FT_UINT8, BASE_DEC, NULL, 0x0,
4985                 NULL, HFILL }},
4986         { &hf_gryphon_filter_block_filter_start,
4987           { "Filter field starts at byte", "gryphon.filter_block.filter_start", FT_UINT16, BASE_DEC, NULL, 0x0,
4988                 NULL, HFILL }},
4989         { &hf_gryphon_filter_block_filter_length,
4990           { "Filter field length", "gryphon.filter_block.filter_length", FT_UINT16, BASE_DEC, NULL, 0x0,
4991                 NULL, HFILL }},
4992         { &hf_gryphon_filter_block_filter_type,
4993           { "Filtering on", "gryphon.filter_block.filter_type", FT_UINT8, BASE_DEC, VALS(filter_data_types), 0x0,
4994                 NULL, HFILL }},
4995         { &hf_gryphon_filter_block_filter_operator,
4996           { "Type of comparison", "gryphon.filter_block.filter_operator", FT_UINT8, BASE_DEC, VALS(operators), 0x0,
4997                 NULL, HFILL }},
4998         { &hf_gryphon_filter_block_filter_value1,
4999           { "Value", "gryphon.filter_block.filter_value", FT_UINT8, BASE_DEC, NULL, 0x0,
5000                 NULL, HFILL }},
5001         { &hf_gryphon_filter_block_filter_value2,
5002           { "Value", "gryphon.filter_block.filter_value", FT_UINT16, BASE_DEC, NULL, 0x0,
5003                 NULL, HFILL }},
5004         { &hf_gryphon_filter_block_filter_value4,
5005           { "Value", "gryphon.filter_block.filter_value", FT_UINT32, BASE_DEC, NULL, 0x0,
5006                 NULL, HFILL }},
5007         { &hf_gryphon_filter_block_filter_value_bytes,
5008           { "Value",    "gryphon.filter_block.filter_value_bytes", FT_BYTES, BASE_NONE, NULL, 0x0,
5009                 NULL, HFILL }},
5010         { &hf_gryphon_blm_mode,
5011           { "Mode", "gryphon.blm_mode", FT_UINT32, BASE_DEC, VALS(blm_mode_vals), 0x0,
5012                 NULL, HFILL }},
5013         { &hf_gryphon_blm_mode_avg_period,
5014           { "Averaging period (seconds)", "gryphon.blm_mode.avg_period", FT_UINT32, BASE_DEC, NULL, 0x0,
5015                 NULL, HFILL }},
5016         { &hf_gryphon_blm_mode_avg_frames,
5017           { "Averaging period (frames)", "gryphon.blm_mode.avg_frames", FT_UINT32, BASE_DEC, NULL, 0x0,
5018                 NULL, HFILL }},
5019         { &hf_gryphon_command,
5020           { "Command", "gryphon.command", FT_STRING, BASE_NONE, NULL, 0x0,
5021                 NULL, HFILL }},
5022         { &hf_gryphon_cmd_mode,
5023           { "Mode", "gryphon.command.mode", FT_UINT8, BASE_DEC, NULL, 0x0,
5024                 NULL, HFILL }},
5025         { &hf_gryphon_option,
5026           { "Option", "gryphon.option", FT_UINT32, BASE_DEC, NULL, 0x0,
5027                 NULL, HFILL }},
5028         { &hf_gryphon_option_data,
5029           { "Option data", "gryphon.option_data", FT_BYTES, BASE_NONE, NULL, 0x0,
5030                 NULL, HFILL }},
5031         { &hf_gryphon_cmd_file,
5032           { "File", "gryphon.command.file", FT_UINT8, BASE_DEC, NULL, 0x0,
5033                 NULL, HFILL }},
5034         { &hf_gryphon_bit_in_digital_data,
5035           { "Digital values set", "gryphon.bit_in_digital_data", FT_UINT8, BASE_HEX, NULL, 0x0,
5036                 NULL, HFILL }},
5037         { &hf_gryphon_bit_out_digital_data,
5038           { "Digital values set", "gryphon.bit_out_digital_data", FT_UINT8, BASE_HEX, NULL, 0x0,
5039                 NULL, HFILL }},
5040         { &hf_gryphon_filter_block_pattern,
5041           { "Pattern", "gryphon.filter_block.pattern", FT_BYTES, BASE_NONE, NULL, 0x0,
5042                 NULL, HFILL }},
5043         { &hf_gryphon_filter_block_mask,
5044           { "Mask", "gryphon.filter_block.mask", FT_BYTES, BASE_NONE, NULL, 0x0,
5045                 NULL, HFILL }},
5046         /* 20171012 USDT */
5047         { &hf_gryphon_usdt_nids,
5048           { "Number of IDs in block", "gryphon.nids", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5049
5050         { &hf_gryphon_usdt_request,
5051           { "USDT request IDs", "gryphon.usdt_request", FT_UINT32, BASE_HEX, NULL, 0x0,
5052                 NULL, HFILL }},
5053         { &hf_gryphon_usdt_request_ext,
5054           { "USDT request extended address", "gryphon.usdt_request_ext", FT_UINT8, BASE_HEX, NULL, 0x0,
5055                 NULL, HFILL }},
5056         { &hf_gryphon_usdt_response,
5057           { "USDT response IDs", "gryphon.usdt_response", FT_UINT32, BASE_HEX, NULL, 0x0,
5058                 NULL, HFILL }},
5059         { &hf_gryphon_usdt_response_ext,
5060           { "USDT response extended address", "gryphon.usdt_response_ext", FT_UINT8, BASE_HEX, NULL, 0x0,
5061                 NULL, HFILL }},
5062         { &hf_gryphon_uudt_response,
5063           { "UUDT response IDs", "gryphon.uudt_response", FT_UINT32, BASE_HEX, NULL, 0x0,
5064                 NULL, HFILL }},
5065         { &hf_gryphon_uudt_response_ext,
5066           { "UUDT response extended address", "gryphon.usdt_response_ext", FT_UINT8, BASE_HEX, NULL, 0x0,
5067                 NULL, HFILL }},
5068         { &hf_gryphon_more_filenames,
5069           { "More filenames to return", "gryphon.more_filenames", FT_UINT8, BASE_DEC, NULL, 0x0,
5070                 NULL, HFILL }},
5071         { &hf_gryphon_filenames,
5072           { "File and directory names", "gryphon.filenames", FT_STRING, BASE_NONE, NULL, 0x0,
5073                 NULL, HFILL }},
5074         { &hf_gryphon_program_channel_number,
5075           { "Program channel number", "gryphon.program_channel_number", FT_UINT8, BASE_DEC, NULL, 0x0,
5076                 NULL, HFILL }},
5077         { &hf_gryphon_valid_header_length,
5078           { "Valid Header length", "gryphon.valid_header_length", FT_UINT32, BASE_HEX, NULL, 0x0,
5079                 NULL, HFILL }},
5080     };
5081
5082     static gint *ett[] = {
5083         &ett_gryphon,
5084         &ett_gryphon_header,
5085         &ett_gryphon_body,
5086         &ett_gryphon_command_data,
5087         &ett_gryphon_response_data,
5088         &ett_gryphon_data_header,
5089         &ett_gryphon_flags,
5090         &ett_gryphon_data_body,
5091         &ett_gryphon_cmd_filter_block,
5092         &ett_gryphon_cmd_events_data,
5093         &ett_gryphon_cmd_config_device,
5094         &ett_gryphon_cmd_sched_data,
5095         &ett_gryphon_cmd_sched_cmd,
5096         &ett_gryphon_cmd_response_block,
5097         &ett_gryphon_pgm_list,
5098         &ett_gryphon_pgm_status,
5099         &ett_gryphon_pgm_options,
5100         &ett_gryphon_valid_headers,
5101         &ett_gryphon_usdt_data,
5102         &ett_gryphon_usdt_action_flags,
5103         &ett_gryphon_usdt_tx_options_flags,
5104         &ett_gryphon_usdt_rx_options_flags,
5105         &ett_gryphon_usdt_len_options_flags,
5106         &ett_gryphon_usdt_data_block,
5107         &ett_gryphon_lin_emulate_node,
5108         &ett_gryphon_ldf_block,
5109         &ett_gryphon_ldf_schedule_name,
5110         &ett_gryphon_lin_schedule_msg,
5111         &ett_gryphon_cnvt_getflags,
5112         &ett_gryphon_digital_data,
5113         &ett_gryphon_blm_mode
5114     };
5115     module_t *gryphon_module;
5116
5117     proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
5118                                             "Gryphon",
5119                                             "gryphon");
5120     proto_register_field_array(proto_gryphon, hf, array_length(hf));
5121     proto_register_subtree_array(ett, array_length(ett));
5122
5123     gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
5124     prefs_register_bool_preference(gryphon_module, "desegment",
5125         "Desegment all Gryphon messages spanning multiple TCP segments",
5126         "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
5127         &gryphon_desegment);
5128 }
5129
5130 void
5131 proto_reg_handoff_gryphon(void)
5132 {
5133     dissector_handle_t gryphon_handle;
5134
5135     gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
5136     dissector_add_uint_with_preference("tcp.port", GRYPHON_TCP_PORT, gryphon_handle);
5137 }
5138
5139 /*
5140  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
5141  *
5142  * Local variables:
5143  * c-basic-offset: 4
5144  * tab-width: 8
5145  * indent-tabs-mode: nil
5146  * End:
5147  *
5148  * vi: set shiftwidth=4 tabstop=8 expandtab:
5149  * :indentSize=4:tabSize=8:noTabs=true:
5150  */