ACN with blobs and magic bullet
[metze/wireshark/wip.git] / epan / dissectors / packet-acn.c
1 /* packet-acn.c
2  * Routines for ACN packet disassembly
3  *
4  * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
5  * Copyright (c) 2006 by Electronic Theatre Controls, Inc.
6  *                    Bill Florac <bflorac@etcconnect.com>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1999 Gerald Combs
11  *
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.
16  *
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.
21  *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27  /*
28     Todo:
29       Add reading of DDL files so we can futher explode DMP packets
30       For some of the Set/Get properties where we have a range of data
31       it would be better to show the block of data rather and
32       address-data pair on each line...
33
34       Build CID to "Name" table from file so we can display real names
35       rather than CIDs
36  */
37
38 /* Include files */
39
40 #include "config.h"
41
42 #include <epan/packet.h>
43 #include <epan/prefs.h>
44 #include <epan/strutil.h>
45 #include <epan/to_str.h>
46
47 /* Forward declarations */
48 void proto_register_acn(void);
49 void proto_reg_handoff_acn(void);
50
51 /* pdu flags */
52 #define ACN_PDU_FLAG_L     0x80
53 #define ACN_PDU_FLAG_V     0x40
54 #define ACN_PDU_FLAG_H     0x20
55 #define ACN_PDU_FLAG_D     0x10
56
57 #define ACN_DMX_OPTION_P   0x80
58 #define ACN_DMX_OPTION_S   0x40
59
60 #define ACN_DMP_ADT_FLAG_V 0x80 /* V = Specifies whether address is a virtual address or not. */
61 #define ACN_DMP_ADT_FLAG_R 0x40 /* R = Specifies whether address is relative to last valid address in packet or not. */
62 #define ACN_DMP_ADT_FLAG_D 0x30 /* D1, D0 = Specify non-range or range address, single data, equal size
63                                    or mixed size data array */
64 #define ACN_DMP_ADT_EXTRACT_D(f)        (((f) & ACN_DMP_ADT_FLAG_D) >> 4)
65
66 #define ACN_DMP_ADT_FLAG_X 0x0c /* X1, X0 = These bits are reserved and their values shall be set to 0
67                                    when encoded. Their values shall be ignored when decoding. */
68
69 #define ACN_DMP_ADT_FLAG_A 0x03 /* A1, A0 = Size of Address elements */
70 #define ACN_DMP_ADT_EXTRACT_A(f)        ((f) & ACN_DMP_ADT_FLAG_A)
71
72 #define ACN_DMP_ADT_V_VIRTUAL   0
73 #define ACN_DMP_ADT_V_ACTUAL    1
74
75 #define ACN_DMP_ADT_R_RELATIVE  0
76 #define ACN_DMP_ADT_R_ABSOLUTE  1
77
78 #define ACN_DMP_ADT_D_NS        0
79 #define ACN_DMP_ADT_D_RS        1
80 #define ACN_DMP_ADT_D_RE        2
81 #define ACN_DMP_ADT_D_RM        3
82
83 #define ACN_DMP_ADT_A_1         0
84 #define ACN_DMP_ADT_A_2         1
85 #define ACN_DMP_ADT_A_4         2
86 #define ACN_DMP_ADT_A_R         3
87
88 #define ACN_PROTOCOL_ID_SDT           1
89 #define ACN_PROTOCOL_ID_DMP           2
90 #define ACN_PROTOCOL_ID_DMX           3
91 #define ACN_PROTOCOL_ID_DMX_2         4
92
93 #define ACN_ADDR_NULL                 0
94 #define ACN_ADDR_IPV4                 1
95 #define ACN_ADDR_IPV6                 2
96 #define ACN_ADDR_IPPORT               3
97
98 /* STD Messages */
99 #define ACN_SDT_VECTOR_UNKNOWN          0
100 #define ACN_SDT_VECTOR_REL_WRAP         1
101 #define ACN_SDT_VECTOR_UNREL_WRAP       2
102 #define ACN_SDT_VECTOR_CHANNEL_PARAMS   3
103 #define ACN_SDT_VECTOR_JOIN             4
104 #define ACN_SDT_VECTOR_JOIN_REFUSE      5
105 #define ACN_SDT_VECTOR_JOIN_ACCEPT      6
106 #define ACN_SDT_VECTOR_LEAVE            7
107 #define ACN_SDT_VECTOR_LEAVING          8
108 #define ACN_SDT_VECTOR_CONNECT          9
109 #define ACN_SDT_VECTOR_CONNECT_ACCEPT  10
110 #define ACN_SDT_VECTOR_CONNECT_REFUSE  11
111 #define ACN_SDT_VECTOR_DISCONNECT      12
112 #define ACN_SDT_VECTOR_DISCONNECTING   13
113 #define ACN_SDT_VECTOR_ACK             14
114 #define ACN_SDT_VECTOR_NAK             15
115 #define ACN_SDT_VECTOR_GET_SESSION     16
116 #define ACN_SDT_VECTOR_SESSIONS        17
117
118 #define ACN_REFUSE_CODE_NONSPECIFIC     1
119 #define ACN_REFUSE_CODE_ILLEGAL_PARAMS  2
120 #define ACN_REFUSE_CODE_LOW_RESOURCES   3
121 #define ACN_REFUSE_CODE_ALREADY_MEMBER  4
122 #define ACN_REFUSE_CODE_BAD_ADDR_TYPE   5
123 #define ACN_REFUSE_CODE_NO_RECIP_CHAN   6
124
125 #define ACN_REASON_CODE_NONSPECIFIC          1
126 /*#define ACN_REASON_CODE_                   2 */
127 /*#define ACN_REASON_CODE_                   3 */
128 /*#define ACN_REASON_CODE_                   4 */
129 /*#define ACN_REASON_CODE_                   5 */
130 #define ACN_REASON_CODE_NO_RECIP_CHAN        6
131 #define ACN_REASON_CODE_CHANNEL_EXPIRED      7
132 #define ACN_REASON_CODE_LOST_SEQUENCE        8
133 #define ACN_REASON_CODE_SATURATED            9
134 #define ACN_REASON_CODE_TRANS_ADDR_CHANGING 10
135 #define ACN_REASON_CODE_ASKED_TO_LEAVE      11
136 #define ACN_REASON_CODE_NO_RECIPIENT        12
137
138 /* Blob Information */
139 #define ACN_BLOB_FIELD_TYPE1             1
140 #define ACN_BLOB_FIELD_TYPE2             2
141 #define ACN_BLOB_FIELD_TYPE3             3
142 #define ACN_BLOB_FIELD_TYPE4             4
143 #define ACN_BLOB_FIELD_TYPE5             5
144 #define ACN_BLOB_FIELD_TYPE6             6
145 #define ACN_BLOB_FIELD_TYPE7             7
146 #define ACN_BLOB_FIELD_TYPE8             8
147 #define ACN_BLOB_FIELD_TYPE9             9
148 #define ACN_BLOB_FIELD_TYPE10            10
149 #define ACN_BLOB_FIELD_TYPE11            11
150 #define ACN_BLOB_FIELD_TYPE12            12
151
152 #define ACN_BLOB_RANGE_MID               0
153 #define ACN_BLOB_RANGE_START             1
154 #define ACN_BLOB_RANGE_END               2
155 #define ACN_BLOB_RANGE_SINGLE            3
156
157 #define ACN_BLOB_IPV4                               1
158 #define ACN_BLOB_IPV6                               2
159 #define ACN_BLOB_ERROR1                             3
160 #define ACN_BLOB_ERROR2                             4
161 #define ACN_BLOB_METADATA                           5
162 #define ACN_BLOB_METADATA_DEVICES                   6
163 #define ACN_BLOB_METADATA_TYPES                     7
164 #define ACN_BLOB_TIME1                              8
165 #define ACN_BLOB_DIMMER_PROPERTIES                  9
166 #define ACN_BLOB_DIMMER_LOAD_PROPERTIES             10
167 #define ACN_BLOB_DIMMING_RACK_PROPERTIES            11
168 #define ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES     12
169 #define ACN_BLOB_DIMMER_STATUS_PROPERTIES           13
170 #define ACN_BLOB_SET_LEVELS_OPERATION               14
171 #define ACN_BLOB_PRESET_OPERATION                   15
172 #define ACN_BLOB_ADVANCED_FEATURES_OPERATION        16
173 #define ACN_BLOB_DIRECT_CONTROL_OPERATION           17
174 #define ACN_BLOB_GENERATE_CONFIG_OPERATION          18
175 #define ACN_BLOB_ERROR3                             19
176 #define ACN_BLOB_DIMMER_PROPERTIES2                 20
177 #define ACN_BLOB_DIMMER_LOAD_PROPERTIES2            21
178 #define ACN_BLOB_DIMMER_RACK_PROPERTIES2            22
179 #define ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2     23
180 #define ACN_BLOB_DIMMER_STATUS_PROPERTIES2          24
181 #define ACN_BLOB_TIME2                              25
182 #define ACN_BLOB_RPC                                26
183 #define ACN_BLOB_DHCP_CONFIG_SUBNET                 27
184 #define ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE           28
185 #define ACN_BLOB_ENERGY_MANAGEMENT                  29
186 #define ACN_BLOB_TIME3                              30
187
188 #define ACN_BLOB_PRESET_PROPERTIES                  250
189
190 #define ACN_DMP_VECTOR_UNKNOWN               0
191 #define ACN_DMP_VECTOR_GET_PROPERTY          1
192 #define ACN_DMP_VECTOR_SET_PROPERTY          2
193 #define ACN_DMP_VECTOR_GET_PROPERTY_REPLY    3
194 #define ACN_DMP_VECTOR_EVENT                 4
195 #define ACN_DMP_VECTOR_MAP_PROPERTY          5
196 #define ACN_DMP_VECTOR_UNMAP_PROPERTY        6
197 #define ACN_DMP_VECTOR_SUBSCRIBE             7
198 #define ACN_DMP_VECTOR_UNSUBSCRIBE           8
199 #define ACN_DMP_VECTOR_GET_PROPERTY_FAIL     9
200 #define ACN_DMP_VECTOR_SET_PROPERTY_FAIL    10
201 #define ACN_DMP_VECTOR_MAP_PROPERTY_FAIL    11
202 #define ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT     12
203 #define ACN_DMP_VECTOR_SUBSCRIBE_REJECT     13
204 #define ACN_DMP_VECTOR_ALLOCATE_MAP         14
205 #define ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY   15
206 #define ACN_DMP_VECTOR_DEALLOCATE_MAP       16
207 #define ACN_DMP_VECTOR_SYNC_EVENT           17
208
209 #define ACN_DMP_REASON_CODE_NONSPECIFIC                  1
210 #define ACN_DMP_REASON_CODE_NOT_A_PROPERTY               2
211 #define ACN_DMP_REASON_CODE_WRITE_ONLY                   3
212 #define ACN_DMP_REASON_CODE_NOT_WRITABLE                 4
213 #define ACN_DMP_REASON_CODE_DATA_ERROR                   5
214 #define ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED           6
215 #define ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE          7
216 #define ACN_DMP_REASON_CODE_PROP_NOT_MAPPABLE            8
217 #define ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED            9
218 #define ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED  10
219 #define ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED  11
220
221 #define ACN_DMX_VECTOR      2
222
223 #define ACN_PREF_DMX_DISPLAY_HEX  0
224 #define ACN_PREF_DMX_DISPLAY_DEC  1
225 #define ACN_PREF_DMX_DISPLAY_PER  2
226
227 #define ACN_PREF_DMX_DISPLAY_20PL 0
228 #define ACN_PREF_DMX_DISPLAY_16PL 1
229
230
231 #define MAGIC_V1           0    /* 1.0 default version */
232 #define MAGIC_COMMAND      1    /* 2.0 command         */
233 #define MAGIC_REPLY        2    /* 2.0 reply           */
234 #define MAGIC_REPLY_TYPE_3 3    /* 2.0 reply type 3    */
235
236 #define V1_SWITCH_TO_NET1       1
237 #define V1_SWITCH_TO_NET2       2
238 #define V1_BOOTP          1114467
239
240 #define V2_CMD_SWITCH_TO_NET1               1
241 #define V2_CMD_SWITCH_TO_NET2               2
242 #define V2_CMD_DOWNLOAD                     3
243 #define V2_CMD_SOFTBOOT                     4
244 #define V2_CMD_PHYSICAL_BEACON              5
245 #define V2_CMD_NETWORK_BEACON               6
246 #define V2_CMD_SWITCH_TO_ACN                7
247 #define V2_CMD_SWITCH_TO_DYNAMIC_IP         8
248 #define V2_CMD_EXTENDED_NETWORK_BEACON      9
249 #define V2_CMD_IP_CONFIGURATION            10
250 #define V2_CMD_RESTORE_FACTORY_DEFAULT     11
251 #define V2_CMD_PHYSICAL_BEACON_BY_CID      12
252 #define V2_CMD_NET2_DOWNLOAD           110163
253
254 #define MAGIC_SWITCH_TO_DYNAMIC_RESET_LEASE    0
255 #define MAGIC_SWITCH_TO_DYNAMIC_MAINTAIN_LEASE 1
256
257 #define MAGIC_DYNAMIC_IP_MAINTAIN_LEASE 0
258 #define MAGIC_DYNAMIC_IP_RESET_LEASE    1
259 #define MAGIC_STATIC_IP                 2
260
261 typedef struct
262 {
263   guint32 start;
264   guint32 vector;
265   guint32 header;
266   guint32 data;
267   guint32 data_length;
268 } acn_pdu_offsets;
269
270 typedef struct
271 {
272   guint8  flags;
273   guint32 address;  /* or first address */
274   guint32 increment;
275   guint32 count;
276   guint32 size;
277   guint32 data_length;
278 } acn_dmp_adt_type;
279
280 /*
281  * See
282  * ANSI BSR E1.17 Architecture for Control Networks
283  * ANSI BSR E1.31
284  */
285
286 #define ACTUAL_ADDRESS  0
287 /* forward reference */
288 static guint32 acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, const char *label);
289 static int     dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
290
291 /* Global variables */
292 static int proto_acn = -1;
293 static gint ett_acn = -1;
294 static gint ett_acn_channel_owner_info_block = -1;
295 static gint ett_acn_channel_member_info_block = -1;
296 static gint ett_acn_channel_parameter = -1;
297 static gint ett_acn_address = -1;
298 static gint ett_acn_address_type = -1;
299 static gint ett_acn_blob = -1;
300 static gint ett_acn_pdu_flags = -1;
301 static gint ett_acn_dmp_pdu = -1;
302 static gint ett_acn_sdt_pdu = -1;
303 static gint ett_acn_sdt_client_pdu = -1;
304 static gint ett_acn_sdt_base_pdu = -1;
305 static gint ett_acn_root_pdu = -1;
306 static gint ett_acn_dmx_address = -1;
307 static gint ett_acn_dmx_2_options = -1;
308 static gint ett_acn_dmx_data_pdu = -1;
309 static gint ett_acn_dmx_pdu = -1;
310
311 /*  Register fields */
312 /* In alphabetical order */
313 static int hf_acn_association = -1;
314 static int hf_acn_blob = -1;
315 /* static int hf_acn_blob_dimmer_load_properties2_type = -1; */
316 static int hf_acn_blob_field_length = -1;
317 static int hf_acn_blob_field_type = -1;
318 static int hf_acn_blob_field_value_number = -1;
319 static int hf_acn_blob_field_value_ipv4 = -1;
320 static int hf_acn_blob_field_value_ipv6 = -1;
321 static int hf_acn_blob_field_value_float = -1;
322 static int hf_acn_blob_field_value_double = -1;
323 static int hf_acn_blob_field_value_guid = -1;
324 static int hf_acn_blob_field_value_string = -1;
325 /* static int hf_acn_blob_metadata_types_type = -1; */
326 static int hf_acn_blob_range_number = -1;
327 /* static int hf_acn_blob_range_start = -1; */
328 static int hf_acn_blob_range_type = -1;
329 static int hf_acn_blob_tree_field_type = -1;
330 static int hf_acn_blob_type = -1;
331 static int hf_acn_blob_version = -1;
332 static int hf_acn_blob_time_zone = -1;
333 static int hf_acn_blob_dst_type = -1;
334 static int hf_acn_blob_dst_start_day = -1;
335 static int hf_acn_blob_dst_stop_day = -1;
336 static int hf_acn_blob_dst_start_locality = -1;
337 static int hf_acn_blob_dst_stop_locality = -1;
338 static int hf_acn_channel_number = -1;
339 static int hf_acn_cid = -1;
340 /* static int hf_acn_client_protocol_id = -1; */
341 static int hf_acn_data = -1;
342 static int hf_acn_data8 = -1;
343 static int hf_acn_data16 = -1;
344 static int hf_acn_data24 = -1;
345 static int hf_acn_data32 = -1;
346 /* static int hf_acn_dmp_adt = -1; */ /* address and data type*/
347 static int hf_acn_dmp_adt_a = -1;
348 static int hf_acn_dmp_adt_v = -1;
349 static int hf_acn_dmp_adt_r = -1;
350 static int hf_acn_dmp_adt_d = -1;
351 static int hf_acn_dmp_adt_x = -1;
352 static int hf_acn_dmp_reason_code = -1;
353 static int hf_acn_dmp_vector = -1;
354 static int hf_acn_dmp_actual_address = -1;
355 static int hf_acn_dmp_virtual_address = -1;
356 static int hf_acn_dmp_actual_address_first = -1;
357 static int hf_acn_dmp_virtual_address_first = -1;
358 static int hf_acn_expiry = -1;
359 static int hf_acn_first_memeber_to_ack = -1;
360 static int hf_acn_first_missed_sequence = -1;
361 static int hf_acn_ip_address_type = -1;
362 static int hf_acn_ipv4 = -1;
363 static int hf_acn_ipv6 = -1;
364 static int hf_acn_last_memeber_to_ack = -1;
365 static int hf_acn_last_missed_sequence = -1;
366 static int hf_acn_mak_threshold = -1;
367 static int hf_acn_member_id = -1;
368 static int hf_acn_nak_holdoff = -1;
369 static int hf_acn_nak_max_wait = -1;
370 static int hf_acn_nak_modulus = -1;
371 static int hf_acn_nak_outbound_flag = -1;
372 static int hf_acn_oldest_available_wrapper = -1;
373 static int hf_acn_packet_identifier = -1;
374 static int hf_acn_pdu = -1;
375 static int hf_acn_pdu_flag_d = -1;
376 static int hf_acn_pdu_flag_h = -1;
377 static int hf_acn_pdu_flag_l = -1;
378 static int hf_acn_pdu_flag_v = -1;
379 static int hf_acn_pdu_flags = -1;
380 static int hf_acn_pdu_length = -1;
381 static int hf_acn_port = -1;
382 static int hf_acn_postamble_size = -1;
383 static int hf_acn_preamble_size = -1;
384 static int hf_acn_protocol_id = -1;
385 static int hf_acn_reason_code = -1;
386 static int hf_acn_reciprocal_channel = -1;
387 static int hf_acn_refuse_code = -1;
388 static int hf_acn_reliable_sequence_number = -1;
389 static int hf_acn_adhoc_expiry = -1;
390 /* static int hf_acn_sdt_pdu = -1; */
391 static int hf_acn_sdt_vector = -1;
392 static int hf_acn_dmx_vector = -1;
393 /* static int hf_acn_session_count = -1; */
394 static int hf_acn_total_sequence_number = -1;
395 static int hf_acn_dmx_source_name = -1;
396 static int hf_acn_dmx_priority = -1;
397 static int hf_acn_dmx_2_reserved = -1;
398 static int hf_acn_dmx_sequence_number = -1;
399 static int hf_acn_dmx_2_options = -1;
400 static int hf_acn_dmx_2_option_p = -1;
401 static int hf_acn_dmx_2_option_s = -1;
402 static int hf_acn_dmx_universe = -1;
403
404 static int hf_acn_dmx_start_code = -1;
405 static int hf_acn_dmx_2_first_property_address = -1;
406 static int hf_acn_dmx_increment = -1;
407 static int hf_acn_dmx_count = -1;
408 static int hf_acn_dmx_2_start_code = -1;
409 static int hf_acn_dmx_data = -1;
410
411 /* static int hf_acn_dmx_dmp_vector = -1; */
412
413 /* Try heuristic ACN decode */
414 static gboolean global_acn_dmx_enable = FALSE;
415 static gint     global_acn_dmx_display_view = 0;
416 static gint     global_acn_dmx_display_line_format = 0;
417 static gboolean global_acn_dmx_display_zeros = FALSE;
418 static gboolean global_acn_dmx_display_leading_zeros = FALSE;
419
420
421 static int proto_magic = -1;
422 static gint ett_magic = -1;
423
424 /* Register fields */
425 static int hf_magic_protocol_id = -1;
426 static int hf_magic_pdu_subtype = -1;
427 static int hf_magic_major_version = -1;
428 static int hf_magic_minor_version = -1;
429
430 static int hf_magic_v1command_vals = -1;
431
432 static int hf_magic_command_vals = -1;
433 static int hf_magic_command_beacon_duration = -1;
434 static int hf_magic_command_tftp = -1;
435 static int hf_magic_command_reset_lease = -1;
436 static int hf_magic_command_cid = -1;
437 static int hf_magic_command_ip_configuration = -1;
438 static int hf_magic_command_ip_address = -1;
439 static int hf_magic_command_subnet_mask = -1;
440 static int hf_magic_command_gateway = -1;
441
442 static int hf_magic_reply_ip_address = -1;
443 static int hf_magic_reply_subnet_mask = -1;
444 static int hf_magic_reply_gateway = -1;
445 static int hf_magic_reply_tftp = -1;
446
447 static int hf_magic_reply_version = -1;
448 static int hf_magic_reply_device_type_name = -1;
449 static int hf_magic_reply_default_name = -1;
450 static int hf_magic_reply_user_name = -1;
451 static int hf_magic_reply_cid = -1;
452 static int hf_magic_reply_dcid = -1;
453 static int hf_magic_reply_invalid_type = -1;
454
455
456 static const value_string acn_protocol_id_vals[] = {
457   { ACN_PROTOCOL_ID_SDT,   "SDT Protocol" },
458   { ACN_PROTOCOL_ID_DMP,   "DMP Protocol" },
459   { ACN_PROTOCOL_ID_DMX,   "DMX Protocol" },
460   { ACN_PROTOCOL_ID_DMX_2, "Ratified DMX Protocol" },
461   { 0,       NULL },
462 };
463
464 static const value_string acn_dmp_adt_r_vals[] = {
465   { ACN_DMP_ADT_R_RELATIVE, "Relative" },
466   { ACN_DMP_ADT_R_ABSOLUTE, "Absolute" },
467   { 0,       NULL },
468 };
469
470 static const value_string acn_dmp_adt_v_vals[] = {
471   { ACN_DMP_ADT_V_ACTUAL,  "Actual" },
472   { ACN_DMP_ADT_V_VIRTUAL, "Virtual" },
473   { 0,       NULL },
474 };
475
476 static const value_string acn_dmp_adt_d_vals[] = {
477   { ACN_DMP_ADT_D_NS, "Non-range, single data item" },
478   { ACN_DMP_ADT_D_RS, "Range, single data item" },
479   { ACN_DMP_ADT_D_RE, "Range, array of equal size data items" },
480   { ACN_DMP_ADT_D_RM, "Range, series of mixed size data items" },
481   { 0,       NULL },
482 };
483
484 static const value_string acn_dmp_adt_a_vals[] = {
485   { ACN_DMP_ADT_A_1, "1 octet" },
486   { ACN_DMP_ADT_A_2, "2 octets" },
487   { ACN_DMP_ADT_A_4, "4 octets" },
488   { ACN_DMP_ADT_A_R, "reserved" },
489   { 0,       NULL },
490 };
491
492
493 static const value_string acn_sdt_vector_vals[] = {
494   {ACN_SDT_VECTOR_UNKNOWN,        "Unknown"},
495   {ACN_SDT_VECTOR_REL_WRAP,       "Reliable Wrapper"},
496   {ACN_SDT_VECTOR_UNREL_WRAP,     "Unreliable Wrapper"},
497   {ACN_SDT_VECTOR_CHANNEL_PARAMS, "Channel Parameters"},
498   {ACN_SDT_VECTOR_JOIN,           "Join"},
499   {ACN_SDT_VECTOR_JOIN_REFUSE,    "Join Refuse"},
500   {ACN_SDT_VECTOR_JOIN_ACCEPT,    "Join Accept"},
501   {ACN_SDT_VECTOR_LEAVE,          "Leave"},
502   {ACN_SDT_VECTOR_LEAVING,        "Leaving"},
503   {ACN_SDT_VECTOR_CONNECT,        "Connect"},
504   {ACN_SDT_VECTOR_CONNECT_ACCEPT, "Connect Accept"},
505   {ACN_SDT_VECTOR_CONNECT_REFUSE, "Connect Refuse"},
506   {ACN_SDT_VECTOR_DISCONNECT,     "Disconnect"},
507   {ACN_SDT_VECTOR_DISCONNECTING,  "Disconnecting"},
508   {ACN_SDT_VECTOR_ACK,            "Ack"},
509   {ACN_SDT_VECTOR_NAK,            "Nak"},
510   {ACN_SDT_VECTOR_GET_SESSION,    "Get Session"},
511   {ACN_SDT_VECTOR_SESSIONS,       "Sessions"},
512   { 0,       NULL },
513 };
514
515 static const value_string acn_dmx_vector_vals[] = {
516   {ACN_DMX_VECTOR,  "Streaming DMX"},
517   { 0,       NULL },
518 };
519
520 static const value_string acn_blob_advanced_features_operation_field_name[] = {
521   { 1, "Operation Type" },
522   { 2, "Use Controlled Loads" },
523   { 3, "Start Dimmer Address" },
524   { 4, "End Dimmer Address" },
525   { 5, "Space" },
526   { 0, NULL }
527 };
528
529 static const value_string acn_blob_dimmer_load_properties2_field_name[] = {
530   { 1, "System" },
531   { 2, "Processor" },
532   { 3, "Rack" },
533   { 4, "Lug" },
534   { 5, "Module" },
535   { 6, "Station" },
536   { 7, "Port" },
537   { 8, "Subdevice" },
538   { 9, "Space" },
539   { 10, "UDN" },
540   { 11, "Reserved" },
541   { 12, "Is Load Recorded" },
542   { 13, "Output Voltage Step 1" },
543   { 14, "Output Voltage Step 2" },
544   { 15, "Output Voltage Step 3" },
545   { 16, "Output Voltage Step 4" },
546   { 17, "Output Voltage Step 5" },
547   { 18, "Output Voltage Step 6" },
548   { 19, "Output Voltage Step 7" },
549   { 20, "Output Voltage Step 8" },
550   { 21, "Output Voltage Step 9" },
551   { 22, "Output Voltage Step 10" },
552   { 23, "Output Voltage Step 11" },
553   { 24, "Output Voltage Step 12" },
554   { 25, "Output Voltage Step 13" },
555   { 26, "Output Voltage Step 14" },
556   { 27, "Output Voltage Step 15" },
557   { 28, "Output Voltage Step 16" },
558   { 29, "Output Voltage Step 17" },
559   { 30, "Output Voltage Step 18" },
560   { 31, "Output Voltage Step 19" },
561   { 32, "Output Voltage Step 20" },
562   { 33, "Amperage Step 1" },
563   { 34, "Amperage Step 2" },
564   { 35, "Amperage Step 3" },
565   { 36, "Amperage Step 4" },
566   { 37, "Amperage Step 5" },
567   { 38, "Amperage Step 6" },
568   { 39, "Amperage Step 7" },
569   { 40, "Amperage Step 8" },
570   { 41, "Amperage Step 9" },
571   { 42, "Amperage Step 10" },
572   { 43, "Amperage Step 11" },
573   { 44, "Amperage Step 12" },
574   { 45, "Amperage Step 13" },
575   { 46, "Amperage Step 14" },
576   { 47, "Amperage Step 15" },
577   { 48, "Amperage Step 16" },
578   { 49, "Amperage Step 17" },
579   { 50, "Amperage Step 18" },
580   { 51, "Amperage Step 19" },
581   { 52, "Amperage Step 20" },
582   { 53, "Voltage Time Step 1" },
583   { 54, "Voltage Time Step 2" },
584   { 55, "Voltage Time Step 3" },
585   { 56, "Voltage Time Step 4" },
586   { 57, "Voltage Time Step 5" },
587   { 58, "Voltage Time Step 6" },
588   { 59, "Voltage Time Step 7" },
589   { 60, "Voltage Time Step 8" },
590   { 61, "Voltage Time Step 9" },
591   { 62, "Voltage Time Step 10" },
592   { 63, "Voltage Time Step 11" },
593   { 64, "Voltage Time Step 12" },
594   { 65, "Voltage Time Step 13" },
595   { 66, "Voltage Time Step 14" },
596   { 67, "Voltage Time Step 15" },
597   { 68, "Voltage Time Step 16" },
598   { 69, "Voltage Time Step 17" },
599   { 70, "Voltage Time Step 18" },
600   { 71, "Voltage Time Step 19" },
601   { 72, "Voltage Time Step 20" },
602   { 73, "Is Rig Check Recorded" },
603   { 74, "Recorded Level" },
604   { 75, "Recorded Current" },
605   { 0, NULL }
606 };
607 static value_string_ext acn_blob_dimmer_load_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_load_properties2_field_name);
608
609 static const value_string acn_blob_dimmer_properties2_field_name[] = {
610   { 1, "System" },
611   { 2, "Processor" },
612   { 3, "Rack" },
613   { 4, "Lug" },
614   { 5, "Module" },
615   { 6, "Station" },
616   { 7, "Port" },
617   { 8, "Subdevice" },
618   { 9, "Space" },
619   { 10, "UDN" },
620   { 11, "Reserved" },
621   { 12, "Dimmer Name" },
622   { 13, "Dimmer Module" },
623   { 14, "Dimmer Mode" },
624   { 15, "Dimmer Control" },
625   { 16, "Dimmer Curve" },
626   { 17, "On Level Percent" },
627   { 18, "Off Level Percent" },
628   { 19, "On Time(sec)" },
629   { 20, "Off Time(sec)" },
630   { 21, "Dimmer AF Enabled" },
631   { 22, "Threshold" },
632   { 23, "Min Scale" },
633   { 24, "Unregulated Min Scale" },
634   { 25, "Max Scale" },
635   { 26, "Unregulated Max Scale" },
636   { 27, "Voltage Regulation" },
637   { 28, "Preheat Enable" },
638   { 29, "Preheat Time" },
639   { 30, "DC Output Prevent" },
640   { 31, "Inrush Protect" },
641   { 32, "AF Sensitivity" },
642   { 33, "AF Reaction Time" },
643   { 34, "Scale Load" },
644   { 35, "PTIO" },
645   { 36, "Allow In Preset" },
646   { 37, "Allow In Panic" },
647   { 38, "Allow In Panic DD" },
648   { 39, "Loads Reporting Mode" },
649   { 40, "New Dimmer Space Number" },
650   { 41, "New Dimmer Number" },
651   { 42, "DMX A Patch" },
652   { 43, "DMX B Patch" },
653   { 44, "sACN Patch" },
654   { 45, "DMX A Patch DD" },
655   { 46, "DMX B Patch DD" },
656   { 47, "sACN Patch DD" },
657   { 48, "DMX A 16-bit Enable" },
658   { 49, "DMX B 16-bit Enable" },
659   { 50, "sACN 16-bit Enable" },
660   { 51, "Dimmer Zone" },
661   { 0, NULL }
662 };
663 static value_string_ext acn_blob_dimmer_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_properties2_field_name);
664
665 static const value_string acn_blob_dimmer_rack_properties2_field_name[] = {
666   { 1, "System" },
667   { 2, "Processor" },
668   { 3, "Rack" },
669   { 4, "Lug" },
670   { 5, "Module" },
671   { 6, "Station" },
672   { 7, "Port" },
673   { 8, "Subdevice" },
674   { 9, "Space" },
675   { 10, "UDN" },
676   { 11, "Reserved" },
677   { 12, "Rack CID" },
678   { 13, "Rack Number" },
679   { 14, "Rack Name" },
680   { 15, "Rack Model" },
681   { 16, "Rack AF Enable" },
682   { 17, "Temperature Format" },
683   { 18, "Data Loss Behavior DMX A" },
684   { 19, "Data Loss Behavior DMX B" },
685   { 20, "Data Loss Behavior sACN" },
686   { 21, "Data Loss Cross/Wait Time DMX A" },
687   { 22, "Data Loss Cross/Wait Time DMX B" },
688   { 23, "Data Loss Wait Time sACN" },
689   { 24, "Data Loss Fade Time DMX A" },
690   { 25, "Data Loss Fade Time DMX B" },
691   { 26, "Data Loss Fade Time sACN" },
692   { 27, "Data Loss Preset DMX A" },
693   { 28, "Data Loss Preset DMX B" },
694   { 29, "Data Port Priority DMX A" },
695   { 30, "Data Port Priority DMX B" },
696   { 31, "Data Port Enabled DMX A" },
697   { 32, "Data Port Enabled DMX B" },
698   { 33, "Data Port Enabled sACN" },
699   { 34, "16 Bit Enabled DMX A" },
700   { 35, "16 Bit Enabled DMX B" },
701   { 36, "16 Bit Enabled sACN" },
702   { 37, "Patch From Home Screen" },
703   { 38, "SCR Off Time" },
704   { 39, "Time Mode" },
705   { 40, "Offset from UTC" },
706   { 41, "Universal Hold Last Look Time" },
707   { 42, "Reactivate Presets On Boot" },
708   { 43, "Voltage High Warning Level" },
709   { 44, "Temperature High Warning Level" },
710   { 45, "Fan Operation Timing" },
711   { 46, "Allow Backplane Communication Errors" },
712   { 47, "Activate Presets on Boot" },
713   { 48, "SmartLink2 Power Supply Enable" },
714   { 49, "Remote Record Enable" },
715   { 50, "System Number" },
716   { 51, "Architectural Priority" },
717   { 52, "Data Loss Preset Space DMX A" },
718   { 53, "Data Loss Preset Space DMX B" },
719   { 0, NULL }
720 };
721 static value_string_ext acn_blob_dimmer_rack_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_properties2_field_name);
722
723 static const value_string acn_blob_dimmer_rack_status_properties2_field_name[] = {
724   { 1, "System" },
725   { 2, "Processor" },
726   { 3, "Rack" },
727   { 4, "Lug" },
728   { 5, "Module" },
729   { 6, "Station" },
730   { 7, "Port" },
731   { 8, "Subdevice" },
732   { 9, "Space" },
733   { 10, "UDN" },
734   { 11, "Reserved" },
735   { 12, "CPU Tempeture" },
736   { 13, "Time of Last Reboot" },
737   { 14, "Time Now" },
738   { 15, "Rack Phasing" },
739   { 16, "Power Frequency" },
740   { 17, "Phase A Voltage" },
741   { 18, "Phase B Voltage" },
742   { 19, "Phase C Voltage" },
743   { 20, "DMX A Port Status" },
744   { 21, "DMX B Port Status" },
745   { 22, "Active Preset Group IDs" },
746   { 23, "Active Preset Group ID[0]" },
747   { 24, "Active Preset Group ID[1]" },
748   { 25, "Active Preset Group ID[2]" },
749   { 26, "Active Preset Group ID[3]" },
750   { 27, "Active Preset Group ID[4]" },
751   { 28, "Active Preset Group ID[5]" },
752   { 29, "Active Preset Group ID[6]" },
753   { 30, "Active Preset Group ID[7]" },
754   { 31, "Active Preset Group ID[8]" },
755   { 32, "Active Preset Group ID[9]" },
756   { 33, "Active Preset Group ID[10]" },
757   { 34, "Active Preset Group ID[11]" },
758   { 35, "Active Preset Group ID[12]" },
759   { 36, "Active Preset Group ID[13]" },
760   { 37, "Active Preset Group ID[14]" },
761   { 38, "Active Preset Group ID[15]" },
762   { 39, "Active Preset Group ID[16]" },
763   { 40, "Active Preset Group ID[17]" },
764   { 41, "Active Preset Group ID[18]" },
765   { 42, "Active Preset Group ID[19]" },
766   { 43, "Active Preset Group ID[20]" },
767   { 44, "Active Preset Group ID[21]" },
768   { 45, "Active Preset Group ID[22]" },
769   { 46, "Active Preset Group ID[23]" },
770   { 47, "Active Preset Group ID[24]" },
771   { 48, "Active Preset Group ID[25]" },
772   { 49, "Active Preset Group ID[26]" },
773   { 50, "Active Preset Group ID[27]" },
774   { 51, "Active Preset Group ID[28]" },
775   { 52, "Active Preset Group ID[29]" },
776   { 53, "Active Preset Group ID[30]" },
777   { 54, "Active Preset Group ID[31]" },
778   { 55, "Active Preset Group ID[32]" },
779   { 56, "Active Preset Group ID[33]" },
780   { 57, "Active Preset Group ID[34]" },
781   { 58, "Active Preset Group ID[35]" },
782   { 59, "Active Preset Group ID[36]" },
783   { 60, "Active Preset Group ID[37]" },
784   { 61, "Active Preset Group ID[38]" },
785   { 62, "Active Preset Group ID[39]" },
786   { 63, "Active Preset Group ID[40]" },
787   { 64, "Active Preset Group ID[41]" },
788   { 65, "Active Preset Group ID[42]" },
789   { 66, "Active Preset Group ID[43]" },
790   { 67, "Active Preset Group ID[44]" },
791   { 68, "Active Preset Group ID[45]" },
792   { 69, "Active Preset Group ID[46]" },
793   { 70, "Active Preset Group ID[47]" },
794   { 71, "Active Preset Group ID[48]" },
795   { 72, "Active Preset Group ID[49]" },
796   { 73, "Active Preset Group ID[50]" },
797   { 74, "Active Preset Group ID[51]" },
798   { 75, "Active Preset Group ID[52]" },
799   { 76, "Active Preset Group ID[53]" },
800   { 77, "Active Preset Group ID[54]" },
801   { 78, "Active Preset Group ID[55]" },
802   { 79, "Active Preset Group ID[56]" },
803   { 80, "Active Preset Group ID[57]" },
804   { 81, "Active Preset Group ID[58]" },
805   { 82, "Active Preset Group ID[59]" },
806   { 83, "Active Preset Group ID[60]" },
807   { 84, "Active Preset Group ID[61]" },
808   { 85, "Active Preset Group ID[62]" },
809   { 86, "Active Preset Group ID[63]" },
810   { 87, "Rack AF State" },
811   { 88, "Number of Stored Presets for This Rack" },
812   { 89, "Number of Lugs in This Rack" },
813   { 90, "DSP Version" },
814   { 91, "AF Card Version Slot 1" },
815   { 92, "AF Card Version Slot 2" },
816   { 93, "AF Card Version Slot 3" },
817   { 94, "AF Card Version Slot 4" },
818   { 95, "HCS08 Version" },
819   { 96, "FPGA Version" },
820   { 97, "Upload Progress AF Card 1" },
821   { 98, "Upload Progress AF Card 2" },
822   { 99, "Upload Progress AF Card 3" },
823   { 100, "Upload Progress AF Card 4" },
824   { 0, NULL }
825 };
826 static value_string_ext acn_blob_dimmer_rack_status_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_status_properties2_field_name);
827
828 static const value_string acn_blob_dimmer_status_properties2_field_name[] = {
829   { 1, "System" },
830   { 2, "Processor" },
831   { 3, "Rack" },
832   { 4, "Lug" },
833   { 5, "Module" },
834   { 6, "Station" },
835   { 7, "Port" },
836   { 8, "Subdevice" },
837   { 9, "Space" },
838   { 10, "UDN" },
839   { 11, "Reserved" },
840   { 12, "Source Winning Control" },
841   { 13, "Priority of Winning Source" },
842   { 14, "Winning Level" },
843   { 15, "Winning DMX A Level" },
844   { 16, "Winning DMX B Level" },
845   { 17, "Winning sACN Level" },
846   { 18, "Source Winning Control DD" },
847   { 19, "Priority of Winning Soruce DD" },
848   { 20, "Winning Level DD" },
849   { 21, "Winning DMX A Level DD" },
850   { 22, "Winning DMX B Level DD" },
851   { 23, "Winning DMX sACN Level DD" },
852   { 24, "Actual Load" },
853   { 25, "Load Status" },
854   { 0, NULL }
855 };
856 static value_string_ext acn_blob_dimmer_status_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_status_properties2_field_name);
857
858
859 static const value_string acn_blob_direct_control_operation_field_name[] = {
860   { 1, "Space" },
861   { 2, "Dimmer Number" },
862   { 3, "DD Side" },
863   { 4, "Level" },
864   { 5, "Priority" },
865   { 0, NULL }
866 };
867
868 static const value_string acn_blob_error3_field_name[] = {
869   { 1, "System" },
870   { 2, "Processor" },
871   { 3, "Rack" },
872   { 4, "Lug" },
873   { 5, "Module" },
874   { 6, "Station" },
875   { 7, "Port" },
876   { 8, "Subdevice" },
877   { 9, "Space" },
878   { 10, "UDN" },
879   { 11, "sACN Address" },
880   { 12, "Error Type" },
881   { 13, "Severity" },
882   { 14, "Timestamp" },
883   { 15, "Error Text" },
884   { 0, NULL }
885 };
886
887 static const value_string acn_blob_field_type_vals[] = {
888   { ACN_BLOB_FIELD_TYPE1, "1 Byte Signed Integer" },
889   { ACN_BLOB_FIELD_TYPE2, "2 Bits Signed Integer" },
890   { ACN_BLOB_FIELD_TYPE3, "4 Bits Signed Integer" },
891   { ACN_BLOB_FIELD_TYPE4, "8 Bits Signed Integer" },
892   { ACN_BLOB_FIELD_TYPE5, "1 Byte Unsigned Integer" },
893   { ACN_BLOB_FIELD_TYPE6, "2 Bits Unsigned Integer" },
894   { ACN_BLOB_FIELD_TYPE7, "4 Bits Unsigned Integer" },
895   { ACN_BLOB_FIELD_TYPE8, "8 Bits Unsigned Integer" },
896   { ACN_BLOB_FIELD_TYPE9, "Float" },
897   { ACN_BLOB_FIELD_TYPE10, "Double" },
898   { ACN_BLOB_FIELD_TYPE11, "Variblob" },
899   { ACN_BLOB_FIELD_TYPE12, "Ignore" },
900   { 0, NULL }
901 };
902
903 static const value_string acn_blob_generate_config_operation_field_name[] = {
904   { 1, "First Dimmer" },
905   { 2, "Numbering Style" },
906   { 3, "Use Dimmer Doubling" },
907   { 4, "Default Module Type" },
908   { 0, NULL }
909 };
910
911 static const value_string acn_blob_ip_field_name[] = {
912   { 1, "IP Address" },
913   { 2, "Subnet Mask" },
914   { 3, "Gateway" },
915   { 0, NULL }
916 };
917
918 static const value_string acn_blob_error1_field_name[] = {
919   { 1, "System" },
920   { 2, "Processor" },
921   { 3, "Rack" },
922   { 4, "Lug" },
923   { 5, "Module" },
924   { 6, "Station" },
925   { 7, "Port" },
926   { 8, "Subdevice" },
927   /*{9,  "Space"}, */
928   { 9, "UDN" },
929   { 10, "sACN Address" },
930   { 11, "Error Type" },
931   { 12, "Severity" },
932   { 13, "Timestamp" },
933   { 14, "Error Text" },
934   { 0, NULL }
935 };
936
937 static const value_string acn_blob_error2_field_name[] = {
938   { 1, "System" },
939   { 2, "Processor" },
940   { 3, "Rack" },
941   { 4, "Lug" },
942   { 5, "Module" },
943   { 6, "Station" },
944   { 7, "Port" },
945   { 8, "Subdevice" },
946   { 9, "Space" },
947   { 10, "UDN" },
948   { 11, "sACN Address" },
949   { 12, "Error Type" },
950   { 13, "Severity" },
951   { 14, "Timestamp" },
952   { 15, "Error Text" },
953   { 0, NULL }
954 };
955
956 static const value_string acn_blob_metadata_devices_field_name[] = {
957   { 1, "Device Type" },
958   { 2, "Identifier Name 1" },
959   { 3, "Identifier Name 2" },
960   { 4, "Identifier Name 3" },
961   { 5, "Identifier Name 4" },
962   { 0, NULL }
963 };
964
965 static const value_string acn_blob_metadata_field_name[] = {
966   { 1, "Device Type" },
967   { 2, "Metadata Type" },
968   { 3, "Identifier Name 1" },
969   { 4, "Identifier Name 2" },
970   { 5, "Identifier Name 3" },
971   { 6, "Identifier Name 4" },
972   { 7, "Metadata 1" },
973   { 8, "Metadata 2" },
974   { 9, "Metadata 3" },
975   { 10, "Metadata 4" },
976   { 11, "Metadata 5" },
977   { 12, "Metadata 6" },
978   { 13, "Metadata 7" },
979   { 14, "Metadata 8" },
980   { 15, "Device CID" },
981   { 0, NULL }
982 };
983
984 static const value_string acn_blob_metadata_types_field_name[] = {
985   { 1, "Metadata Type" },
986   { 2, "Identifier Name 1" },
987   { 3, "Identifier Name 2" },
988   { 4, "Identifier Name 3" },
989   { 5, "Identifier Name 4" },
990   { 6, "Identifier Name 5" },
991   { 7, "Identifier Name 6" },
992   { 8, "Identifier Name 7" },
993   { 9, "Identifier Name 8" },
994   { 0, NULL }
995 };
996
997 static const value_string acn_blob_time1_field_name[] = {
998   { 1, "Time" },
999   { 2, "Time Zone Name" },
1000   { 3, "Time Zone Offset Hour" },
1001   { 4, "Time Zone Offset Min" },
1002   { 5, "Time Zone Offset Sec" },
1003   { 6, "DST Name" },
1004   { 7, "Start Month" },
1005   { 8, "Start Week" },
1006   { 9, "Start Day" },
1007   { 10, "End Month" },
1008   { 11, "End Week" },
1009   { 12, "End Day" },
1010   { 13, "Timed Event Update" },
1011   { 0, NULL }
1012 };
1013
1014 static const value_string acn_blob_dimmer_properties1_field_name[] = {
1015   { 1, "System" },
1016   { 2, "Processor" },
1017   { 3, "Rack" },
1018   { 4, "Lug" },
1019   { 5, "Module" },
1020   { 6, "Station" },
1021   { 7, "Port" },
1022   { 8, "Subdevice" },
1023   { 9, "Space" },
1024   { 10, "UDN" },
1025   { 11, "Reserved" },
1026   { 12, "Dimmer Name" },
1027   { 13, "Dimmer Module" },
1028   { 14, "Dimmer Mode" },
1029   { 15, "Dimmer Control" },
1030   { 16, "Dimmer Curve" },
1031   { 17, "On Level Percent" },
1032   { 18, "Off Level Percent" },
1033   { 19, "On Time(sec)" },
1034   { 20, "Off Time(sec)" },
1035   { 21, "Dimmer AF Enabled" },
1036   { 22, "Threshold" },
1037   { 23, "Min Scale" },
1038   { 24, "Unregulated Min Scale" },
1039   { 25, "Max Scale" },
1040   { 26, "Unregulated Max Scale" },
1041   { 27, "Voltage Regulation" },
1042   { 28, "Preheat Enable" },
1043   { 29, "Preheat Time" },
1044   { 30, "DC Output Prevent" },
1045   { 31, "Inrush Protect" },
1046   { 32, "AF Sensitivity" },
1047   { 33, "AF Reaction Time" },
1048   { 34, "Scale Load" },
1049   { 35, "PTIO" },
1050   { 36, "Allow In Preset" },
1051   { 37, "Allow In Panic" },
1052   { 38, "Allow In Panic DD" },
1053   /*{39, "Loads Reporting Mode"},
1054   {40, "New Dimmer Space Number"}, */
1055   { 39, "Report No Loads Enable" },
1056   { 40, "Loads Error Reporting Enable" },
1057   { 41, "Dimmer Space" },
1058   { 42, "New Dimmer Number" },
1059   { 43, "DMX A Patch" },
1060   { 44, "DMX B Patch" },
1061   { 45, "sACN Patch" },
1062   { 46, "DMX A Patch DD" },
1063   { 47, "DMX B Patch DD" },
1064   { 48, "sACN Patch DD" },
1065   { 0, NULL }
1066 };
1067 static value_string_ext acn_blob_dimmer_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_properties1_field_name);
1068
1069 static const value_string acn_blob_dimmer_load_properties1_field_name[] = {
1070   { 1, "System" },
1071   { 2, "Processor" },
1072   { 3, "Rack" },
1073   { 4, "Lug" },
1074   { 5, "Module" },
1075   { 6, "Station" },
1076   { 7, "Port" },
1077   { 8, "Subdevice" },
1078   { 9, "Space" },
1079   { 10, "UDN" },
1080   { 11, "Reserved" },
1081   { 12, "Is Load Recorded" },
1082   { 13, "Output Voltage Step 1" },
1083   { 14, "Output Voltage Step 2" },
1084   { 15, "Output Voltage Step 3" },
1085   { 16, "Output Voltage Step 4" },
1086   { 17, "Output Voltage Step 5" },
1087   { 18, "Output Voltage Step 6" },
1088   { 19, "Output Voltage Step 7" },
1089   { 20, "Output Voltage Step 8" },
1090   { 21, "Output Voltage Step 9" },
1091   { 22, "Output Voltage Step 10" },
1092   { 23, "Output Voltage Step 11" },
1093   { 24, "Output Voltage Step 12" },
1094   { 25, "Output Voltage Step 13" },
1095   { 26, "Output Voltage Step 14" },
1096   { 27, "Output Voltage Step 15" },
1097   { 28, "Output Voltage Step 16" },
1098   { 29, "Output Voltage Step 17" },
1099   { 30, "Output Voltage Step 18" },
1100   { 31, "Output Voltage Step 19" },
1101   { 32, "Output Voltage Step 20" },
1102   { 33, "Amperage Step 1" },
1103   { 34, "Amperage Step 2" },
1104   { 35, "Amperage Step 3" },
1105   { 36, "Amperage Step 4" },
1106   { 37, "Amperage Step 5" },
1107   { 38, "Amperage Step 6" },
1108   { 39, "Amperage Step 7" },
1109   { 40, "Amperage Step 8" },
1110   { 41, "Amperage Step 9" },
1111   { 42, "Amperage Step 10" },
1112   { 43, "Amperage Step 11" },
1113   { 44, "Amperage Step 12" },
1114   { 45, "Amperage Step 13" },
1115   { 46, "Amperage Step 14" },
1116   { 47, "Amperage Step 15" },
1117   { 48, "Amperage Step 16" },
1118   { 49, "Amperage Step 17" },
1119   { 50, "Amperage Step 18" },
1120   { 51, "Amperage Step 19" },
1121   { 52, "Amperage Step 20" },
1122   { 53, "Voltage Time Step 1" },
1123   { 54, "Voltage Time Step 2" },
1124   { 55, "Voltage Time Step 3" },
1125   { 56, "Voltage Time Step 4" },
1126   { 57, "Voltage Time Step 5" },
1127   { 58, "Voltage Time Step 6" },
1128   { 59, "Voltage Time Step 7" },
1129   { 60, "Voltage Time Step 8" },
1130   { 61, "Voltage Time Step 9" },
1131   { 62, "Voltage Time Step 10" },
1132   { 63, "Voltage Time Step 11" },
1133   { 64, "Voltage Time Step 12" },
1134   { 65, "Voltage Time Step 13" },
1135   { 66, "Voltage Time Step 14" },
1136   { 67, "Voltage Time Step 15" },
1137   { 68, "Voltage Time Step 16" },
1138   { 69, "Voltage Time Step 17" },
1139   { 70, "Voltage Time Step 18" },
1140   { 71, "Voltage Time Step 19" },
1141   { 72, "Voltage Time Step 20" },
1142   { 0, NULL }
1143 };
1144 static value_string_ext acn_blob_dimmer_load_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_load_properties1_field_name);
1145
1146 static const value_string acn_blob_dimmer_rack_properties1_field_name[] = {
1147   { 1, "System" },
1148   { 2, "Processor" },
1149   { 3, "Rack" },
1150   { 4, "Lug" },
1151   { 5, "Module" },
1152   { 6, "Station" },
1153   { 7, "Port" },
1154   { 8, "Subdevice" },
1155   { 9, "Space" },
1156   { 10, "UDN" },
1157   { 11, "Reserved" },
1158   { 12, "Rack CID" },
1159   { 13, "Rack Number" },
1160   { 14, "Rack Name" },
1161   { 15, "Rack Model" },
1162   { 16, "Rack AF Enable" },
1163   { 17, "Temperature Format" },
1164   { 18, "Data Loss Behavior DMX A" },
1165   { 19, "Data Loss Behavior DMX B" },
1166   { 20, "Data Loss Behavior sACN" },
1167   { 21, "Data Loss Cross/Wait Time DMX A" },
1168   { 22, "Data Loss Cross/Wait Time DMX B" },
1169   { 23, "Data Loss Wait Time sACN" },
1170   { 24, "Data Loss Fade Time DMX A" },
1171   { 25, "Data Loss Fade Time DMX B" },
1172   { 26, "Data Loss Fade Time sACN" },
1173   { 27, "Data Loss Preset DMX A" },
1174   { 28, "Data Loss Preset DMX B" },
1175   { 29, "Data Port Priority DMX A" },
1176   { 30, "Data Port Priority DMX B" },
1177   { 31, "Data Port Enabled DMX A" },
1178   { 32, "Data Port Enabled DMX B" },
1179   { 33, "Data Port Enabled sACN" },
1180   { 34, "16 Bit Enabled DMX A" },
1181   { 35, "16 Bit Enabled DMX B" },
1182   { 36, "16 Bit Enabled sACN" },
1183   { 37, "Patch From Home Screen" },
1184   { 38, "SCR Off Time" },
1185   { 39, "Time Mode" },
1186   { 40, "Offset from UTC" },
1187   { 41, "Universal Hold Last Look Time" },
1188   { 42, "Reactivate Presets On Boot" },
1189   { 43, "Voltage High Warning Level" },
1190   { 44, "Temperature High Warning Level" },
1191   { 45, "Fan Operation Timing" },
1192   { 46, "Allow Backplane Communication Errors" },
1193   { 0, NULL }
1194 };
1195 static value_string_ext acn_blob_dimmer_rack_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_properties1_field_name);
1196
1197
1198 static const value_string acn_blob_dimmer_rack_status_properties1_field_name[] = {
1199   { 1, "System" },
1200   { 2, "Processor" },
1201   { 3, "Rack" },
1202   { 4, "Lug" },
1203   { 5, "Module" },
1204   { 6, "Station" },
1205   { 7, "Port" },
1206   { 8, "Subdevice" },
1207   { 9, "Space" },
1208   { 10, "UDN" },
1209   { 11, "Reserved" },
1210   { 12, "CPU Tempeture" },
1211   { 13, "Time of Last Reboot" },
1212   { 14, "Time Now" },
1213   { 15, "Rack Phasing" },
1214   { 16, "Power Frequency" },
1215   { 17, "Phase A Voltage" },
1216   { 18, "Phase B Voltage" },
1217   { 19, "Phase C Voltage" },
1218   { 20, "DMX A Port Status" },
1219   { 21, "DMX B Port Status" },
1220   { 22, "Rack AF State" },
1221   { 23, "Number of Stored Presets for This Rack" },
1222   { 24, "Number of Lugs in This Rack" },
1223   { 25, "DSP Version" },
1224   { 26, "AF Card Version Slot 1" },
1225   { 27, "AF Card Version Slot 2" },
1226   { 28, "AF Card Version Slot 3" },
1227   { 29, "AF Card Version Slot 4" },
1228   { 30, "HCS08 Version" },
1229   { 31, "FPGA Version" },
1230   { 32, "Upload Progress AF Card 1" },
1231   { 33, "Upload Progress AF Card 2" },
1232   { 34, "Upload Progress AF Card 3" },
1233   { 35, "Upload Progress AF Card 4" },
1234   { 0, NULL }
1235 };
1236 static value_string_ext acn_blob_dimmer_rack_status_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_status_properties1_field_name);
1237
1238 static const value_string acn_blob_dimmer_status_properties1_field_name[] = {
1239   { 1, "System" },
1240   { 2, "Processor" },
1241   { 3, "Rack" },
1242   { 4, "Lug" },
1243   { 5, "Module" },
1244   { 6, "Station" },
1245   { 7, "Port" },
1246   { 8, "Subdevice" },
1247   { 9, "Space" },
1248   { 10, "UDN" },
1249   { 11, "Reserved" },
1250   { 12, "Source Winning Control" },
1251   { 13, "Priority of Winning Source" },
1252   { 14, "Winning Level" },
1253   { 15, "Winning DMX A Level" },
1254   { 16, "Winning DMX B Level" },
1255   { 17, "Winning sACN Level" },
1256   { 18, "Source Winning Control DD" },
1257   { 19, "Priority of Winning Soruce DD" },
1258   { 20, "Winning Level DD" },
1259   { 21, "Winning DMX A Level DD" },
1260   { 22, "Winning DMX B Level DD" },
1261   { 23, "Winning DMX sACN Level DD" },
1262   { 24, "Actual Load" },
1263   { 0, NULL }
1264 };
1265 static value_string_ext acn_blob_dimmer_status_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_status_properties1_field_name);
1266
1267 static const value_string acn_blob_preset_operation_field_name[] = {
1268   { 1, "Operation Type" },
1269   { 2, "Preset Number" },
1270   { 3, "Space" },
1271   { 0, NULL }
1272 };
1273
1274 static const value_string acn_blob_preset_properties_field_name[] = {
1275   { 1, "System" },
1276   { 2, "Processor" },
1277   { 3, "Rack" },
1278   { 4, "Lug" },
1279   { 5, "Module" },
1280   { 6, "Station" },
1281   { 7, "Port" },
1282   { 8, "Subdevice" },
1283   { 9, "Space" },
1284   { 10, "UDN" },
1285   { 11, "Reserved" },
1286   { 12, "Preset Number" },
1287   { 13, "Preset Name" },
1288   { 14, "Fade In Time" },
1289   { 15, "Fade Out Time" },
1290   { 16, "Priority" },
1291   { 17, "Levels" },
1292   { 18, "Level[0]" },
1293   { 19, "Level[1]" },
1294   { 20, "Level[2]" },
1295   { 21, "Level[3]" },
1296   { 22, "Level[4]" },
1297   { 23, "Level[5]" },
1298   { 24, "Level[6]" },
1299   { 25, "Level[7]" },
1300   { 26, "Level[8]" },
1301   { 27, "Level[9]" },
1302   { 28, "Level[10]" },
1303   { 29, "Level[11]" },
1304   { 30, "Level[12]" },
1305   { 31, "Level[13]" },
1306   { 32, "Level[14]" },
1307   { 33, "Level[15]" },
1308   { 34, "Level[16]" },
1309   { 35, "Level[17]" },
1310   { 36, "Level[18]" },
1311   { 37, "Level[19]" },
1312   { 38, "Level[20]" },
1313   { 39, "Level[21]" },
1314   { 40, "Level[22]" },
1315   { 41, "Level[23]" },
1316   { 42, "Level[24]" },
1317   { 43, "Level[25]" },
1318   { 44, "Level[26]" },
1319   { 45, "Level[27]" },
1320   { 46, "Level[28]" },
1321   { 47, "Level[29]" },
1322   { 48, "Level[30]" },
1323   { 49, "Level[31]" },
1324   { 50, "Level[32]" },
1325   { 51, "Level[33]" },
1326   { 52, "Level[34]" },
1327   { 53, "Level[35]" },
1328   { 54, "Level[36]" },
1329   { 55, "Level[37]" },
1330   { 56, "Level[38]" },
1331   { 57, "Level[39]" },
1332   { 58, "Level[40]" },
1333   { 59, "Level[41]" },
1334   { 60, "Level[42]" },
1335   { 61, "Level[43]" },
1336   { 62, "Level[44]" },
1337   { 63, "Level[45]" },
1338   { 64, "Level[46]" },
1339   { 65, "Level[47]" },
1340   { 66, "Level[48]" },
1341   { 67, "Level[49]" },
1342   { 68, "Level[50]" },
1343   { 69, "Level[51]" },
1344   { 70, "Level[52]" },
1345   { 71, "Level[53]" },
1346   { 72, "Level[54]" },
1347   { 73, "Level[55]" },
1348   { 74, "Level[56]" },
1349   { 75, "Level[57]" },
1350   { 76, "Level[58]" },
1351   { 77, "Level[59]" },
1352   { 78, "Level[60]" },
1353   { 79, "Level[61]" },
1354   { 80, "Level[62]" },
1355   { 81, "Level[63]" },
1356   { 82, "Level[64]" },
1357   { 83, "Level[65]" },
1358   { 84, "Level[66]" },
1359   { 85, "Level[67]" },
1360   { 86, "Level[68]" },
1361   { 87, "Level[69]" },
1362   { 88, "Level[70]" },
1363   { 89, "Level[71]" },
1364   { 90, "Level[72]" },
1365   { 91, "Level[73]" },
1366   { 92, "Level[74]" },
1367   { 93, "Level[75]" },
1368   { 94, "Level[76]" },
1369   { 95, "Level[77]" },
1370   { 96, "Level[78]" },
1371   { 97, "Level[79]" },
1372   { 98, "Level[80]" },
1373   { 99, "Level[81]" },
1374   { 100, "Level[82]" },
1375   { 101, "Level[83]" },
1376   { 102, "Level[84]" },
1377   { 103, "Level[85]" },
1378   { 104, "Level[86]" },
1379   { 105, "Level[87]" },
1380   { 106, "Level[88]" },
1381   { 107, "Level[89]" },
1382   { 108, "Level[90]" },
1383   { 109, "Level[91]" },
1384   { 110, "Level[92]" },
1385   { 111, "Level[93]" },
1386   { 112, "Level[94]" },
1387   { 113, "Level[95]" },
1388   { 114, "Level[96]" },
1389   { 115, "Level[97]" },
1390   { 116, "Level[98]" },
1391   { 117, "Level[99]" },
1392   { 118, "Level[100]" },
1393   { 119, "Level[101]" },
1394   { 120, "Level[102]" },
1395   { 121, "Level[103]" },
1396   { 122, "Level[104]" },
1397   { 123, "Level[105]" },
1398   { 124, "Level[106]" },
1399   { 125, "Level[107]" },
1400   { 126, "Level[108]" },
1401   { 127, "Level[109]" },
1402   { 128, "Level[110]" },
1403   { 129, "Level[111]" },
1404   { 130, "Level[112]" },
1405   { 131, "Level[113]" },
1406   { 132, "Level[114]" },
1407   { 133, "Level[115]" },
1408   { 134, "Level[116]" },
1409   { 135, "Level[117]" },
1410   { 136, "Level[118]" },
1411   { 137, "Level[119]" },
1412   { 138, "Level[120]" },
1413   { 139, "Level[121]" },
1414   { 140, "Level[122]" },
1415   { 141, "Level[123]" },
1416   { 142, "Level[124]" },
1417   { 143, "Level[125]" },
1418   { 144, "Level[126]" },
1419   { 145, "Level[127]" },
1420   { 146, "Level[128]" },
1421   { 147, "Level[129]" },
1422   { 148, "Level[130]" },
1423   { 149, "Level[131]" },
1424   { 150, "Level[132]" },
1425   { 151, "Level[133]" },
1426   { 152, "Level[134]" },
1427   { 153, "Level[135]" },
1428   { 154, "Level[136]" },
1429   { 155, "Level[137]" },
1430   { 156, "Level[138]" },
1431   { 157, "Level[139]" },
1432   { 158, "Level[140]" },
1433   { 159, "Level[141]" },
1434   { 160, "Level[142]" },
1435   { 161, "Level[143]" },
1436   { 162, "Level[144]" },
1437   { 163, "Level[145]" },
1438   { 164, "Level[146]" },
1439   { 165, "Level[147]" },
1440   { 166, "Level[148]" },
1441   { 167, "Level[149]" },
1442   { 168, "Level[150]" },
1443   { 169, "Level[151]" },
1444   { 170, "Level[152]" },
1445   { 171, "Level[153]" },
1446   { 172, "Level[154]" },
1447   { 173, "Level[155]" },
1448   { 174, "Level[156]" },
1449   { 175, "Level[157]" },
1450   { 176, "Level[158]" },
1451   { 177, "Level[159]" },
1452   { 178, "Level[160]" },
1453   { 179, "Level[161]" },
1454   { 180, "Level[162]" },
1455   { 181, "Level[163]" },
1456   { 182, "Level[164]" },
1457   { 183, "Level[165]" },
1458   { 184, "Level[166]" },
1459   { 185, "Level[167]" },
1460   { 186, "Level[168]" },
1461   { 187, "Level[169]" },
1462   { 188, "Level[170]" },
1463   { 189, "Level[171]" },
1464   { 190, "Level[172]" },
1465   { 191, "Level[173]" },
1466   { 192, "Level[174]" },
1467   { 193, "Level[175]" },
1468   { 194, "Level[176]" },
1469   { 195, "Level[177]" },
1470   { 196, "Level[178]" },
1471   { 197, "Level[179]" },
1472   { 198, "Level[180]" },
1473   { 199, "Level[181]" },
1474   { 200, "Level[182]" },
1475   { 201, "Level[183]" },
1476   { 202, "Level[184]" },
1477   { 203, "Level[185]" },
1478   { 204, "Level[186]" },
1479   { 205, "Level[187]" },
1480   { 206, "Level[188]" },
1481   { 207, "Level[189]" },
1482   { 208, "Level[190]" },
1483   { 209, "Level[191]" },
1484   { 0, NULL }
1485 };
1486 static value_string_ext acn_blob_preset_properties_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_preset_properties_field_name);
1487
1488 static const value_string acn_blob_range_type_vals[] = {
1489   { ACN_BLOB_RANGE_MID, "Middle range Blob" },
1490   { ACN_BLOB_RANGE_START, "Start range Blob" },
1491   { ACN_BLOB_RANGE_END, "End Range Blob" },
1492   { ACN_BLOB_RANGE_SINGLE, "Single Blob" },
1493   { 0, NULL }
1494 };
1495
1496 static const value_string acn_blob_set_levels_operation_field_name[] = {
1497   { 1, "Start Dimmer Address" },
1498   { 2, "End Dimmer Address" },
1499   { 3, "DD Side" },
1500   { 4, "Space" },
1501   { 5, "Level" },
1502   { 0, NULL }
1503 };
1504
1505 static const value_string acn_blob_time2_field_name[] = {
1506   { 1, "Time" },
1507   { 2, "Time Zone Name" },
1508   { 3, "Time Zone Offset Hour" },
1509   { 4, "Time Zone Offset Min" },
1510   { 5, "Time Zone Offset Sec" },
1511   { 6, "DST Name" },
1512   { 7, "Start Month" },
1513   { 8, "Start Week" },
1514   { 9, "Start Day" },
1515   { 10, "End Month" },
1516   { 11, "End Week" },
1517   { 12, "End Day" },
1518   { 13, "Timed Event Update" },
1519   { 14, "Unix Time Zone Environment-compatible Name" },
1520   { 0, NULL }
1521 };
1522
1523 static const value_string acn_blob_rpc_field_name[] = {
1524   { 1, "Command" },
1525   { 2, "Transaction ID" },
1526   { 3, "Number of Arguments" },
1527   { 4, "Argument" },
1528   { 0, NULL }
1529 };
1530
1531 static const value_string acn_blob_dhcp_config_subnet_field_name[] = {
1532   { 1, "Command" },
1533   { 2, "Subnet" },
1534   { 3, "Netmask" },
1535   { 4, "Given Next Server" },
1536   { 5, "Given Router" },
1537   { 6, "Given Netmask" },
1538   { 7, "Default Lease Time" },
1539   { 8, "Max Lease Time" },
1540   { 9, "Given Domain Name" },
1541   { 10, "Given DNS Servers" },
1542   { 11, "Given NTP Server" },
1543   { 12, "Given Time Zone Offset Hour" },
1544   { 13, "Given Time Zone Offset Minute" },
1545   { 14, "Given Time Zone Offset Second" },
1546   { 15, "Given Time Zone DST Name" },
1547   { 16, "Given Time Zone Start Month" },
1548   { 17, "Given Time Zone Start Week" },
1549   { 18, "Given Time Zone Start Day" },
1550   { 19, "Given Time Zone End Month" },
1551   { 20, "Given Time Zone End Week" },
1552   { 21, "Given Time Zone End Day" },
1553   { 22, "Given UNIX Timezone Name" },
1554   { 0, NULL }
1555 };
1556
1557 static const value_string acn_blob_dhcp_config_static_route_field_name[] = {
1558   { 1, "Command" },
1559   { 2, "Subnet" },
1560   { 3, "Netmask" },
1561   { 4, "MAC Address" },
1562   { 5, "Host Name" },
1563   { 6, "Address" },
1564   { 0, NULL }
1565 };
1566
1567 static const value_string acn_blob_energy_management_field_name[] = {
1568   { 1, "Project ID" },
1569   { 2, "Space" },
1570   { 3, "Circuit Power Count" },
1571   { 4, "Circuit" },
1572   { 5, "Power" },
1573   { 6, "Shed Actual" },
1574   { 7, "Shed Potential" },
1575   { 0, NULL }
1576 };
1577
1578 static const value_string acn_blob_time3_field_name[] = {
1579   { 1, "Time" },
1580   { 2, "Time Zone Index" },
1581   { 3, "City" },
1582   { 4, "Country" },
1583   { 5, "Longitude" },
1584   { 6, "Latitude" },
1585   { 7, "UTC Offset Hours" },
1586   { 8, "UTC Offset Minutes" },
1587   { 9, "Time Zone Name" },
1588   { 10, "DST Type" },
1589   { 11, "DST Start Month" },
1590   { 12, "DST Start Week" },
1591   { 13, "DST Start Day" },
1592   { 14, "DST Start Hours" },
1593   { 15, "DST Start Minutes" },
1594   { 16, "DST Start Locality" },
1595   { 17, "DST Stop Month" },
1596   { 18, "DST Stop Week" },
1597   { 19, "DST Stop Day" },
1598   { 20, "DST Stop Hours" },
1599   { 21, "DST Stop Minutes" },
1600   { 22, "DST Stop Locality" },
1601   { 23, "Timed Event Update" },
1602   { 0, NULL }
1603 };
1604
1605 static const value_string acn_blob_time3_time_zone_vals[] = {
1606   { 0, "Aalborg, Denmark - Central European Standard Time : (UTC+01:00)" },
1607   { 1, "Aberdeen, United Kingdom - Greenwich Mean Time : (UTC)" },
1608   { 2, "Abu Dhabi, United Arab Emirates - Gulf Standard Time : (UTC+04:00)" },
1609   { 3, "Abuja, Nigeria - West Africa Time : (UTC+01:00)" },
1610   { 4, "Accra, Ghana - Greenwich Mean Time : (UTC)" },
1611   { 5, "Addis Ababa, Ethiopia - Eastern Africa Standard Time : (UTC+03:00)" },
1612   { 6, "Adelaide, SA, Australia - Australian Central Standard Time : (UTC+09:30)" },
1613   { 7, "Agana, GU, Guam - Chamorro Standard Time : (UTC+10:00)" },
1614   { 8, "Ahmadabad, India - India Standard Time : (UTC+05:30)" },
1615   { 9, "Akita, Japan - Japan Standard Time : (UTC+09:00)" },
1616   { 10, "Akron, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1617   { 11, "Albuquerque, NM, USA - Mountain Standard Time : (UTC-07:00)" },
1618   { 12, "Alexandria, VA, USA - Eastern Standard Time : (UTC-05:00)" },
1619   { 13, "Algiers, Algeria - Central European Standard Time : (UTC+01:00)" },
1620   { 14, "Allentown, PA, USA - Eastern Standard Time : (UTC-05:00)" },
1621   { 15, "Almaty, Kazakhstan - Alma-Ata Time : (UTC+06:00)" },
1622   { 16, "Amman, Jordan - Arabia Standard Time : (UTC+03:00)" },
1623   { 17, "Amsterdam, Netherlands - Central European Standard Time : (UTC+01:00)" },
1624   { 18, "Anaheim, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1625   { 19, "Anchorage, AK, USA - Alaska Standard Time : (UTC-09:00)" },
1626   { 20, "Andorra la Vella, Andorra - Central European Standard Time : (UTC+01:00)" },
1627   { 21, "Angers, France - Central European Standard Time : (UTC+01:00)" },
1628   { 22, "Ankara, Turkey - Eastern European Standard Time : (UTC+02:00)" },
1629   { 23, "Ann Arbor, MI, USA - Eastern Standard Time : (UTC-05:00)" },
1630   { 24, "Antananarivo, Madagascar - Eastern Africa Standard Time : (UTC+03:00)" },
1631   { 25, "Antwerp, Belgium - Central European Standard Time : (UTC+01:00)" },
1632   { 26, "Apia, Samoa - West Samoa Time : (UTC+14:00)" },
1633   { 27, "Ashgabat, Turkmenistan - Turkmenistan Time : (UTC+05:00)" },
1634   { 28, "Asmara, Eritrea - Eastern Africa Standard Time : (UTC+03:00)" },
1635   { 29, "Athens, Greece - Eastern European Standard Time : (UTC+02:00)" },
1636   { 30, "Atlanta, GA, USA - Eastern Standard Time : (UTC-05:00)" },
1637   { 31, "Auckland, New Zealand - New Zealand Standard Time : (UTC+12:00)" },
1638   { 32, "Austin, TX, USA - Central Standard Time : (UTC-06:00)" },
1639   { 33, "Badajoz, Spain - Central European Standard Time : (UTC+01:00)" },
1640   { 34, "Baghdad, Iraq - Arabia Standard Time : (UTC+03:00)" },
1641   { 35, "Bakersfield, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1642   { 36, "Baku, Azerbaijan - Azerbaijan Time : (UTC+04:00)" },
1643   { 37, "Baltimore, MD, USA - Eastern Standard Time : (UTC-05:00)" },
1644   { 38, "Bamako, Mali - Greenwich Mean Time : (UTC)" },
1645   { 39, "Bandar Seri Begawan, Brunei - Brunei Darussalam Time : (UTC+08:00)" },
1646   { 40, "Bangalore, India - India Standard Time : (UTC+05:30)" },
1647   { 41, "Bangkok, Thailand - Indochina Time : (UTC+07:00)" },
1648   { 42, "Bangui, Central African Republic - West Africa Time : (UTC+01:00)" },
1649   { 43, "Banjul, Gambia - Greenwich Mean Time : (UTC)" },
1650   { 44, "Barcelona, Spain - Central European Standard Time : (UTC+01:00)" },
1651   { 45, "Bari, Italy - Central European Standard Time : (UTC+01:00)" },
1652   { 46, "Baton Rouge, LA, USA - Central Standard Time : (UTC-06:00)" },
1653   { 47, "Beaumont, TX, USA - Central Standard Time : (UTC-06:00)" },
1654   { 48, "Beijing, China - China Standard Time : (UTC+08:00)" },
1655   { 49, "Beirut, Lebanon - Eastern European Standard Time : (UTC+02:00)" },
1656   { 50, "Belem, Brazil - Brasilia Time : (UTC-03:00)" },
1657   { 51, "Belfast, United Kingdom - Greenwich Mean Time : (UTC)" },
1658   { 52, "Belgrade, Serbia - Central European Standard Time : (UTC+01:00)" },
1659   { 53, "Belmopan, Belize - Central Standard Time : (UTC-06:00)" },
1660   { 54, "Belo Horizonte, Brazil - Brasilia Time : (UTC-03:00)" },
1661   { 55, "Bergen, Norway - Central European Standard Time : (UTC+01:00)" },
1662   { 56, "Berkeley, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1663   { 57, "Berlin, Germany - Central European Standard Time : (UTC+01:00)" },
1664   { 58, "Bern, Switzerland - Central European Standard Time : (UTC+01:00)" },
1665   { 59, "Birmingham, AL, USA - Central Standard Time : (UTC-06:00)" },
1666   { 60, "Birmingham, United Kingdom - Greenwich Mean Time : (UTC)" },
1667   { 61, "Bishkek, Kyrgyzstan - Kyrgyzstan Time : (UTC+06:00)" },
1668   { 62, "Bissau, Guinea-Bissau - Greenwich Mean Time : (UTC)" },
1669   { 63, "Boise, ID, USA - Mountain Standard Time : (UTC-07:00)" },
1670   { 64, "Bologna, Italy - Central European Standard Time : (UTC+01:00)" },
1671   { 65, "Bonn, Germany - Central European Standard Time : (UTC+01:00)" },
1672   { 66, "Bordeaux, France - Central European Standard Time : (UTC+01:00)" },
1673   { 67, "Boston, MA, USA - Eastern Standard Time : (UTC-05:00)" },
1674   { 68, "Bournemouth, United Kingdom - Greenwich Mean Time : (UTC)" },
1675   { 69, "Brasilia, Brazil - Brasilia Time : (UTC-03:00)" },
1676   { 70, "Bratislava, Slovakia - Central European Standard Time : (UTC+01:00)" },
1677   { 71, "Brazzaville, Republic of the Congo - West Africa Time : (UTC+01:00)" },
1678   { 72, "Bremen, Germany - Central European Standard Time : (UTC+01:00)" },
1679   { 73, "Brest, France - Central European Standard Time : (UTC+01:00)" },
1680   { 74, "Bridgeport, CT, USA - Eastern Standard Time : (UTC-05:00)" },
1681   { 75, "Bridgetown, Barbados - Atlantic Standard Time : (UTC-04:00)" },
1682   { 76, "Brisbane, QLD, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
1683   { 77, "Brno, Czech Republic - Central European Standard Time : (UTC+01:00)" },
1684   { 78, "Brussels, Belgium - Central European Standard Time : (UTC+01:00)" },
1685   { 79, "Bucharest, Romania - Eastern European Standard Time : (UTC+02:00)" },
1686   { 80, "Budapest, Hungary - Central European Standard Time : (UTC+01:00)" },
1687   { 81, "Buenos Aires, Argentina - Argentina Time : (UTC-03:00)" },
1688   { 82, "Buffalo, NY, USA - Eastern Standard Time : (UTC-05:00)" },
1689   { 83, "Bujumbura, Burundi - South Africa Standard Time : (UTC+02:00)" },
1690   { 84, "Cagliari, Italy - Central European Standard Time : (UTC+01:00)" },
1691   { 85, "Cairo, Egypt - Eastern European Standard Time : (UTC+02:00)" },
1692   { 86, "Calgary, AB, Canada - Mountain Standard Time : (UTC-07:00)" },
1693   { 87, "Cali, Colombia - Colombia Time : (UTC-05:00)" },
1694   { 88, "Canberra, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
1695   { 89, "Cape Town, South Africa - South Africa Standard Time : (UTC+02:00)" },
1696   { 90, "Caracas, Venezuela - Venezuelan Standard Time : (UTC-04:30)" },
1697   { 91, "Cardiff, United Kingdom - Greenwich Mean Time : (UTC)" },
1698   { 92, "Cedar Rapids, IA, USA - Central Standard Time : (UTC-06:00)" },
1699   { 93, "Charlotte, NC, USA - Eastern Standard Time : (UTC-05:00)" },
1700   { 94, "Charlottetown, PE, Canada - Atlantic Standard Time : (UTC-04:00)" },
1701   { 95, "Chatham Islands, Chatham Islands, New Zealand - Chatham Island Standard Time : (UTC+12:45)" },
1702   { 96, "Chengdu, China - China Standard Time : (UTC+08:00)" },
1703   { 97, "Chennai, India - India Standard Time : (UTC+05:30)" },
1704   { 98, "Chiba, Japan - Japan Standard Time : (UTC+09:00)" },
1705   { 99, "Chicago, IL, USA - Central Standard Time : (UTC-06:00)" },
1706   { 100, "Chisinau, Moldova - Eastern European Standard Time : (UTC+02:00)" },
1707   { 101, "Chongqing, China - China Standard Time : (UTC+08:00)" },
1708   { 102, "Cincinnati, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1709   { 103, "Cleveland, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1710   { 104, "Colorado Springs, CO, USA - Mountain Standard Time : (UTC-07:00)" },
1711   { 105, "Columbus, GA, USA - Eastern Standard Time : (UTC-05:00)" },
1712   { 106, "Columbus, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1713   { 107, "Conakry, Guinea - Greenwich Mean Time : (UTC)" },
1714   { 108, "Copenhagen, Denmark - Central European Standard Time : (UTC+01:00)" },
1715   { 109, "Cork, Ireland - Greenwich Mean Time : (UTC)" },
1716   { 110, "Corpus Christi, TX, USA - Central Standard Time : (UTC-06:00)" },
1717   { 111, "Curitiba, Brazil - Brasilia Time : (UTC-03:00)" },
1718   { 112, "Dakar, Senegal - Greenwich Mean Time : (UTC)" },
1719   { 113, "Dallas, TX, USA - Central Standard Time : (UTC-06:00)" },
1720   { 114, "Damascus, Syria - Eastern European Standard Time : (UTC+02:00)" },
1721   { 115, "Dar es Salaam, Tanzania - Eastern Africa Standard Time : (UTC+03:00)" },
1722   { 116, "Darwin, NT, Australia - Australian Central Standard Time : (UTC+09:30)" },
1723   { 117, "Dayton, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1724   { 118, "Delhi, India - India Standard Time : (UTC+05:30)" },
1725   { 119, "Denver, CO, USA - Mountain Standard Time : (UTC-07:00)" },
1726   { 120, "Des Moines, IA, USA - Central Standard Time : (UTC-06:00)" },
1727   { 121, "Detroit, MI, USA - Eastern Standard Time : (UTC-05:00)" },
1728   { 122, "Dhaka, Bangladesh - Central Asia Standard Time : (UTC+06:00)" },
1729   { 123, "Dijon, France - Romance Standard Time : (UTC+01:00)" },
1730   { 124, "Djibouti, Djibouti - Eastern Africa Standard Time : (UTC+03:00)" },
1731   { 125, "Doha, Qatar - Arabia Standard Time : (UTC+03:00)" },
1732   { 126, "Dortmund, Germany - Central European Standard Time : (UTC+01:00)" },
1733   { 127, "Dresden, Germany - Central European Standard Time : (UTC+01:00)" },
1734   { 128, "Dublin, Ireland - Greenwich Mean Time : (UTC)" },
1735   { 129, "Dushanbe, Tajikistan - Tajikistan Time : (UTC+05:00)" },
1736   { 130, "Dusseldorf, Germany - Central European Standard Time : (UTC+01:00)" },
1737   { 131, "Edinburgh, United Kingdom - Greenwich Mean Time : (UTC)" },
1738   { 132, "Edmonton, AB, Canada - Mountain Standard Time : (UTC-07:00)" },
1739   { 133, "El Paso, TX, USA - Mountain Standard Time : (UTC-07:00)" },
1740   { 134, "Erfurt, Germany - Central European Standard Time : (UTC+01:00)" },
1741   { 135, "Eucla, WA, Australia - Australian Central Western Standard Time  : (UTC+08:45)" },
1742   { 136, "Eugene, OR, USA - Pacific Standard Time : (UTC-08:00)" },
1743   { 137, "Evansville, IN, USA - Eastern Standard Time : (UTC-05:00)" },
1744   { 138, "Florence, Italy - Central European Standard Time : (UTC+01:00)" },
1745   { 139, "Fort Defiance, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
1746   { 140, "Fort Lauderdale, FL, USA - Eastern Standard Time : (UTC-05:00)" },
1747   { 141, "Fort Wayne, IN, USA - Eastern Standard Time : (UTC-05:00)" },
1748   { 142, "Fort Worth, TX, USA - Central Standard Time : (UTC-06:00)" },
1749   { 143, "Fortaleza, Brazil - Brasilia Time : (UTC-03:00)" },
1750   { 144, "Frankfurt, Germany - Central European Standard Time : (UTC+01:00)" },
1751   { 145, "Freetown, Sierra Leone - Greenwich Mean Time : (UTC)" },
1752   { 146, "Freiburg, Germany - Central European Standard Time : (UTC+01:00)" },
1753   { 147, "Fremont, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1754   { 148, "Fresno, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1755   { 149, "Fukuoka, Japan - Japan Standard Time : (UTC+09:00)" },
1756   { 150, "Gaborone, Botswana - Central Africa Time : (UTC+02:00)" },
1757   { 151, "Galway, Ireland - Greenwich Mean Time : (UTC)" },
1758   { 152, "Geneva, Switzerland - Central European Standard Time : (UTC+01:00)" },
1759   { 153, "Genova, Italy - Central European Standard Time : (UTC+01:00)" },
1760   { 154, "George Town, Cayman Islands - Eastern Standard Time : (UTC-05:00)" },
1761   { 155, "Georgetown, Guyana - Guyana Time : (UTC-04:00)" },
1762   { 156, "Glasgow, United Kingdom - Greenwich Mean Time : (UTC)" },
1763   { 157, "Glendale, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1764   { 158, "Granada, Spain - Central European Standard Time : (UTC+01:00)" },
1765   { 159, "Grand Rapids, MI, USA - Eastern Standard Time : (UTC-05:00)" },
1766   { 160, "Guadalajara, Mexico - Central Standard Time : (UTC-06:00)" },
1767   { 161, "Guangzhou, China - China Standard Time : (UTC+08:00)" },
1768   { 162, "Guatemala City, Guatemala - Central Standard Time : (UTC-06:00)" },
1769   { 163, "Haikou, China - China Standard Time : (UTC+08:00)" },
1770   { 164, "Halifax, NS, Canada - Atlantic Standard Time : (UTC-04:00)" },
1771   { 165, "Hamburg, Germany - Central European Standard Time : (UTC+01:00)" },
1772   { 166, "Hamilton, Bermuda - Atlantic Standard Time : (UTC-04:00)" },
1773   { 167, "Hannover, Germany - Central European Standard Time : (UTC+01:00)" },
1774   { 168, "Hanoi, Vietnam - Indochina Time : (UTC+07:00)" },
1775   { 169, "Harare, Zimbabwe - Central Africa Time : (UTC+02:00)" },
1776   { 170, "Harbin, China - China Standard Time : (UTC+08:00)" },
1777   { 171, "Hartford, CT, USA - Eastern Standard Time : (UTC-05:00)" },
1778   { 172, "Havana, Cuba - Cuba Standard Time : (UTC-05:00)" },
1779   { 173, "Helsinki, Finland - Eastern European Standard Time : (UTC+02:00)" },
1780   { 174, "Hiroshima, Japan - Japan Standard Time : (UTC+09:00)" },
1781   { 175, "Hobart, TAS, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
1782   { 176, "Hong Kong SAR, China - China Standard Time : (UTC+08:00)" },
1783   { 177, "Honiara, Solomon Islands - Solomon Islands Time : (UTC+11:00)" },
1784   { 178, "Honolulu, HI, USA - Hawaii-Aleutian Standard Time : (UTC-10:00)" },
1785   { 179, "Houston, TX, USA - Central Standard Time : (UTC-06:00)" },
1786   { 180, "Hull, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
1787   { 181, "Huntsville, AL, USA - Central Standard Time : (UTC-06:00)" },
1788   { 182, "Indianapolis, IN, USA - Eastern Standard Time : (UTC-05:00)" },
1789   { 183, "Irkutsk, Russia - Irkutsk Time : (UTC+08:00)" },
1790   { 184, "Islamabad, Pakistan - Pakistan Standard Time : (UTC+05:00)" },
1791   { 185, "Istanbul, Turkey - Eastern European Standard Time : (UTC+02:00)" },
1792   { 186, "Jackson, MS, USA - Central Standard Time : (UTC-06:00)" },
1793   { 187, "Jacksonville, FL, USA - Eastern Standard Time : (UTC-05:00)" },
1794   { 188, "Jakarta, Indonesia - Western Indonesian Time : (UTC+07:00)" },
1795   { 189, "Jerusalem, Israel - Israel Standard Time : (UTC+02:00)" },
1796   { 190, "Kabul, Afghanistan - Afghanistan Standard Time : (UTC+04:30)" },
1797   { 191, "Kampala, Uganda - Eastern Africa Standard Time : (UTC+03:00)" },
1798   { 192, "Kanazawa, Japan - Japan Standard Time : (UTC+09:00)" },
1799   { 193, "Kansas City, KS, USA - Central Standard Time : (UTC-06:00)" },
1800   { 194, "Kansas City, MO, USA - Central Standard Time : (UTC-06:00)" },
1801   { 195, "Karachi, Pakistan - Pakistan Standard Time : (UTC+05:00)" },
1802   { 196, "Kathmandu, Nepal - Nepal Standard Time : (UTC+05:45)" },
1803   { 197, "Kelowna, BC, Canada - Pacific Standard Time : (UTC-08:00)" },
1804   { 198, "Khartoum, Sudan - Eastern Africa Standard Time : (UTC+03:00)" },
1805   { 199, "Kiev, Ukraine - Eastern European Standard Time : (UTC+02:00)" },
1806   { 200, "Kigali, Rwanda - Central Africa Time : (UTC+02:00)" },
1807   { 201, "Kingston, Jamaica - Eastern Standard Time : (UTC-05:00)" },
1808   { 202, "Kingston, Norfolk Island - Norfolk Time : (UTC+11:30)" },
1809   { 203, "Kinshasa, Democratic Republic of the Congo - West Africa Time : (UTC+01:00)" },
1810   { 204, "Kiritimati, Christmas Island, Kiribati - Line Islands Time : (UTC+14:00)" },
1811   { 205, "Knoxville, TN, USA - Eastern Standard Time : (UTC-05:00)" },
1812   { 206, "Kobe, Japan - Japan Standard Time : (UTC+09:00)" },
1813   { 207, "Kochi, Japan - Japan Standard Time : (UTC+09:00)" },
1814   { 208, "Kolkata (Calcutta), India - India Standard Time : (UTC+05:30)" },
1815   { 209, "Krasnoyarsk, Russia - Krasnoyarsk Time : (UTC+07:00)" },
1816   { 210, "Kuala Lumpur, Malaysia - Singapore Standard Time : (UTC+08:00)" },
1817   { 211, "Kuwait, Kuwait - Arabia Standard Time : (UTC+03:00)" },
1818   { 212, "Kwangju, Korea - Korea Standard Time : (UTC+09:00)" },
1819   { 213, "Kyoto, Japan - Japan Standard Time : (UTC+09:00)" },
1820   { 214, "La Paz, Bolivia - Bolivia Time : (UTC-04:00)" },
1821   { 215, "Lansing, MI, USA - Eastern Standard Time : (UTC-05:00)" },
1822   { 216, "Laredo, TX, USA - Central Standard Time : (UTC-06:00)" },
1823   { 217, "Las Vegas, NV, USA - Pacific Standard Time : (UTC-08:00)" },
1824   { 218, "Leipzig, Germany - Central European Standard Time : (UTC+01:00)" },
1825   { 219, "Lexington, KY, USA - Eastern Standard Time : (UTC-05:00)" },
1826   { 220, "Lhasa, China - China Standard Time : (UTC+08:00)" },
1827   { 221, "Libreville, Gabon - West Africa Time : (UTC+01:00)" },
1828   { 222, "Lille, France - Central European Standard Time : (UTC+01:00)" },
1829   { 223, "Lilongwe, Malawi - Central Africa Time : (UTC+02:00)" },
1830   { 224, "Lima, Peru - Peru Time : (UTC-05:00)" },
1831   { 225, "Limerick, Ireland - Greenwich Mean Time : (UTC)" },
1832   { 226, "Limoges, France - Central European Standard Time : (UTC+01:00)" },
1833   { 227, "Lincoln, NE, USA - Central Standard Time : (UTC-06:00)" },
1834   { 228, "Lisbon, Portugal - Greenwich Mean Time : (UTC)" },
1835   { 229, "Little Rock, AR, USA - Central Standard Time : (UTC-06:00)" },
1836   { 230, "Liverpool, United Kingdom - Greenwich Mean Time : (UTC)" },
1837   { 231, "Ljubljana, Slovenia - Central European Standard Time : (UTC+01:00)" },
1838   { 232, "London, United Kingdom - Greenwich Mean Time : (UTC)" },
1839   { 233, "Londonderry, United Kingdom - Greenwich Mean Time : (UTC)" },
1840   { 234, "Long Beach, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1841   { 235, "Lord Howe Island, Lord Howe Island, Australia - Lord Howe Standard Time : (UTC+10:30)" },
1842   { 236, "Los Angeles, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1843   { 237, "Louisville, KY, USA - Eastern Standard Time : (UTC-05:00)" },
1844   { 238, "Luanda, Angola - West Africa Time : (UTC+01:00)" },
1845   { 239, "Lubbock, TX, USA - Central Standard Time : (UTC-06:00)" },
1846   { 240, "Lusaka, Zambia - Central Africa Time : (UTC+02:00)" },
1847   { 241, "Luxembourg, Luxembourg - Central European Standard Time : (UTC+01:00)" },
1848   { 242, "Lyon, France - Central European Standard Time : (UTC+01:00)" },
1849   { 243, "Madison, WI, USA - Central Standard Time : (UTC-06:00)" },
1850   { 244, "Madrid, Spain - Central European Standard Time : (UTC+01:00)" },
1851   { 245, "Malabo, Equatorial Guinea - West Africa Time : (UTC+01:00)" },
1852   { 246, "Malaga, Spain - Central European Standard Time : (UTC+01:00)" },
1853   { 247, "Managua, Nicaragua - Central Standard Time : (UTC-06:00)" },
1854   { 248, "Manama, Bahrain - Arabia Standard Time : (UTC+03:00)" },
1855   { 249, "Manaus, Brazil - Amazon Time : (UTC-04:00)" },
1856   { 250, "Manchester, United Kingdom - Greenwich Mean Time : (UTC)" },
1857   { 251, "Manila, Philippines - Philippine Time : (UTC+08:00)" },
1858   { 252, "Maputo, Mozambique - Central Africa Time : (UTC+02:00)" },
1859   { 253, "Maracaibo, Venezuela - Venezuelan Standard Time : (UTC-04:30)" },
1860   { 254, "Marseille, France - Central European Standard Time : (UTC+01:00)" },
1861   { 255, "Maseru, Lesotho - South Africa Standard Time : (UTC+02:00)" },
1862   { 256, "Masqat, Oman - Gulf Standard Time : (UTC+04:00)" },
1863   { 257, "Mbabane, Swaziland - South Africa Standard Time : (UTC+02:00)" },
1864   { 258, "Medellin, Colombia - Colombia Time : (UTC-05:00)" },
1865   { 259, "Melbourne, VIC, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
1866   { 260, "Memphis, TN, USA - Central Standard Time : (UTC-06:00)" },
1867   { 261, "Metz, France - Central European Standard Time : (UTC+01:00)" },
1868   { 262, "Mexico City, Mexico - Central Standard Time : (UTC-06:00)" },
1869   { 263, "Miami, FL, USA - Eastern Standard Time : (UTC-05:00)" },
1870   { 264, "Milan, Italy - Central European Standard Time : (UTC+01:00)" },
1871   { 265, "Milwaukee, WI, USA - Central Standard Time : (UTC-06:00)" },
1872   { 266, "Minneapolis, MN, USA - Central Standard Time : (UTC-06:00)" },
1873   { 267, "Minsk, Belarus - Further-Eastern European Time : (UTC+03:00)" },
1874   { 268, "Mobile, AL, USA - Central Standard Time : (UTC-06:00)" },
1875   { 269, "Mogadishu, Somalia - Eastern Africa Standard Time : (UTC+03:00)" },
1876   { 270, "Monaco, Monaco - Central European Standard Time : (UTC+01:00)" },
1877   { 271, "Monrovia, Liberia - Greenwich Mean Time : (UTC)" },
1878   { 272, "Monterrey, Mexico - Central Standard Time : (UTC-06:00)" },
1879   { 273, "Montevideo, Uruguay - Uruguay Time : (UTC-03:00)" },
1880   { 274, "Montreal, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
1881   { 275, "Morioka, Japan - Japan Standard Time : (UTC+09:00)" },
1882   { 276, "Moscow, Russia - Moscow Standard Time : (UTC+03:00)" },
1883   { 277, "Mumbai, India - India Standard Time : (UTC+05:30)" },
1884   { 278, "Munich, Germany - Central European Standard Time : (UTC+01:00)" },
1885   { 279, "Murmansk, Russia - Moscow Standard Time : (UTC+03:00)" },
1886   { 280, "N'Djamena, Chad - West Africa Time : (UTC+01:00)" },
1887   { 281, "Nagano, Japan - Japan Standard Time : (UTC+09:00)" },
1888   { 282, "Nagasaki, Japan - Japan Standard Time : (UTC+09:00)" },
1889   { 283, "Nagoya, Japan - Japan Standard Time : (UTC+09:00)" },
1890   { 284, "Nairobi, Kenya - Eastern Africa Standard Time : (UTC+03:00)" },
1891   { 285, "Nanjing, China - China Standard Time : (UTC+08:00)" },
1892   { 286, "Naples, Italy - Central European Standard Time : (UTC+01:00)" },
1893   { 287, "Nashville, TN, USA - Central Standard Time : (UTC-06:00)" },
1894   { 288, "Nassau, Bahamas - Eastern Standard Time : (UTC-05:00)" },
1895   { 289, "New Orleans, LA, USA - Central Standard Time : (UTC-06:00)" },
1896   { 290, "New York, NY, USA - Eastern Standard Time : (UTC-05:00)" },
1897   { 291, "Newark, NJ, USA - Eastern Standard Time : (UTC-05:00)" },
1898   { 292, "Niamey, Niger - West Africa Time : (UTC+01:00)" },
1899   { 293, "Nicosia, Cyprus - Eastern European Standard Time : (UTC+02:00)" },
1900   { 294, "Norwich, United Kingdom - Greenwich Mean Time : (UTC)" },
1901   { 295, "Nouakchott, Mauritania - Greenwich Mean Time : (UTC)" },
1902   { 296, "Novosibirsk, Russia - Novosibirsk Time : (UTC+06:00)" },
1903   { 297, "Nuku'alofa, Tonga - Tonga Standard Time : (UTC+13:00)" },
1904   { 298, "Nuuk, Greenland - West Greenland Time : (UTC-03;00)" },
1905   { 299, "Oakland, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1906   { 300, "Oklahoma City, OK, USA - Central Standard Time : (UTC-06:00)" },
1907   { 301, "Omaha, NE, USA - Central Standard Time : (UTC-06:00)" },
1908   { 302, "Orlando, FL, USA - Eastern Standard Time : (UTC-05:00)" },
1909   { 303, "Osaka, Japan - Japan Standard Time : (UTC+09:00)" },
1910   { 304, "Oshawa, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
1911   { 305, "Oslo, Norway - Central European Standard Time : (UTC+01:00)" },
1912   { 306, "Ottawa, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
1913   { 307, "Ouagadougou, Burkina Faso - Greenwich Mean Time : (UTC)" },
1914   { 308, "Overland Park, KS, USA - Central Standard Time : (UTC-06:00)" },
1915   { 309, "Oviedo, Spain - Central European Standard Time : (UTC+01:00)" },
1916   { 310, "Palermo, Italy - Central European Standard Time : (UTC+01:00)" },
1917   { 311, "Palma de Mallorca, Spain - Central European Standard Time : (UTC+01:00)" },
1918   { 312, "Panama City, Panama - Eastern Standard Time : (UTC-05:00)" },
1919   { 313, "Paramaribo, Surinam - Suriname Time : (UTC-03:00)" },
1920   { 314, "Paris, France - Central European Standard Time : (UTC+01:00)" },
1921   { 315, "Pasadena, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1922   { 316, "Pasadena, TX, USA - Central Standard Time : (UTC-06:00)" },
1923   { 317, "Peoria, IL, USA - Central Standard Time : (UTC-06:00)" },
1924   { 318, "Perth, WA, Australia - Australia Western Standard Time : (UTC+08:00)" },
1925   { 319, "Perugia, Italy - Central European Standard Time : (UTC+01:00)" },
1926   { 320, "Philadelphia, PA, USA - Eastern Standard Time : (UTC-05:00)" },
1927   { 321, "Phnom Penh, Cambodia - Indochina Time : (UTC+07:00)" },
1928   { 322, "Phoenix, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
1929   { 323, "Pisa, Italy - Central European Standard Time : (UTC+01:00)" },
1930   { 324, "Pittsburgh, PA, USA - Eastern Standard Time : (UTC-05:00)" },
1931   { 325, "Plymouth, United Kingdom - Greenwich Mean Time : (UTC)" },
1932   { 326, "Port Louis, Mauritius - Mauritius Time : (UTC+04:00)" },
1933   { 327, "Port Moresby, Papua New Guinea - Papua New Guinea Time : (UTC+10:00)" },
1934   { 328, "Port-au-Prince, Haiti - Eastern Standard Time : (UTC-05:00)" },
1935   { 329, "Port-of-Spain, Trinidad and Tobago - Atlantic Standard Time : (UTC-04:00)" },
1936   { 330, "Portland, OR, USA - Pacific Standard Time : (UTC-08:00)" },
1937   { 331, "Porto Alegre, Brazil - Brasilia Time : (UTC-03:00)" },
1938   { 332, "Porto, Portugal - Western European Time : (UTC)" },
1939   { 333, "Porto-Novo, Benin - West Africa Time : (UTC+01:00)" },
1940   { 334, "Prague, Czech Republic - Central European Standard Time : (UTC+01:00)" },
1941   { 335, "Praia, Cape Verde - Cape Verde Time : (UTC-01:00)" },
1942   { 336, "Pretoria, South Africa - South Africa Standard Time : (UTC+02:00)" },
1943   { 337, "Providence, RI, USA - Eastern Standard Time : (UTC-05:00)" },
1944   { 338, "Puebla de Zaragoza, Mexico - Eastern Standard Time : (UTC-05:00)" },
1945   { 339, "Pusan, Korea - Korea Standard Time : (UTC+09:00)" },
1946   { 340, "Pyongyang, North Korea - Korea Standard Time : (UTC+09:00)" },
1947   { 341, "Quebec City, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
1948   { 342, "Quito, Ecuador - Ecuador Time : (UTC-05:00)" },
1949   { 343, "Rabat, Morocco - Western European Time : (UTC)" },
1950   { 344, "Raleigh, NC, USA - Eastern Standard Time : (UTC-05:00)" },
1951   { 345, "Recife, Brazil - Brasilia Time : (UTC-03:00)" },
1952   { 346, "Redmond, WA, USA - Pacific Standard Time : (UTC-08:00)" },
1953   { 347, "Reggio Calabria, Italy - Central European Standard Time : (UTC+01:00)" },
1954   { 348, "Regina, SK, Canada - Central Standard Time : (UTC-06:00)" },
1955   { 349, "Richmond, VA, USA - Eastern Standard Time : (UTC-05:00)" },
1956   { 350, "Riga, Latvia - Eastern European Standard Time : (UTC+02:00)" },
1957   { 351, "Rio de Janeiro, Brazil - Brasilia Time : (UTC-03:00)" },
1958   { 352, "Riyadh, Saudi Arabia - Arabia Standard Time : (UTC+03:00)" },
1959   { 353, "Rockford, IL, USA - Central Standard Time : (UTC-06:00)" },
1960   { 354, "Rome, Italy - Central European Standard Time : (UTC+01:00)" },
1961   { 355, "Roseau, Dominica - Atlantic Standard Time : (UTC-04:00)" },
1962   { 356, "Roswell, NM, USA - Mountain Standard Time : (UTC-07:00)" },
1963   { 357, "Rouen, France - Central European Standard Time : (UTC+01:00)" },
1964   { 358, "Sacramento, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1965   { 359, "Saint John, NB, Canada - Atlantic Standard Time : (UTC-04:00)" },
1966   { 360, "Saint Louis, MO, USA - Central Standard Time : (UTC-06:00)" },
1967   { 361, "Saint Paul, MN, USA - Central Standard Time : (UTC-06:00)" },
1968   { 362, "Salt Lake City, UT, USA - Mountain Standard Time : (UTC-07:00)" },
1969   { 363, "Salvador, Brazil - Brasilia Time : (UTC-03:00)" },
1970   { 364, "Salzburg, Austria - Central European Standard Time : (UTC+01:00)" },
1971   { 365, "San Antonio, TX, USA - Central Standard Time : (UTC-06:00)" },
1972   { 366, "San Bernardino, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1973   { 367, "San Diego, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1974   { 368, "San Francisco, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1975   { 369, "San Jose, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1976   { 370, "San Salvador, El Salvador - Central Standard Time : (UTC-06:00)" },
1977   { 371, "Sana'a, Yemen - Arabia Standard Time : (UTC+03:00)" },
1978   { 372, "Santa Ana, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1979   { 373, "Santa Rosa, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1980   { 374, "Santander, Spain - Central European Standard Time : (UTC+01:00)" },
1981   { 375, "Santiago, Chile - Chile Standard Time : (UTC-04:00)" },
1982   { 376, "Santo Domingo, Dominican Republic - Atlantic Standard Time : (UTC-04:00)" },
1983   { 377, "Sao Paulo, Brazil - Brasilia Time : (UTC-03:00)" },
1984   { 378, "Sapporo, Japan - Japan Standard Time : (UTC+09:00)" },
1985   { 379, "Sarajevo, Bosnia and Herzegovina - Central European Standard Time : (UTC+01:00)" },
1986   { 380, "Saskatoon, SK, Canada - Central Standard Time : (UTC-06:00)" },
1987   { 381, "Savannah, GA, USA - Eastern Standard Time : (UTC-05:00)" },
1988   { 382, "Seattle, WA, USA - Pacific Standard Time : (UTC-08:00)" },
1989   { 383, "Sendai, Japan - Japan Standard Time : (UTC+09:00)" },
1990   { 384, "Seoul, Korea - Korea Standard Time : (UTC+09:00)" },
1991   { 385, "Sevilla, Spain - Central European Standard Time : (UTC+01:00)" },
1992   { 386, "Shanghai, China - China Standard Time : (UTC+08:00)" },
1993   { 387, "Shreveport, LA, USA - Central Standard Time : (UTC-06:00)" },
1994   { 388, "Simi Valley, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1995   { 389, "Singapore, Singapore - Singapore Standard Time : (UTC+08:00)" },
1996   { 390, "Sioux Falls, SD, USA - Central Standard Time : (UTC-06:00)" },
1997   { 391, "Skopje, F.Y.R.O. Macedonia - Central European Standard Time : (UTC+01:00)" },
1998   { 392, "Sofia, Bulgaria - Eastern European Standard Time : (UTC+02:00)" },
1999   { 393, "South Bend, IN, USA - Eastern Standard Time : (UTC-05:00)" },
2000   { 394, "Spokane, WA, USA - Pacific Standard Time : (UTC-08:00)" },
2001   { 395, "Springfield, IL, USA - Central Standard Time : (UTC-06:00)" },
2002   { 396, "Springfield, MA, USA - Eastern Standard Time : (UTC-05:00)" },
2003   { 397, "Springfield, MO, USA - Central Standard Time : (UTC-06:00)" },
2004   { 398, "Sri Jayawardenepura, Sri Lanka - India Standard Time : (UTC+05:30)" },
2005   { 399, "St. Catharines, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2006   { 400, "St. John's, NF, Canada - Newfoundland Standard Time : (UTC-03:30)" },
2007   { 401, "St. Petersburg, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2008   { 402, "St. Petersburg, Russia - Moscow Standard Time : (UTC+03:00)" },
2009   { 403, "Stockholm, Sweden - Central European Standard Time : (UTC+01:00)" },
2010   { 404, "Stockton, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2011   { 405, "Strasbourg, France - Central European Standard Time : (UTC+01:00)" },
2012   { 406, "Stuttgart, Germany - Central European Standard Time : (UTC+01:00)" },
2013   { 407, "Sucre, Bolivia - Bolivia Time : (UTC-04:00)" },
2014   { 408, "Sunnyvale, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2015   { 409, "Suva, Fiji Islands - Fiji Standard Time : (UTC+12:00)" },
2016   { 410, "Sydney, NSW, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
2017   { 411, "Syracuse, NY, USA - Eastern Standard Time : (UTC-05:00)" },
2018   { 412, "T'bilisi, Georgia - Georgia Standard Time : (UTC+04:00)" },
2019   { 413, "Taejon, Korea - Korea Standard Time : (UTC+09:00)" },
2020   { 414, "Taiohae, Marquesas Islands,  French Polynesia - Marquesas Time : (UTC-9:30)" },
2021   { 415, "Taipei, Taiwan - China Standard Time : (UTC+08:00)" },
2022   { 416, "Tallinn, Estonia - Eastern European Standard Time : (UTC+02:00)" },
2023   { 417, "Tampa, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2024   { 418, "Taranto, Italy - Central European Standard Time : (UTC+01:00)" },
2025   { 419, "Tashkent, Uzbekistan - Uzbekistan Time : (UTC+05:00)" },
2026   { 420, "Tegucigalpa, Honduras - Central Standard Time : (UTC-06:00)" },
2027   { 421, "Tehran, Iran - Iran Standard Time : (UTC+03:30)" },
2028   { 422, "Tel Aviv, Israel - Israel Standard Time : (UTC+02:00)" },
2029   { 423, "The Hague, Netherlands - Central European Standard Time : (UTC+01:00)" },
2030   { 424, "Thimphu, Bhutan - Bhutan Time : (UTC+06:00)" },
2031   { 425, "Thunder Bay, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2032   { 426, "Tirana, Albania - Central European Standard Time : (UTC+01:00)" },
2033   { 427, "Tokyo, Japan - Japan Standard Time : (UTC+09:00)" },
2034   { 428, "Toledo, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2035   { 429, "Torino, Italy - Central European Standard Time : (UTC+01:00)" },
2036   { 430, "Toronto, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2037   { 431, "Torrance, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2038   { 432, "Toulouse, France - Central European Standard Time : (UTC+01:00)" },
2039   { 433, "Tripoli, Libya - Eastern European Standard Time : (UTC+02:00)" },
2040   { 434, "Tucson, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
2041   { 435, "Tulsa, OK, USA - Central Standard Time : (UTC-06:00)" },
2042   { 436, "Tunis, Tunisia - West Africa Time : (UTC+01:00)" },
2043   { 437, "Ulaanbaatar, Mongolia - Ulaanbaatar Time : (UTC+08:00)" },
2044   { 438, "Urumqi, China - China Standard Time : (UTC+08:00)" },
2045   { 439, "Vaduz, Liechtenstein - Central European Standard Time : (UTC+01:00)" },
2046   { 440, "Valencia, Spain - Central European Standard Time : (UTC+01:00)" },
2047   { 441, "Valletta, Malta - Central European Standard Time : (UTC+01:00)" },
2048   { 442, "Vancouver, BC, Canada - Pacific Standard Time : (UTC-08:00)" },
2049   { 443, "Vatican City, Vatican City - Central European Standard Time : (UTC+01:00)" },
2050   { 444, "Venice, Italy - Central European Standard Time : (UTC+01:00)" },
2051   { 445, "Veracruz, Mexico - Central Standard Time : (UTC-06:00)" },
2052   { 446, "Victoria, Seychelles - Seychelles Time : (UTC+04:00)" },
2053   { 447, "Vienna, Austria - Central European Standard Time : (UTC+01:00)" },
2054   { 448, "Vientiane, Laos - Indochina Time : (UTC+07:00)" },
2055   { 449, "Vilnius, Lithuania - Eastern European Standard Time : (UTC+02:00)" },
2056   { 450, "Vladivostok, Russia - Vladivostok Standard Time : (UTC+10:00)" },
2057   { 451, "Volgograd, Russia - Moscow Standard Time : (UTC+03:00)" },
2058   { 452, "Waco, TX, USA - Central Standard Time : (UTC-06:00)" },
2059   { 453, "Warsaw, Poland - Central European Standard Time : (UTC+01:00)" },
2060   { 454, "Washington, DC, USA - Eastern Standard Time : (UTC-05:00)" },
2061   { 455, "Wellington, New Zealand - New Zealand Standard Time : (UTC+12:00)" },
2062   { 456, "Whitehorse, YT, Canada - Pacific Standard Time : (UTC-08:00)" },
2063   { 457, "Windhoek, Namibia - West Africa Time : (UTC+01:00)" },
2064   { 458, "Winnipeg, MB, Canada - Central Standard Time : (UTC-06:00)" },
2065   { 459, "Wuhan, China - China Standard Time : (UTC+08:00)" },
2066   { 460, "Xian, China - China Standard Time : (UTC+08:00)" },
2067   { 461, "Yakutsk, Russia - Yakutsk Standard Time : (UTC+09:00)" },
2068   { 462, "Yangon, Myanmar - Myanmar Standard Time : (UTC+06:30)" },
2069   { 463, "Yekaterinburg, Russia - Yekaterinburg Standard Time : (UTC+05:00)" },
2070   { 464, "Yellowknife, NT, Canada - Mountain Standard Time : (UTC-07:00)" },
2071   { 465, "Yerevan, Armenia - Armenia Time : (UTC+04:00)" },
2072   { 466, "Yokohama, Japan - Japan Standard Time : (UTC+09:00)" },
2073   { 467, "Zagreb, Croatia - Central European Standard Time : (UTC+01:00)" },
2074   { 468, "Zaragoza, Spain - Central European Standard Time : (UTC+01:00)" },
2075   { 469, "Zurich, Switzerland - Central European Standard Time : (UTC+01:00)" },
2076   { 0, NULL }
2077 };
2078
2079 static const value_string acn_blob_time3_dst_vals[] = {
2080   { 0, "DST US" },
2081   { 1, "DST Europe" },
2082   { 2, "DST Funky" },
2083   { 3, "DST None" },
2084   { 0, NULL }
2085 };
2086
2087 static const value_string acn_blob_time3_month_vals[] = {
2088   { 0, "None" },
2089   { 1, "January" },
2090   { 2, "February" },
2091   { 3, "March" },
2092   { 4, "April" },
2093   { 5, "May" },
2094   { 6, "June" },
2095   { 7, "July" },
2096   { 8, "August" },
2097   { 9, "September" },
2098   { 10, "October" },
2099   { 11, "November" },
2100   { 12, "December" },
2101   { 0, NULL }
2102 };
2103
2104 static const value_string acn_blob_time3_week_vals[] = {
2105   { 0, "None" },
2106   { 1, "First" },
2107   { 2, "Second" },
2108   { 3, "Third" },
2109   { 4, "Fourth" },
2110   { 5, "Last" },
2111   { 0, NULL }
2112 };
2113
2114 static const value_string acn_blob_time3_day_vals[] = {
2115   { 0, "Sunday" },
2116   { 1, "Monday" },
2117   { 2, "Tuesday" },
2118   { 3, "Wednesday" },
2119   { 4, "Thursday" },
2120   { 5, "Friday" },
2121   { 6, "Saturday" },
2122   { 0, NULL }
2123 };
2124
2125 static const value_string acn_blob_time3_locality_vals[] = {
2126   { 0, "LOCAL" },
2127   { 1, "UTC" },
2128   { 0, NULL }
2129 };
2130
2131 static const value_string acn_blob_type_vals[] = {
2132   { ACN_BLOB_IPV4,                           "IPv4 Blob" },
2133   { ACN_BLOB_IPV6,                           "IPv6 Blob" },
2134   { ACN_BLOB_ERROR1,                         "Error Blob v1" },
2135   { ACN_BLOB_ERROR2,                         "Error Blob v2" },
2136   { ACN_BLOB_METADATA,                       "Metadata" },
2137   { ACN_BLOB_METADATA_DEVICES,               "Metadata Devices" },
2138   { ACN_BLOB_METADATA_TYPES,                 "Metadata Types" },
2139   { ACN_BLOB_TIME1,                          "Time Blob (deprecated 1)" },
2140   { ACN_BLOB_DIMMER_PROPERTIES,              "Dimmer Properties Blob v1" },
2141   { ACN_BLOB_DIMMER_LOAD_PROPERTIES,         "Dimmer Load Properties Blob v1" },
2142   { ACN_BLOB_DIMMING_RACK_PROPERTIES,        "Dimming Rack Properties Blob v1" },
2143   { ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES, "Dimming Rack Status Properties Blob v1" },
2144   { ACN_BLOB_DIMMER_STATUS_PROPERTIES,       "Dimmer Status Properties Blob v1" },
2145   { ACN_BLOB_SET_LEVELS_OPERATION,           "Set Levels Operation Blob" },
2146   { ACN_BLOB_PRESET_OPERATION,               "Preset Operation Blob" },
2147   { ACN_BLOB_ADVANCED_FEATURES_OPERATION,    "Advanced Features Operation Blob" },
2148   { ACN_BLOB_DIRECT_CONTROL_OPERATION,       "Direct Control Operation Blob" },
2149   { ACN_BLOB_GENERATE_CONFIG_OPERATION,      "Generate Config Operation Blob" },
2150   { ACN_BLOB_ERROR3,                         "Error Blob v3" },
2151   { ACN_BLOB_DIMMER_PROPERTIES2,             "Dimmer Properties Blob v2" },
2152   { ACN_BLOB_DIMMER_LOAD_PROPERTIES2,        "Dimmer Load Properties Blob v2" },
2153   { ACN_BLOB_DIMMER_RACK_PROPERTIES2,        "Dimming Rack Properties Blob v2" },
2154   { ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2, "Dimming Rack Status Properties Blob v2" },
2155   { ACN_BLOB_DIMMER_STATUS_PROPERTIES2,      "Dimmer Status Properties Blob v2" },
2156   { ACN_BLOB_TIME2,                          "Time Blob (deprecated 2)" },
2157   { ACN_BLOB_RPC,                            "RPC Blob" },
2158   { ACN_BLOB_DHCP_CONFIG_SUBNET,             "DHCP Config Subnet Blob" },
2159   { ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE,       "DHCP Config Static Route Blob" },
2160   { ACN_BLOB_ENERGY_MANAGEMENT,              "Energy Management Blob" },
2161   { ACN_BLOB_PRESET_PROPERTIES,              "Preset Properties Blob" },
2162   { ACN_BLOB_TIME3,                          "Time Blob v2" },
2163   { 0, NULL }
2164 };
2165
2166 static const value_string acn_dmp_vector_vals[] = {
2167   {ACN_DMP_VECTOR_UNKNOWN,            "Unknown"},
2168   {ACN_DMP_VECTOR_GET_PROPERTY,       "Get Property"},
2169   {ACN_DMP_VECTOR_SET_PROPERTY,       "Set Property"},
2170   {ACN_DMP_VECTOR_GET_PROPERTY_REPLY, "Get property reply"},
2171   {ACN_DMP_VECTOR_EVENT,              "Event"},
2172   {ACN_DMP_VECTOR_MAP_PROPERTY,       "Map Property"},
2173   {ACN_DMP_VECTOR_UNMAP_PROPERTY,     "Unmap Property"},
2174   {ACN_DMP_VECTOR_SUBSCRIBE,          "Subscribe"},
2175   {ACN_DMP_VECTOR_UNSUBSCRIBE,        "Unsubscribe"},
2176   {ACN_DMP_VECTOR_GET_PROPERTY_FAIL,  "Get Property Fail"},
2177   {ACN_DMP_VECTOR_SET_PROPERTY_FAIL,  "Set Property Fail"},
2178   {ACN_DMP_VECTOR_MAP_PROPERTY_FAIL,  "Map Property Fail"},
2179   {ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT,   "Subscribe Accept"},
2180   {ACN_DMP_VECTOR_SUBSCRIBE_REJECT,   "Subscribe Reject"},
2181   {ACN_DMP_VECTOR_ALLOCATE_MAP,       "Allocate Map"},
2182   {ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY, "Allocate Map Reply"},
2183   { ACN_DMP_VECTOR_DEALLOCATE_MAP,    "Deallocate Map" },
2184   { ACN_DMP_VECTOR_SYNC_EVENT,        "Sync Event" },
2185   { 0,       NULL },
2186 };
2187
2188 static const value_string acn_ip_address_type_vals[] = {
2189   { ACN_ADDR_NULL,   "Null"},
2190   { ACN_ADDR_IPV4,   "IPv4"},
2191   { ACN_ADDR_IPV6,   "IPv6"},
2192   { ACN_ADDR_IPPORT, "Port"},
2193   { 0,       NULL },
2194 };
2195
2196 static const value_string acn_refuse_code_vals[] = {
2197   { ACN_REFUSE_CODE_NONSPECIFIC,    "Nonspecific" },
2198   { ACN_REFUSE_CODE_ILLEGAL_PARAMS, "Illegal Parameters" },
2199   { ACN_REFUSE_CODE_LOW_RESOURCES,  "Low Resources" },
2200   { ACN_REFUSE_CODE_ALREADY_MEMBER, "Already Member" },
2201   { ACN_REFUSE_CODE_BAD_ADDR_TYPE,  "Bad Address Type" },
2202   { ACN_REFUSE_CODE_NO_RECIP_CHAN,  "No Reciprocal Channel" },
2203   { 0,       NULL },
2204 };
2205
2206 static const value_string acn_reason_code_vals[] = {
2207   { ACN_REASON_CODE_NONSPECIFIC,         "Nonspecific" },
2208   { ACN_REASON_CODE_NO_RECIP_CHAN,       "No Reciprocal Channel" },
2209   { ACN_REASON_CODE_CHANNEL_EXPIRED,     "Channel Expired" },
2210   { ACN_REASON_CODE_LOST_SEQUENCE,       "Lost Sequence" },
2211   { ACN_REASON_CODE_SATURATED,           "Saturated" },
2212   { ACN_REASON_CODE_TRANS_ADDR_CHANGING, "Transport Address Changing" },
2213   { ACN_REASON_CODE_ASKED_TO_LEAVE,      "Asked to Leave" },
2214   { ACN_REASON_CODE_NO_RECIPIENT,        "No Recipient"},
2215   { 0,       NULL },
2216 };
2217
2218 static const value_string acn_dmp_reason_code_vals[] = {
2219   { ACN_DMP_REASON_CODE_NONSPECIFIC,                "Nonspecific" },
2220   { ACN_DMP_REASON_CODE_NOT_A_PROPERTY,             "Not a Property" },
2221   { ACN_DMP_REASON_CODE_WRITE_ONLY,                 "Write Only" },
2222   { ACN_DMP_REASON_CODE_NOT_WRITABLE,               "Not Writable" },
2223   { ACN_DMP_REASON_CODE_DATA_ERROR,                 "Data Error" },
2224   { ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED,         "Maps not Supported" },
2225   { ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE,        "Space not Available" },
2226   { ACN_DMP_REASON_CODE_PROP_NOT_MAPPABLE,          "Property not Mappable"},
2227   { ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED,          "Map not Allocated"},
2228   { ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED, "Subscription not Supported"},
2229   { ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED, "No Subscriptions Supported"},
2230   { 0,       NULL },
2231 };
2232
2233 static const enum_val_t dmx_display_view[] = {
2234   { "hex"    , "Hex    ",     ACN_PREF_DMX_DISPLAY_HEX  },
2235   { "decimal", "Decimal",     ACN_PREF_DMX_DISPLAY_DEC  },
2236   { "percent", "Percent",     ACN_PREF_DMX_DISPLAY_PER  },
2237   { NULL, NULL, 0 }
2238 };
2239
2240 static const enum_val_t dmx_display_line_format[] = {
2241   { "20 per line", "20 per line",     ACN_PREF_DMX_DISPLAY_20PL  },
2242   { "16 per line", "16 per line",     ACN_PREF_DMX_DISPLAY_16PL  },
2243   { NULL, NULL, 0 }
2244 };
2245
2246
2247 static const value_string magic_pdu_subtypes[] = {
2248   { MAGIC_V1,           "V1" },
2249   { MAGIC_COMMAND,      "V2 Command" },
2250   { MAGIC_REPLY,        "V2 Reply" },
2251   { MAGIC_REPLY_TYPE_3, "V2 Reply Type 3" },
2252   { 0, NULL }
2253 };
2254
2255 static const value_string magic_v1command_vals[] = {
2256   { V1_SWITCH_TO_NET1, "Switch to Net1" },
2257   { V1_SWITCH_TO_NET2, "Switch to Net2" },
2258   { V1_BOOTP,          "bootp" },
2259   { 0, NULL }
2260 };
2261
2262 static const value_string magic_command_vals[] = {
2263   { V2_CMD_SWITCH_TO_NET1,          "Switch to Net1 mode" },
2264   { V2_CMD_SWITCH_TO_NET2,          "Switch to Net2 mode" },
2265   { V2_CMD_DOWNLOAD,                "Code download" },
2266   { V2_CMD_SOFTBOOT,                "Soft reboot" },
2267   { V2_CMD_PHYSICAL_BEACON,         "Physical beacon" },
2268   { V2_CMD_NETWORK_BEACON,          "Network beacon" },
2269   { V2_CMD_SWITCH_TO_ACN,           "Switch to ACN mode" },
2270   { V2_CMD_SWITCH_TO_DYNAMIC_IP,    "Switch to dynamic IP address configuration" },
2271   { V2_CMD_EXTENDED_NETWORK_BEACON, "Extended network beacon" },
2272   { V2_CMD_IP_CONFIGURATION,        "IP configuration" },
2273   { V2_CMD_RESTORE_FACTORY_DEFAULT, "Restore factory default" },
2274   { V2_CMD_PHYSICAL_BEACON_BY_CID,  "Physical beacon by CID" },
2275   { V2_CMD_NET2_DOWNLOAD,           "NET2 code download and reboot" },
2276   { 0, NULL }
2277 };
2278
2279 static const value_string magic_reset_lease_vals[] = {
2280   { MAGIC_SWITCH_TO_DYNAMIC_RESET_LEASE,    "Reset lease" },
2281   { MAGIC_SWITCH_TO_DYNAMIC_MAINTAIN_LEASE, "Maintain lease" },
2282   { 0, NULL }
2283 };
2284
2285 static const value_string magic_ip_configuration_vals[] = {
2286   { MAGIC_DYNAMIC_IP_MAINTAIN_LEASE, "Dynamic IP, maintain lease" },
2287   { MAGIC_DYNAMIC_IP_RESET_LEASE,    "Dynamic IP, reset lease" },
2288   { MAGIC_STATIC_IP,                 "Static IP" },
2289   { 0, NULL }
2290 };
2291
2292 /******************************************************************************/
2293 /* Test to see if it is a Magic Bullet Packet                                 */
2294 static gboolean
2295 is_magic(tvbuff_t *tvb)
2296 {
2297   static const guint8 magic_protocol_id = 15;
2298
2299   if (tvb_get_guint8(tvb, 0) == magic_protocol_id)
2300     return TRUE;
2301
2302   return FALSE;
2303 }
2304
2305 /******************************************************************************/
2306 /* Dissect Magic Bullet                                                       */
2307 static int
2308 dissect_magic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2309 {
2310   guint8 pdu_subtype;
2311   guint offset = 0;
2312   const char *pdu_subtype_string;
2313   proto_tree *ti;
2314   proto_tree *magic_tree;
2315   guint32 command;
2316   guint32 str_len;
2317   guint32 major, minor, patch, aud, crit, build;
2318   gchar *buffer;
2319
2320   /* Set the protocol column */
2321   col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAGIC");
2322
2323   /* Create our tree */
2324   ti = proto_tree_add_item(tree, proto_magic, tvb, offset, -1, ENC_NA);
2325   magic_tree = proto_item_add_subtree(ti, ett_magic);
2326
2327   /* Protocol ID */
2328   proto_tree_add_item(magic_tree, hf_magic_protocol_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2329   offset++;
2330
2331   /* PDU Type */
2332   pdu_subtype = tvb_get_guint8(tvb, offset);
2333   pdu_subtype_string = val_to_str(pdu_subtype, magic_pdu_subtypes, "Unknown (0x%02x)");
2334
2335   /* Adjust info column */
2336   col_clear(pinfo->cinfo, COL_INFO);
2337   col_add_fstr(pinfo->cinfo, COL_INFO, "MAGIC - %s", pdu_subtype_string);
2338
2339   /* Append subtype description */
2340   proto_item_append_text(ti, ": %s", pdu_subtype_string);
2341
2342   proto_tree_add_item(magic_tree, hf_magic_pdu_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
2343   offset++;
2344   proto_tree_add_item(magic_tree, hf_magic_major_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2345   offset++;
2346   proto_tree_add_item(magic_tree, hf_magic_minor_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2347   offset++;
2348
2349   switch (pdu_subtype) {
2350     case MAGIC_V1:
2351       proto_tree_add_item(magic_tree, hf_magic_v1command_vals, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2352       offset += 4;
2353       break;
2354
2355     case MAGIC_COMMAND:
2356       /* note, v2 is big-endian */
2357       proto_tree_add_item_ret_uint(magic_tree, hf_magic_command_vals, tvb, offset, 4, ENC_BIG_ENDIAN, &command);
2358       offset += 4;
2359       /* deal with variable parameter */
2360       switch (command) {
2361         case V2_CMD_DOWNLOAD:
2362           proto_tree_add_item(magic_tree, hf_magic_command_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
2363           offset += 4;
2364           break;
2365         case V2_CMD_PHYSICAL_BEACON:
2366           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
2367           offset += 4;
2368           break;
2369         case V2_CMD_NETWORK_BEACON:
2370           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
2371           offset += 4;
2372           break;
2373         case V2_CMD_SWITCH_TO_DYNAMIC_IP:
2374           proto_tree_add_item(magic_tree, hf_magic_command_reset_lease, tvb, offset, 4, ENC_BIG_ENDIAN);
2375           offset += 4;
2376           break;
2377         case V2_CMD_EXTENDED_NETWORK_BEACON:
2378           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
2379           offset += 4;
2380           break;
2381         case V2_CMD_IP_CONFIGURATION:
2382           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
2383           offset += 16;
2384           proto_tree_add_item(magic_tree, hf_magic_command_ip_configuration, tvb, offset, 4, ENC_BIG_ENDIAN);
2385           offset += 4;
2386           proto_tree_add_item(magic_tree, hf_magic_command_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
2387           offset += 4;
2388           proto_tree_add_item(magic_tree, hf_magic_command_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
2389           offset += 4;
2390           proto_tree_add_item(magic_tree, hf_magic_command_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
2391           offset += 4;
2392           break;
2393         case V2_CMD_RESTORE_FACTORY_DEFAULT:
2394           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
2395           offset += 16;
2396           break;
2397         case V2_CMD_PHYSICAL_BEACON_BY_CID:
2398           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
2399           offset += 16;
2400           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
2401           offset += 4;
2402           break;
2403         /* case V2_CMD_SOFTBOOT:       */
2404         /* case V2_CMD_SWITCH_TO_NET1: */
2405         /* case V2_CMD_SWITCH_TO_NET2: */
2406         /* case V2_CMD_SWITCH_TO_ACN:  */
2407         /* case V2_CMD_NET2_DOWNLOAD:  */
2408       }
2409       break;
2410
2411     case MAGIC_REPLY:
2412       /* note, v2 is big-endian */
2413       proto_tree_add_item(magic_tree, hf_magic_reply_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
2414       offset += 4;
2415       proto_tree_add_item(magic_tree, hf_magic_reply_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
2416       offset += 4;
2417       proto_tree_add_item(magic_tree, hf_magic_reply_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
2418       offset += 4;
2419       proto_tree_add_item(magic_tree, hf_magic_reply_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
2420       offset += 4;
2421
2422       /* encoded and display version */
2423       major = tvb_get_guint8(tvb, offset++);
2424       minor = tvb_get_guint8(tvb, offset++);
2425       patch = tvb_get_guint8(tvb, offset++);
2426       aud = tvb_get_guint8(tvb, offset++);
2427       crit = tvb_get_guint8(tvb, offset++);
2428       build = tvb_get_ntohs(tvb, offset);
2429       offset += 2;
2430
2431       offset -= 7;
2432       buffer = wmem_strdup_printf(wmem_packet_scope(), "%d.%d.%d.%d.%d.%d", major, minor, patch, aud, crit, build);
2433       proto_tree_add_string(magic_tree, hf_magic_reply_version, tvb, offset, 7, buffer);
2434       offset += 7;
2435
2436       /* Device Type Name string */
2437       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_device_type_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2438       offset += str_len;
2439
2440       /* Default Name string */
2441       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_default_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2442       offset += str_len;
2443
2444       /* User Name string */
2445       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_user_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2446       offset += str_len;
2447       break;
2448
2449     case MAGIC_REPLY_TYPE_3:
2450       command = tvb_get_ntohl(tvb, offset);
2451       proto_tree_add_item(magic_tree, hf_magic_command_vals, tvb, offset, 4, ENC_BIG_ENDIAN);
2452       offset += 4;
2453       proto_tree_add_item(magic_tree, hf_magic_reply_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
2454       offset += 4;
2455       proto_tree_add_item(magic_tree, hf_magic_reply_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
2456       offset += 4;
2457       proto_tree_add_item(magic_tree, hf_magic_reply_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
2458       offset += 4;
2459       proto_tree_add_item(magic_tree, hf_magic_reply_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
2460       offset += 4;
2461       proto_tree_add_item(magic_tree, hf_magic_reply_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
2462       offset += 16;
2463       proto_tree_add_item(magic_tree, hf_magic_reply_dcid, tvb, offset, 16, ENC_BIG_ENDIAN);
2464       offset += 16;
2465
2466       /* encoded and display version */
2467       major = tvb_get_guint8(tvb, offset++);
2468       minor = tvb_get_guint8(tvb, offset++);
2469       patch = tvb_get_guint8(tvb, offset++);
2470       aud = tvb_get_guint8(tvb, offset++);
2471       crit = tvb_get_guint8(tvb, offset++);
2472       build = tvb_get_ntohs(tvb, offset);
2473       offset += 2;
2474
2475       offset -= 7;
2476       buffer = wmem_strdup_printf(wmem_packet_scope(), "%d.%d.%d.%d.%d.%d", major, minor, patch, aud, crit, build);
2477       proto_tree_add_string(magic_tree, hf_magic_reply_version, tvb, offset, 7, buffer);
2478       offset += 7;
2479
2480       /* Device Type Name string */
2481       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_device_type_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2482       offset += str_len;
2483
2484       /* Default Name string */
2485       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_default_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2486       offset += str_len;
2487
2488       /* User Name string */
2489       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_user_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
2490       offset += str_len;
2491       break;
2492
2493     default:
2494       proto_tree_add_int(magic_tree, hf_magic_reply_invalid_type, tvb, offset, -1, pdu_subtype);
2495       offset = tvb_captured_length(tvb);
2496   }
2497   return offset;
2498 }
2499
2500 /******************************************************************************/
2501 /* Test to see if it is an ACN Packet                                         */
2502 static gboolean
2503 is_acn(tvbuff_t *tvb)
2504 {
2505   static const char acn_packet_id[] = "ASC-E1.17\0\0\0";  /* must be 12 bytes */
2506
2507   if (tvb_captured_length(tvb) < (4+sizeof(acn_packet_id)))
2508     return FALSE;
2509
2510   /* Check the bytes in octets 4 - 16 */
2511   if (tvb_memeql(tvb, 4, acn_packet_id, sizeof(acn_packet_id)-1) != 0)
2512     return FALSE;
2513
2514   return TRUE;
2515 }
2516
2517
2518 /******************************************************************************/
2519 /* Heuristic dissector                                                        */
2520 static gboolean
2521 dissect_acn_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
2522 {
2523   /* This is a heuristic dissector, which means we get all the UDP
2524    * traffic not sent to a known dissector and not claimed by
2525    * a heuristic dissector called before us!
2526    */
2527
2528   if (is_acn(tvb)) {
2529     dissect_acn(tvb, pinfo, tree);
2530     return TRUE;
2531   }
2532
2533   if (is_magic(tvb)) {
2534     dissect_magic(tvb, pinfo, tree);
2535     return TRUE;
2536   }
2537
2538   /* abort if it is NOT an ACN or Magic Bullet packet */
2539   return FALSE;
2540 }
2541
2542 /******************************************************************************/
2543 /*  Adds tree branch for channel owner info block                             */
2544 static guint32
2545 acn_add_channel_owner_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
2546 {
2547   proto_item *pi;
2548   proto_tree *this_tree;
2549   guint32     session_count;
2550   guint32     x;
2551
2552   this_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_owner_info_block, NULL,
2553                                     "Channel Owner Info Block");
2554
2555   proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2556   offset += 2;
2557   proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, ENC_BIG_ENDIAN);
2558   offset += 2;
2559   offset += acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address:");
2560   offset += acn_add_address(tvb, pinfo, this_tree, offset, "Source Address:");
2561
2562   session_count = tvb_get_ntohs(tvb, offset);
2563   for (x=0; x<session_count; x++) {
2564     pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2565     proto_item_append_text(pi, " #%d",  x+1);
2566     offset += 4;
2567   }
2568   return offset;
2569 }
2570
2571 /******************************************************************************/
2572 /*  Adds tree branch for channel member info block                            */
2573 static guint32
2574 acn_add_channel_member_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
2575 {
2576   proto_item *pi;
2577   proto_tree *this_tree;
2578   guint32     session_count;
2579   guint32     x;
2580
2581   this_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_member_info_block,
2582                                 NULL, "Channel Member Info Block");
2583
2584   proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2585   offset += 2;
2586   proto_tree_add_item(this_tree, hf_acn_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
2587   offset += 16;
2588   proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, ENC_BIG_ENDIAN);
2589   offset += 2;
2590   offset += acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address:");
2591   offset += acn_add_address(tvb, pinfo, this_tree, offset, "Source Address:");
2592   proto_tree_add_item(this_tree, hf_acn_reciprocal_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
2593   offset += 2;
2594
2595   session_count = tvb_get_ntohs(tvb, offset);
2596   for (x=0; x<session_count; x++) {
2597     pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
2598     proto_item_append_text(pi, " #%d",  x+1);
2599     offset += 4;
2600   }
2601   return offset;
2602 }
2603
2604
2605 /******************************************************************************/
2606 /* Add labeled expiry                                                         */
2607 static guint32
2608 acn_add_expiry(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int hf)
2609 {
2610   proto_tree_add_item(tree, hf, tvb, offset, 1, ENC_NA);
2611   offset += 1;
2612   return offset;
2613 }
2614
2615
2616 /******************************************************************************/
2617 /*  Adds tree branch for channel parameters                                   */
2618 static guint32
2619 acn_add_channel_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
2620 {
2621   proto_tree *param_tree;
2622
2623   param_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_parameter,
2624                             NULL, "Channel Parameter Block");
2625
2626   proto_tree_add_item(param_tree, hf_acn_expiry, tvb, offset, 1, ENC_BIG_ENDIAN);
2627   offset += 1;
2628   proto_tree_add_item(param_tree, hf_acn_nak_outbound_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2629   offset += 1;
2630   proto_tree_add_item(param_tree, hf_acn_nak_holdoff, tvb, offset, 2, ENC_BIG_ENDIAN);
2631   offset += 2;
2632   proto_tree_add_item(param_tree, hf_acn_nak_modulus, tvb, offset, 2, ENC_BIG_ENDIAN);
2633   offset += 2;
2634   proto_tree_add_item(param_tree, hf_acn_nak_max_wait, tvb, offset, 2, ENC_BIG_ENDIAN);
2635   offset += 2;
2636   return offset; /* bytes used */
2637 }
2638
2639
2640 /******************************************************************************/
2641 /* Add an address tree                                                        */
2642 static guint32
2643 acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, const char *label)
2644 {
2645   proto_item *pi;
2646   proto_tree *addr_tree = NULL;
2647   guint8      ip_address_type;
2648   guint32     port;
2649
2650   /* Get type */
2651   ip_address_type = tvb_get_guint8(tvb, offset);
2652
2653   switch (ip_address_type) {
2654     case ACN_ADDR_NULL:
2655       proto_tree_add_item(tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2656       offset    += 1;
2657       break;
2658     case ACN_ADDR_IPV4:
2659       /* Build tree and add type*/
2660       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 7, ett_acn_address, &pi, label);
2661       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2662       offset    += 1;
2663       /* Add port */
2664       port       = tvb_get_ntohs(tvb, offset);
2665       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
2666       offset    += 2;
2667       /* Add Address */
2668       proto_tree_add_item(addr_tree, hf_acn_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
2669       /* Append port and address to tree item */
2670       proto_item_append_text(pi, " %s, Port %d", tvb_address_to_str(wmem_packet_scope(), tvb, AT_IPv4, offset), port);
2671       offset    += 4;
2672       break;
2673     case ACN_ADDR_IPV6:
2674       /* Build tree and add type*/
2675       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 19, ett_acn_address, &pi, label);
2676       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2677       offset    += 1;
2678       /* Add port */
2679       port       = tvb_get_ntohs(tvb, offset);
2680       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
2681       offset    += 2;
2682       /* Add Address */
2683       proto_tree_add_item(addr_tree, hf_acn_ipv6, tvb, offset, 16, ENC_NA);
2684       /* Append port and address to tree item */
2685       proto_item_append_text(pi, " %s, Port %d", tvb_address_to_str(wmem_packet_scope(), tvb, AT_IPv6, offset), port);
2686       offset    += 16;
2687       break;
2688     case ACN_ADDR_IPPORT:
2689       /* Build tree and add type*/
2690       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_acn_address, &pi, label);
2691       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2692       offset    += 1;
2693       /* Add port */
2694       port       = tvb_get_ntohs(tvb, offset);
2695       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
2696       /* Append port to tree item */
2697       proto_item_append_text(pi, " Port %d", port);
2698       offset    += 2;
2699       break;
2700   }
2701   return offset;
2702 }
2703
2704 /******************************************************************************/
2705 /*  Adds tree branch for address type                             */
2706 static guint32
2707 acn_add_dmp_address_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
2708 {
2709   proto_tree  *this_tree;
2710   guint8       D;
2711   const gchar *name;
2712
2713   /* header contains address and data type */
2714   adt->flags = tvb_get_guint8(tvb, offset);
2715
2716   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
2717   name = val_to_str(D, acn_dmp_adt_d_vals, "not valid (%d)");
2718   this_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_acn_address_type,
2719                                 NULL, "Address and Data Type: %s", name);
2720
2721   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_v, tvb, offset, 1, adt->flags);
2722   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_r, tvb, offset, 1, adt->flags);
2723   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_d, tvb, offset, 1, adt->flags);
2724   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_x, tvb, offset, 1, adt->flags);
2725   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_a, tvb, offset, 1, adt->flags);
2726   offset += 1;
2727
2728   return offset; /* bytes used */
2729 }
2730
2731 /******************************************************************************/
2732 /* Add an dmp address                                                         */
2733 static guint32
2734 acn_add_dmp_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
2735 {
2736   guint32 start_offset;
2737   guint32 bytes_used;
2738   guint8  D, A;
2739
2740   start_offset = offset;
2741
2742   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
2743   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
2744
2745   switch (D) {
2746     case ACN_DMP_ADT_D_NS:      /* Non-range address, Single data item */
2747       adt->increment    = 1;
2748       adt->count        = 1;
2749       switch (A) {              /* address */
2750         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
2751           adt->address  = tvb_get_guint8(tvb, offset);
2752           offset       += 1;
2753           bytes_used    = 1;
2754           break;
2755         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
2756           adt->address  = tvb_get_ntohs(tvb, offset);
2757           offset       += 2;
2758           bytes_used    = 2;
2759           break;
2760         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: one octet address, increment, and count). */
2761           adt->address  = tvb_get_ntohl(tvb, offset);
2762           offset       += 4;
2763           bytes_used    = 4;
2764           break;
2765         default:                /* and ACN_DMP_ADT_A_R (Four octet address, (range: four octet address, increment, and count)*/
2766           return offset;
2767       }                         /* of switch (A)  */
2768
2769       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
2770         proto_tree_add_uint(tree, hf_acn_dmp_virtual_address, tvb, start_offset, bytes_used, adt->address);
2771       } else {
2772         proto_tree_add_uint(tree, hf_acn_dmp_actual_address, tvb, start_offset, bytes_used, adt->address);
2773       }
2774       break;
2775
2776     case ACN_DMP_ADT_D_RS:      /* Range address, Single data item */
2777       switch (A) {
2778         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
2779           adt->address    = tvb_get_guint8(tvb, offset);
2780           offset         += 1;
2781           adt->increment  = tvb_get_guint8(tvb, offset);
2782           offset         += 1;
2783           adt->count      = tvb_get_guint8(tvb, offset);
2784           offset         += 1;
2785           bytes_used      = 3;
2786           break;
2787         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
2788           adt->address    = tvb_get_ntohs(tvb, offset);
2789           offset         += 2;
2790           adt->increment  = tvb_get_ntohs(tvb, offset);
2791           offset         += 2;
2792           adt->count      = tvb_get_ntohs(tvb, offset);
2793           offset         += 2;
2794           bytes_used      = 6;
2795           break;
2796         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: four octet address, increment, and count). */
2797           adt->address    = tvb_get_ntohl(tvb, offset);
2798           offset         += 4;
2799           adt->increment  = tvb_get_ntohl(tvb, offset);
2800           offset         += 4;
2801           adt->count      = tvb_get_ntohl(tvb, offset);
2802           offset         += 4;
2803           bytes_used      = 12;
2804           break;
2805         default:                /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
2806           return offset;
2807       }                         /* of switch (A)  */
2808
2809       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
2810         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
2811                             adt->address, "0x%X, inc: %d, count: %d",
2812                             adt->address, adt->increment, adt->count);
2813       } else {
2814         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
2815                             adt->address, "0x%X, inc: %d, count: %d",
2816                             adt->address, adt->increment, adt->count);
2817       }
2818       break;
2819
2820     case ACN_DMP_ADT_D_RE:      /* Range address, Array of equal size data items */
2821       switch (A) {
2822         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
2823           adt->address    = tvb_get_guint8(tvb, offset);
2824           offset         += 1;
2825           adt->increment  = tvb_get_guint8(tvb, offset);
2826           offset         += 1;
2827           adt->count      = tvb_get_guint8(tvb, offset);
2828           offset         += 1;
2829           bytes_used      = 3;
2830           break;
2831         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
2832           adt->address    = tvb_get_ntohs(tvb, offset);
2833           offset         += 2;
2834           adt->increment  = tvb_get_ntohs(tvb, offset);
2835           offset         += 2;
2836           adt->count      = tvb_get_ntohs(tvb, offset);
2837           offset         += 2;
2838           bytes_used      = 6;
2839           break;
2840         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: four octet address, increment, and count). */
2841           adt->address    = tvb_get_ntohl(tvb, offset);
2842           offset         += 4;
2843           adt->increment  = tvb_get_ntohl(tvb, offset);
2844           offset         += 4;
2845           adt->count      = tvb_get_ntohl(tvb, offset);
2846           offset         += 4;
2847           bytes_used      = 12;
2848           break;
2849         default:                /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
2850           return offset;
2851       }                         /* of switch (A)  */
2852
2853       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
2854         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
2855                             adt->address, "0x%X, inc: %d, count: %d",
2856                             adt->address, adt->increment, adt->count);
2857       } else {
2858         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
2859                             adt->address, "0x%X, inc: %d, count: %d",
2860                             adt->address, adt->increment, adt->count);
2861       }
2862       break;
2863
2864     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
2865       switch (A) {
2866         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
2867           adt->address =   tvb_get_guint8(tvb, offset);
2868           offset += 1;
2869           adt->increment =   tvb_get_guint8(tvb, offset);
2870           offset += 1;
2871           adt->count =   tvb_get_guint8(tvb, offset);
2872           offset += 1;
2873           bytes_used = 3;
2874           break;
2875         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
2876           adt->address =   tvb_get_ntohs(tvb, offset);
2877           offset += 2;
2878           adt->increment =   tvb_get_ntohs(tvb, offset);
2879           offset += 2;
2880           adt->count =   tvb_get_ntohs(tvb, offset);
2881           offset += 2;
2882           bytes_used = 6;
2883           break;
2884         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
2885           adt->address =   tvb_get_ntohl(tvb, offset);
2886           offset += 4;
2887           adt->increment =   tvb_get_ntohl(tvb, offset);
2888           offset += 4;
2889           adt->count =   tvb_get_ntohl(tvb, offset);
2890           offset += 4;
2891           bytes_used = 12;
2892           break;
2893         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
2894           return offset;
2895       } /* of switch (A)  */
2896
2897       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
2898         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
2899                             adt->address, "0x%X, inc: %d, count: %d",
2900                             adt->address, adt->increment, adt->count);
2901       } else {
2902         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
2903                             adt->address, "0x%X, inc: %d, count: %d",
2904                             adt->address, adt->increment, adt->count);
2905       }
2906       break;
2907   } /* of switch (D) */
2908
2909   return offset;
2910 }
2911
2912
2913 /*******************************************************************************/
2914 /* Display DMP Data                                                            */
2915 static guint32
2916 acn_add_dmp_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
2917 {
2918   guint8      D, A;
2919   guint32     data_size;
2920   guint32     data_value;
2921   guint32     data_address;
2922   guint32     x,y;
2923   gchar      *buffer;
2924   wmem_strbuf_t *default_buffer;
2925   proto_item *ti;
2926   guint32     ok_to_process = FALSE;
2927
2928   /* We would like to rip through Property Address-Data pairs                 */
2929   /* but since we don't now how many there are nor how big the data size is,  */
2930   /* it not possible. So, we just show the whole thing as a block of date!    */
2931   /*                                                                          */
2932   /* There are a few exceptions however                                       */
2933   /* 1) if the address type is ACN_DMP_ADT_D_NS or ACN_DMP_ADT_D_RS and       */
2934   /*    or ACN_DMP_ADT_D_RE                                                   */
2935   /*    then number of bytes is <= count + 4. Each value is at least one byte */
2936   /*    and another address/data pair is at least 4 bytes so if the remaining */
2937   /*    bytes is less than the count plus 4 then the remaining data           */
2938   /*    must be all data                                                      */
2939   /*                                                                          */
2940   /* 2) if the address type is ACN_DMP_ADT_D_RE and the number of bytes       */
2941   /*    equals the number of bytes in remaining in the pdu then there is      */
2942   /*    a 1 to one match                                                      */
2943
2944   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
2945   switch (D) {
2946     case ACN_DMP_ADT_D_NS:
2947     case ACN_DMP_ADT_D_RS:
2948       if (adt->data_length <= adt->count + 4) {
2949         ok_to_process = TRUE;
2950       }
2951       break;
2952     case ACN_DMP_ADT_D_RE:
2953       if (adt->count == 0) {
2954         break;
2955       }
2956       if (adt->data_length <= adt->count + 4) {
2957         ok_to_process = TRUE;
2958       }
2959       break;
2960   }
2961
2962   if (!ok_to_process) {
2963     data_size  = adt->data_length;
2964     ti         = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
2965     offset    += data_size;
2966     proto_item_set_text(ti, "Data and more Address-Data Pairs (further dissection not possible)");
2967     return offset;
2968   }
2969
2970   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
2971
2972   switch (D) {
2973     case ACN_DMP_ADT_D_NS:      /* Non-range address, Single data item */
2974       /* calculate data size */
2975       data_size    = adt->data_length;
2976       data_address = adt->address;
2977
2978       switch (A) {
2979         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
2980           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
2981           break;
2982         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
2983           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
2984           break;
2985         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
2986           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
2987           break;
2988         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
2989           offset += data_size;
2990           return offset;
2991       }
2992
2993       switch (data_size) {
2994         case 1:
2995           data_value = tvb_get_guint8(tvb, offset);
2996           proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
2997           break;
2998         case 2:
2999           data_value = tvb_get_ntohs(tvb, offset);
3000           proto_tree_add_uint_format(tree, hf_acn_data16, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3001           break;
3002         case 3:
3003           data_value = tvb_get_ntoh24(tvb, offset);
3004           proto_tree_add_uint_format(tree, hf_acn_data24, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3005           break;
3006         case 4:
3007           data_value = tvb_get_ntohl(tvb, offset);
3008           proto_tree_add_uint_format(tree, hf_acn_data32, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3009           break;
3010         default:
3011           default_buffer = wmem_strbuf_new(wmem_packet_scope(), "");
3012           /* build string of values */
3013           for (y=0; y<20 && y<data_size; y++) {
3014             data_value = tvb_get_guint8(tvb, offset+y);
3015             wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3016           }
3017           /* add the item */
3018           ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3019           offset += data_size;
3020           /* change the text */
3021           proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3022           break;
3023       } /* of switch (data_size) */
3024       offset += data_size;
3025       break;
3026
3027     case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
3028       /* calculate data size */
3029       data_size = adt->data_length;
3030       data_address = adt->address;
3031
3032       for (x=0; x<adt->count; x++) {
3033         switch (A) {
3034           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3035             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
3036             break;
3037           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3038             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
3039             break;
3040           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3041             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
3042             break;
3043           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3044             return offset;
3045         }
3046
3047         switch (data_size) {
3048           case 1:
3049             data_value = tvb_get_guint8(tvb, offset);
3050             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
3051             break;
3052           case 2:
3053             data_value = tvb_get_ntohs(tvb, offset);
3054             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3055             break;
3056           case 3:
3057             data_value = tvb_get_ntoh24(tvb, offset);
3058             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3059             break;
3060           case 4:
3061             data_value = tvb_get_ntohl(tvb, offset);
3062             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3063             break;
3064           default:
3065             /* build string of values */
3066             default_buffer = wmem_strbuf_new(wmem_packet_scope(), "");
3067             for (y=0; y<20 && y<data_size; y++) {
3068               data_value = tvb_get_guint8(tvb, offset+y);
3069               wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3070             }
3071             /* add the item */
3072             ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3073             /* change the text */
3074             proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3075             break;
3076         } /* of switch (data_size) */
3077         data_address += adt->increment;
3078       } /* of (x=0;x<adt->count;x++) */
3079       offset += data_size;
3080       break;
3081
3082     case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
3083       /* calculate data size */
3084       data_size = adt->data_length / adt->count;
3085       data_address = adt->address;
3086
3087       for (x=0; x<adt->count; x++) {
3088         switch (A) {
3089           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3090             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
3091             break;
3092           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3093             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
3094             break;
3095           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3096             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
3097             break;
3098           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3099             return offset;
3100         }
3101
3102         switch (data_size) {
3103           case 1:
3104             data_value = tvb_get_guint8(tvb, offset);
3105             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
3106             break;
3107           case 2:
3108             data_value = tvb_get_ntohs(tvb, offset);
3109             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3110             break;
3111           case 3:
3112             data_value = tvb_get_ntoh24(tvb, offset);
3113             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3114             break;
3115           case 4:
3116             data_value = tvb_get_ntohl(tvb, offset);
3117             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3118             break;
3119           default:
3120             /* build string of values */
3121             default_buffer = wmem_strbuf_new(wmem_packet_scope(), "");
3122             for (y=0; y<20 && y<data_size; y++) {
3123               data_value = tvb_get_guint8(tvb, offset+y);
3124               wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3125             }
3126             /* add the item */
3127             ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3128             /* change the text */
3129             proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3130             break;
3131         } /* of switch (data_size) */
3132
3133         offset += data_size;
3134         data_address += adt->increment;
3135       } /* of (x=0;x<adt->count;x++) */
3136       break;
3137
3138     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
3139       data_size = adt->data_length;
3140       ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3141       offset += data_size;
3142       /* change the text */
3143       proto_item_set_text(ti, "Mixed size data items");
3144       break;
3145   } /* of switch (D) */
3146   return offset;
3147 }
3148
3149 /*******************************************************************************/
3150 /* Display DMP Reason codes                                                    */
3151 static guint32
3152 acn_add_dmp_reason_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
3153 {
3154   guint8       D, A;
3155   guint32      data_value;
3156   guint32      data_address;
3157   guint32      x;
3158
3159   gchar       *buffer;
3160   const gchar *name;
3161
3162   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
3163   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
3164   switch (D) {
3165     case ACN_DMP_ADT_D_NS: /* Non-range address, Single data item */
3166       data_address = adt->address;
3167       switch (A) {
3168         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3169           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
3170           break;
3171         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3172           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
3173           break;
3174         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3175           buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
3176           break;
3177         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3178           return offset;
3179       }
3180
3181       /* Get reason */
3182       data_value  = tvb_get_guint8(tvb, offset);
3183       name        = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
3184       proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
3185       offset     += 1;
3186       break;
3187
3188     case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
3189       data_address = adt->address;
3190       for (x=0; x<adt->count; x++) {
3191         switch (A) {
3192           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3193             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
3194             break;
3195           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3196             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
3197             break;
3198           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3199             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
3200             break;
3201           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3202             return offset;
3203         }
3204
3205         /* Get reason */
3206         data_value = tvb_get_guint8(tvb, offset);
3207         name       = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
3208         proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
3209
3210         data_address += adt->increment;
3211       } /* of (x=0;x<adt->count;x++) */
3212       offset += 1;
3213       break;
3214
3215     case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
3216     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
3217       data_address = adt->address;
3218       for (x=0; x<adt->count; x++) {
3219         switch (A) {
3220           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3221             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%2.2X ->", data_address);
3222             break;
3223           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3224             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%4.4X ->", data_address);
3225             break;
3226           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3227             buffer = wmem_strdup_printf(wmem_packet_scope(), "Addr 0x%8.8X ->", data_address);
3228             break;
3229           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3230             return offset;
3231         }
3232         /* Get reason */
3233         data_value    = tvb_get_guint8(tvb, offset);
3234         name          = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
3235         proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
3236         data_address += adt->increment;
3237         offset       += 1;
3238       } /* of (x=0;x<adt->count;x++) */
3239       break;
3240   } /* of switch (D) */
3241   return offset;
3242 }
3243
3244 /******************************************************************************/
3245 /* Get Field Type Parameters */
3246 static void
3247 get_field_type_parameters(tvbuff_t *tvb, int blob_offset, guint8 field_type, guint8 *field_length, guint8 *blob_offset1, guint8 *blob_offset2, guint8 *blob_offset3)
3248 {
3249   /* Switch Over Field Type to Determine Data */
3250   switch (field_type) {
3251     case ACN_BLOB_FIELD_TYPE1:
3252     case ACN_BLOB_FIELD_TYPE5:
3253       /* Set field length and blob_offsets to use */
3254       *field_length = 1;
3255       *blob_offset1 = 0;
3256       *blob_offset2 = 1;
3257       *blob_offset3 = *field_length;
3258       break;
3259     case ACN_BLOB_FIELD_TYPE2:
3260     case ACN_BLOB_FIELD_TYPE6:
3261       /* Set field length and blob_offsets to use */
3262       *field_length = 2;
3263       *blob_offset1 = 0;
3264       *blob_offset2 = 1;
3265       *blob_offset3 = *field_length;
3266       break;
3267     case ACN_BLOB_FIELD_TYPE3:
3268     case ACN_BLOB_FIELD_TYPE7:
3269       /* Set field length and blob_offsets to use */
3270       *field_length = 4;
3271       *blob_offset1 = 0;
3272       *blob_offset2 = 1;
3273       *blob_offset3 = *field_length;
3274       break;
3275     case ACN_BLOB_FIELD_TYPE4:
3276     case ACN_BLOB_FIELD_TYPE8:
3277       /* Set field length and blob_offsets to use */
3278       *field_length = 8;
3279       *blob_offset1 = 0;
3280       *blob_offset2 = 1;
3281       *blob_offset3 = *field_length;
3282       break;
3283     case ACN_BLOB_FIELD_TYPE9:
3284       /* float */
3285       /* Set field length and blob_offsets to use */
3286       *field_length = 4;
3287       *blob_offset1 = 0;
3288       *blob_offset2 = 1;
3289       *blob_offset3 = *field_length;
3290       break;
3291     case ACN_BLOB_FIELD_TYPE10:
3292       /* double */
3293       /* Set field length and blob_offsets to use */
3294       *field_length = 8;
3295       *blob_offset1 = 0;
3296       *blob_offset2 = 1;
3297       *blob_offset3 = *field_length;
3298       break;
3299     case ACN_BLOB_FIELD_TYPE11:
3300       /* Set field length and blob_offsets to use */
3301       *field_length = tvb_get_guint8(tvb, blob_offset + 2);
3302       *blob_offset1 = 2;
3303       *blob_offset2 = 1;
3304       *blob_offset3 = (*field_length) - 2;
3305       break;
3306     case ACN_BLOB_FIELD_TYPE12:
3307       /* Set field length and blob_offsets to use for ignores */
3308       *field_length = 0;
3309       *blob_offset1 = 0;
3310       *blob_offset2 = 0;
3311       *blob_offset3 = 1;
3312       break;
3313     default:
3314       /* Set field length and blob_offsets to use for unknowns */
3315       *field_length = 0;
3316       *blob_offset1 = 0;
3317       *blob_offset2 = 0;
3318       *blob_offset3 = 1;
3319   }
3320 }
3321
3322 /******************************************************************************/
3323 /* Get Field Name */
3324 static const gchar *
3325 get_field_name(guint8 blob_type, guint16 field_number)
3326 {
3327   guint16 temp_field_number;
3328   const gchar *field_name;
3329
3330   /*Find the field sub tree name depending on the blob type.*/
3331   switch (blob_type) {
3332     case ACN_BLOB_IPV4:
3333     case ACN_BLOB_IPV6:
3334       field_name = val_to_str(field_number, acn_blob_ip_field_name, "not valid (%d)");
3335       break;
3336     case ACN_BLOB_ERROR1:
3337       field_name = val_to_str(field_number, acn_blob_error1_field_name, "not valid (%d)");
3338       break;
3339     case ACN_BLOB_ERROR2:
3340       field_name = val_to_str(field_number, acn_blob_error2_field_name, "not valid (%d)");
3341       break;
3342     case ACN_BLOB_METADATA:
3343       field_name = val_to_str(field_number, acn_blob_metadata_field_name, "not valid (%d)");
3344       break;
3345     case ACN_BLOB_METADATA_DEVICES:
3346       field_name = val_to_str(field_number, acn_blob_metadata_devices_field_name, "not valid (%d)");
3347       break;
3348     case ACN_BLOB_METADATA_TYPES:
3349       field_name = val_to_str(field_number, acn_blob_metadata_types_field_name, "not valid (%d)");
3350       break;
3351     case ACN_BLOB_TIME1:
3352       field_name = val_to_str(field_number, acn_blob_time1_field_name, "not valid (%d)");
3353       break;
3354     case ACN_BLOB_DIMMER_PROPERTIES:
3355       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_properties1_field_name_ext, "not valid (%d)");
3356       break;
3357     case ACN_BLOB_DIMMER_LOAD_PROPERTIES:
3358       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_load_properties1_field_name_ext, "not valid (%d)");
3359       break;
3360     case ACN_BLOB_DIMMING_RACK_PROPERTIES:
3361       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_properties1_field_name_ext, "not valid (%d)");
3362       break;
3363     case ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES:
3364       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_status_properties1_field_name_ext, "not valid (%d)");
3365       break;
3366     case ACN_BLOB_DIMMER_STATUS_PROPERTIES:
3367       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_status_properties1_field_name_ext, "not valid (%d)");
3368       break;
3369     case ACN_BLOB_SET_LEVELS_OPERATION:
3370       field_name = val_to_str(field_number, acn_blob_set_levels_operation_field_name, "not valid (%d)");
3371       break;
3372     case ACN_BLOB_PRESET_OPERATION:
3373       field_name = val_to_str(field_number, acn_blob_preset_operation_field_name, "not valid (%d)");
3374       break;
3375     case ACN_BLOB_ADVANCED_FEATURES_OPERATION:
3376       field_name = val_to_str(field_number, acn_blob_advanced_features_operation_field_name, "not valid (%d)");
3377       break;
3378     case ACN_BLOB_DIRECT_CONTROL_OPERATION:
3379       field_name = val_to_str(field_number, acn_blob_direct_control_operation_field_name, "not valid (%d)");
3380       break;
3381     case ACN_BLOB_GENERATE_CONFIG_OPERATION:
3382       field_name = val_to_str(field_number, acn_blob_generate_config_operation_field_name, "not valid (%d)");
3383       break;
3384     case ACN_BLOB_ERROR3:
3385       field_name = val_to_str(field_number, acn_blob_error3_field_name, "not valid (%d)");
3386       break;
3387     case ACN_BLOB_DIMMER_PROPERTIES2:
3388       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_properties2_field_name_ext, "not valid (%d)");
3389       break;
3390     case ACN_BLOB_DIMMER_LOAD_PROPERTIES2:
3391       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_load_properties2_field_name_ext, "not valid (%d)");
3392       break;
3393     case ACN_BLOB_DIMMER_RACK_PROPERTIES2:
3394       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_properties2_field_name_ext, "not valid (%d)");
3395       break;
3396     case ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2:
3397       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_status_properties2_field_name_ext, "not valid (%d)");
3398       break;
3399     case ACN_BLOB_DIMMER_STATUS_PROPERTIES2:
3400       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_status_properties2_field_name_ext, "not valid (%d)");
3401       break;
3402     case ACN_BLOB_TIME2:
3403       field_name = val_to_str(field_number, acn_blob_time2_field_name, "not valid (%d)");
3404       break;
3405     case ACN_BLOB_RPC:
3406       {
3407         temp_field_number = field_number;
3408         /* field names 4 repeats: 1, 2, 3, 4, 4, 4, ... */
3409         if (temp_field_number > 3)
3410           temp_field_number = 4;
3411         field_name = val_to_str(temp_field_number, acn_blob_rpc_field_name, "not valid (%d)");
3412       }
3413       break;
3414     case ACN_BLOB_DHCP_CONFIG_SUBNET:
3415       field_name = val_to_str(field_number, acn_blob_dhcp_config_subnet_field_name, "not valid (%d)");
3416       break;
3417     case ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE:
3418       field_name = val_to_str(field_number, acn_blob_dhcp_config_static_route_field_name, "not valid (%d)");
3419       break;
3420     case ACN_BLOB_ENERGY_MANAGEMENT:
3421       {
3422         temp_field_number = field_number;
3423         /* field names 4 through 7 repeat: 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, ... */
3424         if (temp_field_number > 3)
3425           temp_field_number = (field_number % 4) + 4;
3426         field_name = val_to_str(temp_field_number, acn_blob_energy_management_field_name, "not valid (%d)");
3427       }
3428       break;
3429     case ACN_BLOB_PRESET_PROPERTIES:
3430       field_name = val_to_str_ext(field_number, &acn_blob_preset_properties_field_name_ext, "not valid (%d)");
3431       break;
3432     case ACN_BLOB_TIME3:
3433       field_name = val_to_str(field_number, acn_blob_time3_field_name, "not valid (%d)");
3434       break;
3435     default:
3436       field_name = "Unknown field";
3437       break;
3438   }
3439
3440   return field_name;
3441 }
3442
3443 /******************************************************************************/
3444 /* Display Blob Field Value */
3445 static void
3446 display_blob_field_value(tvbuff_t *tvb, proto_tree *field_tree, guint16 field_number, guint8 blob_type, guint8 field_type, guint8 field_length, int blob_offset, guint8 blob_offset3, int display_variblob_as_CID)
3447 {
3448   gint8             field_value8;
3449   gint32            field_value32;
3450   const gchar      *field_string;
3451   proto_item       *ti;
3452
3453   /* Add field value to field sub tree */
3454   if (field_type == ACN_BLOB_FIELD_TYPE12) {
3455     /* "ignore" always takes priority */
3456     proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, field_length, "Ignore");
3457   }
3458   else if (blob_type == ACN_BLOB_IPV4) {
3459     proto_tree_add_item(field_tree, hf_acn_blob_field_value_ipv4, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
3460   }
3461   else if (blob_type == ACN_BLOB_IPV6) {
3462     proto_tree_add_item(field_tree, hf_acn_blob_field_value_ipv6, tvb, blob_offset, field_length, ENC_NA);
3463   }
3464   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 2)) {
3465     /* time zone index */
3466     field_value32 = (gint32)(tvb_get_ntohl(tvb, blob_offset));
3467     if (field_value32 == -1) {
3468       field_string = "Field Value: Custom";
3469     }
3470     else {
3471       field_string = val_to_str(field_value32, acn_blob_time3_time_zone_vals, "not valid (%d)");
3472     }
3473     proto_tree_add_int_format(field_tree, hf_acn_blob_time_zone, tvb, blob_offset, 4, field_value32, "%s", field_string);
3474   }
3475   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 10)) {
3476     /* DST type */
3477     field_value8 = tvb_get_guint8(tvb, blob_offset);
3478     field_string = val_to_str(field_value8, acn_blob_time3_dst_vals, "not valid (%d)");
3479     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
3480   }
3481   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 11)) {
3482     /* DST on month */
3483     field_value8 = tvb_get_guint8(tvb, blob_offset);
3484     field_string = val_to_str(field_value8, acn_blob_time3_month_vals, "not valid (%d)");
3485     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
3486   }
3487   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 12)) {
3488     /* DST on week */
3489     field_value8 = tvb_get_guint8(tvb, blob_offset);
3490     field_string = val_to_str(field_value8, acn_blob_time3_week_vals, "not valid (%d)");
3491     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
3492   }
3493   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 13)) {
3494     /* DST start day */
3495     field_value8 = tvb_get_guint8(tvb, blob_offset);
3496     field_string = val_to_str(field_value8, acn_blob_time3_day_vals, "not valid (%d)");
3497     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_start_day, tvb, blob_offset, 1, field_value8, "%s", field_string);
3498   }
3499   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 16)) {
3500     /* DST start locality */
3501     field_value8 = tvb_get_guint8(tvb, blob_offset);
3502     field_string = val_to_str(field_value8, acn_blob_time3_locality_vals, "not valid (%d)");
3503     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_start_locality, tvb, blob_offset, 1, field_value8, "%s", field_string);
3504   }
3505   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 17)) {
3506     /* DST off month */
3507     field_value8 = tvb_get_guint8(tvb, blob_offset);
3508     field_string = val_to_str(field_value8, acn_blob_time3_month_vals, "not valid (%d)");
3509     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
3510   }
3511   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 18)) {
3512     /* DST off week */
3513     field_value8 = tvb_get_guint8(tvb, blob_offset);
3514     field_string = val_to_str(field_value8, acn_blob_time3_week_vals, "not valid (%d)");
3515     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
3516   }
3517   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 19)) {
3518     /* DST stop day */
3519     field_value8 = tvb_get_guint8(tvb, blob_offset);
3520     field_string = val_to_str(field_value8, acn_blob_time3_day_vals, "not valid (%d)");
3521     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_stop_day, tvb, blob_offset, 1, field_value8, "%s", field_string);
3522   }
3523   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 22)) {
3524     /* DST stop locality */
3525     field_value8 = tvb_get_guint8(tvb, blob_offset);
3526     field_string = val_to_str(field_value8, acn_blob_time3_locality_vals, "not valid (%d)");
3527     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_stop_locality, tvb, blob_offset, 1, field_value8, "%s", field_string);
3528   }
3529   else {
3530     switch (field_type) {
3531       case ACN_BLOB_FIELD_TYPE1:
3532         /* Need special code to display signed data */
3533         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 1, ENC_BIG_ENDIAN);
3534         proto_item_set_len(ti, blob_offset3);
3535         break;
3536       case ACN_BLOB_FIELD_TYPE2:
3537         /* Need special code to display signed data */
3538         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 2, ENC_BIG_ENDIAN);
3539         proto_item_set_len(ti, blob_offset3);
3540         break;
3541       case ACN_BLOB_FIELD_TYPE3:
3542         /* Need special code to display signed data */
3543         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 3, ENC_BIG_ENDIAN);
3544         proto_item_set_len(ti, blob_offset3);
3545         break;
3546       case ACN_BLOB_FIELD_TYPE4:
3547         /* Need special code to display signed data */
3548         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 4, ENC_BIG_ENDIAN);
3549         proto_item_set_len(ti, blob_offset3);
3550         break;
3551       case ACN_BLOB_FIELD_TYPE9:
3552         /* float */
3553         proto_tree_add_item(field_tree, hf_acn_blob_field_value_float, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
3554         break;
3555       case ACN_BLOB_FIELD_TYPE10:
3556         /* double */
3557         proto_tree_add_item(field_tree, hf_acn_blob_field_value_double, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
3558         break;
3559       case ACN_BLOB_FIELD_TYPE11:
3560         if (blob_offset3 == 0) {
3561           proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, 0, "<none>");
3562         }
3563         else if (display_variblob_as_CID) {
3564           proto_tree_add_item(field_tree, hf_acn_blob_field_value_guid, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
3565         }
3566         else {
3567           proto_tree_add_item(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, blob_offset3, ENC_UTF_8 | ENC_NA);
3568         }
3569         break;
3570       /* "ignore", handled above */
3571       /* case ACN_BLOB_FIELD_TYPE12: */
3572       /*   proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, field_length, "Field Value: Ignore"); */
3573       /*   break; */
3574       default:
3575         proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, blob_offset3, ENC_BIG_ENDIAN);
3576         break;
3577     }
3578   }
3579 }
3580
3581 /******************************************************************************/
3582 /* Display Blob Field */
3583 static void
3584 display_blob_field(tvbuff_t *tvb, proto_tree *blob_tree, guint8 blob_type, int *blob_offset, guint16 *field_number, int display_variblob_as_CID)
3585 {
3586   guint8            field_type;
3587   guint8            field_length;
3588   guint8            blob_offset1;
3589   guint8            blob_offset2;
3590   guint8            blob_offset3;
3591   guint16           temp_field_number;
3592
3593   proto_item       *fi;
3594   proto_tree       *field_tree = NULL;
3595   proto_item       *ti;
3596
3597   const gchar      *field_name;
3598
3599   if ((blob_type == ACN_BLOB_ENERGY_MANAGEMENT) && (*field_number > 3)) {
3600     /* an exception to blob field rules: no "type" subfield, no "length" subfield */
3601
3602     /* field names 4 through 7 repeat: 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, ... */
3603     temp_field_number = (*field_number % 4) + 4;
3604
3605     switch (temp_field_number) {
3606       case 4:
3607         /* uint2 */
3608         field_length = 2;
3609         blob_offset3 = 2;
3610         field_name = get_field_name(blob_type, temp_field_number);
3611
3612         /* Create Sub Tree for Field Type*/
3613         fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length, ENC_NA);
3614         field_tree = proto_item_add_subtree(fi, ett_acn_blob);
3615
3616         /* Add the Field Name Found to Sub Tree */
3617         proto_item_append_text(fi, ": %s", field_name);
3618
3619         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, *blob_offset, 2, ENC_BIG_ENDIAN);
3620         proto_item_set_len(ti, blob_offset3);
3621         break;
3622       case 5:
3623       case 6:
3624       case 7:
3625         /* uint4 */
3626         field_length = 4;
3627         blob_offset3 = 4;
3628         field_name = get_field_name(blob_type, temp_field_number);
3629
3630         /* Create Sub Tree for Field Type*/
3631         fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length, ENC_NA);
3632         field_tree = proto_item_add_subtree(fi, ett_acn_blob);
3633
3634         /* Add the Field Name Found to Sub Tree */
3635         proto_item_append_text(fi, ": %s", field_name);
3636         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, *blob_offset, 4, ENC_BIG_ENDIAN);
3637         proto_item_set_len(ti, blob_offset3);
3638         break;
3639     }
3640   }
3641   else {
3642     /* Get field type*/
3643     field_type = tvb_get_guint8(tvb, *blob_offset);
3644     get_field_type_parameters(tvb, *blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
3645     field_name = get_field_name(blob_type, *field_number);
3646
3647     /* Create Sub Tree for Field Type*/
3648     fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length + 1, ENC_NA);
3649     field_tree = proto_item_add_subtree(fi, ett_acn_blob);
3650
3651     /* Add the Field Name Found to Sub Tree */
3652     proto_item_append_text(fi, ": %s", field_name);
3653
3654     /* Add field type to field sub tree */
3655     proto_tree_add_uint(field_tree, hf_acn_blob_field_type, tvb, *blob_offset, 1, field_type);
3656     *blob_offset += blob_offset1;
3657
3658     /* Add field length to field sub tree */
3659     proto_tree_add_uint(field_tree, hf_acn_blob_field_length, tvb, *blob_offset, 1, field_length);
3660     *blob_offset += blob_offset2;
3661
3662     display_blob_field_value(tvb, field_tree, *field_number, blob_type, field_type, field_length, *blob_offset, blob_offset3, display_variblob_as_CID);
3663   }
3664
3665   *blob_offset += blob_offset3;
3666   *field_number += 1;
3667 }
3668
3669 /******************************************************************************/
3670 /* Dissect Blob Metadata */
3671 static guint32
3672 dissect_acn_blob_metadata(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
3673 {
3674   guint8   blob_type = ACN_BLOB_METADATA;
3675   guint16  field_number = 1;
3676   gboolean display_variblob_as_CID;
3677
3678   /* Loop though dissecting fields until the end is reached */
3679   while (blob_offset < end_offset) {
3680     if (field_number == 15) {
3681
3682       display_variblob_as_CID = 1;
3683     }
3684     else {
3685       display_variblob_as_CID = 0;
3686
3687     }
3688
3689     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, display_variblob_as_CID);
3690   }
3691   return 0;
3692 }
3693
3694 /******************************************************************************/
3695 /* Dissect Blob Preset Properties */
3696 static guint32
3697 dissect_acn_blob_preset_properties(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
3698 {
3699   guint8       blob_type = ACN_BLOB_PRESET_PROPERTIES;
3700   guint8       field_type;
3701   guint8       field_length;
3702   guint8       blob_offset1;
3703   guint8       blob_offset2;
3704   guint8       blob_offset3;
3705   guint8       sub_blob_index;
3706   guint16      field_number = 1;
3707   guint8       max_sub_blobs = 192;
3708   proto_item  *fi;
3709   proto_tree  *sub_blob_tree = NULL;
3710   const gchar *field_name;
3711
3712   /* Loop though dissecting fields until the end is reached */
3713   while (blob_offset < end_offset) {
3714     if (field_number == 17) {
3715       /* Create subtree for "Levels" */
3716       field_type = tvb_get_guint8(tvb, blob_offset);
3717       get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
3718
3719       field_name = get_field_name(blob_type, field_number);
3720       field_number += 1;
3721
3722       /* Create Sub Tree for Field Type */
3723       fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, blob_offset, (field_length + 1) * max_sub_blobs, ENC_NA);
3724       sub_blob_tree = proto_item_add_subtree(fi, ett_acn_blob);
3725
3726       proto_item_append_text(fi, ": %s", field_name);
3727       sub_blob_index = 0;
3728
3729       while ((sub_blob_index < max_sub_blobs) && (blob_offset < end_offset)) {
3730         display_blob_field(tvb, sub_blob_tree, blob_type, &blob_offset, &field_number, 0);
3731
3732         sub_blob_index += 1;
3733       }
3734
3735     }
3736
3737     else {
3738       display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
3739     }
3740
3741   }
3742   return 0;
3743 }
3744
3745 /******************************************************************************/
3746 /* Dissect Blob Dimming Rack Properties v2 */
3747 static guint32
3748 dissect_acn_blob_dimming_rack_properties_v2(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
3749 {
3750   guint8       blob_type = ACN_BLOB_DIMMER_RACK_PROPERTIES2;
3751   guint16      field_number = 1;
3752   gboolean     display_variblob_as_CID;
3753
3754   /* Loop though dissecting fields until the end is reached */
3755   while (blob_offset < end_offset) {
3756     if (field_number == 12) {
3757
3758       display_variblob_as_CID = 1;
3759
3760     }
3761     else {
3762
3763       display_variblob_as_CID = 0;
3764
3765     }
3766
3767     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, display_variblob_as_CID);
3768   }
3769   return 0;
3770 }
3771
3772 /******************************************************************************/
3773 /* Dissect Blob Dimming Rack Status Properties v2 */
3774 static guint32
3775 dissect_acn_blob_dimming_rack_status_properties_v2(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
3776 {
3777   guint8       blob_type;
3778   guint8       field_type;
3779   guint8       field_length;
3780   guint8       blob_offset1;
3781   guint8       blob_offset2;
3782   guint8       blob_offset3;
3783   guint8       sub_blob_index;
3784   guint16      field_number;
3785
3786   int          number_of_sub_blobs;
3787
3788   proto_item  *fi;
3789   proto_tree  *sub_blob_tree = NULL;
3790
3791   const gchar *field_name;
3792
3793   /*First Assignments*/
3794   blob_type = ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2;
3795   field_number = 1;
3796   number_of_sub_blobs = 64;
3797
3798   /* Loop though dissecting fields until the end is reached */
3799   while (blob_offset < end_offset) {
3800     if (field_number == 22) {
3801       /* Create subtree for "Active Preset Group IDs" */
3802       field_type = tvb_get_guint8(tvb, blob_offset);
3803       get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
3804
3805       field_name = get_field_name(blob_type, field_number);
3806       field_number += 1;
3807
3808       /* Create Sub Tree for Field Type */
3809       fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, blob_offset, (field_length + 1) * number_of_sub_blobs, ENC_NA);
3810       sub_blob_tree = proto_item_add_subtree(fi, ett_acn_blob);
3811
3812       proto_item_append_text(fi, ": %s", field_name);
3813
3814       sub_blob_index = 0;
3815
3816       while ((sub_blob_index < number_of_sub_blobs) && (blob_offset < end_offset)) {
3817         display_blob_field(tvb, sub_blob_tree, blob_type, &blob_offset, &field_number, 0);
3818
3819         sub_blob_index += 1;
3820
3821       }
3822
3823     }
3824
3825     else {
3826       display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
3827     }
3828
3829   }
3830   return 0;
3831 }
3832
3833 /******************************************************************************/
3834 /* Get Blob Type From Fields
3835 Both "Dimmer Properties v2" and "Preset Properties" ended up with blob type 20 */
3836 static guint8
3837 get_blob_type_from_fields(tvbuff_t *tvb, int blob_offset, int end_offset)
3838 {
3839   guint8  field_type;
3840   guint8  field_length;
3841   guint8  blob_offset1;
3842   guint8  blob_offset2;
3843   guint8  blob_offset3;
3844   guint16 field_number = 1;
3845
3846   while (blob_offset < end_offset) {
3847     field_type = tvb_get_guint8(tvb, blob_offset);
3848     if (field_number == 12) {
3849       if (field_type == ACN_BLOB_FIELD_TYPE11) {
3850         /* string: dimmer name field */
3851         return ACN_BLOB_DIMMER_PROPERTIES2;
3852       }
3853       /* number: preset number field */
3854       return ACN_BLOB_PRESET_PROPERTIES;
3855     }
3856     get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
3857     blob_offset += blob_offset2 + blob_offset3;
3858     field_number += 1;
3859   }
3860
3861   return ACN_BLOB_DIMMER_PROPERTIES2;
3862 }
3863
3864 /******************************************************************************/
3865 /* Dissect Blob */
3866 static guint32
3867 dissect_acn_blob(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *pdu_tree, int blob_offset, int end_offset)
3868 {
3869   /* Declarations for blobs*/
3870   guint8     version;
3871   guint8     range;
3872   guint8     blob_type;
3873   guint8     range_number;
3874   guint16    field_number = 1;
3875   proto_item *bi;
3876   proto_tree *blob_tree = NULL;
3877   const gchar *blob_name;
3878   /* const gchar *range_type; */
3879
3880   /* Add blob to tree */
3881   bi = proto_tree_add_item(pdu_tree, hf_acn_blob, tvb, blob_offset, end_offset, ENC_NA);
3882   blob_tree = proto_item_add_subtree(bi, 0);
3883   end_offset = blob_offset + end_offset;
3884   blob_offset += 4;
3885
3886   /* Add Blob version item to tree */
3887   version = tvb_get_guint8(tvb, blob_offset);
3888   proto_tree_add_item(blob_tree, hf_acn_blob_version, tvb, blob_offset, 1, version);
3889   blob_offset += 1;
3890
3891   /* Add Blob Start and End Range Info */
3892   range = tvb_get_guint8(tvb, blob_offset);
3893   proto_tree_add_item(blob_tree, hf_acn_blob_range_type, tvb, blob_offset, 1, range);
3894   /* range_type = val_to_str(range, acn_blob_range_type_vals, "not valid (%d)"); */
3895   blob_offset += 1;
3896
3897   /* Add Blob Range Number */
3898   range_number = tvb_get_guint8(tvb, blob_offset);
3899   proto_tree_add_item(blob_tree, hf_acn_blob_range_number, tvb, blob_offset, 1, range_number);
3900   blob_offset += 1;
3901
3902   /* Add Blob Meta-Type */
3903   blob_type = tvb_get_guint8(tvb, blob_offset);
3904   if (blob_type == ACN_BLOB_DIMMER_PROPERTIES2) {
3905     /* Dimmer  Properties v2 and Preset Properties have the same 'type' value (20) */
3906     blob_type = get_blob_type_from_fields(tvb, blob_offset + 1, end_offset);
3907   }
3908
3909   proto_tree_add_item(blob_tree, hf_acn_blob_type, tvb, blob_offset, 1, blob_type);
3910
3911   blob_name = val_to_str(blob_type, acn_blob_type_vals, "not valid (%d)");
3912   proto_item_append_text(bi, ": %s", blob_name);
3913   blob_offset += 1;
3914
3915   if (blob_type == ACN_BLOB_METADATA) {
3916     return dissect_acn_blob_metadata(tvb, blob_tree, blob_offset, end_offset);
3917   }
3918   if (blob_type == ACN_BLOB_PRESET_PROPERTIES) {
3919     return dissect_acn_blob_preset_properties(tvb, blob_tree, blob_offset, end_offset);
3920   }
3921   if (blob_type == ACN_BLOB_DIMMER_RACK_PROPERTIES2) {
3922     return dissect_acn_blob_dimming_rack_properties_v2(tvb, blob_tree, blob_offset, end_offset);
3923   }
3924   if (blob_type == ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2) {
3925     return dissect_acn_blob_dimming_rack_status_properties_v2(tvb, blob_tree, blob_offset, end_offset);
3926   }
3927
3928   /* Loop though dissecting fields until the end is reached */
3929   while (blob_offset < end_offset) {
3930     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
3931   }
3932   return 0;
3933 }
3934
3935 /******************************************************************************/
3936 /* Dissect wrapped SDT PDU                                                    */
3937 static guint32
3938 dissect_acn_dmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
3939 {
3940   /* common to all pdu */
3941   gboolean          blob_exists = 0;
3942   guint8            pdu_flags;
3943   guint32           pdu_start;
3944   guint32           pdu_length;
3945   guint32           pdu_flvh_length; /* flags, length, vector, header */
3946   guint8            D;
3947   guint8            octet;
3948   guint32           length1;
3949   guint32           length2;
3950   guint32           length3;
3951   guint32           vector_offset;
3952   guint32           header_offset;
3953   guint32           data_offset;
3954   guint32           old_offset;
3955   guint32           end_offset;
3956   guint32           data_length;
3957   guint32           address_count;
3958   guint32           blob_offset;
3959   guint32           blob_end_offset = 0;
3960
3961   proto_item       *ti, *pi;
3962   proto_tree       *pdu_tree  = NULL;
3963   proto_tree       *flag_tree = NULL;
3964
3965   /* this pdu */
3966   const gchar      *name;
3967   acn_dmp_adt_type  adt       = {0,0,0,0,0,0};
3968   acn_dmp_adt_type  adt2      = {0,0,0,0,0,0};
3969   guint32           vector;
3970
3971   /* save start of pdu block */
3972   pdu_start = offset;
3973
3974   /* get PDU flags and length flag first */
3975   octet     = tvb_get_guint8(tvb, offset++);
3976   pdu_flags = octet & 0xf0;
3977   length1   = octet & 0x0f;     /* bottom 4 bits only */
3978   length2   = tvb_get_guint8(tvb, offset++);
3979
3980   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
3981   /* flvh = flags, length, vector, header */
3982   if (pdu_flags & ACN_PDU_FLAG_L) {
3983     length3 = tvb_get_guint8(tvb, offset);
3984     offset += 1;
3985     pdu_length = length3 | (length2 << 8) | (length1 << 16);
3986     pdu_flvh_length = 3;
3987   } else {
3988     pdu_length = length2 | (length1 << 8);
3989     pdu_flvh_length = 2;
3990   }
3991   /* offset should now be pointing to vector (if one exists) */
3992
3993   /* Add pdu item and tree */
3994   ti       = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
3995   pdu_tree = proto_item_add_subtree(ti, ett_acn_dmp_pdu);
3996
3997   /* Add flag item and tree */
3998   pi        = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
3999   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4000   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4001   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4002   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4003   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4004
4005   /* Add PDU Length item */
4006   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4007
4008   /* Set vector offset */
4009   if (pdu_flags & ACN_PDU_FLAG_V) {
4010     /* use new values */
4011     vector_offset             = offset;
4012     last_pdu_offsets->vector  = offset;
4013     offset                   += 1;
4014     pdu_flvh_length++;
4015   } else {
4016     /* use last values */
4017     vector_offset             = last_pdu_offsets->vector;
4018   }
4019   /* offset should now be pointing to header (if one exists) */
4020
4021   /* Add Vector item */
4022   vector = tvb_get_guint8(tvb, vector_offset);
4023   proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
4024
4025   /* Add Vector item to tree*/
4026   name = val_to_str(vector, acn_dmp_vector_vals, "not valid (%d)");
4027   proto_item_append_text(ti, ": ");
4028   proto_item_append_text(ti, "%s", name);
4029
4030   /* Set header offset */
4031   if (pdu_flags & ACN_PDU_FLAG_H) {
4032     /* use new values */
4033     header_offset             = offset;
4034     last_pdu_offsets->header  = offset;
4035     offset                   += 1;
4036     pdu_flvh_length++;
4037   } else {
4038     /* use last values */
4039     header_offset             = last_pdu_offsets->header;
4040   }
4041   /* offset should now be pointing to data (if one exists) */
4042
4043   /* header contains address and data type */
4044   acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
4045
4046   /* Adjust data */
4047   if (pdu_flags & ACN_PDU_FLAG_D) {
4048     /* use new values */
4049     data_offset                   = offset;
4050     data_length                   = pdu_length - pdu_flvh_length;
4051     last_pdu_offsets->data        = offset;
4052     last_pdu_offsets->data_length = data_length;
4053   } else {
4054     /* use last values */
4055     data_offset                   = last_pdu_offsets->data;
4056     data_length                   = last_pdu_offsets->data_length;
4057   }
4058   end_offset = data_offset + data_length;
4059
4060   /* Check if blob exists, find beginning offset */
4061   blob_offset = data_offset;
4062   while (blob_offset < end_offset - 3 && blob_exists != 1) {
4063     if (tvb_get_ntohl(tvb, blob_offset) == 0x426c6f62) {
4064       /* 0x426c6f62 == "Blob" */
4065       blob_exists = 1;
4066       break;
4067     }
4068     blob_offset += 1;
4069   }
4070
4071   /* Fix the end_offset for finding Address-Data pair if blob exists*/
4072   if (blob_exists == 1) {
4073     blob_end_offset = end_offset - blob_offset;
4074     end_offset = blob_offset;
4075     data_length = blob_offset - data_offset;
4076   }
4077
4078   switch (vector) {
4079     case ACN_DMP_VECTOR_UNKNOWN:
4080       break;
4081     case ACN_DMP_VECTOR_GET_PROPERTY:
4082       /* Rip through property address */
4083       while (data_offset < end_offset) {
4084         old_offset      = data_offset;
4085         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4086         if (old_offset == data_offset) break;
4087       }
4088       break;
4089     case ACN_DMP_VECTOR_SET_PROPERTY:
4090       /* Rip through Property Address-Data pairs                                 */
4091       /* But, in reality, this generally won't work as we have know way of       */
4092       /* calculating the next Address-Data pair                                  */
4093       while (data_offset < end_offset) {
4094         old_offset      = data_offset;
4095         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4096         if (old_offset == data_offset) break;
4097
4098         adt.data_length = data_length - (data_offset - old_offset);
4099         old_offset      = data_offset;
4100         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
4101         if (old_offset == data_offset) break;
4102       }
4103       break;
4104     case ACN_DMP_VECTOR_GET_PROPERTY_REPLY:
4105       /* Rip through Property Address-Data pairs */
4106       /* But, in reality, this generally won't work as we have know way of       */
4107       /* calculating the next Address-Data pair                                  */
4108       while (data_offset < end_offset) {
4109         old_offset      = data_offset;
4110         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4111         if (old_offset == data_offset) break;
4112
4113         adt.data_length = data_length - (data_offset - old_offset);
4114         old_offset      = data_offset;
4115         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
4116         if (old_offset == data_offset) break;
4117       }
4118       break;
4119     case ACN_DMP_VECTOR_EVENT:
4120     case ACN_DMP_VECTOR_SYNC_EVENT:
4121       /* Rip through Property Address-Data pairs */
4122       /* But, in reality, this generally won't work as we have know way of       */
4123       /* calculating the next Address-Data pair                                  */
4124       while (data_offset < end_offset) {
4125         old_offset      = data_offset;
4126         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4127         if (old_offset == data_offset) break;
4128
4129         adt.data_length = data_length - (data_offset - old_offset);
4130         old_offset      = data_offset;
4131         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
4132         if (old_offset == data_offset) break;
4133       }
4134       break;
4135     case ACN_DMP_VECTOR_MAP_PROPERTY:
4136       /* Virtual Address type */
4137       data_offset = acn_add_dmp_address_type(tvb, pinfo, pdu_tree, data_offset, &adt2);
4138       /* Rip through Actual-Virtual Address Pairs */
4139       while (data_offset < end_offset) {
4140         /* actual */
4141         old_offset      = data_offset;
4142         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4143         if (old_offset == data_offset) break;
4144         D = ACN_DMP_ADT_EXTRACT_D(adt.flags);
4145         switch (D) {
4146           case ACN_DMP_ADT_D_NS:
4147             address_count = 1;
4148             break;
4149           case ACN_DMP_ADT_D_RS:
4150             address_count = 1;
4151             break;
4152           case ACN_DMP_ADT_D_RE:
4153             address_count = adt.count;
4154             break;
4155             /*case ACN_DMP_ADT_D_RM: */
4156           default:
4157             /* OUCH */
4158             return pdu_start + pdu_length;
4159             break;
4160         }
4161
4162         /* virtual */
4163         while (address_count > 0) {
4164           data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt2);
4165           address_count--;
4166         }
4167       }
4168       break;
4169     case ACN_DMP_VECTOR_UNMAP_PROPERTY:
4170       /* Rip through Actual Property Address */
4171       while (data_offset < end_offset) {
4172         old_offset      = data_offset;
4173         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4174         if (old_offset == data_offset) break;
4175       }
4176       break;
4177     case ACN_DMP_VECTOR_SUBSCRIBE:
4178       /* Rip through Property Address */
4179       while (data_offset < end_offset) {
4180         old_offset      = data_offset;
4181         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4182         if (old_offset == data_offset) break;
4183       }
4184       break;
4185     case ACN_DMP_VECTOR_UNSUBSCRIBE:
4186       /* Rip through Property Address */
4187       while (data_offset < end_offset) {
4188         old_offset      = data_offset;
4189         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4190         if (old_offset == data_offset) break;
4191       }
4192       break;
4193     case ACN_DMP_VECTOR_GET_PROPERTY_FAIL:
4194       /* Rip through Address-Reason Code Pairs */
4195       while (data_offset < end_offset) {
4196         old_offset      = data_offset;
4197         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4198         if (old_offset == data_offset) break;
4199
4200         adt.data_length = data_length - (data_offset - old_offset);
4201         old_offset      = data_offset;
4202         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
4203         if (old_offset == data_offset) break;
4204       }
4205       break;
4206     case ACN_DMP_VECTOR_SET_PROPERTY_FAIL:
4207       /* Rip through Address-Reason Code Pairs */
4208       while (data_offset < end_offset) {
4209         old_offset      = data_offset;
4210         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4211         if (old_offset == data_offset) break;
4212
4213         adt.data_length = data_length - (data_offset - old_offset);
4214         old_offset      = data_offset;
4215         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
4216         if (old_offset == data_offset) break;
4217       }
4218       break;
4219     case ACN_DMP_VECTOR_MAP_PROPERTY_FAIL:
4220       /* Rip through Address-Reason Code Pairs */
4221       while (data_offset < end_offset) {
4222         old_offset      = data_offset;
4223         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4224         if (old_offset == data_offset) break;
4225
4226         adt.data_length = data_length - (data_offset - old_offset);
4227         old_offset      = data_offset;
4228         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
4229         if (old_offset == data_offset) break;
4230       }
4231       break;
4232     case ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT:
4233       /* Rip through Property Addresses */
4234       while (data_offset < end_offset) {
4235         old_offset      = data_offset;
4236         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4237         if (old_offset == data_offset) break;
4238       }
4239       break;
4240     case ACN_DMP_VECTOR_SUBSCRIBE_REJECT:
4241       /* Rip through Address-Reason Code Pairs */
4242       while (data_offset < end_offset) {
4243         old_offset      = data_offset;
4244         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4245         if (old_offset == data_offset) break;
4246
4247         adt.data_length = data_length - (data_offset - old_offset);
4248         old_offset      = data_offset;
4249         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
4250         if (old_offset == data_offset) break;
4251       }
4252       break;
4253     case ACN_DMP_VECTOR_ALLOCATE_MAP:
4254       /* No data for this */
4255       break;
4256     case ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY:
4257       /* Single reason code  */
4258       proto_tree_add_item(pdu_tree, hf_acn_dmp_reason_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
4259       /* data_offset += 1; */
4260     case ACN_DMP_VECTOR_DEALLOCATE_MAP:
4261       /* No data for this */
4262       break;
4263   }
4264
4265   /* If blob exists, call function to dissect blob*/
4266   if (blob_exists == 1) {
4267     dissect_acn_blob(tvb, pinfo, pdu_tree, blob_offset, blob_end_offset);
4268   }
4269
4270   return pdu_start + pdu_length;
4271 }
4272
4273
4274 /******************************************************************************/
4275 /* Dissect wrapped SDT PDU                                                    */
4276 static guint32
4277 dissect_acn_sdt_wrapped_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
4278 {
4279   /* common to all pdu */
4280   guint8       pdu_flags;
4281   guint32      pdu_start;
4282   guint32      pdu_length;
4283   guint32      pdu_flvh_length; /* flags, length, vector, header */
4284   guint8       octet;
4285   guint32      length1;
4286   guint32      length2;
4287   guint32      length3;
4288   guint32      vector_offset;
4289   guint32      data_offset;
4290   guint32      data_length;
4291
4292   proto_item  *ti, *pi;
4293   proto_tree  *pdu_tree  = NULL;
4294   proto_tree  *flag_tree = NULL;
4295
4296   /* this pdu */
4297   const gchar *name;
4298   guint32      vector;
4299
4300   /* save start of pdu block */
4301   pdu_start = offset;
4302
4303   /* get PDU flags and length flag first */
4304   octet     = tvb_get_guint8(tvb, offset++);
4305   pdu_flags = octet & 0xf0;
4306   length1   = octet & 0x0f;     /* bottom 4 bits only */
4307   length2   = tvb_get_guint8(tvb, offset++);
4308
4309   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
4310   /* flvh = flags, length, vector, header */
4311   if (pdu_flags & ACN_PDU_FLAG_L) {
4312     length3 = tvb_get_guint8(tvb, offset);
4313     offset += 1;
4314     pdu_length = length3 | (length2 << 8) | (length1 << 16);
4315     pdu_flvh_length = 3;
4316   } else {
4317     pdu_length = length2 | (length1 << 8);
4318     pdu_flvh_length = 2;
4319   }
4320   /* offset should now be pointing to vector (if one exists) */
4321
4322   /* Add pdu item and tree */
4323   ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
4324   pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_pdu);
4325
4326   /* Add flag item and tree */
4327   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
4328   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4329   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4330   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4331   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4332   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4333
4334   /* Add PDU Length item */
4335   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4336
4337   /* Set vector offset */
4338   if (pdu_flags & ACN_PDU_FLAG_V) {
4339     /* use new values */
4340     vector_offset = offset;
4341     last_pdu_offsets->vector = offset;
4342     offset += 1;
4343     pdu_flvh_length++;
4344   } else {
4345     /* use last values */
4346     vector_offset = last_pdu_offsets->vector;
4347   }
4348   /* offset should now be pointing to header (if one exists) */
4349
4350   /* Add Vector item */
4351   vector = tvb_get_guint8(tvb, vector_offset);
4352   proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
4353
4354   /* Add Vector item to tree*/
4355   name = val_to_str(vector, acn_sdt_vector_vals, "not valid (%d)");
4356   proto_item_append_text(ti, ": ");
4357   proto_item_append_text(ti, "%s", name);
4358
4359   /* NO HEADER DATA ON THESE* (at least so far) */
4360
4361   /* Adjust data */
4362   if (pdu_flags & ACN_PDU_FLAG_D) {
4363     /* use new values */
4364     data_offset = offset;
4365     data_length = pdu_length - pdu_flvh_length;
4366     last_pdu_offsets->data = offset;
4367     last_pdu_offsets->data_length = data_length;
4368   } else {
4369     /* use last values */
4370     data_offset = last_pdu_offsets->data;
4371     /*data_length = last_pdu_offsets->data_length;*/
4372   }
4373
4374   switch (vector) {
4375     case ACN_SDT_VECTOR_ACK:
4376       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4377       /*data_offset += 4;*/
4378       break;
4379     case ACN_SDT_VECTOR_CHANNEL_PARAMS:
4380       data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
4381       data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Ad-hoc Address:");
4382       /*data_offset =*/ acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, hf_acn_adhoc_expiry);
4383       break;
4384     case ACN_SDT_VECTOR_LEAVE:
4385       /* nothing more */
4386       break;
4387     case ACN_SDT_VECTOR_CONNECT:
4388       /* Protocol ID item */
4389       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4390       /*data_offset += 4;*/
4391       break;
4392     case ACN_SDT_VECTOR_CONNECT_ACCEPT:
4393       /* Protocol ID item */
4394       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4395       /*data_offset += 4;*/
4396       break;
4397     case ACN_SDT_VECTOR_CONNECT_REFUSE:
4398       /* Protocol ID item */
4399       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4400       data_offset += 4;
4401       proto_tree_add_item(pdu_tree, hf_acn_refuse_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
4402       /*data_offset += 1;*/
4403       break;
4404     case ACN_SDT_VECTOR_DISCONNECT:
4405       /* Protocol ID item */
4406       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4407       /*data_offset += 4;*/
4408       break;
4409     case ACN_SDT_VECTOR_DISCONNECTING:
4410       /* Protocol ID item */
4411       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
4412       data_offset += 4;
4413       proto_tree_add_item(pdu_tree, hf_acn_reason_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
4414       /*data_offset += 1;*/
4415       break;
4416
4417   }
4418
4419   return pdu_start + pdu_length;
4420 }
4421
4422
4423 /******************************************************************************/
4424 /* Dissect SDT Client PDU                                                     */
4425 static guint32
4426 dissect_acn_sdt_client_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
4427 {
4428   /* common to all pdu */
4429   guint8           pdu_flags;
4430   guint32          pdu_start;
4431   guint32          pdu_length;
4432   guint32          pdu_flvh_length; /* flags, length, vector, header */
4433   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
4434   guint8           octet;
4435   guint32          length1;
4436   guint32          length2;
4437   guint32          length3;
4438   guint32          vector_offset;
4439   guint32          header_offset;
4440   guint32          data_offset;
4441   guint32          data_length;
4442   guint32          old_offset;
4443   guint32          end_offset;
4444
4445   proto_item      *ti, *pi;
4446   proto_tree      *pdu_tree    = NULL;
4447   proto_tree      *flag_tree   = NULL;
4448
4449   /* this pdu */
4450   const gchar     *name;
4451   guint32          member_id;
4452   guint32          protocol_id;
4453   guint16          association;
4454
4455   /* save start of pdu block */
4456   pdu_start         = offset;
4457   pdu_offsets.start = pdu_start;
4458
4459   /* get PDU flags and length flag first */
4460   octet     = tvb_get_guint8(tvb, offset++);
4461   pdu_flags = octet & 0xf0;
4462   length1   = octet & 0x0f;     /* bottom 4 bits only */
4463   length2   = tvb_get_guint8(tvb, offset++);
4464
4465   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
4466   /* flvh = flags, length, vector, header */
4467   if (pdu_flags & ACN_PDU_FLAG_L) {
4468     length3 = tvb_get_guint8(tvb, offset);
4469     offset += 1;
4470     pdu_length = length3 | (length2 << 8) | (length1 << 16);
4471     pdu_flvh_length = 3;
4472   } else {
4473     pdu_length = length2 | (length1 << 8);
4474     pdu_flvh_length = 2;
4475   }
4476   /* offset should now be pointing to vector (if one exists) */
4477
4478   /* Add pdu item and tree */
4479   ti       = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
4480   pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_client_pdu);
4481
4482   /* Add flag item and tree */
4483   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
4484   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4485   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4486   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4487   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4488   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4489
4490   /* Add PDU Length item */
4491   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4492
4493   /* Set vector offset */
4494   if (pdu_flags & ACN_PDU_FLAG_V) {
4495     /* use new values */
4496     vector_offset = offset;
4497     last_pdu_offsets->vector = offset;
4498     offset += 2;
4499     pdu_flvh_length += 2;
4500   } else {
4501     /* use last values */
4502     vector_offset = last_pdu_offsets->vector;
4503   }
4504   /* offset should now be pointing to header (if one exists) */
4505
4506   /* add Member ID item  */
4507   member_id = tvb_get_ntohs(tvb, vector_offset);
4508   proto_tree_add_uint(pdu_tree, hf_acn_member_id, tvb, vector_offset, 2, member_id);
4509
4510   /* Set header offset */
4511   if (pdu_flags & ACN_PDU_FLAG_H) {
4512     /* use new values */
4513     header_offset             = offset;
4514     last_pdu_offsets->header  = offset;
4515     offset                   += 6;
4516     pdu_flvh_length          += 6;
4517   } else {
4518     /* use last values */
4519     header_offset             = last_pdu_offsets->header;
4520   }
4521   /* offset should now be pointing to data (if one exists) */
4522
4523   /* add Protocol ID item (Header)*/
4524   protocol_id = tvb_get_ntohl(tvb, header_offset);
4525   proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, header_offset, 4, protocol_id);
4526   header_offset += 4;
4527
4528   /* Add protocol to tree*/
4529   name = val_to_str(protocol_id, acn_protocol_id_vals, "id not valid (%d)");
4530   proto_item_append_text(ti, ": ");
4531   proto_item_append_text(ti, "%s", name);
4532
4533   /* add association item */
4534   association = tvb_get_ntohs(tvb, header_offset);
4535   proto_tree_add_uint(pdu_tree, hf_acn_association, tvb, header_offset, 2, association);
4536   /*header_offset += 2;*/
4537
4538   /* Adjust data */
4539   if (pdu_flags & ACN_PDU_FLAG_D) {
4540     /* use new values */
4541     data_offset = offset;
4542     data_length = pdu_length - pdu_flvh_length;
4543     last_pdu_offsets->data = offset;
4544     last_pdu_offsets->data_length = data_length;
4545   } else {
4546     /* use last values */
4547     data_offset = last_pdu_offsets->data;
4548     data_length = last_pdu_offsets->data_length;
4549   }
4550   end_offset = data_offset + data_length;
4551
4552   switch (protocol_id) {
4553     case ACN_PROTOCOL_ID_SDT:
4554       while (data_offset < end_offset) {
4555         old_offset  = data_offset;
4556         data_offset = dissect_acn_sdt_wrapped_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
4557         if (old_offset == data_offset) break;
4558       }
4559       break;
4560     case ACN_PROTOCOL_ID_DMP:
4561       while (data_offset < end_offset) {
4562         old_offset  = data_offset;
4563         data_offset = dissect_acn_dmp_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
4564         if (data_offset == old_offset) break;
4565       }
4566       break;
4567   }
4568   return pdu_start + pdu_length;
4569 }
4570
4571
4572 /******************************************************************************/
4573 /* level to string (ascii)                                                    */
4574 /*  level    : 8 bit value                                                    */
4575 /*  string   : pointer to buffer to fill                                      */
4576 /*  leading_char: character to buffer left of digits                             */
4577 /*  min_char : minimum number of characters (for filling, not including space)*/
4578 /*  show_zero: show zeros or dots                                             */
4579 /* also adds a space to right end                                             */
4580 /*                                                                            */
4581 /*  returns end of string                                                     */
4582 /*  faster than printf()                                                      */
4583 static char *
4584 ltos(guint8 level, gchar *string, guint8 base, gchar leading_char, guint8 min_chars, gboolean show_zero)
4585 {
4586   guint8 i;
4587   /* verify base */
4588   if (base < 2 || base > 16) {
4589     *string = '\0';
4590     return(string);
4591   }
4592   /* deal with zeros */
4593   if ((level == 0) && (!show_zero)) {
4594     for (i=0; i<min_chars; i++) {
4595       string[i] = '.';
4596     }
4597     string[i++] = ' ';
4598     string[i] = '\0';
4599     return(string + i);
4600   }
4601
4602   i = 0;
4603   /* do our convert, comes out backwards! */
4604   do {
4605     string[i++] = "0123456789ABCDEF"[level % base];
4606   } while ((level /= base) > 0);
4607
4608   /* expand to needed character */
4609   for (; i<min_chars; i++) {
4610     string[i] = leading_char;
4611   }
4612   /* terminate */
4613   string[i] = '\0';
4614
4615   /* now reverse (and correct) the order */
4616   g_strreverse(string);
4617
4618   /* add a space at the end (ok it's at the start but it will be at the end)*/
4619   string[i++] = ' ';
4620   string[i] = '\0';
4621   return(string + i);
4622 }
4623
4624
4625 /******************************************************************************/
4626 /* Dissect DMX data PDU                                                       */
4627 #define BUFFER_SIZE 128
4628 static guint32
4629 dissect_acn_dmx_data_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
4630 {
4631   /* common to all pdu */
4632   guint8            pdu_flags;
4633   guint32           pdu_start;
4634   guint32           pdu_length;
4635   guint32           pdu_flvh_length; /* flags, length, vector, header */
4636   guint8            octet;
4637   guint32           length1;
4638   guint32           length2;
4639   guint32           length3;
4640   guint32           vector_offset;
4641   guint32           data_offset;
4642   guint32           end_offset;
4643   guint32           data_length;
4644   guint32           header_offset;
4645   guint32           total_cnt;
4646   guint32           item_cnt;
4647
4648   proto_item       *ti, *pi;
4649   proto_tree       *pdu_tree;
4650   proto_tree       *flag_tree;
4651
4652 /* this pdu */
4653   acn_dmp_adt_type  adt       = {0,0,0,0,0,0};
4654   const gchar      *name;
4655   guint32           vector;
4656   gchar            *buffer;
4657   char             *buf_ptr;
4658   guint             x;
4659   guint8            level;
4660   guint8            min_char;
4661   guint8            base;
4662   gchar             leading_char;
4663   guint             perline;
4664   guint             halfline;
4665   guint16           dmx_count;
4666   guint16           dmx_start_code;
4667   guint16           info_start_code;
4668   guint8            dmx_2_start_code;
4669
4670   buffer = (gchar*)wmem_alloc(wmem_packet_scope(), BUFFER_SIZE);
4671   buffer[0] = '\0';
4672
4673   /* save start of pdu block */
4674   pdu_start = offset;
4675
4676   /* get PDU flags and length flag first */
4677   octet     = tvb_get_guint8(tvb, offset++);
4678   pdu_flags = octet & 0xf0;
4679   length1   = octet & 0x0f;     /* bottom 4 bits only */
4680   length2   = tvb_get_guint8(tvb, offset++);
4681
4682   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
4683   /* flvh = flags, length, vector, header */
4684   if (pdu_flags & ACN_PDU_FLAG_L) {
4685     length3 = tvb_get_guint8(tvb, offset);
4686     offset += 1;
4687     pdu_length = length3 | (length2 << 8) | (length1 << 16);
4688     pdu_flvh_length = 3;
4689   } else {
4690     pdu_length = length2 | (length1 << 8);
4691     pdu_flvh_length = 2;
4692   }
4693   /* offset should now be pointing to vector (if one exists) */
4694
4695   /* Add pdu item and tree */
4696   ti       = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
4697   pdu_tree = proto_item_add_subtree(ti, ett_acn_dmx_data_pdu);
4698
4699   /* Add flag item and tree */
4700   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
4701   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4702   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4703   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4704   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4705   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4706
4707   /* Add PDU Length item */
4708   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4709
4710   /* Set vector offset */
4711   if (pdu_flags & ACN_PDU_FLAG_V) {
4712     /* use new values */
4713     vector_offset = offset;
4714     last_pdu_offsets->vector = offset;
4715     offset += 1;
4716     pdu_flvh_length += 1;
4717   } else {
4718     /* use last values */
4719     vector_offset = last_pdu_offsets->vector;
4720   }
4721   /* offset should now be pointing to header (if one exists) */
4722
4723   /* Add Vector item */
4724   vector = tvb_get_guint8(tvb, vector_offset);
4725   proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
4726
4727   /* Add Vector item to tree*/
4728   name = val_to_str(vector, acn_dmp_vector_vals, "not valid (%d)");
4729   proto_item_append_text(ti, ": ");
4730   proto_item_append_text(ti, "%s", name);
4731
4732   /* Set header offset */
4733   if (pdu_flags & ACN_PDU_FLAG_H) {
4734     /* use new values */
4735     header_offset = offset;
4736     last_pdu_offsets->header = offset;
4737     offset += 1;
4738     pdu_flvh_length++;
4739   } else {
4740     /* use last values */
4741     header_offset = last_pdu_offsets->header;
4742   }
4743   /* offset should now be pointing to data (if one exists) */
4744
4745   /* process based on vector */
4746   acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
4747
4748   /* Adjust data */
4749   if (pdu_flags & ACN_PDU_FLAG_D) {
4750     /* use new values */
4751     data_offset = offset;
4752     data_length = pdu_length - pdu_flvh_length;
4753     last_pdu_offsets->data = offset;
4754     last_pdu_offsets->data_length = data_length;
4755   } else {
4756     /* use last values */
4757     data_offset = last_pdu_offsets->data;
4758     data_length = last_pdu_offsets->data_length;
4759   }
4760   end_offset = data_offset + data_length;
4761
4762   switch (vector) {
4763     case ACN_DMP_VECTOR_SET_PROPERTY:
4764       dmx_start_code = tvb_get_ntohs(tvb, data_offset);
4765       if (protocol_id==ACN_PROTOCOL_ID_DMX_2) {
4766         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_first_property_address, tvb, data_offset, 2, ENC_BIG_ENDIAN);
4767       } else{
4768         proto_tree_add_item(pdu_tree, hf_acn_dmx_start_code, tvb, data_offset, 2, ENC_BIG_ENDIAN);
4769       }
4770       data_offset += 2;
4771       proto_tree_add_item(pdu_tree, hf_acn_dmx_increment, tvb, data_offset, 2, ENC_BIG_ENDIAN);
4772       data_offset += 2;
4773       dmx_count    = tvb_get_ntohs(tvb, data_offset);
4774       proto_tree_add_item(pdu_tree, hf_acn_dmx_count, tvb, data_offset, 2, ENC_BIG_ENDIAN);
4775       data_offset += 2;
4776
4777     if (protocol_id == ACN_PROTOCOL_ID_DMX_2) {
4778         dmx_2_start_code = (guint8)tvb_get_ntohs(tvb, data_offset - 1);
4779         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_start_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
4780         data_offset += 1;
4781         dmx_count   -= 1;
4782       }
4783
4784       buf_ptr = buffer;
4785
4786       switch (global_acn_dmx_display_line_format) {
4787         case ACN_PREF_DMX_DISPLAY_16PL:
4788           perline  = 16;
4789           halfline = 8;
4790           break;
4791         default:
4792           perline  = 20;
4793           halfline = 10;
4794       }
4795
4796       /* values base on display mode */
4797       switch ((guint)global_acn_dmx_display_view) {
4798         case ACN_PREF_DMX_DISPLAY_HEX:
4799           min_char = 2;
4800           base     = 16;
4801           break;
4802 /*        case ACN_PREF_DMX_DISPLAY_PER: */
4803         default:
4804           min_char = 3;
4805           base     = 10;
4806       }
4807
4808       /* do we display leading zeros */
4809       if (global_acn_dmx_display_leading_zeros) {
4810         leading_char = '0';
4811       } else {
4812         leading_char = ' ';
4813       }
4814       /* add a snippet to info (this may be slow) */
4815     if (protocol_id == ACN_PROTOCOL_ID_DMX_2) {
4816       info_start_code = dmx_2_start_code;
4817     }
4818     else {
4819       info_start_code = dmx_start_code;
4820     }
4821       col_append_fstr(pinfo->cinfo,COL_INFO, ", Sc %02x, [%02x %02x %02x %02x %02x %02x...]",
4822         info_start_code,
4823         tvb_get_guint8(tvb, data_offset),
4824         tvb_get_guint8(tvb, data_offset+1),
4825         tvb_get_guint8(tvb, data_offset+2),
4826         tvb_get_guint8(tvb, data_offset+3),
4827         tvb_get_guint8(tvb, data_offset+4),
4828         tvb_get_guint8(tvb, data_offset+5));
4829
4830       /* add a header line */
4831       for (x=0; x<perline; x++) {
4832         buf_ptr = ltos((guint8)(x+1), buf_ptr, 10, ' ', min_char, FALSE);
4833         if ((x+1)==halfline) {
4834           *buf_ptr++ =  '|';
4835           *buf_ptr++ =  ' ';
4836         }
4837       }
4838       *buf_ptr = '\0';
4839       proto_tree_add_string(pdu_tree, hf_acn_dmx_data, tvb, data_offset, dmx_count, buffer);
4840
4841       /* start our line */
4842       g_snprintf(buffer, BUFFER_SIZE, "001-%03d: ", perline);
4843       buf_ptr = buffer + 9;
4844
4845       total_cnt = 0;
4846       item_cnt = 0;
4847       for (x=data_offset; x<end_offset; x++) {
4848         level = tvb_get_guint8(tvb, x);
4849         if (global_acn_dmx_display_view==ACN_PREF_DMX_DISPLAY_PER) {
4850           if ((level > 0) && (level < 3)) {
4851             level = 1;
4852           } else {
4853             level = level * 100 / 255;
4854           }
4855         }
4856         buf_ptr = ltos(level, buf_ptr, base, leading_char, min_char, global_acn_dmx_display_zeros);
4857         total_cnt++;
4858         item_cnt++;
4859
4860         if (item_cnt == perline || x == (end_offset-1)) {
4861           /* add leader... */
4862           proto_tree_add_string_format(pdu_tree, hf_acn_dmx_data, tvb, data_offset, item_cnt, buffer, "%s", buffer);
4863           data_offset += perline;
4864           g_snprintf(buffer, BUFFER_SIZE, "%03d-%03d: ",total_cnt, total_cnt+perline);
4865           buf_ptr = buffer + 9;
4866           item_cnt = 0;
4867         } else {
4868           /* add separator character */
4869           if (item_cnt == halfline) {
4870             *buf_ptr++ = '|';
4871             *buf_ptr++ = ' ';
4872             *buf_ptr   = '\0';
4873           }
4874         }
4875       }
4876     /* NOTE:
4877      address data type                   (fixed at 0xA2)
4878      start code - 1 byte, reserved       (should be 0)
4879                 - 1 byte, start code     (0x255)
4880                 - 2 bytes, packet offset (should be 0000)
4881      address increment - 4 bytes         (ignore)
4882      number of dmx values - 4 bytes      (0-512)
4883      dmx values 0-512 bytes              (data)
4884      */
4885
4886     break;
4887   }
4888   return pdu_start + pdu_length;
4889 }
4890
4891 /******************************************************************************/
4892 /* Dissect DMX Base PDU                                                       */
4893 static guint32
4894 dissect_acn_dmx_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
4895 {
4896   /* common to all pdu */
4897   guint8           pdu_flags;
4898   guint32          pdu_start;
4899   guint32          pdu_length;
4900   guint32          pdu_flvh_length; /* flags, length, vector, header */
4901   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
4902   guint8           octet;
4903   guint8           option_flags;
4904   guint32          length1;
4905   guint32          length2;
4906   guint32          length3;
4907   guint32          vector_offset;
4908   guint32          data_offset;
4909   guint32          data_length;
4910
4911   proto_item      *ti, *pi;
4912   proto_tree      *pdu_tree;
4913   proto_tree      *flag_tree;
4914
4915   const char      *name;
4916
4917 /* this pdu */
4918   guint32          vector;
4919
4920   guint32          universe;
4921   guint32          priority;
4922   guint32          sequence;
4923
4924   /* save start of pdu block */
4925   pdu_start = offset;
4926   pdu_offsets.start = pdu_start;
4927
4928   /* get PDU flags and length flag first */
4929   octet     = tvb_get_guint8(tvb, offset++);
4930   pdu_flags = octet & 0xf0;
4931   length1   = octet & 0x0f;     /* bottom 4 bits only */
4932   length2   = tvb_get_guint8(tvb, offset++);
4933
4934   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
4935   /* flvh = flags, length, vector, header */
4936   if (pdu_flags & ACN_PDU_FLAG_L) {
4937     length3 = tvb_get_guint8(tvb, offset);
4938     offset += 1;
4939     pdu_length = length3 | (length2 << 8) | (length1 << 16);
4940     pdu_flvh_length = 3;
4941   } else {
4942     pdu_length = length2 | (length1 << 8);
4943     pdu_flvh_length = 2;
4944   }
4945
4946   /* offset should now be pointing to vector (if one exists) */
4947
4948   /* Add pdu item and tree */
4949   ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
4950   pdu_tree = proto_item_add_subtree(ti, ett_acn_dmx_pdu);
4951
4952   /* Add flag item and tree */
4953   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
4954   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4955   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4956   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4957   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4958   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
4959
4960   /* Add PDU Length item */
4961   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4962
4963   /* Set vector offset */
4964   if (pdu_flags & ACN_PDU_FLAG_V) {
4965     /* use new values */
4966     vector_offset = offset;
4967     last_pdu_offsets->vector = offset;
4968     offset          += 4;
4969     pdu_flvh_length += 4;
4970   } else {
4971     /* use last values */
4972     vector_offset = last_pdu_offsets->vector;
4973   }
4974   /* offset should now be pointing to header (if one exists) */
4975
4976   /* Add Vector item */
4977   vector = tvb_get_ntohl(tvb, vector_offset);
4978   proto_tree_add_item(pdu_tree, hf_acn_dmx_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
4979   /* vector_offset +=4; */
4980
4981   /* Add Vector item to tree*/
4982   name = val_to_str(vector, acn_dmx_vector_vals, "not valid (%d)");
4983   proto_item_append_text(ti, ": %s", name);
4984
4985   /* NO HEADER DATA ON THESE* (at least so far) */
4986
4987   /* Adjust data */
4988   if (pdu_flags & ACN_PDU_FLAG_D) {
4989     /* use new values */
4990     data_offset = offset;
4991     data_length = pdu_length - pdu_flvh_length;
4992     last_pdu_offsets->data = offset;
4993     last_pdu_offsets->data_length = data_length;
4994   } else {
4995     /* use last values */
4996     data_offset = last_pdu_offsets->data;
4997     /*data_length = last_pdu_offsets->data_length;*/
4998   }
4999
5000   /* process based on vector */
5001   switch (vector) {
5002     case 0x02:
5003       if (protocol_id==ACN_PROTOCOL_ID_DMX_2) {
5004         proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 64, ENC_UTF_8|ENC_NA);
5005         data_offset += 64;
5006       } else{
5007         proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 32, ENC_UTF_8|ENC_NA);
5008         data_offset += 32;
5009       }
5010
5011       priority = tvb_get_guint8(tvb, data_offset);
5012       proto_tree_add_item(pdu_tree, hf_acn_dmx_priority, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5013       data_offset += 1;
5014
5015       if (protocol_id==ACN_PROTOCOL_ID_DMX_2) {
5016         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_reserved, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5017         data_offset += 2;
5018       }
5019
5020       sequence = tvb_get_guint8(tvb, data_offset);
5021       proto_tree_add_item(pdu_tree, hf_acn_dmx_sequence_number, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5022       data_offset += 1;
5023
5024       if (protocol_id == ACN_PROTOCOL_ID_DMX_2) {
5025         option_flags = tvb_get_guint8(tvb, data_offset);
5026         pi = proto_tree_add_uint(pdu_tree, hf_acn_dmx_2_options, tvb, data_offset, 1, option_flags);
5027         flag_tree = proto_item_add_subtree(pi, ett_acn_dmx_2_options);
5028         proto_tree_add_item(flag_tree, hf_acn_dmx_2_option_p, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5029         proto_tree_add_item(flag_tree, hf_acn_dmx_2_option_s, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5030         data_offset += 1;
5031       }
5032
5033       universe = tvb_get_ntohs(tvb, data_offset);
5034       proto_tree_add_item(pdu_tree, hf_acn_dmx_universe, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5035       data_offset += 2;
5036
5037       /* add universe to info */
5038       col_append_fstr(pinfo->cinfo,COL_INFO, ", Universe %d, Seq %3d", universe, sequence );
5039       proto_item_append_text(ti, ", Universe: %d, Priority: %d", universe, priority);
5040
5041       /*data_offset =*/ dissect_acn_dmx_data_pdu(protocol_id, tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5042
5043       break;
5044   }
5045   return pdu_start + pdu_length;
5046 }
5047
5048 /******************************************************************************/
5049 /* Dissect SDT Base PDU                                                       */
5050 static guint32
5051 dissect_acn_sdt_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5052 {
5053   /* common to all pdu */
5054   guint8           pdu_flags;
5055   guint32          pdu_start;
5056   guint32          pdu_length;
5057   guint32          pdu_flvh_length; /* flags, length, vector, header */
5058   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5059   guint8           octet;
5060   guint32          length1;
5061   guint32          length2;
5062   guint32          length3;
5063   guint32          vector_offset;
5064   guint32          data_offset;
5065   guint32          end_offset;
5066   guint32          old_offset;
5067   guint32          data_length;
5068
5069   proto_item      *ti, *pi;
5070   proto_tree      *pdu_tree;
5071   proto_tree      *flag_tree;
5072
5073   /* this pdu */
5074   const gchar     *name;
5075   guint32          vector;
5076   guint32          member_id;
5077
5078   /* save start of pdu block */
5079   pdu_start         = offset;
5080   pdu_offsets.start = pdu_start;
5081
5082   /* get PDU flags and length flag first */
5083   octet     = tvb_get_guint8(tvb, offset++);
5084   pdu_flags = octet & 0xf0;
5085   length1   = octet & 0x0f;     /* bottom 4 bits only */
5086   length2   = tvb_get_guint8(tvb, offset++);
5087
5088   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
5089   /* flvh = flags, length, vector, header */
5090   if (pdu_flags & ACN_PDU_FLAG_L) {
5091     length3 = tvb_get_guint8(tvb, offset);
5092     offset += 1;
5093     pdu_length      = length3 | (length2 << 8) | (length1 << 16);
5094     pdu_flvh_length = 3;
5095   } else {
5096     pdu_length = length2 | (length1 << 8);
5097     pdu_flvh_length = 2;
5098   }
5099   /* offset should now be pointing to vector (if one exists) */
5100
5101   /* Add pdu item and tree */
5102   ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
5103   pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_base_pdu);
5104
5105   /* Add flag item and tree */
5106   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
5107   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
5108   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5109   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5110   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5111   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5112
5113   /* Add PDU Length item */
5114   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5115
5116   /* Set vector offset */
5117   if (pdu_flags & ACN_PDU_FLAG_V) {
5118     /* use new values */
5119     vector_offset = offset;
5120     last_pdu_offsets->vector = offset;
5121     offset += 1;
5122     pdu_flvh_length++;
5123   } else {
5124     /* use last values */
5125     vector_offset = last_pdu_offsets->vector;
5126   }
5127   /* offset should now be pointing to header (if one exists) */
5128
5129   /* Add Vector item */
5130   vector = tvb_get_guint8(tvb, vector_offset);
5131   proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
5132
5133   /* Add Vector item to tree*/
5134   name = val_to_str(vector, acn_sdt_vector_vals, "not valid (%d)");
5135   proto_item_append_text(ti, ": ");
5136   proto_item_append_text(ti, "%s", name);
5137
5138   /* NO HEADER DATA ON THESE* (at least so far) */
5139
5140   /* Adjust data */
5141   if (pdu_flags & ACN_PDU_FLAG_D) {
5142     /* use new values */
5143     data_offset = offset;
5144     data_length = pdu_length - pdu_flvh_length;
5145     last_pdu_offsets->data = offset;
5146     last_pdu_offsets->data_length = data_length;
5147   } else {
5148     /* use last values */
5149     data_offset = last_pdu_offsets->data;
5150     data_length = last_pdu_offsets->data_length;
5151   }
5152   end_offset = data_offset + data_length;
5153
5154   /* process based on vector */
5155   switch (vector) {
5156     case ACN_SDT_VECTOR_UNKNOWN:
5157       break;
5158     case ACN_SDT_VECTOR_REL_WRAP:
5159     case ACN_SDT_VECTOR_UNREL_WRAP:
5160       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5161       data_offset += 2;
5162       proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5163       data_offset += 4;
5164       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5165       data_offset += 4;
5166       proto_tree_add_item(pdu_tree, hf_acn_oldest_available_wrapper, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5167       data_offset += 4;
5168       proto_tree_add_item(pdu_tree, hf_acn_first_memeber_to_ack,     tvb, data_offset, 2, ENC_BIG_ENDIAN);
5169       data_offset += 2;
5170       proto_tree_add_item(pdu_tree, hf_acn_last_memeber_to_ack,      tvb, data_offset, 2, ENC_BIG_ENDIAN);
5171       data_offset += 2;
5172       proto_tree_add_item(pdu_tree, hf_acn_mak_threshold,            tvb, data_offset, 2, ENC_BIG_ENDIAN);
5173       data_offset += 2;
5174
5175       while (data_offset < end_offset) {
5176         old_offset = data_offset;
5177         data_offset = dissect_acn_sdt_client_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5178         if (data_offset == old_offset) break;
5179       }
5180       break;
5181     case ACN_SDT_VECTOR_CHANNEL_PARAMS:
5182       break;
5183     case ACN_SDT_VECTOR_JOIN:
5184       proto_tree_add_item(pdu_tree, hf_acn_cid,                      tvb, data_offset, 16, ENC_BIG_ENDIAN);
5185       data_offset += 16;
5186       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5187       data_offset += 2;
5188       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5189       data_offset += 2;
5190       proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel,       tvb, data_offset, 2, ENC_BIG_ENDIAN);
5191       data_offset += 2;
5192       proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5193       data_offset += 4;
5194       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5195       data_offset += 4;
5196       data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Destination Address:");
5197       data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
5198       /*data_offset =*/ acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, hf_acn_adhoc_expiry);
5199       break;
5200     case ACN_SDT_VECTOR_JOIN_REFUSE:
5201       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                  tvb, data_offset, 16, ENC_BIG_ENDIAN);
5202       data_offset += 16;
5203       proto_item_append_text(pi, "(Leader)");
5204       proto_tree_add_item(pdu_tree, hf_acn_channel_number,            tvb, data_offset, 2, ENC_BIG_ENDIAN);
5205       data_offset += 2;
5206       proto_tree_add_item(pdu_tree, hf_acn_member_id,                 tvb, data_offset, 2, ENC_BIG_ENDIAN);
5207       data_offset += 2;
5208       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number,  tvb, data_offset, 4, ENC_BIG_ENDIAN);
5209       data_offset += 4;
5210       proto_tree_add_item(pdu_tree, hf_acn_refuse_code,               tvb, data_offset, 1, ENC_BIG_ENDIAN);
5211       /*data_offset ++;*/
5212       break;
5213     case ACN_SDT_VECTOR_JOIN_ACCEPT:
5214       pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, ENC_BIG_ENDIAN);
5215       data_offset += 16;
5216       proto_item_append_text(pi, "(Leader)");
5217       proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5218       data_offset += 2;
5219       proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5220       data_offset += 2;
5221       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5222       data_offset += 4;
5223       proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5224       /*data_offset += 2;*/
5225       break;
5226     case ACN_SDT_VECTOR_LEAVE:
5227       break;
5228     case ACN_SDT_VECTOR_LEAVING:
5229       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                 tvb, data_offset, 16, ENC_BIG_ENDIAN);
5230       data_offset += 16;
5231       proto_item_append_text(pi, "(Leader)");
5232       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5233       data_offset += 2;
5234       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5235       data_offset += 2;
5236       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5237       data_offset += 4;
5238       proto_tree_add_item(pdu_tree, hf_acn_reason_code,              tvb, data_offset, 1, ENC_BIG_ENDIAN);
5239       /* offset += 1; */
5240       break;
5241     case ACN_SDT_VECTOR_CONNECT:
5242       break;
5243     case ACN_SDT_VECTOR_CONNECT_ACCEPT:
5244       break;
5245     case ACN_SDT_VECTOR_CONNECT_REFUSE:
5246       break;
5247     case ACN_SDT_VECTOR_DISCONNECT:
5248       break;
5249     case ACN_SDT_VECTOR_DISCONNECTING:
5250       break;
5251     case ACN_SDT_VECTOR_ACK:
5252       break;
5253     case ACN_SDT_VECTOR_NAK:
5254       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                 tvb, data_offset, 16, ENC_BIG_ENDIAN);
5255       data_offset += 16;
5256       proto_item_append_text(pi, "(Leader)");
5257       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5258       data_offset += 2;
5259       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5260       data_offset += 2;
5261       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5262       data_offset += 4;
5263       proto_tree_add_item(pdu_tree, hf_acn_first_missed_sequence,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5264       data_offset += 4;
5265       proto_tree_add_item(pdu_tree, hf_acn_last_missed_sequence,     tvb, data_offset, 4, ENC_BIG_ENDIAN);
5266       /*data_offset += 4;*/
5267       break;
5268     case ACN_SDT_VECTOR_GET_SESSION:
5269       proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, ENC_BIG_ENDIAN);
5270       /*data_offset += 16;*/
5271       break;
5272     case ACN_SDT_VECTOR_SESSIONS:
5273       member_id = tvb_get_ntohs(tvb, data_offset);
5274       switch (member_id) {
5275         case 0:
5276           /*data_offset =*/ acn_add_channel_owner_info_block(tvb, pinfo, pdu_tree, data_offset);
5277           break;
5278         case 1:
5279           /*data_offset =*/ acn_add_channel_member_info_block(tvb, pinfo, pdu_tree, data_offset);
5280           break;
5281       }
5282       break;
5283   }
5284
5285   return pdu_start + pdu_length;
5286 }
5287
5288 /******************************************************************************/
5289 /* Dissect Root PDU                                                           */
5290 static guint32
5291 dissect_acn_root_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5292 {
5293   /* common to all pdu */
5294   guint8           pdu_flags;
5295   guint32          pdu_start;
5296   guint32          pdu_length;
5297   guint32          pdu_flvh_length; /* flags, length, vector, header */
5298   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5299   guint8           octet;
5300   guint32          length1;
5301   guint32          length2;
5302   guint32          length3;
5303   guint32          vector_offset;
5304   guint32          header_offset;
5305   guint32          data_offset;
5306   guint32          end_offset;
5307   guint32          old_offset;
5308   guint32          data_length;
5309
5310   proto_item      *ti, *pi;
5311   proto_tree      *pdu_tree;
5312   proto_tree      *flag_tree;
5313
5314   /* this pdu */
5315   guint32          protocol_id;
5316   e_guid_t         guid;
5317
5318   /* save start of pdu block */
5319   pdu_start         = offset;
5320   pdu_offsets.start = pdu_start;
5321
5322   /* get PDU flags and length flag first */
5323   octet     = tvb_get_guint8(tvb, offset++);
5324   pdu_flags = octet & 0xf0;
5325   length1   = octet & 0x0f;     /* bottom 4 bits only */
5326   length2   = tvb_get_guint8(tvb, offset++);
5327
5328   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
5329   /* flvh = flags, length, vector, header */
5330   if (pdu_flags & ACN_PDU_FLAG_L) {
5331     length3 = tvb_get_guint8(tvb, offset);
5332     offset += 1;
5333     pdu_length = length3 | (length2 << 8) | (length1 << 16);
5334     pdu_flvh_length = 3;
5335   } else {
5336     pdu_length = length2 | (length1 << 8);
5337     pdu_flvh_length = 2;
5338   }
5339   /* offset should now be pointing to vector (if one exists) */
5340
5341   /* Add pdu item and tree */
5342   ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, ENC_NA);
5343   pdu_tree = proto_item_add_subtree(ti, ett_acn_root_pdu);
5344
5345   /* Add flag item and tree */
5346   pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags);
5347   flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
5348   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5349   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5350   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5351   proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, ENC_BIG_ENDIAN);
5352
5353   /* Add PDU Length item */
5354   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5355
5356   /* Set vector offset */
5357   if (pdu_flags & ACN_PDU_FLAG_V) {
5358     /* use new values */
5359     vector_offset = offset;
5360     last_pdu_offsets->vector = offset;
5361     offset += 4;
5362     pdu_flvh_length += 4;
5363   } else {
5364     /* use last values */
5365     vector_offset = last_pdu_offsets->vector;
5366   }
5367   /* offset should now be pointing to header (if one exists) */
5368
5369   /* Get Protocol ID (vector) */
5370   protocol_id = tvb_get_ntohl(tvb, vector_offset);
5371   proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, vector_offset, 4, protocol_id);
5372
5373   /* process based on protocol_id */
5374   switch (protocol_id) {
5375     case ACN_PROTOCOL_ID_DMX:
5376     case ACN_PROTOCOL_ID_DMX_2:
5377       if (global_acn_dmx_enable) {
5378         proto_item_append_text(ti,": Root DMX");
5379
5380         /* Set header offset */
5381         if (pdu_flags & ACN_PDU_FLAG_H) {
5382           /* use new values */
5383           header_offset = offset;
5384           last_pdu_offsets->header = offset;
5385           offset += 16;
5386           pdu_flvh_length += 16;
5387         } else {
5388           /* use last values */
5389           header_offset = last_pdu_offsets->header;
5390         }
5391         /* offset should now be pointing to data (if one exists) */
5392
5393         /* get Header (CID) 16 bytes */
5394         tvb_get_guid(tvb, header_offset, &guid, ENC_BIG_ENDIAN);
5395         proto_item_append_text(ti, ", Src: %s", guid_to_str(wmem_packet_scope(), &guid));
5396
5397         /* add cid to info */
5398         col_add_fstr(pinfo->cinfo,COL_INFO, "CID %s", guid_to_str(wmem_packet_scope(), &guid));
5399
5400         proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, header_offset, 16, ENC_BIG_ENDIAN);
5401         /*header_offset += 16;*/
5402
5403         /* Adjust data */
5404         if (pdu_flags & ACN_PDU_FLAG_D) {
5405           /* use new values */
5406           data_offset = offset;
5407           data_length = pdu_length - pdu_flvh_length;
5408           last_pdu_offsets->data = offset;
5409           last_pdu_offsets->data_length = data_length;
5410         } else {
5411           /* use last values */
5412           data_offset = last_pdu_offsets->data;
5413           data_length = last_pdu_offsets->data_length;
5414         }
5415         end_offset = data_offset + data_length;
5416
5417         /* adjust for what we used */
5418         while (data_offset < end_offset) {
5419           old_offset = data_offset;
5420           data_offset = dissect_acn_dmx_pdu(protocol_id, tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5421           if (data_offset == old_offset) break;
5422         }
5423       }
5424       break;
5425     case ACN_PROTOCOL_ID_SDT:
5426       /* Adjust header */
5427       proto_item_append_text(ti,": Root SDT");
5428
5429       /* Set header offset */
5430       if (pdu_flags & ACN_PDU_FLAG_H) {
5431         /* use new values */
5432         header_offset = offset;
5433         last_pdu_offsets->header = offset;
5434         offset += 16;
5435         pdu_flvh_length += 16;
5436       } else {
5437         /* use last values */
5438         header_offset = last_pdu_offsets->header;
5439       }
5440       /* offset should now be pointing to data (if one exists) */
5441
5442       /* get Header (CID) 16 bytes */
5443       tvb_get_guid(tvb, header_offset, &guid, ENC_BIG_ENDIAN);
5444       proto_item_append_text(ti, ", Src: %s", guid_to_str(wmem_packet_scope(), &guid));
5445
5446       proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, header_offset, 16, ENC_BIG_ENDIAN);
5447       /*header_offset += 16;*/
5448
5449       /* Adjust data */
5450       if (pdu_flags & ACN_PDU_FLAG_D) {
5451         /* use new values */
5452         data_offset = offset;
5453         data_length = pdu_length - pdu_flvh_length;
5454         last_pdu_offsets->data = offset;
5455         last_pdu_offsets->data_length = data_length;
5456       } else {
5457         /* use last values */
5458         data_offset = last_pdu_offsets->data;
5459         data_length = last_pdu_offsets->data_length;
5460       }
5461       end_offset = data_offset + data_length;
5462
5463       /* adjust for what we used */
5464       while (data_offset < end_offset) {
5465         old_offset = data_offset;
5466         data_offset = dissect_acn_sdt_base_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5467         if (data_offset == old_offset) break;
5468       }
5469       break;
5470   }
5471
5472   return pdu_start + pdu_length;
5473 }
5474
5475 /******************************************************************************/
5476 /* Dissect ACN                                                                */
5477 static int
5478 dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5479 {
5480   proto_item      *ti;
5481   proto_tree      *acn_tree;
5482   guint32          data_offset = 0;
5483   guint32          old_offset;
5484   guint32          end_offset;
5485   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5486
5487 /*   if (!is_acn(tvb)) { */
5488 /*     return 0;         */
5489 /*   }                   */
5490
5491   /* Set the protocol column */
5492   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACN");
5493
5494   col_add_fstr(pinfo->cinfo,COL_INFO, "ACN [Src Port: %d, Dst Port: %d]", pinfo->srcport, pinfo->destport );
5495
5496   ti = proto_tree_add_item(tree, proto_acn, tvb, 0, -1, ENC_NA);
5497   acn_tree = proto_item_add_subtree(ti, ett_acn);
5498
5499   /* add preamble, postamble and ACN Packet ID */
5500   proto_tree_add_item(acn_tree, hf_acn_preamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5501   data_offset += 2;
5502   proto_tree_add_item(acn_tree, hf_acn_postamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5503   data_offset += 2;
5504   proto_tree_add_item(acn_tree, hf_acn_packet_identifier, tvb, data_offset, 12, ENC_UTF_8 | ENC_NA);
5505   data_offset += 12;
5506
5507   /* one past the last byte */
5508   end_offset = data_offset + tvb_reported_length_remaining(tvb, data_offset);
5509   while (data_offset < end_offset) {
5510     old_offset = data_offset;
5511     data_offset = dissect_acn_root_pdu(tvb, pinfo, acn_tree, data_offset, &pdu_offsets);
5512     if (data_offset == old_offset) break;
5513   }
5514   return tvb_reported_length(tvb);
5515 }
5516
5517 /******************************************************************************/
5518 /* Register protocol                                                          */
5519 void
5520 proto_register_acn(void)
5521 {
5522   static hf_register_info hf[] = {
5523     /**************************************************************************/
5524     /* In alphabetical order */
5525     /* Address Type */
5526     /* PDU flags*/
5527     { &hf_acn_ip_address_type,
5528       { "Addr Type", "acn.ip_address_type",
5529         FT_UINT8, BASE_DEC, VALS(acn_ip_address_type_vals), 0x0,
5530         NULL, HFILL }
5531     },
5532     /* Association */
5533     { &hf_acn_association,
5534       { "Association", "acn.association",
5535         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5536         NULL, HFILL }
5537     },
5538     /* Blob */
5539     { &hf_acn_blob,
5540       { "Blob", "acn.blob",
5541         FT_NONE, BASE_NONE, NULL, 0x0,
5542         NULL, HFILL }
5543     },
5544 #if 0
5545     /* Blob Dimmer Load Properties 2 Type */
5546     { &hf_acn_blob_dimmer_load_properties2_type,
5547       { "Blob Field", "acn.blob_dimmer_load_properties2_type",
5548         FT_NONE, BASE_NONE, NULL, 0x0,
5549         NULL, HFILL }
5550     },
5551 #endif
5552     /* Blob Field Length */
5553     { &hf_acn_blob_field_length,
5554       { "Field Length", "acn.blob_field_length",
5555         FT_UINT8, BASE_DEC, NULL, 0x0,
5556         NULL, HFILL }
5557     },
5558     /* Blob Field Type */
5559     { &hf_acn_blob_field_type,
5560       { "Field Type", "acn.blob_field_type",
5561         FT_UINT8, BASE_DEC, VALS(acn_blob_field_type_vals), 0x0,
5562         NULL, HFILL }
5563     },
5564     /* Blob Field Value Number*/
5565     { &hf_acn_blob_field_value_number,
5566       { "Field Value", "acn.blob_field_value_number",
5567         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5568         NULL, HFILL }
5569     },
5570     { &hf_acn_blob_field_value_ipv4,
5571       { "Field Value", "acn.blob_field_value_ipv4",
5572         FT_IPv4, BASE_NONE, NULL, 0x0,
5573         NULL, HFILL }
5574     },
5575     { &hf_acn_blob_field_value_ipv6,
5576       { "Field Value", "acn.blob_field_value_ipv6",
5577         FT_IPv6, BASE_NONE, NULL, 0x0,
5578         NULL, HFILL }
5579     },
5580     { &hf_acn_blob_field_value_float,
5581       { "Field Value", "acn.blob_field_value_float",
5582         FT_FLOAT, BASE_NONE, NULL, 0x0,
5583         NULL, HFILL }
5584     },
5585     { &hf_acn_blob_field_value_double,
5586       { "Field Value", "acn.blob_field_value_double",
5587         FT_DOUBLE, BASE_NONE, NULL, 0x0,
5588         NULL, HFILL }
5589     },
5590     { &hf_acn_blob_field_value_guid,
5591       { "Field Value", "acn.blob_field_value_guid",
5592         FT_GUID, BASE_NONE, NULL, 0x0,
5593         NULL, HFILL }
5594     },
5595
5596     /* Blob Field Value String*/
5597     { &hf_acn_blob_field_value_string,
5598       { "Field Value", "acn.blob_field_value_string",
5599         FT_STRING, BASE_NONE, NULL, 0x0,
5600         NULL, HFILL }
5601     },
5602     /* Blob Metadata Device Type */
5603     { &hf_acn_blob_tree_field_type,
5604       { "Blob Field", "acn.blob_tree_field_type",
5605         FT_NONE, BASE_NONE, NULL, 0x0,
5606         NULL, HFILL }
5607     },
5608 #if 0
5609     /* Blob Metadata Types Type */
5610     { &hf_acn_blob_metadata_types_type,
5611       { "Blob Field", "acn.blob_metadata_types_type",
5612         FT_NONE, BASE_NONE, NULL, 0x0,
5613         NULL, HFILL }
5614     },
5615 #endif
5616     /* Blob Range Number */
5617     { &hf_acn_blob_range_number,
5618       { "Blob Range Number", "acn.blob_range_number",
5619         FT_UINT8, BASE_DEC, NULL, 0x0,
5620         NULL, HFILL }
5621     },
5622     /* Blob Range Type */
5623     { &hf_acn_blob_range_type,
5624       { "Blob Range Type", "acn.blob_range_type",
5625         FT_UINT8, BASE_HEX, VALS(acn_blob_range_type_vals), 0x0,
5626         NULL, HFILL }
5627     },
5628 #if 0
5629     /* Blob Range Start */
5630     { &hf_acn_blob_range_start,
5631       { "Blob Range Start", "acn.blob_range_start",
5632         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
5633         NULL, HFILL }
5634     },
5635 #endif
5636     /* Blob Type */
5637     { &hf_acn_blob_type,
5638       { "Blob Type", "acn.blob_type",
5639         FT_UINT8, BASE_DEC, VALS(acn_blob_type_vals), 0x0,
5640         NULL, HFILL }
5641     },
5642     /* Blob Version */
5643     { &hf_acn_blob_version,
5644       { "Blob Version", "acn.blob_version",
5645         FT_UINT8, BASE_DEC, NULL, 0x0,
5646         NULL, HFILL }
5647     },
5648     { &hf_acn_blob_time_zone,
5649       { "Time Zone", "acn.blob_time_zone",
5650         FT_INT8, BASE_DEC, NULL, 0x0,
5651         NULL, HFILL }
5652     },
5653     { &hf_acn_blob_dst_type,
5654       { "DST Type", "acn.blob_dst_type",
5655         FT_UINT8, BASE_DEC, NULL, 0x0,
5656         NULL, HFILL }
5657     },
5658     { &hf_acn_blob_dst_start_day,
5659       { "DST Start Day", "acn.blob_dst_start_day",
5660         FT_UINT8, BASE_DEC, NULL, 0x0,
5661         NULL, HFILL }
5662     },
5663     { &hf_acn_blob_dst_stop_day,
5664       { "DST Stop Day", "acn.blob_dst_stop_day",
5665         FT_UINT8, BASE_DEC, NULL, 0x0,
5666         NULL, HFILL }
5667     },
5668     { &hf_acn_blob_dst_start_locality,
5669       { "DST Start Locality", "acn.blob_dst_start_locality",
5670         FT_UINT8, BASE_DEC, NULL, 0x0,
5671         NULL, HFILL }
5672     },
5673     { &hf_acn_blob_dst_stop_locality,
5674       { "DST Stop Locality", "acn.blob_dst_stop_locality",
5675         FT_UINT8, BASE_DEC, NULL, 0x0,
5676         NULL, HFILL }
5677     },
5678     /* Channel Number */
5679     { &hf_acn_channel_number,
5680       { "Channel Number", "acn.channel_number",
5681         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5682         NULL, HFILL }
5683     },
5684     /* CID */
5685     { &hf_acn_cid,
5686       { "CID", "acn.cid",
5687         FT_GUID, BASE_NONE, NULL, 0x0,
5688         NULL, HFILL }
5689     },
5690     /* Client Protocol ID */
5691 #if 0
5692     { &hf_acn_client_protocol_id,
5693       { "Client Protocol ID", "acn.client_protocol_id",
5694         FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
5695         NULL, HFILL }
5696     },
5697 #endif
5698     /* DMP data */
5699     { &hf_acn_data,
5700       { "Data", "acn.dmp_data",
5701         FT_BYTES, BASE_NONE, NULL, 0x0,
5702         NULL, HFILL }
5703     },
5704     { &hf_acn_data8,
5705       { "Addr", "acn.dmp_data8",
5706         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
5707         "Data8", HFILL }
5708     },
5709     { &hf_acn_data16,
5710       { "Addr", "acn.dmp_data16",
5711         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5712         "Data16", HFILL }
5713     },
5714     { &hf_acn_data24,
5715       { "Addr", "acn.dmp_data24",
5716         FT_UINT24, BASE_DEC_HEX, NULL, 0x0,
5717         "Data24", HFILL }
5718     },
5719     { &hf_acn_data32,
5720       { "Addr", "acn.dmp_data32",
5721         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5722         "Data32", HFILL }
5723     },
5724
5725     /* DMP Address type*/
5726 #if 0
5727     { &hf_acn_dmp_adt,
5728       { "Address and Data Type", "acn.dmp_adt",
5729         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
5730         NULL, HFILL }
5731     },
5732 #endif
5733     { &hf_acn_dmp_adt_a,
5734       { "Size", "acn.dmp_adt_a",
5735         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_a_vals), 0x03,
5736         NULL, HFILL }
5737     },
5738     { &hf_acn_dmp_adt_d,
5739       { "Data Type", "acn.dmp_adt_d",
5740         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_d_vals), 0x30,
5741         NULL, HFILL }
5742     },
5743     { &hf_acn_dmp_adt_r,
5744       { "Relative", "acn.dmp_adt_r",
5745         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_r_vals), 0x40,
5746         NULL, HFILL }
5747     },
5748     { &hf_acn_dmp_adt_v,
5749       { "Virtual", "acn.dmp_adt_v",
5750         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_v_vals), 0x80,
5751         NULL, HFILL }
5752     },
5753     { &hf_acn_dmp_adt_x,
5754       { "Reserved", "acn.dmp_adt_x",
5755         FT_UINT8, BASE_DEC, NULL, 0x0c,
5756         NULL, HFILL }
5757     },
5758
5759     /* DMP Reason Code */
5760     { &hf_acn_dmp_reason_code,
5761       { "Reason Code", "acn.dmp_reason_code",
5762         FT_UINT8, BASE_DEC, VALS(acn_dmp_reason_code_vals), 0x0,
5763         NULL, HFILL }
5764     },
5765
5766     /* DMP Vector */
5767     { &hf_acn_dmp_vector,
5768       { "DMP Vector", "acn.dmp_vector",
5769         FT_UINT8, BASE_DEC, VALS(acn_dmp_vector_vals), 0x0,
5770         NULL, HFILL }
5771     },
5772
5773     { &hf_acn_dmp_actual_address,
5774       { "Actual Address", "acn.dmp_actual_address",
5775         FT_UINT32, BASE_HEX, NULL, 0x0,
5776         NULL, HFILL }
5777     },
5778
5779     { &hf_acn_dmp_virtual_address,
5780       { "Virtual Address", "acn.dmp_virtual_address",
5781         FT_UINT32, BASE_HEX, NULL, 0x0,
5782         NULL, HFILL }
5783     },
5784
5785     { &hf_acn_dmp_actual_address_first,
5786       { "Actual Address First", "acn.dmp_actual_address_first",
5787         FT_UINT32, BASE_HEX, NULL, 0x0,
5788         NULL, HFILL }
5789     },
5790
5791     { &hf_acn_dmp_virtual_address_first,
5792       { "Virtual Address First", "acn.dmp_virtual_address_first",
5793         FT_UINT32, BASE_HEX, NULL, 0x0,
5794         NULL, HFILL }
5795     },
5796
5797     /* Expiry */
5798     { &hf_acn_expiry,
5799       { "Expiry", "acn.expiry",
5800         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5801         NULL, HFILL }
5802     },
5803     /* First Member to ACK */
5804     { &hf_acn_first_memeber_to_ack,
5805       { "First Member to ACK", "acn.first_member_to_ack",
5806         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5807         NULL, HFILL }
5808     },
5809     /* First Missed Sequence */
5810     { &hf_acn_first_missed_sequence,
5811       { "First Missed Sequence", "acn.first_missed_sequence",
5812         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5813         NULL, HFILL }
5814     },
5815     /* IPV4 */
5816     { &hf_acn_ipv4,
5817       { "IPV4", "acn.ipv4",
5818         FT_IPv4, BASE_NONE, NULL, 0x0,
5819         NULL, HFILL }
5820     },
5821     /* IPV6 */
5822     { &hf_acn_ipv6,
5823       { "IPV6", "acn.ipv6",
5824         FT_IPv6, BASE_NONE, NULL, 0x0,
5825         NULL, HFILL }
5826     },
5827     /* Last Member to ACK */
5828     { &hf_acn_last_memeber_to_ack,
5829       { "Last Member to ACK", "acn.last_member_to_ack",
5830         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5831         NULL, HFILL }
5832     },
5833     /* Last Missed Sequence */
5834     { &hf_acn_last_missed_sequence,
5835       { "Last Missed Sequence", "acn.last_missed_sequence",
5836         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5837         NULL, HFILL }
5838     },
5839     /* MAK threshold */
5840     { &hf_acn_mak_threshold,
5841       { "MAK Threshold", "acn.mak_threshold",
5842         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5843         NULL, HFILL }
5844     },
5845     /* MemberID */
5846     { &hf_acn_member_id,
5847       { "Member ID", "acn.member_id",
5848         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5849         NULL, HFILL }
5850     },
5851     /* NAK Holdoff */
5852     { &hf_acn_nak_holdoff,
5853       { "NAK holdoff (ms)", "acn.nak_holdoff",
5854         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5855         NULL, HFILL }
5856     },
5857     /* NAK Max Wait */
5858     { &hf_acn_nak_max_wait,
5859       { "NAK Max Wait (ms)", "acn.nak_max_wait",
5860         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5861         NULL, HFILL }
5862     },
5863     /* NAK Modulus */
5864     { &hf_acn_nak_modulus,
5865       { "NAK Modulus", "acn.nak_modulus",
5866         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5867         NULL, HFILL }
5868     },
5869     /* NAK Outbound Flag */
5870     { &hf_acn_nak_outbound_flag,
5871       { "NAK Outbound Flag", "acn.nak_outbound_flag",
5872         FT_BOOLEAN, 8, NULL, 0x80,
5873         NULL, HFILL }
5874     },
5875     /* Oldest Available Wrapper */
5876     { &hf_acn_oldest_available_wrapper,
5877       { "Oldest Available Wrapper", "acn.oldest_available_wrapper",
5878         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5879         NULL, HFILL }
5880     },
5881     /* Preamble Sizet */
5882     { &hf_acn_preamble_size,
5883       { "Size of preamble", "acn.preamble_size",
5884         FT_UINT16, BASE_DEC, NULL, 0x0,
5885         "Preamble size in bytes", HFILL }
5886     },
5887     /* Packet Identifier */
5888     { &hf_acn_packet_identifier,
5889       { "Packet Identifier", "acn.packet_identifier",
5890         FT_STRING, BASE_NONE, NULL, 0x0,
5891         NULL, HFILL }
5892     },
5893     /* PDU */
5894     { &hf_acn_pdu,
5895       { "PDU", "acn.pdu",
5896         FT_NONE, BASE_NONE, NULL, 0x0,
5897         NULL, HFILL }
5898     },
5899     /* PDU flags*/
5900     { &hf_acn_pdu_flags,
5901       { "Flags", "acn.pdu.flags",
5902         FT_UINT8, BASE_HEX, NULL, 0x0,
5903         "PDU Flags", HFILL }
5904     },
5905     { &hf_acn_pdu_flag_d,
5906       { "Data", "acn.pdu.flag_d",
5907         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_D,
5908         "Data flag", HFILL }
5909     },
5910     { &hf_acn_pdu_flag_h,
5911       { "Header", "acn.pdu.flag_h",
5912         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_H,
5913         "Header flag", HFILL }
5914     },
5915     { &hf_acn_pdu_flag_l,
5916       { "Length", "acn.pdu.flag_l",
5917         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_L,
5918         "Length flag", HFILL }
5919     },
5920     { &hf_acn_pdu_flag_v,
5921       { "Vector", "acn.pdu.flag_v",
5922         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_V,
5923         "Vector flag", HFILL }
5924     },
5925     /* PDU Length */
5926     { &hf_acn_pdu_length,
5927       { "Length", "acn.pdu.length",
5928         FT_UINT32, BASE_DEC, NULL, 0x0,
5929         "PDU Length", HFILL }
5930     },
5931     /* Port */
5932     { &hf_acn_port,
5933       { "Port", "acn.port",
5934         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5935         NULL, HFILL }
5936     },
5937     /* Postamble Size */
5938     { &hf_acn_postamble_size,
5939       { "Size of postamble", "acn.postamble_size",
5940         FT_UINT16, BASE_DEC, NULL, 0x0,
5941         "Postamble size in bytes", HFILL }
5942     },
5943     /* Protocol ID */
5944     { &hf_acn_protocol_id,
5945       { "Protocol ID", "acn.protocol_id",
5946         FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
5947         NULL, HFILL }
5948     },
5949     /* Reason Code */
5950     { &hf_acn_reason_code,
5951       { "Reason Code", "acn.reason_code",
5952         FT_UINT8, BASE_DEC, VALS(acn_reason_code_vals), 0x0,
5953         NULL, HFILL }
5954     },
5955     /* Reciprocal Channel */
5956     { &hf_acn_reciprocal_channel,
5957       { "Reciprocal Channel Number", "acn.reciprocal_channel",
5958         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
5959         "Reciprocal Channel", HFILL }
5960     },
5961     /* Refuse Code */
5962     { &hf_acn_refuse_code,
5963       { "Refuse Code", "acn.refuse_code",
5964         FT_UINT8, BASE_DEC, VALS(acn_refuse_code_vals), 0x0,
5965         NULL, HFILL }
5966     },
5967     /* Reliable Sequence Number */
5968     { &hf_acn_reliable_sequence_number,
5969       { "Reliable Sequence Number", "acn.reliable_sequence_number",
5970         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
5971         NULL, HFILL }
5972     },
5973     /* Ad-hoc Expiry */
5974     { &hf_acn_adhoc_expiry,
5975       { "Ad-hoc Expiry", "acn.adhoc_expiry",
5976         FT_UINT8, BASE_DEC, NULL, 0x0,
5977         NULL, HFILL }
5978     },
5979     /* SDT Vector */
5980     { &hf_acn_sdt_vector,
5981       { "STD Vector", "acn.sdt_vector",
5982         FT_UINT8, BASE_DEC, VALS(acn_sdt_vector_vals), 0x0,
5983         NULL, HFILL }
5984     },
5985
5986     /* DMX Vector */
5987     { &hf_acn_dmx_vector,
5988       { "Vector", "acn.dmx_vector",
5989         FT_UINT32, BASE_DEC, VALS(acn_dmx_vector_vals), 0x0,
5990         "DMX Vector", HFILL }
5991     },
5992     /* DMX Source Name */
5993     { &hf_acn_dmx_source_name,
5994       { "Source", "acn.dmx.source_name",
5995         FT_STRING, BASE_NONE, NULL, 0x0,
5996         "DMX Source Name", HFILL }
5997     },
5998
5999     /* DMX priority */
6000     { &hf_acn_dmx_priority,
6001       { "Priority", "acn.dmx.priority",
6002         FT_UINT8, BASE_DEC, NULL, 0x0,
6003         "DMX Priority", HFILL }
6004     },
6005
6006     /* DMX 2 reserved */
6007     { &hf_acn_dmx_2_reserved,
6008       { "Reserved", "acn.dmx.reserved",
6009         FT_UINT16, BASE_DEC, NULL, 0x0,
6010         "DMX Reserved", HFILL }
6011     },
6012
6013     /* DMX Sequence number */
6014     { &hf_acn_dmx_sequence_number,
6015       { "Seq No", "acn.dmx.seq_number",
6016         FT_UINT8, BASE_DEC, NULL, 0x0,
6017         "DMX Sequence Number", HFILL }
6018     },
6019
6020     /* DMX 2 options */
6021     { &hf_acn_dmx_2_options,
6022       { "Options", "acn.dmx.options",
6023         FT_UINT8, BASE_DEC, NULL, 0x0,
6024         "DMX Options", HFILL }
6025     },
6026
6027     { &hf_acn_dmx_2_option_p,
6028       { "Preview Data", "acn.dmx.option_p",
6029         FT_BOOLEAN, 8, NULL, ACN_DMX_OPTION_P,
6030         "Preview Data flag", HFILL }
6031     },
6032
6033     { &hf_acn_dmx_2_option_s,
6034       { "Stream Terminated", "acn.dmx.option_s",
6035         FT_BOOLEAN, 8, NULL, ACN_DMX_OPTION_S,
6036         "Stream Terminated flag", HFILL }
6037     },
6038
6039     /* DMX Universe */
6040     { &hf_acn_dmx_universe,
6041       { "Universe", "acn.dmx.universe",
6042         FT_UINT16, BASE_DEC, NULL, 0x0,
6043         "DMX Universe", HFILL }
6044     },
6045
6046     /* DMX Start Code */
6047     { &hf_acn_dmx_start_code,
6048       { "Start Code", "acn.dmx.start_code",
6049         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
6050         "DMX Start Code", HFILL }
6051     },
6052
6053     /* DMX 2 First Property Address */
6054     { &hf_acn_dmx_2_first_property_address,
6055       { "First Property Address", "acn.dmx.start_code",
6056         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
6057         "DMX First Property Address", HFILL }
6058     },
6059
6060     /* DMX Address Increment */
6061     { &hf_acn_dmx_increment,
6062       { "Increment", "acn.dmx.increment",
6063         FT_UINT16, BASE_DEC, NULL, 0x0,
6064         "DMX Increment", HFILL }
6065     },
6066
6067     /* DMX Packet Count */
6068     { &hf_acn_dmx_count,
6069       { "Count", "acn.dmx.count",
6070         FT_UINT16, BASE_DEC, NULL, 0x0,
6071         "DMX Count", HFILL }
6072     },
6073
6074     /* DMX 2 Start Code */
6075     { &hf_acn_dmx_2_start_code,
6076       { "Start Code", "acn.dmx.start_code2",
6077         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
6078         "DMX Start Code", HFILL }
6079     },
6080
6081     /*
6082      * If you want the pretty-printed data in the field, for filtering
6083      * purposes, you have to make it an FT_STRING.
6084      *
6085      * If you want the raw data in the field, for filtering purposes,
6086      * you have to make it an FT_BYTES *AND* use "proto_tree_add_bytes_format()"
6087      * to put the pretty-printed data into the display but not the field.
6088      */
6089     { &hf_acn_dmx_data,
6090       { "Data", "acn.dmx.data",
6091         FT_STRING, BASE_NONE, NULL, 0x0,
6092         NULL, HFILL }
6093     },
6094
6095     /* Session Count */
6096 #if 0
6097     { &hf_acn_session_count,
6098       { "Session Count", "acn.session_count",
6099         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
6100         NULL, HFILL }
6101     },
6102 #endif
6103     /* Total Sequence Number */
6104     { &hf_acn_total_sequence_number,
6105       { "Total Sequence Number", "acn.total_sequence_number",
6106         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
6107         NULL, HFILL }
6108     }
6109   };
6110
6111   static hf_register_info magic_hf[] = {
6112     /* Protocol ID */
6113     { &hf_magic_protocol_id,
6114       { "Protocol ID", "magic.protocol_id",
6115         FT_UINT8, BASE_DEC, NULL, 0x0,
6116         NULL, HFILL }
6117     },
6118
6119     /* PDU Type */
6120     { &hf_magic_pdu_subtype,
6121       { "PDU type", "magic.type",
6122         FT_UINT8, BASE_DEC, VALS(magic_pdu_subtypes), 0x0,
6123         NULL, HFILL },
6124     },
6125
6126     /* Major Version */
6127     { &hf_magic_major_version,
6128       { "Major Version", "magic.major_version",
6129         FT_UINT8, BASE_DEC, NULL, 0x0,
6130         NULL, HFILL }
6131     },
6132
6133     /* Minor Version */
6134     { &hf_magic_minor_version,
6135       { "Minor Version", "magic.minor_version",
6136         FT_UINT8, BASE_DEC, NULL, 0x0,
6137         NULL, HFILL }
6138     },
6139
6140     /* V1 Command */
6141     { &hf_magic_v1command_vals,
6142       { "Command", "magic.v1_command",
6143         FT_UINT32, BASE_DEC, VALS(magic_v1command_vals), 0x0,
6144         NULL, HFILL }
6145     },
6146
6147     /* V2 Command */
6148     { &hf_magic_command_vals,
6149       { "Command", "magic.command",
6150         FT_UINT32, BASE_DEC, VALS(magic_command_vals), 0x0,
6151         NULL, HFILL }
6152     },
6153
6154     /* Beacon Duration */
6155     { &hf_magic_command_beacon_duration,
6156       { "Duration", "magic.beacon_duration",
6157         FT_UINT32, BASE_DEC, NULL, 0x0,
6158         "Beacon Duration", HFILL }
6159     },
6160
6161     /* TFTP */
6162     { &hf_magic_command_tftp,
6163       { "TFTP IP", "magic.tftp",
6164         FT_IPv4, BASE_NONE, NULL, 0x0,
6165         "IP of TFTP server", HFILL }
6166     },
6167
6168     /* Reset Lease */
6169     { &hf_magic_command_reset_lease,
6170       { "Reset Lease", "magic.reset_lease",
6171         FT_UINT32, BASE_DEC, VALS(magic_reset_lease_vals), 0x0,
6172         NULL, HFILL }
6173     },
6174
6175     /* CID */
6176     { &hf_magic_command_cid,
6177       { "CID", "magic.cid",
6178         FT_GUID, BASE_NONE, NULL, 0x0,
6179         NULL, HFILL }
6180     },
6181
6182     /* Command IP Configuration */
6183     { &hf_magic_command_ip_configuration,
6184       { "IP Configuration", "magic.ip_configuration",
6185         FT_UINT32, BASE_DEC, VALS(magic_ip_configuration_vals), 0x0,
6186         NULL, HFILL }
6187     },
6188
6189     /* Command IP Address */
6190     { &hf_magic_command_ip_address,
6191       { "IP Address", "magic.ip_address",
6192         FT_IPv4, BASE_NONE, NULL, 0x0,
6193         NULL, HFILL }
6194     },
6195
6196     /* Command Subnet Mask */
6197     { &hf_magic_command_subnet_mask,
6198       { "Subnet Mask", "magic.subnet_mask",
6199         FT_IPv4, BASE_NONE, NULL, 0x0,
6200         NULL, HFILL }
6201     },
6202
6203     /* Command Gateway */
6204     { &hf_magic_command_gateway,
6205       { "Gateway", "magic.gateway",
6206         FT_IPv4, BASE_NONE, NULL, 0x0,
6207         NULL, HFILL }
6208     },
6209
6210     /* Reply IP Address */
6211     { &hf_magic_reply_ip_address,
6212       { "IP", "magic.reply.ip_address",
6213         FT_IPv4, BASE_NONE, NULL, 0x0,
6214         "Local IP Address", HFILL }
6215     },
6216
6217     /* Reply Subnet Mask */
6218     { &hf_magic_reply_subnet_mask,
6219       { "Subnet Mask", "magic.reply.subnet_mask",
6220         FT_IPv4, BASE_NONE, NULL, 0x0,
6221         "Local Subnet Mask", HFILL }
6222     },
6223
6224     /* Reply Gateway */
6225     { &hf_magic_reply_gateway,
6226       { "Gateway", "magic.reply.gateway",
6227         FT_IPv4, BASE_NONE, NULL, 0x0,
6228         "Local Gateway", HFILL }
6229     },
6230
6231     /* Reply TFTP */
6232     { &hf_magic_reply_tftp,
6233       { "TFTP IP", "magic.reply.tftp",
6234         FT_IPv4, BASE_NONE, NULL, 0x0,
6235         "IP of TFTP server", HFILL }
6236     },
6237
6238     /* Reply Version */
6239     { &hf_magic_reply_version,
6240       { "Reply Version", "magic.reply.version",
6241         FT_STRING, BASE_NONE, NULL, 0x0,
6242         NULL, HFILL }
6243     },
6244
6245     /* Reply Device Type Name */
6246     { &hf_magic_reply_device_type_name,
6247       { "Device Type Name", "magic.reply.device_type_name",
6248         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
6249         "Reply Device Type Name", HFILL }
6250     },
6251
6252     /* Reply Default Name */
6253     { &hf_magic_reply_default_name,
6254       { "Default Name", "magic.reply.default_name",
6255         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
6256         "Reply Default Name", HFILL }
6257     },
6258
6259     /* Reply User Name */
6260     { &hf_magic_reply_user_name,
6261       { "User Name", "magic.reply.user_name",
6262         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
6263         "Reply User Name", HFILL }
6264     },
6265
6266     /* CID */
6267     { &hf_magic_reply_cid,
6268       { "CID", "magic.reply.cid",
6269         FT_GUID, BASE_NONE, NULL, 0x0,
6270         "Reply CID", HFILL }
6271     },
6272
6273     /* DCID */
6274     { &hf_magic_reply_dcid,
6275       { "DCID", "magic.reply.dcid",
6276         FT_GUID, BASE_NONE, NULL, 0x0,
6277         "Reply DCID", HFILL }
6278     },
6279
6280     /* Invalid Reply Type */
6281     { &hf_magic_reply_invalid_type,
6282       { "Invalid type", "magic.reply.dcid",
6283         FT_UINT8, BASE_DEC, NULL, 0x0,
6284         "Invalid Reply Type", HFILL }
6285     }
6286   };
6287
6288   /* Setup protocol subtree array */
6289   static gint *ett[] = {
6290     &ett_acn,
6291     &ett_acn_channel_owner_info_block,
6292     &ett_acn_channel_member_info_block,
6293     &ett_acn_channel_parameter,
6294     &ett_acn_address,
6295     &ett_acn_address_type,
6296     &ett_acn_pdu_flags,
6297     &ett_acn_dmp_pdu,
6298     &ett_acn_sdt_pdu,
6299     &ett_acn_sdt_client_pdu,
6300     &ett_acn_sdt_base_pdu,
6301     &ett_acn_root_pdu,
6302     &ett_acn_dmx_address,
6303     &ett_acn_dmx_2_options,
6304     &ett_acn_dmx_data_pdu,
6305     &ett_acn_dmx_pdu,
6306     &ett_acn_blob
6307   };
6308
6309   /* Setup protocol subtree array */
6310   static gint *magic_ett[] = {
6311     &ett_magic
6312   };
6313
6314   module_t *acn_module;
6315   proto_acn = proto_register_protocol (
6316     "Architecture for Control Networks", /* name */
6317     "ACN",                               /* short name */
6318     "acn"                                /* abbrev */
6319     );
6320
6321   proto_magic = proto_register_protocol(
6322     "Magic",                             /* name */
6323     "MAGIC",                             /* short name */
6324     "magic"                              /* abbrev */
6325     );
6326
6327   proto_register_field_array(proto_acn, hf, array_length(hf));
6328   proto_register_subtree_array(ett, array_length(ett));
6329
6330   acn_module = prefs_register_protocol(proto_acn, NULL);
6331   prefs_register_obsolete_preference(acn_module, "heuristic_acn");
6332
6333   prefs_register_bool_preference(acn_module, "dmx_enable",
6334                                  "Streaming DMX",
6335                                  "Enable Streaming DMX extension dissector (ANSI BSR E1.31)",
6336                                  &global_acn_dmx_enable);
6337
6338   prefs_register_enum_preference(acn_module, "dmx_display_view",
6339                                  "DMX, display format",
6340                                  "Display format",
6341                                  &global_acn_dmx_display_view,
6342                                  dmx_display_view,
6343                                  TRUE);
6344
6345   prefs_register_bool_preference(acn_module, "dmx_display_zeros",
6346                                  "DMX, display zeros",
6347                                  "Display zeros instead of dots",
6348                                  &global_acn_dmx_display_zeros);
6349
6350   prefs_register_bool_preference(acn_module, "dmx_display_leading_zeros",
6351                                  "DMX, display leading zeros",
6352                                  "Display leading zeros on levels",
6353                                  &global_acn_dmx_display_leading_zeros);
6354
6355   prefs_register_enum_preference(acn_module, "dmx_display_line_format",
6356                                  "DMX, display line format",
6357                                  "Display line format",
6358                                  &global_acn_dmx_display_line_format,
6359                                  dmx_display_line_format,
6360                                  TRUE);
6361
6362   proto_register_field_array(proto_magic, magic_hf, array_length(magic_hf));
6363   proto_register_subtree_array(magic_ett, array_length(magic_ett));
6364 }
6365
6366
6367 /******************************************************************************/
6368 /* Register handoff                                                           */
6369 void
6370 proto_reg_handoff_acn(void)
6371 {
6372   /* dissector_handle_t acn_handle; */
6373   /* acn_handle = create_dissector_handle(dissect_acn, proto_acn); */
6374   /* dissector_add_for_decode_as_with_preference("udp.port", acn_handle);                         */
6375   heur_dissector_add("udp", dissect_acn_heur, "ACN over UDP", "acn_udp", proto_acn, HEURISTIC_DISABLE);
6376 }
6377
6378 /*
6379  * Editor modelines
6380  *
6381  * Local Variables:
6382  * c-basic-offset: 2
6383  * tab-width: 8
6384  * indent-tabs-mode: nil
6385  * End:
6386  *
6387  * ex: set shiftwidth=2 tabstop=8 expandtab:
6388  * :indentSize=2:tabSize=8:noTabs=true:
6389  */