Rename the routines that handle dissector tables with unsigned integer
[obnox/wireshark/wip.git] / plugins / ethercat / packet-ams.c
1 /* packet-ams.c
2  * Routines for ethercat packet disassembly
3  *
4  * $Id$
5  *
6  * Copyright (c) 2007 by Beckhoff Automation GmbH
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /* Include files */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <glib.h>
34
35 #include <epan/packet.h>
36
37 #include "packet-ams.h"
38
39 /* Define the ams proto */
40 int proto_ams = -1;
41
42 /* Define the tree for ams */
43 static int ett_ams = -1;
44 static int ett_ams_stateflags = -1;
45 static int ett_ams_adsreadrequest = -1;
46 static int ett_ams_adsreadresponse = -1;
47 static int ett_ams_adswriterequest = -1;
48 static int ett_ams_adswriteresponse = -1;
49 static int ett_ams_adsreadwriterequest = -1;
50 static int ett_ams_adsreadwriteresponse = -1;
51 static int ett_ams_adsreadstaterequest = -1;
52 static int ett_ams_adsreadstateresponse = -1;
53 static int ett_ams_adswritectrlrequest = -1;
54 static int ett_ams_adswritectrlresponse = -1;
55 static int ett_ams_adsreaddinforequest = -1;
56 static int ett_ams_adsreaddinforesponse = -1;
57 static int ett_ams_adsadddnrequest = -1;
58 static int ett_ams_adsadddnresponse = -1;
59 static int ett_ams_adsdeldnrequest = -1;
60 static int ett_ams_adsdeldnresponse = -1;
61 static int ett_ams_adsdnrequest = -1;
62
63 static int hf_ams_sendernetid = -1;
64 static int hf_ams_senderport = -1;
65 static int hf_ams_targetnetid = -1;
66 static int hf_ams_targetport = -1;
67 static int hf_ams_cmdid = -1;
68 static int hf_ams_stateflags = -1;
69 static int hf_ams_stateresponse = -1;
70 static int hf_ams_statenoreturn = -1;
71 static int hf_ams_stateadscmd = -1;
72 static int hf_ams_statesyscmd = -1;
73 static int hf_ams_statehighprio = -1;
74 static int hf_ams_statetimestampadded = -1;
75 static int hf_ams_stateudp = -1;
76 static int hf_ams_stateinitcmd = -1;
77 static int hf_ams_statebroadcast = -1;
78 static int hf_ams_cbdata = -1;
79 static int hf_ams_errorcode = -1;
80 static int hf_ams_invokeid = -1;
81 static int hf_ams_data = -1;
82
83 /*ads Commands */
84 static int hf_ams_adsindexgroup = -1;
85 static int hf_ams_adsindexoffset = -1;
86 static int hf_ams_adscblength = -1;
87 static int hf_ams_adsreadrequest = -1;
88 static int hf_ams_adsreadresponse = -1;
89 static int hf_ams_adsinvokeid = -1;
90 static int hf_ams_adsresult = -1;
91 static int hf_ams_adsdata = -1;
92 static int hf_ams_adswriterequest = -1;
93 static int hf_ams_adswriteresponse = -1;
94 static int hf_ams_adsreadwriterequest = -1;
95 static int hf_ams_adsreadwriteresponse = -1;
96 static int hf_ams_adscbreadlength = -1;
97 static int hf_ams_adscbwritelength = -1;
98 static int hf_ams_adsstate = -1;
99 static int hf_ams_adsdevicestate = -1;
100 static int hf_ams_adsnotificationhandle = -1;
101 static int hf_ams_adsreadstaterequest = -1;
102 static int hf_ams_adsreadstateresponse = -1;
103 static int hf_ams_adswritectrlrequest = -1;
104 static int hf_ams_adswritectrlresponse = -1;
105 static int hf_ams_adsreaddinforequest = -1;
106 static int hf_ams_adsreaddinforesponse = -1;
107 static int hf_ams_adsadddnrequest = -1;
108 static int hf_ams_adsadddnresponse = -1;
109 static int hf_ams_adsdeldnrequest = -1;
110 static int hf_ams_adsdeldnresponse = -1;
111 static int hf_ams_adsdnrequest = -1;
112 static int hf_ams_adsdnresponse = -1;
113 static int hf_ams_adsnoteattrib = -1;
114 static int hf_ams_adsnoteblocks = -1;
115 static int hf_ams_adsversion = -1;
116 static int hf_ams_adsdevicename = -1;
117 static int hf_ams_adsversionversion = -1;
118 static int hf_ams_adsversionrevision = -1;
119 static int hf_ams_adsversionbuild = -1;
120 static int hf_ams_adsnoteblocksstamps = -1;
121 static int hf_ams_adsnoteblocksstamp = -1;
122 static int hf_ams_adstimestamp = -1;
123 static int hf_ams_adssamplecnt = -1;
124 static int hf_ams_adsnoteblockssample = -1;
125 static int hf_ams_adstransmode = -1;
126 static int hf_ams_adsmaxdelay = -1;
127 static int hf_ams_adscycletime = -1;
128 static int hf_ams_adscmpmax = -1;
129 static int hf_ams_adscmpmin = -1;
130
131 static const value_string TransMode[] =
132 {
133    {  0, "NO TRANS"},
134    {  1, "CLIENT CYCLE"},
135    {  2, "CLIENT ON CHANGE"},
136    {  3, "SERVER CYCLE"},
137    {  4, "SERVER ON CHANGE"},
138    { 10, "CLIENT FIRST REQUEST"},
139    {  0, NULL }
140 };
141
142 static const value_string ErrorCode[] =
143 {
144    { ERR_NOERROR,                       "NO ERROR"},
145    { ERR_INTERNAL,                      "INTERNAL"},
146    { ERR_NORTIME,                       "NO RTIME"},
147    { ERR_ALLOCLOCKEDMEM,                "ALLOC LOCKED MEM"},
148    { ERR_INSERTMAILBOX,                 "INSERT MAILBOX"},
149    { ERR_WRONGRECEIVEHMSG,              "WRONGRECEIVEHMSG"},
150    { ERR_TARGETPORTNOTFOUND,            "TARGET PORT NOT FOUND"},
151    { ERR_TARGETMACHINENOTFOUND,         "TARGET MACHINE NOT FOUND"},
152    { ERR_UNKNOWNCMDID,                  "UNKNOWN CMDID"},
153    { ERR_BADTASKID,                     "BAD TASKID"},
154    { ERR_NOIO,                          "NOIO"},
155    { ERR_UNKNOWNAMSCMD,                 "UNKNOWN AMSCMD"},
156    { ERR_WIN32ERROR,                    "WIN32 ERROR"},
157    { ERR_PORTNOTCONNECTED,              "PORT NOT CONNECTED"},
158    { ERR_INVALIDAMSLENGTH,              "INVALID AMS LENGTH"},
159    { ERR_INVALIDAMSNETID,               "INVALID AMS NETID"},
160    { ERR_LOWINSTLEVEL,                  "LOW INST LEVEL"},
161    { ERR_NODEBUGINTAVAILABLE,           "NO DEBUG INT AVAILABLE"},
162    { ERR_PORTDISABLED,                  "PORT DISABLED"},
163    { ERR_PORTALREADYCONNECTED,          "PORT ALREADY CONNECTED"},
164    { ERR_AMSSYNC_W32ERROR,              "AMSSYNC_W32ERROR"},
165    { ERR_AMSSYNC_TIMEOUT,               "AMSSYNC_TIMEOUT"},
166    { ERR_AMSSYNC_AMSERROR,              "AMSSYNC_AMSERROR"},
167    { ERR_AMSSYNC_NOINDEXINMAP,          "AMSSYNC_NOINDEXINMAP"},
168    { ERR_INVALIDAMSPORT,                "INVALID AMSPORT"},
169    { ERR_NOMEMORY,                      "NO MEMORY"},
170    { ERR_TCPSEND,                       "TCP SEND"},
171    { ERR_HOSTUNREACHABLE,               "HOST UNREACHABLE"},
172    { ROUTERERR_NOLOCKEDMEMORY,          "ROUTERERR_NOLOCKEDMEMORY"},
173    { ROUTERERR_RESIZEMEMORY,            "ROUTERERR_RESIZEMEMORY"},
174    { ROUTERERR_MAILBOXFULL,             "ROUTERERR_MAILBOXFULL"},
175    { ROUTERERR_DEBUGBOXFULL,            "ROUTERERR_DEBUGBOXFULL"},
176    { ROUTERERR_UNKNOWNPORTTYPE,         "ROUTERERR_UNKNOWNPORTTYPE"},
177    { ROUTERERR_NOTINITIALIZED,          "ROUTERERR_NOTINITIALIZED"},
178    { ROUTERERR_PORTALREADYINUSE,        "ROUTERERR_PORTALREADYINUSE"},
179    { ROUTERERR_NOTREGISTERED,           "ROUTERERR_NOTREGISTERED   "},
180    { ROUTERERR_NOMOREQUEUES,            "ROUTERERR_NOMOREQUEUES"},
181    { ROUTERERR_INVALIDPORT,             "ROUTERERR_INVALIDPORT"},
182    { ROUTERERR_NOTACTIVATED,            "ROUTERERR_NOTACTIVATED"},
183    { IOERR_INTERNAL,                    "IOERR_INTERNAL"},
184    { IOERR_BADCARDNO,                   "IOERR_BADCARDNO"},
185    { IOERR_INVALIDCARDADDR,             "IOERR_INVALIDCARDADDR"},
186    { IOERR_CDLLISTFULL,                 "IOERR_CDLLISTFULL"},
187    { IOERR_BADCDLPARAM,                 "IOERR_BADCDLPARAM"},
188    { IOERR_OPENIOFAILED,                "IOERR_OPENIOFAILED"},
189    { IOERR_RESETIOFAILED,               "IOERR_RESETIOFAILED"},
190    { IOERR_UNKNOWNDEVICE,               "IOERR_UNKNOWNDEVICE"},
191    { IOERR_UNKNOWNDEVICEID,             "IOERR_UNKNOWNDEVICEID"},
192    { IOERR_UNKNOWNIMAGEID,              "IOERR_UNKNOWNIMAGEID"},
193    { IOERR_GETIOSTATE,                  "IOERR_GETIOSTATE"},
194    { IOERR_BADIMAGEID,                  "IOERR_BADIMAGEID"},
195    { IOERR_NOMORECLIENTSPACE,           "IOERR_NOMORECLIENTSPACE"},
196    { IOERR_CLIENTINFONOTFOUND,          "IOERR_CLIENTINFONOTFOUND"},
197    { IOERR_CDLNOTINUSE,                 "IOERR_CDLNOTINUSE"},
198    { IOERR_TIMEOUTWITHDEVICE,           "IOERR_TIMEOUTWITHDEVICE"},
199    { IOERR_C1220FUNC_1,                 "IOERR_C1220FUNC_1"},
200    { IOERR_C1220FUNC_9,                 "IOERR_C1220FUNC_9"},
201    { IOERR_C1220FUNC_C,                 "IOERR_C1220FUNC_C"},
202    { IOERR_C1220FUNC_10,                "IOERR_C1220FUNC_10"},
203    { IOERR_C1220FUNC_1_MAXSEND,         "IOERR_C1220FUNC_1_MAXSEND"},
204    { IOERR_C1220FUNC_1_ADDRSET,         "IOERR_C1220FUNC_1_ADDRSET"},
205    { IOERR_C1220FUNC_1_BREAK,           "IOERR_C1220FUNC_1_BREAK"},
206    { IOERR_C1220FUNC_1_BREAK0,          "IOERR_C1220FUNC_1_BREAK0"},
207    { IOERR_C1220FUNC_1_BREAK1,          "IOERR_C1220FUNC_1_BREAK1"},
208    { IOERR_C1220FUNC_1_BREAK2,          "IOERR_C1220FUNC_1_BREAK2"},
209    { IOERR_C1220FUNC_1_BREAK3,          "IOERR_C1220FUNC_1_BREAK3"},
210    { IOERR_C1220FUNC_1_BREAK4,          "IOERR_C1220FUNC_1_BREAK4"},
211    { IOERR_C1220FUNC_1_BREAK5,          "IOERR_C1220FUNC_1_BREAK5"},
212    { IOERR_C1220FUNC_1_BREAK6,          "IOERR_C1220FUNC_1_BREAK6"},
213    { IOERR_C1220FUNC_1_BREAK7,          "IOERR_C1220FUNC_1_BREAK7"},
214    { IOERR_C1220FUNC_1_BREAK8,          "IOERR_C1220FUNC_1_BREAK8"},
215    { IOERR_C1220FUNC_1_BREAK9,          "IOERR_C1220FUNC_1_BREAK9"},
216    { IOERR_C1220FUNC_1_BREAK10,         "IOERR_C1220FUNC_1_BREAK10"},
217    { IOERR_C1220FUNC_1_BREAK11,         "IOERR_C1220FUNC_1_BREAK11"},
218    { IOERR_C1220FUNC_1_BREAK12,         "IOERR_C1220FUNC_1_BREAK12"},
219    { IOERR_C1220FUNC_1_BREAK13,         "IOERR_C1220FUNC_1_BREAK13"},
220    { IOERR_C1220FUNC_1_BREAK14,          "IOERR_C1220FUNC_1_BREAK14"},
221    { IOERR_C1220FUNC_1_BREAK15,         "IOERR_C1220FUNC_1_BREAK15"},
222    { IOERR_C1220FUNC_1_BREAK16,         "IOERR_C1220FUNC_1_BREAK16"},
223    { IOERR_SPC3DEVINITDP,               "IOERR_SPC3DEVINITDP"},
224    { IOERR_SPC3UPDATEOUTPUT,            "IOERR_SPC3UPDATEOUTPUT"},
225    { IOERR_CIF30READDIAG,               "IOERR_CIF30READDIAG"},
226    { IOERR_CIF30COMMNOTSTARTED,         "IOERR_CIF30COMMNOTSTARTED"},
227    { IOERR_CIF30SLAVEPARASIZE,          "IOERR_CIF30SLAVEPARASIZE"},
228    { IOERR_CIF30NOPARAS,                "IOERR_CIF30NOPARAS"},
229    { IOERR_CIF30SLAVEERROR,             "IOERR_CIF30SLAVEERROR"},
230    { IOERR_CIF30WATCHDOGEXPIRED,        "IOERR_CIF30WATCHDOGEXPIRED"},
231    { IOERR_UNKNOWNDEVICECMD,            "IOERR_UNKNOWNDEVICECMD"},
232    { IOERR_CIF40MESSAGEHANDLING,        "IOERR_CIF40MESSAGEHANDLING"},
233    { IOERR_CIF40PARAERROR,              "IOERR_CIF40PARAERROR"},
234    { IOERR_CIF40WATCHDOGEXPIRED,        "IOERR_CIF40WATCHDOGEXPIRED"},
235    { IOERR_CIF40FLAGERROR,              "IOERR_CIF40FLAGERROR"},
236    { IOERR_CIF40COMMNOTSTARTED,         "IOERR_CIF40COMMNOTSTARTED"},
237    { IOERR_CIF40READDIAG,               "IOERR_CIF40READDIAG"},
238    { IOERR_CIF40SLAVEERROR,             "IOERR_CIF40SLAVEERROR"},
239    { IOERR_CIF40GLOBALERROR,            "IOERR_CIF40GLOBALERROR"},
240    { IOERR_CIF40CONFIGLIST,             "IOERR_CIF40CONFIGLIST"},
241    { IOERR_CP5412A2SLAVEPARASIZE,       "IOERR_CP5412A2SLAVEPARASIZE"},
242    { IOERR_CP5412A2NOPARAS,             "IOERR_CP5412A2NOPARAS"},
243    { IOERR_CP5412A2SLAVEERROR,          "IOERR_CP5412A2SLAVEERROR"},
244    { IOERR_CP5412A2FATAL,               "IOERR_CP5412A2FATAL"},
245    { IOERR_CP5412A2MAILBOXUSED,         "IOERR_CP5412A2MAILBOXUSED"},
246    { IOERR_BEGINCONFIGWHILETICKER,      "IOERR_BEGINCONFIGWHILETICKER"},
247    { IOERR_UNEXPECTEDBOXCOUNT,          "IOERR_UNEXPECTEDBOXCOUNT"},
248    { IOERR_C1200CHECKADDR,              "IOERR_C1200CHECKADDR"},
249    { IOERR_C1200INTENSITYTEST,          "IOERR_C1200INTENSITYTEST"},
250    { IOERR_NOIMAGE,                     "IOERR_NOIMAGE"},
251    { IOERR_INVALIDIMAGEOFFSSIZE,        "IOERR_INVALIDIMAGEOFFSSIZE"},
252    { IOERR_FORCESCOUNTEXCEEDEDMAXIMUM,  "IOERR_FORCESCOUNTEXCEEDEDMAXIMUM"},
253    { IOERR_SERCOSLIFECOUNTERERR,        "IOERR_SERCOSLIFECOUNTERERR"},
254    { IOERR_C1220NOTFOUND,               "IOERR_C1220NOTFOUND"},
255    { IOERR_AMSDEVICENOAMSINTF,          "IOERR_AMSDEVICENOAMSINTF"},
256    { IOERR_AMSDEVICEAMSCMDIDNOTSUPP,    "IOERR_AMSDEVICEAMSCMDIDNOTSUPP"},
257    { IOERR_AMSDEVICEAMSSERVICERUNNING,  "IOERR_AMSDEVICEAMSSERVICERUNNING"},
258    { IOERR_PLCINTERFACE_BUSY,           "IOERR_PLCINTERFACE_BUSY"},
259    { IOERR_PLCINTERFACE_FAULT,          "IOERR_PLCINTERFACE_FAULT"},
260    { IOERR_PLCINTERFACE_TIMEOUT,        "IOERR_PLCINTERFACE_TIMEOUT"},
261    { IOERR_PLCINTERFACE_RESETTIMEOUT,   "IOERR_PLCINTERFACE_RESETTIMEOUT"},
262    { IOERR_PLCINTERFACE_NODATAEXCH,     "IOERR_PLCINTERFACE_NODATAEXCH"},
263    { IOERR_PLCINTERFACE_RESET,          "IOERR_PLCINTERFACE_RESET"},
264    { IOERR_CP5412A2INVALIDADDR,         "IOERR_CP5412A2INVALIDADDR"},
265    { IOERR_CP5412A2INVALIDPORT,         "IOERR_CP5412A2INVALIDPORT"},
266    { IOERR_AMSDEVICEBADBOXNO,           "IOERR_AMSDEVICEBADBOXNO"},
267    { IOERR_AMSDEVICEBADTYPE,            "IOERR_AMSDEVICEBADTYPE"},
268    { IOERR_AMSDEVICEILLEGALADDRESS,     "IOERR_AMSDEVICEILLEGALADDRESS"},
269    { IOERR_CP5412A2INVALIDBOX,          "IOERR_CP5412A2INVALIDBOX"},
270    { IOERR_AMSDEVICEFIFOOVERFLOW,       "IOERR_AMSDEVICEFIFOOVERFLOW"},
271    { IOERR_AMSDEVICEAMSSEQUENCEERROR,   "IOERR_AMSDEVICEAMSSEQUENCEERROR"},
272    { IOERR_CP5412A2DPV1SYNTAXERROR,     "IOERR_CP5412A2DPV1SYNTAXERROR"},
273    { IOERR_CP5412A2DEVICENOTRUNNING,    "IOERR_CP5412A2DEVICENOTRUNNING"},
274    { IOERR_AMSDEVICENOTRUNNING,         "IOERR_AMSDEVICENOTRUNNING"},
275    { IOERR_AMSDEVICEBOXNOTDEFINED,      "IOERR_AMSDEVICEBOXNOTDEFINED"},
276    { IOERR_CP5412A2BADSERVICEPARA,      "IOERR_CP5412A2BADSERVICEPARA"},
277    { IOERR_CP5412A2FIFOOVERFLOW,        "IOERR_CP5412A2FIFOOVERFLOW"},
278    { IOERR_COMPORTOPENFAILED,           "IOERR_COMPORTOPENFAILED"},
279    { IOERR_CIF30BADMESSAGERESPONSE,     "IOERR_CIF30BADMESSAGERESPONSE"},
280    { IOERR_CIF30DELETEDATABASE,         "IOERR_CIF30DELETEDATABASE"},
281    { IOERR_CIF30STARTSEQFAILED,         "IOERR_CIF30STARTSEQFAILED"},
282    { IOERR_CIF30DOWNLOADFAILED,         "IOERR_CIF30DOWNLOADFAILED"},
283    { IOERR_CIF30ENDSEQFAILED,           "IOERR_CIF30ENDSEQFAILED"},
284    { IOERR_CIF30BUSLOADFAILED,          "IOERR_CIF30BUSLOADFAILED"},
285    { IOERR_PLCINTERFACE_RESETREQ,       "IOERR_PLCINTERFACE_RESETREQ"},
286    { IOERR_CP5412A2INVALIDCYCLETICKS,   "IOERR_CP5412A2INVALIDCYCLETICKS"},
287    { IOERR_CP5412A2DPBUSFAULT,          "IOERR_CP5412A2DPBUSFAULT"},
288    { IOERR_INVALIDTERMCONFIG,           "IOERR_INVALIDTERMCONFIG"},
289    { IOERR_SERCANSBREAK,                "IOERR_SERCANSBREAK"},
290    { IOERR_SERCANSPHASE0,               "IOERR_SERCANSPHASE0"},
291    { IOERR_SERCANSPHASE1,               "IOERR_SERCANSPHASE1"},
292    { IOERR_SERCANSPHASE2,               "IOERR_SERCANSPHASE2"},
293    { IOERR_SERCANSPHASE3,               "IOERR_SERCANSPHASE3"},
294    { IOERR_SERCANSPHASE4,               "IOERR_SERCANSPHASE4"},
295    { IOERR_SERCANSNCSERVICECHNFAILED,   "IOERR_SERCANSNCSERVICECHNFAILED"},
296    { IOERR_RESOURCECONFICT,             "IOERR_RESOURCECONFICT"},
297    { IOERR_C1220INITSTRINGCOMM,         "IOERR_C1220INITSTRINGCOMM"},
298    { IOERR_C1220REGSTRINGSLAVE,         "IOERR_C1220REGSTRINGSLAVE"},
299    { IOERR_C1220STRREGFAULT,            "IOERR_C1220STRREGFAULT"},
300    { IOERR_IOSTATEBUSY,                 "IOERR_IOSTATEBUSY"},
301    { IOERR_IBSSCITWATCHDOGEXPIRED,      "IOERR_IBSSCITWATCHDOGEXPIRED"},
302    { IOERR_IBSSCITSYNCMAILBOXERROR,     "IOERR_IBSSCITSYNCMAILBOXERROR"},
303    { IOERR_IBSSCITCONFIRMDIAGERROR,     "IOERR_IBSSCITCONFIRMDIAGERROR"},
304    { IOERR_IBSSCITCREATECFGERROR,       "IOERR_IBSSCITCREATECFGERROR"},
305    { 0,                                 NULL }
306 };
307
308 static const value_string AdsErrorMode[] =
309 {
310    { ADSERR_NOERR,                       "NO ERROR", },
311    { ADSERR_DEVICE_ERROR,                "ERROR", },
312    { ADSERR_DEVICE_SRVNOTSUPP,           "SRV NOT SUPP", },
313    { ADSERR_DEVICE_INVALIDGRP,           "INVALID GRP", },
314    { ADSERR_DEVICE_INVALIDOFFSET,        "INVALID OFFSET", },
315    { ADSERR_DEVICE_INVALIDACCESS,        "INVALID ACCESS", },
316    { ADSERR_DEVICE_INVALIDSIZE,          "INVALID SIZE", },
317    { ADSERR_DEVICE_INVALIDDATA,          "INVALID DATA", },
318    { ADSERR_DEVICE_NOTREADY,             "NOT READY", },
319    { ADSERR_DEVICE_BUSY,                 "BUSY", },
320    { ADSERR_DEVICE_INVALIDCONTEXT,       "INVALID CONTEXT", },
321    { ADSERR_DEVICE_NOMEMORY,             "NO MEMORY", },
322    { ADSERR_DEVICE_INVALIDPARM,          "INVALID PARM", },
323    { ADSERR_DEVICE_NOTFOUND,             "NOT FOUND", },
324    { ADSERR_DEVICE_SYNTAX,               "SYNTAX", },
325    { ADSERR_DEVICE_INCOMPATIBLE,         "INCOMPATIBLE", },
326    { ADSERR_DEVICE_EXISTS,               "EXISTS", },
327    { ADSERR_DEVICE_SYMBOLNOTFOUND,       "SYMBOL NOT FOUND", },
328    { ADSERR_DEVICE_SYMBOLVERSIONINVALID, "SYMBOL VERSION INVALID", },
329    { ADSERR_DEVICE_INVALIDSTATE,         "INVALID STATE", },
330    { ADSERR_DEVICE_TRANSMODENOTSUPP,     "TRANS MODE NOT SUPP", },
331    { ADSERR_DEVICE_NOTIFYHNDINVALID,     "NOTIFY HND INVALID", },
332    { ADSERR_DEVICE_CLIENTUNKNOWN,        "CLIENT UNKNOWN", },
333    { ADSERR_DEVICE_NOMOREHDLS,           "NO MORE HDLS", },
334    { ADSERR_DEVICE_INVALIDWATCHSIZE,     "INVALID WATCHSIZE", },
335    { ADSERR_DEVICE_NOTINIT,              "NOT INIT", },
336    { ADSERR_DEVICE_TIMEOUT,              "TIMEOUT", },
337    { ADSERR_DEVICE_NOINTERFACE,          "NO INTERFACE", },
338    { ADSERR_DEVICE_INVALIDINTERFACE,     "INVALID INTERFACE", },
339    { ADSERR_DEVICE_INVALIDCLSID,         "INVALID CLSID", },
340    { ADSERR_DEVICE_INVALIDOBJID,         "INVALID OBJID", },
341    { ADSERR_DEVICE_PENDING,              "PENDING", },
342    { ADSERR_DEVICE_ABORTED,              "ABORTED", },
343    { ADSERR_DEVICE_WARNING,              "WARNING", },
344    { ADSERR_DEVICE_INVALIDARRAYIDX,      "INVALID ARRAY IDX", },
345    { ADSERR_CLIENT_ERROR,                "CLIENT ERROR", },
346    { ADSERR_CLIENT_INVALIDPARM,          "CLIENT INVALID PARM", },
347    { ADSERR_CLIENT_LISTEMPTY,            "CLIENT LIST EMPTY", },
348    { ADSERR_CLIENT_VARUSED,              "CLIENT VAR USED", },
349    { ADSERR_CLIENT_DUPLINVOKEID,         "CLIENT DUPL INVOKEID", },
350    { ADSERR_CLIENT_SYNCTIMEOUT,          "CLIENT SYNC TIMEOUT", },
351    { ADSERR_CLIENT_W32ERROR,             "CLIENT W32ERROR", },
352    { ADSERR_CLIENT_TIMEOUTINVALID,       "CLIENT TIMEOUT INVALID", },
353    { ADSERR_CLIENT_PORTNOTOPEN,          "CLIENT PORT NOT OPEN", },
354    { ADSERR_CLIENT_NOAMSADDR,            "CLIENT NO AMS ADDR", },
355    { ADSERR_CLIENT_SYNCINTERNAL,         "CLIENT SYNC INTERNAL", },
356    { ADSERR_CLIENT_ADDHASH,              "CLIENT ADD HASH", },
357    { ADSERR_CLIENT_REMOVEHASH,           "CLIENT REMOVE HASH", },
358    { ADSERR_CLIENT_NOMORESYM,            "CLIENT NO MORE SYM", },
359    { ADSERR_CLIENT_SYNCRESINVALID,       "CLIENT SYNC RES INVALID", },
360    { ADSERR_CLIENT_SYNCPORTLOCKED,       "CLIENT SYNC PORT LOCKED", },
361    {  0,                                 NULL }
362 };
363
364 static void NetIdFormater(tvbuff_t *tvb, guint offset, char *szText, gint nMax)
365 {
366    g_snprintf ( szText, nMax, "%d.%d.%d.%d.%d.%d", tvb_get_guint8(tvb, offset),
367       tvb_get_guint8(tvb, offset+1),
368       tvb_get_guint8(tvb, offset+2),
369       tvb_get_guint8(tvb, offset+3),
370       tvb_get_guint8(tvb, offset+4),
371       tvb_get_guint8(tvb, offset+5)
372       );
373 }
374
375
376
377 /*ams*/
378 static void dissect_ams(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
379 {
380    proto_item *ti, *anItem;
381    proto_tree *ams_tree = NULL, *ams_adstree, *ams_statetree;
382    gint offset = 0;
383    guint ams_length = tvb_reported_length(tvb); 
384    guint16 stateflags = 0;
385    guint16 cmdId = 0;
386    
387    char szText[200];
388    int nMax = sizeof(szText)-1;
389
390    col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMS");
391
392    col_clear(pinfo->cinfo, COL_INFO);
393
394    if( pinfo->ethertype != 0x88a4 )
395    {
396       if( TcpAdsParserHDR_Len > ams_length )
397          return;
398       ams_length -= TcpAdsParserHDR_Len;
399
400       offset = TcpAdsParserHDR_Len;
401    }
402
403    if( ams_length < AmsHead_Len )
404       return;
405
406   if (tree)
407   {
408      ti = proto_tree_add_item(tree, proto_ams, tvb, 0, -1, TRUE);
409      ams_tree = proto_item_add_subtree(ti, ett_ams);
410      
411      NetIdFormater(tvb, offset, szText, nMax);
412      proto_tree_add_string(ams_tree, hf_ams_targetnetid, tvb, offset, AmsNetId_Len, szText);
413      offset += AmsNetId_Len;
414
415      proto_tree_add_item(ams_tree, hf_ams_targetport, tvb, offset, sizeof(guint16), TRUE);
416      offset += sizeof(guint16);
417
418      NetIdFormater(tvb, offset, szText, nMax);
419      proto_tree_add_string(ams_tree, hf_ams_sendernetid, tvb, offset, AmsNetId_Len, szText);
420      offset += AmsNetId_Len;
421
422      proto_tree_add_item(ams_tree, hf_ams_senderport, tvb, offset, sizeof(guint16), TRUE);
423      offset += sizeof(guint16);
424
425      proto_tree_add_item(ams_tree, hf_ams_cmdid, tvb, offset, sizeof(guint16), TRUE);
426      cmdId = tvb_get_letohs(tvb, offset);
427      offset+=sizeof(guint16);
428
429      anItem = proto_tree_add_item(ams_tree, hf_ams_stateflags, tvb, offset, sizeof(guint16), TRUE);
430      ams_statetree = proto_item_add_subtree(anItem, ett_ams_stateflags);
431      proto_tree_add_item(ams_statetree, hf_ams_stateresponse,tvb, offset, sizeof(guint16), TRUE);
432      proto_tree_add_item(ams_statetree, hf_ams_statenoreturn,tvb, offset, sizeof(guint16), TRUE);
433      proto_tree_add_item(ams_statetree, hf_ams_stateadscmd,tvb, offset, sizeof(guint16), TRUE);
434      proto_tree_add_item(ams_statetree, hf_ams_statesyscmd,tvb, offset, sizeof(guint16), TRUE);
435      proto_tree_add_item(ams_statetree, hf_ams_statehighprio,tvb, offset, sizeof(guint16), TRUE);
436      proto_tree_add_item(ams_statetree, hf_ams_statetimestampadded,tvb, offset, sizeof(guint16), TRUE);
437      proto_tree_add_item(ams_statetree, hf_ams_stateudp,tvb, offset, sizeof(guint16), TRUE);
438      proto_tree_add_item(ams_statetree, hf_ams_stateinitcmd,tvb, offset, sizeof(guint16), TRUE);
439      proto_tree_add_item(ams_statetree, hf_ams_statebroadcast,tvb, offset, sizeof(guint16), TRUE);
440      stateflags = tvb_get_letohs(tvb, offset);
441      offset+=sizeof(guint16);
442
443      proto_tree_add_item(ams_tree, hf_ams_cbdata, tvb, offset, sizeof(guint32), TRUE);
444      offset+=sizeof(guint32);
445
446      proto_tree_add_item(ams_tree, hf_ams_errorcode, tvb, offset, sizeof(guint32),TRUE);
447      offset+=sizeof(guint32);
448
449      proto_tree_add_item(ams_tree, hf_ams_invokeid, tvb, offset, sizeof(guint32), TRUE);
450      offset+=sizeof(guint32);
451   }
452   else
453   {
454      offset+=AmsHead_Len;
455   }
456
457   if ( (stateflags & AMSCMDSF_ADSCMD) != 0 )
458   {
459      /* ADS */
460      if ( (stateflags & AMSCMDSF_RESPONSE) == 0 )
461      {
462         /* Request */
463         switch ( cmdId )
464         {          
465         case ADSSRVID_READ:
466            {
467               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Request");
468
469               if( tree )
470               {
471                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadrequest, tvb, offset, ams_length-offset, TRUE);
472                  if( ams_length-offset >= TAdsReadReq_Len )
473                  {
474                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadrequest);
475                     proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE);
476                     offset+=sizeof(guint32);
477
478                     proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE);
479                     offset+=sizeof(guint32);
480
481                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
482                     offset+=sizeof(guint32);
483                  }
484               }
485            }
486            break;
487         case ADSSRVID_WRITE:
488            {
489               col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Request");
490
491               if( tree )
492               {
493                  anItem = proto_tree_add_item(ams_tree, hf_ams_adswriterequest, tvb, offset, ams_length-offset, TRUE);
494                  if( ams_length-offset >= TAdsWriteReq_Len - sizeof(guint16) )
495                  {
496                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriterequest);
497                     proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, 4, TRUE);
498                     offset+=sizeof(guint32);
499
500                     proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, 4, TRUE);
501                     offset+=sizeof(guint32);
502
503                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, 4, TRUE);
504                     offset+=sizeof(guint32);
505
506                     proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE);
507                  }
508               }
509            }
510            break;
511         case ADSSRVID_READWRITE:
512            {
513               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Request");
514
515               if( tree )
516               {
517                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriterequest, tvb, offset, ams_length-offset, TRUE);
518                  if( ams_length-offset >= TAdsReadWriteReq_Len - sizeof(guint16))
519                  {
520                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriterequest);
521                     proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE);
522                     offset+=sizeof(guint32);
523
524                     proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE);
525                     offset+=sizeof(guint32);
526
527                     proto_tree_add_item(ams_adstree, hf_ams_adscbreadlength, tvb, offset, sizeof(guint32), TRUE);
528                     offset+=sizeof(guint32);
529
530                     proto_tree_add_item(ams_adstree, hf_ams_adscbwritelength, tvb, offset, sizeof(guint32), TRUE);
531                     offset+=sizeof(guint32);
532
533                     proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset+16, ams_length-offset, TRUE);
534                  }
535               }
536            }
537            break;
538         case ADSSRVID_READSTATE:
539            {
540               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Request");
541
542               if( tree )
543               {
544                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstaterequest, tvb, offset, ams_length-offset, TRUE);
545                  if( ams_length-offset >= TAdsReadStateReq_Len )
546                  {
547                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstaterequest);
548                     proto_tree_add_item(ams_adstree, hf_ams_adsinvokeid, tvb, offset, sizeof(guint32), TRUE);
549                  }
550               }
551            }
552            break;
553         case ADSSRVID_WRITECTRL:
554            {
555               col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Request");
556
557               if( tree )
558               {
559                  anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlrequest, tvb, offset, ams_length-offset, TRUE);
560                  if( ams_length-offset >= TAdsWriteControlReq_Len - sizeof(guint16) )
561                  {
562                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlrequest);
563                     proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, 2, TRUE);
564                     offset+=sizeof(guint16);
565
566                     proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, 2, TRUE);
567                     offset+=sizeof(guint16);
568
569                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
570                     offset+=sizeof(guint32);
571
572                     proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE);
573                  }
574               }
575            }
576            break;
577         case ADSSRVID_READDEVICEINFO:
578            {
579               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Request");
580
581               if( tree )
582               {
583                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforequest, tvb, offset, ams_length-offset, TRUE);
584                  if( ams_length-offset >= TAdsReadDeviceInfoReq_Len )
585                  {
586                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforequest);
587                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
588                  }
589               }
590            }
591            break;
592         case ADSSRVID_ADDDEVICENOTE:
593            {
594               col_append_str(pinfo->cinfo, COL_INFO, "ADS Add Device Notification Request");
595
596               if( tree )
597               {
598                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnrequest, tvb, offset, ams_length-offset, TRUE);
599                  if( ams_length-offset >= TAdsAddDeviceNotificationReq_Len )
600                  {
601                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnrequest);
602                     proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE);
603                     offset+=sizeof(guint32);
604
605                     proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE);
606                     offset+=sizeof(guint32);
607
608                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
609                     offset+=sizeof(guint32);
610
611                     proto_tree_add_item(ams_adstree, hf_ams_adstransmode, tvb, offset, sizeof(guint32), TRUE);
612                     offset+=sizeof(guint32);
613
614                     proto_tree_add_item(ams_adstree, hf_ams_adsmaxdelay, tvb, offset, sizeof(guint32), TRUE);
615                     offset+=sizeof(guint32);
616
617                     proto_tree_add_item(ams_adstree, hf_ams_adscycletime, tvb, offset, sizeof(guint32), TRUE);
618                     offset+=sizeof(guint32);
619                  }
620               }
621            }
622            break;
623         case ADSSRVID_DELDEVICENOTE:
624            {
625               col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Request");
626
627               if( tree )
628               {
629                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnrequest, tvb, offset, ams_length-offset, TRUE);
630                  if( ams_length-offset >= TAdsDelDeviceNotificationReq_Len )
631                  {
632                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnrequest);
633                     proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, sizeof(guint32), TRUE);
634                  }
635               }
636            }
637            break;
638         case ADSSRVID_DEVICENOTE:
639            {
640               col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Request");
641
642               if( tree )
643               {
644                  /*guint32 cbLength;
645                  guint32 nStamps;*/
646                  
647                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsdnrequest, tvb, offset, ams_length-offset, TRUE);
648                  if( ams_length-offset >= TAdsDeviceNotificationReq_Len )
649                  {
650                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdnrequest);
651                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
652                     /*cbLength = tvb_get_letohs(tvb, offset);*/
653                     offset+=sizeof(guint32);
654
655                     proto_tree_add_item(ams_adstree, hf_ams_adsnoteblocksstamps, tvb, offset, sizeof(guint32), TRUE);
656                     /*nStamps = tvb_get_letohs(tvb, offset);*/
657                     offset+=sizeof(guint32);
658
659                     /*ToDo: dissect noteblocks*/
660                  }
661               }
662            }
663            break;
664         }
665      }
666      else
667      {
668         /* Response */
669         switch ( cmdId )
670         {
671         case ADSSRVID_READ:
672            {
673               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Response");
674
675               if( tree )
676               {
677                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadresponse, tvb, offset, ams_length-offset, TRUE);
678                  if( ams_length-offset >= TAdsReadRes_Len - sizeof(guint16) )
679                  {
680                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadresponse);
681                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
682                     offset+=sizeof(guint32);
683
684                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
685                     offset+=sizeof(guint32);
686
687                     proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE);
688                  }
689               }
690            }
691            break;
692         case ADSSRVID_WRITE:
693            {
694               col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Response");
695
696               if( tree )
697               {
698                  anItem = proto_tree_add_item(ams_tree, hf_ams_adswriteresponse, tvb, offset, ams_length-offset, TRUE);
699                  if( ams_length-offset >= TAdsWriteRes_Len )
700                  {
701                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriteresponse);
702                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
703                  }
704               }
705            }
706            break;
707         case ADSSRVID_READWRITE:
708            {
709               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Response");
710
711               if( tree )
712               {
713                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriteresponse, tvb, offset, ams_length-offset, TRUE);
714                  if( ams_length-offset >= TAdsReadWriteRes_Len - sizeof(guint16) )
715                  {
716                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriteresponse);
717                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
718                     offset+=sizeof(guint32);
719
720                     proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE);
721                     offset+=sizeof(guint32);
722
723                     proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE);
724                  }
725               }
726            }
727            break;
728         case ADSSRVID_READSTATE:
729            {
730               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Response");
731
732               if( tree )
733               {
734                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstateresponse, tvb, offset, ams_length-offset, TRUE);
735                  if( ams_length-offset >= TAdsReadStateRes_Len )
736                  {
737                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstateresponse);
738                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
739                     offset+=sizeof(guint32);
740
741                     proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, sizeof(guint16), TRUE);
742                     offset+=sizeof(guint32);
743
744                     proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, sizeof(guint16), TRUE);
745                  }
746               }
747            }
748            break;
749         case ADSSRVID_WRITECTRL:
750            {
751               col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Response");
752
753               if( tree )
754               {
755                  anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlresponse, tvb, offset, ams_length-offset, TRUE);
756                  if( ams_length-offset >= TAdsWriteControlRes_Len )
757                  {
758                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlresponse);
759                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
760                  }
761               }
762            }
763            break;
764         case ADSSRVID_READDEVICEINFO:
765            {
766               col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Response");
767
768               if( tree )
769               {
770                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforesponse, tvb, offset, ams_length-offset, TRUE);
771                  if( ams_length-offset >= TAdsReadDeviceInfoRes_Len )
772                  {
773                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforesponse);
774                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
775                     offset+=sizeof(guint32);
776
777                     proto_tree_add_item(ams_adstree, hf_ams_adsversionversion, tvb, offset++, sizeof(guint8), TRUE);
778                     proto_tree_add_item(ams_adstree, hf_ams_adsversionrevision, tvb, offset++, sizeof(guint8), TRUE);
779                     proto_tree_add_item(ams_adstree, hf_ams_adsversionbuild, tvb, offset, sizeof(guint16), TRUE);
780                     offset+=sizeof(guint16);
781
782                     proto_tree_add_item(ams_adstree, hf_ams_adsdevicename, tvb, offset, ams_length-offset, TRUE);
783                  }
784               }
785            }
786            break;
787         case ADSSRVID_ADDDEVICENOTE:
788            {
789               col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Response");
790
791               if( tree )
792               {
793                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnresponse, tvb, offset, ams_length-offset, TRUE);
794                  if( ams_length-offset >= TAdsAddDeviceNotificationRes_Len )
795                  {
796                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnresponse);
797                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
798                     offset+=sizeof(guint32);
799
800                     proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, sizeof(guint32), TRUE);
801                  }
802               }
803            }
804            break;
805         case ADSSRVID_DELDEVICENOTE:
806            {
807               col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Response");
808
809               if( tree )
810               {
811                  anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnresponse, tvb, offset, ams_length-offset, TRUE);
812                  if( ams_length-offset >= TAdsDelDeviceNotificationRes_Len )
813                  {
814                     ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnresponse);
815                     proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE);
816                  }
817               }
818            }
819            break;
820         }
821      }
822   }
823   else
824   {
825     if ( (stateflags & AMSCMDSF_RESPONSE) == 0 )
826        col_append_str(pinfo->cinfo, COL_INFO, "AMS Request");
827     else
828        col_append_str(pinfo->cinfo, COL_INFO, "AMS Response");
829     if( tree && ams_length-offset > 0 )
830         proto_tree_add_item(ams_tree, hf_ams_data, tvb, offset, ams_length-offset, TRUE);
831   }
832
833 }
834
835
836 void proto_register_ams(void)
837 {
838    static const true_false_string flags_set_truth =
839    {
840       "Set",
841       "Not set"
842    };
843
844    static hf_register_info hf[] =
845    {
846       { &hf_ams_sendernetid,
847       { "AMS Sender Net Id", "ams.sendernetid",
848       FT_STRING, BASE_NONE, NULL, 0x0,
849       NULL, HFILL }
850       },
851       { &hf_ams_senderport,
852       { "AMS Sender port", "ams.senderport",
853       FT_UINT16, BASE_DEC, NULL, 0x0,
854       NULL, HFILL }
855       },
856       { &hf_ams_targetnetid,
857       { "AMS Target Net Id", "ams.targetnetid",
858       FT_STRING, BASE_NONE, NULL, 0x0,
859       NULL, HFILL }
860       },
861       { &hf_ams_targetport,
862       { "AMS Target port", "ams.targetport",
863       FT_UINT16, BASE_DEC, NULL, 0x0,
864       NULL, HFILL }
865       },
866       { &hf_ams_cmdid,
867       { "CmdId", "ams.cmdid",
868       FT_UINT16, BASE_DEC, NULL, 0x0,
869       NULL, HFILL }
870       },
871       { &hf_ams_stateflags,
872       { "StateFlags", "ams.stateflags",
873       FT_UINT16, BASE_HEX, NULL, 0x0,
874       NULL, HFILL }
875       },
876       { &hf_ams_stateresponse,
877       { "RESPONSE", "ams.state_response",
878       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_RESPONSE,
879       NULL, HFILL }
880       },
881       { &hf_ams_statenoreturn,
882       { "NO RETURN", "ams.state_noreturn",
883       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_NORETURN,
884       NULL, HFILL }
885       },
886       { &hf_ams_stateadscmd,
887       { "ADS COMMAND", "ams.state_adscmd",
888       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_ADSCMD,
889       NULL, HFILL }
890       },
891       { &hf_ams_statesyscmd,
892       { "SYSTEM COMMAND", "ams.state_syscmd",
893       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_SYSCMD,
894       NULL, HFILL }
895       },
896       { &hf_ams_statehighprio,
897       { "HIGH PRIORITY COMMAND", "ams.state_highprio",
898       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_HIGHPRIO,
899       NULL, HFILL }
900       },
901       { &hf_ams_statetimestampadded,
902       { "TIMESTAMP ADDED", "ams.state_timestampadded",
903       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_TIMESTAMPADDED,
904       NULL, HFILL }
905       },
906       { &hf_ams_stateudp,
907       { "UDP COMMAND", "ams.state_udp",
908       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_UDP,
909       NULL, HFILL }
910       },
911       { &hf_ams_stateinitcmd,
912       { "INIT COMMAND", "ams.state_initcmd",
913       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_INITCMD,
914       NULL, HFILL }
915       },
916       { &hf_ams_statebroadcast,
917       { "BROADCAST", "ams.state_broadcast",
918       FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_BROADCAST,
919       NULL, HFILL }
920       },
921       { &hf_ams_cbdata,
922       { "cbData", "ams.cbdata",
923       FT_UINT32, BASE_DEC, NULL, 0x0,
924       NULL, HFILL }
925       },
926       { &hf_ams_errorcode,
927       { "ErrorCode", "ams.errorcode",
928       FT_UINT32, BASE_HEX, VALS(ErrorCode), 0x0,
929       NULL, HFILL }
930       },
931       { &hf_ams_invokeid,
932       { "InvokeId", "ams.invokeid",
933       FT_UINT32, BASE_HEX, NULL, 0x0,
934       NULL, HFILL }
935       },
936       { &hf_ams_adsdata,
937       { "Data", "ams.ads_data",
938       FT_NONE, BASE_NONE, NULL, 0x0,
939       NULL, HFILL }
940       },
941       { &hf_ams_data,
942       { "Data", "ams.data",
943       FT_NONE, BASE_NONE, NULL, 0x0,
944       NULL, HFILL }
945       },
946       { &hf_ams_adsindexgroup,
947       { "IndexGroup", "ams.ads_indexgroup",
948       FT_UINT32, BASE_HEX, NULL, 0x0,
949       NULL, HFILL }
950       },
951       { &hf_ams_adsindexoffset,
952       { "IndexOffset", "ams.ads_indexoffset",
953       FT_UINT32, BASE_HEX, NULL, 0x0,
954       NULL, HFILL }
955       },
956       { &hf_ams_adscblength,
957       { "CbLength", "ams.ads_cblength",
958       FT_UINT32, BASE_DEC, NULL, 0x0,
959       NULL, HFILL }
960       },
961       { &hf_ams_adsreadrequest,
962       { "ADS Read Request", "ams.ads_read_req",
963       FT_NONE, BASE_NONE, NULL, 0x0,
964       NULL, HFILL }
965       },
966       { &hf_ams_adsreadresponse,
967       { "ADS Read Response", "ams.ads_read_res",
968       FT_NONE, BASE_NONE, NULL, 0x0,
969       NULL, HFILL }
970       },
971       { &hf_ams_adsinvokeid,
972       { "InvokeId", "ams.ads_invokeid",
973       FT_UINT32, BASE_HEX, NULL, 0x0,
974       NULL, HFILL }
975       },
976       { &hf_ams_adsresult,
977       { "Result", "ams.adsresult",
978       FT_UINT32, BASE_HEX, VALS(AdsErrorMode), 0x0,
979       NULL, HFILL }
980       },
981       { &hf_ams_adswriterequest,
982       { "ADS Write Request", "ams.ads_write_req",
983       FT_NONE, BASE_NONE, NULL, 0x0,
984       NULL, HFILL }
985       },
986       { &hf_ams_adswriteresponse,
987       { "ADS Write Response", "ams.ads_write_res",
988       FT_NONE, BASE_NONE, NULL, 0x0,
989       NULL, HFILL }
990       },
991       { &hf_ams_adsreadwriterequest,
992       { "ADS ReadWrite Request", "ams.ads_readwrite_req",
993       FT_NONE, BASE_NONE, NULL, 0x0,
994       NULL, HFILL }
995       },
996       { &hf_ams_adsreadwriteresponse,
997       { "ADS ReadWrite Response", "ams.ads_readwrite_res",
998       FT_NONE, BASE_NONE, NULL, 0x0,
999       NULL, HFILL }
1000       },
1001       { &hf_ams_adscbreadlength,
1002       { "CBReadLength", "ams.ads_cbreadlength",
1003       FT_UINT32, BASE_DEC, NULL, 0x0,
1004       NULL, HFILL }
1005       },
1006       { &hf_ams_adscbwritelength,
1007       { "CBWriteLength", "ams.ads_cbwritelength",
1008       FT_UINT32, BASE_DEC, NULL, 0x0,
1009       NULL, HFILL }
1010       },
1011       { &hf_ams_adsstate,
1012       { "AdsState", "ams.ads_state",
1013       FT_UINT16, BASE_HEX, NULL, 0x0,
1014       NULL, HFILL }
1015       },
1016       { &hf_ams_adsdevicestate,
1017       { "DeviceState", "ams.ads_devicestate",
1018       FT_UINT16, BASE_HEX, NULL, 0x0,
1019       NULL, HFILL }
1020       },
1021       { &hf_ams_adsnotificationhandle,
1022       { "NotificationHandle", "ams.ads_notificationhandle",
1023       FT_UINT32, BASE_HEX, NULL, 0x0,
1024       NULL, HFILL }
1025       },
1026       { &hf_ams_adsreadstaterequest,
1027       { "ADS Read State Request", "ams.ads_readstate_req",
1028       FT_NONE, BASE_NONE, NULL, 0x0,
1029       NULL, HFILL }
1030       },
1031       { &hf_ams_adsreadstateresponse,
1032       { "ADS Read State Response", "ams.ads_readstate_res",
1033       FT_NONE, BASE_NONE, NULL, 0x0,
1034       NULL, HFILL }
1035       },
1036       { &hf_ams_adswritectrlrequest,
1037       { "ADS Write Ctrl Request", "ams.ads_writectrl_req",
1038       FT_NONE, BASE_NONE, NULL, 0x0,
1039       NULL, HFILL }
1040       },
1041       { &hf_ams_adswritectrlresponse,
1042       { "ADS Write Ctrl Response", "ams.ads_writectrl_res",
1043       FT_NONE, BASE_NONE, NULL, 0x0,
1044       NULL, HFILL }
1045       },
1046       { &hf_ams_adsreaddinforequest,
1047       { "ADS Read Device Info Request", "ams.ads_readdinfo_req",
1048       FT_NONE, BASE_NONE, NULL, 0x0,
1049       NULL, HFILL }
1050       },
1051       { &hf_ams_adsreaddinforesponse,
1052       { "ADS Read Device Info Response", "ams.ads_readdinfo_res",
1053       FT_NONE, BASE_NONE, NULL, 0x0,
1054       NULL, HFILL }
1055       },
1056       { &hf_ams_adsadddnrequest,
1057       { "ADS Add Device Notification Request", "ams.ads_adddn_req",
1058       FT_NONE, BASE_NONE, NULL, 0x0,
1059       NULL, HFILL }
1060       },
1061       { &hf_ams_adsadddnresponse,
1062       { "ADS Add Device Notification Response", "ams.ads_adddn_res",
1063       FT_NONE, BASE_NONE, NULL, 0x0,
1064       NULL, HFILL }
1065       },
1066       { &hf_ams_adsdeldnrequest,
1067       { "ADS Delete Device Notification Request", "ams.ads_deldn_req",
1068       FT_NONE, BASE_NONE, NULL, 0x0,
1069       NULL, HFILL }
1070       },
1071       { &hf_ams_adsdeldnresponse,
1072       { "ADS Delete Device Notification Response", "ams.ads_deldn_res",
1073       FT_NONE, BASE_NONE, NULL, 0x0,
1074       NULL, HFILL }
1075       },
1076       { &hf_ams_adsdnrequest,
1077       { "ADS Device Notification Request", "ams.ads_dn_req",
1078       FT_NONE, BASE_NONE, NULL, 0x0,
1079       NULL, HFILL }
1080       },
1081       { &hf_ams_adsdnresponse,
1082       { "ADS Device Notification Response", "ams.ads_dn_res",
1083       FT_NONE, BASE_NONE, NULL, 0x0,
1084       NULL, HFILL }
1085       },
1086       { &hf_ams_adsnoteattrib,
1087       { "InvokeId", "ams.ads_noteattrib",
1088       FT_NONE, BASE_NONE, NULL, 0x0,
1089       NULL, HFILL }
1090       },
1091       { &hf_ams_adsnoteblocks,
1092       { "InvokeId", "ams.ads_noteblocks",
1093       FT_NONE, BASE_NONE, NULL, 0x0,
1094       NULL, HFILL }
1095       },
1096       { &hf_ams_adsversion,
1097       { "ADS Version", "ams.ads_version",
1098       FT_UINT32, BASE_DEC, NULL, 0x0,
1099       NULL, HFILL }
1100       },
1101       { &hf_ams_adsdevicename,
1102       { "Device Name","ams.ads_devicename",
1103       FT_STRING, BASE_NONE, NULL, 0x0,
1104       NULL, HFILL }
1105       },
1106       { &hf_ams_adsversionversion,
1107       { "ADS Major Version", "ams.ads_versionversion",
1108       FT_UINT8, BASE_DEC, NULL, 0x0,
1109       NULL, HFILL }
1110       },
1111       { &hf_ams_adsversionrevision,
1112       { "ADS Minor Version", "ams.ads_versionrevision",
1113       FT_UINT8, BASE_DEC, NULL, 0x0,
1114       NULL, HFILL }
1115       },
1116       { &hf_ams_adsversionbuild,
1117       { "ADS Version Build", "ams.ads_versionbuild",
1118       FT_UINT16, BASE_DEC, NULL, 0x0,
1119       NULL, HFILL }
1120       },
1121       { &hf_ams_adsnoteblocksstamps,
1122       { "Count of Stamps", "ams.ads_noteblocksstamps",
1123       FT_UINT32, BASE_DEC, NULL, 0x0,
1124       NULL, HFILL }
1125       },
1126       { &hf_ams_adsnoteblocksstamp,
1127       { "Notification Stamp", "ams.ads_noteblocksstamp",
1128       FT_NONE, BASE_NONE, NULL, 0x0,
1129       NULL, HFILL }
1130       },
1131       { &hf_ams_adstimestamp,
1132       { "Time Stamp", "ams.ads_timestamp",
1133       FT_UINT64, BASE_DEC, NULL, 0x0,
1134       NULL, HFILL }
1135       },
1136       { &hf_ams_adssamplecnt,
1137       { "Count of Stamps", "ams.ads_samplecnt",
1138       FT_UINT32, BASE_DEC, NULL, 0x0,
1139       NULL, HFILL }
1140       },
1141       { &hf_ams_adsnoteblockssample,
1142       { "Notification Sample", "ams.ads_noteblockssample",
1143       FT_NONE, BASE_NONE, NULL, 0x0,
1144       NULL, HFILL }
1145       },
1146       { &hf_ams_adstransmode,
1147       { "Trans Mode", "ams.ads_transmode",
1148       FT_UINT32, BASE_DEC, VALS(TransMode), 0x0,
1149       NULL, HFILL }
1150       },
1151       { &hf_ams_adsmaxdelay,
1152       { "Max Delay", "ams.ads_maxdelay",
1153       FT_UINT32, BASE_DEC, NULL, 0x0,
1154       NULL, HFILL }
1155       },
1156       { &hf_ams_adscycletime,
1157       { "Cycle Time", "ams.ads_cycletime",
1158       FT_UINT32, BASE_DEC, NULL, 0x0,
1159       NULL, HFILL }
1160       },
1161       { &hf_ams_adscmpmax,
1162       { "Cmp Mad", "ams.ads_cmpmax",
1163       FT_NONE, BASE_NONE, NULL, 0x0,
1164       NULL, HFILL }
1165       },
1166       { &hf_ams_adscmpmin,
1167       { "Cmp Min", "ams.ads_cmpmin",
1168       FT_NONE, BASE_NONE, NULL, 0x0,
1169       NULL, HFILL }
1170       }
1171    };
1172
1173    static gint *ett[] =
1174    {
1175       &ett_ams,
1176       &ett_ams_stateflags,
1177       &ett_ams_adsreadrequest,
1178       &ett_ams_adsreadresponse,
1179       &ett_ams_adswriterequest,
1180       &ett_ams_adswriteresponse,
1181       &ett_ams_adsreadwriterequest,
1182       &ett_ams_adsreadwriteresponse,
1183       &ett_ams_adsreadstaterequest,
1184       &ett_ams_adsreadstateresponse,
1185       &ett_ams_adswritectrlrequest,
1186       &ett_ams_adswritectrlresponse,
1187       &ett_ams_adsreaddinforequest,
1188       &ett_ams_adsreaddinforesponse,
1189       &ett_ams_adsadddnrequest,
1190       &ett_ams_adsadddnresponse,
1191       &ett_ams_adsdeldnrequest,
1192       &ett_ams_adsdeldnresponse,
1193       &ett_ams_adsdnrequest
1194    };
1195
1196    proto_ams = proto_register_protocol("AMS", "AMS", "ams");
1197    proto_register_field_array(proto_ams, hf, array_length(hf));
1198    proto_register_subtree_array(ett, array_length(ett));
1199
1200    register_dissector("ams", dissect_ams, proto_ams);
1201 }
1202
1203 /* The registration hand-off routing */
1204
1205 void proto_reg_handoff_ams(void)
1206 {
1207    dissector_handle_t ams_handle;
1208
1209    ams_handle = find_dissector("ams");
1210    dissector_add_uint("tcp.port", 0xbf02, ams_handle);
1211    dissector_add_uint("ecatf.type", 2, ams_handle);
1212 }