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.
36 #include <epan/packet.h>
37 #include "packet-gryphon.h"
38 #include <epan/dissectors/packet-tcp.h>
39 #include <epan/prefs.h>
44 * http://www.dgtech.com/gryphon/sys/www/docs/html/
47 static int proto_gryphon = -1;
49 static int hf_gryphon_src = -1;
50 static int hf_gryphon_srcchan = -1;
51 static int hf_gryphon_dest = -1;
52 static int hf_gryphon_destchan= -1;
53 static int hf_gryphon_type = -1;
54 static int hf_gryphon_cmd = -1;
56 static gint ett_gryphon = -1;
57 static gint ett_gryphon_header = -1;
58 static gint ett_gryphon_body = -1;
59 static gint ett_gryphon_command_data = -1;
60 static gint ett_gryphon_response_data = -1;
61 static gint ett_gryphon_data_header = -1;
62 static gint ett_gryphon_flags = -1;
63 static gint ett_gryphon_data_body = -1;
64 static gint ett_gryphon_cmd_filter_block = -1;
65 static gint ett_gryphon_cmd_events_data = -1;
66 static gint ett_gryphon_cmd_config_device = -1;
67 static gint ett_gryphon_cmd_sched_data = -1;
68 static gint ett_gryphon_cmd_sched_cmd = -1;
69 static gint ett_gryphon_cmd_response_block = -1;
70 static gint ett_gryphon_pgm_list = -1;
71 static gint ett_gryphon_pgm_status = -1;
72 static gint ett_gryphon_pgm_options = -1;
73 static gint ett_gryphon_valid_headers = -1;
74 static gint ett_gryphon_usdt_data = -1;
75 static gint ett_gryphon_digital_data = -1;
77 /* desegmentation of Gryphon */
78 static gboolean gryphon_desegment = TRUE;
80 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
81 proto_tree *tree, gboolean is_msgresp_add);
82 static int decode_command(tvbuff_t*, int, int, proto_tree*);
83 static int decode_response(tvbuff_t*, int, int, proto_tree*);
84 static int decode_data(tvbuff_t*, int, proto_tree*);
85 static int decode_event(tvbuff_t*, int, proto_tree*);
86 static int decode_misc(tvbuff_t*, int, proto_tree*);
87 static int cmd_init(tvbuff_t*, int, proto_tree*);
88 static int resp_time(tvbuff_t*, int, proto_tree*);
89 static int cmd_setfilt(tvbuff_t*, int, proto_tree*);
90 static int cmd_ioctl(tvbuff_t*, int, proto_tree*);
91 static int cmd_addfilt(tvbuff_t*, int, proto_tree*);
92 static int resp_addfilt(tvbuff_t*, int, proto_tree*);
93 static int cmd_modfilt(tvbuff_t*, int, proto_tree*);
94 static int resp_filthan(tvbuff_t*, int, proto_tree*);
95 static int dfiltmode(tvbuff_t*, int, proto_tree*);
96 static int filtmode(tvbuff_t*, int, proto_tree*);
97 static int resp_events(tvbuff_t*, int, proto_tree*);
98 static int cmd_register(tvbuff_t*, int, proto_tree*);
99 static int resp_register(tvbuff_t*, int, proto_tree*);
100 static int resp_getspeeds(tvbuff_t*, int, proto_tree*);
101 static int cmd_sort(tvbuff_t*, int, proto_tree*);
102 static int cmd_optimize(tvbuff_t*, int, proto_tree*);
103 static int resp_config(tvbuff_t*, int, proto_tree*);
104 static int cmd_sched(tvbuff_t*, int, proto_tree*);
105 static int cmd_sched_rep(tvbuff_t*, int, proto_tree*);
106 static int resp_blm_data(tvbuff_t*, int, proto_tree*);
107 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
108 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
109 static int resp_addresp(tvbuff_t*, int, proto_tree*);
110 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
111 static int resp_resphan(tvbuff_t*, int, proto_tree*);
112 static int resp_sched(tvbuff_t*, int, proto_tree*);
113 static int cmd_desc(tvbuff_t*, int, proto_tree*);
114 static int resp_desc(tvbuff_t*, int, proto_tree*);
115 static int cmd_upload(tvbuff_t*, int, proto_tree*);
116 static int cmd_delete(tvbuff_t*, int, proto_tree*);
117 static int cmd_list(tvbuff_t*, int, proto_tree*);
118 static int resp_list(tvbuff_t*, int, proto_tree*);
119 static int cmd_start(tvbuff_t*, int, proto_tree*);
120 static int resp_start(tvbuff_t*, int, proto_tree*);
121 static int resp_status(tvbuff_t*, int, proto_tree*);
122 static int cmd_options(tvbuff_t*, int, proto_tree*);
123 static int cmd_files(tvbuff_t*, int, proto_tree*);
124 static int resp_files(tvbuff_t*, int, proto_tree*);
125 static int eventnum(tvbuff_t*, int, proto_tree*);
126 static int speed(tvbuff_t*, int, proto_tree*);
127 static int filter_block(tvbuff_t*, int, proto_tree*);
128 static int blm_mode(tvbuff_t*, int, proto_tree*);
129 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
130 static int cmd_bits_in(tvbuff_t*, int, proto_tree*);
131 static int cmd_bits_out(tvbuff_t*, int, proto_tree*);
132 static int cmd_init_strat(tvbuff_t*, int, proto_tree*);
134 static const char *frame_type[] = {
138 "Network (vehicle) data",
145 * Length of the frame header.
147 #define FRAME_HEADER_LEN 8
150 get_gryphon_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
156 * Get the length of the Gryphon packet, and then get the length as
157 * padded to a 4-byte boundary.
159 plen = tvb_get_ntohs(tvb, offset + 4);
160 padded_len = plen + 3 - (plen + 3) % 4;
163 * That length doesn't include the fixed-length part of the header;
166 return padded_len + FRAME_HEADER_LEN;
170 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
172 dissect_gryphon_message(tvb, pinfo, tree, FALSE);
176 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
178 tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, FRAME_HEADER_LEN,
179 get_gryphon_pdu_len, dissect_gryphon_pdu);
182 static const value_string src_dest[] = {
184 {SD_SERVER, "Server"},
185 {SD_CLIENT, "Client"},
186 {SD_SCHED, "Scheduler"},
187 {SD_SCRIPT, "Script Processor"},
188 {SD_PGM, "Program Loader"},
189 {SD_USDT, "USDT Server"},
190 {SD_BLM, "Bus Load Monitoring"},
191 {SD_FLIGHT, "Flight Recorder"},
192 {SD_RESP, "Message Responder"},
193 {SD_IOPWR, "I/O and power"},
194 {SD_UTIL, "Utility/Miscellaneous"},
199 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
200 gboolean is_msgresp_add)
203 proto_tree *gryphon_tree;
205 proto_tree *header_tree, *body_tree, *localTree;
206 proto_item *header_item, *body_item, *localItem, *hiddenItem;
207 int start_offset, msgend;
209 unsigned int src, dest, i, frmtyp;
212 if (!is_msgresp_add) {
213 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
214 if (check_col(pinfo->cinfo, COL_INFO))
215 col_clear(pinfo->cinfo, COL_INFO);
218 if (!is_msgresp_add) {
219 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
220 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
224 src = tvb_get_guint8(tvb, offset + 0);
225 dest = tvb_get_guint8(tvb, offset + 2);
226 msglen = tvb_get_ntohs(tvb, offset + 4);
227 flags = tvb_get_guint8(tvb, offset + 6);
228 frmtyp = flags & ~RESPONSE_FLAGS;
230 if (!is_msgresp_add) {
232 * This tvbuff includes padding to make its length a multiple
233 * of 4 bytes; set it to the actual length.
235 set_actual_length(tvb, msglen + FRAME_HEADER_LEN);
237 if (check_col(pinfo->cinfo, COL_INFO)) {
239 * Indicate what kind of message this is.
241 if (frmtyp >= SIZEOF (frame_type))
242 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
244 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
251 if (frmtyp >= SIZEOF (frame_type)) {
253 * Unknown message type.
255 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
259 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
260 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
261 proto_tree_add_text(header_tree, tvb, offset, 2,
262 "Source: %s, channel %u",
263 val_to_str(src, src_dest, "Unknown (0x%02x)"),
264 tvb_get_guint8(tvb, offset + 1));
266 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_src, tvb,
268 PROTO_ITEM_SET_HIDDEN(hiddenItem);
270 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_srcchan, tvb,
271 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
272 PROTO_ITEM_SET_HIDDEN(hiddenItem);
274 proto_tree_add_text(header_tree, tvb, offset+2, 2,
275 "Destination: %s, channel %u",
276 val_to_str(dest, src_dest, "Unknown (0x%02x)"),
277 tvb_get_guint8(tvb, offset + 3));
279 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_dest, tvb,
281 PROTO_ITEM_SET_HIDDEN(hiddenItem);
283 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_destchan, tvb,
284 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
285 PROTO_ITEM_SET_HIDDEN(hiddenItem);
287 proto_tree_add_text(header_tree, tvb, offset+4, 2,
288 "Data length: %u byte%s", msglen, msglen == 1 ? "" : "s");
289 proto_tree_add_text(header_tree, tvb, offset+6, 1,
290 "Frame type: %s", frame_type[frmtyp]);
292 if (is_msgresp_add) {
293 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
294 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
295 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
296 decode_boolean_bitfield(flags, DONT_WAIT_FOR_RESP, 8,
297 "Don't wait for response",
298 "Wait for response"));
299 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
300 decode_boolean_bitfield(flags, WAIT_FOR_PREV_RESP, 8,
301 "Wait for previous responses",
302 "Don't wait for previous responses"));
304 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
306 hiddenItem = proto_tree_add_uint(header_tree, hf_gryphon_type, tvb,
307 offset+6, 1, frmtyp);
308 PROTO_ITEM_SET_HIDDEN(hiddenItem);
310 msgpad = 3 - (msglen + 3) % 4;
311 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
313 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
314 msglen + msgpad, "Body");
315 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
317 start_offset = offset;
318 offset += MSG_HDR_SZ;
321 offset = decode_command(tvb, offset, dest, body_tree);
324 offset = decode_response(tvb, offset, src, body_tree);
327 offset = decode_data(tvb, offset, body_tree);
330 offset = decode_event(tvb, offset, body_tree);
333 offset = decode_misc (tvb, offset, body_tree);
340 if (offset < msgend - msgpad) {
341 i = msgend - msgpad - offset;
342 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
345 if (offset < msgend) {
347 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
353 static const val_str_dsp cmds[] = {
354 {CMD_INIT, "Initialize", cmd_init, NULL},
355 {CMD_GET_STAT, "Get status", NULL, NULL},
356 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
357 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
358 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
359 {CMD_GET_TIME, "Get time", NULL, resp_time},
360 {CMD_SET_TIME, "Set time", resp_time, NULL},
361 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
362 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
363 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
364 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
365 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
366 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
367 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
368 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
369 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
370 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
371 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
372 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
373 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
374 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
375 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
376 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
377 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
378 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
379 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
380 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
381 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
382 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
383 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
384 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
385 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
386 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
387 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
388 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
389 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
390 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
391 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
392 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
393 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
394 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
395 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
396 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
397 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
398 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
399 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
400 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
401 {CMD_PGM_START2, "Start an uploaded program", NULL, resp_start},
402 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
403 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
404 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
405 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
406 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
407 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", resp_sched, NULL},
408 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", resp_sched, NULL},
409 {CMD_SCHED_MSG_REPLACE, "Replace a scheduled message", cmd_sched_rep, NULL},
410 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
411 {CMD_USDT_REGISTER, "Register/Unregister with USDT server", cmd_usdt, NULL},
412 {CMD_USDT_SET_FUNCTIONAL, "Set IDs to use extended addressing", cmd_usdt, NULL},
413 {CMD_IOPWR_GETINP, "Read current digital inputs", NULL, cmd_bits_in},
414 {CMD_IOPWR_GETLATCH, "Read latched digital inputs", NULL, cmd_bits_in},
415 {CMD_IOPWR_CLRLATCH, "Read & clear latched digital inputs", cmd_bits_in, cmd_bits_in},
416 {CMD_IOPWR_GETOUT, "Read digital outputs", NULL, cmd_bits_out},
417 {CMD_IOPWR_SETOUT, "Write digital outputs", cmd_bits_out, NULL},
418 {CMD_IOPWR_SETBIT, "Set indicated output bits", cmd_bits_out, NULL},
419 {CMD_IOPWR_CLRBIT, "Clear indicated output bits", cmd_bits_out, NULL},
420 {CMD_IOPWR_GETPOWER, "Read digital inputs at power on time", NULL, cmd_bits_in},
421 {CMD_UTIL_SET_INIT_STRATEGY, "Set initialization strategy", cmd_init_strat, NULL},
422 {CMD_UTIL_GET_INIT_STRATEGY, "Get initialization strategy", NULL, cmd_init_strat},
423 {-1, "- unknown -", NULL, NULL},
426 static const value_string responses[] = {
427 {RESP_OK, "OK - no error"},
428 {RESP_UNKNOWN_ERR, "Unknown error"},
429 {RESP_UNKNOWN_CMD, "Unrecognised command"},
430 {RESP_UNSUPPORTED, "Unsupported command"},
431 {RESP_INVAL_CHAN, "Invalid channel specified"},
432 {RESP_INVAL_DST, "Invalid destination"},
433 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
434 {RESP_INVAL_MSG, "Invalid message"},
435 {RESP_INVAL_LEN, "Invalid length field"},
436 {RESP_TX_FAIL, "Transmit failed"},
437 {RESP_RX_FAIL, "Receive failed"},
438 {RESP_AUTH_FAIL, "Authorization failed"},
439 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
440 {RESP_TIMEOUT, "Command timed out"},
441 {RESP_UNAVAILABLE, "Unavailable"},
442 {RESP_BUF_FULL, "Buffer full"},
443 {RESP_NO_SUCH_JOB, "No such job"},
447 static const value_string filter_data_types[] = {
448 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
449 {FILTER_DATA_TYPE_HEADER, "data message header"},
450 {FILTER_DATA_TYPE_DATA, "data message data"},
451 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
452 {FILTER_EVENT_TYPE_HEADER, "event message header"},
453 {FILTER_EVENT_TYPE_DATA, "event message"},
457 static const value_string operators[] = {
458 {BIT_FIELD_CHECK, "Bit field check"},
459 {SVALUE_GT, "Greater than (signed)"},
460 {SVALUE_GE, "Greater than or equal to (signed)"},
461 {SVALUE_LT, "Less than (signed)"},
462 {SVALUE_LE, "Less than or equal to (signed)"},
463 {VALUE_EQ, "Equal to"},
464 {VALUE_NE, "Not equal to"},
465 {UVALUE_GT, "Greater than (unsigned)"},
466 {UVALUE_GE, "Greater than or equal to (unsigned)"},
467 {UVALUE_LT, "Less than (unsigned)"},
468 {UVALUE_LE, "Less than or equal to (unsigned)"},
469 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
470 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
471 {DIG_TRANSITION, "Digital, change of state"},
475 static const value_string modes[] = {
476 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
477 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
478 {FILTER_ON, "Filter on"},
482 static const value_string dmodes[] = {
483 {DEFAULT_FILTER_BLOCK, "Block"},
484 {DEFAULT_FILTER_PASS, "Pass"},
488 static const value_string filtacts[] = {
489 {DELETE_FILTER, "Delete"},
490 {ACTIVATE_FILTER, "Activate"},
491 {DEACTIVATE_FILTER, "Deactivate"},
495 static const value_string ioctls[] = {
496 {GINIT, "GINIT: Initialize"},
497 {GLOOPON, "GLOOPON: Loop on"},
498 {GLOOPOFF, "GLOOPOFF: Loop off"},
499 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
500 {GGETREG, "GGETREG: Get register"},
501 {GSETREG, "GSETREG: Set register"},
502 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
503 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
504 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
505 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
506 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
507 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
508 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
509 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
510 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
511 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
512 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
513 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
514 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
515 {GGETERRLEV, "GGETERRLEV: Get error level"},
516 {GSETERRLEV, "GSETERRLEV: Set error level"},
517 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
518 {GGETRAM, "GGETRAM: Read value from RAM"},
519 {GSETRAM, "GSETRAM: Write value to RAM"},
520 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
521 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
522 {GCANGETBC, "GCANGETBC: Read CAN bus configuration register"},
523 {GCANSETBC, "GCANSETBC: Write CAN bus configuration register"},
524 {GCANGETMODE, "GCANGETMODE"},
525 {GCANSETMODE, "GCANSETMODE"},
526 {GCANGETTRANS, "GCANGETTRANS"},
527 {GCANSETTRANS, "GCANSETTRANS"},
528 {GCANSENDERR, "GCANSENDERR"},
529 {GCANRGETOBJ, "GCANRGETOBJ"},
530 {GCANRSETSTDID, "GCANRSETSTDID"},
531 {GCANRSETEXTID, "GCANRSETEXTID"},
532 {GCANRSETDATA, "GCANRSETDATA"},
533 {GCANRENABLE, "GCANRENABLE"},
534 {GCANRDISABLE, "GCANRDISABLE"},
535 {GCANRGETMASKS, "GCANRGETMASKS"},
536 {GCANRSETMASKS, "GCANRSETMASKS"},
537 {GCANSWGETMODE, "GCANSWGETMODE"},
538 {GCANSWSETMODE, "GCANSWSETMODE"},
539 {GDLCGETFOURX, "GDLCGETFOURX"},
540 {GDLCSETFOURX, "GDLCSETFOURX"},
541 {GDLCGETLOAD, "GDLCGETLOAD"},
542 {GDLCSETLOAD, "GDLCSETLOAD"},
543 {GDLCSENDBREAK, "GDLCSENDBREAK"},
544 {GDLCABORTTX, "GDLCABORTTX"},
545 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
546 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
547 {GHONSLEEP, "GHONSLEEP"},
548 {GHONSILENCE, "GHONSILENCE"},
549 {GKWPSETPTIMES, "GKWPSETPTIMES"},
550 {GKWPSETWTIMES, "GKWPSETWTIMES"},
551 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
552 {GKWPGETBITTIME, "GKWPGETBITTIME"},
553 {GKWPSETBITTIME, "GKWPSETBITTIME"},
554 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
555 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
556 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
557 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
558 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
559 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
560 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
561 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
562 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
563 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
564 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
565 {GSCPGETBBR, "GSCPGETBBR"},
566 {GSCPSETBBR, "GSCPSETBBR"},
567 {GSCPGETID, "GSCPGETID"},
568 {GSCPSETID, "GSCPSETID"},
569 {GSCPADDFUNCID, "GSCPADDFUNCID"},
570 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
571 {GUBPGETBITRATE, "GUBPGETBITRATE"},
572 {GUBPSETBITRATE, "GUBPSETBITRATE"},
573 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
574 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
575 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
576 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
577 {GUBPGETRETRYDELAY, "GUBPGETRETRYDELAY"},
578 {GUBPSETRETRYDELAY, "GUBPSETRETRYDELAY"},
579 {GRESETHC08, "GRESETHC08: Reset the HC08 processor"},
580 {GTESTHC08COP, "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
581 {GSJAGETLISTEN, "GSJAGETLISTEN"},
582 {GSJASETLISTEN, "GSJASETLISTEN"},
583 {GSJAGETSELFTEST, "GSJAGETSELFTEST"},
584 {GSJASETSELFTEST, "GSJASETSELFTEST"},
585 {GSJAGETXMITONCE, "GSJAGETXMITONCE"},
586 {GSJASETXMITONCE, "GSJASETXMITONCE"},
587 {GSJAGETTRIGSTATE, "GSJAGETTRIGSTATE"},
588 {GSJASETTRIGCTRL, "GSJASETTRIGCTRL"},
589 {GSJAGETTRIGCTRL, "GSJAGETTRIGCTRL"},
590 {GSJAGETOUTSTATE, "GSJAGETOUTSTATE"},
591 {GSJASETOUTSTATE, "GSJASETOUTSTATE"},
592 {GSJAGETFILTER, "GSJAGETFILTER"},
593 {GSJASETFILTER, "GSJASETFILTER"},
594 {GSJAGETMASK, "GSJAGETMASK"},
595 {GSJASETMASK, "GSJASETMASK"},
596 {GSJAGETINTTERM, "GSJAGETINTTERM"},
597 {GSJASETINTTERM, "GSJASETINTTERM"},
598 {GSJAGETFTTRANS, "GSJAGETFTTRANS"},
599 {GSJASETFTTRANS, "GSJASETFTTRANS"},
600 {GSJAGETFTERROR, "GSJAGETFTERROR"},
601 {GLINGETBITRATE, "GLINGETBITRATE: Get the current bit rate"},
602 {GLINSETBITRATE, "GLINSETBITRATE: Set the bit rate"},
603 {GLINGETBRKSPACE, "GLINGETBRKSPACE"},
604 {GLINSETBRKSPACE, "GLINSETBRKSPACE"},
605 {GLINGETBRKMARK, "GLINGETBRKMARK"},
606 {GLINSETBRKMARK, "GLINSETBRKMARK"},
607 {GLINGETIDDELAY, "GLINGETIDDELAY"},
608 {GLINSETIDDELAY, "GLINSETIDDELAY"},
609 {GLINGETRESPDELAY, "GLINGETRESPDELAY"},
610 {GLINSETRESPDELAY, "GLINSETRESPDELAY"},
611 {GLINGETINTERBYTE, "GLINGETINTERBYTE"},
612 {GLINSETINTERBYTE, "GLINSETINTERBYTE"},
613 {GLINGETWAKEUPDELAY, "GLINGETWAKEUPDELAY"},
614 {GLINSETWAKEUPDELAY, "GLINSETWAKEUPDELAY"},
615 {GLINGETWAKEUPTIMEOUT, "GLINGETWAKEUPTIMEOUT"},
616 {GLINSETWAKEUPTIMEOUT, "GLINSETWAKEUPTIMEOUT"},
617 {GLINGETWUTIMOUT3BR, "GLINGETWUTIMOUT3BR"},
618 {GLINSETWUTIMOUT3BR, "GLINSETWUTIMOUT3BR"},
619 {GLINSENDWAKEUP, "GLINSENDWAKEUP"},
620 {GLINGETMODE, "GLINGETMODE"},
621 {GLINSETMODE, "GLINSETMODE"},
622 {GINPGETINP, "GINPGETINP: Read current digital inputs"},
623 {GINPGETLATCH, "GINPGETLATCH: Read latched digital inputs"},
624 {GINPCLRLATCH, "GINPCLRLATCH: Read and clear latched digital inputs"},
625 {GOUTGET, "GOUTGET: Read digital outputs"},
626 {GOUTSET, "GOUTSET: Write digital outputs"},
627 {GOUTSETBIT, "GOUTSETBIT: Set digital output bits"},
628 {GOUTCLEARBIT, "GOUTCLEARBIT"},
629 {GPWRGETWHICH, "GPWRGETWHICH"},
630 {GPWROFF, "GPWROFF"},
631 {GPWROFFRESET, "GPWROFFRESET"},
632 {GPWRRESET, "GPWRRESET"},
641 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
643 int cmd, padding, msglen;
649 msglen = tvb_reported_length_remaining(tvb, offset);
650 cmd = tvb_get_guint8(tvb, offset);
651 hi = proto_tree_add_uint(pt, hf_gryphon_cmd, tvb, offset, 1, cmd);
652 PROTO_ITEM_SET_HIDDEN(hi);
656 for (i = 0; i < SIZEOF(cmds); i++) {
657 if (cmds[i].value == cmd)
660 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
661 cmd = (cmd & 0xFF) + SD_CARD * 256;
662 for (i = 0; i < SIZEOF(cmds); i++) {
663 if (cmds[i].value == cmd)
667 if (i >= SIZEOF(cmds))
668 i = SIZEOF(cmds) - 1;
670 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
674 if (cmds[i].cmd_fnct && msglen > 0) {
675 padding = 3 - (msglen + 3) % 4;
676 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d byte%s)",
677 msglen, msglen == 1 ? "" : "s");
678 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
679 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
685 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
688 unsigned int i, resp;
692 msglen = tvb_reported_length_remaining(tvb, offset);
693 cmd = tvb_get_guint8(tvb, offset);
697 for (i = 0; i < SIZEOF(cmds); i++) {
698 if (cmds[i].value == cmd)
701 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
702 cmd = (cmd & 0xFF) + SD_CARD * 256;
703 for (i = 0; i < SIZEOF(cmds); i++) {
704 if (cmds[i].value == cmd)
708 if (i >= SIZEOF(cmds))
709 i = SIZEOF(cmds) - 1;
710 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
714 resp = tvb_get_ntohl (tvb, offset);
715 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
716 val_to_str(resp, responses, "Unknown (0x%08x)"));
720 if (cmds[i].rsp_fnct && msglen > 0) {
721 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d byte%s)",
722 msglen, msglen == 1 ? "" : "s");
723 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
724 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
730 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
732 proto_item *item, *item1;
733 proto_tree *tree, *tree1;
734 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
735 int hours, minutes, seconds, fraction;
736 unsigned long timestamp;
738 hdrsize = tvb_get_guint8(tvb, offset+0);
739 hdrbits = tvb_get_guint8(tvb, offset+1);
740 datasize = tvb_get_ntohs(tvb, offset+2);
741 extrasize = tvb_get_guint8(tvb, offset+4);
742 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
743 msgsize = hdrsize + datasize + extrasize + padding + 16;
745 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
746 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
747 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d byte%s, %d bits",
748 hdrsize, plurality(hdrsize, "", "s"), hdrbits);
749 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d byte%s",
750 datasize, plurality(datasize, "", "s"));
751 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d byte%s",
752 extrasize, plurality(extrasize, "", "s"));
753 mode = tvb_get_guint8(tvb, offset+5);
754 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
756 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
758 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
759 decode_boolean_bitfield(mode, 0x80, 8,
760 "Transmitted message", NULL));
763 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
764 decode_boolean_bitfield(mode, 0x40, 8,
765 "Received message", NULL));
768 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
769 decode_boolean_bitfield(mode, 0x20, 8,
770 "Local message", NULL));
773 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
774 decode_boolean_bitfield(mode, 0x10, 8,
775 "Remote message", NULL));
778 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
779 decode_boolean_bitfield(mode, 0x01, 8,
780 "Internal message", NULL));
783 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
784 tvb_get_guint8(tvb, offset+6));
785 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
786 tvb_get_guint8(tvb, offset+7));
787 timestamp = tvb_get_ntohl(tvb, offset+8);
788 hours = timestamp /(100000 * 60 *60);
789 minutes = (timestamp / (100000 * 60)) % 60;
790 seconds = (timestamp / 100000) % 60;
791 fraction = timestamp % 100000;
792 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
793 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
794 tvb_get_guint8(tvb, offset+12));
795 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
797 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
798 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
800 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
804 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
808 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
812 proto_tree_add_text(pt, tvb, offset, padding, "padding");
819 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
822 int hours, minutes, seconds, fraction, padding, length;
823 unsigned long timestamp;
826 msglen = tvb_reported_length_remaining(tvb, offset);
827 padding = 3 - (msglen + 3) % 4;
828 msgend = offset + msglen;
829 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
830 tvb_get_guint8(tvb, offset));
831 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
832 tvb_get_guint8(tvb, offset+1));
833 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
835 timestamp = tvb_get_ntohl(tvb, offset);
836 hours = timestamp /(100000 * 60 *60);
837 minutes = (timestamp / (100000 * 60)) % 60;
838 seconds = (timestamp / 100000) % 60;
839 fraction = timestamp % 100000;
840 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
842 if (offset < msgend) {
843 length = msgend - offset;
844 proto_tree_add_text (pt, tvb, offset, length, "Data (%d byte%s)",
845 length, length == 1 ? "" : "s");
849 proto_tree_add_text(pt, tvb, offset, padding, "padding");
856 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
861 unsigned char local_data[LENGTH+1];
863 msglen = tvb_reported_length_remaining(tvb, offset);
864 padding = 3 - (msglen + 3) % 4;
865 length = tvb_get_nstringz0(tvb, offset, LENGTH, local_data);
866 proto_tree_add_text(pt, tvb, offset, msglen, "Data: %s", local_data);
869 proto_tree_add_text (pt, tvb, offset, padding, "padding");
876 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
880 if (tvb_get_guint8(tvb, offset) == 0)
881 ptr = "Always initialize";
883 ptr = "Initialize if not previously initialized";
884 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
885 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
891 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
893 guint8 event = tvb_get_guint8(tvb, offset);
896 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
898 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
899 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
905 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
910 static const char *mon_names[12] = {
925 ts = tvb_get_ntoh64(tvb, offset);
926 timestamp = (time_t) (ts / 100000);
927 tmp = localtime(×tamp);
928 proto_tree_add_text(pt, tvb, offset, 8,
929 "Date/Time: %s %d, %d %02d:%02d:%02d.%05u",
930 mon_names[tmp->tm_mon],
936 (guint) (ts % 100000));
942 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
944 int flag = tvb_get_ntohl(tvb, offset);
948 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
949 + tvb_get_ntohs(tvb, offset+6);
951 g_strlcpy (mode, "Pass", 30);
953 g_strlcpy (mode, "Block", 30);
955 g_strlcat (mode, " all", 30);
956 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
957 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
960 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
961 offset += length * 2;
963 padding = 3 - (length * 2 + 3) % 4;
965 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
972 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
977 msglen = tvb_reported_length_remaining(tvb, offset);
978 ioctl = tvb_get_ntohl(tvb, offset);
979 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
980 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
984 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
991 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
996 int blocks, i, length;
998 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
999 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1000 flags = tvb_get_guint8(tvb, offset);
1001 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1002 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
1003 "Conforming messages are passed",
1004 "Conforming messages are blocked"));
1005 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1006 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1007 "The filter is active", "The filter is inactive"));
1009 blocks = tvb_get_guint8(tvb, offset);
1010 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1011 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
1013 for (i = 1; i <= blocks; i++) {
1014 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1015 length += 3 - (length + 3) % 4;
1016 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1017 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1018 offset = filter_block(tvb, offset, tree);
1024 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1026 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1027 tvb_get_guint8(tvb, offset));
1028 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1034 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1036 guint8 filter_handle;
1037 unsigned char action;
1039 filter_handle = tvb_get_guint8(tvb, offset);
1041 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1044 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1045 action = tvb_get_guint8(tvb, offset + 1);
1046 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
1047 val_to_str(action, filtacts, "Unknown (%u)"));
1048 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1054 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
1056 int handles = tvb_get_guint8(tvb, offset);
1059 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1060 for (i = 1; i <= handles; i++){
1061 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1062 tvb_get_guint8(tvb, offset+i));
1064 padding = 3 - (handles + 1 + 3) % 4;
1066 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1067 offset += 1+handles+padding;
1072 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1076 mode = tvb_get_guint8(tvb, offset);
1077 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1078 val_to_str(mode, dmodes, "Unknown (%u)"));
1079 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1085 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1089 mode = tvb_get_guint8(tvb, offset);
1090 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1091 val_to_str(mode, modes, "Unknown (%u)"));
1092 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1098 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
1105 msglen = tvb_reported_length_remaining(tvb, offset);
1107 while (msglen != 0) {
1108 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1109 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1110 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1111 tvb_get_guint8(tvb, offset));
1112 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1113 tvb_get_ptr(tvb, offset+1, 19));
1122 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1124 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1125 tvb_get_ptr(tvb, offset, 16));
1127 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1128 tvb_get_ptr(tvb, offset, 32));
1134 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1136 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1137 tvb_get_guint8(tvb, offset));
1138 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1139 tvb_get_guint8(tvb, offset+1));
1140 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1147 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1153 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1154 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1155 size = tvb_get_guint8(tvb, offset+8);
1156 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d byte%s",
1157 size, size == 1 ? "" : "s");
1158 number = tvb_get_guint8(tvb, offset+9);
1159 proto_tree_add_text(pt, tvb, offset+9, 1, "There %s %d preset speed%s",
1160 number == 1 ? "is" : "are", number, number == 1 ? "" : "s");
1162 for (index = 0; index < number; index++) {
1163 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1171 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1175 which = tvb_get_guint8(tvb, offset) ?
1176 "Sort into blocks of up to 16 messages" :
1177 "Do not sort messages";
1178 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1184 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1188 which = tvb_get_guint8(tvb, offset) ?
1189 "Optimize for latency (Nagle algorithm disabled)" :
1190 "Optimize for throughput (Nagle algorithm enabled)";
1191 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1197 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1199 proto_item *ti, *item;
1200 proto_tree *ft, *tree;
1205 static const value_string protocol_types[] = {
1206 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1207 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1208 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1209 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1210 {GCAN * 256 + G82527ISO11992, "CAN, 82527 ISO11992 subtype"},
1211 {GCAN * 256 + G82527_SINGLECHAN, "CAN, Fiber Optic 82527 subtype"},
1212 {GCAN * 256 + G82527SW_SINGLECHAN, "CAN, Fiber Optic 82527 single wire subtype"},
1213 {GCAN * 256 + G82527ISO11992_SINGLECHAN, "CAN, Fiber Optic ISO11992 subtype"},
1214 {GCAN * 256 + GSJA1000FT, "CAN, SJA1000 Fault Tolerant subtype"},
1215 {GCAN * 256 + GSJA1000C, "CAN, SJA1000 onboard subtype"},
1216 {GCAN * 256 + GSJA1000FT_FO, "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1217 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1218 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1219 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1220 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1221 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000/ISO 9141"},
1222 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1223 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1224 {GSCI * 256 + G16550SCI, "Chrysler SCI, UART subtype"},
1225 {GCCD * 256 + G16550CDP68HC68, "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1226 {GLIN * 256 + GDGLIN08, "LIN, DG HC08 subtype"},
1230 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1231 tvb_get_ptr(tvb, offset, 20));
1234 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1235 tvb_get_ptr(tvb, offset, 8));
1238 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1239 tvb_get_ptr(tvb, offset, 20));
1242 devices = tvb_get_guint8(tvb, offset);
1243 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1244 proto_tree_add_text(pt, tvb, offset+1, 11, "Name & version extension: %.11s",
1245 tvb_get_ptr(tvb, offset+1, 11));
1246 proto_tree_add_text(pt, tvb, offset+12, 4, "reserved");
1248 for (i = 1; i <= devices; i++) {
1249 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1250 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1251 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1252 tvb_get_ptr(tvb, offset, 20));
1255 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1256 tvb_get_ptr(tvb, offset, 8));
1259 proto_tree_add_text(ft, tvb, offset, 16, "Device security string: %.16s",
1260 tvb_get_ptr(tvb, offset, 16));
1263 x = tvb_get_ntohl (tvb, offset);
1265 item = proto_tree_add_text(ft, tvb, offset, 4, "Valid Header lengths");
1266 tree = proto_item_add_subtree (item, ett_gryphon_valid_headers);
1267 for (j = 0; ; j++) {
1269 proto_tree_add_text(tree, tvb, offset, 4, "%d byte%s", j,
1278 x = tvb_get_ntohs (tvb, offset);
1279 proto_tree_add_text(ft, tvb, offset, 2, "Maximum data length = %d byte%s",
1280 x, x == 1 ? "" : "s");
1283 x = tvb_get_ntohs (tvb, offset);
1284 proto_tree_add_text(ft, tvb, offset, 2, "Minimum data length = %d byte%s",
1285 x, x == 1 ? "" : "s");
1288 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1289 tvb_get_ptr(tvb, offset, 20));
1292 x = tvb_get_ntohs(tvb, offset);
1293 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1294 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1297 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1298 tvb_get_guint8(tvb, offset));
1301 proto_tree_add_text(ft, tvb, offset, 1, "Card slot number: %u",
1302 tvb_get_guint8(tvb, offset));
1305 x = tvb_get_ntohs (tvb, offset);
1306 proto_tree_add_text(ft, tvb, offset, 2, "Maximum extra data = %d byte%s",
1307 x, x == 1 ? "" : "s");
1310 x = tvb_get_ntohs (tvb, offset);
1311 proto_tree_add_text(ft, tvb, offset, 2, "Minimum extra data = %d byte%s",
1312 x, x == 1 ? "" : "s");
1320 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1323 proto_item *item, *item1;
1324 proto_tree *tree, *tree1;
1326 unsigned int i, x, length;
1327 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1329 msglen = tvb_reported_length_remaining(tvb, offset);
1330 x = tvb_get_ntohl(tvb, offset);
1331 if (x == 0xFFFFFFFF)
1332 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: \"infinite\"");
1334 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1337 x = tvb_get_ntohl(tvb, offset);
1338 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1339 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1340 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1341 decode_boolean_bitfield(x, 0x01, 32,
1342 "Critical scheduler", "Normal scheduler"));
1346 while (msglen > 0) {
1347 length = 16 + tvb_get_guint8(tvb, offset+16) +
1348 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1349 length += 3 - (length + 3) % 4;
1350 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1351 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1352 x = tvb_get_ntohl(tvb, offset);
1353 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1356 x = tvb_get_ntohl(tvb, offset);
1357 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1360 x = tvb_get_ntohl(tvb, offset);
1361 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1364 x = tvb_get_ntohs(tvb, offset);
1365 item1 = proto_tree_add_text(tree, tvb, offset, 2, "Flags");
1366 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
1367 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1368 decode_boolean_bitfield(x, 1, 16, "S", "Do not s"),
1369 "kip the last \"Transmit period\"");
1371 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1372 decode_boolean_bitfield(x, 2, 16, "S", "Do not s"),
1373 "kip the first \"Sleep\" value");
1375 x = tvb_get_guint8(tvb, offset+2);
1378 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1379 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1382 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1383 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1384 save_offset = offset;
1385 offset = decode_data(tvb, offset, tree1);
1386 msglen -= offset - save_offset;
1393 cmd_sched_rep(tvbuff_t *tvb, int offset, proto_tree *pt)
1401 msglen = tvb_reported_length_remaining(tvb, offset);
1402 x = tvb_get_ntohl(tvb, offset);
1407 proto_tree_add_text(pt, tvb, offset, 4, "%s schedule ID: %u", type, x);
1410 x= tvb_get_guint8(tvb, offset);
1411 item = proto_tree_add_text(pt, tvb, offset, 1, "Message index: %d", x);
1412 item = proto_tree_add_text(pt, tvb, offset + 1, 3, "reserved");
1415 save_offset = offset;
1416 offset = decode_data(tvb, offset, pt);
1417 msglen -= offset - save_offset;
1422 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1425 int hours, minutes, seconds, fraction, x, fract;
1426 unsigned long timestamp;
1427 static const char *fields[] = {
1428 "Bus load average: %d.%02d%%",
1429 "Current bus load: %d.%02d%%",
1430 "Peak bus load: %d.%02d%%",
1431 "Historic peak bus load: %d.%02d%%"
1434 timestamp = tvb_get_ntohl(tvb, offset);
1435 hours = timestamp /(100000 * 60 *60);
1436 minutes = (timestamp / (100000 * 60)) % 60;
1437 seconds = (timestamp / 100000) % 60;
1438 fraction = timestamp % 100000;
1439 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1441 for (i = 0; i < SIZEOF(fields); i++){
1442 x = tvb_get_ntohs(tvb, offset);
1445 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1452 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
1455 const char *fields[] = {
1456 "Receive frame count: %u",
1457 "Transmit frame count: %u",
1458 "Receive dropped frame count: %u",
1459 "Transmit dropped frame count: %u",
1460 "Receive error count: %u",
1461 "Transmit error count: %u",
1464 offset = resp_blm_data(tvb, offset, pt);
1465 for (i = 0; i < SIZEOF(fields); i++){
1466 x = tvb_get_ntohl(tvb, offset);
1467 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1473 static const value_string action_vals[] = {
1474 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1475 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1476 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1480 static const value_string deact_on_event_vals[] = {
1481 { FR_DEACT_ON_EVENT,
1482 "Deactivate this response for a conforming message" },
1483 { FR_DELETE|FR_DEACT_ON_EVENT,
1484 "Delete this response for a conforming message" },
1489 static const value_string deact_after_per_vals[] = {
1490 { FR_DEACT_AFTER_PER,
1491 "Deactivate this response after the specified period following a conforming message" },
1492 { FR_DELETE|FR_DEACT_AFTER_PER,
1493 "Delete this response after the specified period following a conforming message" },
1499 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1504 int blocks, responses, old_handle, i, msglen, length;
1505 int action, actionType, actionValue;
1509 flags = tvb_get_guint8(tvb, offset);
1510 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1511 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1512 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1513 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1514 "The response is active", "The response is inactive"));
1516 blocks = tvb_get_guint8(tvb, offset);
1517 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1519 responses = tvb_get_guint8(tvb, offset);
1520 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1522 old_handle = tvb_get_guint8(tvb, offset);
1523 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1525 action = tvb_get_guint8(tvb, offset);
1526 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1527 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1528 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1529 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1530 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1531 actionValue = tvb_get_ntohs(tvb, offset+2);
1533 if (action & FR_PERIOD_MSGS) {
1538 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1539 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1540 "The period is in frames", "The period is in 0.01 seconds"));
1542 if (action & FR_DEACT_ON_EVENT) {
1543 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1544 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1545 deact_on_event_vals, "%s"));
1547 if (action & FR_DEACT_AFTER_PER) {
1548 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1549 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1550 deact_after_per_vals, "%s"));
1553 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1556 if (actionType == 1) {
1557 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1559 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1563 for (i = 1; i <= blocks; i++) {
1564 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1565 length += 3 - (length + 3) % 4;
1566 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1567 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1568 offset = filter_block(tvb, offset, tree);
1570 for (i = 1; i <= responses; i++) {
1571 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1572 length = msglen + 3 - (msglen + 3) % 4;
1573 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1574 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1575 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1576 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1583 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1585 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1586 tvb_get_guint8(tvb, offset));
1587 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1593 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1595 unsigned char action;
1596 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1599 resp_handle = tvb_get_guint8(tvb, offset);
1601 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1604 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hd", dest);
1606 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1607 action = tvb_get_guint8(tvb, offset+1);
1608 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1609 val_to_str(action, filtacts, "Unknown (%u)"));
1610 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1616 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1618 int handles = tvb_get_guint8(tvb, offset);
1621 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1622 for (i = 1; i <= handles; i++){
1623 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1624 tvb_get_guint8(tvb, offset+i));
1626 padding = 3 - (handles + 1 + 3) % 4;
1628 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1629 offset += 1+handles+padding;
1634 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1636 unsigned int id = tvb_get_ntohl(tvb, offset);
1638 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1644 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1646 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1647 tvb_get_ntohl(tvb, offset));
1649 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1650 tvb_get_ptr(tvb, offset, 32));
1652 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1653 tvb_get_ptr(tvb, offset, 80));
1659 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1665 flags = tvb_get_guint8(tvb, offset);
1666 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1667 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1668 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1669 decode_boolean_bitfield(flags, 0x01, 8,
1670 "The program is already present",
1671 "The program is not present"));
1672 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1673 tvb_get_guint8(tvb, offset+1));
1674 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1680 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1683 unsigned int length;
1685 msglen = tvb_reported_length_remaining(tvb, offset);
1686 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1687 tvb_get_ntohs(tvb, offset));
1688 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1689 tvb_get_guint8(tvb, offset+2));
1693 proto_tree_add_text(pt, tvb, offset, length, "Data (%u byte%s)",
1694 length, length == 1 ? "" : "s");
1696 length = 3 - (length + 3) % 4;
1698 proto_tree_add_text(pt, tvb, offset, length, "padding");
1705 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1707 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1708 tvb_get_ptr(tvb, offset, 32));
1714 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1716 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1717 tvb_get_guint8(tvb, offset));
1718 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1724 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1728 unsigned int i, count;
1730 count = tvb_get_guint8(tvb, offset);
1731 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1732 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1734 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1735 tvb_get_ntohs(tvb, offset));
1737 for (i = 1; i <= count; i++) {
1738 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1739 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1740 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1741 tvb_get_ptr(tvb, offset, 32));
1743 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1744 tvb_get_ptr(tvb, offset, 80));
1751 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1756 int hdr_stuff = offset;
1758 msglen = tvb_reported_length_remaining(tvb, offset);
1759 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1760 if (offset < msglen + hdr_stuff) {
1761 string = tvb_get_stringz(tvb, offset, &length);
1763 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1765 length = 3 - (length + 3) % 4;
1767 proto_tree_add_text(pt, tvb, offset, length, "padding");
1777 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1781 msglen = tvb_reported_length_remaining(tvb, offset);
1783 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1784 tvb_get_guint8(tvb, offset));
1785 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1792 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1796 unsigned int i, copies, length;
1798 copies = tvb_get_guint8(tvb, offset);
1799 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1800 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1803 for (i = 1; i <= copies; i++) {
1804 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1805 i, tvb_get_guint8(tvb, offset));
1809 length = 3 - (copies + 1 + 3) % 4;
1811 proto_tree_add_text(pt, tvb, offset, length, "padding");
1818 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1823 unsigned int i, size, padding, option, option_length, option_value;
1824 const char *string, *string1;
1826 msglen = tvb_reported_length_remaining(tvb, offset);
1827 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1828 tvb_get_guint8(tvb, offset));
1829 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1832 for (i = 1; msglen > 0; i++) {
1833 option_length = tvb_get_guint8(tvb, offset+1);
1834 size = option_length + 2;
1835 padding = 3 - ((size + 3) %4);
1836 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1837 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1838 option = tvb_get_guint8(tvb, offset);
1839 switch (option_length) {
1841 option_value = tvb_get_guint8(tvb, offset+2);
1844 option_value = tvb_get_ntohs(tvb, offset+2);
1847 option_value = tvb_get_ntohl(tvb, offset+2);
1852 string = "unknown option";
1853 string1 = "unknown option data";
1856 string = "Type of data in the file";
1857 switch (option_value) {
1859 string1 = "Binary - Don't modify";
1862 string1 = "ASCII - Remove CR's";
1867 string = "Type of file";
1868 switch (option_value) {
1870 string1 = "Executable";
1878 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1879 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1881 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1882 offset += size + padding;
1883 msglen -= size + padding;
1889 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1894 msglen = tvb_reported_length_remaining(tvb, offset);
1895 if (tvb_get_guint8(tvb, offset) == 0)
1896 which = "First group of names";
1898 which = "Subsequent group of names";
1900 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1901 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1902 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1908 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1913 msglen = tvb_reported_length_remaining(tvb, offset);
1914 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1915 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1916 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1922 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1924 int ids, id, remain, size, i, j, bytes;
1927 proto_tree *localTree;
1928 proto_item *localItem;
1929 const gchar *actions[] = {
1930 "Use 11 bit headers only",
1931 "Use 29 bit headers only",
1932 "Use both 11 & 29 bit headers",
1935 const gchar *xmit_opts[] = {
1936 "Pad messages with less than 8 data bytes with 0x00's",
1937 "Pad messages with less than 8 data bytes with 0xFF's",
1938 "Do not pad messages with less than 8 data bytes",
1941 const gchar *recv_opts[] = {
1942 "Do not verify the integrity of long received messages and do not send them to the client",
1943 "Verify the integrity of long received messages and send them to the client",
1944 "Verify the integrity of long received messages but do not send them to the client",
1947 const gchar *block_desc[] = {"USDT request", "USDT response", "UUDT response"};
1949 flags = tvb_get_guint8(tvb, offset);
1954 proto_tree_add_text(pt, tvb, offset, 1, "%segister with gusdt", desc);
1957 localItem = proto_tree_add_text(pt, tvb, offset, 1, "Action flags");
1958 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1959 proto_tree_add_text(localTree, tvb, offset, 1, "%s%s",
1960 decode_boolean_bitfield (flags, 1, 8,
1961 "R", "Unr"), "egister with gusdt");
1962 proto_tree_add_text(localTree, tvb, offset, 1, "%s = %s",
1963 decode_numeric_bitfield (flags, 6, 8, "%d"),
1964 actions[(flags >> 1) & 3]);
1966 flags = tvb_get_guint8(tvb, offset+1);
1967 localItem = proto_tree_add_text(pt, tvb, offset+1, 1, "Transmit options");
1968 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1969 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1970 decode_boolean_bitfield (flags, 1, 8,
1972 "cho long transmit messages back to the client");
1973 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s = %s",
1974 decode_numeric_bitfield (flags, 6, 8, "%d"),
1975 xmit_opts[(flags >> 1) & 3]);
1976 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1977 decode_boolean_bitfield (flags, 8, 8,
1979 "end a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted");
1981 flags = tvb_get_guint8(tvb, offset+2);
1982 localItem = proto_tree_add_text(pt, tvb, offset+2, 1, "Receive options");
1983 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1984 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s = %s",
1985 decode_numeric_bitfield (flags, 3, 8, "%d"),
1986 recv_opts[flags & 3]);
1987 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1988 decode_boolean_bitfield (flags, 4, 8,
1990 "end a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received");
1991 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1992 decode_boolean_bitfield (flags, 8, 8,
1994 "end a USDT_LASTFRAME event when the last frame of a multi-frame USDT message is received");
1996 if ((ids = tvb_get_guint8(tvb, offset+3))) {
1997 localItem = proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for %d ID%s",
1998 ids, ids == 1?"":"s");
2000 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2002 id = tvb_get_ntohl (tvb, offset);
2003 proto_tree_add_text (localTree, tvb, offset, 4, "%04X", id);
2008 proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for the single, internally defined, ID");
2011 for (i = 0; i < 2; i++) {
2012 bytes = tvb_reported_length_remaining (tvb, offset);
2015 localItem = proto_tree_add_text(pt, tvb, offset, 16, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
2016 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2017 size = tvb_get_ntohl (tvb, offset);
2019 proto_tree_add_text (localTree, tvb, offset, 16, "No IDs in the block");
2021 } else if (size == 1) {
2022 proto_tree_add_text (localTree, tvb, offset, 4, "1 ID in the block");
2024 for (j = 0; j < 3; j++){
2025 id = tvb_get_ntohl (tvb, offset);
2026 proto_tree_add_text (localTree, tvb, offset, 4,
2027 "%s ID: %04X", block_desc[j], id);
2031 proto_tree_add_text (localTree, tvb, offset, 4, "%d IDs in the block", size);
2033 for (j = 0; j < 3; j++){
2034 id = tvb_get_ntohl (tvb, offset);
2035 proto_tree_add_text (localTree, tvb, offset, 4,
2036 "%s IDs from %04X through %04X", block_desc[j], id, id+size-1);
2042 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2046 if ((remain = tvb_reported_length_remaining(tvb, offset))) {
2047 proto_tree_add_text(pt, tvb, offset, remain, "%d ignored byte%s",
2048 remain, remain == 1 ? "" : "s");
2056 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
2061 int msglen, mask, value;
2062 const char *decode[] = {"Input 1", "Input 2", "Input 3", "Pushbutton"};
2064 msglen = tvb_reported_length_remaining(tvb, offset);
2065 value = tvb_get_guint8(tvb, offset);
2067 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2068 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2069 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2071 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2076 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2085 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
2090 int msglen, mask, value;
2091 const char *decode[] = {"Output 1", "Output 2"};
2093 msglen = tvb_reported_length_remaining(tvb, offset);
2094 value = tvb_get_guint8(tvb, offset);
2096 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2097 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2098 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2100 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2105 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2114 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
2119 msglen = tvb_reported_length_remaining(tvb, offset);
2120 proto_tree_add_text(pt, tvb, offset, 4, "Reset Limit = %u messages",
2121 tvb_get_ntohl(tvb, offset));
2124 for (index = 1; msglen; index++, offset++, msglen--) {
2125 value = tvb_get_guint8(tvb, offset);
2128 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = %.2f seconds",
2131 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = infinite",
2139 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
2141 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
2142 tvb_get_guint8(tvb, offset));
2143 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2149 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2151 unsigned int type, operator;
2152 int length, padding;
2154 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
2155 tvb_get_ntohs(tvb, offset));
2156 length = tvb_get_ntohs(tvb, offset+2);
2157 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d byte%s long",
2158 length, length == 1 ? "" : "s");
2159 type = tvb_get_guint8(tvb, offset+4);
2160 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
2161 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
2163 operator = tvb_get_guint8(tvb, offset+5);
2164 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
2165 val_to_str(operator, operators, "Unknown (%u)"));
2166 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
2169 if (operator == BIT_FIELD_CHECK) {
2170 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
2171 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
2175 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
2176 tvb_get_guint8(tvb, offset));
2179 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
2180 tvb_get_ntohs(tvb, offset));
2183 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
2184 tvb_get_ntohl(tvb, offset));
2187 proto_tree_add_text(pt, tvb, offset, length, "Value");
2190 offset += length * 2;
2191 padding = 3 - (length * 2 + 3) % 4;
2193 proto_tree_add_text(pt, tvb, offset, padding, "padding");
2200 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
2206 x = tvb_get_ntohl(tvb, offset);
2207 y = tvb_get_ntohl(tvb, offset+4);
2211 g_snprintf (line, 50, "reserved");
2214 mode = "Average over time";
2217 g_snprintf (line, 50, "Averaging period: %d.%03d seconds", seconds, y);
2220 mode = "Average over frame count";
2221 g_snprintf (line, 50, "Averaging period: %d frames", y);
2224 mode = "- unknown -";
2225 g_snprintf (line, 50, "reserved");
2227 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
2229 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
2235 proto_register_gryphon(void)
2237 static hf_register_info hf[] = {
2239 { "Source", "gryphon.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2241 { &hf_gryphon_srcchan,
2242 { "Source channel", "gryphon.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2245 { "Destination", "gryphon.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2247 { &hf_gryphon_destchan,
2248 { "Destination channel", "gryphon.destchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2251 { "Frame type", "gryphon.type", FT_UINT8, BASE_DEC, NULL, 0x0,
2254 { "Command", "gryphon.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
2258 static gint *ett[] = {
2260 &ett_gryphon_header,
2262 &ett_gryphon_command_data,
2263 &ett_gryphon_response_data,
2264 &ett_gryphon_data_header,
2266 &ett_gryphon_data_body,
2267 &ett_gryphon_cmd_filter_block,
2268 &ett_gryphon_cmd_events_data,
2269 &ett_gryphon_cmd_config_device,
2270 &ett_gryphon_cmd_sched_data,
2271 &ett_gryphon_cmd_sched_cmd,
2272 &ett_gryphon_cmd_response_block,
2273 &ett_gryphon_pgm_list,
2274 &ett_gryphon_pgm_status,
2275 &ett_gryphon_pgm_options,
2276 &ett_gryphon_valid_headers,
2277 &ett_gryphon_usdt_data,
2278 &ett_gryphon_digital_data,
2280 module_t *gryphon_module;
2282 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
2285 proto_register_field_array(proto_gryphon, hf, array_length(hf));
2286 proto_register_subtree_array(ett, array_length(ett));
2288 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
2289 prefs_register_bool_preference(gryphon_module, "desegment",
2290 "Desegment all Gryphon messages spanning multiple TCP segments",
2291 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2292 &gryphon_desegment);
2296 proto_reg_handoff_gryphon(void)
2298 dissector_handle_t gryphon_handle;
2300 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2301 dissector_add("tcp.port", 7000, gryphon_handle);