2 * Harman HiQnet protocol dissector for Wireshark
3 * By Raphael Doursenaud <rdoursenaud@free.fr>
4 * Copyright 2014 Raphael Doursenaud
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <epan/packet.h>
28 #include "packet-tcp.h"
32 * http://adn.harmanpro.com/site_elements/resources/487_1411413911/HiQnet_third-party_programmers_quick-start_guide_original.pdf
33 * http://hiqnet.harmanpro.com/content/misc/hiqnet%20third%20party%20programmers%20guide%20v2.pdf
36 #define HIQNET_PORT 3804
38 #define HIQNET_FLAGS_MASK 0x016f
40 #define HIQNET_REQACK_FLAG 0x0001
41 #define HIQNET_ACK_FLAG 0x0002
42 #define HIQNET_INFO_FLAG 0x0004
43 #define HIQNET_ERROR_FLAG 0x0008
44 #define HIQNET_GUARANTEED_FLAG 0x0020
45 #define HIQNET_MULTIPART_FLAG 0x0040
46 #define HIQNET_SESSION_NUMBER_FLAG 0x0100
48 #define HIQNET_SUBSCRIPTION_TYPE_MASK 0x07
50 #define HIQNET_SUBSCRIPTION_FLAGS_MASK 0x00000001
52 #define HIQNET_CATEGORIES_MASK 0x00004fff
54 #define HIQNET_APPLICATION_CAT 0x00000002
55 #define HIQNET_CONF_CAT 0x00000004
56 #define HIQNET_AUDIONET_CAT 0x00000008
57 #define HIQNET_CTRLNET_CAT 0x00000010
58 #define HIQNET_VENDNET_CAT 0x00000020
59 #define HIQNET_STARTUP_CAT 0x00000040
60 #define HIQNET_DSP_CAT 0x00000080
61 #define HIQNET_MISC_CAT 0x00000100
62 #define HIQNET_CTRLLOG_CAT 0x00000200
63 #define HIQNET_FOREIGNPROTO_CAT 0x00000400
64 #define HIQNET_DIGIO_CAT 0x00000800
65 #define HIQNET_CTRLSURF_CAT 0x00004000
67 /* Routing layer message IDs */
68 #define HIQNET_DISCOINFO_MSG 0x0000
69 #define HIQNET_RESERVED0_MSG 0x0001
70 #define HIQNET_GETNETINFO_MSG 0x0002
71 #define HIQNET_RESERVED1_MSG 0x0003
72 #define HIQNET_REQADDR_MSG 0x0004
73 #define HIQNET_ADDRUSED_MSG 0x0005
74 #define HIQNET_SETADDR_MSG 0x0006
75 #define HIQNET_GOODBYE_MSG 0x0007
76 #define HIQNET_HELLO_MSG 0x0008
78 /* Other message IDs */
79 #define HIQNET_MULTPARMSET_MSG 0x0100
80 #define HIQNET_MULTOBJPARMSET_MSG 0x0101
81 #define HIQNET_PARMSETPCT_MSG 0x0102
82 #define HIQNET_MULTPARMGET_MSG 0x0103
83 #define HIQNET_GETATTR_MSG 0x010d
84 #define HIQNET_SETATTR_MSG 0x010e /* Reverse engineered. Not part of the official spec. */
85 #define HIQNET_MULTPARMSUB_MSG 0x010f
86 #define HIQNET_PARMSUBPCT_MSG 0x0111
87 #define HIQNET_MULTPARMUNSUB_MSG 0x0112
88 #define HIQNET_PARMSUBALL_MSG 0x0113
89 #define HIQNET_PARMUNSUBALL_MSG 0x0114
90 #define HIQNET_SUBEVTLOGMSGS_MSG 0x0115
91 #define HIQNET_GETVDLIST_MSG 0x011a
92 #define HIQNET_STORE_MSG 0x0124
93 #define HIQNET_RECALL_MSG 0x0125
94 #define HIQNET_LOCATE_MSG 0x0129
95 #define HIQNET_UNSUBEVTLOGMSGS_MSG 0x012b
96 #define HIQNET_REQEVTLOG_MSG 0x012c
98 #define HIQNET_TCPIP_NET 1
99 #define HIQNET_RS232_NET 4
101 static const value_string device_attributes_names[] = {
103 { 1, "Name String" },
104 /* Device Manager attributes */
106 { 3, "Serial Number" },
107 { 4, "Software Version" },
111 static const value_string messageidnames[] = {
112 { HIQNET_DISCOINFO_MSG, "DiscoInfo" },
113 { HIQNET_RESERVED0_MSG, "Reserved" },
114 { HIQNET_GETNETINFO_MSG, "GetNetworkInfo" },
115 { HIQNET_RESERVED1_MSG, "Reserved" },
116 { HIQNET_REQADDR_MSG, "RequestAddress" },
117 { HIQNET_ADDRUSED_MSG, "AddressUsed" },
118 { HIQNET_SETADDR_MSG, "SetAddress" },
119 { HIQNET_GOODBYE_MSG, "Goodbye" },
120 { HIQNET_HELLO_MSG, "Hello" },
121 { HIQNET_MULTPARMSET_MSG, "MultiParamSet" },
122 { HIQNET_MULTOBJPARMSET_MSG, "MultiObjectParamSet" },
123 { HIQNET_PARMSETPCT_MSG, "ParamSetPercent" },
124 { HIQNET_MULTPARMGET_MSG, "MultiParamGet" },
125 { HIQNET_GETATTR_MSG, "GetAttributes" },
126 { HIQNET_MULTPARMSUB_MSG, "MultiParamSubscribe" },
127 { HIQNET_PARMSUBPCT_MSG, "ParamSubscribePercent" },
128 { HIQNET_SETATTR_MSG, "SetAttribute" }, /* Reverse engineered. Not part of the official spec. */
129 { HIQNET_MULTPARMUNSUB_MSG, "MultiParamUnsubscribe" },
130 { HIQNET_PARMSUBALL_MSG, "ParameterSubscribeAll" },
131 { HIQNET_PARMUNSUBALL_MSG, "ParameterUnSubscribeAll" },
132 { HIQNET_SUBEVTLOGMSGS_MSG, "Subscribe Event Log Messages" },
133 { HIQNET_GETVDLIST_MSG, "GetVDList" },
134 { HIQNET_STORE_MSG, "Store" },
135 { HIQNET_RECALL_MSG, "Recall" },
136 { HIQNET_LOCATE_MSG, "Locate" },
137 { HIQNET_UNSUBEVTLOGMSGS_MSG, "Unsubscribe Event Log Messages" },
138 { HIQNET_REQEVTLOG_MSG, "Request Event Log" },
143 static const value_string flagnames[] = {
144 { HIQNET_REQACK_FLAG, "Request Acknowledgement" },
145 { HIQNET_ACK_FLAG, "Acknowlegement" },
146 { HIQNET_INFO_FLAG, "Information" },
147 { HIQNET_ERROR_FLAG, "Error" },
148 { HIQNET_GUARANTEED_FLAG, "Guaranteed" },
149 { HIQNET_MULTIPART_FLAG, "Multi-part" },
150 { HIQNET_SESSION_NUMBER_FLAG, "Session Number" },
155 static const value_string datatypenames[] = {
171 static const value_string actionnames[] = {
173 { 1, "Subscriptions" },
181 static const value_string timenames[] = {
182 { 0x0000, "Turn off locate LEDs" },
183 { 0xffff, "Turn on locate LEDs" },
187 static const value_string eventcategorynames[] = {
189 { 1, "Application" },
190 { 2, "Configuration" },
191 { 3, "Audio Network" },
192 { 4, "Control Network" },
193 { 5, "Vendor Network" },
196 { 8, "Miscellaneous" },
197 { 9, "Control Logic" },
198 { 10, "Foreign Protocol" },
199 { 11, "Digital I/O" },
200 { 12, "Unassigned" },
201 { 13, "Unassigned" },
202 { 14, "Control Surface" },
203 { 15, "Unassigned" },
204 { 16, "Unassigned" },
205 { 17, "Unassigned" },
206 { 18, "Unassigned" },
207 { 19, "Unassigned" },
208 { 20, "Unassigned" },
209 { 21, "Unassigned" },
210 { 22, "Unassigned" },
211 { 23, "Unassigned" },
212 { 24, "Unassigned" },
213 { 25, "Unassigned" },
214 { 26, "Unassigned" },
215 { 27, "Unassigned" },
216 { 28, "Unassigned" },
217 { 29, "Unassigned" },
218 { 30, "Unassigned" },
219 { 31, "Unassigned" },
223 static const value_string eventidnames[] = {
224 { 0x0001, "Invalid Version" },
225 { 0x0002, "Invalid Length" },
226 { 0x0003, "Invalid Virtual Device" },
227 { 0x0004, "Invalid Object" },
228 { 0x0005, "Invalid Parameter" },
229 { 0x0006, "Invalid Message ID" },
230 { 0x0007, "Invalid Value" },
231 { 0x0008, "Resource Unavailable" },
232 { 0x0009, "Unsupported" },
233 { 0x000a, "Invalid Virtual Device Class" },
234 { 0x000b, "Invalid Object Class" },
235 { 0x000c, "Invalid Parameter Class" },
236 { 0x000d, "Invalid Attribute ID" },
237 { 0x000e, "Invalid DataType" },
238 { 0x000f, "Invalid Configuration" },
239 { 0x0010, "Flash Error" },
240 { 0x0011, "Not a Router" },
244 static const value_string prioritynames[] = {
247 { 2, "Information" },
251 static const value_string networknames[] = {
252 { HIQNET_TCPIP_NET, "TCP/IP" },
255 { HIQNET_RS232_NET, "RS232" },
259 static const value_string paritynames[] = {
268 static const value_string stopbitsnames[] = {
275 static const value_string flowcontrolnames[] = {
282 static const gint hiqnet_datasize_per_type[] = { 1, 1, 2, 2, 4, 4, 4, 8, -1, -1, 8, 8 };
284 static int proto_hiqnet = -1;
286 static int hf_hiqnet_version = -1;
288 static gint ett_hiqnet = -1;
289 static gint ett_hiqnet_flags = -1;
290 static gint ett_hiqnet_cats = -1;
292 static int hf_hiqnet_headerlen = -1;
293 static int hf_hiqnet_messagelen = -1;
294 static int hf_hiqnet_sourcedev = -1;
295 static int hf_hiqnet_sourceaddr = -1;
296 static int hf_hiqnet_destdev = -1;
297 static int hf_hiqnet_destaddr = -1;
298 static int hf_hiqnet_messageid = -1;
299 static int hf_hiqnet_flags = -1;
300 static int hf_hiqnet_reqack_flag = -1;
301 static int hf_hiqnet_ack_flag = -1;
302 static int hf_hiqnet_info_flag = -1;
303 static int hf_hiqnet_error_flag = -1;
304 static int hf_hiqnet_guaranteed_flag = -1;
305 static int hf_hiqnet_multipart_flag = -1;
306 static int hf_hiqnet_session_number_flag = -1;
307 static int hf_hiqnet_hopcnt = -1;
308 static int hf_hiqnet_seqnum = -1;
309 static int hf_hiqnet_errcode = -1;
310 static int hf_hiqnet_errstr = -1;
311 static int hf_hiqnet_startseqno = -1;
312 static int hf_hiqnet_rembytes = -1;
313 static int hf_hiqnet_sessnum = -1;
314 static int hf_hiqnet_cost = -1;
315 static int hf_hiqnet_sernumlen = -1;
316 static int hf_hiqnet_sernum = -1;
317 static int hf_hiqnet_maxmsgsize = -1;
318 static int hf_hiqnet_keepaliveperiod = -1;
319 static int hf_hiqnet_netid = -1;
320 static int hf_hiqnet_macaddr = -1;
321 static int hf_hiqnet_dhcp = -1;
322 static int hf_hiqnet_ipaddr = -1;
323 static int hf_hiqnet_subnetmsk = -1;
324 static int hf_hiqnet_gateway = -1;
325 static int hf_hiqnet_flagmask = -1;
326 static int hf_hiqnet_paramcount = -1;
327 static int hf_hiqnet_paramid = -1;
328 static int hf_hiqnet_datatype = -1;
329 static int hf_hiqnet_value = -1;
330 static int hf_hiqnet_vdobject = -1;
331 static int hf_hiqnet_subtype = -1;
332 static int hf_hiqnet_sensrate = -1;
333 static int hf_hiqnet_subflags = -1;
334 static int hf_hiqnet_subcount = -1;
335 static int hf_hiqnet_pubparmid = -1;
336 static int hf_hiqnet_subaddr = -1;
337 static int hf_hiqnet_subparmid = -1;
338 static int hf_hiqnet_reserved0 = -1;
339 static int hf_hiqnet_reserved1 = -1;
340 static int hf_hiqnet_attrcount = -1;
341 static int hf_hiqnet_attrid = -1;
342 static int hf_hiqnet_datalen = -1;
343 static int hf_hiqnet_string = -1;
344 static int hf_hiqnet_wrkgrppath = -1;
345 static int hf_hiqnet_numvds = -1;
346 static int hf_hiqnet_vdaddr = -1;
347 static int hf_hiqnet_vdclassid = -1;
348 static int hf_hiqnet_stract = -1;
349 static int hf_hiqnet_strnum = -1;
350 static int hf_hiqnet_scope = -1;
351 static int hf_hiqnet_recact = -1;
352 static int hf_hiqnet_recnum = -1;
353 static int hf_hiqnet_strlen = -1;
354 static int hf_hiqnet_time = -1;
355 static int hf_hiqnet_maxdatasize = -1;
356 static int hf_hiqnet_catfilter = -1;
357 static int hf_hiqnet_app_cat = -1;
358 static int hf_hiqnet_conf_cat = -1;
359 static int hf_hiqnet_audionet_cat = -1;
360 static int hf_hiqnet_ctrlnet_cat = -1;
361 static int hf_hiqnet_vendnet_cat = -1;
362 static int hf_hiqnet_startup_cat = -1;
363 static int hf_hiqnet_dsp_cat = -1;
364 static int hf_hiqnet_misc_cat = -1;
365 static int hf_hiqnet_ctrlog_cat = -1;
366 static int hf_hiqnet_foreignproto_cat = -1;
367 static int hf_hiqnet_digio_cat = -1;
368 static int hf_hiqnet_ctrlsurf_cat = -1;
369 static int hf_hiqnet_entrieslen = -1;
370 static int hf_hiqnet_category = -1;
371 static int hf_hiqnet_eventid = -1;
372 static int hf_hiqnet_priority = -1;
373 static int hf_hiqnet_eventseqnum = -1;
374 static int hf_hiqnet_eventtime = -1;
375 static int hf_hiqnet_eventdate = -1;
376 static int hf_hiqnet_eventinfo = -1;
377 static int hf_hiqnet_eventadddata = -1;
378 static int hf_hiqnet_objcount = -1;
379 static int hf_hiqnet_paramval = -1;
380 static int hf_hiqnet_ifacecount = -1;
381 static int hf_hiqnet_comid = -1;
382 static int hf_hiqnet_baudrate = -1;
383 static int hf_hiqnet_parity = -1;
384 static int hf_hiqnet_stopbits = -1;
385 static int hf_hiqnet_databits = -1;
386 static int hf_hiqnet_flowcontrol = -1;
387 static int hf_hiqnet_devaddr = -1;
388 static int hf_hiqnet_newdevaddr = -1;
390 static const int *hiqnet_flag_fields[] = {
391 &hf_hiqnet_reqack_flag,
393 &hf_hiqnet_info_flag,
394 &hf_hiqnet_error_flag,
395 &hf_hiqnet_guaranteed_flag,
396 &hf_hiqnet_multipart_flag,
397 &hf_hiqnet_session_number_flag,
401 static const int *hiqnet_cat_fields[] = {
404 &hf_hiqnet_audionet_cat,
405 &hf_hiqnet_ctrlnet_cat,
406 &hf_hiqnet_vendnet_cat,
407 &hf_hiqnet_startup_cat,
410 &hf_hiqnet_ctrlog_cat,
411 &hf_hiqnet_foreignproto_cat,
412 &hf_hiqnet_digio_cat,
413 &hf_hiqnet_ctrlsurf_cat,
417 void proto_register_hiqnet(void);
418 void proto_reg_handoff_hiqnet(void);
422 hiqnet_display_vdobjectaddr(proto_tree *hiqnet_tree, int hf_hiqnet, tvbuff_t *tvb, gint offset) {
423 proto_tree_add_bytes_format_value(hiqnet_tree, hf_hiqnet, tvb, offset, 4, NULL,
425 tvb_get_guint8(tvb, offset), /* Virtual Device address */
426 tvb_get_guint8(tvb, offset + 1), /* Object address part 1 */
427 tvb_get_guint8(tvb, offset + 2), /* Object address part 2 */
428 tvb_get_guint8(tvb, offset + 3)); /* Object address part 3 */
433 hiqnet_display_tcpipnetinfo(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
434 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_macaddr, tvb, offset, 6, ENC_NA);
436 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_dhcp, tvb, offset, 1, ENC_BIG_ENDIAN);
438 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
440 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subnetmsk, tvb, offset, 4, ENC_BIG_ENDIAN);
442 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
449 hiqnet_display_rs232netinfo(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
450 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_comid, tvb, offset, 1, ENC_BIG_ENDIAN);
452 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_baudrate, tvb, offset, 4, ENC_BIG_ENDIAN);
454 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_parity, tvb, offset, 1, ENC_BIG_ENDIAN);
456 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_stopbits, tvb, offset, 1, ENC_BIG_ENDIAN);
458 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_databits, tvb, offset, 1, ENC_BIG_ENDIAN);
460 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_flowcontrol, tvb, offset, 1, ENC_BIG_ENDIAN);
467 hiqnet_display_netinfo(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
469 netid = tvb_get_guint8(tvb, offset);
470 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_netid, tvb, offset, 1, ENC_BIG_ENDIAN);
472 if (netid == HIQNET_TCPIP_NET) {
473 offset = hiqnet_display_tcpipnetinfo(hiqnet_payload_tree, tvb, offset);
475 if (netid == HIQNET_RS232_NET) {
476 offset = hiqnet_display_rs232netinfo(hiqnet_payload_tree, tvb, offset);
483 hiqnet_display_sernum(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
485 str_len = tvb_get_ntohs(tvb, offset);
486 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_sernumlen, tvb, offset, 2, ENC_BIG_ENDIAN);
488 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_sernum, tvb, offset, str_len, ENC_NA);
495 hiqnet_display_paramsub(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
496 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_pubparmid, tvb, offset, 2, ENC_BIG_ENDIAN);
498 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
500 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subaddr, tvb, offset, 6, ENC_NA);
502 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subparmid, tvb, offset, 2, ENC_BIG_ENDIAN);
504 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_reserved0, tvb, offset, 1, ENC_NA);
506 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_reserved1, tvb, offset, 2, ENC_NA);
508 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_sensrate, tvb, offset, 2, ENC_BIG_ENDIAN);
514 /* TODO: decode flags for attributes and parameters */
516 hiqnet_display_data(proto_tree *hiqnet_payload_tree, tvbuff_t *tvb, gint offset) {
520 datatype = tvb_get_guint8(tvb, offset);
521 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_datatype, tvb, offset, 1, ENC_BIG_ENDIAN);
523 datalen = hiqnet_datasize_per_type[datatype];
524 if (datalen < 0) { /* This is a string or a block */
525 datalen = tvb_get_ntohs(tvb, offset);
526 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_datalen, tvb, offset, 2, ENC_BIG_ENDIAN);
529 if (datatype == 9) { /* This is a string */
530 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_string, tvb, offset, datalen, ENC_UCS_2);
532 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_value, tvb, offset, datalen, ENC_NA);
539 dissect_hiqnet_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
541 guint8 headerlen = 0;
542 guint32 messagelen = 0;
544 guint8 srcvdaddr = 0;
545 guint8 srcob0addr = 0;
546 guint8 srcob1addr = 0;
547 guint8 srcob2addr = 0;
549 guint8 dstvdaddr = 0;
550 guint8 dstob0addr = 0;
551 guint8 dstob1addr = 0;
552 guint8 dstob2addr = 0;
553 guint16 messageid = 0;
555 guint16 paramcount = 0;
556 guint16 subcount = 0;
557 guint16 attrcount = 0;
559 guint16 vdscount = 0;
560 guint16 eventscount = 0;
561 guint16 objcount = 0;
562 guint16 ifacecount = 0;
564 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HiQnet");
565 /* Clear out stuff in the info column */
566 col_clear(pinfo->cinfo,COL_INFO);
568 srcdev = tvb_get_ntohs(tvb, 6);
569 srcvdaddr = tvb_get_guint8(tvb, 8);
570 srcob0addr = tvb_get_guint8(tvb, 9);
571 srcob1addr = tvb_get_guint8(tvb, 10);
572 srcob2addr = tvb_get_guint8(tvb, 11);
573 dstdev = tvb_get_ntohs(tvb, 12);
574 dstvdaddr = tvb_get_guint8(tvb, 14);
575 dstob0addr = tvb_get_guint8(tvb, 15);
576 dstob1addr = tvb_get_guint8(tvb, 16);
577 dstob2addr = tvb_get_guint8(tvb, 17);
578 messageid = tvb_get_ntohs(tvb, 18);
579 col_add_fstr(pinfo->cinfo, COL_INFO, "Msg: %s, Src: %u.%u.%u.%u.%u, Dst: %u.%u.%u.%u.%u",
580 val_to_str(messageid, messageidnames, "Unknown (0x%04x)"),
581 srcdev, srcvdaddr, srcob0addr, srcob1addr, srcob2addr,
582 dstdev, dstvdaddr, dstob0addr, dstob1addr, dstob2addr);
584 if (tree) { /* we are being asked for details */
585 proto_item *ti = NULL;
586 proto_item *item = NULL;
587 proto_tree *hiqnet_tree = NULL;
588 proto_tree *hiqnet_header_tree = NULL;
589 proto_tree *hiqnet_session_tree = NULL;
590 proto_tree *hiqnet_error_tree = NULL;
591 proto_tree *hiqnet_multipart_tree = NULL;
592 proto_tree *hiqnet_payload_tree = NULL;
593 proto_tree *hiqnet_parameter_tree = NULL;
594 proto_tree *hiqnet_attribute_tree = NULL;
595 proto_tree *hiqnet_vds_tree = NULL;
596 proto_tree *hiqnet_event_tree = NULL;
597 proto_tree *hiqnet_subscription_tree = NULL;
598 proto_tree *hiqnet_object_tree = NULL;
599 proto_tree *hiqnet_ifaces_tree = NULL;
602 messagelen = tvb_get_ntohl(tvb, 2);
603 ti = proto_tree_add_item(tree, proto_hiqnet, tvb, 0, messagelen, ENC_NA);
604 proto_item_append_text(ti, ", Msg: %s",
605 val_to_str(messageid, messageidnames, "Unknown (0x%04x)"));
606 proto_item_append_text(ti, ", Src %u.%u.%u.%u.%u",
607 srcdev, srcvdaddr, srcob0addr, srcob1addr, srcob2addr);
608 proto_item_append_text(ti, ", Dst: %u.%u.%u.%u.%u",
609 dstdev, dstvdaddr, dstob0addr, dstob1addr, dstob2addr);
610 hiqnet_tree = proto_item_add_subtree(ti, ett_hiqnet);
613 headerlen = tvb_get_guint8(tvb, 1);
614 hiqnet_header_tree = proto_tree_add_subtree(hiqnet_tree, tvb, 0, headerlen, ett_hiqnet, NULL, "Header");
616 /* Standard header */
617 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_version, tvb, offset, 1, ENC_BIG_ENDIAN);
619 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_headerlen, tvb, offset, 1, ENC_BIG_ENDIAN);
621 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_messagelen, tvb, offset, 4, ENC_BIG_ENDIAN);
623 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_sourcedev, tvb, offset, 2, ENC_BIG_ENDIAN);
624 item = proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
625 PROTO_ITEM_SET_HIDDEN(item);
627 hiqnet_display_vdobjectaddr(hiqnet_header_tree, hf_hiqnet_sourceaddr, tvb, offset);
629 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_destdev, tvb, offset, 2, ENC_BIG_ENDIAN);
630 item = proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
631 PROTO_ITEM_SET_HIDDEN(item);
633 hiqnet_display_vdobjectaddr(hiqnet_header_tree, hf_hiqnet_destaddr, tvb, offset);
635 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_messageid, tvb, offset, 2, ENC_BIG_ENDIAN);
637 flags = tvb_get_ntohs(tvb, offset);
638 proto_tree_add_bitmask(hiqnet_header_tree, tvb, offset, hf_hiqnet_flags,
639 ett_hiqnet_flags, hiqnet_flag_fields, ENC_BIG_ENDIAN);
641 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_hopcnt, tvb, offset, 1, ENC_BIG_ENDIAN);
643 proto_tree_add_item(hiqnet_header_tree, hf_hiqnet_seqnum, tvb, offset, 2, ENC_BIG_ENDIAN);
646 /* Optional headers */
647 if (flags & HIQNET_ERROR_FLAG) {
648 /* TODO: mark the erroneous frame */
649 hiqnet_error_tree = proto_tree_add_subtree(hiqnet_header_tree, tvb, offset, 2, ett_hiqnet, NULL, "Error");
650 proto_tree_add_item(hiqnet_error_tree, hf_hiqnet_errcode, tvb, offset, 1, ENC_BIG_ENDIAN);
652 proto_tree_add_item(hiqnet_error_tree, hf_hiqnet_errstr, tvb, offset, headerlen - offset, ENC_UCS_2);
654 if (flags & HIQNET_MULTIPART_FLAG) {
655 /* TODO: rebuild the full message */
656 hiqnet_multipart_tree = proto_tree_add_subtree(hiqnet_header_tree, tvb, offset, 2, ett_hiqnet, NULL, "Multi-part");
657 proto_tree_add_item(hiqnet_multipart_tree, hf_hiqnet_startseqno, tvb, offset, 1, ENC_BIG_ENDIAN);
659 proto_tree_add_item(hiqnet_multipart_tree, hf_hiqnet_rembytes, tvb, offset, 4, ENC_BIG_ENDIAN);
662 if (flags & HIQNET_SESSION_NUMBER_FLAG) {
663 hiqnet_session_tree = proto_tree_add_subtree(hiqnet_header_tree, tvb, offset, 2, ett_hiqnet, NULL, "Session");
664 proto_tree_add_item(hiqnet_session_tree, hf_hiqnet_sessnum, tvb, offset, 2, ENC_BIG_ENDIAN);
668 offset = headerlen; /* Make sure we are at the payload start */
669 hiqnet_payload_tree = proto_tree_add_subtree(
670 hiqnet_tree, tvb, offset, messagelen - headerlen, ett_hiqnet, NULL, "Payload");
672 case HIQNET_DISCOINFO_MSG :
673 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
675 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_cost, tvb, offset, 1, ENC_BIG_ENDIAN);
677 offset = hiqnet_display_sernum(hiqnet_payload_tree, tvb, offset);
678 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_maxmsgsize, tvb, offset, 4, ENC_BIG_ENDIAN);
680 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_keepaliveperiod, tvb, offset, 2, ENC_BIG_ENDIAN);
682 hiqnet_display_netinfo(hiqnet_payload_tree, tvb, offset);
684 case HIQNET_HELLO_MSG :
685 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_sessnum, tvb, offset, 2, ENC_BIG_ENDIAN);
687 proto_tree_add_bitmask(hiqnet_payload_tree, tvb, offset, hf_hiqnet_flagmask,
688 ett_hiqnet_flags, hiqnet_flag_fields, ENC_BIG_ENDIAN);
690 case HIQNET_MULTPARMGET_MSG :
691 paramcount = tvb_get_ntohs(tvb, offset);
692 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_paramcount, tvb, offset, 2, ENC_BIG_ENDIAN);
694 while (paramcount > 0) {
695 hiqnet_parameter_tree = proto_tree_add_subtree(
696 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Parameter");
697 proto_tree_add_item(hiqnet_parameter_tree, hf_hiqnet_paramid, tvb, offset, 2, ENC_BIG_ENDIAN);
699 if (flags & HIQNET_INFO_FLAG) { /* This is not a request */
700 offset = hiqnet_display_data(hiqnet_parameter_tree, tvb, offset);
705 case HIQNET_MULTPARMSET_MSG :
706 paramcount = tvb_get_ntohs(tvb, offset);
707 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_paramcount, tvb, offset, 2, ENC_BIG_ENDIAN);
709 while (paramcount > 0) {
710 hiqnet_parameter_tree = proto_tree_add_subtree(
711 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Parameter");
712 proto_tree_add_item(hiqnet_parameter_tree, hf_hiqnet_paramid, tvb, offset, 2, ENC_BIG_ENDIAN);
714 offset = hiqnet_display_data(hiqnet_parameter_tree, tvb, offset);
718 case HIQNET_PARMSUBALL_MSG :
719 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
721 hiqnet_display_vdobjectaddr(hiqnet_payload_tree, hf_hiqnet_vdobject, tvb, offset);
723 /* TODO: can be decoded in two ways (old and new) */
724 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
726 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_sensrate, tvb, offset, 2, ENC_BIG_ENDIAN);
728 /* TODO: decode and display */
729 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subflags, tvb, offset, 2, ENC_BIG_ENDIAN);
731 case HIQNET_PARMUNSUBALL_MSG : /* Reverse engineered. Not part of the official spec. */
732 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
734 hiqnet_display_vdobjectaddr(hiqnet_payload_tree, hf_hiqnet_vdobject, tvb, offset);
736 /* TODO: can be decoded in two ways (old and new) */
737 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
739 case HIQNET_MULTPARMSUB_MSG :
740 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
741 subcount = tvb_get_ntohs(tvb, offset);
742 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subcount, tvb, offset, 2, ENC_BIG_ENDIAN);
744 while (subcount > 0) {
745 hiqnet_subscription_tree = proto_tree_add_subtree(
746 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Subscription");
747 offset = hiqnet_display_paramsub(hiqnet_subscription_tree, tvb, offset);
751 case HIQNET_GOODBYE_MSG :
752 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
754 case HIQNET_GETATTR_MSG :
755 attrcount = tvb_get_ntohs(tvb, offset);
756 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_attrcount, tvb, offset, 2, ENC_BIG_ENDIAN);
758 if (flags & HIQNET_INFO_FLAG) { /* This not a request */
759 while (attrcount > 0) {
760 hiqnet_attribute_tree = proto_tree_add_subtree(
761 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Attribute");
762 proto_tree_add_item(hiqnet_attribute_tree, hf_hiqnet_attrid, tvb, offset, 2, ENC_BIG_ENDIAN);
764 offset = hiqnet_display_data(hiqnet_attribute_tree, tvb, offset);
767 } else { /* This may be a request */
768 while (attrcount > 0) {
769 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_attrid, tvb, offset, 2, ENC_BIG_ENDIAN);
775 case HIQNET_GETVDLIST_MSG :
776 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
777 str_len = tvb_get_ntohs(tvb, offset);
778 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_strlen, tvb, offset, 2, ENC_BIG_ENDIAN);
780 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_wrkgrppath, tvb, offset, str_len, ENC_UCS_2);
782 if (flags & HIQNET_INFO_FLAG) { /* This is not a request */
783 vdscount = tvb_get_ntohs(tvb, offset);
784 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_numvds, tvb, offset, 2, ENC_BIG_ENDIAN);
786 while (vdscount > 0) {
787 hiqnet_vds_tree = proto_tree_add_subtree(
788 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Virtual Devices");
789 proto_tree_add_item(hiqnet_vds_tree, hf_hiqnet_vdaddr, tvb, offset, 1, ENC_BIG_ENDIAN);
791 proto_tree_add_item(hiqnet_vds_tree, hf_hiqnet_vdclassid, tvb, offset, 2, ENC_BIG_ENDIAN);
797 case HIQNET_STORE_MSG :
798 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
799 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_stract, tvb, offset, 1, ENC_BIG_ENDIAN);
801 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_strnum, tvb, offset, 2, ENC_BIG_ENDIAN);
803 str_len = tvb_get_ntohs(tvb, offset);
804 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_strlen, tvb, offset, 2, ENC_BIG_ENDIAN);
806 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_wrkgrppath, tvb, offset, str_len, ENC_UCS_2);
808 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
810 case HIQNET_RECALL_MSG :
811 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_recact, tvb, offset, 1, ENC_BIG_ENDIAN);
813 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_recnum, tvb, offset, 2, ENC_BIG_ENDIAN);
815 str_len = tvb_get_ntohs(tvb, offset);
816 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_strlen, tvb, offset, 2, ENC_BIG_ENDIAN);
818 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_wrkgrppath, tvb, offset, str_len, ENC_UCS_2);
820 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
822 case HIQNET_LOCATE_MSG :
823 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_time, tvb, offset, 2, ENC_BIG_ENDIAN);
825 hiqnet_display_sernum(hiqnet_payload_tree, tvb, offset);
827 case HIQNET_SUBEVTLOGMSGS_MSG :
828 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_maxdatasize, tvb, offset, 2, ENC_BIG_ENDIAN);
830 proto_tree_add_bitmask(hiqnet_payload_tree, tvb, offset, hf_hiqnet_catfilter,
831 ett_hiqnet_cats, hiqnet_cat_fields, ENC_BIG_ENDIAN);
833 case HIQNET_UNSUBEVTLOGMSGS_MSG :
834 proto_tree_add_bitmask(hiqnet_payload_tree, tvb, offset, hf_hiqnet_catfilter,
835 ett_hiqnet_cats, hiqnet_cat_fields, ENC_BIG_ENDIAN);
837 case HIQNET_REQEVTLOG_MSG :
838 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
839 if (flags & HIQNET_INFO_FLAG) { /* This is not a request */
840 eventscount = tvb_get_ntohs(tvb, offset);
841 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_entrieslen, tvb, offset, 2, ENC_BIG_ENDIAN);
843 while (eventscount > 0) {
844 hiqnet_event_tree = proto_tree_add_subtree(
845 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Event");
847 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_category, tvb, offset, 2, ENC_BIG_ENDIAN);
850 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_eventid, tvb, offset, 2, ENC_BIG_ENDIAN);
852 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
854 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_eventseqnum, tvb, offset, 4, ENC_BIG_ENDIAN);
856 str_len = tvb_get_ntohs(tvb, offset);
857 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_eventtime, tvb, offset, str_len, ENC_UCS_2);
859 str_len = tvb_get_ntohs(tvb, offset);
860 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_eventdate, tvb, offset, str_len, ENC_UCS_2);
862 str_len = tvb_get_ntohs(tvb, offset);
863 proto_tree_add_item(hiqnet_event_tree, hf_hiqnet_eventinfo, tvb, offset, str_len, ENC_UCS_2);
865 str_len = tvb_get_ntohs(tvb, offset);
867 hiqnet_event_tree, hf_hiqnet_eventadddata, tvb, offset, str_len, ENC_NA);
873 case HIQNET_MULTPARMUNSUB_MSG :
874 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
875 subcount = tvb_get_ntohs(tvb, offset);
876 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subcount, tvb, offset, 2, ENC_BIG_ENDIAN);
878 while (subcount > 0) {
879 hiqnet_subscription_tree = proto_tree_add_subtree(
880 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Subscription");
881 proto_tree_add_item(hiqnet_subscription_tree, hf_hiqnet_pubparmid, tvb, offset, 2, ENC_BIG_ENDIAN);
883 proto_tree_add_item(hiqnet_subscription_tree, hf_hiqnet_subparmid, tvb, offset, 2, ENC_BIG_ENDIAN);
888 case HIQNET_MULTOBJPARMSET_MSG :
889 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
890 objcount = tvb_get_ntohs(tvb, offset);
891 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_objcount, tvb, offset, 2, ENC_BIG_ENDIAN);
893 while (objcount > 0) {
894 hiqnet_object_tree = proto_tree_add_subtree(
895 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Object");
896 hiqnet_display_vdobjectaddr(hiqnet_header_tree, hf_hiqnet_vdobject, tvb, offset);
898 paramcount = tvb_get_ntohs(tvb, offset);
899 proto_tree_add_item(hiqnet_object_tree, hf_hiqnet_paramcount, tvb, offset, 2, ENC_BIG_ENDIAN);
901 while (paramcount > 0) {
902 hiqnet_parameter_tree = proto_tree_add_subtree(
903 hiqnet_object_tree, tvb, offset, -1, ett_hiqnet, NULL, "Parameter");
904 proto_tree_add_item(hiqnet_parameter_tree, hf_hiqnet_paramid, tvb, offset, 2, ENC_BIG_ENDIAN);
906 offset = hiqnet_display_data(hiqnet_parameter_tree, tvb, offset);
912 case HIQNET_PARMSETPCT_MSG :
913 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
914 paramcount = tvb_get_ntohs(tvb, offset);
915 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_paramcount, tvb, offset, 2, ENC_BIG_ENDIAN);
917 while (paramcount > 0) {
918 hiqnet_parameter_tree = proto_tree_add_subtree(
919 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Parameter");
920 proto_tree_add_item(hiqnet_parameter_tree, hf_hiqnet_paramid, tvb, offset, 2, ENC_BIG_ENDIAN);
922 /* TODO: docode paramval is in percentage represented as a 1.15 signed fixed point format */
923 proto_tree_add_item(hiqnet_parameter_tree, hf_hiqnet_paramval, tvb, offset, 2, ENC_BIG_ENDIAN);
928 case HIQNET_PARMSUBPCT_MSG :
929 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
930 subcount = tvb_get_ntohs(tvb, offset);
931 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_subcount, tvb, offset, 2, ENC_BIG_ENDIAN);
933 while (subcount > 0) {
934 hiqnet_subscription_tree = proto_tree_add_subtree(
935 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Subscription");
936 offset = hiqnet_display_paramsub(hiqnet_subscription_tree, tvb, offset);
940 case HIQNET_GETNETINFO_MSG :
941 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
942 offset = hiqnet_display_sernum(hiqnet_payload_tree, tvb, offset);
943 if (flags & HIQNET_INFO_FLAG) { /* This is not a request */
944 ifacecount = tvb_get_ntohs(tvb, offset);
945 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_ifacecount, tvb, offset, 2, ENC_BIG_ENDIAN);
947 while (ifacecount > 0) {
948 hiqnet_ifaces_tree = proto_tree_add_subtree(
949 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Interface");
950 proto_tree_add_item(hiqnet_ifaces_tree, hf_hiqnet_maxmsgsize, tvb, offset, 4, ENC_BIG_ENDIAN);
952 offset = hiqnet_display_netinfo(hiqnet_ifaces_tree, tvb, offset);
957 case HIQNET_REQADDR_MSG :
958 /* FIXME: Not tested, straight from the spec, never occurred with the devices I own */
959 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_devaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
961 case HIQNET_SETADDR_MSG :
962 offset = hiqnet_display_sernum(hiqnet_payload_tree, tvb, offset);
963 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_newdevaddr, tvb, offset, 2, ENC_BIG_ENDIAN);
965 hiqnet_display_netinfo(hiqnet_payload_tree, tvb, offset);
967 case HIQNET_SETATTR_MSG : /* Reverse engineered. Not part of the official spec. */
968 attrcount = tvb_get_ntohs(tvb, offset);
969 proto_tree_add_item(hiqnet_payload_tree, hf_hiqnet_attrcount, tvb, offset, 2, ENC_BIG_ENDIAN);
971 while (attrcount > 0) {
972 hiqnet_attribute_tree = proto_tree_add_subtree(
973 hiqnet_payload_tree, tvb, offset, -1, ett_hiqnet, NULL, "Attribute");
974 proto_tree_add_item(hiqnet_attribute_tree, hf_hiqnet_attrid, tvb, offset, 2, ENC_BIG_ENDIAN);
976 offset = hiqnet_display_data(hiqnet_attribute_tree, tvb, offset);
980 /* FIXME: Messages unknown, assumed without payload */
981 case HIQNET_RESERVED0_MSG:
982 case HIQNET_RESERVED1_MSG:
983 /* Message without payload */
984 case HIQNET_ADDRUSED_MSG:
986 default : /* Unknown message or malformed packet */
987 /* TODO: display something useful? */
991 return tvb_reported_length(tvb);
996 get_hiqnet_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
998 /* length is at offset + 2 */
999 return tvb_get_ntohl(tvb, offset + 2);
1002 /* Fixme: For multiple hiqnet PDUS in a single TCP or UDP packet,
1003 the INFO column shows the information only for the last PDU */
1006 dissect_hiqnet_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1008 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 6,
1009 get_hiqnet_pdu_len, dissect_hiqnet_pdu, data);
1010 return tvb_captured_length(tvb);
1014 dissect_hiqnet_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1020 guint captured_length;
1022 /* loop on (possibly multiple) hiqnet PDUs in UDP payload */
1023 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1024 plen = get_hiqnet_pdu_len(pinfo, tvb, offset);
1025 captured_length = tvb_captured_length_remaining(tvb, offset);
1027 if (captured_length > plen)
1028 captured_length = plen;
1029 next_tvb = tvb_new_subset(tvb, offset, captured_length, plen);
1031 dissect_hiqnet_pdu(next_tvb, pinfo, tree, data);
1034 * Step to the next PDU.
1035 * Make sure we don't overflow.
1037 offset_before = offset;
1039 if (offset <= offset_before)
1042 return tvb_captured_length(tvb);
1046 proto_register_hiqnet(void)
1048 static hf_register_info hf[] = {
1049 { &hf_hiqnet_version,
1050 { "Version", "hiqnet.version",
1055 { &hf_hiqnet_headerlen,
1056 { "Header length", "hiqnet.hlen",
1057 FT_UINT16, BASE_DEC,
1061 { &hf_hiqnet_messagelen,
1062 { "Message length", "hiqnet.mlen",
1063 FT_UINT32, BASE_DEC,
1067 { &hf_hiqnet_sourcedev,
1068 { "Source device", "hiqnet.srcdev",
1069 FT_UINT8, BASE_DEC_HEX,
1073 { &hf_hiqnet_sourceaddr,
1074 { "Source address", "hiqnet.srcaddr",
1075 FT_BYTES, BASE_NONE,
1079 { &hf_hiqnet_destdev,
1080 { "Destination device", "hiqnet.dstdev",
1081 FT_UINT8, BASE_DEC_HEX,
1085 { &hf_hiqnet_destaddr,
1086 { "Destination address", "hiqnet.dstaddr",
1087 FT_BYTES, BASE_NONE,
1091 { &hf_hiqnet_messageid,
1092 { "Message ID", "hiqnet.msgid",
1093 FT_UINT16, BASE_HEX,
1094 VALS(messageidnames), 0x0,
1098 { "Flags", "hiqnet.flags",
1099 FT_UINT16, BASE_HEX,
1100 NULL, HIQNET_FLAGS_MASK,
1103 { &hf_hiqnet_reqack_flag,
1104 { "Request Acknowledgement", "hiqnet.flags.reqack",
1106 NULL, HIQNET_REQACK_FLAG,
1109 { &hf_hiqnet_ack_flag,
1110 { "Acknowledgement", "hiqnet.flags.ack",
1112 NULL, HIQNET_ACK_FLAG,
1115 { &hf_hiqnet_info_flag,
1116 { "Information", "hiqnet.flags.info",
1118 NULL, HIQNET_INFO_FLAG,
1121 { &hf_hiqnet_error_flag,
1122 { "Error", "hiqnet.flags.error",
1124 NULL, HIQNET_ERROR_FLAG,
1127 { &hf_hiqnet_guaranteed_flag,
1128 { "Guaranteed", "hiqnet.flags.guar",
1130 NULL, HIQNET_GUARANTEED_FLAG,
1133 { &hf_hiqnet_multipart_flag,
1134 { "Multipart", "hiqnet.flags.multi",
1136 NULL, HIQNET_MULTIPART_FLAG,
1139 { &hf_hiqnet_session_number_flag,
1140 { "Session Number", "hiqnet.flags.session_number",
1142 NULL, HIQNET_SESSION_NUMBER_FLAG,
1145 { &hf_hiqnet_hopcnt,
1146 { "Hop count", "hiqnet.hc",
1151 { &hf_hiqnet_seqnum,
1152 { "Sequence number", "hiqnet.seqnum",
1153 FT_UINT16, BASE_DEC,
1157 { &hf_hiqnet_errcode,
1158 { "Error code", "hiqnet.errcode",
1159 FT_UINT8, BASE_DEC_HEX,
1163 { &hf_hiqnet_errstr,
1164 { "Error string", "hiqnet.errstr",
1165 FT_STRINGZ, STR_UNICODE,
1169 { &hf_hiqnet_startseqno,
1170 { "Start seq. no.", "hiqnet.ssno",
1175 { &hf_hiqnet_rembytes,
1176 { "Remaining bytes", "hiqnet.rembytes",
1177 FT_UINT32, BASE_DEC,
1181 { &hf_hiqnet_sessnum,
1182 { "Session number", "hiqnet.sessnum",
1183 FT_UINT16, BASE_DEC,
1188 { "Cost", "hiqnet.cost",
1193 { &hf_hiqnet_sernumlen,
1194 { "Serial number length", "hiqnet.sernumlen",
1195 FT_UINT16, BASE_DEC,
1199 { &hf_hiqnet_sernum,
1200 { "Serial number", "hiqnet.sernum",
1201 FT_BYTES, BASE_NONE,
1205 { &hf_hiqnet_maxmsgsize,
1206 { "Max message size", "hiqnet.maxmsgsize",
1207 FT_UINT32, BASE_DEC,
1211 { &hf_hiqnet_keepaliveperiod,
1212 { "Keepalive period (ms)", "hiqnet.keepaliveperiod",
1213 FT_UINT16, BASE_DEC,
1218 { "Network ID", "hiqnet.netid",
1220 VALS(networknames), 0x0,
1223 { &hf_hiqnet_macaddr,
1224 { "MAC address", "hiqnet.macaddr",
1225 FT_ETHER, BASE_NONE,
1230 { "DHCP", "hiqnet.dhcp",
1231 FT_BOOLEAN, BASE_NONE,
1235 { &hf_hiqnet_ipaddr,
1236 { "IP Address", "hiqnet.ipaddr",
1241 { &hf_hiqnet_subnetmsk,
1242 { "Subnet mask", "hiqnet.subnetmsk",
1247 { &hf_hiqnet_gateway,
1248 { "Gateway", "hiqnet.gateway",
1253 { &hf_hiqnet_flagmask,
1254 { "Flag mask", "hiqnet.flagmask",
1255 FT_UINT16, BASE_HEX,
1256 NULL, HIQNET_FLAGS_MASK,
1259 { &hf_hiqnet_paramcount,
1260 { "Parameter count", "hiqnet.paramcount",
1261 FT_UINT16, BASE_DEC,
1265 { &hf_hiqnet_paramid,
1266 { "Parameter ID", "hiqnet.paramid",
1267 FT_UINT16, BASE_DEC,
1271 { &hf_hiqnet_datatype,
1272 { "Data type", "hiqnet.datatype",
1274 VALS(datatypenames), 0x0,
1278 { "Value", "hiqnet.value",
1279 FT_BYTES, BASE_NONE,
1283 { &hf_hiqnet_vdobject,
1284 { "Virtual Device Object", "hiqnet.vdobject",
1285 FT_BYTES, BASE_NONE,
1289 { &hf_hiqnet_subtype,
1290 { "Subscription Type (New Style)", "hiqnet.subtype",
1292 NULL, HIQNET_SUBSCRIPTION_TYPE_MASK,
1295 /* FIXME: decode old style subscription type
1296 { &hf_hiqnet_subtypeold,
1297 { "Subscription Type (Old Style)", "hiqnet.subtype",
1299 VALS(subscription_types_oldstyle_names), 0x0,
1303 { &hf_hiqnet_sensrate,
1304 { "Sensor Rate (ms)", "hiqnet.sensrate",
1305 FT_UINT16, BASE_DEC,
1309 { &hf_hiqnet_subflags,
1310 { "Subscription Flags", "hiqnet.subflags",
1311 FT_UINT16, BASE_HEX,
1312 NULL, HIQNET_SUBSCRIPTION_FLAGS_MASK,
1315 { &hf_hiqnet_subcount,
1316 { "No of Subscriptions", "hiqnet.subcount",
1317 FT_UINT16, BASE_DEC,
1321 { &hf_hiqnet_pubparmid,
1322 { "Publisher Parameter ID", "hiqnet.pubparmid",
1323 FT_UINT16, BASE_DEC,
1327 { &hf_hiqnet_subaddr,
1328 { "Subscriber Address", "hiqnet.subaddr",
1329 FT_BYTES, BASE_NONE,
1333 { &hf_hiqnet_subparmid,
1334 { "Subscriber Parameter ID", "hiqnet.subparmid",
1335 FT_UINT16, BASE_DEC,
1339 { &hf_hiqnet_reserved0,
1340 { "Reserved", "hiqnet.reserved0",
1341 FT_BYTES, BASE_NONE,
1345 { &hf_hiqnet_reserved1,
1346 { "Reserved", "hiqnet.reserved1",
1347 FT_BYTES, BASE_NONE,
1351 { &hf_hiqnet_attrcount,
1352 { "Attribute count", "hiqnet.attrcount",
1353 FT_UINT16, BASE_DEC,
1357 { &hf_hiqnet_attrid,
1358 { "Attribute ID", "hiqnet.attrid",
1359 FT_UINT16, BASE_DEC,
1360 VALS(device_attributes_names), 0x0,
1363 { &hf_hiqnet_datalen,
1364 { "Data length", "hiqnet.datalen",
1365 FT_UINT16, BASE_DEC,
1369 { &hf_hiqnet_string,
1370 { "String", "hiqnet.string",
1371 FT_STRINGZ, STR_UNICODE,
1375 { &hf_hiqnet_wrkgrppath,
1376 { "Workgroup Path", "hiqnet.wrkgrppath",
1377 FT_STRINGZ, STR_UNICODE,
1381 { &hf_hiqnet_numvds,
1382 { "Number of Virtual Devices", "hiqnet.numvds",
1383 FT_UINT16, BASE_DEC,
1387 { &hf_hiqnet_vdaddr,
1388 { "Virtual Device Address", "hiqnet.vdaddr",
1393 { &hf_hiqnet_vdclassid,
1394 { "Virtual Device Class ID", "hiqnet.vdclassid",
1395 FT_UINT16, BASE_HEX,
1399 { &hf_hiqnet_stract,
1400 { "Store Action", "hiqnet.stract",
1402 VALS(actionnames), 0x0,
1405 { &hf_hiqnet_strnum,
1406 { "Store Number", "hiqnet.strnum",
1407 FT_UINT16, BASE_DEC,
1412 { "Scope", "hiqnet.scope",
1417 { &hf_hiqnet_recact,
1418 { "Recall Action", "hiqnet.rec.act",
1420 VALS(actionnames), 0x0,
1423 { &hf_hiqnet_recnum,
1424 { "Recall Number", "hiqnet.recnum",
1425 FT_UINT16, BASE_DEC,
1429 { &hf_hiqnet_strlen,
1430 { "String length", "hiqnet.strlen",
1431 FT_UINT16, BASE_DEC,
1436 { "Locate time (ms)", "hiqnet.time",
1437 FT_UINT16, BASE_DEC,
1438 VALS(timenames), 0x0,
1441 { &hf_hiqnet_maxdatasize,
1442 { "Maximum Data Size", "hiqnet.maxdatasize",
1443 FT_UINT16, BASE_DEC,
1447 { &hf_hiqnet_catfilter,
1448 { "Category Filter", "hiqnet.catfilter",
1449 FT_UINT32, BASE_HEX,
1450 NULL, HIQNET_CATEGORIES_MASK,
1453 { &hf_hiqnet_app_cat,
1454 { "Application", "hiqnet.appcat",
1456 NULL, HIQNET_APPLICATION_CAT,
1459 { &hf_hiqnet_conf_cat,
1460 { "Configuration", "hiqnet.confcat",
1462 NULL, HIQNET_CONF_CAT,
1465 { &hf_hiqnet_audionet_cat,
1466 { "Audio Network", "hiqnet.audionetcat",
1468 NULL, HIQNET_AUDIONET_CAT,
1471 { &hf_hiqnet_ctrlnet_cat,
1472 { "Control Network", "hiqnet.ctrlnetcat",
1474 NULL, HIQNET_CTRLNET_CAT,
1477 { &hf_hiqnet_vendnet_cat,
1478 { "Vendor Network", "hiqnet.vendnetcat",
1480 NULL, HIQNET_VENDNET_CAT,
1483 { &hf_hiqnet_startup_cat,
1484 { "Startup", "hiqnet.startupcat",
1486 NULL, HIQNET_STARTUP_CAT,
1489 { &hf_hiqnet_dsp_cat,
1490 { "DSP", "hiqnet.dspcat",
1492 NULL, HIQNET_DSP_CAT,
1495 { &hf_hiqnet_misc_cat,
1496 { "Miscellenaous", "hiqnet.misccat",
1498 NULL, HIQNET_MISC_CAT,
1501 { &hf_hiqnet_ctrlog_cat,
1502 { "Control Logic", "hiqnet.crtllogcat",
1504 NULL, HIQNET_CTRLLOG_CAT,
1507 { &hf_hiqnet_foreignproto_cat,
1508 { "Foreign Protocol", "hiqnet.foreignprotocat",
1510 NULL, HIQNET_FOREIGNPROTO_CAT,
1513 { &hf_hiqnet_digio_cat,
1514 { "Digital I/O", "hiqnet.digiocat",
1516 NULL, HIQNET_DIGIO_CAT,
1519 { &hf_hiqnet_ctrlsurf_cat,
1520 { "Control Surface", "hiqnet.ctrlsurfcat",
1522 NULL, HIQNET_CTRLSURF_CAT,
1525 { &hf_hiqnet_entrieslen,
1526 { "Number of Entries", "hiqnet.entrieslen",
1527 FT_UINT16, BASE_DEC,
1531 { &hf_hiqnet_category,
1532 { "Category", "hiqnet.cat",
1533 FT_UINT16, BASE_HEX,
1534 VALS(eventcategorynames), 0x0,
1537 { &hf_hiqnet_eventid,
1538 { "Event ID", "hiqnet.eventid",
1539 FT_UINT16, BASE_DEC,
1540 VALS(eventidnames), 0x0,
1543 { &hf_hiqnet_priority,
1544 { "Priority", "hiqnet.priority",
1546 VALS(prioritynames), 0x0,
1549 { &hf_hiqnet_eventseqnum,
1550 { "Sequence Number", "hiqnet.eventseqnum",
1551 FT_UINT32, BASE_DEC,
1555 { &hf_hiqnet_eventtime,
1556 { "Time", "hiqnet.eventtime",
1557 FT_STRING, STR_UNICODE,
1561 { &hf_hiqnet_eventdate,
1562 { "Date", "hiqnet.eventdate",
1563 FT_STRING, STR_UNICODE,
1567 { &hf_hiqnet_eventinfo,
1568 { "Information", "hiqnet.information",
1569 FT_STRING, STR_UNICODE,
1573 { &hf_hiqnet_eventadddata,
1574 { "Additional Data", "hiqnet.eventadddata",
1575 FT_BYTES, BASE_NONE,
1579 { &hf_hiqnet_objcount,
1580 { "Object Count", "hiqnet.objcount",
1581 FT_UINT16, BASE_DEC,
1585 { &hf_hiqnet_paramval,
1586 { "Parameter Value (%)", "hiqnet.paramval",
1591 { &hf_hiqnet_ifacecount,
1592 { "Interface Count", "hiqnet.ifacecount",
1593 FT_UINT16, BASE_DEC,
1598 { "Com Port Identifier", "hiqnet.comid",
1603 { &hf_hiqnet_baudrate,
1604 { "Baud Rate", "hiqnet.baudrate",
1605 FT_UINT32, BASE_DEC,
1609 { &hf_hiqnet_parity,
1610 { "Parity", "hiqnet.parity",
1612 VALS(paritynames), 0x0,
1615 { &hf_hiqnet_stopbits,
1616 { "Stop Bits", "hiqnet.stopbits",
1618 VALS(stopbitsnames), 0x0,
1621 { &hf_hiqnet_databits,
1622 { "Data Bits", "hiqnet.databits",
1627 { &hf_hiqnet_flowcontrol,
1628 { "Flowcontrol", "hiqnet.flowcontrol",
1630 VALS(flowcontrolnames), 0x0,
1633 { &hf_hiqnet_devaddr,
1634 { "Device Address", "hiqnet.device",
1635 FT_UINT16, BASE_DEC_HEX,
1639 { &hf_hiqnet_newdevaddr,
1640 { "New Device Address", "hiqnet.device",
1641 FT_UINT16, BASE_DEC_HEX,
1647 /* Setup protocol subtree array */
1648 static gint *ett[] = {
1654 proto_hiqnet = proto_register_protocol (
1655 "Harman HiQnet", /* name */
1656 "HiQnet", /* short name */
1657 "hiqnet" /* abbrev */
1660 proto_register_field_array(proto_hiqnet, hf, array_length(hf));
1661 proto_register_subtree_array(ett, array_length(ett));
1666 proto_reg_handoff_hiqnet(void)
1668 static dissector_handle_t hiqnet_udp_handle;
1669 static dissector_handle_t hiqnet_tcp_handle;
1671 hiqnet_udp_handle = new_create_dissector_handle(dissect_hiqnet_udp, proto_hiqnet);
1672 hiqnet_tcp_handle = new_create_dissector_handle(dissect_hiqnet_tcp, proto_hiqnet);
1673 dissector_add_uint("udp.port", HIQNET_PORT, hiqnet_udp_handle);
1674 dissector_add_uint("tcp.port", HIQNET_PORT, hiqnet_tcp_handle);
1678 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1682 * indent-tabs-mode: nil
1685 * vi: set shiftwidth=4 expandtab:
1686 * :indentSize=4:noTabs=true: