/src/wireshark/epan/dissectors/packet-idn.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-idn.c |
2 | | * Routines for IDN dissection |
3 | | * By Maxim Kropp <maxim.kropp@hotmail.de> |
4 | | * Copyright 2017 Maxim Kropp |
5 | | * |
6 | | * Supervised by Matthias Frank <matthew@cs.uni-bonn.de> |
7 | | * Copyright 2017 Matthias Frank, Institute of Computer Science 4, University of Bonn |
8 | | * |
9 | | * Stream Specification: https://www.ilda.com/resources/StandardsDocs/ILDA_IDN-Stream_rev001.pdf |
10 | | * This specification only defines IDN messages, the other packet commands |
11 | | * are part of the hello specification which is not released yet. |
12 | | * All ILDA Technical Standards can be found at https://www.ilda.com/technical.htm |
13 | | * |
14 | | * Wireshark - Network traffic analyzer |
15 | | * By Gerald Combs <gerald@wireshark.org> |
16 | | * Copyright 1998 Gerald Combs |
17 | | * |
18 | | * SPDX-License-Identifier: GPL-2.0-or-later |
19 | | */ |
20 | | |
21 | | #include <config.h> |
22 | | #include <epan/packet.h> |
23 | | #include <epan/conversation.h> |
24 | | #include <epan/expert.h> |
25 | | |
26 | | #include <wsutil/array.h> |
27 | | |
28 | 14 | #define IDN_PORT 7255 |
29 | | |
30 | 26 | #define MAX_CHANNELS 512 |
31 | | #define MAX_BUFFER 2048 |
32 | | |
33 | | /* Packet Commands */ |
34 | 1.00k | #define IDNCMD_VOID 0x00 |
35 | | #define IDNCMD_PING_REQUEST 0x08 |
36 | 498 | #define IDNCMD_PING_RESPONSE 0x09 |
37 | | #define IDNCMD_SCAN_REQUEST 0x10 |
38 | 1 | #define IDNCMD_SCAN_RESPONSE 0x11 |
39 | | #define IDNCMD_SERVICEMAP_REQUEST 0x12 |
40 | 10 | #define IDNCMD_SERVICEMAP_RESPONSE 0x13 |
41 | 22 | #define IDNCMD_MESSAGE 0x40 |
42 | 76 | #define IDNCMD_MESSAGE_ACKREQ 0x41 |
43 | 186 | #define IDNCMD_MESSAGE_CLOSE 0x44 |
44 | 231 | #define IDNCMD_MESSAGE_ACKREQ_CLOSE 0x45 |
45 | 1 | #define IDNCMD_MESSAGE_ACK 0x47 |
46 | | |
47 | | /* Chunk Types */ |
48 | 631 | #define IDNCT_VOID 0x00 |
49 | 4 | #define IDNCT_LP_WAVE_SAMPLE 0x01 |
50 | 5 | #define IDNCT_LP_FRAME_CHUNK 0x02 |
51 | 7 | #define IDNCT_LP_FRAME_FF 0x03 |
52 | 568 | #define IDNCT_LP_FRAME_SF 0xC0 |
53 | 691 | #define IDNCT_OCTET_SEGMENT 0x10 |
54 | 98 | #define IDNCT_OCTET_STRING 0x11 |
55 | 54 | #define IDNCT_DIMMER_LEVELS 0x18 |
56 | 365 | #define IDNCT_AUDIO_WAVE_SAMPLE 0x20 |
57 | | |
58 | | /* Service Modes (CONT = continuous stream, DISC = discrete stream) */ |
59 | | #define IDNSM_VOID 0x00 |
60 | | #define IDNSM_LP_GRAPHIC_CONT 0x01 |
61 | | #define IDNSM_LP_GRAPHIC_DISC 0x02 |
62 | | #define IDNSM_LP_EFFECTS_CONT 0x03 |
63 | | #define IDNSM_LP_EFFECTS_DISC 0x04 |
64 | | #define IDNSM_DMX512_CONT 0x05 |
65 | | #define IDNSM_DMX512_DISC 0x06 |
66 | | #define IDNSM_AUDIO_WAVE_SEGMENTS 0x0C |
67 | | |
68 | | /* Dictionary Tags */ |
69 | 4.28k | #define IDNTAG_PRECISION 0x4010 |
70 | 3.96k | #define IDNTAG_WAVELENGTH_PREFIX 0x5C00 |
71 | 3.95k | #define IDNTAG_INTENSITY 0x5C10 |
72 | 3.95k | #define IDNTAG_BEAM_BRUSH 0x5C20 |
73 | 8.55k | #define IDNTAG_BREAK_START 0x1000 |
74 | 3.41k | #define IDNTAG_BREAK_END 0x100F |
75 | 8.50k | #define IDNTAG_SPACE_MOD_START 0x1100 |
76 | 3.27k | #define IDNTAG_SPACE_MOD_END 0x11FF |
77 | 4.14k | #define IDNTAG_NOP 0x4000 |
78 | 8.26k | #define IDNTAG_HINT0 0x4100 |
79 | 2.28k | #define IDNTAG_HINT1 0x4101 |
80 | 8.16k | #define IDNTAG_COLOR_START 0x5000 |
81 | 1.90k | #define IDNTAG_COLOR_END 0x53FF |
82 | | #define IDNTAG_COLOR_RED 0x527E |
83 | | #define IDNTAG_COLOR_GREEN 0x5214 |
84 | | #define IDNTAG_COLOR_BLUE 0x51CC |
85 | | #define IDNTAG_OPTIONAL_U1 0x51BD |
86 | | #define IDNTAG_OPTIONAL_U2 0x5241 |
87 | | #define IDNTAG_OPTIONAL_U3 0x51E8 |
88 | 44 | #define IDNTAG_OPTIONAL_U4 0x4201 |
89 | 8.25k | #define IDNTAG_COORD_X 0x4200 |
90 | 2.16k | #define IDNTAG_COORD_X_END 0x420F |
91 | 8.21k | #define IDNTAG_COORD_Y 0x4210 |
92 | 2.14k | #define IDNTAG_COORD_Y_END 0x421F |
93 | 8.19k | #define IDNTAG_COORD_Z 0x4220 |
94 | 2.13k | #define IDNTAG_COORD_Z_END 0x422F |
95 | 4.54k | #define IDNTAG_DIMMER_START 0x0040 |
96 | 1.71k | #define IDNTAG_DIMMER_END 0x004F |
97 | | |
98 | | /* Other */ |
99 | 9.10k | #define IDNO_VOID_AREA 0xF |
100 | | |
101 | | typedef struct { |
102 | | bool has_config_header; |
103 | | bool is_dmx; |
104 | | uint16_t total_size; |
105 | | uint8_t channel_id; |
106 | | uint8_t chunk_type; |
107 | | gboolean is_audio; |
108 | | } message_info; |
109 | | |
110 | | typedef struct { |
111 | | uint8_t word_count; |
112 | | uint8_t sdm; |
113 | | char *dic_precision; |
114 | | wmem_strbuf_t *sample_column_string; |
115 | | int sample_size; |
116 | | int *count; |
117 | | int *base; |
118 | | guint8 audio_format; |
119 | | guint8 audio_channels; |
120 | | } configuration_info; |
121 | | |
122 | | void proto_register_idn(void); |
123 | | void proto_reg_handoff_idn(void); |
124 | | |
125 | | static dissector_handle_t idn_handle; |
126 | | |
127 | | static int proto_idn; |
128 | | |
129 | | static int ett_idn; |
130 | | static int ett_idn_header_tree; |
131 | | static int ett_idn_scanreply_header_tree; |
132 | | static int ett_idn_channel_message_header_tree; |
133 | | static int ett_protocol_version; |
134 | | static int ett_unit_id; |
135 | | static int ett_status; |
136 | | static int ett_idn_cnl; |
137 | | static int ett_configuration_header; |
138 | | static int ett_chunk_header_tree; |
139 | | static int ett_chunk_header_flags; |
140 | | static int ett_cfl; |
141 | | static int ett_dic; |
142 | | static int ett_dic_tree; |
143 | | static int ett_data; |
144 | | static int ett_subdata; |
145 | | static int ett_dmx_subtree; |
146 | | static int ett_audio_header; |
147 | | static int ett_audio_samples; |
148 | | |
149 | | static expert_field ei_idn_no_config; |
150 | | static expert_field ei_idn_scwc_unknown; |
151 | | static expert_field ei_idn_channels_over; |
152 | | static expert_field ei_idn_scm_mismatch; |
153 | | |
154 | | /* IDN-Header */ |
155 | | static int hf_idn_command; |
156 | | static int hf_idn_flags; |
157 | | static int hf_idn_sequence; |
158 | | static int hf_idn_total_size; |
159 | | |
160 | | /* Scanreply Header */ |
161 | | static int hf_idn_struct_size; |
162 | | static int hf_idn_protocol_version; |
163 | | static int hf_idn_protocol_version_major; |
164 | | static int hf_idn_protocol_version_minor; |
165 | | static int hf_idn_status; |
166 | | static int hf_idn_malfn; |
167 | | static int hf_idn_offline; |
168 | | static int hf_idn_xcld; |
169 | | static int hf_idn_ocpd; |
170 | | static int hf_idn_rt; |
171 | | static int hf_idn_reserved8; |
172 | | static int hf_idn_unit_id; |
173 | | static int hf_idn_uid_length; |
174 | | static int hf_idn_uid_category; |
175 | | static int hf_idn_uid; |
176 | | static int hf_idn_name; |
177 | | |
178 | | /* Service Map Response */ |
179 | | static int hf_idn_entry_size; |
180 | | static int hf_idn_relay_count; |
181 | | static int hf_idn_service_count; |
182 | | static int hf_idn_relay_number; |
183 | | |
184 | | /* Channel Message Header */ |
185 | | static int hf_idn_cnl; |
186 | | static int hf_idn_most_significant_bit_cnl; |
187 | | static int hf_idn_cclf; |
188 | | static int hf_idn_channel_id; |
189 | | static int hf_idn_chunk_type; |
190 | | static int hf_idn_timestamp; |
191 | | |
192 | | /* Configuration Header */ |
193 | | static int hf_idn_scwc; |
194 | | static int hf_idn_cfl; |
195 | | static int hf_idn_sdm; |
196 | | static int hf_idn_close; |
197 | | static int hf_idn_routing; |
198 | | static int hf_idn_service_id; |
199 | | static int hf_idn_service_mode; |
200 | | |
201 | | /* Chunk Header */ |
202 | | static int hf_idn_chunk_header_flags; |
203 | | static int hf_idn_two_bits_reserved_1; |
204 | | static int hf_idn_two_bits_reserved_2; |
205 | | static int hf_idn_three_bits_reserved; |
206 | | static int hf_idn_four_bits_reserved; |
207 | | static int hf_idn_scm; |
208 | | static int hf_idn_once; |
209 | | static int hf_idn_duration; |
210 | | static int hf_idn_chunk_data_sequence; |
211 | | static int hf_idn_offset; |
212 | | static int hf_idn_dlim; |
213 | | static int hf_idn_reserved; |
214 | | |
215 | | /* Audio Dictionary Tags */ |
216 | | static int hf_idn_audio_dictionary_tag; |
217 | | static int hf_idn_category; |
218 | | static int hf_idn_format; |
219 | | static int hf_idn_subcategory; |
220 | | static int hf_idn_parameter; |
221 | | static int hf_idn_suffix_length; |
222 | | static int hf_idn_layout; |
223 | | static int hf_idn_4bit_channels; |
224 | | static int hf_idn_8bit_channels; |
225 | | |
226 | | /* Audio Header */ |
227 | | static int hf_idn_audio_flags; |
228 | | static int hf_idn_audio_duration; |
229 | | static int hf_idn_audio_flags_two_bits_reserved; |
230 | | static int hf_idn_audio_flags_four_bits_reserved; |
231 | | static int hf_idn_audio_flags_scm; |
232 | | |
233 | | /* Audio Samples */ |
234 | | static int hf_idn_audio_sample_format_zero; |
235 | | static int hf_idn_audio_sample_format_one; |
236 | | static int hf_idn_audio_sample_format_two; |
237 | | /* Tags */ |
238 | | static int hf_idn_gts; |
239 | | static int hf_idn_gts_void; |
240 | | static int hf_idn_boundary; |
241 | | static int hf_idn_gts_word; |
242 | | static int hf_idn_gts_break; |
243 | | static int hf_idn_gts_space_modifier; |
244 | | static int hf_idn_gts_hint; |
245 | | static int hf_idn_gts_category; |
246 | | static int hf_idn_gts_subcategory; |
247 | | static int hf_idn_gts_identifier; |
248 | | static int hf_idn_gts_parameter; |
249 | | static int hf_idn_gts_glin; |
250 | | static int hf_idn_gts_clin; |
251 | | static int hf_idn_gts_cbal; |
252 | | static int hf_idn_gts_ctim; |
253 | | static int hf_idn_gts_nop; |
254 | | static int hf_idn_gts_precision; |
255 | | static int hf_idn_gts_cscl; |
256 | | static int hf_idn_gts_iscl; |
257 | | static int hf_idn_gts_sht; |
258 | | static int hf_idn_gts_u4; |
259 | | static int hf_idn_gts_x; |
260 | | static int hf_idn_gts_y; |
261 | | static int hf_idn_gts_z; |
262 | | static int hf_idn_gts_color; |
263 | | static int hf_idn_gts_wavelength_prefix; |
264 | | static int hf_idn_gts_intensity; |
265 | | static int hf_idn_gts_beam_brush; |
266 | | static int hf_idn_gts_sample; |
267 | | static int hf_idn_dmx_octet; |
268 | | static int hf_idn_dmx_identifier; |
269 | | static int hf_idn_dmx_parameter; |
270 | | static int hf_idn_dmx_void; |
271 | | static int hf_idn_octet; |
272 | | static int hf_idn_dmx_base; |
273 | | static int hf_idn_dmx_count; |
274 | | static int hf_idn_dmx_dls; |
275 | | static int hf_idn_dmx_unknown; |
276 | | |
277 | | /* Acknowledgement */ |
278 | | static int hf_idn_result_code; |
279 | | static int hf_idn_event_flags; |
280 | | |
281 | | /* Long Bitmasks that need defining */ |
282 | | |
283 | | |
284 | | static const value_string command_code[] = { |
285 | | { IDNCMD_VOID, "VOID" }, |
286 | | { IDNCMD_PING_REQUEST, "PING_REQUEST" }, |
287 | | { IDNCMD_PING_RESPONSE, "PING_RESPONSE" }, |
288 | | { IDNCMD_SCAN_REQUEST, "SCAN_REQUEST" }, |
289 | | { IDNCMD_SCAN_RESPONSE, "SCAN_RESPONSE" }, |
290 | | { IDNCMD_SERVICEMAP_REQUEST, "SERVICEMAP_REQUEST" }, |
291 | | { IDNCMD_SERVICEMAP_RESPONSE, "SERVICEMAP_RESPONSE" }, |
292 | | { IDNCMD_MESSAGE, "MESSAGE" }, |
293 | | { IDNCMD_MESSAGE_ACKREQ, "MESSAGE_ACKREQ" }, |
294 | | { IDNCMD_MESSAGE_CLOSE, "MESSAGE_CLOSE" }, |
295 | | { IDNCMD_MESSAGE_ACKREQ_CLOSE, "MESSAGE_ACKREQ_CLOSE" }, |
296 | | { IDNCMD_MESSAGE_ACK, "MESSAGE_ACK" }, |
297 | | { 0, NULL} |
298 | | }; |
299 | | static const value_string chunk_type[] = { |
300 | | { IDNCT_VOID, "VOID" }, |
301 | | { IDNCT_LP_WAVE_SAMPLE, "Laser Projector Wave Samples" }, |
302 | | { IDNCT_LP_FRAME_CHUNK, "Laser Projector Frame Samples (entire chunk)" }, |
303 | | { IDNCT_LP_FRAME_FF, "Laser Projector Frame Samples (first fragment)" }, |
304 | | { IDNCT_OCTET_SEGMENT, "Octet Segment" }, |
305 | | { IDNCT_OCTET_STRING, "Octet String" }, |
306 | | { IDNCT_DIMMER_LEVELS, "Dimmer Levels" }, |
307 | | { IDNCT_LP_FRAME_SF, "Laser Projector Frame Samples (sequel fragment)" }, |
308 | | { IDNCT_AUDIO_WAVE_SAMPLE, "Audio Wave Samples"}, |
309 | | { 0, NULL} |
310 | | }; |
311 | | static const value_string chunk_type_header[] = { |
312 | | { IDNCT_LP_WAVE_SAMPLE, "Wave Sample" }, |
313 | | { IDNCT_LP_FRAME_CHUNK, "Frame Sample" }, |
314 | | { IDNCT_LP_FRAME_FF, "Frame Sample" }, |
315 | | { IDNCT_OCTET_SEGMENT, "Octet Segment" }, |
316 | | { IDNCT_OCTET_STRING, "Octet String" }, |
317 | | { IDNCT_DIMMER_LEVELS, "Dimmer Levels" }, |
318 | | { 0, NULL} |
319 | | }; |
320 | | static const value_string cfl_string[] = { |
321 | | { 0x30, "DATA_MATCH" }, |
322 | | { 0x01, "ROUTING" }, |
323 | | { 0x02, "CLOSE" }, |
324 | | { 0, NULL} |
325 | | }; |
326 | | static const value_string service_mode_string[] = { |
327 | | { IDNSM_VOID, "VOID" }, |
328 | | { IDNSM_LP_GRAPHIC_CONT, "Laser Projector Graphic (Continuous)" }, |
329 | | { IDNSM_LP_GRAPHIC_DISC, "Laser Projector Graphic (Discrete)" }, |
330 | | { IDNSM_LP_EFFECTS_CONT, "Laser Projector Effects (Continuous)" }, |
331 | | { IDNSM_LP_EFFECTS_DISC, "Laser Projector Effects (Discrete)" }, |
332 | | { IDNSM_DMX512_CONT, "DMX512 (Continuous)" }, |
333 | | { IDNSM_DMX512_DISC, "DMX512 (Discrete)" }, |
334 | | { IDNSM_AUDIO_WAVE_SEGMENTS, "Audio: Stream of waveform segments"}, |
335 | | { 0, NULL} |
336 | | }; |
337 | | static const value_string gts_glin[] = { |
338 | | { 0, "Projector specific" }, |
339 | | { 1, "Geometrically corrected and linear, aspect ratio 1:1" }, |
340 | | { 2, "Reserved" }, |
341 | | { 3, "No transformation" }, |
342 | | { 0, NULL} |
343 | | }; |
344 | | static const value_string gts_clin[] = { |
345 | | { 0, "Projector specific" }, |
346 | | { 1, "Power linear (half value SHALL be half power)" }, |
347 | | { 2, "Visually linear (half value SHALL be half brightness)" }, |
348 | | { 3, "No transformation" }, |
349 | | { 0, NULL} |
350 | | }; |
351 | | static const value_string gts_cbal[] = { |
352 | | { 0, "Projector specific" }, |
353 | | { 1, "White balanced" }, |
354 | | { 2, "Reserved" }, |
355 | | { 3, "No transformation" }, |
356 | | { 0, NULL} |
357 | | }; |
358 | | static const value_string gts_ctim[] = { |
359 | | { 0, "Projector specific" }, |
360 | | { 1, "Coordinates and colors correlated in time" }, |
361 | | { 2, "Reserved" }, |
362 | | { 3, "No transformation" }, |
363 | | { 0, NULL} |
364 | | }; |
365 | | static const value_string idn_color[] = { |
366 | | { 638, "Red" }, |
367 | | { 532, "Green" }, |
368 | | { 460, "Blue" }, |
369 | | { 445, "Optional(U1), used as deep blue" }, |
370 | | { 577, "Optional(U2), used as yellow" }, |
371 | | { 488, "Optional(U3), used as cyan" }, |
372 | | { 0, NULL} |
373 | | }; |
374 | | static const value_string idn_cat_color[] = { |
375 | | { IDNTAG_OPTIONAL_U1, "U1" }, |
376 | | { IDNTAG_COLOR_BLUE, "B" }, |
377 | | { IDNTAG_OPTIONAL_U3, "U3" }, |
378 | | { IDNTAG_COLOR_GREEN, "G" }, |
379 | | { IDNTAG_OPTIONAL_U2, "U2" }, |
380 | | { IDNTAG_COLOR_RED, "R" }, |
381 | | { 0, NULL} |
382 | | }; |
383 | | static const value_string result_code[] = { |
384 | | { 0x00, "Message successfully received and passed to the IDN session" }, |
385 | | { 0xEB, "Empty (no message) close command without established connection" }, |
386 | | { 0xEC, "All sessions are occupied by clients (new connection refused)" }, |
387 | | { 0xED, "The client group is excluded from streaming" }, |
388 | | { 0xEE, "Invalid payload" }, |
389 | | { 0xEF, "Any other processing error" }, |
390 | | { 0, NULL} |
391 | | }; |
392 | | |
393 | | static const value_string category[] _U_= { |
394 | | { 0x0, "Decoder modifiers with suffix" }, |
395 | | { 0x1, "Decoder modifiers with parameter" }, |
396 | | { 0x4, "Sample word descriptors" }, |
397 | | { 0x6, "Common channel layout descriptors" }, |
398 | | { 0x8, "Multichannel layout descriptors" }, |
399 | | { 0, NULL } |
400 | | }; |
401 | | |
402 | | static const value_string format[] _U_={ |
403 | | { 0x0, "8 Bit signed integer (one octet)" }, |
404 | | { 0x1, "16 Bit signed integer (two octets)" }, |
405 | | { 0x2, "24 Bit signed integer (three octets)" }, |
406 | | { 0, NULL } |
407 | | }; |
408 | | |
409 | 225 | static int get_service_match(uint8_t flags) { |
410 | 225 | return flags >> 4; |
411 | 225 | } |
412 | | |
413 | 230 | static void determine_message_type(packet_info *pinfo, message_info *minfo) { |
414 | 230 | minfo->is_dmx = 0; |
415 | 230 | minfo->is_audio = 0; |
416 | 230 | switch(minfo->chunk_type) { |
417 | 19 | case IDNCT_VOID: |
418 | 19 | col_append_str(pinfo->cinfo, COL_INFO, "-VOID"); |
419 | 19 | break; |
420 | 3 | case IDNCT_LP_WAVE_SAMPLE: |
421 | 3 | col_append_str(pinfo->cinfo, COL_INFO, "-WAVE"); |
422 | 3 | break; |
423 | 2 | case IDNCT_LP_FRAME_CHUNK: |
424 | 2 | col_append_str(pinfo->cinfo, COL_INFO, "-FRAME"); |
425 | 2 | break; |
426 | 2 | case IDNCT_LP_FRAME_FF: |
427 | 2 | col_append_str(pinfo->cinfo, COL_INFO, "-FIRST"); |
428 | 2 | break; |
429 | 10 | case IDNCT_DIMMER_LEVELS: |
430 | 10 | col_append_str(pinfo->cinfo, COL_INFO, "-DMX"); |
431 | 10 | minfo->is_dmx = 1; |
432 | 10 | break; |
433 | 44 | case IDNCT_OCTET_STRING: |
434 | 44 | col_append_str(pinfo->cinfo, COL_INFO, "-DMX"); |
435 | 44 | minfo->is_dmx = 1; |
436 | 44 | break; |
437 | 10 | case IDNCT_OCTET_SEGMENT: |
438 | 10 | col_append_str(pinfo->cinfo, COL_INFO, "-DMX"); |
439 | 10 | minfo->is_dmx = 1; |
440 | 10 | break; |
441 | 1 | case IDNCT_LP_FRAME_SF: |
442 | 1 | if(minfo->has_config_header) { |
443 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "-LAST"); |
444 | 1 | }else { |
445 | 1 | col_append_str(pinfo->cinfo, COL_INFO, "-SEQ"); |
446 | 1 | } |
447 | 1 | break; |
448 | 40 | case IDNCT_AUDIO_WAVE_SAMPLE: |
449 | 40 | col_append_str(pinfo->cinfo, COL_INFO, "-AUDIO"); |
450 | 40 | minfo->is_audio = 1; |
451 | 40 | break; |
452 | 99 | default: |
453 | 99 | col_append_str(pinfo->cinfo, COL_INFO, "-UNKNOWN"); |
454 | 230 | } |
455 | 230 | } |
456 | | |
457 | 1 | static int dissect_idn_message_acknowledgement(tvbuff_t *tvb, int offset, proto_tree *idn_tree) { |
458 | 1 | proto_tree *idn_message_acknowledgement_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 4, ett_idn_header_tree, NULL, "Message Acknowledgement"); |
459 | 1 | proto_tree_add_item(idn_message_acknowledgement_tree, hf_idn_struct_size, tvb, offset, 1, ENC_BIG_ENDIAN); |
460 | 1 | offset += 1; |
461 | 1 | proto_tree_add_item(idn_message_acknowledgement_tree, hf_idn_result_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
462 | 1 | offset += 1; |
463 | 1 | proto_tree_add_item(idn_message_acknowledgement_tree, hf_idn_event_flags, tvb, offset, 2, ENC_BIG_ENDIAN); |
464 | 1 | offset += 2; |
465 | 1 | return offset; |
466 | 1 | } |
467 | | |
468 | 4 | static configuration_info *get_configuration_info(packet_info *pinfo, int channel_id) { |
469 | 4 | configuration_info *config = NULL; |
470 | | |
471 | 4 | conversation_element_t *conv_key = wmem_alloc_array(pinfo->pool, conversation_element_t, 6); |
472 | 4 | conv_key[0].type = CE_ADDRESS; |
473 | 4 | conv_key[0].addr_val = pinfo->src; |
474 | 4 | conv_key[1].type = CE_PORT; |
475 | 4 | conv_key[1].port_val = pinfo->srcport; |
476 | 4 | conv_key[2].type = CE_ADDRESS; |
477 | 4 | conv_key[2].addr_val = pinfo->dst; |
478 | 4 | conv_key[3].type = CE_PORT; |
479 | 4 | conv_key[3].port_val = pinfo->destport; |
480 | 4 | conv_key[4].type = CE_UINT; |
481 | 4 | conv_key[4].uint_val = channel_id; |
482 | 4 | conv_key[5].type = CE_CONVERSATION_TYPE; |
483 | 4 | conv_key[5].conversation_type_val = CONVERSATION_IDN; |
484 | | |
485 | 4 | conversation_t *conv = find_conversation_full(pinfo->num, conv_key); |
486 | 4 | if(conv) { |
487 | 2 | wmem_tree_t *config_tree = (wmem_tree_t*)conversation_get_proto_data(conv, proto_idn); |
488 | 2 | if (config_tree) { |
489 | 2 | config = (configuration_info *)wmem_tree_lookup32_le(config_tree, pinfo->num); |
490 | 2 | } |
491 | 2 | } |
492 | | |
493 | 4 | return config; |
494 | 4 | } |
495 | | |
496 | 13 | static int dissect_idn_dmx_sample_values(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *idn_dmx_subtree, uint16_t data_size, int base) { |
497 | 13 | int i, j; |
498 | 13 | short int rest; |
499 | 13 | wmem_strbuf_t* values; |
500 | | |
501 | 83 | for(i=0; i+16<=data_size; i+=16) { |
502 | 70 | values = wmem_strbuf_new(pinfo->pool, ""); |
503 | 1.07k | for(j=1; j<16; j++){ |
504 | 1.00k | wmem_strbuf_append_printf(values, " %3d", tvb_get_uint8(tvb, offset+j)); |
505 | 1.00k | } |
506 | 70 | proto_tree_add_bytes_format(idn_dmx_subtree, hf_idn_gts_sample, tvb, offset, 16, NULL, "%3d: %s", base+i, wmem_strbuf_get_str(values)); |
507 | 70 | offset += 16; |
508 | 70 | } |
509 | 13 | rest = data_size - i; |
510 | 13 | if(rest > 0) { |
511 | 6 | values = wmem_strbuf_new(pinfo->pool, ""); |
512 | 42 | for(j=0; j<rest; j++){ |
513 | 36 | wmem_strbuf_append_printf(values, " %3d", tvb_get_uint8(tvb, offset+j)); |
514 | 36 | } |
515 | 6 | proto_tree_add_bytes_format(idn_dmx_subtree, hf_idn_gts_sample, tvb, offset, rest, NULL, "%3d: %s", base+i, wmem_strbuf_get_str(values)); |
516 | 6 | offset += rest; |
517 | 6 | } |
518 | 13 | return offset; |
519 | 13 | } |
520 | | |
521 | 1.21k | static void set_laser_sample_values_string(tvbuff_t *tvb, int offset, configuration_info *config, wmem_strbuf_t* values) { |
522 | 1.21k | int i; |
523 | 1.21k | if((config->dic_precision)[2] == 1) |
524 | 0 | wmem_strbuf_append_printf(values, "%5d", tvb_get_uint16(tvb, offset, 2)); |
525 | 1.21k | else |
526 | 1.21k | wmem_strbuf_append_printf(values, "%5d", tvb_get_uint8(tvb, offset)); |
527 | | |
528 | 3.95k | for(i=1; i<config->sample_size; i++){ |
529 | 2.74k | if((config->dic_precision)[i+1] == 1) { |
530 | | //do nothing |
531 | 2.74k | }else if((config->dic_precision)[i+2] == 1) { |
532 | 28 | wmem_strbuf_append_printf(values, " %5d", tvb_get_uint16(tvb, offset+i, 2)); |
533 | 28 | i++; |
534 | 2.71k | }else { |
535 | 2.71k | wmem_strbuf_append_printf(values, " %5d", tvb_get_uint8(tvb, offset+i)); |
536 | 2.71k | } |
537 | 2.74k | } |
538 | 1.21k | } |
539 | | |
540 | 10 | static int dissect_idn_octet_segment(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *idn_tree) { |
541 | 10 | int i, j; |
542 | 10 | short int rest; |
543 | 10 | wmem_strbuf_t* values; |
544 | 10 | int data_size = tvb_reported_length_remaining(tvb, offset); |
545 | 10 | proto_tree *idn_samples_tree = proto_tree_add_subtree(idn_tree, tvb, offset, data_size, ett_data, NULL, "Octets"); |
546 | | |
547 | 86 | for(i=0; i+16<=data_size; i+=16) { |
548 | 76 | values = wmem_strbuf_new(pinfo->pool, ""); |
549 | 1.29k | for(j=0; j<16; j++){ |
550 | 1.21k | wmem_strbuf_append_printf(values, " %3d", tvb_get_int8(tvb, offset+j)); |
551 | 1.21k | } |
552 | 76 | proto_tree_add_bytes_format(idn_samples_tree, hf_idn_gts_sample, tvb, offset, 16, NULL, "%s", wmem_strbuf_get_str(values)); |
553 | 76 | offset += 16; |
554 | 76 | } |
555 | 10 | rest = data_size - i; |
556 | 10 | if(rest > 0) { |
557 | 9 | values = wmem_strbuf_new(pinfo->pool, ""); |
558 | 99 | for(j=0; j<rest; j++){ |
559 | 90 | wmem_strbuf_append_printf(values, " %3d", tvb_get_int8(tvb, offset+j)); |
560 | 90 | } |
561 | 9 | proto_tree_add_bytes_format(idn_samples_tree, hf_idn_gts_sample, tvb, offset, rest, NULL, "%s", wmem_strbuf_get_str(values)); |
562 | 9 | offset += rest; |
563 | 9 | } |
564 | 10 | return offset; |
565 | 10 | } |
566 | | |
567 | 27 | static int dissect_idn_dmx_data(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *idn_tree, configuration_info *config) { |
568 | 27 | int i; |
569 | 27 | int *count = config->count; |
570 | 27 | int *base = config->base; |
571 | 27 | int base_value; |
572 | 27 | int data_size = tvb_reported_length_remaining(tvb, offset); |
573 | 27 | proto_tree *idn_samples_tree = proto_tree_add_subtree(idn_tree, tvb, offset, data_size, ett_data, NULL, "Channels"); |
574 | 27 | proto_tree *idn_dmx_subtree; |
575 | | |
576 | 40 | for(i=0; i<config->word_count; i++) { |
577 | 28 | base_value = base[i]-1; |
578 | 28 | if(base_value == -1) |
579 | 14 | break; |
580 | 14 | if(count[i] != -1) { |
581 | 3 | data_size = count[i]; |
582 | 3 | if(data_size + base_value > MAX_CHANNELS) { |
583 | 1 | expert_add_info_format(pinfo, idn_samples_tree, &ei_idn_channels_over, "Over %5d Channels", MAX_CHANNELS); |
584 | 1 | return offset; |
585 | 1 | } |
586 | 2 | idn_dmx_subtree = proto_tree_add_subtree_format(idn_samples_tree, tvb, offset, data_size, ett_dmx_subtree, NULL, "Range: %3d - %3d", base[i], base_value+data_size); |
587 | 11 | }else { |
588 | 11 | int base_size = MAX_CHANNELS - base_value; |
589 | 11 | data_size = tvb_reported_length_remaining(tvb, offset); |
590 | 11 | if(data_size > base_size) { |
591 | 5 | data_size = base_size; |
592 | 5 | } |
593 | 11 | if(data_size + base_value > MAX_CHANNELS) { |
594 | 0 | data_size = MAX_CHANNELS - base_value; |
595 | 0 | } |
596 | 11 | idn_dmx_subtree = proto_tree_add_subtree_format(idn_samples_tree, tvb, offset, data_size, ett_dmx_subtree, NULL, "Range: %3d - %3d", base[i], base_value+data_size); |
597 | 11 | } |
598 | 13 | offset = dissect_idn_dmx_sample_values(tvb, pinfo, offset, idn_dmx_subtree, data_size, base_value); |
599 | 13 | } |
600 | 26 | return offset; |
601 | 27 | } |
602 | | |
603 | 35 | static int dissect_idn_laser_data(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *idn_tree, configuration_info *config) { |
604 | 35 | int i; |
605 | 35 | int laser_data_size = tvb_reported_length_remaining(tvb, offset); |
606 | 35 | wmem_strbuf_t* values; |
607 | | |
608 | 35 | if (config->sample_size == 0) { |
609 | | /* TODO: log expert info error? */ |
610 | 1 | return 0; |
611 | 1 | } |
612 | | |
613 | 34 | int sample_size = laser_data_size/config->sample_size; |
614 | 34 | proto_tree *idn_samples_tree = proto_tree_add_subtree_format(idn_tree, tvb, offset, laser_data_size, ett_data, NULL, "Samples %s", wmem_strbuf_get_str(config->sample_column_string)); |
615 | 34 | proto_tree *idn_samples_subtree = NULL; |
616 | | |
617 | 1.24k | for(i=1; i<=sample_size; i++) { |
618 | 1.21k | if((i-1)%10 == 0 && i+10 > sample_size) { |
619 | 33 | idn_samples_subtree = proto_tree_add_subtree_format(idn_samples_tree, tvb, offset, tvb_reported_length_remaining(tvb, offset), ett_subdata, NULL, "Samples %3d - %3d", i, sample_size); |
620 | 1.18k | }else if((i-1)%10 == 0) { |
621 | 107 | idn_samples_subtree = proto_tree_add_subtree_format(idn_samples_tree, tvb, offset, config->sample_size*10, ett_subdata, NULL, "Samples %3d - %3d", i, i+9); |
622 | 107 | } |
623 | 1.21k | values = wmem_strbuf_new(pinfo->pool, ""); |
624 | 1.21k | set_laser_sample_values_string(tvb, offset, config, values); |
625 | 1.21k | proto_tree_add_bytes_format(idn_samples_subtree, hf_idn_gts_sample, tvb, offset, config->sample_size, NULL, "Sample %3d: %s", i, wmem_strbuf_get_str(values)); |
626 | 1.21k | offset += config->sample_size; |
627 | 1.21k | } |
628 | 34 | return offset; |
629 | 35 | } |
630 | | |
631 | 1 | static int dissect_idn_dimmer_levels_chunk_header(tvbuff_t *tvb, int offset, proto_tree* chunk_header_tree, proto_tree* flag_tree) { |
632 | | |
633 | 1 | proto_tree_add_item(flag_tree, hf_idn_four_bits_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
634 | 1 | offset += 1; |
635 | 1 | proto_tree_add_item(chunk_header_tree, hf_idn_reserved, tvb, offset, 3, ENC_NA); |
636 | 1 | offset += 3; |
637 | 1 | return offset; |
638 | 1 | } |
639 | | |
640 | 12 | static int dissect_idn_octet_string_chunk_header(tvbuff_t *tvb, int offset, proto_tree* chunk_header_tree, proto_tree* flag_tree) { |
641 | | |
642 | 12 | proto_tree_add_item(flag_tree, hf_idn_four_bits_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
643 | 12 | offset += 1; |
644 | 12 | proto_tree_add_item(chunk_header_tree, hf_idn_reserved, tvb, offset, 3, ENC_NA); |
645 | 12 | offset += 3; |
646 | 12 | return offset; |
647 | 12 | } |
648 | | |
649 | 3 | static int dissect_idn_octet_segment_chunk_header(tvbuff_t *tvb, int offset, proto_tree* chunk_header_tree, proto_tree* flag_tree) { |
650 | | |
651 | 3 | proto_tree_add_item(flag_tree, hf_idn_three_bits_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
652 | 3 | proto_tree_add_item(flag_tree, hf_idn_dlim, tvb, offset, 1, ENC_BIG_ENDIAN); |
653 | 3 | offset += 1; |
654 | 3 | proto_tree_add_item(chunk_header_tree, hf_idn_chunk_data_sequence, tvb, offset, 1, ENC_BIG_ENDIAN); |
655 | 3 | offset += 1; |
656 | 3 | proto_tree_add_item(chunk_header_tree, hf_idn_offset, tvb, offset, 2, ENC_BIG_ENDIAN); |
657 | 3 | offset += 2; |
658 | 3 | return offset; |
659 | 3 | } |
660 | | |
661 | 2 | static int dissect_idn_frame_chunk_header(tvbuff_t *tvb, int offset, proto_tree* chunk_header_tree, proto_tree* flag_tree) { |
662 | | |
663 | 2 | proto_tree_add_item(flag_tree, hf_idn_three_bits_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
664 | 2 | proto_tree_add_item(flag_tree, hf_idn_once, tvb, offset, 1, ENC_BIG_ENDIAN); |
665 | 2 | offset += 1; |
666 | 2 | proto_tree_add_item(chunk_header_tree, hf_idn_duration, tvb, offset, 3, ENC_BIG_ENDIAN); |
667 | 2 | offset += 3; |
668 | 2 | return offset; |
669 | 2 | } |
670 | | |
671 | 0 | static int dissect_idn_wave_chunk_header(tvbuff_t *tvb, int offset, proto_tree* chunk_header_tree, proto_tree* flag_tree) { |
672 | |
|
673 | 0 | proto_tree_add_item(flag_tree, hf_idn_four_bits_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); |
674 | 0 | offset += 1; |
675 | 0 | proto_tree_add_item(chunk_header_tree, hf_idn_duration, tvb, offset, 3, ENC_BIG_ENDIAN); |
676 | 0 | offset += 3; |
677 | 0 | return offset; |
678 | 0 | } |
679 | | |
680 | 75 | static int dissect_idn_chunk_header(tvbuff_t* tvb, packet_info* pinfo, int offset, proto_tree* idn_tree, message_info* minfo, configuration_info* config) { |
681 | | |
682 | 75 | proto_tree *chunk_header_tree, *flag_tree; |
683 | 75 | proto_item *flag_item, *scm_item; |
684 | 75 | uint32_t scm; |
685 | | |
686 | 75 | switch (minfo->chunk_type) { |
687 | 1 | case IDNCT_LP_WAVE_SAMPLE: |
688 | 2 | case IDNCT_LP_FRAME_CHUNK: |
689 | 3 | case IDNCT_LP_FRAME_FF: |
690 | 13 | case IDNCT_OCTET_SEGMENT: |
691 | 42 | case IDNCT_OCTET_STRING: |
692 | 43 | case IDNCT_DIMMER_LEVELS: |
693 | 43 | chunk_header_tree = proto_tree_add_subtree_format(idn_tree, tvb, offset, 4, ett_chunk_header_tree, NULL, "%s Chunk Header", val_to_str_const(minfo->chunk_type, chunk_type_header, "Unknown")); |
694 | 43 | flag_item = proto_tree_add_item(chunk_header_tree, hf_idn_chunk_header_flags, tvb, offset, 1, ENC_BIG_ENDIAN); |
695 | 43 | flag_tree = proto_item_add_subtree(flag_item, ett_chunk_header_flags); |
696 | 43 | proto_tree_add_item(flag_tree, hf_idn_two_bits_reserved_1, tvb, offset, 1, ENC_BIG_ENDIAN); |
697 | 43 | scm_item = proto_tree_add_item_ret_uint(flag_tree, hf_idn_scm, tvb, offset, 1, ENC_BIG_ENDIAN, &scm); |
698 | 43 | if (config->sdm != scm) { |
699 | 23 | expert_add_info(pinfo, scm_item, &ei_idn_scm_mismatch); |
700 | 23 | return offset; |
701 | 23 | } |
702 | | |
703 | 20 | switch (minfo->chunk_type) { |
704 | 0 | case IDNCT_LP_WAVE_SAMPLE: |
705 | 0 | offset = dissect_idn_wave_chunk_header(tvb, offset, chunk_header_tree, flag_tree); |
706 | 0 | break; |
707 | 1 | case IDNCT_LP_FRAME_CHUNK: |
708 | 2 | case IDNCT_LP_FRAME_FF: |
709 | 2 | offset = dissect_idn_frame_chunk_header(tvb, offset, chunk_header_tree, flag_tree); |
710 | 2 | break; |
711 | 3 | case IDNCT_OCTET_SEGMENT: |
712 | 3 | offset = dissect_idn_octet_segment_chunk_header(tvb, offset, chunk_header_tree, flag_tree); |
713 | 3 | break; |
714 | 12 | case IDNCT_OCTET_STRING: |
715 | 12 | offset = dissect_idn_octet_string_chunk_header(tvb, offset, chunk_header_tree, flag_tree); |
716 | 12 | break; |
717 | 1 | case IDNCT_DIMMER_LEVELS: |
718 | 1 | offset = dissect_idn_dimmer_levels_chunk_header(tvb, offset, chunk_header_tree, flag_tree); |
719 | 1 | break; |
720 | 20 | } |
721 | 16 | break; |
722 | 32 | default: |
723 | 32 | return offset; |
724 | 75 | } |
725 | 16 | return offset; |
726 | 75 | } |
727 | | |
728 | 2.46k | static int dissect_idn_dmx_gts(tvbuff_t *tvb, int offset, proto_tree *gts_tree, const int hf_hdr, int *dictionary_size) { |
729 | 2.46k | static int * const gts[] = { |
730 | 2.46k | &hf_idn_dmx_identifier, |
731 | 2.46k | &hf_idn_dmx_parameter, |
732 | 2.46k | NULL |
733 | 2.46k | }; |
734 | 2.46k | proto_tree_add_bitmask(gts_tree, tvb, offset, hf_hdr, ett_dic, gts, ENC_BIG_ENDIAN); |
735 | 2.46k | offset++; |
736 | 2.46k | if(dictionary_size) |
737 | 2.25k | (*dictionary_size)++; |
738 | | |
739 | 2.46k | return offset; |
740 | 2.46k | } |
741 | | |
742 | 557 | static int dissect_idn_dimmer_level_subset(tvbuff_t *tvb, int offset, proto_tree *gts_tree, configuration_info *config, int i, int *dictionary_size) { |
743 | 557 | uint8_t dls = tvb_get_uint8(tvb, offset); |
744 | 557 | offset = dissect_idn_dmx_gts(tvb, offset, gts_tree, hf_idn_dmx_dls, dictionary_size); |
745 | | |
746 | 557 | if(dls & 2) { |
747 | 113 | proto_tree_add_item(gts_tree, hf_idn_dmx_base, tvb, offset, 2, ENC_BIG_ENDIAN); |
748 | 113 | config->base[i-1] = tvb_get_uint16(tvb, offset, 2); |
749 | 113 | offset += 2; |
750 | 113 | (*dictionary_size) += 2; |
751 | 113 | if(dls & 1) { |
752 | 55 | proto_tree_add_item(gts_tree, hf_idn_dmx_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
753 | 55 | config->count[i-1] = tvb_get_uint8(tvb, offset); |
754 | 55 | offset++; |
755 | 55 | (*dictionary_size)++; |
756 | 58 | }else { |
757 | 58 | config->count[i-1] = -1; |
758 | 58 | } |
759 | 113 | } |
760 | | |
761 | 557 | return offset; |
762 | 557 | } |
763 | | |
764 | 54 | static int dissect_idn_dmx_dictionary(tvbuff_t *tvb, int offset, proto_tree *idn_tree, configuration_info *config) { |
765 | 54 | int i, j, curr_size; |
766 | 54 | bool words_found = 0; |
767 | 54 | int dictionary_size = 0; |
768 | 54 | uint8_t idepar; /* idetifier + parameter */ |
769 | 54 | proto_tree *gts_tree = proto_tree_add_subtree(idn_tree, tvb, offset, -1, ett_dic_tree, NULL, "Dictionary"); |
770 | | |
771 | 3.64k | for(i=1; i<=config->word_count; i++) { |
772 | 3.58k | idepar = tvb_get_uint8(tvb, offset); |
773 | | |
774 | 3.58k | if(idepar <= IDNO_VOID_AREA) { |
775 | 1.31k | if(idepar == 0) { |
776 | 1.10k | proto_tree_add_item(gts_tree, hf_idn_dmx_void, tvb, offset, 1, ENC_BIG_ENDIAN); |
777 | 1.10k | offset += 1; |
778 | 1.10k | dictionary_size += 1; |
779 | 1.10k | if(!words_found) |
780 | 1.10k | i -= 1; |
781 | 1.10k | }else { |
782 | 207 | offset = dissect_idn_dmx_gts(tvb, offset, gts_tree, hf_idn_dmx_unknown, NULL); |
783 | 1.43k | for(j=1; j<=idepar; j++) { |
784 | 1.22k | proto_tree_add_item(gts_tree, hf_idn_octet, tvb, offset, 1, ENC_BIG_ENDIAN); |
785 | 1.22k | offset += 1; |
786 | 1.22k | dictionary_size += 1; |
787 | 1.22k | if(words_found) |
788 | 15 | i += 1; |
789 | 1.22k | } |
790 | 207 | if(!words_found) |
791 | 196 | i -= 1; |
792 | 207 | } |
793 | 2.27k | }else if(idepar >= IDNTAG_DIMMER_START && idepar <= IDNTAG_DIMMER_END) { |
794 | 557 | offset = dissect_idn_dimmer_level_subset(tvb, offset, gts_tree, config, i, &dictionary_size); |
795 | 1.71k | }else { |
796 | 1.71k | offset = dissect_idn_dmx_gts(tvb, offset, gts_tree, hf_idn_dmx_unknown, &dictionary_size); |
797 | 1.71k | } |
798 | | |
799 | 3.58k | if(i == config->word_count && !words_found) { |
800 | 32 | curr_size = dictionary_size; |
801 | 78 | while(curr_size%4 != 0 && i > 0) { |
802 | 46 | i -= 1; |
803 | 46 | curr_size += 1; |
804 | 46 | } |
805 | 32 | words_found = 1; |
806 | 32 | } |
807 | 3.58k | } |
808 | 54 | proto_item_set_len(gts_tree, dictionary_size); |
809 | | |
810 | 54 | return offset; |
811 | 54 | } |
812 | | |
813 | 5.79k | static int dissect_idn_laser_gts(tvbuff_t *tvb, int offset, proto_tree *gts_tree, const int hf_hdr, int *dictionary_size, configuration_info *config, bool is_sample) { |
814 | 5.79k | static int * const gts[] = { |
815 | 5.79k | &hf_idn_gts_category, |
816 | 5.79k | &hf_idn_gts_subcategory, |
817 | 5.79k | &hf_idn_gts_identifier, |
818 | 5.79k | &hf_idn_gts_parameter, |
819 | 5.79k | NULL |
820 | 5.79k | }; |
821 | | |
822 | 5.79k | proto_tree_add_bitmask(gts_tree, tvb, offset, hf_hdr, ett_dic, gts, ENC_BIG_ENDIAN); |
823 | | |
824 | 5.79k | if(dictionary_size) |
825 | 5.78k | *dictionary_size += 2; |
826 | 5.79k | if(config && is_sample) |
827 | 4.08k | config->sample_size++; |
828 | | |
829 | 5.79k | return offset + 2; |
830 | 5.79k | } |
831 | | |
832 | 22 | static int dissect_idn_x_area(tvbuff_t *tvb, int offset, proto_tree *gts_tree, uint16_t catsub, int *dictionary_size, configuration_info *config) { |
833 | | |
834 | 22 | if(catsub == IDNTAG_OPTIONAL_U4) { |
835 | 11 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_u4, dictionary_size, config, 1); |
836 | 11 | }else { |
837 | 11 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_x, dictionary_size, config, 1); |
838 | 11 | } |
839 | | |
840 | 22 | return offset; |
841 | 22 | } |
842 | | |
843 | 118 | static int dissect_idn_laser_dictionary(tvbuff_t *tvb, int offset, proto_tree *idn_tree, configuration_info *config) { |
844 | 118 | int i, j; |
845 | 118 | int dictionary_size = 0; |
846 | 118 | uint16_t catsub; /* category + subcategory */ |
847 | 118 | proto_tree *gts_tree = proto_tree_add_subtree(idn_tree, tvb, offset, -1, ett_dic_tree, NULL, "Dictionary"); |
848 | | |
849 | | /* Reset the sample column data */ |
850 | 118 | config->sample_column_string = wmem_strbuf_new_len(wmem_file_scope(), "", 0); |
851 | 118 | wmem_strbuf_append(config->sample_column_string, "("); |
852 | 5.63k | for(i=1; i<=config->word_count*2; i++) { |
853 | 5.51k | catsub = tvb_get_uint16(tvb, offset, 2); |
854 | | |
855 | 5.51k | if(catsub <= IDNO_VOID_AREA) { |
856 | 1.23k | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_void, &dictionary_size, config, 0); |
857 | 1.23k | if(catsub > 0) { |
858 | 432 | for(j=0; j<catsub; j++) { |
859 | 351 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_void, &dictionary_size, config, 0); |
860 | 351 | } |
861 | 81 | } |
862 | 4.28k | }else if(catsub == IDNTAG_PRECISION) { |
863 | 7 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_precision, &dictionary_size, config, 1); |
864 | 7 | (config->dic_precision)[i] = 1; |
865 | 4.27k | }else if(catsub >= IDNTAG_BREAK_START && catsub <= IDNTAG_BREAK_END) { |
866 | 22 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_break, &dictionary_size, config, 0); |
867 | 4.25k | }else if(catsub >= IDNTAG_SPACE_MOD_START && catsub <= IDNTAG_SPACE_MOD_END) { |
868 | 105 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_space_modifier, &dictionary_size, config, 0); |
869 | 4.14k | }else if(catsub == IDNTAG_NOP) { |
870 | 15 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_nop, &dictionary_size, config, 1); |
871 | 15 | wmem_strbuf_append(config->sample_column_string, " NOP"); |
872 | 4.13k | }else if(catsub >= IDNTAG_HINT0 && catsub <= IDNTAG_HINT1) { |
873 | 6 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_hint, &dictionary_size, config, 1); |
874 | 6 | wmem_strbuf_append(config->sample_column_string, " H"); |
875 | 4.12k | }else if(catsub >= IDNTAG_COORD_X && catsub <= IDNTAG_COORD_X_END) { |
876 | 22 | offset = dissect_idn_x_area(tvb, offset, gts_tree, catsub, &dictionary_size, config); |
877 | 22 | wmem_strbuf_append(config->sample_column_string, (catsub == IDNTAG_OPTIONAL_U4) ? " U4" : " X"); |
878 | 4.10k | }else if(catsub >= IDNTAG_COORD_Y && catsub <= IDNTAG_COORD_Y_END) { |
879 | 9 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_y, &dictionary_size, config, 1); |
880 | 9 | wmem_strbuf_append(config->sample_column_string, " Y"); |
881 | 4.09k | }else if(catsub >= IDNTAG_COORD_Z && catsub <= IDNTAG_COORD_Z_END) { |
882 | 13 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_z, &dictionary_size, config, 1); |
883 | 13 | wmem_strbuf_append(config->sample_column_string, " Z"); |
884 | 4.08k | }else if(catsub >= IDNTAG_COLOR_START && catsub <= IDNTAG_COLOR_END) { |
885 | 115 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_color, &dictionary_size, config, 1); |
886 | 115 | wmem_strbuf_append_printf(config->sample_column_string, " %s", val_to_str_const(catsub, idn_cat_color, "C")); |
887 | 3.96k | }else if(catsub == IDNTAG_WAVELENGTH_PREFIX) { |
888 | 14 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_wavelength_prefix, &dictionary_size, config, 1); |
889 | 14 | wmem_strbuf_append(config->sample_column_string, " WP"); |
890 | 3.95k | }else if(catsub == IDNTAG_INTENSITY) { |
891 | 1 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_intensity, &dictionary_size, config, 1); |
892 | 1 | wmem_strbuf_append(config->sample_column_string, " I"); |
893 | 3.95k | }else if(catsub == IDNTAG_BEAM_BRUSH) { |
894 | 12 | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts_beam_brush, &dictionary_size, config, 1); |
895 | 12 | wmem_strbuf_append(config->sample_column_string, " BB"); |
896 | 3.94k | }else { |
897 | 3.94k | offset = dissect_idn_laser_gts(tvb, offset, gts_tree, hf_idn_gts, &dictionary_size, config, 1); |
898 | 3.94k | wmem_strbuf_append(config->sample_column_string, " U/R"); |
899 | 3.94k | } |
900 | 5.51k | } |
901 | 118 | proto_item_set_len(gts_tree, dictionary_size); |
902 | 118 | wmem_strbuf_append(config->sample_column_string, " )"); |
903 | | |
904 | 118 | return offset; |
905 | 118 | } |
906 | | |
907 | 225 | static int dissect_idn_channel_configuration_header(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *idn_tree, int channel_id, configuration_info **config_p) { |
908 | 225 | conversation_t *conv; |
909 | 225 | uint8_t word_count; |
910 | 225 | uint8_t sdm; |
911 | 225 | static int * const channel_and_service_configuration_flags[] = { |
912 | 225 | &hf_idn_two_bits_reserved_1, |
913 | 225 | &hf_idn_sdm, |
914 | 225 | &hf_idn_two_bits_reserved_2, |
915 | 225 | &hf_idn_close, |
916 | 225 | &hf_idn_routing, |
917 | 225 | NULL |
918 | 225 | }; |
919 | | |
920 | 225 | col_append_str(pinfo->cinfo, COL_INFO, " (Configuration Header)"); |
921 | 225 | proto_tree *configuration_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 4, ett_configuration_header, NULL, "Channel Configuration Header"); |
922 | 225 | proto_tree_add_item(configuration_header_tree, hf_idn_scwc, tvb, offset, 1, ENC_BIG_ENDIAN); |
923 | 225 | word_count = tvb_get_uint8(tvb, offset); |
924 | 225 | offset += 1; |
925 | 225 | proto_tree_add_bitmask(configuration_header_tree, tvb, offset, hf_idn_cfl, ett_cfl, channel_and_service_configuration_flags, ENC_BIG_ENDIAN); |
926 | 225 | sdm = get_service_match(tvb_get_uint8(tvb, offset)); |
927 | 225 | offset += 1; |
928 | 225 | proto_tree_add_item(configuration_header_tree, hf_idn_service_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
929 | 225 | offset += 1; |
930 | 225 | proto_tree_add_item(configuration_header_tree, hf_idn_service_mode, tvb, offset, 1, ENC_BIG_ENDIAN); |
931 | 225 | offset += 1; |
932 | | |
933 | | |
934 | 225 | conversation_element_t *conv_key = wmem_alloc_array(pinfo->pool, conversation_element_t, 6); |
935 | 225 | conv_key[0].type = CE_ADDRESS; |
936 | 225 | conv_key[0].addr_val = pinfo->src; |
937 | 225 | conv_key[1].type = CE_PORT; |
938 | 225 | conv_key[1].port_val = pinfo->srcport; |
939 | 225 | conv_key[2].type = CE_ADDRESS; |
940 | 225 | conv_key[2].addr_val = pinfo->dst; |
941 | 225 | conv_key[3].type = CE_PORT; |
942 | 225 | conv_key[3].port_val = pinfo->destport; |
943 | 225 | conv_key[4].type = CE_UINT; |
944 | 225 | conv_key[4].uint_val = channel_id; |
945 | 225 | conv_key[5].type = CE_CONVERSATION_TYPE; |
946 | 225 | conv_key[5].conversation_type_val = CONVERSATION_IDN; |
947 | | |
948 | 225 | configuration_info *config; |
949 | 225 | conv = find_conversation_full(pinfo->num, conv_key); |
950 | 225 | if (!(conv && conv->setup_frame == pinfo->num)) { |
951 | 222 | conv = conversation_new_full(pinfo->num, conv_key); |
952 | 222 | } |
953 | 225 | wmem_tree_t *config_tree = (wmem_tree_t*)conversation_get_proto_data(conv, proto_idn); |
954 | 225 | if (!config_tree) { |
955 | 222 | config_tree = wmem_tree_new(wmem_file_scope()); |
956 | 222 | conversation_add_proto_data(conv, proto_idn, config_tree); |
957 | 222 | } |
958 | | /* XXX: It wastes some memory to allocate a new configuration if it |
959 | | * hasn't changed since the last time it was sent, so we could use |
960 | | * lookup32_le and see if it's the same as the previous, but that |
961 | | * requires doing so after parsing the rest of the configuration. |
962 | | */ |
963 | 225 | config = (configuration_info *)wmem_tree_lookup32(config_tree, pinfo->num); |
964 | 225 | if (config) { |
965 | | /* sample size increments as we parse the dictionary, so reset. |
966 | | * The other values shouldn't change, though we'll waste time |
967 | | * overwriting the array with the same values. |
968 | | */ |
969 | 0 | config->sample_size = 0; |
970 | 225 | } else { |
971 | 225 | config = wmem_new0(wmem_file_scope(), configuration_info); |
972 | 225 | config->word_count = word_count; |
973 | 225 | config->sdm = sdm; |
974 | 225 | config->sample_size = 0; |
975 | 225 | config->dic_precision = wmem_alloc0_array(wmem_file_scope(), char, (255*2)+1); |
976 | 225 | config->sample_column_string = wmem_strbuf_new(wmem_file_scope(), ""); |
977 | 225 | config->count = wmem_alloc0_array(wmem_file_scope(), int, word_count+1); |
978 | 225 | config->base = wmem_alloc0_array(wmem_file_scope(), int, word_count+1); |
979 | 225 | wmem_tree_insert32(config_tree, pinfo->num, config); |
980 | 225 | } |
981 | | |
982 | 225 | *config_p = config; |
983 | | |
984 | 225 | return offset; |
985 | 225 | } |
986 | | |
987 | 225 | static int dissect_idn_channel_configuration(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *idn_tree, message_info *minfo, configuration_info **config_p) { |
988 | 225 | offset = dissect_idn_channel_configuration_header(tvb, pinfo, offset, idn_tree, minfo->channel_id, config_p); |
989 | | |
990 | 225 | configuration_info *config = *config_p; |
991 | 225 | if(config->word_count > 0) { |
992 | 219 | if(minfo->chunk_type == IDNCT_OCTET_SEGMENT || minfo->chunk_type == IDNCT_AUDIO_WAVE_SAMPLE) { |
993 | 47 | return offset; |
994 | 172 | }else if(minfo->is_dmx) { |
995 | 54 | offset = dissect_idn_dmx_dictionary(tvb, offset, idn_tree, config); |
996 | 118 | }else { |
997 | 118 | offset = dissect_idn_laser_dictionary(tvb, offset, idn_tree, config); |
998 | 118 | } |
999 | 219 | } |
1000 | | |
1001 | 178 | return offset; |
1002 | 225 | } |
1003 | | |
1004 | 231 | static int dissect_idn_message_header(tvbuff_t *tvb, int offset, proto_tree *idn_tree, message_info *minfo) { |
1005 | 231 | uint8_t cnl; |
1006 | 231 | static int * const cnl_data[] = { |
1007 | 231 | &hf_idn_most_significant_bit_cnl, |
1008 | 231 | &hf_idn_cclf, |
1009 | 231 | &hf_idn_channel_id, |
1010 | 231 | NULL |
1011 | 231 | }; |
1012 | | |
1013 | 231 | proto_tree *idn_channel_message_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 8, ett_idn_channel_message_header_tree, NULL, "Channel Message Header"); |
1014 | 231 | proto_tree_add_item(idn_channel_message_header_tree, hf_idn_total_size, tvb, offset, 2, ENC_BIG_ENDIAN); |
1015 | 231 | minfo->total_size = tvb_get_uint16(tvb, offset, 2); |
1016 | 231 | offset += 2; |
1017 | 231 | proto_tree_add_bitmask(idn_channel_message_header_tree, tvb, offset, hf_idn_cnl, ett_idn_cnl, cnl_data, ENC_BIG_ENDIAN); |
1018 | | |
1019 | 231 | cnl = tvb_get_uint8(tvb, offset); |
1020 | 231 | minfo->has_config_header = cnl & 0x40; |
1021 | 231 | minfo->channel_id = cnl & 0x3f; |
1022 | | |
1023 | 231 | offset += 1; |
1024 | 231 | proto_tree_add_item(idn_channel_message_header_tree, hf_idn_chunk_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
1025 | 231 | minfo->chunk_type = tvb_get_uint8(tvb, offset); |
1026 | 231 | offset += 1; |
1027 | 231 | proto_tree_add_item(idn_channel_message_header_tree, hf_idn_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN); |
1028 | 231 | offset += 4; |
1029 | | |
1030 | 231 | return offset; |
1031 | 231 | } |
1032 | | |
1033 | | // static int dissect_idn_audio_category_0(tvbuff_t *tvb _U_, packet_info *pinfo _U_, int offset _U_, proto_tree *idn_tree _U_){ |
1034 | | // static int * const audio_cat_0[] = { |
1035 | | // &hf_idn_category, |
1036 | | // &hf_idn_subcategory, |
1037 | | // &hf_idn_parameter, |
1038 | | // &hf_idn_suffix_length, |
1039 | | // NULL |
1040 | | // }; |
1041 | | // proto_tree_add_bitmask(idn_tree, tvb, offset, hf_idn_audio_dictionary_tag, ett_audio_header, audio_cat_0, ENC_BIG_ENDIAN); |
1042 | | // return offset; |
1043 | | // } |
1044 | | |
1045 | 0 | static int dissect_idn_audio_category_8(tvbuff_t *tvb, int offset, proto_tree *idn_tree, configuration_info *cinfo){ |
1046 | |
|
1047 | 0 | static int * const audio_cat_8[] = { |
1048 | 0 | &hf_idn_category, |
1049 | 0 | &hf_idn_format, |
1050 | 0 | &hf_idn_8bit_channels, |
1051 | 0 | NULL |
1052 | 0 | }; |
1053 | 0 | guint8 channels = tvb_get_int8(tvb, offset); |
1054 | 0 | cinfo->audio_format = channels & 0x0F; |
1055 | 0 | channels &= 0x00FF; |
1056 | 0 | cinfo->audio_channels = channels; |
1057 | |
|
1058 | 0 | proto_tree_add_bitmask(idn_tree, tvb, offset, hf_idn_audio_dictionary_tag, ett_audio_header, audio_cat_8, ENC_BIG_ENDIAN); |
1059 | |
|
1060 | 0 | return offset; |
1061 | 0 | } |
1062 | | |
1063 | 454 | static int dissect_idn_audio_category_6(tvbuff_t *tvb, int offset, proto_tree *idn_tree, configuration_info *cinfo){ |
1064 | | //proto_tree_add_item(idn_tree, hf_idn_category, tvb, offset, 1, ENC_BIG_ENDIAN); |
1065 | | //offset += 1; |
1066 | 454 | static int * const audio_cat_6[] = { |
1067 | 454 | &hf_idn_category, |
1068 | 454 | &hf_idn_format, |
1069 | 454 | &hf_idn_layout, |
1070 | 454 | &hf_idn_4bit_channels, |
1071 | 454 | NULL |
1072 | 454 | }; |
1073 | 454 | guint8 channels = tvb_get_int8(tvb, offset); |
1074 | 454 | guint8 audio_format = channels; |
1075 | 454 | audio_format = audio_format & 0x0F; |
1076 | 454 | cinfo->audio_format = audio_format; |
1077 | 454 | channels &= 0x0F; |
1078 | 454 | cinfo->audio_channels = channels; |
1079 | | |
1080 | 454 | proto_tree_add_bitmask(idn_tree, tvb, offset, hf_idn_audio_dictionary_tag, ett_audio_header, audio_cat_6, ENC_BIG_ENDIAN); |
1081 | 454 | return offset; |
1082 | 454 | } |
1083 | | |
1084 | 39 | static int dissect_idn_audio_dictionary(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *idn_tree, configuration_info *config){ |
1085 | 39 | gint8 det_category; |
1086 | 39 | gint16 current_tag; |
1087 | 39 | int tag_count = config->word_count; |
1088 | 39 | tag_count *= 2; |
1089 | 39 | proto_item *dictionary_tree = proto_tree_add_subtree(idn_tree, tvb, offset, tag_count, ett_dic_tree, NULL, "Dictionary"); |
1090 | | |
1091 | 2.02k | for(int i = 0; i < tag_count; i++){ |
1092 | 1.99k | current_tag = tvb_get_uint16(tvb, offset, 2); |
1093 | 1.99k | switch (current_tag) { |
1094 | 319 | case 0x0000: |
1095 | | //add void tag |
1096 | 319 | proto_tree_add_item(dictionary_tree, hf_idn_gts_void, tvb, offset, 2, ENC_BIG_ENDIAN); |
1097 | 319 | offset += 2; |
1098 | 319 | break; |
1099 | 1.66k | default: |
1100 | | //determing category |
1101 | 1.66k | det_category = tvb_get_int8(tvb, offset); |
1102 | 1.66k | det_category = det_category >> 4; |
1103 | | //dissect depending on category |
1104 | 1.66k | switch (det_category) { |
1105 | 454 | case 0x6: |
1106 | 454 | dissect_idn_audio_category_6(tvb, offset, dictionary_tree, config); |
1107 | 454 | break; |
1108 | 0 | case 0x8: |
1109 | 0 | dissect_idn_audio_category_8(tvb, offset, dictionary_tree, config); |
1110 | 0 | break; |
1111 | 1.66k | } |
1112 | 1.66k | offset += 2; |
1113 | 1.66k | break; |
1114 | 1.99k | } |
1115 | 1.99k | } |
1116 | 23 | return offset; |
1117 | 39 | } |
1118 | | |
1119 | 23 | static int dissect_idn_audio_header(tvbuff_t *tvb, int offset, proto_tree *idn_tree){ |
1120 | | |
1121 | 23 | static int * const audio_flags[] = { |
1122 | 23 | &hf_idn_audio_flags_two_bits_reserved, |
1123 | 23 | &hf_idn_audio_flags_scm, |
1124 | 23 | &hf_idn_audio_flags_four_bits_reserved, |
1125 | 23 | NULL |
1126 | 23 | }; |
1127 | | |
1128 | 23 | proto_item *audio_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 4, ett_audio_header, NULL, "Audio Header"); |
1129 | | |
1130 | 23 | proto_tree_add_bitmask(audio_header_tree, tvb, offset, hf_idn_audio_flags, ett_audio_header, audio_flags, ENC_BIG_ENDIAN); |
1131 | 23 | offset +=1; |
1132 | | |
1133 | 23 | proto_tree_add_item(audio_header_tree, hf_idn_audio_duration, tvb, offset, 3, ENC_BIG_ENDIAN); |
1134 | 23 | offset+= 3; |
1135 | | |
1136 | 23 | return offset; |
1137 | 23 | } |
1138 | | |
1139 | 7 | static int dissect_idn_audio_samples_format_0(tvbuff_t *tvb, int offset, proto_tree *idn_tree){ |
1140 | 7 | int max_samples = tvb_reported_length_remaining(tvb, offset); |
1141 | 279 | for(int i = 0; i < max_samples; i++){ |
1142 | 272 | proto_tree_add_item(idn_tree, hf_idn_audio_sample_format_zero, tvb, offset, 1, ENC_BIG_ENDIAN); |
1143 | 272 | offset++; |
1144 | 272 | } |
1145 | 7 | return offset; |
1146 | 7 | } |
1147 | | |
1148 | 8 | static int dissect_idn_audio_samples_format_1(tvbuff_t *tvb, int offset, proto_tree *idn_tree){ |
1149 | 8 | int max_samples = tvb_reported_length_remaining(tvb, offset); |
1150 | 8 | max_samples /= 2; |
1151 | 339 | for(int i = 0; i < max_samples; i++){ |
1152 | 331 | proto_tree_add_item(idn_tree, hf_idn_audio_sample_format_one, tvb, offset, 2, ENC_BIG_ENDIAN); |
1153 | 331 | offset += 2; |
1154 | 331 | } |
1155 | 8 | return offset; |
1156 | 8 | } |
1157 | | |
1158 | 7 | static int dissect_idn_audio_samples_format_2(tvbuff_t *tvb, int offset, proto_tree *idn_tree){ |
1159 | 7 | int max_samples = tvb_reported_length_remaining(tvb, offset); |
1160 | 7 | max_samples /= 3; |
1161 | 305 | for(int i = 0; i < max_samples; i++){ |
1162 | 298 | proto_tree_add_item( idn_tree, hf_idn_audio_sample_format_two, tvb, offset, 3, ENC_BIG_ENDIAN); |
1163 | 298 | offset += 3; |
1164 | 298 | } |
1165 | 7 | return offset; |
1166 | 7 | } |
1167 | | |
1168 | 23 | static int dissect_idn_audio_samples(tvbuff_t *tvb, int offset, proto_tree *idn_tree, configuration_info * config){ |
1169 | 23 | proto_item *audio_samples_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 4, ett_audio_samples, NULL, "Audio Samples"); |
1170 | 23 | switch (config->audio_format) { |
1171 | 7 | case 0x00: |
1172 | 7 | dissect_idn_audio_samples_format_0(tvb, offset, audio_samples_tree); |
1173 | 7 | break; |
1174 | 8 | case 0x01: |
1175 | 8 | dissect_idn_audio_samples_format_1(tvb, offset, audio_samples_tree); |
1176 | 8 | break; |
1177 | 7 | case 0x02: |
1178 | 7 | dissect_idn_audio_samples_format_2(tvb, offset, audio_samples_tree); |
1179 | 7 | break; |
1180 | 23 | } |
1181 | 23 | return offset; |
1182 | 23 | } |
1183 | | |
1184 | 39 | static int dissect_idn_audio(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *idn_tree, configuration_info * config){ |
1185 | | |
1186 | 39 | offset = dissect_idn_audio_dictionary(tvb, pinfo, offset, idn_tree, config); |
1187 | 39 | offset = dissect_idn_audio_header(tvb, offset, idn_tree); |
1188 | 39 | offset = dissect_idn_audio_samples(tvb, offset, idn_tree, config); |
1189 | 39 | return offset; |
1190 | 39 | } |
1191 | | |
1192 | 231 | static int dissect_idn_message(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *idn_tree) { |
1193 | | |
1194 | 231 | configuration_info *config = NULL; |
1195 | 231 | message_info minfo; |
1196 | | |
1197 | 231 | offset = dissect_idn_message_header(tvb, offset, idn_tree, &minfo); |
1198 | 231 | determine_message_type(pinfo, &minfo); |
1199 | 231 | if(minfo.total_size == 8) |
1200 | 0 | return offset; |
1201 | | |
1202 | 231 | if(minfo.has_config_header && minfo.chunk_type != IDNCT_LP_FRAME_SF) { |
1203 | 225 | offset = dissect_idn_channel_configuration(tvb, pinfo, offset, idn_tree, &minfo, &config); |
1204 | 225 | }else if(minfo.chunk_type != IDNCT_VOID) { |
1205 | 4 | config = get_configuration_info(pinfo, minfo.channel_id); |
1206 | 4 | } |
1207 | | |
1208 | 231 | if (config == NULL) { |
1209 | 3 | expert_add_info(pinfo, idn_tree, &ei_idn_no_config); |
1210 | 3 | return offset; |
1211 | 3 | } |
1212 | | |
1213 | 228 | if (config->word_count == 0 && minfo.chunk_type != IDNCT_OCTET_SEGMENT) { |
1214 | 1 | expert_add_info(pinfo, idn_tree, &ei_idn_scwc_unknown); |
1215 | 1 | return offset; |
1216 | 1 | } |
1217 | | |
1218 | 227 | if(minfo.chunk_type != IDNCT_VOID && minfo.chunk_type != IDNCT_LP_FRAME_SF && minfo.chunk_type != IDNCT_AUDIO_WAVE_SAMPLE) { |
1219 | 75 | offset = dissect_idn_chunk_header(tvb, pinfo, offset, idn_tree, &minfo, config); |
1220 | 152 | }else if(minfo.chunk_type == IDNCT_VOID) { |
1221 | 3 | return offset; |
1222 | 3 | } |
1223 | | |
1224 | 224 | if(minfo.chunk_type == IDNCT_OCTET_SEGMENT) { |
1225 | 10 | offset = dissect_idn_octet_segment(tvb, pinfo, offset, idn_tree); |
1226 | 214 | }else if(minfo.is_dmx) { |
1227 | 27 | offset = dissect_idn_dmx_data(tvb, pinfo, offset, idn_tree, config); |
1228 | 187 | }else if(minfo.is_audio){ |
1229 | 39 | offset = dissect_idn_audio(tvb, pinfo, offset, idn_tree, config); |
1230 | 148 | }else { |
1231 | 148 | offset = dissect_idn_laser_data(tvb, pinfo, offset, idn_tree, config); |
1232 | 148 | } |
1233 | | |
1234 | 224 | return offset; |
1235 | 227 | } |
1236 | | |
1237 | 83 | static int dissect_idn_servicemap_entry(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *idn_tree) { |
1238 | 83 | uint8_t service_id = tvb_get_uint8(tvb, offset); |
1239 | 83 | proto_tree *idn_servicemap_entry_tree = NULL; |
1240 | 83 | proto_item *entry_item; |
1241 | 83 | const uint8_t* name; |
1242 | | |
1243 | 83 | if(service_id == 0) { |
1244 | 38 | idn_servicemap_entry_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 24, ett_idn_header_tree, &entry_item, "Relay Entry"); |
1245 | 45 | }else { |
1246 | 45 | idn_servicemap_entry_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 24, ett_idn_header_tree, &entry_item, "Service Entry"); |
1247 | 45 | } |
1248 | | |
1249 | 83 | proto_tree_add_item(idn_servicemap_entry_tree, hf_idn_service_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
1250 | 83 | offset += 1; |
1251 | 83 | proto_tree_add_item(idn_servicemap_entry_tree, hf_idn_service_mode, tvb, offset, 1, ENC_BIG_ENDIAN); |
1252 | 83 | offset += 1; |
1253 | 83 | proto_tree_add_item(idn_servicemap_entry_tree, hf_idn_flags, tvb, offset, 1, ENC_BIG_ENDIAN); |
1254 | 83 | offset += 1; |
1255 | 83 | proto_tree_add_item(idn_servicemap_entry_tree, hf_idn_relay_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
1256 | 83 | offset += 1; |
1257 | 83 | proto_tree_add_item_ret_string(idn_servicemap_entry_tree, hf_idn_name, tvb, offset, 20, ENC_ASCII, pinfo->pool, &name); |
1258 | 83 | proto_item_append_text(entry_item, " - %s", name); |
1259 | 83 | offset += 20; |
1260 | 83 | return offset; |
1261 | 83 | } |
1262 | | |
1263 | 10 | static int dissect_idn_servicemap_response_header(tvbuff_t *tvb, int offset, proto_tree *idn_tree, uint8_t *relay_count, uint8_t *service_count) { |
1264 | 10 | proto_tree *idn_servicemap_response_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 4, ett_idn_header_tree, NULL, "Service Map Response Header"); |
1265 | 10 | proto_tree_add_item(idn_servicemap_response_header_tree, hf_idn_struct_size, tvb, offset, 1, ENC_BIG_ENDIAN); |
1266 | 10 | offset += 1; |
1267 | 10 | proto_tree_add_item(idn_servicemap_response_header_tree, hf_idn_entry_size, tvb, offset, 1, ENC_BIG_ENDIAN); |
1268 | 10 | offset += 1; |
1269 | 10 | *relay_count = tvb_get_uint8(tvb, offset); |
1270 | 10 | proto_tree_add_item(idn_servicemap_response_header_tree, hf_idn_relay_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
1271 | 10 | offset += 1; |
1272 | 10 | *service_count = tvb_get_uint8(tvb, offset); |
1273 | 10 | proto_tree_add_item(idn_servicemap_response_header_tree, hf_idn_service_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
1274 | 10 | offset += 1; |
1275 | 10 | return offset; |
1276 | 10 | } |
1277 | | |
1278 | 10 | static int dissect_idn_servicemap_response(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *idn_tree) { |
1279 | 10 | uint8_t relay_count, service_count; |
1280 | 10 | uint16_t map_entries_size; |
1281 | | |
1282 | 10 | offset = dissect_idn_servicemap_response_header(tvb, offset, idn_tree, &relay_count, &service_count); |
1283 | 10 | map_entries_size = relay_count + service_count; |
1284 | 10 | proto_tree *idn_servicemap_entries_tree = proto_tree_add_subtree(idn_tree, tvb, offset, map_entries_size*24, ett_idn_header_tree, NULL, "Service Map Entries"); |
1285 | 93 | for(int i=0; i<map_entries_size; i++) |
1286 | 83 | offset = dissect_idn_servicemap_entry(tvb, pinfo, offset, idn_servicemap_entries_tree); |
1287 | | |
1288 | 10 | return offset; |
1289 | 10 | } |
1290 | | |
1291 | 1 | static int dissect_idn_scan_response(tvbuff_t *tvb, int offset, proto_tree *idn_tree) { |
1292 | 1 | static int * const protocol_version[] = { |
1293 | 1 | &hf_idn_protocol_version_major, |
1294 | 1 | &hf_idn_protocol_version_minor, |
1295 | 1 | NULL |
1296 | 1 | }; |
1297 | 1 | static int * const status[] = { |
1298 | 1 | &hf_idn_malfn, |
1299 | 1 | &hf_idn_offline, |
1300 | 1 | &hf_idn_xcld, |
1301 | 1 | &hf_idn_ocpd, |
1302 | 1 | &hf_idn_three_bits_reserved, |
1303 | 1 | &hf_idn_rt, |
1304 | 1 | NULL |
1305 | 1 | }; |
1306 | | |
1307 | | |
1308 | 1 | proto_tree *idn_scanreply_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, 40, ett_idn_header_tree, NULL, "Scan Response"); |
1309 | 1 | proto_tree_add_item(idn_scanreply_header_tree, hf_idn_struct_size, tvb, offset, 1, ENC_BIG_ENDIAN); |
1310 | 1 | offset += 1; |
1311 | 1 | proto_tree_add_bitmask(idn_scanreply_header_tree, tvb, offset, hf_idn_protocol_version, ett_protocol_version, protocol_version, ENC_BIG_ENDIAN); |
1312 | 1 | offset += 1; |
1313 | 1 | proto_tree_add_bitmask(idn_scanreply_header_tree, tvb, offset, hf_idn_status, ett_status, status, ENC_BIG_ENDIAN); |
1314 | 1 | offset += 1; |
1315 | 1 | proto_tree_add_item(idn_scanreply_header_tree, hf_idn_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
1316 | 1 | offset += 1; |
1317 | 1 | proto_tree *uid_tree = proto_tree_add_subtree(idn_scanreply_header_tree, tvb, offset, 16, ett_unit_id, NULL, "Unit ID"); |
1318 | 1 | proto_tree_add_item(uid_tree, hf_idn_uid_length, tvb, offset, 1, ENC_BIG_ENDIAN); |
1319 | 1 | offset += 1; |
1320 | 1 | proto_tree_add_item(uid_tree, hf_idn_uid_category, tvb, offset, 1, ENC_BIG_ENDIAN); |
1321 | 1 | offset += 1; |
1322 | 1 | proto_tree_add_item(uid_tree, hf_idn_unit_id, tvb, offset, 14, ENC_NA); |
1323 | 1 | offset += 14; |
1324 | | |
1325 | 1 | proto_tree_add_item(idn_scanreply_header_tree, hf_idn_name, tvb, offset, 20, ENC_ASCII); |
1326 | 1 | offset += 20; |
1327 | 1 | return offset; |
1328 | 1 | } |
1329 | | |
1330 | 250 | static int dissect_idn_header(tvbuff_t *tvb, int offset, proto_tree *idn_tree, uint8_t packet_type) { |
1331 | 250 | int header_len = (packet_type == IDNCMD_VOID || packet_type == IDNCMD_PING_RESPONSE) ? 1 : 4; |
1332 | 250 | proto_tree *idn_header_tree = proto_tree_add_subtree(idn_tree, tvb, offset, header_len, ett_idn_header_tree, NULL, "IDN Header"); |
1333 | 250 | proto_tree_add_item(idn_header_tree, hf_idn_command, tvb, offset, 1, ENC_BIG_ENDIAN); |
1334 | 250 | offset += 1; |
1335 | 250 | if (packet_type == IDNCMD_VOID || packet_type == IDNCMD_PING_RESPONSE) { |
1336 | 2 | return offset; |
1337 | 2 | } |
1338 | 248 | proto_tree_add_item(idn_header_tree, hf_idn_flags, tvb, offset, 1, ENC_BIG_ENDIAN); |
1339 | 248 | offset += 1; |
1340 | 248 | proto_tree_add_item(idn_header_tree, hf_idn_sequence, tvb, offset, 2, ENC_BIG_ENDIAN); |
1341 | 248 | offset += 2; |
1342 | 248 | return offset; |
1343 | 250 | } |
1344 | | |
1345 | 250 | static int dissect_idn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { |
1346 | 250 | int offset = 0; |
1347 | 250 | proto_item *ti = proto_tree_add_item(tree, proto_idn, tvb, 0, -1, ENC_NA); |
1348 | 250 | proto_tree *idn_tree = proto_item_add_subtree(ti, ett_idn); |
1349 | 250 | uint8_t packet_type = tvb_get_uint8(tvb, 0); |
1350 | | |
1351 | 250 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDN"); |
1352 | 250 | col_clear(pinfo->cinfo, COL_INFO); |
1353 | 250 | col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, command_code, "Unknown (0x%02x)")); |
1354 | | |
1355 | 250 | offset = dissect_idn_header(tvb, offset, idn_tree, packet_type); |
1356 | | |
1357 | 250 | switch (packet_type) { |
1358 | 1 | case IDNCMD_SCAN_RESPONSE: |
1359 | 1 | dissect_idn_scan_response(tvb, offset, idn_tree); |
1360 | 1 | break; |
1361 | 10 | case IDNCMD_SERVICEMAP_RESPONSE: |
1362 | 10 | offset = dissect_idn_servicemap_response(tvb, pinfo, offset, idn_tree); |
1363 | 10 | break; |
1364 | 22 | case IDNCMD_MESSAGE: |
1365 | 76 | case IDNCMD_MESSAGE_ACKREQ: |
1366 | 186 | case IDNCMD_MESSAGE_CLOSE: |
1367 | 231 | case IDNCMD_MESSAGE_ACKREQ_CLOSE: |
1368 | 231 | offset = dissect_idn_message(tvb, pinfo, offset, idn_tree); |
1369 | 231 | break; |
1370 | 1 | case IDNCMD_MESSAGE_ACK: |
1371 | 1 | offset = dissect_idn_message_acknowledgement(tvb, offset, idn_tree); |
1372 | 1 | break; |
1373 | 3 | default: |
1374 | 3 | break; |
1375 | 250 | } |
1376 | | |
1377 | 101 | return offset; |
1378 | 250 | } |
1379 | | |
1380 | 14 | void proto_register_idn(void) { |
1381 | 14 | static hf_register_info hf[] = { |
1382 | 14 | { &hf_idn_command, |
1383 | 14 | { "Command code", "idn.command", |
1384 | 14 | FT_UINT8, BASE_HEX, |
1385 | 14 | VALS(command_code), 0x0, |
1386 | 14 | NULL, HFILL } |
1387 | 14 | }, |
1388 | 14 | { &hf_idn_flags, |
1389 | 14 | { "Flags", "idn.flags", |
1390 | 14 | FT_UINT8, BASE_HEX, |
1391 | 14 | NULL, 0x0, |
1392 | 14 | NULL, HFILL } |
1393 | 14 | }, |
1394 | 14 | { &hf_idn_sequence, |
1395 | 14 | { "Sequence counter", "idn.sequence", |
1396 | 14 | FT_UINT16, BASE_DEC, |
1397 | 14 | NULL, 0x0, |
1398 | 14 | NULL, HFILL } |
1399 | 14 | }, |
1400 | 14 | { &hf_idn_total_size, |
1401 | 14 | { "Total Size", "idn.total_size", |
1402 | 14 | FT_UINT16, BASE_DEC, |
1403 | 14 | NULL, 0x0, |
1404 | 14 | NULL, HFILL } |
1405 | 14 | }, |
1406 | 14 | { &hf_idn_struct_size, |
1407 | 14 | { "Struct Size", "idn.struct_size", |
1408 | 14 | FT_UINT8, BASE_DEC, |
1409 | 14 | NULL, 0x0, |
1410 | 14 | NULL, HFILL } |
1411 | 14 | }, |
1412 | 14 | { &hf_idn_protocol_version, |
1413 | 14 | { "Protocol Version", "idn.protocol_version", |
1414 | 14 | FT_UINT8, BASE_DEC, |
1415 | 14 | NULL, 0x0, |
1416 | 14 | NULL, HFILL } |
1417 | 14 | }, |
1418 | 14 | { &hf_idn_protocol_version_major, |
1419 | 14 | { "Major", "idn.protocol_version_major", |
1420 | 14 | FT_UINT8, BASE_DEC, |
1421 | 14 | NULL, 0xF0, |
1422 | 14 | NULL, HFILL } |
1423 | 14 | }, |
1424 | 14 | { &hf_idn_protocol_version_minor, |
1425 | 14 | { "Minor", "idn.protocol_version_minor", |
1426 | 14 | FT_UINT8, BASE_DEC, |
1427 | 14 | NULL, 0x0F, |
1428 | 14 | NULL, HFILL } |
1429 | 14 | }, |
1430 | 14 | { &hf_idn_status, |
1431 | 14 | { "Status", "idn.status", |
1432 | 14 | FT_UINT8, BASE_HEX, |
1433 | 14 | NULL, 0x0, |
1434 | 14 | NULL, HFILL } |
1435 | 14 | }, |
1436 | 14 | { &hf_idn_malfn, |
1437 | 14 | { "Malfunction", "idn.status_malfn", |
1438 | 14 | FT_UINT8, BASE_DEC, |
1439 | 14 | NULL, 0x80, |
1440 | 14 | NULL, HFILL } |
1441 | 14 | }, |
1442 | 14 | { &hf_idn_offline, |
1443 | 14 | { "Offline", "idn.offline", |
1444 | 14 | FT_UINT8, BASE_DEC, |
1445 | 14 | NULL, 0x40, |
1446 | 14 | NULL, HFILL } |
1447 | 14 | }, |
1448 | 14 | { &hf_idn_xcld, |
1449 | 14 | { "Excluded", "idn.xcld", |
1450 | 14 | FT_UINT8, BASE_DEC, |
1451 | 14 | NULL, 0x20, |
1452 | 14 | NULL, HFILL } |
1453 | 14 | }, |
1454 | 14 | { &hf_idn_ocpd, |
1455 | 14 | { "Occupied", "idn.ocpd", |
1456 | 14 | FT_UINT8, BASE_DEC, |
1457 | 14 | NULL, 0x10, |
1458 | 14 | NULL, HFILL } |
1459 | 14 | }, |
1460 | 14 | { &hf_idn_rt, |
1461 | 14 | { "Realtime", "idn.rt", |
1462 | 14 | FT_UINT8, BASE_DEC, |
1463 | 14 | NULL, 0x1, |
1464 | 14 | NULL, HFILL } |
1465 | 14 | }, |
1466 | 14 | { &hf_idn_reserved8, |
1467 | 14 | { "Reserved", "idn.reserved8", |
1468 | 14 | FT_UINT8, BASE_HEX, |
1469 | 14 | NULL, 0x0, |
1470 | 14 | NULL, HFILL } |
1471 | 14 | }, |
1472 | 14 | { &hf_idn_unit_id, |
1473 | 14 | { "Unit ID", "idn.unit_id", |
1474 | 14 | FT_BYTES, SEP_SPACE, |
1475 | 14 | NULL, 0x0, |
1476 | 14 | NULL, HFILL } |
1477 | 14 | }, |
1478 | 14 | { &hf_idn_uid_length, |
1479 | 14 | { "Length", "idn.unit_id_length", |
1480 | 14 | FT_UINT8, BASE_HEX, |
1481 | 14 | NULL, 0x0, |
1482 | 14 | NULL, HFILL } |
1483 | 14 | }, |
1484 | 14 | { &hf_idn_uid_category, |
1485 | 14 | { "Caregory", "idn.unit_id_category", |
1486 | 14 | FT_UINT8, BASE_HEX, |
1487 | 14 | NULL, 0x0, |
1488 | 14 | NULL, HFILL } |
1489 | 14 | }, |
1490 | 14 | { &hf_idn_uid, |
1491 | 14 | { "Unit ID", "idn.unit_id_number", |
1492 | 14 | FT_BYTES, SEP_SPACE, |
1493 | 14 | NULL, 0x0, |
1494 | 14 | NULL, HFILL } |
1495 | 14 | }, |
1496 | 14 | { &hf_idn_name, |
1497 | 14 | { "Name", "idn.name", |
1498 | 14 | FT_STRING, BASE_NONE, |
1499 | 14 | NULL, 0x0, |
1500 | 14 | NULL, HFILL } |
1501 | 14 | }, |
1502 | 14 | { &hf_idn_entry_size, |
1503 | 14 | { "Entry Size", "idn.entry_size", |
1504 | 14 | FT_UINT8, BASE_DEC, |
1505 | 14 | NULL, 0x0, |
1506 | 14 | NULL, HFILL } |
1507 | 14 | }, |
1508 | 14 | { &hf_idn_relay_count, |
1509 | 14 | { "Relay Count", "idn.relay_count", |
1510 | 14 | FT_UINT8, BASE_DEC, |
1511 | 14 | NULL, 0x0, |
1512 | 14 | NULL, HFILL } |
1513 | 14 | }, |
1514 | 14 | { &hf_idn_service_count, |
1515 | 14 | { "Service Count", "idn.service_count", |
1516 | 14 | FT_UINT8, BASE_DEC, |
1517 | 14 | NULL, 0x0, |
1518 | 14 | NULL, HFILL } |
1519 | 14 | }, |
1520 | 14 | { &hf_idn_cnl, |
1521 | 14 | { "Channel configuration and routing information (CNL)", "idn.cnl", |
1522 | 14 | FT_UINT8, BASE_HEX, |
1523 | 14 | NULL, 0x0, |
1524 | 14 | NULL, HFILL } |
1525 | 14 | }, |
1526 | 14 | { &hf_idn_most_significant_bit_cnl, |
1527 | 14 | { "Most significant bit (always 1)", "idn.most_significant_bit_cnl", |
1528 | 14 | FT_UINT8, BASE_DEC, |
1529 | 14 | NULL, 0x80, |
1530 | 14 | NULL, HFILL } |
1531 | 14 | }, |
1532 | 14 | { &hf_idn_cclf, |
1533 | 14 | { "Channel Configuration and Last Fragment bit (CCLF)", "idn.cclf", |
1534 | 14 | FT_UINT8, BASE_DEC, |
1535 | 14 | NULL, 0x40, |
1536 | 14 | NULL, HFILL } |
1537 | 14 | }, |
1538 | 14 | { &hf_idn_channel_id, |
1539 | 14 | { "Channel ID (opened Channels)", "idn.channel_id", |
1540 | 14 | FT_UINT8, BASE_DEC, |
1541 | 14 | NULL, 0x3F, |
1542 | 14 | NULL, HFILL } |
1543 | 14 | }, |
1544 | 14 | { &hf_idn_chunk_type, |
1545 | 14 | { "Chunk Type", "idn.chunk_type", |
1546 | 14 | FT_UINT8, BASE_HEX, |
1547 | 14 | VALS(chunk_type), 0x0, |
1548 | 14 | NULL, HFILL } |
1549 | 14 | }, |
1550 | 14 | { &hf_idn_timestamp, |
1551 | 14 | { "Timestamp", "idn.timestamp", |
1552 | 14 | FT_UINT32, BASE_DEC, |
1553 | 14 | NULL, 0x0, |
1554 | 14 | NULL, HFILL } |
1555 | 14 | }, |
1556 | 14 | { &hf_idn_scwc, |
1557 | 14 | { "Service Configuration Word Count (SCWC)", "idn.scwc", |
1558 | 14 | FT_UINT8, BASE_DEC, |
1559 | 14 | NULL, 0x0, |
1560 | 14 | NULL, HFILL } |
1561 | 14 | }, |
1562 | 14 | { &hf_idn_cfl, |
1563 | 14 | { "Channel and service configuration Flags (CFL)", "idn.cfl", |
1564 | 14 | FT_UINT8, BASE_HEX, |
1565 | 14 | VALS(cfl_string), 0x0, |
1566 | 14 | NULL, HFILL } |
1567 | 14 | }, |
1568 | 14 | { &hf_idn_sdm, |
1569 | 14 | { "Service Data Match (SDM)", "idn.sdm", |
1570 | 14 | FT_UINT8, BASE_DEC, |
1571 | 14 | NULL, 0x30, |
1572 | 14 | NULL, HFILL } |
1573 | 14 | }, |
1574 | 14 | { &hf_idn_close, |
1575 | 14 | { "Close", "idn.close", |
1576 | 14 | FT_UINT8, BASE_DEC, |
1577 | 14 | NULL, 0x2, |
1578 | 14 | NULL, HFILL } |
1579 | 14 | }, |
1580 | 14 | { &hf_idn_routing, |
1581 | 14 | { "Routing", "idn.routing", |
1582 | 14 | FT_UINT8, BASE_DEC, |
1583 | 14 | NULL, 0x1, |
1584 | 14 | NULL, HFILL } |
1585 | 14 | }, |
1586 | 14 | { &hf_idn_service_id, |
1587 | 14 | { "Service ID", "idn.service_id", |
1588 | 14 | FT_UINT8, BASE_HEX, |
1589 | 14 | NULL, 0x0, |
1590 | 14 | NULL, HFILL } |
1591 | 14 | }, |
1592 | 14 | { &hf_idn_relay_number, |
1593 | 14 | { "Relay Number", "idn.relay_number", |
1594 | 14 | FT_UINT8, BASE_HEX, |
1595 | 14 | NULL, 0x0, |
1596 | 14 | NULL, HFILL } |
1597 | 14 | }, |
1598 | 14 | { &hf_idn_service_mode, |
1599 | 14 | { "Service Mode", "idn.service_mode", |
1600 | 14 | FT_UINT8, BASE_HEX, |
1601 | 14 | VALS(service_mode_string), 0x0, |
1602 | 14 | NULL, HFILL } |
1603 | 14 | }, |
1604 | 14 | { &hf_idn_chunk_header_flags, |
1605 | 14 | { "Chunk Header Flags", "idn.chunk_header_flags", |
1606 | 14 | FT_UINT8, BASE_HEX, |
1607 | 14 | NULL, 0x0, |
1608 | 14 | NULL, HFILL } |
1609 | 14 | }, |
1610 | 14 | { &hf_idn_two_bits_reserved_1, |
1611 | 14 | { "Reserved", "idn.zero_zero", |
1612 | 14 | FT_UINT8, BASE_DEC, |
1613 | 14 | NULL, 0xC0, |
1614 | 14 | NULL, HFILL } |
1615 | 14 | }, |
1616 | 14 | { &hf_idn_two_bits_reserved_2, |
1617 | 14 | { "Reserved", "idn.zero_zero", |
1618 | 14 | FT_UINT8, BASE_DEC, |
1619 | 14 | NULL, 0xC, |
1620 | 14 | NULL, HFILL } |
1621 | 14 | }, |
1622 | 14 | { &hf_idn_scm, |
1623 | 14 | { "Service configuration match (SCM)", "idn.scm", |
1624 | 14 | FT_UINT8, BASE_DEC, |
1625 | 14 | NULL, 0x30, |
1626 | 14 | NULL, HFILL } |
1627 | 14 | }, |
1628 | 14 | { &hf_idn_three_bits_reserved, |
1629 | 14 | { "Reserved", "idn.three_bit_reserved", |
1630 | 14 | FT_UINT8, BASE_DEC, |
1631 | 14 | NULL, 0xE, |
1632 | 14 | NULL, HFILL } |
1633 | 14 | }, |
1634 | 14 | { &hf_idn_four_bits_reserved, |
1635 | 14 | { "Reserved", "idn.three_bit_reserved", |
1636 | 14 | FT_UINT8, BASE_DEC, |
1637 | 14 | NULL, 0xF, |
1638 | 14 | NULL, HFILL } |
1639 | 14 | }, |
1640 | 14 | { &hf_idn_once, |
1641 | 14 | { "Once", "idn.once", |
1642 | 14 | FT_UINT8, BASE_DEC, |
1643 | 14 | NULL, 0x1, |
1644 | 14 | NULL, HFILL } |
1645 | 14 | }, |
1646 | 14 | { &hf_idn_dlim, |
1647 | 14 | { "Delimiter (DLIM)", "idn.dlim", |
1648 | 14 | FT_UINT8, BASE_DEC, |
1649 | 14 | NULL, 0x1, |
1650 | 14 | NULL, HFILL } |
1651 | 14 | }, |
1652 | 14 | { &hf_idn_duration, |
1653 | 14 | { "Duration", "idn.frame_sample_duration", |
1654 | 14 | FT_UINT24, BASE_DEC, |
1655 | 14 | NULL, 0x0, |
1656 | 14 | NULL, HFILL } |
1657 | 14 | }, |
1658 | 14 | { &hf_idn_chunk_data_sequence, |
1659 | 14 | { "Sequence", "idn.octet_segment_sequence", |
1660 | 14 | FT_UINT8, BASE_DEC, |
1661 | 14 | NULL, 0x0, |
1662 | 14 | NULL, HFILL } |
1663 | 14 | }, |
1664 | 14 | { &hf_idn_offset, |
1665 | 14 | { "Offset", "idn.offset", |
1666 | 14 | FT_UINT16, BASE_HEX, |
1667 | 14 | NULL, 0x0, |
1668 | 14 | NULL, HFILL } |
1669 | 14 | }, |
1670 | 14 | { &hf_idn_reserved, |
1671 | 14 | { "Reserved", "idn.reserved", |
1672 | 14 | FT_BYTES, BASE_NONE, |
1673 | 14 | NULL, 0x0, |
1674 | 14 | NULL, HFILL } |
1675 | 14 | }, |
1676 | 14 | { &hf_idn_gts, |
1677 | 14 | { "Unknown", "idn.unknown", |
1678 | 14 | FT_UINT16, BASE_HEX, |
1679 | 14 | NULL, 0x0, |
1680 | 14 | NULL, HFILL } |
1681 | 14 | }, |
1682 | 14 | { &hf_idn_gts_void, |
1683 | 14 | { "Void", "idn.gts_void", |
1684 | 14 | FT_UINT16, BASE_HEX, |
1685 | 14 | NULL, 0x0, |
1686 | 14 | NULL, HFILL } |
1687 | 14 | }, |
1688 | 14 | { &hf_idn_boundary, |
1689 | 14 | { "Void (32-bit boundary)", "idn.gts_boundary", |
1690 | 14 | FT_UINT32, BASE_HEX, |
1691 | 14 | NULL, 0x0, |
1692 | 14 | NULL, HFILL } |
1693 | 14 | }, |
1694 | 14 | { &hf_idn_gts_word, |
1695 | 14 | { "16-bit word", "idn.gts_word", |
1696 | 14 | FT_UINT16, BASE_HEX, |
1697 | 14 | NULL, 0x0, |
1698 | 14 | NULL, HFILL } |
1699 | 14 | }, |
1700 | 14 | { &hf_idn_gts_break, |
1701 | 14 | { "Break", "idn.gts_break", |
1702 | 14 | FT_UINT16, BASE_HEX, |
1703 | 14 | NULL, 0x0, |
1704 | 14 | NULL, HFILL } |
1705 | 14 | }, |
1706 | 14 | { &hf_idn_gts_space_modifier, |
1707 | 14 | { "Space Modifier", "idn.gts_space_modifier", |
1708 | 14 | FT_UINT16, BASE_HEX, |
1709 | 14 | NULL, 0x0, |
1710 | 14 | NULL, HFILL } |
1711 | 14 | }, |
1712 | 14 | { &hf_idn_gts_hint, |
1713 | 14 | { "Hint", "idn.gts_hint", |
1714 | 14 | FT_UINT16, BASE_HEX, |
1715 | 14 | NULL, 0x0, |
1716 | 14 | NULL, HFILL } |
1717 | 14 | }, |
1718 | 14 | { &hf_idn_gts_category, |
1719 | 14 | { "Category", "idn.gts_category", |
1720 | 14 | FT_UINT16, BASE_DEC, |
1721 | 14 | NULL, 0xF000, |
1722 | 14 | NULL, HFILL } |
1723 | 14 | }, |
1724 | 14 | { &hf_idn_gts_subcategory, |
1725 | 14 | { "Subcategory", "idn.gts_subcategory", |
1726 | 14 | FT_UINT16, BASE_DEC, |
1727 | 14 | NULL, 0x0F00, |
1728 | 14 | NULL, HFILL } |
1729 | 14 | }, |
1730 | 14 | { &hf_idn_gts_identifier, |
1731 | 14 | { "Identifier", "idn.gts_identifier", |
1732 | 14 | FT_UINT16, BASE_DEC, |
1733 | 14 | NULL, 0x00F0, |
1734 | 14 | NULL, HFILL } |
1735 | 14 | }, |
1736 | 14 | { &hf_idn_gts_parameter, |
1737 | 14 | { "Parameter", "idn.gts_parameter", |
1738 | 14 | FT_UINT16, BASE_DEC, |
1739 | 14 | NULL, 0x000F, |
1740 | 14 | NULL, HFILL } |
1741 | 14 | }, |
1742 | 14 | { &hf_idn_gts_glin, |
1743 | 14 | { "Graphic Space Linearity (GLIN)", "idn.gts_glin", |
1744 | 14 | FT_UINT16, BASE_DEC, |
1745 | 14 | VALS(gts_glin), 0x00C0, |
1746 | 14 | NULL, HFILL } |
1747 | 14 | }, |
1748 | 14 | { &hf_idn_gts_clin, |
1749 | 14 | { "Color Space Linearity (CLIN)", "idn.gts_clin", |
1750 | 14 | FT_UINT16, BASE_DEC, |
1751 | 14 | VALS(gts_clin), 0x0030, |
1752 | 14 | NULL, HFILL } |
1753 | 14 | }, |
1754 | 14 | { &hf_idn_gts_cbal, |
1755 | 14 | { "Color Balance (CBAL)", "idn.gts_cbal", |
1756 | 14 | FT_UINT16, BASE_DEC, |
1757 | 14 | VALS(gts_cbal), 0x000C, |
1758 | 14 | NULL, HFILL } |
1759 | 14 | }, |
1760 | 14 | { &hf_idn_gts_ctim, |
1761 | 14 | { "Color Timing (CTIM)", "idn.gts_ctim", |
1762 | 14 | FT_UINT16, BASE_DEC, |
1763 | 14 | VALS(gts_ctim), 0x0003, |
1764 | 14 | NULL, HFILL } |
1765 | 14 | }, |
1766 | 14 | { &hf_idn_gts_nop, |
1767 | 14 | { "No Operation (NOP)", "idn.gts_nop", |
1768 | 14 | FT_UINT16, BASE_HEX, |
1769 | 14 | NULL, 0x0, |
1770 | 14 | NULL, HFILL } |
1771 | 14 | }, |
1772 | 14 | { &hf_idn_gts_precision, |
1773 | 14 | { "Precision", "idn.gts_precision", |
1774 | 14 | FT_UINT16, BASE_HEX, |
1775 | 14 | NULL, 0x0, |
1776 | 14 | NULL, HFILL } |
1777 | 14 | }, |
1778 | 14 | { &hf_idn_gts_cscl, |
1779 | 14 | { "Color scale (CSCL)", "idn.gts_cscl", |
1780 | 14 | FT_UINT16, BASE_DEC, |
1781 | 14 | NULL, 0x00C0, |
1782 | 14 | NULL, HFILL } |
1783 | 14 | }, |
1784 | 14 | { &hf_idn_gts_iscl, |
1785 | 14 | { "Intensity scale (ISCL)", "idn.gts_iscl", |
1786 | 14 | FT_UINT16, BASE_DEC, |
1787 | 14 | NULL, 0x0030, |
1788 | 14 | NULL, HFILL } |
1789 | 14 | }, |
1790 | 14 | { &hf_idn_gts_sht, |
1791 | 14 | { "Shutter (SHT)", "idn.gts_sht", |
1792 | 14 | FT_UINT16, BASE_DEC, |
1793 | 14 | NULL, 0x000F, |
1794 | 14 | NULL, HFILL } |
1795 | 14 | }, |
1796 | 14 | { &hf_idn_gts_u4, |
1797 | 14 | { "Optional(U4), used as X-prime", "idn.gts_u4", |
1798 | 14 | FT_UINT16, BASE_HEX, |
1799 | 14 | NULL, 0x0, |
1800 | 14 | NULL, HFILL } |
1801 | 14 | }, |
1802 | 14 | { &hf_idn_gts_x, |
1803 | 14 | { "X", "idn.gts_x", |
1804 | 14 | FT_UINT16, BASE_HEX, |
1805 | 14 | NULL, 0x0, |
1806 | 14 | NULL, HFILL } |
1807 | 14 | }, |
1808 | 14 | { &hf_idn_gts_y, |
1809 | 14 | { "Y", "idn.gts_y", |
1810 | 14 | FT_UINT16, BASE_HEX, |
1811 | 14 | NULL, 0x0, |
1812 | 14 | NULL, HFILL } |
1813 | 14 | }, |
1814 | 14 | { &hf_idn_gts_z, |
1815 | 14 | { "Z", "idn.gts_z", |
1816 | 14 | FT_UINT16, BASE_HEX, |
1817 | 14 | NULL, 0x0, |
1818 | 14 | NULL, HFILL } |
1819 | 14 | }, |
1820 | 14 | { &hf_idn_gts_color, |
1821 | 14 | { "Color", "idn.gts_color", |
1822 | 14 | FT_UINT16, BASE_DEC, |
1823 | 14 | VALS(idn_color), 0x03FF, |
1824 | 14 | NULL, HFILL } |
1825 | 14 | }, |
1826 | 14 | { &hf_idn_gts_wavelength_prefix, |
1827 | 14 | { "Wavelength Prefix", "idn.gts_wavelength_prefix", |
1828 | 14 | FT_UINT16, BASE_HEX, |
1829 | 14 | NULL, 0x0, |
1830 | 14 | NULL, HFILL } |
1831 | 14 | }, |
1832 | 14 | { &hf_idn_gts_intensity, |
1833 | 14 | { "Intensity/blanking", "idn.gts_intensity", |
1834 | 14 | FT_UINT16, BASE_HEX, |
1835 | 14 | NULL, 0x0, |
1836 | 14 | NULL, HFILL } |
1837 | 14 | }, |
1838 | 14 | { &hf_idn_gts_beam_brush, |
1839 | 14 | { "Beam-Brush", "idn.gts_beam_brush", |
1840 | 14 | FT_UINT16, BASE_HEX, |
1841 | 14 | NULL, 0x0, |
1842 | 14 | NULL, HFILL } |
1843 | 14 | }, |
1844 | 14 | { &hf_idn_gts_sample, |
1845 | 14 | { "Sample", "idn.gts_sample", |
1846 | 14 | FT_BYTES, BASE_NONE, |
1847 | 14 | NULL, 0x0, |
1848 | 14 | NULL, HFILL } |
1849 | 14 | }, |
1850 | 14 | { &hf_idn_dmx_octet, |
1851 | 14 | { "Octet", "idn.gts_octet", |
1852 | 14 | FT_UINT8, BASE_DEC, |
1853 | 14 | NULL, 0x0, |
1854 | 14 | NULL, HFILL } |
1855 | 14 | }, |
1856 | 14 | { &hf_idn_dmx_identifier, |
1857 | 14 | { "Identifier", "idn.gts_dmx_identifier", |
1858 | 14 | FT_UINT8, BASE_DEC, |
1859 | 14 | NULL, 0xF0, |
1860 | 14 | NULL, HFILL } |
1861 | 14 | }, |
1862 | 14 | { &hf_idn_dmx_parameter, |
1863 | 14 | { "Parameter", "idn.gts_dmx_parameter", |
1864 | 14 | FT_UINT8, BASE_DEC, |
1865 | 14 | NULL, 0x0F, |
1866 | 14 | NULL, HFILL } |
1867 | 14 | }, |
1868 | 14 | { &hf_idn_dmx_void, |
1869 | 14 | { "Void", "idn.gts_dmx_void", |
1870 | 14 | FT_UINT8, BASE_HEX, |
1871 | 14 | NULL, 0x0, |
1872 | 14 | NULL, HFILL } |
1873 | 14 | }, |
1874 | 14 | { &hf_idn_octet, |
1875 | 14 | { "Octet", "idn.gts_dmx_octet", |
1876 | 14 | FT_UINT8, BASE_HEX, |
1877 | 14 | NULL, 0x0, |
1878 | 14 | NULL, HFILL } |
1879 | 14 | }, |
1880 | 14 | { &hf_idn_dmx_dls, |
1881 | 14 | { "Dimmer Level Subset", "idn.dmx_dls", |
1882 | 14 | FT_UINT8, BASE_HEX, |
1883 | 14 | NULL, 0x0, |
1884 | 14 | NULL, HFILL } |
1885 | 14 | }, |
1886 | 14 | { &hf_idn_dmx_base, |
1887 | 14 | { "Base", "idn.dmx_base", |
1888 | 14 | FT_UINT16, BASE_DEC, |
1889 | 14 | NULL, 0x0, |
1890 | 14 | NULL, HFILL } |
1891 | 14 | }, |
1892 | 14 | { &hf_idn_dmx_count, |
1893 | 14 | { "Count", "idn.dmx_count", |
1894 | 14 | FT_UINT8, BASE_DEC, |
1895 | 14 | NULL, 0x0, |
1896 | 14 | NULL, HFILL } |
1897 | 14 | }, |
1898 | 14 | { &hf_idn_dmx_unknown, |
1899 | 14 | { "Unknown", "idn.dmx_unknown", |
1900 | 14 | FT_UINT8, BASE_HEX, |
1901 | 14 | NULL, 0x0, |
1902 | 14 | NULL, HFILL } |
1903 | 14 | }, |
1904 | 14 | { &hf_idn_result_code, |
1905 | 14 | { "Result Code", "idn.result_code", |
1906 | 14 | FT_UINT8, BASE_DEC, |
1907 | 14 | VALS(result_code), 0x0, |
1908 | 14 | NULL, HFILL } |
1909 | 14 | }, |
1910 | 14 | { &hf_idn_event_flags, |
1911 | 14 | { "Event Flags", "idn.event_flags", |
1912 | 14 | FT_UINT16, BASE_HEX, |
1913 | 14 | NULL, 0x0, |
1914 | 14 | NULL, HFILL } |
1915 | 14 | }, |
1916 | 14 | { &hf_idn_audio_dictionary_tag, |
1917 | 14 | { "Audio Dictionary Tag", "idn.audioheader", |
1918 | 14 | FT_UINT16, BASE_HEX, |
1919 | 14 | NULL, 0x0, |
1920 | 14 | NULL, HFILL |
1921 | 14 | } |
1922 | 14 | }, |
1923 | 14 | { &hf_idn_category, |
1924 | 14 | { "Category", "idn.category", |
1925 | 14 | FT_UINT16, BASE_HEX, |
1926 | 14 | VALS(category), 0xF000, |
1927 | 14 | NULL, HFILL |
1928 | 14 | } |
1929 | 14 | }, |
1930 | 14 | { &hf_idn_format, |
1931 | 14 | { "Format", "idn.format", |
1932 | 14 | FT_UINT16, BASE_DEC, |
1933 | 14 | VALS(format), 0x0F00, |
1934 | 14 | NULL, HFILL |
1935 | 14 | } |
1936 | 14 | }, |
1937 | 14 | { &hf_idn_layout, |
1938 | 14 | { "Layout", "idn.layout", |
1939 | 14 | FT_UINT16, BASE_DEC, |
1940 | 14 | NULL, 0x00F0, |
1941 | 14 | NULL, HFILL |
1942 | 14 | } |
1943 | 14 | }, |
1944 | 14 | { &hf_idn_4bit_channels, |
1945 | 14 | { "Channels", "idn.category6channels", |
1946 | 14 | FT_UINT16, BASE_DEC, |
1947 | 14 | NULL, 0x000F, |
1948 | 14 | NULL, HFILL |
1949 | 14 | } |
1950 | 14 | }, |
1951 | 14 | { &hf_idn_subcategory, |
1952 | 14 | { "Subcategory", "idn.subcategory", |
1953 | 14 | FT_UINT16, BASE_DEC, |
1954 | 14 | NULL, 0x0F00, |
1955 | 14 | NULL, HFILL |
1956 | 14 | } |
1957 | 14 | }, |
1958 | 14 | { &hf_idn_parameter, |
1959 | 14 | { "Format", "idn.format", |
1960 | 14 | FT_UINT16, BASE_DEC, |
1961 | 14 | NULL, 0x00F0, |
1962 | 14 | NULL, HFILL |
1963 | 14 | } |
1964 | 14 | }, |
1965 | 14 | { &hf_idn_suffix_length, |
1966 | 14 | { "Suffix length", "idn.suffix_length", |
1967 | 14 | FT_UINT16, BASE_DEC, |
1968 | 14 | NULL, 0x000F, |
1969 | 14 | NULL, HFILL |
1970 | 14 | } |
1971 | 14 | }, |
1972 | 14 | { &hf_idn_8bit_channels, |
1973 | 14 | { "Channels", "idn.channel", |
1974 | 14 | FT_UINT16, BASE_DEC, |
1975 | 14 | NULL, 0x00FF, |
1976 | 14 | NULL, HFILL |
1977 | 14 | } |
1978 | 14 | }, |
1979 | 14 | { &hf_idn_audio_flags, |
1980 | 14 | { "Flags", "idn.audio_flags", |
1981 | 14 | FT_UINT8, BASE_HEX, |
1982 | 14 | NULL, 0x0, |
1983 | 14 | NULL, HFILL} |
1984 | 14 | }, |
1985 | 14 | { &hf_idn_audio_duration, |
1986 | 14 | { "Duration in microseconds", "idn.audio_duration", |
1987 | 14 | FT_UINT24, BASE_DEC, |
1988 | 14 | NULL, 0x0, |
1989 | 14 | NULL, HFILL} |
1990 | 14 | }, |
1991 | 14 | { &hf_idn_audio_flags_two_bits_reserved, |
1992 | 14 | { "Reserved", "idn.audio_2", |
1993 | 14 | FT_UINT8, BASE_HEX, |
1994 | 14 | NULL, 0xC0, |
1995 | 14 | NULL, HFILL} |
1996 | 14 | }, |
1997 | 14 | { &hf_idn_audio_flags_four_bits_reserved, |
1998 | 14 | { "Reserved", "idn.audio_4", |
1999 | 14 | FT_UINT8, BASE_HEX, |
2000 | 14 | NULL, 0x0F, |
2001 | 14 | NULL, HFILL} |
2002 | 14 | }, |
2003 | 14 | { &hf_idn_audio_flags_scm, |
2004 | 14 | { "Service configuration match", "idn.audio_scm", |
2005 | 14 | FT_UINT8, BASE_HEX, |
2006 | 14 | NULL, 0x30, |
2007 | 14 | NULL, HFILL} |
2008 | 14 | }, |
2009 | 14 | { &hf_idn_audio_sample_format_zero, |
2010 | 14 | { "Audio Sample (format 0)", "idn.audio_sample_0", |
2011 | 14 | FT_UINT8, BASE_HEX, |
2012 | 14 | NULL, 0x0, |
2013 | 14 | NULL, HFILL} |
2014 | 14 | }, |
2015 | 14 | { &hf_idn_audio_sample_format_one, |
2016 | 14 | { "Audio Sample (format 1)", "idn.audio_sample_1", |
2017 | 14 | FT_UINT16, BASE_HEX, |
2018 | 14 | NULL, 0x0, |
2019 | 14 | NULL, HFILL} |
2020 | 14 | }, |
2021 | 14 | { &hf_idn_audio_sample_format_two, |
2022 | 14 | { "Audio Sample (format 2)", "idn.audio_sample_2", |
2023 | 14 | FT_UINT24, BASE_HEX, |
2024 | 14 | NULL, 0x0, |
2025 | 14 | NULL, HFILL} |
2026 | 14 | } |
2027 | 14 | }; |
2028 | | |
2029 | 14 | static int *ett[] = { |
2030 | 14 | &ett_idn, |
2031 | 14 | &ett_idn_header_tree, |
2032 | 14 | &ett_idn_scanreply_header_tree, |
2033 | 14 | &ett_idn_channel_message_header_tree, |
2034 | 14 | &ett_protocol_version, |
2035 | 14 | &ett_unit_id, |
2036 | 14 | &ett_status, |
2037 | 14 | &ett_idn_cnl, |
2038 | 14 | &ett_cfl, |
2039 | 14 | &ett_configuration_header, |
2040 | 14 | &ett_chunk_header_tree, |
2041 | 14 | &ett_chunk_header_flags, |
2042 | 14 | &ett_dic, |
2043 | 14 | &ett_dic_tree, |
2044 | 14 | &ett_data, |
2045 | 14 | &ett_subdata, |
2046 | 14 | &ett_dmx_subtree, |
2047 | 14 | &ett_audio_header, |
2048 | 14 | &ett_audio_samples |
2049 | 14 | }; |
2050 | | |
2051 | 14 | expert_module_t* expert_idn; |
2052 | 14 | static ei_register_info ei[] = { |
2053 | 14 | { &ei_idn_no_config, { "idn.no_config", PI_UNDECODED, PI_NOTE, |
2054 | 14 | "No configuration is associated with this message", EXPFILL } }, |
2055 | 14 | { &ei_idn_scwc_unknown, { "idn.scwc.unknown", PI_SEQUENCE, PI_WARN, |
2056 | 14 | "SCWC is zero/unknown", EXPFILL } }, |
2057 | 14 | { &ei_idn_channels_over, { "idn.channel.over", PI_PROTOCOL, PI_ERROR, |
2058 | 14 | "Over number of channels", EXPFILL } }, |
2059 | 14 | { &ei_idn_scm_mismatch, { "idn.scm.mismatch", PI_PROTOCOL, PI_ERROR, |
2060 | 14 | "SCM doesn't match configured SDM", EXPFILL } }, |
2061 | 14 | }; |
2062 | | |
2063 | 14 | proto_idn = proto_register_protocol ( |
2064 | 14 | "Ilda Digital Network Protocol", |
2065 | 14 | "IDN", |
2066 | 14 | "idn" |
2067 | 14 | ); |
2068 | | |
2069 | 14 | proto_register_field_array(proto_idn, hf, array_length(hf)); |
2070 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
2071 | | |
2072 | 14 | expert_idn = expert_register_protocol(proto_idn); |
2073 | 14 | expert_register_field_array(expert_idn, ei, array_length(ei)); |
2074 | | |
2075 | 14 | idn_handle = register_dissector("idn", dissect_idn, proto_idn); |
2076 | 14 | } |
2077 | | |
2078 | 14 | void proto_reg_handoff_idn(void) { |
2079 | 14 | dissector_add_uint("udp.port", IDN_PORT, idn_handle); |
2080 | 14 | } |
2081 | | |
2082 | | /* |
2083 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
2084 | | * |
2085 | | * Local variables: |
2086 | | * c-basic-offset: 8 |
2087 | | * tab-width: 8 |
2088 | | * indent-tabs-mode: t |
2089 | | * End: |
2090 | | * |
2091 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
2092 | | * :indentSize=8:tabSize=8:noTabs=false: |
2093 | | */ |