2 * Routines for Gryphon protocol packet disassembly
3 * By Steve Limkemann <stevelim@dgtech.com>
4 * Copyright 1998 Steve Limkemann
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/packet.h>
33 #include "packet-gryphon.h"
34 #include <epan/dissectors/packet-tcp.h>
35 #include <epan/prefs.h>
40 * http://www.dgtech.com/gryphon/sys/www/docs/html/
43 static int proto_gryphon = -1;
45 static int hf_gryphon_src = -1;
46 static int hf_gryphon_srcchan = -1;
47 static int hf_gryphon_dest = -1;
48 static int hf_gryphon_destchan= -1;
49 static int hf_gryphon_type = -1;
50 static int hf_gryphon_cmd = -1;
52 static gint ett_gryphon = -1;
53 static gint ett_gryphon_header = -1;
54 static gint ett_gryphon_body = -1;
55 static gint ett_gryphon_command_data = -1;
56 static gint ett_gryphon_response_data = -1;
57 static gint ett_gryphon_data_header = -1;
58 static gint ett_gryphon_flags = -1;
59 static gint ett_gryphon_data_body = -1;
60 static gint ett_gryphon_cmd_filter_block = -1;
61 static gint ett_gryphon_cmd_events_data = -1;
62 static gint ett_gryphon_cmd_config_device = -1;
63 static gint ett_gryphon_cmd_sched_data = -1;
64 static gint ett_gryphon_cmd_sched_cmd = -1;
65 static gint ett_gryphon_cmd_response_block = -1;
66 static gint ett_gryphon_pgm_list = -1;
67 static gint ett_gryphon_pgm_status = -1;
68 static gint ett_gryphon_pgm_options = -1;
69 static gint ett_gryphon_valid_headers = -1;
70 static gint ett_gryphon_usdt_data = -1;
71 static gint ett_gryphon_digital_data = -1;
73 /* desegmentation of Gryphon */
74 static gboolean gryphon_desegment = TRUE;
76 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
77 proto_tree *tree, gboolean is_msgresp_add);
78 static int decode_command(tvbuff_t*, int, int, proto_tree*);
79 static int decode_response(tvbuff_t*, int, int, proto_tree*);
80 static int decode_data(tvbuff_t*, int, proto_tree*);
81 static int decode_event(tvbuff_t*, int, proto_tree*);
82 static int decode_misc(tvbuff_t*, int, proto_tree*);
83 static int cmd_init(tvbuff_t*, int, proto_tree*);
84 static int resp_time(tvbuff_t*, int, proto_tree*);
85 static int cmd_setfilt(tvbuff_t*, int, proto_tree*);
86 static int cmd_ioctl(tvbuff_t*, int, proto_tree*);
87 static int cmd_addfilt(tvbuff_t*, int, proto_tree*);
88 static int resp_addfilt(tvbuff_t*, int, proto_tree*);
89 static int cmd_modfilt(tvbuff_t*, int, proto_tree*);
90 static int resp_filthan(tvbuff_t*, int, proto_tree*);
91 static int dfiltmode(tvbuff_t*, int, proto_tree*);
92 static int filtmode(tvbuff_t*, int, proto_tree*);
93 static int resp_events(tvbuff_t*, int, proto_tree*);
94 static int cmd_register(tvbuff_t*, int, proto_tree*);
95 static int resp_register(tvbuff_t*, int, proto_tree*);
96 static int resp_getspeeds(tvbuff_t*, int, proto_tree*);
97 static int cmd_sort(tvbuff_t*, int, proto_tree*);
98 static int cmd_optimize(tvbuff_t*, int, proto_tree*);
99 static int resp_config(tvbuff_t*, int, proto_tree*);
100 static int cmd_sched(tvbuff_t*, int, proto_tree*);
101 static int cmd_sched_rep(tvbuff_t*, int, proto_tree*);
102 static int resp_blm_data(tvbuff_t*, int, proto_tree*);
103 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
104 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
105 static int resp_addresp(tvbuff_t*, int, proto_tree*);
106 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
107 static int resp_resphan(tvbuff_t*, int, proto_tree*);
108 static int resp_sched(tvbuff_t*, int, proto_tree*);
109 static int cmd_desc(tvbuff_t*, int, proto_tree*);
110 static int resp_desc(tvbuff_t*, int, proto_tree*);
111 static int cmd_upload(tvbuff_t*, int, proto_tree*);
112 static int cmd_delete(tvbuff_t*, int, proto_tree*);
113 static int cmd_list(tvbuff_t*, int, proto_tree*);
114 static int resp_list(tvbuff_t*, int, proto_tree*);
115 static int cmd_start(tvbuff_t*, int, proto_tree*);
116 static int resp_start(tvbuff_t*, int, proto_tree*);
117 static int resp_status(tvbuff_t*, int, proto_tree*);
118 static int cmd_options(tvbuff_t*, int, proto_tree*);
119 static int cmd_files(tvbuff_t*, int, proto_tree*);
120 static int resp_files(tvbuff_t*, int, proto_tree*);
121 static int eventnum(tvbuff_t*, int, proto_tree*);
122 static int speed(tvbuff_t*, int, proto_tree*);
123 static int filter_block(tvbuff_t*, int, proto_tree*);
124 static int blm_mode(tvbuff_t*, int, proto_tree*);
125 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
126 static int cmd_bits_in(tvbuff_t*, int, proto_tree*);
127 static int cmd_bits_out(tvbuff_t*, int, proto_tree*);
128 static int cmd_init_strat(tvbuff_t*, int, proto_tree*);
130 static const char *frame_type[] = {
134 "Network (vehicle) data",
141 * Length of the frame header.
143 #define FRAME_HEADER_LEN 8
146 get_gryphon_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
152 * Get the length of the Gryphon packet, and then get the length as
153 * padded to a 4-byte boundary.
155 plen = tvb_get_ntohs(tvb, offset + 4);
156 padded_len = plen + 3 - (plen + 3) % 4;
159 * That length doesn't include the fixed-length part of the header;
162 return padded_len + FRAME_HEADER_LEN;
166 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
168 dissect_gryphon_message(tvb, pinfo, tree, FALSE);
172 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
174 tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, FRAME_HEADER_LEN,
175 get_gryphon_pdu_len, dissect_gryphon_pdu);
178 static const value_string src_dest[] = {
180 {SD_SERVER, "Server"},
181 {SD_CLIENT, "Client"},
182 {SD_SCHED, "Scheduler"},
183 {SD_SCRIPT, "Script Processor"},
184 {SD_PGM, "Program Loader"},
185 {SD_USDT, "USDT Server"},
186 {SD_BLM, "Bus Load Monitoring"},
187 {SD_FLIGHT, "Flight Recorder"},
188 {SD_RESP, "Message Responder"},
189 {SD_IOPWR, "I/O and power"},
190 {SD_UTIL, "Utility/Miscellaneous"},
195 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
196 gboolean is_msgresp_add)
199 proto_tree *gryphon_tree;
201 proto_tree *header_tree, *body_tree, *localTree;
202 proto_item *header_item, *body_item, *localItem, *hiddenItem;
203 int start_offset, msgend;
205 unsigned int src, dest, i, frmtyp;
208 if (!is_msgresp_add) {
209 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
210 col_clear(pinfo->cinfo, COL_INFO);
213 if (!is_msgresp_add) {
214 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
215 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
219 src = tvb_get_guint8(tvb, offset + 0);
220 dest = tvb_get_guint8(tvb, offset + 2);
221 msglen = tvb_get_ntohs(tvb, offset + 4);
222 flags = tvb_get_guint8(tvb, offset + 6);
223 frmtyp = flags & ~RESPONSE_FLAGS;
225 if (!is_msgresp_add) {
227 * This tvbuff includes padding to make its length a multiple
228 * of 4 bytes; set it to the actual length.
230 set_actual_length(tvb, msglen + FRAME_HEADER_LEN);
233 * Indicate what kind of message this is.
235 if (frmtyp >= SIZEOF (frame_type))
236 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
238 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
244 if (frmtyp >= SIZEOF (frame_type)) {
246 * Unknown message type.
248 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
252 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
253 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
254 proto_tree_add_text(header_tree, tvb, offset, 2,
255 "Source: %s, channel %u",
256 val_to_str(src, src_dest, "Unknown (0x%02x)"),
257 tvb_get_guint8(tvb, offset + 1));
259 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_src, tvb,
261 PROTO_ITEM_SET_HIDDEN(hiddenItem);
263 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_srcchan, tvb,
264 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
265 PROTO_ITEM_SET_HIDDEN(hiddenItem);
267 proto_tree_add_text(header_tree, tvb, offset+2, 2,
268 "Destination: %s, channel %u",
269 val_to_str(dest, src_dest, "Unknown (0x%02x)"),
270 tvb_get_guint8(tvb, offset + 3));
272 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_dest, tvb,
274 PROTO_ITEM_SET_HIDDEN(hiddenItem);
276 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_destchan, tvb,
277 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
278 PROTO_ITEM_SET_HIDDEN(hiddenItem);
280 proto_tree_add_text(header_tree, tvb, offset+4, 2,
281 "Data length: %u byte%s", msglen, msglen == 1 ? "" : "s");
282 proto_tree_add_text(header_tree, tvb, offset+6, 1,
283 "Frame type: %s", frame_type[frmtyp]);
285 if (is_msgresp_add) {
286 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
287 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
288 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
289 decode_boolean_bitfield(flags, DONT_WAIT_FOR_RESP, 8,
290 "Don't wait for response",
291 "Wait for response"));
292 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
293 decode_boolean_bitfield(flags, WAIT_FOR_PREV_RESP, 8,
294 "Wait for previous responses",
295 "Don't wait for previous responses"));
297 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
299 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_type, tvb,
300 offset+6, 1, frmtyp);
301 PROTO_ITEM_SET_HIDDEN(hiddenItem);
303 msgpad = 3 - (msglen + 3) % 4;
304 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
306 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
307 msglen + msgpad, "Body");
308 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
310 start_offset = offset;
311 offset += MSG_HDR_SZ;
314 offset = decode_command(tvb, offset, dest, body_tree);
317 offset = decode_response(tvb, offset, src, body_tree);
320 offset = decode_data(tvb, offset, body_tree);
323 offset = decode_event(tvb, offset, body_tree);
326 offset = decode_misc (tvb, offset, body_tree);
333 if (offset < msgend - msgpad) {
334 i = msgend - msgpad - offset;
335 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
338 if (offset < msgend) {
340 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
346 static const val_str_dsp cmds[] = {
347 {CMD_INIT, "Initialize", cmd_init, NULL},
348 {CMD_GET_STAT, "Get status", NULL, NULL},
349 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
350 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
351 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
352 {CMD_GET_TIME, "Get time", NULL, resp_time},
353 {CMD_SET_TIME, "Set time", resp_time, NULL},
354 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
355 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
356 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
357 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
358 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
359 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
360 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
361 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
362 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
363 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
364 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
365 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
366 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
367 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
368 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
369 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
370 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
371 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
372 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
373 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
374 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
375 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
376 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
377 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
378 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
379 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
380 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
381 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
382 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
383 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
384 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
385 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
386 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
387 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
388 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
389 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
390 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
391 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
392 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
393 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
394 {CMD_PGM_START2, "Start an uploaded program", NULL, resp_start},
395 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
396 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
397 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
398 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
399 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
400 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", resp_sched, NULL},
401 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", resp_sched, NULL},
402 {CMD_SCHED_MSG_REPLACE, "Replace a scheduled message", cmd_sched_rep, NULL},
403 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
404 {CMD_USDT_REGISTER, "Register/Unregister with USDT server", cmd_usdt, NULL},
405 {CMD_USDT_SET_FUNCTIONAL, "Set IDs to use extended addressing", cmd_usdt, NULL},
406 {CMD_IOPWR_GETINP, "Read current digital inputs", NULL, cmd_bits_in},
407 {CMD_IOPWR_GETLATCH, "Read latched digital inputs", NULL, cmd_bits_in},
408 {CMD_IOPWR_CLRLATCH, "Read & clear latched digital inputs", cmd_bits_in, cmd_bits_in},
409 {CMD_IOPWR_GETOUT, "Read digital outputs", NULL, cmd_bits_out},
410 {CMD_IOPWR_SETOUT, "Write digital outputs", cmd_bits_out, NULL},
411 {CMD_IOPWR_SETBIT, "Set indicated output bits", cmd_bits_out, NULL},
412 {CMD_IOPWR_CLRBIT, "Clear indicated output bits", cmd_bits_out, NULL},
413 {CMD_IOPWR_GETPOWER, "Read digital inputs at power on time", NULL, cmd_bits_in},
414 {CMD_UTIL_SET_INIT_STRATEGY, "Set initialization strategy", cmd_init_strat, NULL},
415 {CMD_UTIL_GET_INIT_STRATEGY, "Get initialization strategy", NULL, cmd_init_strat},
416 {-1, "- unknown -", NULL, NULL},
419 static const value_string responses_vs[] = {
420 {RESP_OK, "OK - no error"},
421 {RESP_UNKNOWN_ERR, "Unknown error"},
422 {RESP_UNKNOWN_CMD, "Unrecognised command"},
423 {RESP_UNSUPPORTED, "Unsupported command"},
424 {RESP_INVAL_CHAN, "Invalid channel specified"},
425 {RESP_INVAL_DST, "Invalid destination"},
426 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
427 {RESP_INVAL_MSG, "Invalid message"},
428 {RESP_INVAL_LEN, "Invalid length field"},
429 {RESP_TX_FAIL, "Transmit failed"},
430 {RESP_RX_FAIL, "Receive failed"},
431 {RESP_AUTH_FAIL, "Authorization failed"},
432 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
433 {RESP_TIMEOUT, "Command timed out"},
434 {RESP_UNAVAILABLE, "Unavailable"},
435 {RESP_BUF_FULL, "Buffer full"},
436 {RESP_NO_SUCH_JOB, "No such job"},
440 static const value_string filter_data_types[] = {
441 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
442 {FILTER_DATA_TYPE_HEADER, "data message header"},
443 {FILTER_DATA_TYPE_DATA, "data message data"},
444 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
445 {FILTER_EVENT_TYPE_HEADER, "event message header"},
446 {FILTER_EVENT_TYPE_DATA, "event message"},
450 static const value_string operators[] = {
451 {BIT_FIELD_CHECK, "Bit field check"},
452 {SVALUE_GT, "Greater than (signed)"},
453 {SVALUE_GE, "Greater than or equal to (signed)"},
454 {SVALUE_LT, "Less than (signed)"},
455 {SVALUE_LE, "Less than or equal to (signed)"},
456 {VALUE_EQ, "Equal to"},
457 {VALUE_NE, "Not equal to"},
458 {UVALUE_GT, "Greater than (unsigned)"},
459 {UVALUE_GE, "Greater than or equal to (unsigned)"},
460 {UVALUE_LT, "Less than (unsigned)"},
461 {UVALUE_LE, "Less than or equal to (unsigned)"},
462 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
463 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
464 {DIG_TRANSITION, "Digital, change of state"},
468 static const value_string modes[] = {
469 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
470 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
471 {FILTER_ON, "Filter on"},
475 static const value_string dmodes[] = {
476 {DEFAULT_FILTER_BLOCK, "Block"},
477 {DEFAULT_FILTER_PASS, "Pass"},
481 static const value_string filtacts[] = {
482 {DELETE_FILTER, "Delete"},
483 {ACTIVATE_FILTER, "Activate"},
484 {DEACTIVATE_FILTER, "Deactivate"},
488 static const value_string ioctls[] = {
489 {GINIT, "GINIT: Initialize"},
490 {GLOOPON, "GLOOPON: Loop on"},
491 {GLOOPOFF, "GLOOPOFF: Loop off"},
492 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
493 {GGETREG, "GGETREG: Get register"},
494 {GSETREG, "GSETREG: Set register"},
495 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
496 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
497 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
498 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
499 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
500 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
501 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
502 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
503 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
504 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
505 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
506 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
507 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
508 {GGETERRLEV, "GGETERRLEV: Get error level"},
509 {GSETERRLEV, "GSETERRLEV: Set error level"},
510 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
511 {GGETRAM, "GGETRAM: Read value from RAM"},
512 {GSETRAM, "GSETRAM: Write value to RAM"},
513 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
514 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
515 {GCANGETBC, "GCANGETBC: Read CAN bus configuration register"},
516 {GCANSETBC, "GCANSETBC: Write CAN bus configuration register"},
517 {GCANGETMODE, "GCANGETMODE"},
518 {GCANSETMODE, "GCANSETMODE"},
519 {GCANGETTRANS, "GCANGETTRANS"},
520 {GCANSETTRANS, "GCANSETTRANS"},
521 {GCANSENDERR, "GCANSENDERR"},
522 {GCANRGETOBJ, "GCANRGETOBJ"},
523 {GCANRSETSTDID, "GCANRSETSTDID"},
524 {GCANRSETEXTID, "GCANRSETEXTID"},
525 {GCANRSETDATA, "GCANRSETDATA"},
526 {GCANRENABLE, "GCANRENABLE"},
527 {GCANRDISABLE, "GCANRDISABLE"},
528 {GCANRGETMASKS, "GCANRGETMASKS"},
529 {GCANRSETMASKS, "GCANRSETMASKS"},
530 {GCANSWGETMODE, "GCANSWGETMODE"},
531 {GCANSWSETMODE, "GCANSWSETMODE"},
532 {GDLCGETFOURX, "GDLCGETFOURX"},
533 {GDLCSETFOURX, "GDLCSETFOURX"},
534 {GDLCGETLOAD, "GDLCGETLOAD"},
535 {GDLCSETLOAD, "GDLCSETLOAD"},
536 {GDLCSENDBREAK, "GDLCSENDBREAK"},
537 {GDLCABORTTX, "GDLCABORTTX"},
538 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
539 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
540 {GHONSLEEP, "GHONSLEEP"},
541 {GHONSILENCE, "GHONSILENCE"},
542 {GKWPSETPTIMES, "GKWPSETPTIMES"},
543 {GKWPSETWTIMES, "GKWPSETWTIMES"},
544 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
545 {GKWPGETBITTIME, "GKWPGETBITTIME"},
546 {GKWPSETBITTIME, "GKWPSETBITTIME"},
547 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
548 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
549 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
550 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
551 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
552 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
553 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
554 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
555 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
556 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
557 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
558 {GSCPGETBBR, "GSCPGETBBR"},
559 {GSCPSETBBR, "GSCPSETBBR"},
560 {GSCPGETID, "GSCPGETID"},
561 {GSCPSETID, "GSCPSETID"},
562 {GSCPADDFUNCID, "GSCPADDFUNCID"},
563 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
564 {GUBPGETBITRATE, "GUBPGETBITRATE"},
565 {GUBPSETBITRATE, "GUBPSETBITRATE"},
566 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
567 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
568 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
569 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
570 {GUBPGETRETRYDELAY, "GUBPGETRETRYDELAY"},
571 {GUBPSETRETRYDELAY, "GUBPSETRETRYDELAY"},
572 {GRESETHC08, "GRESETHC08: Reset the HC08 processor"},
573 {GTESTHC08COP, "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
574 {GSJAGETLISTEN, "GSJAGETLISTEN"},
575 {GSJASETLISTEN, "GSJASETLISTEN"},
576 {GSJAGETSELFTEST, "GSJAGETSELFTEST"},
577 {GSJASETSELFTEST, "GSJASETSELFTEST"},
578 {GSJAGETXMITONCE, "GSJAGETXMITONCE"},
579 {GSJASETXMITONCE, "GSJASETXMITONCE"},
580 {GSJAGETTRIGSTATE, "GSJAGETTRIGSTATE"},
581 {GSJASETTRIGCTRL, "GSJASETTRIGCTRL"},
582 {GSJAGETTRIGCTRL, "GSJAGETTRIGCTRL"},
583 {GSJAGETOUTSTATE, "GSJAGETOUTSTATE"},
584 {GSJASETOUTSTATE, "GSJASETOUTSTATE"},
585 {GSJAGETFILTER, "GSJAGETFILTER"},
586 {GSJASETFILTER, "GSJASETFILTER"},
587 {GSJAGETMASK, "GSJAGETMASK"},
588 {GSJASETMASK, "GSJASETMASK"},
589 {GSJAGETINTTERM, "GSJAGETINTTERM"},
590 {GSJASETINTTERM, "GSJASETINTTERM"},
591 {GSJAGETFTTRANS, "GSJAGETFTTRANS"},
592 {GSJASETFTTRANS, "GSJASETFTTRANS"},
593 {GSJAGETFTERROR, "GSJAGETFTERROR"},
594 {GLINGETBITRATE, "GLINGETBITRATE: Get the current bit rate"},
595 {GLINSETBITRATE, "GLINSETBITRATE: Set the bit rate"},
596 {GLINGETBRKSPACE, "GLINGETBRKSPACE"},
597 {GLINSETBRKSPACE, "GLINSETBRKSPACE"},
598 {GLINGETBRKMARK, "GLINGETBRKMARK"},
599 {GLINSETBRKMARK, "GLINSETBRKMARK"},
600 {GLINGETIDDELAY, "GLINGETIDDELAY"},
601 {GLINSETIDDELAY, "GLINSETIDDELAY"},
602 {GLINGETRESPDELAY, "GLINGETRESPDELAY"},
603 {GLINSETRESPDELAY, "GLINSETRESPDELAY"},
604 {GLINGETINTERBYTE, "GLINGETINTERBYTE"},
605 {GLINSETINTERBYTE, "GLINSETINTERBYTE"},
606 {GLINGETWAKEUPDELAY, "GLINGETWAKEUPDELAY"},
607 {GLINSETWAKEUPDELAY, "GLINSETWAKEUPDELAY"},
608 {GLINGETWAKEUPTIMEOUT, "GLINGETWAKEUPTIMEOUT"},
609 {GLINSETWAKEUPTIMEOUT, "GLINSETWAKEUPTIMEOUT"},
610 {GLINGETWUTIMOUT3BR, "GLINGETWUTIMOUT3BR"},
611 {GLINSETWUTIMOUT3BR, "GLINSETWUTIMOUT3BR"},
612 {GLINSENDWAKEUP, "GLINSENDWAKEUP"},
613 {GLINGETMODE, "GLINGETMODE"},
614 {GLINSETMODE, "GLINSETMODE"},
615 {GINPGETINP, "GINPGETINP: Read current digital inputs"},
616 {GINPGETLATCH, "GINPGETLATCH: Read latched digital inputs"},
617 {GINPCLRLATCH, "GINPCLRLATCH: Read and clear latched digital inputs"},
618 {GOUTGET, "GOUTGET: Read digital outputs"},
619 {GOUTSET, "GOUTSET: Write digital outputs"},
620 {GOUTSETBIT, "GOUTSETBIT: Set digital output bits"},
621 {GOUTCLEARBIT, "GOUTCLEARBIT"},
622 {GPWRGETWHICH, "GPWRGETWHICH"},
623 {GPWROFF, "GPWROFF"},
624 {GPWROFFRESET, "GPWROFFRESET"},
625 {GPWRRESET, "GPWRRESET"},
634 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
636 int cmd, padding, msglen;
642 msglen = tvb_reported_length_remaining(tvb, offset);
643 cmd = tvb_get_guint8(tvb, offset);
644 hi = proto_tree_add_uint(pt, hf_gryphon_cmd, tvb, offset, 1, cmd);
645 PROTO_ITEM_SET_HIDDEN(hi);
649 for (i = 0; i < SIZEOF(cmds); i++) {
650 if (cmds[i].value == cmd)
653 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
654 cmd = (cmd & 0xFF) + SD_CARD * 256;
655 for (i = 0; i < SIZEOF(cmds); i++) {
656 if (cmds[i].value == cmd)
660 if (i >= SIZEOF(cmds))
661 i = SIZEOF(cmds) - 1;
663 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
667 if (cmds[i].cmd_fnct && msglen > 0) {
668 padding = 3 - (msglen + 3) % 4;
669 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d byte%s)",
670 msglen, msglen == 1 ? "" : "s");
671 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
672 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
678 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
681 unsigned int i, resp;
685 msglen = tvb_reported_length_remaining(tvb, offset);
686 cmd = tvb_get_guint8(tvb, offset);
690 for (i = 0; i < SIZEOF(cmds); i++) {
691 if (cmds[i].value == cmd)
694 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
695 cmd = (cmd & 0xFF) + SD_CARD * 256;
696 for (i = 0; i < SIZEOF(cmds); i++) {
697 if (cmds[i].value == cmd)
701 if (i >= SIZEOF(cmds))
702 i = SIZEOF(cmds) - 1;
703 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
707 resp = tvb_get_ntohl (tvb, offset);
708 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
709 val_to_str(resp, responses_vs, "Unknown (0x%08x)"));
713 if (cmds[i].rsp_fnct && msglen > 0) {
714 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d byte%s)",
715 msglen, msglen == 1 ? "" : "s");
716 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
717 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
723 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
725 proto_item *item, *item1;
726 proto_tree *tree, *tree1;
727 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
728 int hours, minutes, seconds, fraction;
729 unsigned long timestamp;
731 hdrsize = tvb_get_guint8(tvb, offset+0);
732 hdrbits = tvb_get_guint8(tvb, offset+1);
733 datasize = tvb_get_ntohs(tvb, offset+2);
734 extrasize = tvb_get_guint8(tvb, offset+4);
735 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
736 msgsize = hdrsize + datasize + extrasize + padding + 16;
738 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
739 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
740 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d byte%s, %d bits",
741 hdrsize, plurality(hdrsize, "", "s"), hdrbits);
742 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d byte%s",
743 datasize, plurality(datasize, "", "s"));
744 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d byte%s",
745 extrasize, plurality(extrasize, "", "s"));
746 mode = tvb_get_guint8(tvb, offset+5);
747 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
749 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
751 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
752 decode_boolean_bitfield(mode, 0x80, 8,
753 "Transmitted message", NULL));
756 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
757 decode_boolean_bitfield(mode, 0x40, 8,
758 "Received message", NULL));
761 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
762 decode_boolean_bitfield(mode, 0x20, 8,
763 "Local message", NULL));
766 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
767 decode_boolean_bitfield(mode, 0x10, 8,
768 "Remote message", NULL));
771 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
772 decode_boolean_bitfield(mode, 0x01, 8,
773 "Internal message", NULL));
776 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
777 tvb_get_guint8(tvb, offset+6));
778 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
779 tvb_get_guint8(tvb, offset+7));
780 timestamp = tvb_get_ntohl(tvb, offset+8);
781 hours = timestamp /(100000 * 60 *60);
782 minutes = (timestamp / (100000 * 60)) % 60;
783 seconds = (timestamp / 100000) % 60;
784 fraction = timestamp % 100000;
785 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
786 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
787 tvb_get_guint8(tvb, offset+12));
788 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
790 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
791 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
793 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
797 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
801 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
805 proto_tree_add_text(pt, tvb, offset, padding, "padding");
812 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
815 int hours, minutes, seconds, fraction, padding, length;
816 unsigned long timestamp;
819 msglen = tvb_reported_length_remaining(tvb, offset);
820 padding = 3 - (msglen + 3) % 4;
821 msgend = offset + msglen;
822 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
823 tvb_get_guint8(tvb, offset));
824 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
825 tvb_get_guint8(tvb, offset+1));
826 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
828 timestamp = tvb_get_ntohl(tvb, offset);
829 hours = timestamp /(100000 * 60 *60);
830 minutes = (timestamp / (100000 * 60)) % 60;
831 seconds = (timestamp / 100000) % 60;
832 fraction = timestamp % 100000;
833 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
835 if (offset < msgend) {
836 length = msgend - offset;
837 proto_tree_add_text (pt, tvb, offset, length, "Data (%d byte%s)",
838 length, length == 1 ? "" : "s");
842 proto_tree_add_text(pt, tvb, offset, padding, "padding");
849 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
854 unsigned char local_data[LENGTH+1];
856 msglen = tvb_reported_length_remaining(tvb, offset);
857 padding = 3 - (msglen + 3) % 4;
858 length = tvb_get_nstringz0(tvb, offset, LENGTH, local_data);
859 proto_tree_add_text(pt, tvb, offset, msglen, "Data: %s", local_data);
862 proto_tree_add_text (pt, tvb, offset, padding, "padding");
869 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
873 if (tvb_get_guint8(tvb, offset) == 0)
874 ptr = "Always initialize";
876 ptr = "Initialize if not previously initialized";
877 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
878 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
884 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
886 guint8 event = tvb_get_guint8(tvb, offset);
889 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
891 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
892 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
898 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
903 static const char *mon_names[12] = {
918 ts = tvb_get_ntoh64(tvb, offset);
919 timestamp = (time_t) (ts / 100000);
920 tmp = localtime(×tamp);
921 proto_tree_add_text(pt, tvb, offset, 8,
922 "Date/Time: %s %d, %d %02d:%02d:%02d.%05u",
923 mon_names[tmp->tm_mon],
929 (guint) (ts % 100000));
935 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
937 int flag = tvb_get_ntohl(tvb, offset);
941 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
942 + tvb_get_ntohs(tvb, offset+6);
944 g_strlcpy (mode, "Pass", 30);
946 g_strlcpy (mode, "Block", 30);
948 g_strlcat (mode, " all", 30);
949 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
950 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
953 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
954 offset += length * 2;
956 padding = 3 - (length * 2 + 3) % 4;
958 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
965 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
970 msglen = tvb_reported_length_remaining(tvb, offset);
971 ioctl = tvb_get_ntohl(tvb, offset);
972 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
973 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
977 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
984 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
989 int blocks, i, length;
991 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
992 tree = proto_item_add_subtree (item, ett_gryphon_flags);
993 flags = tvb_get_guint8(tvb, offset);
994 proto_tree_add_text(tree, tvb, offset, 1, "%s",
995 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
996 "Conforming messages are passed",
997 "Conforming messages are blocked"));
998 proto_tree_add_text(tree, tvb, offset, 1, "%s",
999 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1000 "The filter is active", "The filter is inactive"));
1002 blocks = tvb_get_guint8(tvb, offset);
1003 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1004 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
1006 for (i = 1; i <= blocks; i++) {
1007 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1008 length += 3 - (length + 3) % 4;
1009 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1010 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1011 offset = filter_block(tvb, offset, tree);
1017 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1019 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1020 tvb_get_guint8(tvb, offset));
1021 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1027 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1029 guint8 filter_handle;
1030 unsigned char action;
1032 filter_handle = tvb_get_guint8(tvb, offset);
1034 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1037 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1038 action = tvb_get_guint8(tvb, offset + 1);
1039 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
1040 val_to_str(action, filtacts, "Unknown (%u)"));
1041 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1047 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
1049 int handles = tvb_get_guint8(tvb, offset);
1052 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1053 for (i = 1; i <= handles; i++){
1054 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1055 tvb_get_guint8(tvb, offset+i));
1057 padding = 3 - (handles + 1 + 3) % 4;
1059 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1060 offset += 1+handles+padding;
1065 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1069 mode = tvb_get_guint8(tvb, offset);
1070 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1071 val_to_str(mode, dmodes, "Unknown (%u)"));
1072 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1078 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1082 mode = tvb_get_guint8(tvb, offset);
1083 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1084 val_to_str(mode, modes, "Unknown (%u)"));
1085 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1091 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
1098 msglen = tvb_reported_length_remaining(tvb, offset);
1100 while (msglen != 0) {
1101 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1102 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1103 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1104 tvb_get_guint8(tvb, offset));
1105 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1106 tvb_get_ptr(tvb, offset+1, 19));
1115 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1117 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1118 tvb_get_ptr(tvb, offset, 16));
1120 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1121 tvb_get_ptr(tvb, offset, 32));
1127 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1129 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1130 tvb_get_guint8(tvb, offset));
1131 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1132 tvb_get_guint8(tvb, offset+1));
1133 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1140 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1146 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1147 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1148 size = tvb_get_guint8(tvb, offset+8);
1149 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d byte%s",
1150 size, size == 1 ? "" : "s");
1151 number = tvb_get_guint8(tvb, offset+9);
1152 proto_tree_add_text(pt, tvb, offset+9, 1, "There %s %d preset speed%s",
1153 number == 1 ? "is" : "are", number, number == 1 ? "" : "s");
1155 for (index = 0; index < number; index++) {
1156 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1164 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1168 which = tvb_get_guint8(tvb, offset) ?
1169 "Sort into blocks of up to 16 messages" :
1170 "Do not sort messages";
1171 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1177 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1181 which = tvb_get_guint8(tvb, offset) ?
1182 "Optimize for latency (Nagle algorithm disabled)" :
1183 "Optimize for throughput (Nagle algorithm enabled)";
1184 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1190 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1192 proto_item *ti, *item;
1193 proto_tree *ft, *tree;
1198 static const value_string protocol_types[] = {
1199 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1200 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1201 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1202 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1203 {GCAN * 256 + G82527ISO11992, "CAN, 82527 ISO11992 subtype"},
1204 {GCAN * 256 + G82527_SINGLECHAN, "CAN, Fiber Optic 82527 subtype"},
1205 {GCAN * 256 + G82527SW_SINGLECHAN, "CAN, Fiber Optic 82527 single wire subtype"},
1206 {GCAN * 256 + G82527ISO11992_SINGLECHAN, "CAN, Fiber Optic ISO11992 subtype"},
1207 {GCAN * 256 + GSJA1000FT, "CAN, SJA1000 Fault Tolerant subtype"},
1208 {GCAN * 256 + GSJA1000C, "CAN, SJA1000 onboard subtype"},
1209 {GCAN * 256 + GSJA1000FT_FO, "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1210 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1211 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1212 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1213 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1214 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000/ISO 9141"},
1215 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1216 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1217 {GSCI * 256 + G16550SCI, "Chrysler SCI, UART subtype"},
1218 {GCCD * 256 + G16550CDP68HC68, "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1219 {GLIN * 256 + GDGLIN08, "LIN, DG HC08 subtype"},
1223 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1224 tvb_get_ptr(tvb, offset, 20));
1227 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1228 tvb_get_ptr(tvb, offset, 8));
1231 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1232 tvb_get_ptr(tvb, offset, 20));
1235 devices = tvb_get_guint8(tvb, offset);
1236 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1237 proto_tree_add_text(pt, tvb, offset+1, 11, "Name & version extension: %.11s",
1238 tvb_get_ptr(tvb, offset+1, 11));
1239 proto_tree_add_text(pt, tvb, offset+12, 4, "reserved");
1241 for (i = 1; i <= devices; i++) {
1242 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1243 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1244 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1245 tvb_get_ptr(tvb, offset, 20));
1248 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1249 tvb_get_ptr(tvb, offset, 8));
1252 proto_tree_add_text(ft, tvb, offset, 16, "Device security string: %.16s",
1253 tvb_get_ptr(tvb, offset, 16));
1256 x = tvb_get_ntohl (tvb, offset);
1258 item = proto_tree_add_text(ft, tvb, offset, 4, "Valid Header lengths");
1259 tree = proto_item_add_subtree (item, ett_gryphon_valid_headers);
1260 for (j = 0; ; j++) {
1262 proto_tree_add_text(tree, tvb, offset, 4, "%d byte%s", j,
1271 x = tvb_get_ntohs (tvb, offset);
1272 proto_tree_add_text(ft, tvb, offset, 2, "Maximum data length = %d byte%s",
1273 x, x == 1 ? "" : "s");
1276 x = tvb_get_ntohs (tvb, offset);
1277 proto_tree_add_text(ft, tvb, offset, 2, "Minimum data length = %d byte%s",
1278 x, x == 1 ? "" : "s");
1281 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1282 tvb_get_ptr(tvb, offset, 20));
1285 x = tvb_get_ntohs(tvb, offset);
1286 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1287 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1290 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1291 tvb_get_guint8(tvb, offset));
1294 proto_tree_add_text(ft, tvb, offset, 1, "Card slot number: %u",
1295 tvb_get_guint8(tvb, offset));
1298 x = tvb_get_ntohs (tvb, offset);
1299 proto_tree_add_text(ft, tvb, offset, 2, "Maximum extra data = %d byte%s",
1300 x, x == 1 ? "" : "s");
1303 x = tvb_get_ntohs (tvb, offset);
1304 proto_tree_add_text(ft, tvb, offset, 2, "Minimum extra data = %d byte%s",
1305 x, x == 1 ? "" : "s");
1313 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1316 proto_item *item, *item1;
1317 proto_tree *tree, *tree1;
1319 unsigned int i, x, length;
1320 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1322 msglen = tvb_reported_length_remaining(tvb, offset);
1323 x = tvb_get_ntohl(tvb, offset);
1324 if (x == 0xFFFFFFFF)
1325 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: \"infinite\"");
1327 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1330 x = tvb_get_ntohl(tvb, offset);
1331 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1332 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1333 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1334 decode_boolean_bitfield(x, 0x01, 32,
1335 "Critical scheduler", "Normal scheduler"));
1339 while (msglen > 0) {
1340 length = 16 + tvb_get_guint8(tvb, offset+16) +
1341 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1342 length += 3 - (length + 3) % 4;
1343 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1344 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1345 x = tvb_get_ntohl(tvb, offset);
1346 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1349 x = tvb_get_ntohl(tvb, offset);
1350 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1353 x = tvb_get_ntohl(tvb, offset);
1354 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1357 x = tvb_get_ntohs(tvb, offset);
1358 item1 = proto_tree_add_text(tree, tvb, offset, 2, "Flags");
1359 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
1360 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1361 decode_boolean_bitfield(x, 1, 16, "S", "Do not s"),
1362 "kip the last \"Transmit period\"");
1364 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1365 decode_boolean_bitfield(x, 2, 16, "S", "Do not s"),
1366 "kip the first \"Sleep\" value");
1368 x = tvb_get_guint8(tvb, offset+2);
1371 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1372 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1375 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1376 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1377 save_offset = offset;
1378 offset = decode_data(tvb, offset, tree1);
1379 msglen -= offset - save_offset;
1386 cmd_sched_rep(tvbuff_t *tvb, int offset, proto_tree *pt)
1394 msglen = tvb_reported_length_remaining(tvb, offset);
1395 x = tvb_get_ntohl(tvb, offset);
1400 proto_tree_add_text(pt, tvb, offset, 4, "%s schedule ID: %u", type, x);
1403 x= tvb_get_guint8(tvb, offset);
1404 item = proto_tree_add_text(pt, tvb, offset, 1, "Message index: %d", x);
1405 item = proto_tree_add_text(pt, tvb, offset + 1, 3, "reserved");
1408 save_offset = offset;
1409 offset = decode_data(tvb, offset, pt);
1410 msglen -= offset - save_offset;
1415 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1418 int hours, minutes, seconds, fraction, x, fract;
1419 unsigned long timestamp;
1420 static const char *fields[] = {
1421 "Bus load average: %d.%02d%%",
1422 "Current bus load: %d.%02d%%",
1423 "Peak bus load: %d.%02d%%",
1424 "Historic peak bus load: %d.%02d%%"
1427 timestamp = tvb_get_ntohl(tvb, offset);
1428 hours = timestamp /(100000 * 60 *60);
1429 minutes = (timestamp / (100000 * 60)) % 60;
1430 seconds = (timestamp / 100000) % 60;
1431 fraction = timestamp % 100000;
1432 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1434 for (i = 0; i < SIZEOF(fields); i++){
1435 x = tvb_get_ntohs(tvb, offset);
1438 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1445 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
1448 const char *fields[] = {
1449 "Receive frame count: %u",
1450 "Transmit frame count: %u",
1451 "Receive dropped frame count: %u",
1452 "Transmit dropped frame count: %u",
1453 "Receive error count: %u",
1454 "Transmit error count: %u",
1457 offset = resp_blm_data(tvb, offset, pt);
1458 for (i = 0; i < SIZEOF(fields); i++){
1459 x = tvb_get_ntohl(tvb, offset);
1460 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1466 static const value_string action_vals[] = {
1467 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1468 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1469 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1473 static const value_string deact_on_event_vals[] = {
1474 { FR_DEACT_ON_EVENT,
1475 "Deactivate this response for a conforming message" },
1476 { FR_DELETE|FR_DEACT_ON_EVENT,
1477 "Delete this response for a conforming message" },
1482 static const value_string deact_after_per_vals[] = {
1483 { FR_DEACT_AFTER_PER,
1484 "Deactivate this response after the specified period following a conforming message" },
1485 { FR_DELETE|FR_DEACT_AFTER_PER,
1486 "Delete this response after the specified period following a conforming message" },
1492 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1497 int blocks, responses, old_handle, i, msglen, length;
1498 int action, actionType, actionValue;
1502 flags = tvb_get_guint8(tvb, offset);
1503 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1504 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1505 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1506 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1507 "The response is active", "The response is inactive"));
1509 blocks = tvb_get_guint8(tvb, offset);
1510 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1512 responses = tvb_get_guint8(tvb, offset);
1513 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1515 old_handle = tvb_get_guint8(tvb, offset);
1516 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1518 action = tvb_get_guint8(tvb, offset);
1519 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1520 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1521 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1522 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1523 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1524 actionValue = tvb_get_ntohs(tvb, offset+2);
1526 if (action & FR_PERIOD_MSGS) {
1531 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1532 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1533 "The period is in frames", "The period is in 0.01 seconds"));
1535 if (action & FR_DEACT_ON_EVENT) {
1536 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1537 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1538 deact_on_event_vals, "%s"));
1540 if (action & FR_DEACT_AFTER_PER) {
1541 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1542 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1543 deact_after_per_vals, "%s"));
1546 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1549 if (actionType == 1) {
1550 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1552 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1556 for (i = 1; i <= blocks; i++) {
1557 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1558 length += 3 - (length + 3) % 4;
1559 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1560 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1561 offset = filter_block(tvb, offset, tree);
1563 for (i = 1; i <= responses; i++) {
1564 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1565 length = msglen + 3 - (msglen + 3) % 4;
1566 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1567 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1568 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1569 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1576 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1578 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1579 tvb_get_guint8(tvb, offset));
1580 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1586 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1588 unsigned char action;
1589 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1592 resp_handle = tvb_get_guint8(tvb, offset);
1594 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1597 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hhd", dest);
1599 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1600 action = tvb_get_guint8(tvb, offset+1);
1601 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1602 val_to_str(action, filtacts, "Unknown (%u)"));
1603 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1609 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1611 int handles = tvb_get_guint8(tvb, offset);
1614 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1615 for (i = 1; i <= handles; i++){
1616 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1617 tvb_get_guint8(tvb, offset+i));
1619 padding = 3 - (handles + 1 + 3) % 4;
1621 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1622 offset += 1+handles+padding;
1627 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1629 unsigned int id = tvb_get_ntohl(tvb, offset);
1631 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1637 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1639 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1640 tvb_get_ntohl(tvb, offset));
1642 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1643 tvb_get_ptr(tvb, offset, 32));
1645 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1646 tvb_get_ptr(tvb, offset, 80));
1652 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1658 flags = tvb_get_guint8(tvb, offset);
1659 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1660 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1661 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1662 decode_boolean_bitfield(flags, 0x01, 8,
1663 "The program is already present",
1664 "The program is not present"));
1665 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1666 tvb_get_guint8(tvb, offset+1));
1667 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1673 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1676 unsigned int length;
1678 msglen = tvb_reported_length_remaining(tvb, offset);
1679 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1680 tvb_get_ntohs(tvb, offset));
1681 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1682 tvb_get_guint8(tvb, offset+2));
1686 proto_tree_add_text(pt, tvb, offset, length, "Data (%u byte%s)",
1687 length, length == 1 ? "" : "s");
1689 length = 3 - (length + 3) % 4;
1691 proto_tree_add_text(pt, tvb, offset, length, "padding");
1698 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1700 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1701 tvb_get_ptr(tvb, offset, 32));
1707 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1709 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1710 tvb_get_guint8(tvb, offset));
1711 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1717 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1721 unsigned int i, count;
1723 count = tvb_get_guint8(tvb, offset);
1724 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1725 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1727 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1728 tvb_get_ntohs(tvb, offset));
1730 for (i = 1; i <= count; i++) {
1731 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1732 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1733 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1734 tvb_get_ptr(tvb, offset, 32));
1736 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1737 tvb_get_ptr(tvb, offset, 80));
1744 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1749 int hdr_stuff = offset;
1751 msglen = tvb_reported_length_remaining(tvb, offset);
1752 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1753 if (offset < msglen + hdr_stuff) {
1754 string = tvb_get_ephemeral_stringz(tvb, offset, &length);
1756 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1758 length = 3 - (length + 3) % 4;
1760 proto_tree_add_text(pt, tvb, offset, length, "padding");
1769 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1773 msglen = tvb_reported_length_remaining(tvb, offset);
1775 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1776 tvb_get_guint8(tvb, offset));
1777 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1784 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1788 unsigned int i, copies, length;
1790 copies = tvb_get_guint8(tvb, offset);
1791 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1792 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1795 for (i = 1; i <= copies; i++) {
1796 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1797 i, tvb_get_guint8(tvb, offset));
1801 length = 3 - (copies + 1 + 3) % 4;
1803 proto_tree_add_text(pt, tvb, offset, length, "padding");
1810 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1815 unsigned int i, size, padding, option, option_length, option_value;
1816 const char *string, *string1;
1818 msglen = tvb_reported_length_remaining(tvb, offset);
1819 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1820 tvb_get_guint8(tvb, offset));
1821 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1824 for (i = 1; msglen > 0; i++) {
1825 option_length = tvb_get_guint8(tvb, offset+1);
1826 size = option_length + 2;
1827 padding = 3 - ((size + 3) %4);
1828 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1829 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1830 option = tvb_get_guint8(tvb, offset);
1831 switch (option_length) {
1833 option_value = tvb_get_guint8(tvb, offset+2);
1836 option_value = tvb_get_ntohs(tvb, offset+2);
1839 option_value = tvb_get_ntohl(tvb, offset+2);
1844 string = "unknown option";
1845 string1 = "unknown option data";
1848 string = "Type of data in the file";
1849 switch (option_value) {
1851 string1 = "Binary - Don't modify";
1854 string1 = "ASCII - Remove CR's";
1859 string = "Type of file";
1860 switch (option_value) {
1862 string1 = "Executable";
1870 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1871 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1873 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1874 offset += size + padding;
1875 msglen -= size + padding;
1881 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1886 msglen = tvb_reported_length_remaining(tvb, offset);
1887 if (tvb_get_guint8(tvb, offset) == 0)
1888 which = "First group of names";
1890 which = "Subsequent group of names";
1892 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1893 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1894 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1900 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1905 msglen = tvb_reported_length_remaining(tvb, offset);
1906 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1907 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1908 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1914 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1916 int ids, id, remain, size, i, j, bytes;
1919 proto_tree *localTree;
1920 proto_item *localItem;
1921 const gchar *actions[] = {
1922 "Use 11 bit headers only",
1923 "Use 29 bit headers only",
1924 "Use both 11 & 29 bit headers",
1927 const gchar *xmit_opts[] = {
1928 "Pad messages with less than 8 data bytes with 0x00's",
1929 "Pad messages with less than 8 data bytes with 0xFF's",
1930 "Do not pad messages with less than 8 data bytes",
1933 const gchar *recv_opts[] = {
1934 "Do not verify the integrity of long received messages and do not send them to the client",
1935 "Verify the integrity of long received messages and send them to the client",
1936 "Verify the integrity of long received messages but do not send them to the client",
1939 const gchar *block_desc[] = {"USDT request", "USDT response", "UUDT response"};
1941 flags = tvb_get_guint8(tvb, offset);
1946 proto_tree_add_text(pt, tvb, offset, 1, "%segister with gusdt", desc);
1949 localItem = proto_tree_add_text(pt, tvb, offset, 1, "Action flags");
1950 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1951 proto_tree_add_text(localTree, tvb, offset, 1, "%s%s",
1952 decode_boolean_bitfield (flags, 1, 8,
1953 "R", "Unr"), "egister with gusdt");
1954 proto_tree_add_text(localTree, tvb, offset, 1, "%s = %s",
1955 decode_numeric_bitfield (flags, 6, 8, "%d"),
1956 actions[(flags >> 1) & 3]);
1958 flags = tvb_get_guint8(tvb, offset+1);
1959 localItem = proto_tree_add_text(pt, tvb, offset+1, 1, "Transmit options");
1960 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1961 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1962 decode_boolean_bitfield (flags, 1, 8,
1964 "cho long transmit messages back to the client");
1965 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s = %s",
1966 decode_numeric_bitfield (flags, 6, 8, "%d"),
1967 xmit_opts[(flags >> 1) & 3]);
1968 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1969 decode_boolean_bitfield (flags, 8, 8,
1971 "end a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted");
1973 flags = tvb_get_guint8(tvb, offset+2);
1974 localItem = proto_tree_add_text(pt, tvb, offset+2, 1, "Receive options");
1975 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1976 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s = %s",
1977 decode_numeric_bitfield (flags, 3, 8, "%d"),
1978 recv_opts[flags & 3]);
1979 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1980 decode_boolean_bitfield (flags, 4, 8,
1982 "end a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received");
1983 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1984 decode_boolean_bitfield (flags, 8, 8,
1986 "end a USDT_LASTFRAME event when the last frame of a multi-frame USDT message is received");
1988 if ((ids = tvb_get_guint8(tvb, offset+3))) {
1989 localItem = proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for %d ID%s",
1990 ids, ids == 1?"":"s");
1992 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
1994 id = tvb_get_ntohl (tvb, offset);
1995 proto_tree_add_text (localTree, tvb, offset, 4, "%04X", id);
2000 proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for the single, internally defined, ID");
2003 for (i = 0; i < 2; i++) {
2004 bytes = tvb_reported_length_remaining (tvb, offset);
2007 localItem = proto_tree_add_text(pt, tvb, offset, 16, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
2008 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2009 size = tvb_get_ntohl (tvb, offset);
2011 proto_tree_add_text (localTree, tvb, offset, 16, "No IDs in the block");
2013 } else if (size == 1) {
2014 proto_tree_add_text (localTree, tvb, offset, 4, "1 ID in the block");
2016 for (j = 0; j < 3; j++){
2017 id = tvb_get_ntohl (tvb, offset);
2018 proto_tree_add_text (localTree, tvb, offset, 4,
2019 "%s ID: %04X", block_desc[j], id);
2023 proto_tree_add_text (localTree, tvb, offset, 4, "%d IDs in the block", size);
2025 for (j = 0; j < 3; j++){
2026 id = tvb_get_ntohl (tvb, offset);
2027 proto_tree_add_text (localTree, tvb, offset, 4,
2028 "%s IDs from %04X through %04X", block_desc[j], id, id+size-1);
2034 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2038 if ((remain = tvb_reported_length_remaining(tvb, offset))) {
2039 proto_tree_add_text(pt, tvb, offset, remain, "%d ignored byte%s",
2040 remain, remain == 1 ? "" : "s");
2048 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
2053 int msglen, mask, value;
2054 const char *decode[] = {"Input 1", "Input 2", "Input 3", "Pushbutton"};
2056 msglen = tvb_reported_length_remaining(tvb, offset);
2057 value = tvb_get_guint8(tvb, offset);
2059 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2060 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2061 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2063 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2068 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2077 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
2082 int msglen, mask, value;
2083 const char *decode[] = {"Output 1", "Output 2"};
2085 msglen = tvb_reported_length_remaining(tvb, offset);
2086 value = tvb_get_guint8(tvb, offset);
2088 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2089 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2090 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2092 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2097 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2106 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
2111 msglen = tvb_reported_length_remaining(tvb, offset);
2112 proto_tree_add_text(pt, tvb, offset, 4, "Reset Limit = %u messages",
2113 tvb_get_ntohl(tvb, offset));
2116 for (index = 1; msglen; index++, offset++, msglen--) {
2117 value = tvb_get_guint8(tvb, offset);
2120 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = %.2f seconds",
2123 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = infinite",
2131 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
2133 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
2134 tvb_get_guint8(tvb, offset));
2135 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2141 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2143 unsigned int type, operator;
2144 int length, padding;
2146 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
2147 tvb_get_ntohs(tvb, offset));
2148 length = tvb_get_ntohs(tvb, offset+2);
2149 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d byte%s long",
2150 length, length == 1 ? "" : "s");
2151 type = tvb_get_guint8(tvb, offset+4);
2152 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
2153 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
2155 operator = tvb_get_guint8(tvb, offset+5);
2156 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
2157 val_to_str(operator, operators, "Unknown (%u)"));
2158 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
2161 if (operator == BIT_FIELD_CHECK) {
2162 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
2163 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
2167 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
2168 tvb_get_guint8(tvb, offset));
2171 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
2172 tvb_get_ntohs(tvb, offset));
2175 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
2176 tvb_get_ntohl(tvb, offset));
2179 proto_tree_add_text(pt, tvb, offset, length, "Value");
2182 offset += length * 2;
2183 padding = 3 - (length * 2 + 3) % 4;
2185 proto_tree_add_text(pt, tvb, offset, padding, "padding");
2192 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
2198 x = tvb_get_ntohl(tvb, offset);
2199 y = tvb_get_ntohl(tvb, offset+4);
2203 g_snprintf (line, 50, "reserved");
2206 mode = "Average over time";
2209 g_snprintf (line, 50, "Averaging period: %d.%03d seconds", seconds, y);
2212 mode = "Average over frame count";
2213 g_snprintf (line, 50, "Averaging period: %d frames", y);
2216 mode = "- unknown -";
2217 g_snprintf (line, 50, "reserved");
2219 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
2221 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
2227 proto_register_gryphon(void)
2229 static hf_register_info hf[] = {
2231 { "Source", "gryphon.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2233 { &hf_gryphon_srcchan,
2234 { "Source channel", "gryphon.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2237 { "Destination", "gryphon.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2239 { &hf_gryphon_destchan,
2240 { "Destination channel", "gryphon.destchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2243 { "Frame type", "gryphon.type", FT_UINT8, BASE_DEC, NULL, 0x0,
2246 { "Command", "gryphon.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
2250 static gint *ett[] = {
2252 &ett_gryphon_header,
2254 &ett_gryphon_command_data,
2255 &ett_gryphon_response_data,
2256 &ett_gryphon_data_header,
2258 &ett_gryphon_data_body,
2259 &ett_gryphon_cmd_filter_block,
2260 &ett_gryphon_cmd_events_data,
2261 &ett_gryphon_cmd_config_device,
2262 &ett_gryphon_cmd_sched_data,
2263 &ett_gryphon_cmd_sched_cmd,
2264 &ett_gryphon_cmd_response_block,
2265 &ett_gryphon_pgm_list,
2266 &ett_gryphon_pgm_status,
2267 &ett_gryphon_pgm_options,
2268 &ett_gryphon_valid_headers,
2269 &ett_gryphon_usdt_data,
2270 &ett_gryphon_digital_data,
2272 module_t *gryphon_module;
2274 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
2277 proto_register_field_array(proto_gryphon, hf, array_length(hf));
2278 proto_register_subtree_array(ett, array_length(ett));
2280 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
2281 prefs_register_bool_preference(gryphon_module, "desegment",
2282 "Desegment all Gryphon messages spanning multiple TCP segments",
2283 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2284 &gryphon_desegment);
2288 proto_reg_handoff_gryphon(void)
2290 dissector_handle_t gryphon_handle;
2292 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2293 dissector_add("tcp.port", 7000, gryphon_handle);