Rename the routines that handle dissector tables with unsigned integer
[obnox/wireshark/wip.git] / epan / dissectors / packet-adwin.c
1 /* packet-adwin.c
2  * Routines for ADwin protocol dissection
3  * Copyright 2010, Thomas Boehne <TBoehne[AT]ADwin.de>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 /* includes needed for wireshark */
31 #include <glib.h>
32 #include <epan/prefs.h>
33 #include <epan/packet.h>
34 #include <epan/proto.h>
35 #include <epan/conversation.h>
36 #include <epan/emem.h>
37
38 /* This is registered to a different protocol */
39 #define ADWIN_COMM_PORT 6543
40
41 /* lengths of valid packet structures */
42 #define UDPH1_OLD_LENGTH              52
43 #define UDPH1_NEW_LENGTH              56
44 #define UDPR1_LENGTH                  32
45 #define UDPH2_LENGTH                 412 /* AFAIK: unused */
46 #define UDPR2_LENGTH                1008
47 #define UDPR3_LENGTH                1408
48 #define UDPR4_LENGTH                1416
49 #define GetDataSHPacket_LENGTH      1356
50 #define GetDataSHRequest_LENGTH       64
51
52 /* operating systems */
53 #define OS_WINDOWS                  0x00
54 #define OS_LINUX                    0x10
55 #define OS_JAVA                     0x20
56 #define OS_DOT_NET                  0x40
57 #define OS_GENERIC                  0x80
58 static const value_string osys_mapping[] = {
59         { OS_WINDOWS, "Windows"},
60         { OS_LINUX,   "Linux"},
61         { OS_JAVA,    "Java"},
62         { OS_DOT_NET, ".Net"},
63         { OS_GENERIC, "Generic TCP/IP Driver"},
64         { 0,          NULL },
65 };
66 static value_string_ext osys_mapping_ext = VALUE_STRING_EXT_INIT(osys_mapping);
67
68 /* error codes */
69 #define EC_OK                          0
70 #define EC_TIMEOUT_TO_LINK             1
71 #define EC_TIMEOUT_FROM_LINK           2
72 #define EC_TIMEOUT_FAST_TO_LINK        3
73 #define EC_TIMEOUT_FAST_FROM_LINK      4
74 #define EC_TIMEOUT                     5
75 #define EC_MEMORY_ERROR             -100
76 #define EC_RETRY_UNKNOWN             -41
77 #define EC_ALREADY_PROCESSED         -40
78 #define EC_WRONG_BINARY_FILE         -35
79 #define EC_INVALID_PACKET_ORDER      -33
80 #define EC_FIFO_NOT_ENOUGH_DATA      -32
81 #define EC_DATA_TOO_SMALL            -31
82 #define EC_WRONG_VERSION             -30
83 #define EC_WRONG_SIZE                -26
84 #define EC_PACKET_TOO_LARGE          -25
85 #define EC_PACKET_ERROR              -20
86 #define EC_FILE_ERROR                -15
87 #define EC_TRY_LATER                 -10
88 #define EC_WRONG_PASSWORD             -5
89 #define EC_UDP_TIMEOUT                -1
90 static const value_string error_code_mapping[] = {
91         { EC_OK,                     "OK"},
92         { EC_TIMEOUT_TO_LINK,        "Timeout to link"},
93         { EC_TIMEOUT_FROM_LINK,      "Timeout from link"},
94         { EC_TIMEOUT_FAST_TO_LINK,   "Timeout fast to link"},
95         { EC_TIMEOUT_FAST_FROM_LINK, "Timeout fast from link"},
96         { EC_TIMEOUT,                "Timeout"},
97         { EC_MEMORY_ERROR,           "Memory error"},
98         { EC_RETRY_UNKNOWN,          "Retry unknown"},
99         { EC_ALREADY_PROCESSED,      "Already processed"},
100         { EC_WRONG_BINARY_FILE,      "Binary/Processor mismatch"},
101         { EC_INVALID_PACKET_ORDER,   "Invalid Packet order"},
102         { EC_FIFO_NOT_ENOUGH_DATA,   "Fifo has not enough data"},
103         { EC_DATA_TOO_SMALL,         "Data too small"},
104         { EC_WRONG_VERSION,          "Wrong version"},
105         { EC_WRONG_SIZE,             "Wrong size"},
106         { EC_PACKET_ERROR,           "Packet error"},
107         { EC_FILE_ERROR,             "File error"},
108         { EC_TRY_LATER,              "Try later"},
109         { EC_WRONG_PASSWORD,         "Wrong password"},
110         { EC_UDP_TIMEOUT,            "UDP timeout"},
111         { 0, NULL },
112 };
113 static value_string_ext error_code_mapping_ext = VALUE_STRING_EXT_INIT(error_code_mapping);
114
115 static const value_string data_type_mapping[] = {
116         { 2, "short / int"},
117         { 3, "int"},
118         { 4, "long"},
119         { 5, "float"},
120         { 6, "double"},
121         { 20, "variant"},
122         { 0, NULL },
123 };
124 static value_string_ext data_type_mapping_ext = VALUE_STRING_EXT_INIT(data_type_mapping);
125
126 #define I_3PLUS1                           0
127 #define I_LOAD_BIN_FILE                    4
128 #define I_GET_DATA                         7
129 #define I_SET_DATA                         8
130 #define I_CREATE_DATA                     10
131 #define I_GET_PAR_ALL                     13
132 #define I_GET_WORKLOAD                    20
133 #define I_GET_FIFO                        24
134 #define I_SET_FIFO                        25
135 #define I_BOOT                            50
136 #define I_GET_DATA_TYPE                  100
137 #define I_GET_DATA_SHIFTED_HANDSHAKE     107
138 #define I_SET_DATA_LAST_STATUS           108
139 #define I_GET_FIFO_RETRY                 124
140 #define I_SET_FIFO_RETRY                 125
141 #define I_GET_DATA_SMALL                 207
142 #define I_TEST_VERSION                   255
143 #define I_GET_ARM_VERSION               1000
144 #define I_GET_MEMORY                 1000000
145
146 static const value_string instruction_mapping[] = {
147         { I_3PLUS1,                     "3+1 instruction" },
148         { I_LOAD_BIN_FILE,              "Load binary file" },
149         { I_GET_DATA,                   "Get data" },
150         { I_SET_DATA,                   "Set data" },
151         { I_CREATE_DATA,                "Create data" },
152         { I_GET_PAR_ALL,                "Get all parameters" },
153         { I_GET_WORKLOAD,               "Get workload"},
154         { I_GET_FIFO,                   "Get fifo" },
155         { I_SET_FIFO,                   "Set fifo" },
156         { I_BOOT,                       "Boot" },
157         { I_GET_DATA_TYPE,              "Get data type" },
158         { I_GET_DATA_SHIFTED_HANDSHAKE, "Get data (shifted handshake)" },
159         { I_SET_DATA_LAST_STATUS,       "Get status of last set data" },
160         { I_GET_FIFO_RETRY,             "Get fifo - retry" },
161         { I_SET_FIFO_RETRY,             "Set fifo - retry" },
162         { I_GET_DATA_SMALL,             "Get data (small/fast)" },
163         { I_TEST_VERSION,               "Get/test version information" },
164         { I_GET_ARM_VERSION,            "Get ARM-Version" },
165         { I_GET_MEMORY,                 "Get memory DSP" },
166         { 0, NULL },
167 };
168 static value_string_ext instruction_mapping_ext = VALUE_STRING_EXT_INIT(instruction_mapping);
169
170 /* 3+1 instructions */
171 #define I_3P1_GET_PAR                     1
172 #define I_3P1_START                       2
173 #define I_3P1_STOP                        3
174 #define I_3P1_GET_MEMORY_INFO             5
175 #define I_3P1_SET_PAR                     6
176 #define I_3P1_CLEAR_DATA                  9
177 #define I_3P1_GET_DATA_LENGTH            11
178 #define I_3P1_GET_DETAILED_MEM_INFO      12
179 #define I_3P1_CLEAR_PROCESS              14
180 #define I_3P1_ADC                        15
181 #define I_3P1_DAC                        16
182 #define I_3P1_GET_DIGIN                  17
183 #define I_3P1_SET_DIGOUT                 18
184 #define I_3P1_GET_DIGOUT                 19
185 #define I_3P1_CLEAR_FIFO                 21
186 #define I_3P1_GET_FIFO_EMPTY             22
187 #define I_3P1_GET_FIFO_COUNT             23
188 static const value_string instruction_3plus1_mapping[] = {
189         { I_3P1_GET_PAR,               "Get parameter"},
190         { I_3P1_START,                 "Start process"},
191         { I_3P1_STOP,                  "Stop process"},
192         { I_3P1_GET_MEMORY_INFO,       "Get memory info"},
193         { I_3P1_SET_PAR,               "Set parameter"},
194         { I_3P1_CLEAR_DATA,            "Clear data"},
195         { I_3P1_GET_DATA_LENGTH,       "Get data length"},
196         { I_3P1_GET_DETAILED_MEM_INFO, "Get detailed memory info"},
197         { I_3P1_CLEAR_PROCESS,         "Clear process"},
198         { I_3P1_ADC,                   "Get ADC value"},
199         { I_3P1_DAC,                   "Set DAC value"},
200         { I_3P1_GET_DIGIN,             "Get digital in"},
201         { I_3P1_SET_DIGOUT,            "Set digital out"},
202         { I_3P1_GET_DIGOUT,            "Get digital out"},
203         { I_3P1_CLEAR_FIFO,            "Clear fifo"},
204         { I_3P1_GET_FIFO_EMPTY,        "Get fifo empty"},
205         { I_3P1_GET_FIFO_COUNT,        "Get fifo full/count"},
206         { 0,               NULL },
207 };
208 static value_string_ext instruction_3plus1_mapping_ext = VALUE_STRING_EXT_INIT(instruction_3plus1_mapping);
209
210 static const value_string parameter_mapping[] = {
211         { 901 , "Status of Process No. 01"},
212         { 902 , "Status of Process No. 02"},
213         { 903 , "Status of Process No. 03"},
214         { 904 , "Status of Process No. 04"},
215         { 905 , "Status of Process No. 05"},
216         { 906 , "Status of Process No. 06"},
217         { 907 , "Status of Process No. 07"},
218         { 908 , "Status of Process No. 08"},
219         { 909 , "Status of Process No. 09"},
220         { 910 , "Status of Process No. 10"},
221         { 911 , "GlobalDelay for Process No. 01"},
222         { 912 , "GlobalDelay for Process No. 02"},
223         { 913 , "GlobalDelay for Process No. 03"},
224         { 914 , "GlobalDelay for Process No. 04"},
225         { 915 , "GlobalDelay for Process No. 05"},
226         { 916 , "GlobalDelay for Process No. 06"},
227         { 917 , "GlobalDelay for Process No. 07"},
228         { 918 , "GlobalDelay for Process No. 08"},
229         { 919 , "GlobalDelay for Process No. 09"},
230         { 920 , "GlobalDelay for Process No. 10"},
231         { 921 , "GlobalDelay for Process No. 11"},
232         { 922 , "GlobalDelay for Process No. 12"},
233         { 923 , "GlobalDelay for Process No. 13"},
234         { 924 , "GlobalDelay for Process No. 14"},
235         { 925 , "GlobalDelay for Process No. 15"},
236         { 926 , "GlobalDelay for Process No. 16"},
237         { 951 , "Debug Information of Process No. 01"},
238         { 952 , "Debug Information of Process No. 02"},
239         { 953 , "Debug Information of Process No. 03"},
240         { 954 , "Debug Information of Process No. 04"},
241         { 955 , "Debug Information of Process No. 05"},
242         { 956 , "Debug Information of Process No. 06"},
243         { 957 , "Debug Information of Process No. 07"},
244         { 958 , "Debug Information of Process No. 08"},
245         { 959 , "Debug Information of Process No. 09"},
246         { 960 , "Debug Information of Process No. 10"},
247         { 961 , "Debug Information of Process No. 11"},
248         { 962 , "Debug Information of Process No. 12"},
249         { 963 , "Debug Information of Process No. 13"},
250         { 964 , "Debug Information of Process No. 14"},
251         { 965 , "Debug Information of Process No. 15"},
252         { 966 , "Debug Information of Process No. 16"},
253         { 1001 , "Parameter No. 01"},
254         { 1002 , "Parameter No. 02"},
255         { 1003 , "Parameter No. 03"},
256         { 1004 , "Parameter No. 04"},
257         { 1005 , "Parameter No. 05"},
258         { 1006 , "Parameter No. 06"},
259         { 1007 , "Parameter No. 07"},
260         { 1008 , "Parameter No. 08"},
261         { 1009 , "Parameter No. 09"},
262         { 1010 , "Parameter No. 10"},
263         { 1011 , "Parameter No. 11"},
264         { 1012 , "Parameter No. 12"},
265         { 1013 , "Parameter No. 13"},
266         { 1014 , "Parameter No. 14"},
267         { 1015 , "Parameter No. 15"},
268         { 1016 , "Parameter No. 16"},
269         { 1017 , "Parameter No. 17"},
270         { 1018 , "Parameter No. 18"},
271         { 1019 , "Parameter No. 19"},
272         { 1020 , "Parameter No. 20"},
273         { 1021 , "Parameter No. 21"},
274         { 1022 , "Parameter No. 22"},
275         { 1023 , "Parameter No. 23"},
276         { 1024 , "Parameter No. 24"},
277         { 1025 , "Parameter No. 25"},
278         { 1026 , "Parameter No. 26"},
279         { 1027 , "Parameter No. 27"},
280         { 1028 , "Parameter No. 28"},
281         { 1029 , "Parameter No. 29"},
282         { 1030 , "Parameter No. 30"},
283         { 1031 , "Parameter No. 31"},
284         { 1032 , "Parameter No. 32"},
285         { 1033 , "Parameter No. 33"},
286         { 1034 , "Parameter No. 34"},
287         { 1035 , "Parameter No. 35"},
288         { 1036 , "Parameter No. 36"},
289         { 1037 , "Parameter No. 37"},
290         { 1038 , "Parameter No. 38"},
291         { 1039 , "Parameter No. 39"},
292         { 1040 , "Parameter No. 40"},
293         { 1041 , "Parameter No. 41"},
294         { 1042 , "Parameter No. 42"},
295         { 1043 , "Parameter No. 43"},
296         { 1044 , "Parameter No. 44"},
297         { 1045 , "Parameter No. 45"},
298         { 1046 , "Parameter No. 46"},
299         { 1047 , "Parameter No. 47"},
300         { 1048 , "Parameter No. 48"},
301         { 1049 , "Parameter No. 49"},
302         { 1050 , "Parameter No. 50"},
303         { 1051 , "Parameter No. 51"},
304         { 1052 , "Parameter No. 52"},
305         { 1053 , "Parameter No. 53"},
306         { 1054 , "Parameter No. 54"},
307         { 1055 , "Parameter No. 55"},
308         { 1056 , "Parameter No. 56"},
309         { 1057 , "Parameter No. 57"},
310         { 1058 , "Parameter No. 58"},
311         { 1059 , "Parameter No. 59"},
312         { 1060 , "Parameter No. 60"},
313         { 1061 , "Parameter No. 61"},
314         { 1062 , "Parameter No. 62"},
315         { 1063 , "Parameter No. 63"},
316         { 1064 , "Parameter No. 64"},
317         { 1065 , "Parameter No. 65"},
318         { 1066 , "Parameter No. 66"},
319         { 1067 , "Parameter No. 67"},
320         { 1068 , "Parameter No. 68"},
321         { 1069 , "Parameter No. 69"},
322         { 1070 , "Parameter No. 70"},
323         { 1071 , "Parameter No. 71"},
324         { 1072 , "Parameter No. 72"},
325         { 1073 , "Parameter No. 73"},
326         { 1074 , "Parameter No. 74"},
327         { 1075 , "Parameter No. 75"},
328         { 1076 , "Parameter No. 76"},
329         { 1077 , "Parameter No. 77"},
330         { 1078 , "Parameter No. 78"},
331         { 1079 , "Parameter No. 79"},
332         { 1080 , "Parameter No. 80"},
333         { 1101 , "Float-Parameter No. 01"},
334         { 1102 , "Float-Parameter No. 02"},
335         { 1103 , "Float-Parameter No. 03"},
336         { 1104 , "Float-Parameter No. 04"},
337         { 1105 , "Float-Parameter No. 05"},
338         { 1106 , "Float-Parameter No. 06"},
339         { 1107 , "Float-Parameter No. 07"},
340         { 1108 , "Float-Parameter No. 08"},
341         { 1109 , "Float-Parameter No. 09"},
342         { 1110 , "Float-Parameter No. 10"},
343         { 1111 , "Float-Parameter No. 11"},
344         { 1112 , "Float-Parameter No. 12"},
345         { 1113 , "Float-Parameter No. 13"},
346         { 1114 , "Float-Parameter No. 14"},
347         { 1115 , "Float-Parameter No. 15"},
348         { 1116 , "Float-Parameter No. 16"},
349         { 1117 , "Float-Parameter No. 17"},
350         { 1118 , "Float-Parameter No. 18"},
351         { 1119 , "Float-Parameter No. 19"},
352         { 1120 , "Float-Parameter No. 20"},
353         { 1121 , "Float-Parameter No. 21"},
354         { 1122 , "Float-Parameter No. 22"},
355         { 1123 , "Float-Parameter No. 23"},
356         { 1124 , "Float-Parameter No. 24"},
357         { 1125 , "Float-Parameter No. 25"},
358         { 1126 , "Float-Parameter No. 26"},
359         { 1127 , "Float-Parameter No. 27"},
360         { 1128 , "Float-Parameter No. 28"},
361         { 1129 , "Float-Parameter No. 29"},
362         { 1130 , "Float-Parameter No. 30"},
363         { 1131 , "Float-Parameter No. 31"},
364         { 1132 , "Float-Parameter No. 32"},
365         { 1133 , "Float-Parameter No. 33"},
366         { 1134 , "Float-Parameter No. 34"},
367         { 1135 , "Float-Parameter No. 35"},
368         { 1136 , "Float-Parameter No. 36"},
369         { 1137 , "Float-Parameter No. 37"},
370         { 1138 , "Float-Parameter No. 38"},
371         { 1139 , "Float-Parameter No. 39"},
372         { 1140 , "Float-Parameter No. 40"},
373         { 1141 , "Float-Parameter No. 41"},
374         { 1142 , "Float-Parameter No. 42"},
375         { 1143 , "Float-Parameter No. 43"},
376         { 1144 , "Float-Parameter No. 44"},
377         { 1145 , "Float-Parameter No. 45"},
378         { 1146 , "Float-Parameter No. 46"},
379         { 1147 , "Float-Parameter No. 47"},
380         { 1148 , "Float-Parameter No. 48"},
381         { 1149 , "Float-Parameter No. 49"},
382         { 1150 , "Float-Parameter No. 50"},
383         { 1151 , "Float-Parameter No. 51"},
384         { 1152 , "Float-Parameter No. 52"},
385         { 1153 , "Float-Parameter No. 53"},
386         { 1154 , "Float-Parameter No. 54"},
387         { 1155 , "Float-Parameter No. 55"},
388         { 1156 , "Float-Parameter No. 56"},
389         { 1157 , "Float-Parameter No. 57"},
390         { 1158 , "Float-Parameter No. 58"},
391         { 1159 , "Float-Parameter No. 59"},
392         { 1160 , "Float-Parameter No. 60"},
393         { 1161 , "Float-Parameter No. 61"},
394         { 1162 , "Float-Parameter No. 62"},
395         { 1163 , "Float-Parameter No. 63"},
396         { 1164 , "Float-Parameter No. 64"},
397         { 1165 , "Float-Parameter No. 65"},
398         { 1166 , "Float-Parameter No. 66"},
399         { 1167 , "Float-Parameter No. 67"},
400         { 1168 , "Float-Parameter No. 68"},
401         { 1169 , "Float-Parameter No. 69"},
402         { 1170 , "Float-Parameter No. 70"},
403         { 1171 , "Float-Parameter No. 71"},
404         { 1172 , "Float-Parameter No. 72"},
405         { 1173 , "Float-Parameter No. 73"},
406         { 1174 , "Float-Parameter No. 74"},
407         { 1175 , "Float-Parameter No. 75"},
408         { 1176 , "Float-Parameter No. 76"},
409         { 1177 , "Float-Parameter No. 77"},
410         { 1178 , "Float-Parameter No. 78"},
411         { 1179 , "Float-Parameter No. 79"},
412         { 1180 , "Float-Parameter No. 80"},
413         { 4891 , "Status of Process No. 11"},
414         { 4892 , "Status of Process No. 12"},
415         { 4893 , "Status of Process No. 13"},
416         { 4894 , "Status of Process No. 14"},
417         { 4895 , "Status of Process No. 15"},
418         { 4896 , "Status of Process No. 16"},
419         {10000 , "Start Timing Analyzer"},
420         {10001 , "Stop Timing Analyzer"},
421         { 0, NULL },
422 };
423 static value_string_ext parameter_mapping_ext = VALUE_STRING_EXT_INIT(parameter_mapping);
424
425 typedef enum {
426         APT_UDPH1_old, APT_UDPH1_new, APT_UDPR1, APT_UDPR2, APT_UDPR3,
427         APT_UDPR4, APT_GDSHP, APT_GDSHR
428 } adwin_packet_types_t;
429
430 static const value_string packet_type_mapping[] = {
431         { APT_UDPH1_old, "UDPH1 old"},
432         { APT_UDPH1_new, "UDPH1 new"},
433         { APT_UDPR1, "UDPR1"},
434         { APT_UDPR2, "UDPR2"},
435         { APT_UDPR3, "UDPR3"},
436         { APT_UDPR4, "UDPR4"},
437         { APT_GDSHP, "GDSHP"},
438         { APT_GDSHR, "GDSHR"},
439         { 0, NULL },
440 };
441 static value_string_ext packet_type_mapping_ext = VALUE_STRING_EXT_INIT(packet_type_mapping);
442
443 /* add little endian number (incorrect network byte-order) value to a tree */
444 #define ADWIN_ADD_LE(tree, field, offset, length)                \
445         proto_tree_add_item(tree, hf_adwin_##field, tvb, offset, \
446                             length, ENC_LITTLE_ENDIAN);
447
448 /* add big endian number (correct network byte-order) value to a tree */
449 #define ADWIN_ADD_BE(tree, field, offset, length)                \
450         proto_tree_add_item(tree, hf_adwin_##field, tvb, offset, \
451                             length, ENC_BIG_ENDIAN);
452
453 #define SET_PACKET_TYPE(tree, type)                              \
454         proto_tree_add_int(tree, hf_adwin_packet_type, tvb, 0, tvb_length(tvb), type);
455
456
457 /* Initialize the protocol and registered fields */
458 static int proto_adwin                = -1;
459
460 static unsigned int global_adwin_udp_port = ADWIN_COMM_PORT;
461 static int global_adwin_dissect_data  = 1;
462
463 static int hf_adwin_address           = -1;
464 static int hf_adwin_armVersion        = -1;
465 static int hf_adwin_binfilesize       = -1;
466 static int hf_adwin_blocksize         = -1;
467 static int hf_adwin_count             = -1;
468 static int hf_adwin_complete_packets  = -1;
469 static int hf_adwin_data_int          = -1;
470 static int hf_adwin_data_float        = -1;
471 static int hf_adwin_data_hex          = -1;
472 static int hf_adwin_data_no16         = -1;
473 static int hf_adwin_data_no32         = -1;
474 static int hf_adwin_data_packet_index = -1;
475 static int hf_adwin_data_type         = -1;
476 static int hf_adwin_dll_version       = -1;
477 static int hf_adwin_fifo_no16         = -1;
478 static int hf_adwin_fifo_no32         = -1;
479 static int hf_adwin_instruction       = -1;
480 static int hf_adwin_is_range          = -1;
481 static int hf_adwin_i3plus1           = -1;
482 static int hf_adwin_link_addr         = -1;
483 static int hf_adwin_mem_type          = -1;
484 static int hf_adwin_memsize           = -1;
485 static int hf_adwin_osys              = -1;
486 static int hf_adwin_packet_index      = -1;
487 static int hf_adwin_packet_no         = -1;
488 static int hf_adwin_packet_start      = -1;
489 static int hf_adwin_packet_end        = -1;
490 static int hf_adwin_packet_type       = -1;
491 static int hf_adwin_parameter         = -1;
492 static int hf_adwin_password          = -1;
493 static int hf_adwin_process_no        = -1;
494 static int hf_adwin_processor         = -1;
495 static int hf_adwin_response_in       = -1;
496 static int hf_adwin_response_to       = -1;
497 static int hf_adwin_response_time     = -1;
498 static int hf_adwin_retry_packet_index= -1;
499 static int hf_adwin_request_no        = -1;
500 static int hf_adwin_start_index       = -1;
501 static int hf_adwin_status            = -1;
502 static int hf_adwin_timeout           = -1;
503 static int hf_adwin_unused            = -1;
504 static int hf_adwin_val1              = -1;
505 static int hf_adwin_val1f             = -1;
506 static int hf_adwin_val2              = -1;
507 static int hf_adwin_val3              = -1;
508 static int hf_adwin_val4              = -1;
509
510 /* Initialize the subtree pointers */
511 static gint ett_adwin                 = -1;
512 static gint ett_adwin_debug           = -1;
513
514 /* response/request tracking */
515 typedef struct _adwin_transaction_t {
516         guint32 req_frame;
517         guint32 rep_frame;
518         nstime_t req_time;
519 } adwin_transaction_t;
520
521 /* response/request tracking */
522 typedef struct _adwin_conv_info_t {
523         emem_tree_t *pdus;
524 } adwin_conv_info_t;
525
526 typedef enum { ADWIN_REQUEST,
527                ADWIN_RESPONSE
528 } adwin_direction_t;
529
530 static void
531 adwin_request_response_handling(tvbuff_t *tvb, packet_info *pinfo,
532                                 proto_tree *adwin_tree, guint32 seq_num, adwin_direction_t direction)
533 {
534         conversation_t *conversation;
535         adwin_conv_info_t *adwin_info;
536         adwin_transaction_t *adwin_trans;
537
538         /*
539          * Find or create a conversation for this connection.
540          */
541         conversation = find_or_create_conversation(pinfo);
542
543         /*
544          * Do we already have a state structure for this conv
545          */
546         adwin_info = conversation_get_proto_data(conversation, proto_adwin);
547         if (!adwin_info) {
548                 /*
549                  * No.  Attach that information to the conversation, and add
550                  * it to the list of information structures.
551                  */
552                 adwin_info = se_alloc(sizeof(adwin_conv_info_t));
553                 adwin_info->pdus = se_tree_create_non_persistent(
554                                         EMEM_TREE_TYPE_RED_BLACK, "adwin_pdus");
555
556                 conversation_add_proto_data(conversation, proto_adwin, adwin_info);
557         }
558         if (!pinfo->fd->flags.visited) {
559                 if (direction == ADWIN_REQUEST) {
560                         /* This is a request */
561                         adwin_trans = se_alloc(sizeof(adwin_transaction_t));
562                         adwin_trans->req_frame = pinfo->fd->num;
563                         adwin_trans->rep_frame = 0;
564                         adwin_trans->req_time = pinfo->fd->abs_ts;
565                         se_tree_insert32(adwin_info->pdus, seq_num, (void *)adwin_trans);
566                 } else {
567                         adwin_trans = se_tree_lookup32(adwin_info->pdus, seq_num);
568                         if (adwin_trans) {
569                                 adwin_trans->rep_frame = pinfo->fd->num;
570                         }
571                 }
572         } else {
573                 adwin_trans = se_tree_lookup32(adwin_info->pdus, seq_num);
574         }
575         if (!adwin_trans) {
576                 /* create a "fake" adwin_trans structure */
577                 adwin_trans = ep_alloc(sizeof(adwin_transaction_t));
578                 adwin_trans->req_frame = 0;
579                 adwin_trans->rep_frame = 0;
580                 adwin_trans->req_time = pinfo->fd->abs_ts;
581         }
582
583         /* print state tracking in the tree */
584         if (direction == ADWIN_REQUEST) {
585                 /* This is a request */
586                 if (adwin_trans->rep_frame) {
587                         proto_item *it;
588
589                         it = proto_tree_add_uint(adwin_tree, hf_adwin_response_in,
590                                         tvb, 0, 0, adwin_trans->rep_frame);
591                         PROTO_ITEM_SET_GENERATED(it);
592                 }
593         } else {
594                 /* This is a reply */
595                 if (adwin_trans->req_frame) {
596                         proto_item *it;
597                         nstime_t ns;
598
599                         it = proto_tree_add_uint(adwin_tree, hf_adwin_response_to,
600                                         tvb, 0, 0, adwin_trans->req_frame);
601                         PROTO_ITEM_SET_GENERATED(it);
602
603                         nstime_delta(&ns, &pinfo->fd->abs_ts, &adwin_trans->req_time);
604                         it = proto_tree_add_time(adwin_tree, hf_adwin_response_time, tvb, 0, 0, &ns);
605                         PROTO_ITEM_SET_GENERATED(it);
606                 }
607         }
608 }
609
610 static void
611 dissect_UDPH1_generic(tvbuff_t *tvb, packet_info *pinfo,
612                       proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string, gchar* packet_name)
613 {
614         guint32 i3plus1code =  0, instructionID, seq_num;
615
616         instructionID = tvb_get_letohl(tvb, 0);
617         *info_string = ep_strdup_printf("%s: %s", packet_name,
618                                         val_to_str_ext(instructionID, &instruction_mapping_ext, "unknown instruction: %d"));
619
620         if (instructionID == I_3PLUS1) {
621                 gchar *tmp = *info_string;
622
623                 i3plus1code = tvb_get_letohl(tvb, 20);
624                 *info_string = ep_strdup_printf("%s: %s", tmp, val_to_str_ext(i3plus1code, &instruction_3plus1_mapping_ext, "unknown 3+1 code: %d"));
625         }
626
627         /* Get the transaction identifier */
628         seq_num = tvb_get_letohl(tvb, 4);
629         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_REQUEST);
630
631         if (! adwin_tree)
632                 return;
633
634         SET_PACKET_TYPE(adwin_tree, APT_UDPH1_old);
635
636         ADWIN_ADD_LE(adwin_tree, instruction,          0,  4);
637         ADWIN_ADD_LE(adwin_tree, packet_index,         4,  4);
638         ADWIN_ADD_BE(adwin_tree, password,             8, 10);
639         ADWIN_ADD_LE(adwin_debug_tree, unused,        18,  2);
640
641         switch(instructionID) {
642         case I_3PLUS1:
643                 ADWIN_ADD_LE(adwin_tree, i3plus1,      20,  4);
644                 switch (i3plus1code) {
645                 case I_3P1_SET_PAR:
646                         ADWIN_ADD_LE(adwin_tree, parameter,     24,  4);
647                         ADWIN_ADD_LE(adwin_tree, val1,          28,  4);
648                         ADWIN_ADD_LE(adwin_tree, val1f,         28,  4);
649                         ADWIN_ADD_LE(adwin_debug_tree, unused,  32,  4);
650                         break;
651                 case I_3P1_GET_PAR:
652                         ADWIN_ADD_LE(adwin_tree, parameter,     24,  4);
653                         ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
654                         break;
655                 case I_3P1_GET_MEMORY_INFO:
656                 case I_3P1_GET_DETAILED_MEM_INFO:
657                         ADWIN_ADD_LE(adwin_tree, mem_type,      24,  4);
658                         ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
659                         break;
660                 case I_3P1_START:
661                 case I_3P1_STOP:
662                 case I_3P1_CLEAR_PROCESS:
663                         ADWIN_ADD_LE(adwin_tree, process_no,    24,  4);
664                         ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
665                         break;
666                 case I_3P1_GET_DATA_LENGTH:
667                         ADWIN_ADD_LE(adwin_tree, data_no32,     24,  4);
668                         ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
669                         break;
670                 case I_3P1_CLEAR_FIFO:
671                 case I_3P1_GET_FIFO_EMPTY:
672                 case I_3P1_GET_FIFO_COUNT:
673                         ADWIN_ADD_LE(adwin_tree, fifo_no32,     24,  4);
674                         ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
675                         break;
676                 default: ; /* should not happen */
677                         /* illegal values should be displayed properly
678                            by 3plus1_mapping */
679                 }
680                 break;
681         case I_BOOT:
682                 ADWIN_ADD_LE(adwin_tree, memsize,       20,  4);
683                 ADWIN_ADD_LE(adwin_tree, blocksize,     24,  2);
684                 ADWIN_ADD_LE(adwin_debug_tree, unused,  26,  2);
685                 ADWIN_ADD_LE(adwin_tree, processor,     28,  4);
686                 ADWIN_ADD_LE(adwin_tree, binfilesize,   32,  4);
687                 break;
688         case I_LOAD_BIN_FILE:
689                 ADWIN_ADD_LE(adwin_debug_tree, unused,  20,  6);
690                 ADWIN_ADD_LE(adwin_tree, blocksize,     26,  2);
691                 ADWIN_ADD_LE(adwin_tree, processor,     28,  4);
692                 ADWIN_ADD_LE(adwin_tree, binfilesize,   32,  4);
693                 break;
694         case I_GET_WORKLOAD:
695                 ADWIN_ADD_LE(adwin_tree, instruction,   20,  4);
696                 ADWIN_ADD_LE(adwin_debug_tree, unused,  24, 12);
697                 break;
698         case I_GET_DATA_TYPE:
699                 ADWIN_ADD_LE(adwin_debug_tree, unused,  20,  4);
700                 ADWIN_ADD_LE(adwin_tree, data_no32,     24,  4);
701                 ADWIN_ADD_LE(adwin_tree, start_index,   28,  4);
702                 ADWIN_ADD_LE(adwin_debug_tree, unused,  32,  4);
703                 break;
704         case I_GET_DATA:
705         case I_SET_DATA:
706                 ADWIN_ADD_LE(adwin_tree, data_type,     20,  4);
707                 ADWIN_ADD_LE(adwin_tree, data_no16,     24,  2);
708                 ADWIN_ADD_LE(adwin_tree, blocksize,     26,  2);
709                 ADWIN_ADD_LE(adwin_tree, start_index,   28,  4);
710                 ADWIN_ADD_LE(adwin_tree, count,         32,  4);
711                 break;
712         case I_GET_DATA_SHIFTED_HANDSHAKE:
713                 ADWIN_ADD_BE(adwin_tree, data_no16,     20,  2);
714                 ADWIN_ADD_BE(adwin_tree, blocksize,     22,  2);
715                 ADWIN_ADD_BE(adwin_tree, start_index,   24,  4);
716                 ADWIN_ADD_BE(adwin_tree, count,         28,  4);
717                 ADWIN_ADD_BE(adwin_debug_tree, unused,  32,  4);
718                 break;
719         case I_GET_DATA_SMALL:
720                 ADWIN_ADD_LE(adwin_debug_tree, unused,  20,  4);
721                 ADWIN_ADD_LE(adwin_tree, data_no16,     24,  2);
722                 ADWIN_ADD_LE(adwin_debug_tree, unused,  26,  2);
723                 ADWIN_ADD_LE(adwin_tree, start_index,   28,  4);
724                 ADWIN_ADD_LE(adwin_tree, count,         32,  4);
725                 break;
726         case I_GET_PAR_ALL:
727                 ADWIN_ADD_LE(adwin_tree, start_index,   20,  4);
728                 ADWIN_ADD_LE(adwin_tree, count,         24,  4);
729                 ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
730                 break;
731         case I_SET_DATA_LAST_STATUS:
732                 ADWIN_ADD_LE(adwin_tree, data_packet_index, 20,  4);
733                 ADWIN_ADD_LE(adwin_debug_tree, unused,  24,  12);
734                 break;
735         case I_GET_ARM_VERSION:
736                 ADWIN_ADD_LE(adwin_tree, armVersion,  20,  4);
737                 ADWIN_ADD_LE(adwin_debug_tree, unused,24, 12);
738                 break;
739         case I_GET_FIFO:
740         case I_SET_FIFO:
741                 ADWIN_ADD_LE(adwin_tree, data_type,     20,  4);
742                 ADWIN_ADD_LE(adwin_tree, fifo_no16,     24,  2);
743                 ADWIN_ADD_LE(adwin_debug_tree, unused,  26,  6);
744                 ADWIN_ADD_LE(adwin_tree, count,         32,  4);
745                 break;
746         case I_GET_FIFO_RETRY:
747         case I_SET_FIFO_RETRY:
748                 ADWIN_ADD_LE(adwin_tree, data_type,     20,  4);
749                 ADWIN_ADD_LE(adwin_tree, fifo_no16,     24,  2);
750                 ADWIN_ADD_LE(adwin_debug_tree, unused,  26,  2);
751                 ADWIN_ADD_LE(adwin_tree, retry_packet_index, 28,  4);
752                 ADWIN_ADD_LE(adwin_tree, count,         32,  4);
753                 break;
754         case I_TEST_VERSION:
755                 ADWIN_ADD_LE(adwin_debug_tree, unused,  20,  16);
756                 break;
757         case I_GET_MEMORY:
758                 ADWIN_ADD_LE(adwin_tree, address,       20,  4);
759                 ADWIN_ADD_LE(adwin_tree, count,         24,  4);
760                 ADWIN_ADD_LE(adwin_debug_tree, unused,  28,  8);
761                 break;
762         default: ; /* should not happen */
763                 /* illegal values should be displayed properly by
764                    instruction_mapping */
765         }
766
767         ADWIN_ADD_LE(adwin_debug_tree, link_addr,36,  4);
768         ADWIN_ADD_LE(adwin_tree, timeout,        40,  4);
769         ADWIN_ADD_LE(adwin_debug_tree, osys,     44,  4);
770         ADWIN_ADD_LE(adwin_debug_tree, unused,   48,  4);
771
772 }
773
774
775 static void
776 dissect_UDPH1_old(tvbuff_t *tvb, packet_info *pinfo,
777                   proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string)
778 {
779         dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (old)");
780 }
781
782 static void
783 dissect_UDPH1_new(tvbuff_t *tvb, packet_info *pinfo,
784                   proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
785                   gchar** info_string)
786 {
787         gchar* dll_version_s;
788         gint32 dll_i;
789
790         dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (new)");
791
792         if (! adwin_tree)
793                 return;
794
795         SET_PACKET_TYPE(adwin_tree, APT_UDPH1_new);
796         dll_i = tvb_get_letohl(tvb, 52);
797         dll_version_s = ep_strdup_printf("%d.%d.%d",
798                                         dll_i / 1000000,
799                                         (dll_i - dll_i / 1000000 * 1000000) / 1000,
800                                         dll_i % 1000);
801
802         proto_tree_add_string(adwin_debug_tree, hf_adwin_dll_version,
803                               tvb, 52, 4, dll_version_s);
804 }
805
806 static void
807 dissect_UDPR1(tvbuff_t *tvb, packet_info *pinfo,
808               proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
809               gchar** info_string)
810 {
811         const gchar *status_string;
812         guint32 seq_num, status;
813
814         status = tvb_get_letohl(tvb, 0);
815         status_string = match_strval_ext(status, &error_code_mapping_ext);
816         if (status_string) {
817                 *info_string = ep_strdup_printf("UDPR1 Status: %s", status_string);
818         } else {
819                 *info_string = ep_strdup_printf("UDPR1 Undefined error code %d", status);
820         }
821
822         /* Get the transaction identifier */
823         seq_num = tvb_get_letohl(tvb, 4);
824         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
825
826         if (! adwin_tree)
827                 return;
828
829         SET_PACKET_TYPE(adwin_tree, APT_UDPR1);
830         ADWIN_ADD_LE(adwin_tree, status,         0,  4);
831         ADWIN_ADD_LE(adwin_tree, packet_index,   4,  4);
832         ADWIN_ADD_LE(adwin_tree, val1,           8,  4);
833         ADWIN_ADD_LE(adwin_tree, val1f,          8,  4);
834         ADWIN_ADD_LE(adwin_tree, val2,          12,  4);
835         ADWIN_ADD_LE(adwin_tree, val3,          16,  4);
836         ADWIN_ADD_LE(adwin_tree, val4,          20,  4);
837         ADWIN_ADD_LE(adwin_debug_tree, unused,  24,  8);
838 }
839
840 static void
841 dissect_UDPR2(tvbuff_t *tvb, packet_info *pinfo,
842               proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
843               gchar** info_string)
844 {
845         const gchar *status_string;
846         guint32 i, status, seq_num;
847
848         status = tvb_get_letohl(tvb, 0);
849         status_string = match_strval_ext(status, &error_code_mapping_ext);
850         if (status_string) {
851                 *info_string = ep_strdup_printf("UDPR2 Status: %s", status_string);
852         } else {
853                 *info_string = ep_strdup_printf("UDPR2 Undefined error code %d", status);
854         }
855
856         /* Get the transaction identifier */
857         seq_num = tvb_get_letohl(tvb, 4);
858         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
859
860         if (! adwin_tree)
861                 return;
862
863         SET_PACKET_TYPE(adwin_tree, APT_UDPR2);
864         ADWIN_ADD_LE(adwin_tree, status,         0,  4);
865         ADWIN_ADD_LE(adwin_tree, packet_index,   4,  4);
866
867         if (! global_adwin_dissect_data) {
868                 proto_tree_add_text(adwin_debug_tree, tvb, 8, 250 * 4, "Data");
869                 return;
870         }
871
872         for (i = 0; i < 250; i++) {
873                 proto_item *item;
874                 guint32 offset = 8 + i * sizeof(guint32);
875                 gint32 value = tvb_get_letohl(tvb, offset);
876                 void * fvalue = &value;
877                 proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
878                                     "Data[%3d]: %10d - %10f - 0x%08x",
879                                     i, value, *(float*)fvalue, value);
880                 item = ADWIN_ADD_LE(adwin_debug_tree, data_int,   offset, 4);
881                 PROTO_ITEM_SET_HIDDEN(item);
882                 item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
883                 PROTO_ITEM_SET_HIDDEN(item);
884                 item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
885                 PROTO_ITEM_SET_HIDDEN(item);
886         }
887 }
888
889 static void
890 dissect_UDPR3(tvbuff_t *tvb, packet_info *pinfo,
891               proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
892 {
893         guint32 i, seq_num;
894
895         /* Get the transaction identifier */
896         seq_num = tvb_get_letohl(tvb, 0);
897         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
898
899         if (! adwin_tree)
900                 return;
901
902         SET_PACKET_TYPE(adwin_tree, APT_UDPR3);
903         ADWIN_ADD_LE(adwin_tree, packet_index,   0,  4);
904         ADWIN_ADD_LE(adwin_tree, packet_no,      4,  4);
905
906         if (! global_adwin_dissect_data) {
907                 proto_tree_add_text(adwin_debug_tree, tvb, 8, 350 * 4, "Data");
908                 return;
909         }
910
911         for (i = 0; i < 350; i++) {
912                 proto_item *item;
913                 guint32 offset = 8 + i * sizeof(guint32);
914                 gint32 value = tvb_get_letohl(tvb, offset);
915                 void * fvalue = &value;
916                 proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
917                                     "Data[%3d]: %10d - %10f - 0x%08x",
918                                     i, value, *(float*)fvalue, value);
919                 item = ADWIN_ADD_LE(adwin_debug_tree, data_int,   offset, 4);
920                 PROTO_ITEM_SET_HIDDEN(item);
921                 item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
922                 PROTO_ITEM_SET_HIDDEN(item);
923                 item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
924                 PROTO_ITEM_SET_HIDDEN(item);
925         }
926 }
927
928 static void
929 dissect_UDPR4(tvbuff_t *tvb, packet_info *pinfo,
930               proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string)
931 {
932         const gchar *status_string;
933         guint32 data_type, i, status, seq_num;
934
935         status = tvb_get_letohl(tvb, 0);
936         status_string = match_strval_ext(status, &error_code_mapping_ext);
937         if (status_string) {
938                 *info_string = ep_strdup_printf("UDPR4 Status: %s", status_string);
939         } else {
940                 *info_string = ep_strdup_printf("UDPR4 Undefined error code %d", status);
941         }
942
943         /* Get the transaction identifier */
944         seq_num = tvb_get_letohl(tvb, 4);
945         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
946
947         if (! adwin_tree)
948                 return;
949
950         SET_PACKET_TYPE(adwin_tree, APT_UDPR4);
951         ADWIN_ADD_LE(adwin_tree, status,         0,  4);
952         ADWIN_ADD_LE(adwin_tree, packet_index,   4,  4);
953         ADWIN_ADD_LE(adwin_tree, packet_no,      1408,  4);
954         ADWIN_ADD_LE(adwin_tree, data_type,      1412,  4);
955
956         data_type = tvb_get_letohl(tvb, 1412);
957
958         if (! global_adwin_dissect_data) {
959                 proto_tree_add_text(adwin_debug_tree, tvb, 8, 350 * 4, "Data");
960                 return;
961         }
962
963         for (i = 0; i < 350; i++) {
964                 proto_item *item;
965                 guint32 offset = 8 + i * sizeof(guint32);
966                 gint32 value = tvb_get_letohl(tvb, offset);
967                 void * fvalue = &value;
968                 switch (data_type) {
969                 case 2:
970                 case 3:
971                 case 4:  /* some kind of int, usually int/long */
972                         proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
973                                             "Data[%3d]: %10d - 0x%08x",
974                                             i, value, value);
975                         item = ADWIN_ADD_LE(adwin_debug_tree, data_int,   offset, 4);
976                         PROTO_ITEM_SET_HIDDEN(item);
977                         item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
978                         PROTO_ITEM_SET_HIDDEN(item);
979                         break;
980                 case 5: /* float */
981                         proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
982                                             "Data[%3d]: %10f - 0x%08x",
983                                             i, *(float*)fvalue, value);
984                         item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
985                         PROTO_ITEM_SET_HIDDEN(item);
986                         item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
987                         PROTO_ITEM_SET_HIDDEN(item);
988                         break;
989                 default: /* string, double, variant, something funny... */
990                         proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
991                                             "Data[%3d]: 0x%08x",
992                                             i, value);
993                         item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
994                         PROTO_ITEM_SET_HIDDEN(item);
995                 }
996         }
997 }
998
999 static void
1000 dissect_GDSHP(tvbuff_t *tvb, packet_info *pinfo,
1001               proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
1002 {
1003         guint32 i, seq_num;
1004
1005         /* Get the transaction identifier */
1006         seq_num = tvb_get_ntohl(tvb, 0);
1007         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
1008
1009         if (! adwin_tree)
1010                 return;
1011
1012         SET_PACKET_TYPE(adwin_tree, APT_GDSHP);
1013         ADWIN_ADD_BE(adwin_tree, packet_index,   0,  4);
1014         ADWIN_ADD_BE(adwin_tree, packet_no,      4,  4);
1015         ADWIN_ADD_BE(adwin_tree, unused,         8,  4);
1016
1017         if (! global_adwin_dissect_data) {
1018                 proto_tree_add_text(adwin_debug_tree, tvb, 12, 336 * 4, "Data");
1019                 return;
1020         }
1021
1022         for (i = 0; i < 336; i++) {
1023                 proto_item *item;
1024                 guint32 offset = 12 + i * sizeof(guint32);
1025                 gint32 value = tvb_get_letohl(tvb, offset);
1026                 void * fvalue = &value;
1027                 proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
1028                                     "Data[%3d]: %10d - %10f - 0x%08x",
1029                                     i, value, *(float*)fvalue, value);
1030                 item = ADWIN_ADD_LE(adwin_debug_tree, data_int,   offset, 4);
1031                 PROTO_ITEM_SET_HIDDEN(item);
1032                 item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
1033                 PROTO_ITEM_SET_HIDDEN(item);
1034                 item = ADWIN_ADD_LE(adwin_debug_tree, data_hex,   offset, 4);
1035                 PROTO_ITEM_SET_HIDDEN(item);
1036         }
1037 }
1038
1039 static void
1040 dissect_GDSHR(tvbuff_t *tvb, packet_info *pinfo,
1041               proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
1042 {
1043         guint32 is_range, packet_start, packet_end, seq_num;
1044
1045         /* Get the transaction identifier */
1046         seq_num = tvb_get_ntohl(tvb, 0);
1047         adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
1048
1049         if (! adwin_tree)
1050                 return;
1051
1052         SET_PACKET_TYPE(adwin_tree, APT_GDSHR);
1053         ADWIN_ADD_BE(adwin_tree, packet_index,        0,  4);
1054         ADWIN_ADD_BE(adwin_tree, request_no,          4,  4);
1055         ADWIN_ADD_BE(adwin_tree, complete_packets,    8,  4);
1056         ADWIN_ADD_BE(adwin_debug_tree, is_range,     12,  4);
1057         ADWIN_ADD_BE(adwin_debug_tree, packet_start, 16,  4);
1058         ADWIN_ADD_BE(adwin_debug_tree, packet_end,   20,  4);
1059
1060         is_range = tvb_get_ntohl(tvb, 12);
1061         packet_start = tvb_get_ntohl(tvb, 16);
1062
1063         switch(is_range) {
1064         case 0: proto_tree_add_text(adwin_tree, tvb, 12, 12,
1065                                     "GDSH status: get single packet no %d",
1066                                     packet_start);
1067                 break;
1068         case 1: packet_end = tvb_get_ntohl(tvb, 20);
1069                 proto_tree_add_text(adwin_tree, tvb, 12, 12,
1070                                     "GDSH status: get packets %d - %d",
1071                                     packet_start, packet_end);
1072                 break;
1073         case 2: proto_tree_add_text(adwin_tree, tvb, 12, 12,
1074                                     "GDSH status: finished");
1075                 break;
1076         default: /* should not happen */
1077                 proto_tree_add_text(adwin_tree, tvb, 12, 12,
1078                                     "GDSH status: unknown code %d", is_range);
1079         }
1080         ADWIN_ADD_BE(adwin_debug_tree, unused,       24, 40);
1081 }
1082
1083 /* here we determine which type of packet is sent by looking at its
1084    size. That is safe since the main server application that processes
1085    these packets does it this way, too.
1086
1087    Depending on the packet type, the appropriate dissector is
1088    called. */
1089
1090 static int
1091 dissect_adwin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1092 {
1093         proto_item *ti, *ti2;
1094         proto_tree *adwin_tree, *adwin_debug_tree;
1095         gchar *info_string;
1096         guint32 length;
1097
1098         length = tvb_reported_length(tvb);
1099
1100         /* First do some heuristics to see if this packet belongs to us */
1101         if(! (length == UDPH1_OLD_LENGTH
1102               || length == UDPH1_NEW_LENGTH
1103               || length == UDPR1_LENGTH
1104               || length == UDPH2_LENGTH
1105               || length == UDPR2_LENGTH
1106               || length == UDPR3_LENGTH
1107               || length == UDPR4_LENGTH
1108               || length == GetDataSHPacket_LENGTH
1109               || length == GetDataSHRequest_LENGTH))
1110                 return(0);
1111
1112         col_set_str(pinfo->cinfo, COL_PROTOCOL, "ADwin");
1113         col_clear(pinfo->cinfo, COL_INFO);
1114
1115         if (tree) {
1116                 ti = proto_tree_add_item(tree, proto_adwin, tvb, 0, -1, ENC_NA);
1117                 adwin_tree = proto_item_add_subtree(ti, ett_adwin);
1118
1119                 ti2 = proto_tree_add_item(adwin_tree, proto_adwin, tvb, 0, -1, ENC_NA);
1120                 adwin_debug_tree = proto_item_add_subtree(ti2, ett_adwin_debug);
1121                 proto_item_set_text(ti2, "ADwin Debug information");
1122         } else {
1123                 adwin_tree = NULL;
1124                 adwin_debug_tree = NULL;
1125         }
1126
1127         switch (length) {
1128         case UDPH1_OLD_LENGTH:
1129                 dissect_UDPH1_old(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
1130                 break;
1131         case UDPH1_NEW_LENGTH:
1132                 dissect_UDPH1_new(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
1133                 break;
1134         case UDPR1_LENGTH:
1135                 dissect_UDPR1(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
1136                 break;
1137         case UDPH2_LENGTH: /* to the best of my knowledge, this struct
1138                             * has never been used publically! */
1139                 /* dissect_UDPH2(tvb, pinfo, adwin_tree, adwin_debug_tree); */
1140                 info_string = ep_strdup("UDPH2 - UNUSED");
1141                 break;
1142         case UDPR2_LENGTH:
1143                 dissect_UDPR2(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
1144                 break;
1145         case UDPR3_LENGTH:
1146                 dissect_UDPR3(tvb, pinfo, adwin_tree, adwin_debug_tree);
1147                 info_string = ep_strdup("UDPR3");
1148                 break;
1149         case UDPR4_LENGTH:
1150                 dissect_UDPR4(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
1151                 break;
1152         case GetDataSHPacket_LENGTH:
1153                 dissect_GDSHP(tvb, pinfo, adwin_tree, adwin_debug_tree);
1154                 info_string = ep_strdup("GDSHP");
1155                 break;
1156         case GetDataSHRequest_LENGTH:
1157                 dissect_GDSHR(tvb, pinfo, adwin_tree, adwin_debug_tree);
1158                 info_string = ep_strdup("GDSHR");
1159                 break;
1160         default:
1161                 info_string = ep_strdup_printf("Unknown ADwin packet, length: %d", length);
1162                 break;
1163         }
1164
1165         col_add_str(pinfo->cinfo, COL_INFO, info_string);
1166
1167         return (tvb_reported_length(tvb));
1168 }
1169
1170 void proto_reg_handoff_adwin(void);
1171
1172 void
1173 proto_register_adwin(void)
1174 {
1175         static hf_register_info hf[] = {
1176                 { &hf_adwin_address,
1177                   { "memory address", "adwin.address",
1178                     FT_UINT32, BASE_HEX, NULL, 0x0,
1179                     "Memory address to read on DSP", HFILL }
1180                 },
1181                 { &hf_adwin_armVersion,
1182                   { "Get ARM Version", "adwin.armVersion",
1183                     FT_UINT32, BASE_DEC, NULL, 0x0,
1184                     NULL, HFILL }
1185                 },
1186                 { &hf_adwin_binfilesize,
1187                   { "File size", "adwin.binfilesize",
1188                     FT_UINT32, BASE_DEC, NULL, 0x0,
1189                     "Size of binary file", HFILL }
1190                 },
1191                 { &hf_adwin_blocksize,
1192                   { "Blocksize", "adwin.blocksize",
1193                     FT_UINT32, BASE_DEC, NULL, 0x0,
1194                     "Maximum number of unacknowledged packets", HFILL }
1195                 },
1196                 { &hf_adwin_complete_packets,
1197                   { "Complete packets", "adwin.complete_packets",
1198                     FT_UINT32, BASE_DEC, NULL, 0x0,
1199                     "Highest sequential package number", HFILL }
1200                 },
1201                 { &hf_adwin_count,
1202                   { "Count", "adwin.count",
1203                     FT_UINT32, BASE_DEC, NULL, 0x0,
1204                     "Number of longs", HFILL }
1205                 },
1206                 { &hf_adwin_data_int,
1207                   { "Data element int", "adwin.data_int",
1208                     FT_INT32, BASE_DEC, NULL, 0x0,
1209                     NULL, HFILL }
1210                 },
1211                 { &hf_adwin_data_float,
1212                   { "Data element float", "adwin.data_float",
1213                     FT_FLOAT, BASE_NONE, NULL, 0x0,
1214                     NULL, HFILL }
1215                 },
1216                 { &hf_adwin_data_hex,
1217                   { "Data element hex", "adwin.data_hex",
1218                     FT_UINT32, BASE_HEX, NULL, 0x0,
1219                     NULL, HFILL }
1220                 },
1221                 { &hf_adwin_data_no16,
1222                   { "Data No. (16bit)", "adwin.data",
1223                     FT_UINT16, BASE_DEC, NULL, 0x0,
1224                     NULL, HFILL }
1225                 },
1226                 { &hf_adwin_data_no32,
1227                   { "Data No. (32bit)", "adwin.data",
1228                     FT_UINT32, BASE_DEC, NULL, 0x0,
1229                     NULL, HFILL }
1230                 },
1231                 { &hf_adwin_data_type,
1232                   { "Data type", "adwin.data_type",
1233                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &data_type_mapping_ext, 0x0,
1234                     NULL, HFILL }
1235                 },
1236                 { &hf_adwin_data_packet_index,
1237                   { "Data packet index", "adwin.data_packet_index",
1238                     FT_UINT32, BASE_DEC, NULL, 0x0,
1239                     NULL, HFILL }
1240                 },
1241                 { &hf_adwin_dll_version,
1242                   { "DLL Version", "adwin.dll_version",
1243                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1244                     NULL, HFILL }
1245                 },
1246                 { &hf_adwin_fifo_no16,
1247                   { "FiFo No. (16bit)", "adwin.fifo_no",
1248                     FT_UINT32, BASE_DEC, NULL, 0x0,
1249                     NULL, HFILL }
1250                 },
1251                 { &hf_adwin_fifo_no32,
1252                   { "FiFo No. (32bit)", "adwin.fifo_no",
1253                     FT_UINT32, BASE_DEC, NULL, 0x0,
1254                     NULL, HFILL }
1255                 },
1256                 { &hf_adwin_instruction,
1257                   { "Instruction", "adwin.instruction",
1258                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &instruction_mapping_ext, 0x0,
1259                     NULL, HFILL }
1260                 },
1261                 { &hf_adwin_is_range,
1262                   { "packets are a range", "adwin.is_range",
1263                     FT_UINT32, BASE_DEC, NULL, 0x0,
1264                     NULL, HFILL }
1265                 },
1266                 { &hf_adwin_i3plus1,
1267                   { "3+1 Instruction", "adwin.i3plus1",
1268                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &instruction_3plus1_mapping_ext, 0x0,
1269                     NULL, HFILL }
1270                 },
1271                 { &hf_adwin_link_addr,
1272                   { "Link address", "adwin.link_addr",
1273                     FT_UINT32, BASE_HEX, NULL, 0x0,
1274                     "Link address (TCP/IP Server only)", HFILL }
1275                 },
1276                 { &hf_adwin_mem_type,
1277                   { "Memory type", "adwin.mem_type",
1278                     FT_UINT32, BASE_DEC, NULL, 0x0,
1279                     NULL, HFILL }
1280                 },
1281                 { &hf_adwin_memsize,
1282                   { "Memory size", "adwin.memsize",
1283                     FT_UINT32, BASE_DEC, NULL, 0x0,
1284                     NULL, HFILL }
1285                 },
1286                 { &hf_adwin_osys,
1287                   { "Operating system", "adwin.osys",
1288                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &osys_mapping_ext, 0x0,
1289                     "Operating system / environment", HFILL }
1290                 },
1291                 { &hf_adwin_packet_end,
1292                   { "End packet", "adwin.packet_end",
1293                     FT_UINT32, BASE_DEC, NULL, 0x0,
1294                     "GDSH: End Packet", HFILL }
1295                 },
1296                 { &hf_adwin_packet_index,
1297                   { "Packet index", "adwin.packet_index",
1298                     FT_UINT32, BASE_DEC, NULL, 0x0,
1299                     NULL, HFILL }
1300                 },
1301                 { &hf_adwin_packet_no,
1302                   { "Packet No.", "adwin.packet_no",
1303                     FT_UINT32, BASE_DEC, NULL, 0x0,
1304                     NULL, HFILL }
1305                 },
1306                 { &hf_adwin_packet_start,
1307                   { "Starting packet", "adwin.packet_start",
1308                     FT_UINT32, BASE_DEC, NULL, 0x0,
1309                     "GDSH: Starting Packet", HFILL }
1310                 },
1311                 { &hf_adwin_packet_type,
1312                   { "Packet type", "adwin.packet_type",
1313                     FT_INT32, BASE_DEC|BASE_EXT_STRING, &packet_type_mapping_ext, 0x0,
1314                     NULL, HFILL }
1315                 },
1316                 { &hf_adwin_parameter,
1317                   { "Parameter", "adwin.parameter",
1318                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &parameter_mapping_ext, 0x0,
1319                     NULL, HFILL }
1320                 },
1321                 { &hf_adwin_password,
1322                   { "Password", "adwin.password",
1323                     FT_STRING, BASE_NONE, NULL, 0x0,
1324                     "Password for ADwin system", HFILL }
1325                 },
1326                 { &hf_adwin_process_no,
1327                   { "Process No.", "adwin.process_no",
1328                     FT_UINT32, BASE_DEC, NULL, 0x0,
1329                     NULL, HFILL }
1330                 },
1331                 { &hf_adwin_processor,
1332                   { "Processor", "adwin.processor",
1333                     FT_UINT32, BASE_DEC, NULL, 0x0,
1334                     NULL, HFILL }
1335                 },
1336                 { &hf_adwin_response_in,
1337                   { "Response In", "adwin.response_in",
1338                     FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1339                     "The response to this ADwin request is in this frame", HFILL }
1340                 },
1341                 { &hf_adwin_response_to,
1342                   { "Request In", "adwin.response_to",
1343                     FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1344                     "This is a response to the ADwin request in this frame", HFILL }
1345                 },
1346                 { &hf_adwin_response_time,
1347                   { "Response time", "adwin.response_time",
1348                     FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1349                     "The time between the Request and the Reply", HFILL }
1350                 },
1351                 { &hf_adwin_retry_packet_index,
1352                   { "Retry packet index", "adwin.retry_packet_index",
1353                     FT_UINT32, BASE_DEC, NULL, 0x0,
1354                     NULL, HFILL }
1355                 },
1356                 { &hf_adwin_request_no,
1357                   { "Request Number", "adwin.request_no",
1358                     FT_UINT32, BASE_DEC, NULL, 0x0,
1359                     "Request number index", HFILL }
1360                 },
1361                 { &hf_adwin_start_index,
1362                   { "Start index", "adwin.start_index",
1363                     FT_UINT32, BASE_DEC, NULL, 0x0,
1364                     NULL, HFILL }
1365                 },
1366                 { &hf_adwin_status,
1367                   { "Status", "adwin.status",
1368                     FT_INT32, BASE_DEC|BASE_EXT_STRING, &error_code_mapping_ext, 0x0,
1369                     NULL, HFILL }
1370                 },
1371                 { &hf_adwin_timeout,
1372                   { "Timeout", "adwin.timeout",
1373                     FT_UINT32, BASE_DEC, NULL, 0x0,
1374                     "Timeout in ms", HFILL }
1375                 },
1376                 { &hf_adwin_unused,
1377                   { "Unused", "adwin.unused",
1378                     FT_NONE, BASE_NONE, NULL, 0x0,
1379                     NULL, HFILL }
1380                 },
1381                 { &hf_adwin_val1,
1382                   { "Value 1 (as int)", "adwin.val1",
1383                     FT_INT32, BASE_DEC, NULL, 0x0,
1384                     "Generic return value 1 interpreted as integer (correct interpretation depends on request).", HFILL }
1385                 },
1386                 { &hf_adwin_val1f,
1387                   { "Value 1 (as float)", "adwin.val1f",
1388                     FT_FLOAT, BASE_NONE, NULL, 0x0,
1389                     "Generic return value 1 interpreted as float (correct interpretation depends on request).", HFILL }
1390                 },
1391                 { &hf_adwin_val2,
1392                   { "Value 2", "adwin.val2",
1393                     FT_INT32, BASE_DEC, NULL, 0x0,
1394                     "Generic return value 2 (interpretation depends on request).", HFILL }
1395                 },
1396                 { &hf_adwin_val3,
1397                   { "Value 3", "adwin.val3",
1398                     FT_INT32, BASE_DEC, NULL, 0x0,
1399                     "Generic return value 3 (interpretation depends on request).", HFILL }
1400                 },
1401                 { &hf_adwin_val4,
1402                   { "Value 4", "adwin.val4",
1403                     FT_INT32, BASE_DEC, NULL, 0x0,
1404                     "Generic return value 4 (interpretation depends on request).", HFILL }
1405                 },
1406         };
1407
1408         /* Setup protocol subtree array */
1409         static gint *ett[] = {
1410                 &ett_adwin,
1411                 &ett_adwin_debug,
1412         };
1413         module_t *adwin_module;
1414
1415         /* Register the protocol name and description */
1416         proto_adwin = proto_register_protocol("ADwin communication protocol",
1417                                               "ADwin", "adwin");
1418
1419         /* Required function calls to register the header fields and
1420            subtrees used */
1421         proto_register_field_array(proto_adwin, hf, array_length(hf));
1422         proto_register_subtree_array(ett, array_length(ett));
1423
1424         /* Register our configuration options for ADwin, particularly
1425            our port */
1426         adwin_module = prefs_register_protocol(proto_adwin, proto_reg_handoff_adwin);
1427
1428         prefs_register_uint_preference(adwin_module, "udp.port", "ADwin UDP Port",
1429                                        "Set the UDP port for ADwin packets (if other"
1430                                        " than the default of 6543)",
1431                                        10, &global_adwin_udp_port);
1432
1433         prefs_register_bool_preference(adwin_module, "dissect_data",
1434                                        "Dissect Data sections",
1435                                        "Specify if the Data sections of packets "
1436                                        "should be dissected or not",
1437                                        &global_adwin_dissect_data);
1438 }
1439
1440 void
1441 proto_reg_handoff_adwin(void)
1442 {
1443         static int adwin_prefs_initialized = FALSE;
1444         static dissector_handle_t adwin_handle;
1445         static unsigned int udp_port;
1446
1447         if (! adwin_prefs_initialized) {
1448                 adwin_handle = new_create_dissector_handle(dissect_adwin, proto_adwin);
1449                 adwin_prefs_initialized = TRUE;
1450         } else {
1451                 dissector_delete_uint("udp.port", udp_port, adwin_handle);
1452         }
1453
1454         udp_port = global_adwin_udp_port;
1455         dissector_add_uint("udp.port", global_adwin_udp_port, adwin_handle);
1456 }