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 <epan/dissectors/packet-tcp.h>
34 #include <epan/prefs.h>
35 #include "packet-gryphon.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;
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, ENC_NA);
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 offset += MSG_HDR_SZ;
313 offset = decode_command(tvb, offset, dest, body_tree);
316 offset = decode_response(tvb, offset, src, body_tree);
319 offset = decode_data(tvb, offset, body_tree);
322 offset = decode_event(tvb, offset, body_tree);
325 offset = decode_misc (tvb, offset, body_tree);
332 if (offset < msgend - msgpad) {
333 i = msgend - msgpad - offset;
334 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
337 if (offset < msgend) {
339 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
345 static const val_str_dsp cmds[] = {
346 {CMD_INIT, "Initialize" , cmd_init , NULL},
347 {CMD_GET_STAT, "Get status" , NULL , NULL},
348 {CMD_GET_CONFIG, "Get configuration" , NULL , resp_config},
349 {CMD_EVENT_ENABLE, "Enable event" , eventnum , NULL},
350 {CMD_EVENT_DISABLE, "Disable event" , eventnum , NULL},
351 {CMD_GET_TIME, "Get time" , NULL , resp_time},
352 {CMD_SET_TIME, "Set time" , resp_time , NULL},
353 {CMD_GET_RXDROP, "Get number of dropped RX messages" , NULL , NULL},
354 {CMD_RESET_RXDROP, "Clear number of dropped RX messages" , NULL , NULL},
355 {CMD_BCAST_ON, "Set broadcasts on" , NULL , NULL},
356 {CMD_BCAST_OFF, "Set broadcasts off" , NULL , NULL},
357 {CMD_CARD_SET_SPEED, "Set channel baud rate" , speed , NULL},
358 {CMD_CARD_GET_SPEED, "Get channel baud rate" , NULL , speed},
359 {CMD_CARD_SET_FILTER, "Set filter (deprecated)" , cmd_setfilt , NULL},
360 {CMD_CARD_GET_FILTER, "Get filter" , resp_addfilt , cmd_addfilt},
361 {CMD_CARD_TX, "Transmit message" , decode_data , NULL},
362 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on" , NULL , NULL},
363 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off" , NULL , NULL},
364 {CMD_CARD_IOCTL, "IOCTL pass-through" , cmd_ioctl , NULL},
365 {CMD_CARD_ADD_FILTER, "Add a filter" , cmd_addfilt , resp_addfilt},
366 {CMD_CARD_MODIFY_FILTER, "Modify a filter" , cmd_modfilt , NULL},
367 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles" , NULL , resp_filthan},
368 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter" , dfiltmode , NULL},
369 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode" , NULL , dfiltmode},
370 {CMD_CARD_SET_FILTER_MODE, "Set filter mode" , filtmode , NULL},
371 {CMD_CARD_GET_FILTER_MODE, "Get filter mode" , NULL , filtmode},
372 {CMD_CARD_GET_EVNAMES, "Get event names" , NULL , resp_events},
373 {CMD_CARD_GET_SPEEDS, "Get defined speeds" , NULL , resp_getspeeds},
374 {CMD_SERVER_REG, "Register with server" , cmd_register , resp_register},
375 {CMD_SERVER_SET_SORT, "Set the sorting behavior" , cmd_sort , NULL},
376 {CMD_SERVER_SET_OPT, "Set the type of optimization" , cmd_optimize , NULL},
377 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode" , blm_mode , NULL},
378 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode" , NULL , blm_mode},
379 {CMD_BLM_GET_DATA, "Get Bus Load data" , NULL , resp_blm_data},
380 {CMD_BLM_GET_STATS, "Get Bus Load statistics" , NULL , resp_blm_stat},
381 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info" , NULL , NULL},
382 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring" , NULL , NULL},
383 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring" , NULL , NULL},
384 {CMD_MSGRESP_ADD, "Add response message" , cmd_addresp , resp_addresp},
385 {CMD_MSGRESP_GET, "Get response message" , resp_addresp , cmd_addresp},
386 {CMD_MSGRESP_MODIFY, "Modify response message state" , cmd_modresp , NULL},
387 {CMD_MSGRESP_GET_HANDLES, "Get response message handles" , NULL , resp_resphan},
388 {CMD_PGM_DESC, "Describe program to to uploaded" , cmd_desc , resp_desc},
389 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon" , cmd_upload , NULL},
390 {CMD_PGM_DELETE, "Delete an uploaded program" , cmd_delete , NULL},
391 {CMD_PGM_LIST, "Get a list of uploaded programs" , cmd_list , resp_list},
392 {CMD_PGM_START, "Start an uploaded program" , cmd_start , resp_start},
393 {CMD_PGM_START2, "Start an uploaded program" , NULL , resp_start},
394 {CMD_PGM_STOP, "Stop an uploaded program" , resp_start , NULL},
395 {CMD_PGM_STATUS, "Get status of an uploaded program" , cmd_delete , resp_status},
396 {CMD_PGM_OPTIONS, "Set program upload options" , cmd_options , resp_status},
397 {CMD_PGM_FILES, "Get a list of files & directories" , cmd_files , resp_files},
398 {CMD_SCHED_TX, "Schedule transmission of messages" , cmd_sched , resp_sched},
399 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission" , resp_sched , NULL},
400 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", resp_sched , NULL},
401 {CMD_SCHED_MSG_REPLACE, "Replace a scheduled message" , cmd_sched_rep , NULL},
402 {CMD_USDT_IOCTL, "Register/Unregister with USDT server" , cmd_usdt , NULL},
403 {CMD_USDT_REGISTER, "Register/Unregister with USDT server" , cmd_usdt , NULL},
404 {CMD_USDT_SET_FUNCTIONAL, "Set IDs to use extended addressing" , cmd_usdt , NULL},
405 {CMD_IOPWR_GETINP, "Read current digital inputs" , NULL , cmd_bits_in},
406 {CMD_IOPWR_GETLATCH, "Read latched digital inputs" , NULL , cmd_bits_in},
407 {CMD_IOPWR_CLRLATCH, "Read & clear latched digital inputs" , cmd_bits_in , cmd_bits_in},
408 {CMD_IOPWR_GETOUT, "Read digital outputs" , NULL , cmd_bits_out},
409 {CMD_IOPWR_SETOUT, "Write digital outputs" , cmd_bits_out , NULL},
410 {CMD_IOPWR_SETBIT, "Set indicated output bits" , cmd_bits_out , NULL},
411 {CMD_IOPWR_CLRBIT, "Clear indicated output bits" , cmd_bits_out , NULL},
412 {CMD_IOPWR_GETPOWER, "Read digital inputs at power on time" , NULL , cmd_bits_in},
413 {CMD_UTIL_SET_INIT_STRATEGY, "Set initialization strategy" , cmd_init_strat, NULL},
414 {CMD_UTIL_GET_INIT_STRATEGY, "Get initialization strategy" , NULL , cmd_init_strat},
415 {-1, "- unknown -" , NULL , NULL},
418 static const value_string responses_vs[] = {
419 {RESP_OK, "OK - no error"},
420 {RESP_UNKNOWN_ERR, "Unknown error"},
421 {RESP_UNKNOWN_CMD, "Unrecognised command"},
422 {RESP_UNSUPPORTED, "Unsupported command"},
423 {RESP_INVAL_CHAN, "Invalid channel specified"},
424 {RESP_INVAL_DST, "Invalid destination"},
425 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
426 {RESP_INVAL_MSG, "Invalid message"},
427 {RESP_INVAL_LEN, "Invalid length field"},
428 {RESP_TX_FAIL, "Transmit failed"},
429 {RESP_RX_FAIL, "Receive failed"},
430 {RESP_AUTH_FAIL, "Authorization failed"},
431 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
432 {RESP_TIMEOUT, "Command timed out"},
433 {RESP_UNAVAILABLE, "Unavailable"},
434 {RESP_BUF_FULL, "Buffer full"},
435 {RESP_NO_SUCH_JOB, "No such job"},
439 static const value_string filter_data_types[] = {
440 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
441 {FILTER_DATA_TYPE_HEADER, "data message header"},
442 {FILTER_DATA_TYPE_DATA, "data message data"},
443 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
444 {FILTER_EVENT_TYPE_HEADER, "event message header"},
445 {FILTER_EVENT_TYPE_DATA, "event message"},
449 static const value_string operators[] = {
450 {BIT_FIELD_CHECK, "Bit field check"},
451 {SVALUE_GT, "Greater than (signed)"},
452 {SVALUE_GE, "Greater than or equal to (signed)"},
453 {SVALUE_LT, "Less than (signed)"},
454 {SVALUE_LE, "Less than or equal to (signed)"},
455 {VALUE_EQ, "Equal to"},
456 {VALUE_NE, "Not equal to"},
457 {UVALUE_GT, "Greater than (unsigned)"},
458 {UVALUE_GE, "Greater than or equal to (unsigned)"},
459 {UVALUE_LT, "Less than (unsigned)"},
460 {UVALUE_LE, "Less than or equal to (unsigned)"},
461 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
462 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
463 {DIG_TRANSITION, "Digital, change of state"},
467 static const value_string modes[] = {
468 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
469 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
470 {FILTER_ON, "Filter on"},
474 static const value_string dmodes[] = {
475 {DEFAULT_FILTER_BLOCK, "Block"},
476 {DEFAULT_FILTER_PASS, "Pass"},
480 static const value_string filtacts[] = {
481 {DELETE_FILTER, "Delete"},
482 {ACTIVATE_FILTER, "Activate"},
483 {DEACTIVATE_FILTER, "Deactivate"},
487 static const value_string ioctls[] = {
488 {GINIT, "GINIT: Initialize"},
489 {GLOOPON, "GLOOPON: Loop on"},
490 {GLOOPOFF, "GLOOPOFF: Loop off"},
491 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
492 {GGETREG, "GGETREG: Get register"},
493 {GSETREG, "GSETREG: Set register"},
494 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
495 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
496 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
497 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
498 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
499 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
500 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
501 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
502 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
503 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
504 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
505 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
506 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
507 {GGETERRLEV, "GGETERRLEV: Get error level"},
508 {GSETERRLEV, "GSETERRLEV: Set error level"},
509 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
510 {GGETRAM, "GGETRAM: Read value from RAM"},
511 {GSETRAM, "GSETRAM: Write value to RAM"},
512 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
513 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
514 {GCANGETBC, "GCANGETBC: Read CAN bus configuration register"},
515 {GCANSETBC, "GCANSETBC: Write CAN bus configuration register"},
516 {GCANGETMODE, "GCANGETMODE"},
517 {GCANSETMODE, "GCANSETMODE"},
518 {GCANGETTRANS, "GCANGETTRANS"},
519 {GCANSETTRANS, "GCANSETTRANS"},
520 {GCANSENDERR, "GCANSENDERR"},
521 {GCANRGETOBJ, "GCANRGETOBJ"},
522 {GCANRSETSTDID, "GCANRSETSTDID"},
523 {GCANRSETEXTID, "GCANRSETEXTID"},
524 {GCANRSETDATA, "GCANRSETDATA"},
525 {GCANRENABLE, "GCANRENABLE"},
526 {GCANRDISABLE, "GCANRDISABLE"},
527 {GCANRGETMASKS, "GCANRGETMASKS"},
528 {GCANRSETMASKS, "GCANRSETMASKS"},
529 {GCANSWGETMODE, "GCANSWGETMODE"},
530 {GCANSWSETMODE, "GCANSWSETMODE"},
531 {GDLCGETFOURX, "GDLCGETFOURX"},
532 {GDLCSETFOURX, "GDLCSETFOURX"},
533 {GDLCGETLOAD, "GDLCGETLOAD"},
534 {GDLCSETLOAD, "GDLCSETLOAD"},
535 {GDLCSENDBREAK, "GDLCSENDBREAK"},
536 {GDLCABORTTX, "GDLCABORTTX"},
537 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
538 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
539 {GHONSLEEP, "GHONSLEEP"},
540 {GHONSILENCE, "GHONSILENCE"},
541 {GKWPSETPTIMES, "GKWPSETPTIMES"},
542 {GKWPSETWTIMES, "GKWPSETWTIMES"},
543 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
544 {GKWPGETBITTIME, "GKWPGETBITTIME"},
545 {GKWPSETBITTIME, "GKWPSETBITTIME"},
546 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
547 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
548 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
549 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
550 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
551 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
552 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
553 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
554 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
555 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
556 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
557 {GSCPGETBBR, "GSCPGETBBR"},
558 {GSCPSETBBR, "GSCPSETBBR"},
559 {GSCPGETID, "GSCPGETID"},
560 {GSCPSETID, "GSCPSETID"},
561 {GSCPADDFUNCID, "GSCPADDFUNCID"},
562 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
563 {GUBPGETBITRATE, "GUBPGETBITRATE"},
564 {GUBPSETBITRATE, "GUBPSETBITRATE"},
565 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
566 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
567 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
568 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
569 {GUBPGETRETRYDELAY, "GUBPGETRETRYDELAY"},
570 {GUBPSETRETRYDELAY, "GUBPSETRETRYDELAY"},
571 {GRESETHC08, "GRESETHC08: Reset the HC08 processor"},
572 {GTESTHC08COP, "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
573 {GSJAGETLISTEN, "GSJAGETLISTEN"},
574 {GSJASETLISTEN, "GSJASETLISTEN"},
575 {GSJAGETSELFTEST, "GSJAGETSELFTEST"},
576 {GSJASETSELFTEST, "GSJASETSELFTEST"},
577 {GSJAGETXMITONCE, "GSJAGETXMITONCE"},
578 {GSJASETXMITONCE, "GSJASETXMITONCE"},
579 {GSJAGETTRIGSTATE, "GSJAGETTRIGSTATE"},
580 {GSJASETTRIGCTRL, "GSJASETTRIGCTRL"},
581 {GSJAGETTRIGCTRL, "GSJAGETTRIGCTRL"},
582 {GSJAGETOUTSTATE, "GSJAGETOUTSTATE"},
583 {GSJASETOUTSTATE, "GSJASETOUTSTATE"},
584 {GSJAGETFILTER, "GSJAGETFILTER"},
585 {GSJASETFILTER, "GSJASETFILTER"},
586 {GSJAGETMASK, "GSJAGETMASK"},
587 {GSJASETMASK, "GSJASETMASK"},
588 {GSJAGETINTTERM, "GSJAGETINTTERM"},
589 {GSJASETINTTERM, "GSJASETINTTERM"},
590 {GSJAGETFTTRANS, "GSJAGETFTTRANS"},
591 {GSJASETFTTRANS, "GSJASETFTTRANS"},
592 {GSJAGETFTERROR, "GSJAGETFTERROR"},
593 {GLINGETBITRATE, "GLINGETBITRATE: Get the current bit rate"},
594 {GLINSETBITRATE, "GLINSETBITRATE: Set the bit rate"},
595 {GLINGETBRKSPACE, "GLINGETBRKSPACE"},
596 {GLINSETBRKSPACE, "GLINSETBRKSPACE"},
597 {GLINGETBRKMARK, "GLINGETBRKMARK"},
598 {GLINSETBRKMARK, "GLINSETBRKMARK"},
599 {GLINGETIDDELAY, "GLINGETIDDELAY"},
600 {GLINSETIDDELAY, "GLINSETIDDELAY"},
601 {GLINGETRESPDELAY, "GLINGETRESPDELAY"},
602 {GLINSETRESPDELAY, "GLINSETRESPDELAY"},
603 {GLINGETINTERBYTE, "GLINGETINTERBYTE"},
604 {GLINSETINTERBYTE, "GLINSETINTERBYTE"},
605 {GLINGETWAKEUPDELAY, "GLINGETWAKEUPDELAY"},
606 {GLINSETWAKEUPDELAY, "GLINSETWAKEUPDELAY"},
607 {GLINGETWAKEUPTIMEOUT, "GLINGETWAKEUPTIMEOUT"},
608 {GLINSETWAKEUPTIMEOUT, "GLINSETWAKEUPTIMEOUT"},
609 {GLINGETWUTIMOUT3BR, "GLINGETWUTIMOUT3BR"},
610 {GLINSETWUTIMOUT3BR, "GLINSETWUTIMOUT3BR"},
611 {GLINSENDWAKEUP, "GLINSENDWAKEUP"},
612 {GLINGETMODE, "GLINGETMODE"},
613 {GLINSETMODE, "GLINSETMODE"},
614 {GINPGETINP, "GINPGETINP: Read current digital inputs"},
615 {GINPGETLATCH, "GINPGETLATCH: Read latched digital inputs"},
616 {GINPCLRLATCH, "GINPCLRLATCH: Read and clear latched digital inputs"},
617 {GOUTGET, "GOUTGET: Read digital outputs"},
618 {GOUTSET, "GOUTSET: Write digital outputs"},
619 {GOUTSETBIT, "GOUTSETBIT: Set digital output bits"},
620 {GOUTCLEARBIT, "GOUTCLEARBIT"},
621 {GPWRGETWHICH, "GPWRGETWHICH"},
622 {GPWROFF, "GPWROFF"},
623 {GPWROFFRESET, "GPWROFFRESET"},
624 {GPWRRESET, "GPWRRESET"},
630 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
638 msglen = tvb_reported_length_remaining(tvb, offset);
639 cmd = tvb_get_guint8(tvb, offset);
640 hi = proto_tree_add_uint(pt, hf_gryphon_cmd, tvb, offset, 1, cmd);
641 PROTO_ITEM_SET_HIDDEN(hi);
645 for (i = 0; i < SIZEOF(cmds); i++) {
646 if (cmds[i].value == cmd)
649 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
650 cmd = (cmd & 0xFF) + SD_CARD * 256;
651 for (i = 0; i < SIZEOF(cmds); i++) {
652 if (cmds[i].value == cmd)
656 if (i >= SIZEOF(cmds))
657 i = SIZEOF(cmds) - 1;
659 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
663 if (cmds[i].cmd_fnct && msglen > 0) {
664 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d byte%s)",
665 msglen, msglen == 1 ? "" : "s");
666 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
667 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
673 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
676 unsigned int i, resp;
680 msglen = tvb_reported_length_remaining(tvb, offset);
681 cmd = tvb_get_guint8(tvb, offset);
685 for (i = 0; i < SIZEOF(cmds); i++) {
686 if (cmds[i].value == cmd)
689 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
690 cmd = (cmd & 0xFF) + SD_CARD * 256;
691 for (i = 0; i < SIZEOF(cmds); i++) {
692 if (cmds[i].value == cmd)
696 if (i >= SIZEOF(cmds))
697 i = SIZEOF(cmds) - 1;
698 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
702 resp = tvb_get_ntohl (tvb, offset);
703 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
704 val_to_str(resp, responses_vs, "Unknown (0x%08x)"));
708 if (cmds[i].rsp_fnct && msglen > 0) {
709 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d byte%s)",
710 msglen, msglen == 1 ? "" : "s");
711 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
712 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
718 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
720 proto_item *item, *item1;
721 proto_tree *tree, *tree1;
722 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
723 int hours, minutes, seconds, fraction;
724 unsigned long timestamp;
726 hdrsize = tvb_get_guint8(tvb, offset+0);
727 hdrbits = tvb_get_guint8(tvb, offset+1);
728 datasize = tvb_get_ntohs(tvb, offset+2);
729 extrasize = tvb_get_guint8(tvb, offset+4);
730 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
731 msgsize = hdrsize + datasize + extrasize + padding + 16;
733 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
734 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
735 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d byte%s, %d bits",
736 hdrsize, plurality(hdrsize, "", "s"), hdrbits);
737 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d byte%s",
738 datasize, plurality(datasize, "", "s"));
739 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d byte%s",
740 extrasize, plurality(extrasize, "", "s"));
741 mode = tvb_get_guint8(tvb, offset+5);
742 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
744 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
746 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
747 decode_boolean_bitfield(mode, 0x80, 8,
748 "Transmitted message", NULL));
751 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
752 decode_boolean_bitfield(mode, 0x40, 8,
753 "Received message", NULL));
756 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
757 decode_boolean_bitfield(mode, 0x20, 8,
758 "Local message", NULL));
761 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
762 decode_boolean_bitfield(mode, 0x10, 8,
763 "Remote message", NULL));
766 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
767 decode_boolean_bitfield(mode, 0x01, 8,
768 "Internal message", NULL));
771 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
772 tvb_get_guint8(tvb, offset+6));
773 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
774 tvb_get_guint8(tvb, offset+7));
775 timestamp = tvb_get_ntohl(tvb, offset+8);
776 hours = timestamp /(100000 * 60 *60);
777 minutes = (timestamp / (100000 * 60)) % 60;
778 seconds = (timestamp / 100000) % 60;
779 fraction = timestamp % 100000;
780 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
781 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
782 tvb_get_guint8(tvb, offset+12));
783 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
785 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
786 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
788 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
792 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
796 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
800 proto_tree_add_text(pt, tvb, offset, padding, "padding");
807 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
810 int hours, minutes, seconds, fraction, padding, length;
811 unsigned long timestamp;
814 msglen = tvb_reported_length_remaining(tvb, offset);
815 padding = 3 - (msglen + 3) % 4;
816 msgend = offset + msglen;
817 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
818 tvb_get_guint8(tvb, offset));
819 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
820 tvb_get_guint8(tvb, offset+1));
821 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
823 timestamp = tvb_get_ntohl(tvb, offset);
824 hours = timestamp /(100000 * 60 *60);
825 minutes = (timestamp / (100000 * 60)) % 60;
826 seconds = (timestamp / 100000) % 60;
827 fraction = timestamp % 100000;
828 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
830 if (offset < msgend) {
831 length = msgend - offset;
832 proto_tree_add_text (pt, tvb, offset, length, "Data (%d byte%s)",
833 length, length == 1 ? "" : "s");
837 proto_tree_add_text(pt, tvb, offset, padding, "padding");
844 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
849 unsigned char local_data[LENGTH+1];
851 msglen = tvb_reported_length_remaining(tvb, offset);
852 padding = 3 - (msglen + 3) % 4;
853 /*length =*/ tvb_get_nstringz0(tvb, offset, LENGTH, local_data);
854 proto_tree_add_text(pt, tvb, offset, msglen, "Data: %s", local_data);
857 proto_tree_add_text (pt, tvb, offset, padding, "padding");
864 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
868 if (tvb_get_guint8(tvb, offset) == 0)
869 ptr = "Always initialize";
871 ptr = "Initialize if not previously initialized";
872 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
873 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
879 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
881 guint8 event = tvb_get_guint8(tvb, offset);
884 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
886 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
887 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
893 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
898 static const char *mon_names[12] = {
913 ts = tvb_get_ntoh64(tvb, offset);
914 timestamp = (time_t) (ts / 100000);
915 tmp = localtime(×tamp);
918 proto_tree_add_text(pt, tvb, offset, 8,
919 "Date/Time: %s %d, %d %02d:%02d:%02d.%05u",
920 mon_names[tmp->tm_mon],
926 (guint) (ts % 100000));
928 proto_tree_add_text(pt, tvb, offset, 8,
929 "Date/Time: [Invalid]");
936 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
938 int flag = tvb_get_ntohl(tvb, offset);
942 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
943 + tvb_get_ntohs(tvb, offset+6);
945 g_strlcpy (mode, "Pass", 30);
947 g_strlcpy (mode, "Block", 30);
949 g_strlcat (mode, " all", 30);
950 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
951 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
954 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
955 offset += length * 2;
957 padding = 3 - (length * 2 + 3) % 4;
959 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
966 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
971 msglen = tvb_reported_length_remaining(tvb, offset);
972 ioctl = tvb_get_ntohl(tvb, offset);
973 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
974 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
978 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
985 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
990 int blocks, i, length;
992 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
993 tree = proto_item_add_subtree (item, ett_gryphon_flags);
994 flags = tvb_get_guint8(tvb, offset);
995 proto_tree_add_text(tree, tvb, offset, 1, "%s",
996 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
997 "Conforming messages are passed",
998 "Conforming messages are blocked"));
999 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1000 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1001 "The filter is active", "The filter is inactive"));
1003 blocks = tvb_get_guint8(tvb, offset);
1004 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1005 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
1007 for (i = 1; i <= blocks; i++) {
1008 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1009 length += 3 - (length + 3) % 4;
1010 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1011 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1012 offset = filter_block(tvb, offset, tree);
1018 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1020 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1021 tvb_get_guint8(tvb, offset));
1022 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1028 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1030 guint8 filter_handle;
1031 unsigned char action;
1033 filter_handle = tvb_get_guint8(tvb, offset);
1035 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1038 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1039 action = tvb_get_guint8(tvb, offset + 1);
1040 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
1041 val_to_str(action, filtacts, "Unknown (%u)"));
1042 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1048 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
1050 int handles = tvb_get_guint8(tvb, offset);
1053 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1054 for (i = 1; i <= handles; i++){
1055 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1056 tvb_get_guint8(tvb, offset+i));
1058 padding = 3 - (handles + 1 + 3) % 4;
1060 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1061 offset += 1+handles+padding;
1066 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1070 mode = tvb_get_guint8(tvb, offset);
1071 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1072 val_to_str(mode, dmodes, "Unknown (%u)"));
1073 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1079 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1083 mode = tvb_get_guint8(tvb, offset);
1084 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1085 val_to_str(mode, modes, "Unknown (%u)"));
1086 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1092 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
1099 msglen = tvb_reported_length_remaining(tvb, offset);
1101 while (msglen != 0) {
1102 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1103 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1104 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1105 tvb_get_guint8(tvb, offset));
1106 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1107 tvb_get_ephemeral_string(tvb, offset+1, 19));
1116 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1118 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1119 tvb_get_ephemeral_string(tvb, offset, 16));
1121 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1122 tvb_get_ephemeral_string(tvb, offset, 32));
1128 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1130 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1131 tvb_get_guint8(tvb, offset));
1132 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1133 tvb_get_guint8(tvb, offset+1));
1134 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1141 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1147 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1148 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1149 size = tvb_get_guint8(tvb, offset+8);
1150 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d byte%s",
1151 size, size == 1 ? "" : "s");
1152 number = tvb_get_guint8(tvb, offset+9);
1153 proto_tree_add_text(pt, tvb, offset+9, 1, "There %s %d preset speed%s",
1154 number == 1 ? "is" : "are", number, number == 1 ? "" : "s");
1156 for (index = 0; index < number; index++) {
1157 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1165 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1169 which = tvb_get_guint8(tvb, offset) ?
1170 "Sort into blocks of up to 16 messages" :
1171 "Do not sort messages";
1172 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1178 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1182 which = tvb_get_guint8(tvb, offset) ?
1183 "Optimize for latency (Nagle algorithm disabled)" :
1184 "Optimize for throughput (Nagle algorithm enabled)";
1185 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1191 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1193 proto_item *ti, *item;
1194 proto_tree *ft, *tree;
1199 static const value_string protocol_types[] = {
1200 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1201 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1202 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1203 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1204 {GCAN * 256 + G82527ISO11992, "CAN, 82527 ISO11992 subtype"},
1205 {GCAN * 256 + G82527_SINGLECHAN, "CAN, Fiber Optic 82527 subtype"},
1206 {GCAN * 256 + G82527SW_SINGLECHAN, "CAN, Fiber Optic 82527 single wire subtype"},
1207 {GCAN * 256 + G82527ISO11992_SINGLECHAN, "CAN, Fiber Optic ISO11992 subtype"},
1208 {GCAN * 256 + GSJA1000FT, "CAN, SJA1000 Fault Tolerant subtype"},
1209 {GCAN * 256 + GSJA1000C, "CAN, SJA1000 onboard subtype"},
1210 {GCAN * 256 + GSJA1000FT_FO, "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1211 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1212 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1213 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1214 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1215 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000/ISO 9141"},
1216 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1217 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1218 {GSCI * 256 + G16550SCI, "Chrysler SCI, UART subtype"},
1219 {GCCD * 256 + G16550CDP68HC68, "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1220 {GLIN * 256 + GDGLIN08, "LIN, DG HC08 subtype"},
1224 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1225 tvb_get_ephemeral_string(tvb, offset, 20));
1228 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1229 tvb_get_ephemeral_string(tvb, offset, 8));
1232 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1233 tvb_get_ephemeral_string(tvb, offset, 20));
1236 devices = tvb_get_guint8(tvb, offset);
1237 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1238 proto_tree_add_text(pt, tvb, offset+1, 11, "Name & version extension: %.11s",
1239 tvb_get_ephemeral_string(tvb, offset+1, 11));
1240 proto_tree_add_text(pt, tvb, offset+12, 4, "reserved");
1242 for (i = 1; i <= devices; i++) {
1243 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1244 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1245 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1246 tvb_get_ephemeral_string(tvb, offset, 20));
1249 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1250 tvb_get_ephemeral_string(tvb, offset, 8));
1253 proto_tree_add_text(ft, tvb, offset, 16, "Device security string: %.16s",
1254 tvb_get_ephemeral_string(tvb, offset, 16));
1257 x = tvb_get_ntohl (tvb, offset);
1259 item = proto_tree_add_text(ft, tvb, offset, 4, "Valid Header lengths");
1260 tree = proto_item_add_subtree (item, ett_gryphon_valid_headers);
1261 for (j = 0; ; j++) {
1263 proto_tree_add_text(tree, tvb, offset, 4, "%d byte%s", j,
1272 x = tvb_get_ntohs (tvb, offset);
1273 proto_tree_add_text(ft, tvb, offset, 2, "Maximum data length = %d byte%s",
1274 x, x == 1 ? "" : "s");
1277 x = tvb_get_ntohs (tvb, offset);
1278 proto_tree_add_text(ft, tvb, offset, 2, "Minimum data length = %d byte%s",
1279 x, x == 1 ? "" : "s");
1282 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1283 tvb_get_ephemeral_string(tvb, offset, 20));
1286 x = tvb_get_ntohs(tvb, offset);
1287 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1288 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1291 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1292 tvb_get_guint8(tvb, offset));
1295 proto_tree_add_text(ft, tvb, offset, 1, "Card slot number: %u",
1296 tvb_get_guint8(tvb, offset));
1299 x = tvb_get_ntohs (tvb, offset);
1300 proto_tree_add_text(ft, tvb, offset, 2, "Maximum extra data = %d byte%s",
1301 x, x == 1 ? "" : "s");
1304 x = tvb_get_ntohs (tvb, offset);
1305 proto_tree_add_text(ft, tvb, offset, 2, "Minimum extra data = %d byte%s",
1306 x, x == 1 ? "" : "s");
1314 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1317 proto_item *item, *item1;
1318 proto_tree *tree, *tree1;
1320 unsigned int i, x, length;
1321 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1323 msglen = tvb_reported_length_remaining(tvb, offset);
1324 x = tvb_get_ntohl(tvb, offset);
1325 if (x == 0xFFFFFFFF)
1326 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: \"infinite\"");
1328 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1331 x = tvb_get_ntohl(tvb, offset);
1332 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1333 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1334 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1335 decode_boolean_bitfield(x, 0x01, 32,
1336 "Critical scheduler", "Normal scheduler"));
1340 while (msglen > 0) {
1341 length = 16 + tvb_get_guint8(tvb, offset+16) +
1342 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1343 length += 3 - (length + 3) % 4;
1344 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1345 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1346 x = tvb_get_ntohl(tvb, offset);
1347 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1350 x = tvb_get_ntohl(tvb, offset);
1351 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1354 x = tvb_get_ntohl(tvb, offset);
1355 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1358 x = tvb_get_ntohs(tvb, offset);
1359 item1 = proto_tree_add_text(tree, tvb, offset, 2, "Flags");
1360 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
1361 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1362 decode_boolean_bitfield(x, 1, 16, "S", "Do not s"),
1363 "kip the last \"Transmit period\"");
1365 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1366 decode_boolean_bitfield(x, 2, 16, "S", "Do not s"),
1367 "kip the first \"Sleep\" value");
1369 x = tvb_get_guint8(tvb, offset+2);
1372 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1373 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1376 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1377 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1378 save_offset = offset;
1379 offset = decode_data(tvb, offset, tree1);
1380 msglen -= offset - save_offset;
1387 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 proto_tree_add_text(pt, tvb, offset, 1, "Message index: %d", x);
1405 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,
1468 "Send response(s) for each conforming message" },
1469 { FR_RESP_AFTER_PERIOD,
1470 "Send response(s) after the specified period expires following a conforming message" },
1471 { FR_IGNORE_DURING_PER,
1472 "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1477 static const value_string deact_on_event_vals[] = {
1478 { FR_DEACT_ON_EVENT,
1479 "Deactivate this response for a conforming message" },
1480 { FR_DELETE|FR_DEACT_ON_EVENT,
1481 "Delete this response for a conforming message" },
1486 static const value_string deact_after_per_vals[] = {
1487 { FR_DEACT_AFTER_PER,
1488 "Deactivate this response after the specified period following a conforming message" },
1489 { FR_DELETE|FR_DEACT_AFTER_PER,
1490 "Delete this response after the specified period following a conforming message" },
1496 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1501 int blocks, responses, old_handle, i, msglen, length;
1502 int action, actionType, actionValue;
1506 flags = tvb_get_guint8(tvb, offset);
1507 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1508 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1509 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1510 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1511 "The response is active", "The response is inactive"));
1513 blocks = tvb_get_guint8(tvb, offset);
1514 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1516 responses = tvb_get_guint8(tvb, offset);
1517 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1519 old_handle = tvb_get_guint8(tvb, offset);
1520 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1522 action = tvb_get_guint8(tvb, offset);
1523 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1524 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1525 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1526 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1527 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1528 actionValue = tvb_get_ntohs(tvb, offset+2);
1530 if (action & FR_PERIOD_MSGS) {
1535 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1536 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1537 "The period is in frames", "The period is in 0.01 seconds"));
1539 if (action & FR_DEACT_ON_EVENT) {
1540 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1541 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1542 deact_on_event_vals, "%s"));
1544 if (action & FR_DEACT_AFTER_PER) {
1545 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1546 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1547 deact_after_per_vals, "%s"));
1550 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1553 if (actionType == 1) {
1554 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1556 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1560 for (i = 1; i <= blocks; i++) {
1561 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1562 length += 3 - (length + 3) % 4;
1563 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1564 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1565 offset = filter_block(tvb, offset, tree);
1567 for (i = 1; i <= responses; i++) {
1568 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1569 length = msglen + 3 - (msglen + 3) % 4;
1570 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1571 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1572 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1573 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1580 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1582 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1583 tvb_get_guint8(tvb, offset));
1584 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1590 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1592 unsigned char action;
1593 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1596 resp_handle = tvb_get_guint8(tvb, offset);
1598 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1601 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %c", dest);
1603 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1604 action = tvb_get_guint8(tvb, offset+1);
1605 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1606 val_to_str(action, filtacts, "Unknown (%u)"));
1607 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1613 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1615 int handles = tvb_get_guint8(tvb, offset);
1618 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1619 for (i = 1; i <= handles; i++){
1620 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1621 tvb_get_guint8(tvb, offset+i));
1623 padding = 3 - (handles + 1 + 3) % 4;
1625 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1626 offset += 1+handles+padding;
1631 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1633 unsigned int id = tvb_get_ntohl(tvb, offset);
1635 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1641 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1643 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1644 tvb_get_ntohl(tvb, offset));
1646 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1647 tvb_get_ephemeral_string(tvb, offset, 32));
1649 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1650 tvb_get_ephemeral_string(tvb, offset, 80));
1656 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1662 flags = tvb_get_guint8(tvb, offset);
1663 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1664 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1665 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1666 decode_boolean_bitfield(flags, 0x01, 8,
1667 "The program is already present",
1668 "The program is not present"));
1669 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1670 tvb_get_guint8(tvb, offset+1));
1671 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1677 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1680 unsigned int length;
1682 msglen = tvb_reported_length_remaining(tvb, offset);
1683 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1684 tvb_get_ntohs(tvb, offset));
1685 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1686 tvb_get_guint8(tvb, offset+2));
1690 proto_tree_add_text(pt, tvb, offset, length, "Data (%u byte%s)",
1691 length, length == 1 ? "" : "s");
1693 length = 3 - (length + 3) % 4;
1695 proto_tree_add_text(pt, tvb, offset, length, "padding");
1702 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1704 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1705 tvb_get_ephemeral_string(tvb, offset, 32));
1711 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1713 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1714 tvb_get_guint8(tvb, offset));
1715 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1721 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1725 unsigned int i, count;
1727 count = tvb_get_guint8(tvb, offset);
1728 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1729 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1731 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1732 tvb_get_ntohs(tvb, offset));
1734 for (i = 1; i <= count; i++) {
1735 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1736 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1737 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1738 tvb_get_ephemeral_string(tvb, offset, 32));
1740 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1741 tvb_get_ephemeral_string(tvb, offset, 80));
1748 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1753 int hdr_stuff = offset;
1755 msglen = tvb_reported_length_remaining(tvb, offset);
1756 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1757 if (offset < msglen + hdr_stuff) {
1758 string = tvb_get_ephemeral_stringz(tvb, offset, &length);
1760 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1762 length = 3 - (length + 3) % 4;
1764 proto_tree_add_text(pt, tvb, offset, length, "padding");
1773 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1777 msglen = tvb_reported_length_remaining(tvb, offset);
1779 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1780 tvb_get_guint8(tvb, offset));
1781 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1788 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1792 unsigned int i, copies, length;
1794 copies = tvb_get_guint8(tvb, offset);
1795 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1796 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1799 for (i = 1; i <= copies; i++) {
1800 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1801 i, tvb_get_guint8(tvb, offset));
1805 length = 3 - (copies + 1 + 3) % 4;
1807 proto_tree_add_text(pt, tvb, offset, length, "padding");
1814 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1819 unsigned int i, size, padding, option, option_length, option_value;
1820 const char *string, *string1;
1822 msglen = tvb_reported_length_remaining(tvb, offset);
1823 proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1824 tvb_get_guint8(tvb, offset));
1825 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1828 for (i = 1; msglen > 0; i++) {
1829 option_length = tvb_get_guint8(tvb, offset+1);
1830 size = option_length + 2;
1831 padding = 3 - ((size + 3) %4);
1832 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1833 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1834 option = tvb_get_guint8(tvb, offset);
1835 switch (option_length) {
1837 option_value = tvb_get_guint8(tvb, offset+2);
1840 option_value = tvb_get_ntohs(tvb, offset+2);
1843 option_value = tvb_get_ntohl(tvb, offset+2);
1848 string = "unknown option";
1849 string1 = "unknown option data";
1852 string = "Type of data in the file";
1853 switch (option_value) {
1855 string1 = "Binary - Don't modify";
1858 string1 = "ASCII - Remove CR's";
1863 string = "Type of file";
1864 switch (option_value) {
1866 string1 = "Executable";
1874 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1875 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1877 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1878 offset += size + padding;
1879 msglen -= size + padding;
1885 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1890 msglen = tvb_reported_length_remaining(tvb, offset);
1891 if (tvb_get_guint8(tvb, offset) == 0)
1892 which = "First group of names";
1894 which = "Subsequent group of names";
1896 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1897 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1898 msglen-1, tvb_get_ephemeral_string(tvb, offset+1, msglen-1));
1904 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1909 msglen = tvb_reported_length_remaining(tvb, offset);
1910 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1911 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1912 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1918 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1920 int ids, id, remain, size, i, j, bytes;
1923 proto_tree *localTree;
1924 proto_item *localItem;
1925 const gchar *actions[] = {
1926 "Use 11 bit headers only",
1927 "Use 29 bit headers only",
1928 "Use both 11 & 29 bit headers",
1931 const gchar *xmit_opts[] = {
1932 "Pad messages with less than 8 data bytes with 0x00's",
1933 "Pad messages with less than 8 data bytes with 0xFF's",
1934 "Do not pad messages with less than 8 data bytes",
1937 const gchar *recv_opts[] = {
1938 "Do not verify the integrity of long received messages and do not send them to the client",
1939 "Verify the integrity of long received messages and send them to the client",
1940 "Verify the integrity of long received messages but do not send them to the client",
1943 const gchar *block_desc[] = {"USDT request", "USDT response", "UUDT response"};
1945 flags = tvb_get_guint8(tvb, offset);
1950 proto_tree_add_text(pt, tvb, offset, 1, "%segister with gusdt", desc);
1953 localItem = proto_tree_add_text(pt, tvb, offset, 1, "Action flags");
1954 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1955 proto_tree_add_text(localTree, tvb, offset, 1, "%s%s",
1956 decode_boolean_bitfield (flags, 1, 8,
1957 "R", "Unr"), "egister with gusdt");
1958 proto_tree_add_text(localTree, tvb, offset, 1, "%s = %s",
1959 decode_numeric_bitfield (flags, 6, 8, "%d"),
1960 actions[(flags >> 1) & 3]);
1962 flags = tvb_get_guint8(tvb, offset+1);
1963 localItem = proto_tree_add_text(pt, tvb, offset+1, 1, "Transmit options");
1964 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1965 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1966 decode_boolean_bitfield (flags, 1, 8,
1968 "cho long transmit messages back to the client");
1969 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s = %s",
1970 decode_numeric_bitfield (flags, 6, 8, "%d"),
1971 xmit_opts[(flags >> 1) & 3]);
1972 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1973 decode_boolean_bitfield (flags, 8, 8,
1975 "end a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted");
1977 flags = tvb_get_guint8(tvb, offset+2);
1978 localItem = proto_tree_add_text(pt, tvb, offset+2, 1, "Receive options");
1979 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1980 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s = %s",
1981 decode_numeric_bitfield (flags, 3, 8, "%d"),
1982 recv_opts[flags & 3]);
1983 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1984 decode_boolean_bitfield (flags, 4, 8,
1986 "end a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received");
1987 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1988 decode_boolean_bitfield (flags, 8, 8,
1990 "end a USDT_LASTFRAME event when the last frame of a multi-frame USDT message is received");
1992 if ((ids = tvb_get_guint8(tvb, offset+3))) {
1993 localItem = proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for %d ID%s",
1994 ids, ids == 1?"":"s");
1996 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
1998 id = tvb_get_ntohl (tvb, offset);
1999 proto_tree_add_text (localTree, tvb, offset, 4, "%04X", id);
2004 proto_tree_add_text(pt, tvb, offset+3, 1,
2005 "Using extended addressing for the single, internally defined, ID");
2008 for (i = 0; i < 2; i++) {
2009 bytes = tvb_reported_length_remaining (tvb, offset);
2012 localItem = proto_tree_add_text(pt, tvb, offset, 16, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
2013 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2014 size = tvb_get_ntohl (tvb, offset);
2016 proto_tree_add_text (localTree, tvb, offset, 16, "No IDs in the block");
2018 } else if (size == 1) {
2019 proto_tree_add_text (localTree, tvb, offset, 4, "1 ID in the block");
2021 for (j = 0; j < 3; j++){
2022 id = tvb_get_ntohl (tvb, offset);
2023 proto_tree_add_text (localTree, tvb, offset, 4,
2024 "%s ID: %04X", block_desc[j], id);
2028 proto_tree_add_text (localTree, tvb, offset, 4, "%d IDs in the block", size);
2030 for (j = 0; j < 3; j++){
2031 id = tvb_get_ntohl (tvb, offset);
2032 proto_tree_add_text (localTree, tvb, offset, 4,
2033 "%s IDs from %04X through %04X", block_desc[j], id, id+size-1);
2039 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2043 if ((remain = tvb_reported_length_remaining(tvb, offset))) {
2044 proto_tree_add_text(pt, tvb, offset, remain, "%d ignored byte%s",
2045 remain, remain == 1 ? "" : "s");
2053 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
2058 int msglen, mask, value;
2059 const char *decode[] = {"Input 1", "Input 2", "Input 3", "Pushbutton"};
2061 msglen = tvb_reported_length_remaining(tvb, offset);
2062 value = tvb_get_guint8(tvb, offset);
2064 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2065 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2066 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2068 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2073 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2082 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
2087 int msglen, mask, value;
2088 const char *decode[] = {"Output 1", "Output 2"};
2090 msglen = tvb_reported_length_remaining(tvb, offset);
2091 value = tvb_get_guint8(tvb, offset);
2093 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2094 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2095 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2097 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2102 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2111 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
2116 msglen = tvb_reported_length_remaining(tvb, offset);
2117 proto_tree_add_text(pt, tvb, offset, 4, "Reset Limit = %u messages",
2118 tvb_get_ntohl(tvb, offset));
2121 for (index = 1; msglen; index++, offset++, msglen--) {
2122 value = tvb_get_guint8(tvb, offset);
2125 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = %.2f seconds",
2128 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = infinite",
2136 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
2138 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
2139 tvb_get_guint8(tvb, offset));
2140 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2146 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2148 unsigned int type, operator;
2149 int length, padding;
2151 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
2152 tvb_get_ntohs(tvb, offset));
2153 length = tvb_get_ntohs(tvb, offset+2);
2154 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d byte%s long",
2155 length, length == 1 ? "" : "s");
2156 type = tvb_get_guint8(tvb, offset+4);
2157 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
2158 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
2160 operator = tvb_get_guint8(tvb, offset+5);
2161 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
2162 val_to_str(operator, operators, "Unknown (%u)"));
2163 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
2166 if (operator == BIT_FIELD_CHECK) {
2167 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
2168 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
2172 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
2173 tvb_get_guint8(tvb, offset));
2176 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
2177 tvb_get_ntohs(tvb, offset));
2180 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
2181 tvb_get_ntohl(tvb, offset));
2184 proto_tree_add_text(pt, tvb, offset, length, "Value");
2187 offset += length * 2;
2188 padding = 3 - (length * 2 + 3) % 4;
2190 proto_tree_add_text(pt, tvb, offset, padding, "padding");
2197 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
2203 x = tvb_get_ntohl(tvb, offset);
2204 y = tvb_get_ntohl(tvb, offset+4);
2208 g_snprintf (line, 50, "reserved");
2211 mode = "Average over time";
2214 g_snprintf (line, 50, "Averaging period: %d.%03d seconds", seconds, y);
2217 mode = "Average over frame count";
2218 g_snprintf (line, 50, "Averaging period: %d frames", y);
2221 mode = "- unknown -";
2222 g_snprintf (line, 50, "reserved");
2224 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
2226 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
2232 proto_register_gryphon(void)
2234 static hf_register_info hf[] = {
2236 { "Source", "gryphon.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2238 { &hf_gryphon_srcchan,
2239 { "Source channel", "gryphon.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2242 { "Destination", "gryphon.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2244 { &hf_gryphon_destchan,
2245 { "Destination channel", "gryphon.destchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2248 { "Frame type", "gryphon.type", FT_UINT8, BASE_DEC, NULL, 0x0,
2251 { "Command", "gryphon.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
2255 static gint *ett[] = {
2257 &ett_gryphon_header,
2259 &ett_gryphon_command_data,
2260 &ett_gryphon_response_data,
2261 &ett_gryphon_data_header,
2263 &ett_gryphon_data_body,
2264 &ett_gryphon_cmd_filter_block,
2265 &ett_gryphon_cmd_events_data,
2266 &ett_gryphon_cmd_config_device,
2267 &ett_gryphon_cmd_sched_data,
2268 &ett_gryphon_cmd_sched_cmd,
2269 &ett_gryphon_cmd_response_block,
2270 &ett_gryphon_pgm_list,
2271 &ett_gryphon_pgm_status,
2272 &ett_gryphon_pgm_options,
2273 &ett_gryphon_valid_headers,
2274 &ett_gryphon_usdt_data,
2275 &ett_gryphon_digital_data,
2277 module_t *gryphon_module;
2279 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
2282 proto_register_field_array(proto_gryphon, hf, array_length(hf));
2283 proto_register_subtree_array(ett, array_length(ett));
2285 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
2286 prefs_register_bool_preference(gryphon_module, "desegment",
2287 "Desegment all Gryphon messages spanning multiple TCP segments",
2288 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2289 &gryphon_desegment);
2293 proto_reg_handoff_gryphon(void)
2295 dissector_handle_t gryphon_handle;
2297 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2298 dissector_add_uint("tcp.port", 7000, gryphon_handle);