Convert 'encoding' parameter of certain proto_tree_add_item() calls in non-autogenera...
[obnox/wireshark/wip.git] / epan / dissectors / packet-sercosiii.c
1 /* packet-sercosiii.c
2  * Routines for SERCOS III dissection
3  *
4  * Initial plugin code by,
5  * Bosch Rexroth
6  * Hilscher
7  *
8  * Hans-Peter Bock <hpbock@avaapgh.de>
9  *
10  * Convert to built-in dissector
11  *   Michael Mann * Copyright 2011
12  *
13  * $Id$
14  * 
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39
40 #include <epan/packet.h>
41 #include <epan/etypes.h>
42
43 #define MAX_SERCOS_DEVICES (512)
44 #define SERCOS_SLAVE_GROUP_SIZE (128)
45
46 #define COMMUNICATION_PHASE_0 (0x0)
47 #define COMMUNICATION_PHASE_1 (0x1)
48 #define COMMUNICATION_PHASE_2 (0x2)
49 #define COMMUNICATION_PHASE_3 (0x3)
50 #define COMMUNICATION_PHASE_4 (0x4)
51
52
53 /* Initialize the protocol and registered fields */
54 static gint proto_siii = -1;
55
56 /* Initialize the subtree pointers */
57 static gint ett_siii = -1;
58 static gint ett_siii_header = -1;
59 static gint ett_siii_mst = -1;
60 static gint ett_siii_mst_teltype = -1;
61 static gint ett_siii_mst_phase = -1;
62 static gint ett_siii_mdt = -1;
63 static gint ett_siii_mdt_svc = -1;
64 static gint ett_siii_mdt_devctrls = -1;
65 static gint ett_siii_mdt_version = -1;
66 static gint ett_siii_mdt_svc_channel = -1;
67 static gint ett_siii_mdt_dev_control = -1;
68 static gint ett_siii_mdt_devctrl = -1;
69 static gint ett_siii_mdt_svcctrl = -1;
70 static gint ett_siii_mdt_svcinfo = -1;
71 static gint ett_siii_at_svcstat = -1;
72 static gint ett_siii_at_svcinfo = -1;
73 static gint ett_siii_mdt_svch_data_error_info = -1;
74 static gint ett_siii_mdt_svch_data = -1;
75 static gint ett_siii_at_devstatus = -1;
76 static gint ett_siii_at = -1;
77 static gint ett_siii_at_svc = -1;
78 static gint ett_siii_at_devstats = -1;
79 static gint ett_siii_at_svc_channel = -1;
80 static gint ett_siii_at_dev_status = -1;
81 static gint ett_siii_mdt_hp = -1;
82 static gint ett_siii_at_hp = -1;
83 static gint ett_siii_mdt_hp_ctrl = -1;
84 static gint ett_siii_mdt_hp_info = -1;
85 static gint ett_siii_at_hp_stat = -1;
86 static gint ett_siii_at_hp_info = -1;
87
88 static gint hf_siii_mdt_version = -1;
89 static gint hf_siii_mdt_version_initprocvers = -1;
90 static gint hf_siii_mdt_version_num_mdt_at_cp1_2 = -1;
91 static gint hf_siii_mdt_version_revision = -1;
92 static gint hf_siii_mdt_dev_control_top_control = -1;
93 static gint hf_siii_at_dev_control_ident = -1;
94 static gint hf_siii_mdt_dev_control_change_topology = -1;
95 static gint hf_siii_mdt_dev_control = -1;
96 static gint hf_siii_mst_channel = -1;
97 static gint hf_siii_mst_type = -1;
98 static gint hf_siii_mst_cyclecntvalid = -1;
99 static gint hf_siii_mst_telno = -1;
100 static gint hf_siii_mst_phase = -1;
101 static gint hf_siii_mst_cyclecnt = -1;
102 static gint hf_siii_mst_crc32 = -1;
103 static gint hf_siii_mdt_svch_dbe = -1;
104 static gint hf_siii_mdt_svch_eot = -1;
105 static gint hf_siii_mdt_svch_rw = -1;
106 static gint hf_siii_mdt_svch_mhs = -1;
107 static gint hf_siii_mdt_svch_info = -1;
108 static gint hf_siii_at_svch_valid = -1;
109 static gint hf_siii_at_svch_error = -1;
110 static gint hf_siii_at_svch_busy = -1;
111 static gint hf_siii_at_svch_ahs = -1;
112 static gint hf_siii_at_svch_info = -1;
113 static gint hf_siii_mdt_svch_idn = -1;
114 static gint hf_siii_mdt_svch_ctrl = -1;
115 static gint hf_siii_at_svch_stat = -1;
116 static gint hf_siii_svch_data_telofs_telno = -1;
117 static gint hf_siii_svch_data_telofs_mdt_at = -1;
118 static gint hf_siii_svch_data_telofs_offset = -1;
119 static gint hf_siii_svch_data_proccmd_proccmdexec = -1;
120 static gint hf_siii_svch_data_proccmd_proccmd = -1;
121 static gint hf_siii_at_dev_status = -1;
122 static gint hf_siii_at_dev_status_commwarning = -1;
123 static gint hf_siii_at_dev_status_change_topology = -1;
124 static gint hf_siii_at_dev_status_top_status = -1;
125 static gint hf_siii_at_dev_status_inactive_port_status = -1;
126 static gint hf_siii_at_dev_status_errorconnection = -1;
127 static gint hf_siii_at_dev_status_slave_valid = -1;
128 static gint hf_siii_at_dev_status_proc_command_change = -1;
129 static gint hf_siii_at_dev_status_parameterization_level_active = -1;
130 static gint hf_siii_mdt_hotplug_address = -1;
131 static gint hf_siii_mdt_hp_ctrl = -1;
132 static gint hf_siii_mdt_hp_info = -1;
133 static gint hf_siii_at_hotplug_address = -1;
134 static gint hf_siii_at_hp_stat = -1;
135 static gint hf_siii_at_hp_info = -1;
136 static gint hf_siii_mdt_hotplug_control_param = -1;
137 static gint hf_siii_mdt_hotplug_control_svc_switch = -1;
138 static gint hf_siii_at_hotplug_status_param = -1;
139 static gint hf_siii_at_hotplug_status_hp0_finished = -1;
140 static gint hf_siii_at_hotplug_status_error = -1;
141
142 /* Allow heuristic dissection */
143 static heur_dissector_list_t heur_subdissector_list;
144
145 static const value_string siii_mdt_version_num_mdtat_cp1_2_text[]=
146 {
147   {0x00, "2 MDTs/ATs in CP1/2"},
148   {0x01, "4 MDTs/ATs in CP1/2"},
149   {0, NULL}
150 };
151
152 static const value_string siii_mdt_version_initprocvers_text[]=
153 {
154   {0x00, "No remote address allocation"},
155   {0x01, "Remote address allocation"},
156   {0, NULL}
157 };
158
159 static const value_string siii_svch_data_proccmd_proccmdexec_text[]=
160 {
161   {0, "Interrupt procedure command execution"},
162   {1, "Enable procedure command execution"},
163   {0, NULL}
164 };
165
166 static const value_string siii_svch_data_proccmd_proccmd_text[]=
167 {
168   {0, "Cancel procedure command"},
169   {1, "Set procedure command"},
170   {0, NULL}
171 };
172
173 static const value_string siii_svch_data_mdt_at_text[]=
174 {
175   {0, "AT-telegram"},
176   {1, "MDT-telegram"},
177   {0, NULL}
178 };
179
180 #define IDN(SI, SE, type, paramset, datablock) ((SI<<24)|(SE<<16)|(type<<15)|(paramset<<12)|(datablock))
181
182 static const value_string siii_mdt_idn_text[]=
183 {
184   {IDN(0,0,0,0,   0), "Dummy-Parameter"},
185   {IDN(0,0,0,0,   1), "Control unit cycle time (tNcyc)"},
186   {IDN(0,0,0,0,   2), "Communication cycle time (tScyc)"},
187   {IDN(0,0,0,0,  11), "Class 1 diagnostic"},
188   {IDN(0,0,0,0,  12), "Class 2 diagnostic"},
189   {IDN(0,0,0,0,  14), "Interface status"},
190   {IDN(0,0,0,0,  15), "Telegram Type"},
191   {IDN(0,0,0,0,  16), "Configuration list of AT"},
192   {IDN(0,0,0,0,  17), "IDN-list of all operation data"},
193   {IDN(0,0,0,0,  18), "IDN-list of operation data for CP2"},
194   {IDN(0,0,0,0,  19), "IDN-list of operation data for CP3"},
195   {IDN(0,0,0,0,  21), "IDN-list of invalid operation data for CP2"},
196   {IDN(0,0,0,0,  22), "IDN-list of invalid operation data for CP3"},
197   {IDN(0,0,0,0,  24), "Configuration list of MDT"},
198   {IDN(0,0,0,0,  25), "IDN-list of all procedure commands"},
199   {IDN(0,0,0,0,  26), "Configuration list for signal status word"},
200   {IDN(0,0,0,0,  27), "Configuration list for signal control word"},
201   {IDN(0,0,0,0,  28), "MST error counter"},
202   {IDN(0,0,0,0,  29), "MDT error counter"},
203   {IDN(0,0,0,0,  32), "Primary operation mode"},
204   {IDN(0,0,0,0,  36), "Velocity command value"},
205   {IDN(0,0,0,0,  37), "Additive velocity command value"},
206   {IDN(0,0,0,0,  38), "Positive velocity limit value"},
207   {IDN(0,0,0,0,  39), "Negative velocity limit value"},
208   {IDN(0,0,0,0,  40), "Velocity feedback value 1"},
209   {IDN(0,0,0,0,  41), "Homing velocity"},
210   {IDN(0,0,0,0,  42), "Homing acceleration"},
211   {IDN(0,0,0,0,  43), "Velocity polarity parameter"},
212   {IDN(0,0,0,0,  44), "Velocity data scaling type"},
213   {IDN(0,0,0,0,  45), "Velocity data scaling factor"},
214   {IDN(0,0,0,0,  46), "Velocity data scaling exponent"},
215   {IDN(0,0,0,0,  47), "Position command value"},
216   {IDN(0,0,0,0,  48), "Additive position command value"},
217   {IDN(0,0,0,0,  49), "Positive position limit value"},
218   {IDN(0,0,0,0,  50), "Negative position limit value"},
219   {IDN(0,0,0,0,  51), "Position feedback value 1 (motor feedback)"},
220   {IDN(0,0,0,0,  52), "Reference distance 1"},
221   {IDN(0,0,0,0,  53), "Position feedback value 2 (external feedback)"},
222   {IDN(0,0,0,0,  54), "Reference distance 2"},
223   {IDN(0,0,0,0,  55), "Position polarity parameter"},
224   {IDN(0,0,0,0,  57), "Position window"},
225   {IDN(0,0,0,0,  58), "Reversal clearance"},
226   {IDN(0,0,0,0,  59), "Position switch flag parameter"},
227   {IDN(0,0,0,0,  60), "Position switches (position switch points on 1-16)"},
228   {IDN(0,0,0,0,  76), "Position data scaling type"},
229   {IDN(0,0,0,0,  77), "Linear position data scaling factor"},
230   {IDN(0,0,0,0,  78), "Linear position data scaling exponent"},
231   {IDN(0,0,0,0,  79), "Rotational position resolution"},
232   {IDN(0,0,0,0,  80), "Torque command value"},
233   {IDN(0,0,0,0,  81), "Additive torque command value"},
234   {IDN(0,0,0,0,  82), "Positive torque limit value"},
235   {IDN(0,0,0,0,  83), "Negative torque limit value"},
236   {IDN(0,0,0,0,  84), "Torque feedback value"},
237   {IDN(0,0,0,0,  85), "Torque polarity parameter"},
238   {IDN(0,0,0,0,  86), "Torque/force data scaling type"},
239   {IDN(0,0,0,0,  91), "Bipolar velocity limit value"},
240   {IDN(0,0,0,0,  92), "Bipolar torque limit value"},
241   {IDN(0,0,0,0,  93), "Torque/force scaling data factor"},
242   {IDN(0,0,0,0,  94), "Torque/force scaling data exponent"},
243   {IDN(0,0,0,0,  95), "Diagnostic message"},
244   {IDN(0,0,0,0,  96), "Slave arrangement (SLKN)"},
245   {IDN(0,0,0,0,  97), "Mask class 2 diagnostic"},
246   {IDN(0,0,0,0,  98), "Mask class 3 diagnostic"},
247   {IDN(0,0,0,0,  99), "Reset class 1 diagnostic"},
248   {IDN(0,0,0,0, 100), "Velocity loop proportional gain"},
249   {IDN(0,0,0,0, 101), "Velocity loop integral action time"},
250   {IDN(0,0,0,0, 102), "Velocity loop differential time"},
251   {IDN(0,0,0,0, 103), "Modulo value"},
252   {IDN(0,0,0,0, 104), "Position loop KV-factor"},
253   {IDN(0,0,0,0, 105), "Position loop integral action time"},
254   {IDN(0,0,0,0, 106), "Current loop proportional gain 1"},
255   {IDN(0,0,0,0, 107), "Current loop integral action time 1"},
256   {IDN(0,0,0,0, 108), "Feedrate override"},
257   {IDN(0,0,0,0, 109), "Motor peak current"},
258   {IDN(0,0,0,0, 110), "Amplifier peak current"},
259   {IDN(0,0,0,0, 111), "Motor continuous stall current"},
260   {IDN(0,0,0,0, 112), "Amplifier rated current"},
261   {IDN(0,0,0,0, 113), "Maximum motor speed"},
262   {IDN(0,0,0,0, 114), "Load limit of the motor"},
263   {IDN(0,0,0,0, 115), "Position feedback 2 type"},
264   {IDN(0,0,0,0, 116), "Resolution of feedback 1"},
265   {IDN(0,0,0,0, 117), "Resolution of feedback 2"},
266   {IDN(0,0,0,0, 118), "Resolution of linear feedback"},
267   {IDN(0,0,0,0, 119), "Current loop proportional gain 2"},
268   {IDN(0,0,0,0, 120), "Current loop integral action time 2"},
269   {IDN(0,0,0,0, 121), "Input revolutions of load gear"},
270   {IDN(0,0,0,0, 122), "Output revolutions of load gear"},
271   {IDN(0,0,0,0, 123), "Feed constant"},
272   {IDN(0,0,0,0, 124), "Standstill window"},
273   {IDN(0,0,0,0, 125), "Velocity threshold (nx)"},
274   {IDN(0,0,0,0, 126), "Torque threshold (Tx)"},
275   {IDN(0,0,0,0, 127), "CP3 transition check"},
276   {IDN(0,0,0,0, 128), "CP4 transition check"},
277   {IDN(0,0,0,0, 129), "Manufacturer class 1 diagnostic"},
278   {IDN(0,0,0,0, 130), "Probe value 1 positive edge"},
279   {IDN(0,0,0,0, 131), "Probe value 1 negative edge"},
280   {IDN(0,0,0,0, 132), "Probe value 2 positive edge"},
281   {IDN(0,0,0,0, 133), "Probe value 2 negative edge"},
282   {IDN(0,0,0,0, 134), "Drive control"},
283   {IDN(0,0,0,0, 135), "Drive status"},
284   {IDN(0,0,0,0, 136), "Positive acceleration limit value"},
285   {IDN(0,0,0,0, 137), "Negative acceleration limit value"},
286   {IDN(0,0,0,0, 138), "Bipolar acceleration limit value"},
287   {IDN(0,0,0,0, 139), "Park axis procedure command"},
288   {IDN(0,0,0,0, 143), "SERCOS Interface version"},
289   {IDN(0,0,0,0, 144), "Signal status word"},
290   {IDN(0,0,0,0, 145), "Signal control word"},
291   {IDN(0,0,0,0, 146), "Control unit controlled homing procedure command"},
292   {IDN(0,0,0,0, 147), "Homing parameter"},
293   {IDN(0,0,0,0, 148), "Drive controlled homing procedure command"},
294   {IDN(0,0,0,0, 149), "Position drive stop procedure command"},
295   {IDN(0,0,0,0, 150), "Reference offset 1"},
296   {IDN(0,0,0,0, 151), "Reference offset 2"},
297   {IDN(0,0,0,0, 152), "Position spindle procedure command"},
298   {IDN(0,0,0,0, 153), "Spindle angle position"},
299   {IDN(0,0,0,0, 154), "Spindle positioning parameter"},
300   {IDN(0,0,0,0, 155), "Friction torque compensation"},
301   {IDN(0,0,0,0, 156), "Velocity feedback value 2"},
302   {IDN(0,0,0,0, 157), "Velocity window"},
303   {IDN(0,0,0,0, 158), "Power threshold (Px)"},
304   {IDN(0,0,0,0, 159), "Monitoring window"},
305   {IDN(0,0,0,0, 161), "Acceleration data scaling factor"},
306   {IDN(0,0,0,0, 162), "Acceleration data scaling exponent"},
307   {IDN(0,0,0,0, 163), "Weight counterbalance"},
308   {IDN(0,0,0,0, 164), "Acceleration feedback value 1"},
309   {IDN(0,0,0,0, 165), "Distance-coded reference marks A"},
310   {IDN(0,0,0,0, 166), "Distance-coded reference marks B"},
311   {IDN(0,0,0,0, 167), "Frequency limit of feedback 1"},
312   {IDN(0,0,0,0, 169), "Probe control"},
313   {IDN(0,0,0,0, 170), "Probing cycle procedure command"},
314   {IDN(0,0,0,0, 171), "Calculate displacement procedure command"},
315   {IDN(0,0,0,0, 172), "Displacement to the referenced system procedure command"},
316   {IDN(0,0,0,0, 173), "Marker position A"},
317   {IDN(0,0,0,0, 174), "Marker position B"},
318   {IDN(0,0,0,0, 175), "Displacement parameter 1"},
319   {IDN(0,0,0,0, 176), "Displacement parameter 2"},
320   {IDN(0,0,0,0, 177), "Absolute distance 1"},
321   {IDN(0,0,0,0, 178), "Absolute distance 2"},
322   {IDN(0,0,0,0, 179), "Probe status"},
323   {IDN(0,0,0,0, 180), "Spindle relative offset"},
324   {IDN(0,0,0,0, 181), "Manufacturer class 2 diagnostic"},
325   {IDN(0,0,0,0, 183), "Synchronization velocity window"},
326   {IDN(0,0,0,0, 184), "Synchronization velocity error limit"},
327   {IDN(0,0,0,0, 185), "Length of the configurable data record in the AT"},
328   {IDN(0,0,0,0, 186), "Length of the configurable data record in the MDT"},
329   {IDN(0,0,0,0, 187), "IDN list of configurable data in the AT"},
330   {IDN(0,0,0,0, 188), "IDN list of configurable data in the MDT"},
331   {IDN(0,0,0,0, 189), "Following distance"},
332   {IDN(0,0,0,0, 190), "Drive controlled gear engaging procedure command"},
333   {IDN(0,0,0,0, 191), "Cancel reference point procedure command"},
334   {IDN(0,0,0,0, 192), "IDN-list of all backup operation data"},
335   {IDN(0,0,0,0, 193), "Positioning jerk"},
336   {IDN(0,0,0,0, 194), "Acceleration command time"},
337   {IDN(0,0,0,0, 195), "Acceleration feedback value 2"},
338   {IDN(0,0,0,0, 196), "Motor rated current"},
339   {IDN(0,0,0,0, 197), "Set coordinate system procedure command"},
340   {IDN(0,0,0,0, 198), "Initial coordinate value"},
341   {IDN(0,0,0,0, 199), "Shift coordinate system procedure command"},
342   {IDN(0,0,0,0, 200), "Amplifier warning temperature"},
343   {IDN(0,0,0,0, 201), "Motor warning temperature"},
344   {IDN(0,0,0,0, 202), "Cooling error warning temperature"},
345   {IDN(0,0,0,0, 203), "Amplifier shut-down temperature"},
346   {IDN(0,0,0,0, 204), "Motor shut-down temperature"},
347   {IDN(0,0,0,0, 205), "Cooling error shut-down temperature"},
348   {IDN(0,0,0,0, 206), "Drive on delay time"},
349   {IDN(0,0,0,0, 207), "Drive off delay time"},
350   {IDN(0,0,0,0, 208), "Temperature data scaling type"},
351   {IDN(0,0,0,0, 209), "Lower adaptation limit"},
352   {IDN(0,0,0,0, 210), "Upper adaptation limit"},
353   {IDN(0,0,0,0, 211), "Adaptation proportional gain"},
354   {IDN(0,0,0,0, 212), "Adaptation integral action time"},
355   {IDN(0,0,0,0, 213), "Engaging dither amplitude"},
356   {IDN(0,0,0,0, 214), "Average engaging speed"},
357   {IDN(0,0,0,0, 215), "Engaging dither period"},
358   {IDN(0,0,0,0, 216), "Switch parameter set procedure command"},
359   {IDN(0,0,0,0, 217), "Parameter set preselection"},
360   {IDN(0,0,0,0, 218), "Gear-ration preselection"},
361   {IDN(0,0,0,0, 219), "IDN-list of parameter set"},
362   {IDN(0,0,0,0, 220), "Minimum spindle speed"},
363   {IDN(0,0,0,0, 221), "Maximum spindle speed"},
364   {IDN(0,0,0,0, 222), "Spindle positioning speed"},
365   {IDN(0,0,0,0, 223), "Drive controlled synchronous operation procedure command"},
366   {IDN(0,0,0,0, 224), "Lead Spindle Address"},
367   {IDN(0,0,0,0, 225), "Synchronous spindle revolutions"},
368   {IDN(0,0,0,0, 226), "Lead spindle revolutions"},
369   {IDN(0,0,0,0, 227), "Synchronous spindle revolutions"},
370   {IDN(0,0,0,0, 228), "Synchronization position window"},
371   {IDN(0,0,0,0, 229), "Synchronization position error limit"},
372   {IDN(0,0,0,0, 230), "Synchronization position offset"},
373   {IDN(0,0,0,0, 254), "Actual parameter set"},
374   {IDN(0,0,0,0, 255), "Actual gear ration"},
375   {IDN(0,0,0,0, 256), "Multiplication factor 1"},
376   {IDN(0,0,0,0, 257), "Multiplication factor 2"},
377   {IDN(0,0,0,0, 258), "Target position"},
378   {IDN(0,0,0,0, 259), "Positioning velocity"},
379   {IDN(0,0,0,0, 260), "Positioning acceleration"},
380   {IDN(0,0,0,0, 261), "Coarse position window"},
381   {IDN(0,0,0,0, 262), "Load defaults procedure command"},
382   {IDN(0,0,0,0, 263), "Load working memory procedure command"},
383   {IDN(0,0,0,0, 264), "Backup working memory procedure command"},
384   {IDN(0,0,0,0, 265), "Language selection"},
385   {IDN(0,0,0,0, 266), "List of available languages"},
386   {IDN(0,0,0,0, 267), "Password"},
387   {IDN(0,0,0,0, 268), "Angular setting"},
388   {IDN(0,0,0,0, 269), "Storage mode"},
389   {IDN(0,0,0,0, 270), "IDN-list of selected backup operation data"},
390   {IDN(0,0,0,0, 272), "Velocity window percentage"},
391   {IDN(0,0,0,0, 273), "Maximum drive off delay time"},
392   {IDN(0,0,0,0, 275), "Coordinate offset value"},
393   {IDN(0,0,0,0, 276), "Return to Modulo range procedure command"},
394   {IDN(0,0,0,0, 277), "Position feedback 1 type"},
395   {IDN(0,0,0,0, 278), "Maximum travel range"},
396   {IDN(0,0,0,0, 279), "IDN list of password protected data"},
397   {IDN(0,0,0,0, 280), "Underflow threshold"},
398   {IDN(0,0,0,0, 282), "Positioning command value"},
399   {IDN(0,0,0,0, 283), "Current coordinate offset"},
400   {IDN(0,0,0,0, 292), "List of supported operation modes"},
401   {IDN(0,0,0,0, 293), "Selectively backup working memory procedure command"},
402   {IDN(0,0,0,0, 294), "Divider modulo value"},
403   {IDN(0,0,0,0, 295), "Drive enable delay time"},
404   {IDN(0,0,0,0, 296), "Velocity feed forward gain"},
405   {IDN(0,0,0,0, 297), "Homing distance"},
406   {IDN(0,0,0,0, 298), "Suggest home switch distance"},
407   {IDN(0,0,0,0, 299), "Home switch offset 1"},
408   {IDN(0,0,0,0, 300), "Real-time control bit 1"},
409   {IDN(0,0,0,0, 301), "Allocation of real-time control bit 1",},
410   {IDN(0,0,0,0, 302), "Real-time control bit 2"},
411   {IDN(0,0,0,0, 303), "Allocation of real-time control bit 2"},
412   {IDN(0,0,0,0, 304), "Real-time status bit 1"},
413   {IDN(0,0,0,0, 305), "Allocation of real-time status bit 1"},
414   {IDN(0,0,0,0, 306), "Real-time status-bit 2"},
415   {IDN(0,0,0,0, 307), "Allocation of real-time status bit 2"},
416   {IDN(0,0,0,0, 308), "Synchronization operation status"},
417   {IDN(0,0,0,0, 309), "Synchronization error status"},
418   {IDN(0,0,0,0, 310), "Overload warning"},
419   {IDN(0,0,0,0, 311), "Amplifier overtemperature warning"},
420   {IDN(0,0,0,0, 312), "Motor overtemperature warning"},
421   {IDN(0,0,0,0, 313), "Cooling error warning"},
422   {IDN(0,0,0,0, 315), "Positioning velocity higher than n Limit"},
423   {IDN(0,0,0,0, 323), "Target position outside of travel range"},
424   {IDN(0,0,0,0, 326), "Parameter checksum"},
425   {IDN(0,0,0,0, 327), "IDN list of checksum parameter"},
426   {IDN(0,0,0,0, 328), "Bit number allocation list for signal status word"},
427   {IDN(0,0,0,0, 329), "Bit number allocation list for signal control word"},
428   {IDN(0,0,0,0, 330), "Status 'nfeedback = ncommand'"},
429   {IDN(0,0,0,0, 331), "Status 'nfeedback = 0'"},
430   {IDN(0,0,0,0, 332), "Status 'nfeedback less then nx'"},
431   {IDN(0,0,0,0, 333), "Status 'T higher than Tx'"},
432   {IDN(0,0,0,0, 334), "Status 'T greater than Tlimit '"},
433   {IDN(0,0,0,0, 335), "Status 'ncommand greater than nlimit'"},
434   {IDN(0,0,0,0, 336), "Status 'In position'"},
435   {IDN(0,0,0,0, 337), "Status 'P greater Px'"},
436   {IDN(0,0,0,0, 338), "Status 'Position feedback = active target position'"},
437   {IDN(0,0,0,0, 339), "Status 'nfeedback less than minimum spindle speed'"},
438   {IDN(0,0,0,0, 340), "Status 'nfeedback exceeds maximum spindle speed'"},
439   {IDN(0,0,0,0, 341), "Status 'In Coarse position'"},
440   {IDN(0,0,0,0, 342), "Status 'Target position attained'"},
441   {IDN(0,0,0,0, 343), "Status 'Interpolator halted'"},
442   {IDN(0,0,0,0, 346), "Positioning control"},
443   {IDN(0,0,0,0, 347), "Velocity error"},
444   {IDN(0,0,0,0, 348), "Acceleration feed forward gain"},
445   {IDN(0,0,0,0, 349), "Bipolar jerk limit"},
446   {IDN(0,0,0,0, 356), "Distance home switch - marker puls"},
447   {IDN(0,0,0,0, 357), "Marker pulse distance"},
448   {IDN(0,0,0,0, 358), "Home switch offset 2"},
449   {IDN(0,0,0,0, 359), "Positioning deceleration"},
450   {IDN(0,0,0,0, 360), "MDT data container"},
451   {IDN(0,0,0,0, 362), "MDT data container A list index"},
452   {IDN(0,0,0,0, 364), "AT data container A1"},
453   {IDN(0,0,0,0, 366), "AT data container A list index"},
454   {IDN(0,0,0,0, 368), "Data container A pointer"},
455   {IDN(0,0,0,0, 370), "MDT data container A/B configuration list"},
456   {IDN(0,0,0,0, 371), "AT data container A/B configuration list"},
457   {IDN(0,0,0,0, 372), "Drive Halt acceleration bipolar"},
458   {IDN(0,0,0,0, 377), "Velocity feedback monitoring window"},
459   {IDN(0,0,0,0, 378), "Absolute encoder range 1"},
460   {IDN(0,0,0,0, 379), "Absolute encoder range 2"},
461   {IDN(0,0,0,0, 380), "DC bus voltage"},
462   {IDN(0,0,0,0, 381), "DC bus current"},
463   {IDN(0,0,0,0, 382), "DC bus power"},
464   {IDN(0,0,0,0, 383), "Motor temperature"},
465   {IDN(0,0,0,0, 384), "Amplifier temperature"},
466   {IDN(0,0,0,0, 385), "Active power"},
467   {IDN(0,0,0,0, 386), "Active position feedback value"},
468   {IDN(0,0,0,0, 387), "Power overload"},
469   {IDN(0,0,0,0, 388), "Braking current limit"},
470   {IDN(0,0,0,0, 389), "Effective current"},
471   {IDN(0,0,0,0, 390), "DiagnosticNumber"},
472   {IDN(0,0,0,0, 391), "Position feedback monitoring window"},
473   {IDN(0,0,0,0, 392), "Velocity feedback filter"},
474   {IDN(0,0,0,0, 393), "Command value mode"},
475   {IDN(0,0,0,0, 398), "IDN list of configurable real-time/status bits"},
476   {IDN(0,0,0,0, 399), "IDN list of configurable real-time/control bits"},
477   {IDN(0,0,0,0, 400), "Home switch"},
478   {IDN(0,0,0,0, 401), "Probe 1"},
479   {IDN(0,0,0,0, 402), "Probe 2"},
480   {IDN(0,0,0,0, 403), "Position feedback value status"},
481   {IDN(0,0,0,0, 404), "Position command value status"},
482   {IDN(0,0,0,0, 405), "Probe 1 enable"},
483   {IDN(0,0,0,0, 406), "Probe 2 enable"},
484   {IDN(0,0,0,0, 407), "Homing enable"},
485   {IDN(0,0,0,0, 408), "Reference marker pulse registered"},
486   {IDN(0,0,0,0, 409), "Probe 1 positive latched"},
487   {IDN(0,0,0,0, 410), "Probe 1 negative latched"},
488   {IDN(0,0,0,0, 411), "Probe 2 positive latched"},
489   {IDN(0,0,0,0, 412), "Probe 2 negative latched"},
490   {IDN(0,0,0,0, 413), "Bit number allocation of real-time control bit 1"},
491   {IDN(0,0,0,0, 414), "Bit number allocation of real-time control bit 2"},
492   {IDN(0,0,0,0, 415), "Bit number allocation of real-time status bit 1"},
493   {IDN(0,0,0,0, 416), "Bit number allocation of real-time status bit 2"},
494   {IDN(0,0,0,0, 417), "Positioning velocity threshold in modulo mode"},
495   {IDN(0,0,0,0, 418), "Target position window in modulo mode"},
496   {IDN(0,0,0,0, 419), "Positioning acknowledge"},
497   {IDN(0,0,0,0, 420), "Activate parametrization level procedure command (PL)"},
498   {IDN(0,0,0,0, 422), "Exit parameterization level procedure command"},
499   {IDN(0,0,0,0, 423), "IDN-list of invalid data for parameterization level"},
500   {IDN(0,0,0,0, 426), "Measuring data allocation 1"},
501   {IDN(0,0,0,0, 427), "Measuring data allocation 2"},
502   {IDN(0,0,0,0, 428), "IDN list of configurable measuring data"},
503   {IDN(0,0,0,0, 429), "Emergency stop deceleration"},
504   {IDN(0,0,0,0, 430), "Active target position"},
505   {IDN(0,0,0,0, 431), "Spindle positioning acceleration bipolar"},
506   {IDN(0,0,0,0, 437), "Positioning status"},
507   {IDN(0,0,0,0, 446), "Ramp reference velocity"},
508   {IDN(0,0,0,0, 447), "Set absolute position procedure command"},
509   {IDN(0,0,0,0, 448), "Set absolute position control word"},
510   {IDN(0,0,0,0, 460), "Position switches (position switch points off 1-16)"},
511   {IDN(0,0,0,0, 476), "Position switch control"},
512   {IDN(0,0,0,0, 477), "Position switch hysteresis"},
513   {IDN(0,0,0,0, 478), "Limit switch status"},
514   {IDN(0,0,0,0, 509), "Extended probe control"},
515   {IDN(0,0,0,0, 510), "Difference value probe 1"},
516   {IDN(0,0,0,0, 511), "Difference value probe 2"},
517   {IDN(0,0,0,0, 512), "Start position probing window 1"},
518   {IDN(0,0,0,0, 513), "End position probing window 1"},
519   {IDN(0,0,0,0, 514), "Start position probing window 2"},
520   {IDN(0,0,0,0, 515), "End position probing window 2"},
521   {IDN(0,0,0,0, 516), "Marker losses probe 1"},
522   {IDN(0,0,0,0, 517), "Marker losses probe 2"},
523   {IDN(0,0,0,0, 518), "Maximum marker losses probe 1"},
524   {IDN(0,0,0,0, 519), "Maximum marker losses probe 2"},
525   {IDN(0,0,0,0, 520), "Axis control word"},
526   {IDN(0,0,0,0, 521), "Axis status word"},
527   {IDN(0,0,0,0, 522), "Difference value 1 latched"},
528   {IDN(0,0,0,0, 523), "Difference value 2 latched"},
529   {IDN(0,0,0,0, 524), "Probe 1 delay positive"},
530   {IDN(0,0,0,0, 525), "Delay Negative Edge, Probe 1"},
531   {IDN(0,0,0,0, 526), "Delay positive Edge, Probe 2"},
532   {IDN(0,0,0,0, 527), "Delay Negative Edge, Probe 2"},
533   {IDN(0,0,0,0, 530), "Clamping torque"},
534   {IDN(0,0,0,0, 531), "Checksum for backup operation data"},
535   {IDN(0,0,0,0, 532), "Limit switch control"},
536   {IDN(0,0,0,0, 533), "Motor continuous stall torque/force"},
537   {IDN(0,0,0,0,1000), "SCP Type & Version"},
538   {IDN(0,0,0,0,1001), "SERCOS III: Control unit cycle time (tNcyc)"},
539   {IDN(0,0,0,0,1002), "SERCOS III: Communication cycle time (tScyc)"},
540   {IDN(0,0,0,0,1003), "SERCOS III: Number of successive MDT errors"},
541   {IDN(0,0,0,0,1005), "SERCOS III: Feedback value computation time (t5)"},
542   {IDN(0,0,0,0,1006), "SERCOS III: AT transmission starting time (t1)"},
543   {IDN(0,0,0,0,1007), "SERCOS III: Synchronization time (t8)"},
544   {IDN(0,0,0,0,1008), "SERCOS III: Command value valid time (t3)"},
545   {IDN(0,0,0,0,1009), "SERCOS III: Device Control offset in MDT"},
546   {IDN(0,0,0,0,1010), "SERCOS III: Length of MDT"},
547   {IDN(0,0,0,0,1011), "SERCOS III: Device Status offset in AT"},
548   {IDN(0,0,0,0,1012), "SERCOS III: Length of AT"},
549   {IDN(0,0,0,0,1013), "SERCOS III: SVC offset in MDT"},
550   {IDN(0,0,0,0,1014), "SERCOS III: SVC offset in AT"},
551   {IDN(0,0,0,0,1015), "SERCOS III: Ring delay"},
552   {IDN(0,0,0,0,1016), "SERCOS III: Slave delay"},
553   {IDN(0,0,0,0,1017), "SERCOS III: Transmission starting time IP channel"},
554   {IDN(0,0,0,0,1018), "SERCOS III: SYNC delay"},
555   {IDN(0,0,0,0,1019), "SERCOS III: MAC address"},
556   {IDN(0,0,0,0,1020), "SERCOS III: IP address"},
557   {IDN(0,0,0,0,1021), "SERCOS III: Network mask"},
558   {IDN(0,0,0,0,1022), "SERCOS III: Gateway address"},
559   {IDN(0,0,0,0,1023), "SERCOS III: Sync jitter"},
560   {IDN(0,0,0,0,1024), "SERCOS III: Ring control - node control"},
561   {IDN(0,0,0,0,1025), "SERCOS III: Ring status - node status"},
562   {IDN(0,0,0,0,1026), "SERCOS III: Hardware identification"},
563   {IDN(1,0,0,0,1027), "Requested MTU"},
564   {IDN(2,0,0,0,1027), "Effective MTU"},
565   {IDN(0,0,0,0,1028), "SERCOS III: Error counter MDT0 MST"},
566   {IDN(0,0,0,0,1029), "SERCOS III: Error counter MDT0-3"},
567   {IDN(0,0,0,0,1030), "SERCOS III: Error counter AT0-3"},
568   {IDN(0,0,0,0,1031), "Signal assignment Port 1 & Port 2"},
569   {IDN(0,0,0,0,1035), "Error counter Port1 and Port2"},
570   {IDN(0,0,0,0,1040), "SERCOSAddress"},
571   {IDN(0,0,0,0,1041), "AT Command value valid time (t9)"},
572   {IDN(0,0,0,0,1044), "Device Control"},
573   {IDN(0,0,0,0,1045), "Device Status"},
574   {IDN(0,0,0,0,1046), "IDN-list of SERCOS addresses in device"},
575   {IDN(0,0,0,0,1134), "SERCOS III: Device control"},
576   {IDN(0,0,0,0,1135), "SERCOS III: Device status"},
577   {0, NULL}
578 };
579
580 static const value_string siii_mdt_svch_dbe_text[]=
581 {
582   {0x00, "Element 0: Closed SVC"},
583   {0x01, "Element 1: Opening IDN"},
584   {0x02, "Element 2: Name of operation data"},
585   {0x03, "Element 3: Attribute of operation data"},
586   {0x04, "Element 4: Unit of operation data"},
587   {0x05, "Element 5: Minimum value of operation data"},
588   {0x06, "Element 6: Maximum value of operation data"},
589   {0x07, "Element 7: Operation data"},
590   {0, NULL}
591 };
592
593 static const value_string siii_mdt_svch_eot_text[]=
594 {
595   {0x00, "Transmission in progress"},
596   {0x01, "Last transmission"},
597   {0, NULL}
598 };
599
600 static const value_string siii_mdt_svch_rw_text[]=
601 {
602   {0x00, "Read SVC INFO"},
603   {0x01, "Write SVC INFO"},
604   {0, NULL}
605 };
606
607 static const value_string siii_mdt_devcontrol_topcontrol_text[]=
608 {
609   {0x00, "Fast Forward on P/S-Channel"},
610   {0x01, "Loopback on P-Channel and Fast Forward"},
611   {0x02, "Loopback on S-Channel and Fast Forward"},
612   {0, NULL}
613 };
614
615 static const value_string siii_at_svch_valid_text[]=
616 {
617   {0x00, "SVC not valid"},
618   {0x01, "SVC valid"},
619   {0, NULL}
620 };
621
622 static const value_string siii_at_svch_error_text[]=
623 {
624   {0x00, "No error"},
625   {0x01, "Error in SVC"},
626   {0, NULL}
627 };
628
629 static const value_string siii_at_svch_busy_text[]=
630 {
631   {0x00, "Step finished, slave ready for new step"},
632   {0x01, "Step in process, new step not allowed"},
633   {0, NULL}
634 };
635
636
637 static const value_string siii_mst_phase_text[]=
638 {
639   {0x00, "CP0"},
640   {0x01, "CP1"},
641   {0x02, "CP2"},
642   {0x03, "CP3"},
643   {0x04, "CP4"},
644   {0x80, "CP0 (Phase Change)"},
645   {0x81, "CP1 (Phase Change)"},
646   {0x82, "CP2 (Phase Change)"},
647   {0x83, "CP3 (Phase Change)"},
648   {0x84, "CP4 (Phase Change)"},
649   {0, NULL}
650 };
651
652 static const value_string siii_mst_teltype_text[]=
653 {
654   {0x00, "CP0"},
655   {0x01, "CP1"},
656   {0x02, "CP2"},
657   {0x03, "CP3"},
658   {0x04, "CP4"},
659   {0x80, "CP0 (Phase Change)"},
660   {0x81, "CP1 (Phase Change)"},
661   {0x82, "CP2 (Phase Change)"},
662   {0x83, "CP3 (Phase Change)"},
663   {0x84, "CP4 (Phase Change)"},
664   {0, NULL}
665 };
666
667 static const value_string siii_mst_channel_text[]=
668 {
669   {0x00, "P-Telegram"},
670   {0x01, "S-Telegram"},
671   {0, NULL}
672 };
673
674 static const value_string siii_mst_type_text[]=
675 {
676   {0x00, "MDT"},
677   {0x01, "AT"},
678   {0, NULL}
679 };
680
681 static const value_string siii_mst_cyclecntvalid_text[]=
682 {
683   {0x00, "Invalid"},
684   {0x01, "Valid"},
685   {0, NULL}
686 };
687
688
689 static const value_string siii_at_devstatus_errorconnection_text[]=
690 {
691   {0x00, "Error-free connection"},
692   {0x01, "Error in the connection occurs"},
693   {0, NULL}
694 };
695
696 static const value_string siii_at_devstatus_topstatus_text[]=
697 {
698   {0x00, "Fast Forward on P/S-Channel"},
699   {0x01, "Loopback on P-Channel and Fast Forward"},
700   {0x02, "Loopback on S-Channel and Fast Forward"},
701   {0, NULL}
702 };
703
704 static const value_string siii_at_devstatus_inactiveportstatus_text[]=
705 {
706   {0x00, "No link on port"},
707   {0x01, "Link on port"},
708   {0x02, "S III P-Telegram on port"},
709   {0x03, "S III S-Telegram on port"},
710   {0, NULL}
711 };
712
713 static const value_string siii_at_dev_status_proc_command_change_text[]=
714 {
715   {0x00, "No change in procedure command acknowledgement"},
716   {0x01, "Changing procedure command acknowledgement"},
717   {0, NULL}
718 };
719
720
721 static const value_string siii_mdt_hotplug_control_functioncode_text[]=
722 {
723   {0x00, "No data"},
724   {0x01, "tScyc"},
725   {0x02, "t1"},
726   {0x03, "t6"},
727   {0x04, "t7"},
728   {0x05, "Communication Version"},
729   {0x06, "Communication timeout"},
730   {0x10, "MDT0 Length"},
731   {0x11, "MDT1 Length"},
732   {0x12, "MDT2 Length"},
733   {0x13, "MDT3 Length"},
734   {0x20, "AT0 Length"},
735   {0x21, "AT1 Length"},
736   {0x22, "AT2 Length"},
737   {0x23, "AT3 Length"},
738   {0x80, "MDT-SVC pointer"},
739   {0x81, "MDT-RTD pointer"},
740   {0x82, "AT-SVC pointer"},
741   {0x83, "AT-RTD pointer"},
742   {0, NULL}
743 };
744
745 static const value_string siii_mdt_hotplug_control_svc_switch_text[]=
746 {
747   {0, "Transmission via HP-field"},
748   {1, "Switch to SVC"},
749   {0, NULL}
750 };
751
752 static const value_string siii_mdt_hotplug_status_ackcode_text[]=
753 {
754   {0x80, "MDT-SVC pointer"},
755   {0x81, "MDT-RTD pointer"},
756   {0x82, "AT-SVC pointer"},
757   {0x83, "AT-RTD pointer"},
758   {255, "Next Sercos Slave has same address"},
759   {0, NULL}
760 };
761
762 static const value_string siii_at_hotplug_status_error_text[]=
763 {
764   {0, "Acknowledgement in HP-1"},
765   {1, "Error in HP-1"},
766   {0, NULL}
767 };
768
769
770
771
772
773 void dissect_siii_mst(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
774 {
775   proto_item*  ti;
776   proto_tree* subtree;
777   proto_tree* subtree2;
778
779   ti = proto_tree_add_text(tree, tvb, 0, 6, "MST");
780   subtree = proto_item_add_subtree(ti, ett_siii_mst);
781
782   ti = proto_tree_add_text(subtree, tvb, 0, 1, "Telegram Type");
783   subtree2 = proto_item_add_subtree(ti, ett_siii_mst_teltype);
784
785   proto_tree_add_item(subtree2, hf_siii_mst_channel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
786   proto_tree_add_item(subtree2, hf_siii_mst_type, tvb, 0, 1, ENC_LITTLE_ENDIAN);
787   proto_tree_add_item(subtree2, hf_siii_mst_cyclecntvalid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
788   proto_tree_add_item(subtree2, hf_siii_mst_telno, tvb, 0, 1, ENC_LITTLE_ENDIAN);
789
790   ti = proto_tree_add_text(subtree, tvb, 1, 1, "Phase Field");
791   subtree2 = proto_item_add_subtree(ti, ett_siii_mst_phase);
792
793   proto_tree_add_item(subtree2, hf_siii_mst_phase, tvb, 1, 1, TRUE);
794   proto_tree_add_item(subtree2, hf_siii_mst_cyclecnt, tvb, 1, 1, TRUE);
795   proto_tree_add_item(subtree, hf_siii_mst_crc32, tvb, 2, 4, ENC_LITTLE_ENDIAN);
796
797 }
798
799 void dissect_siii_mdt_hp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
800 {
801   proto_tree* subtree;
802   proto_tree* subtree2;
803   proto_item* ti;
804
805   ti = proto_tree_add_text(tree, tvb, 0, 8, "Hot-Plug");
806   subtree = proto_item_add_subtree(ti, ett_siii_mdt_hp);
807
808   proto_tree_add_item(subtree, hf_siii_mdt_hotplug_address, tvb, 2, 2, ENC_LITTLE_ENDIAN);
809
810   ti = proto_tree_add_item(subtree, hf_siii_mdt_hp_ctrl, tvb, 2, 2, ENC_LITTLE_ENDIAN);
811   subtree2 = proto_item_add_subtree(ti, ett_siii_mdt_hp_ctrl);
812
813   proto_tree_add_item(subtree2, hf_siii_mdt_hotplug_control_svc_switch, tvb, 2, 2, ENC_LITTLE_ENDIAN);
814   proto_tree_add_item(subtree2, hf_siii_mdt_hotplug_control_param, tvb, 2, 2, ENC_LITTLE_ENDIAN);
815
816   proto_tree_add_item(subtree, hf_siii_mdt_hp_info, tvb, 4, 4, ENC_NA);
817 }
818
819 void dissect_siii_mdt_devctrl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
820 {
821   proto_tree* subtree;
822   proto_item* ti;
823
824   ti = proto_tree_add_item(tree, hf_siii_mdt_dev_control, tvb, 0, 2, ENC_LITTLE_ENDIAN);
825   subtree = proto_item_add_subtree(ti, ett_siii_mdt_devctrl);
826
827   proto_tree_add_item(subtree, hf_siii_at_dev_control_ident, tvb, 0, 2, ENC_LITTLE_ENDIAN);
828   proto_tree_add_item(subtree, hf_siii_mdt_dev_control_change_topology, tvb, 0, 2, TRUE);
829   proto_tree_add_item(subtree, hf_siii_mdt_dev_control_top_control, tvb, 0, 2, TRUE);
830 }
831
832 void dissect_siii_mdt_svc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint devno _U_) /* devno will be needed in later versions */
833 {
834   proto_tree* subtree;
835   proto_item* ti;
836
837   guint16 svc_ctrl = tvb_get_letohs(tvb, 0); /* service channel header */
838   guint32 svc_info = tvb_get_letohl(tvb, 2); /* service channel data */
839   guint8  svc_dbe  = (svc_ctrl>>3) & 7;      /* accessed data block element */
840
841   ti = proto_tree_add_item(tree, hf_siii_mdt_svch_ctrl, tvb, 0, 2, ENC_LITTLE_ENDIAN);
842   subtree = proto_item_add_subtree(ti, ett_siii_mdt_svcctrl);
843
844   proto_tree_add_item(subtree, hf_siii_mdt_svch_dbe, tvb, 0, 2, ENC_LITTLE_ENDIAN); /* data block element */
845   proto_tree_add_item(subtree, hf_siii_mdt_svch_eot, tvb, 0, 2, ENC_LITTLE_ENDIAN); /* end of transmission */
846   proto_tree_add_item(subtree, hf_siii_mdt_svch_rw, tvb, 0, 2, ENC_LITTLE_ENDIAN);  /* read or write */
847   proto_tree_add_item(subtree, hf_siii_mdt_svch_mhs, tvb, 0, 2, ENC_LITTLE_ENDIAN); /* master hand shake */
848
849   ti = proto_tree_add_item(tree, hf_siii_mdt_svch_info, tvb, 2, 4, ENC_NA);
850
851   if(1 == svc_dbe)
852   {
853     subtree = proto_item_add_subtree(ti, ett_siii_mdt_svcinfo);
854     proto_tree_add_text(subtree, tvb, 2, 4, "IDN code: %c-%u-%04d.%d.%d",
855       ((0xFFFF & svc_info)>>15)?'P':'S', /* private or sercos IDN */
856       (svc_info>>12)&7, /* parameter record */
857       (svc_info&4095), /* IDN */
858       (svc_info>>24) & 0xFF, /* structure index */
859       (svc_info>>16) & 0xFF); /* structure element */
860     proto_tree_add_item(subtree, hf_siii_mdt_svch_idn, tvb, 2, 4, ENC_LITTLE_ENDIAN);
861   }
862 }
863
864 static void dissect_siii_mdt_cp0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
865 {
866   proto_item* ti;
867   proto_tree* subtree;
868   ti = proto_tree_add_item(tree, hf_siii_mdt_version, tvb, 0, 4, ENC_LITTLE_ENDIAN);
869   subtree = proto_item_add_subtree(ti, ett_siii_mdt_version);
870
871   proto_tree_add_item(subtree, hf_siii_mdt_version_num_mdt_at_cp1_2, tvb, 0, 4, ENC_LITTLE_ENDIAN);
872   proto_tree_add_item(subtree, hf_siii_mdt_version_initprocvers, tvb, 0, 4, ENC_LITTLE_ENDIAN);
873   proto_tree_add_item(subtree, hf_siii_mdt_version_revision, tvb, 0, 4, ENC_LITTLE_ENDIAN);
874
875 }
876
877 static void dissect_siii_mdt_cp1_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
878 {
879   guint devstart = telno * SERCOS_SLAVE_GROUP_SIZE; /* MDT0: slaves 0-127; MDT1: slaves 128-255; ... */
880   tvbuff_t* tvb_n;
881
882   guint idx;
883
884   proto_item* ti;
885   proto_tree* subtree;
886   proto_tree* subtree_svc;
887   proto_tree* subtree_devctrl;
888
889   ti = proto_tree_add_text(tree, tvb, 0, SERCOS_SLAVE_GROUP_SIZE * 6, "Service Channels");
890   subtree_svc = proto_item_add_subtree(ti, ett_siii_mdt_svc);
891
892   ti = proto_tree_add_text(tree, tvb, SERCOS_SLAVE_GROUP_SIZE * 6, 512, "Device Control");
893   subtree_devctrl = proto_item_add_subtree(ti, ett_siii_mdt_svc);
894
895   for(idx = 0; idx < SERCOS_SLAVE_GROUP_SIZE; ++idx) /* each MDT of CP1/2 has data for 128 different slaves */
896   {
897     tvb_n = tvb_new_subset(tvb, 6 * idx, 6, 6); /* subset for service channel data */
898
899     ti = proto_tree_add_text(subtree_svc, tvb_n, 0, 6, "Device %u", idx + devstart);
900     subtree = proto_item_add_subtree(ti, ett_siii_mdt_svc_channel);
901     dissect_siii_mdt_svc(tvb_n, pinfo, subtree, idx + devstart);
902
903     tvb_n = tvb_new_subset(tvb, SERCOS_SLAVE_GROUP_SIZE * 6 + 4 * idx, 2, 2); /* subset for device control information */
904
905     ti = proto_tree_add_text(subtree_devctrl, tvb_n, 0, 2, "Device %u", idx + devstart);
906     subtree = proto_item_add_subtree(ti, ett_siii_mdt_dev_control);
907
908     dissect_siii_mdt_devctrl(tvb_n, pinfo, subtree);
909   }
910 }
911
912 static void dissect_siii_mdt_cp3_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
913 {
914   guint devstart _U_ = telno * SERCOS_SLAVE_GROUP_SIZE;
915
916   if(0 == telno) /* dissect hotplug field in MDT0 only */
917     dissect_siii_mdt_hp(tvb, pinfo, tree);
918
919   /* offsets of service channel, device status and connections are unknown
920    * this data could be extracted from svc communication during CP2
921    */
922   proto_tree_add_text(tree, tvb, 0, 0, "Service Channels");
923   
924   proto_tree_add_text(tree, tvb, 0, 0, "Device Controls");
925 }
926
927 void dissect_siii_mdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
928 {
929   proto_item* ti;
930   proto_tree* subtree;
931   tvbuff_t* tvb_n;
932
933   guint t_phase;
934   guint telno;
935
936   col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIII MDT");
937
938   t_phase = (tvb_get_guint8(tvb, 1)&0x8F); /* read communication phase out of SERCOS III header */
939   telno = (tvb_get_guint8(tvb, 0) & 0xF); /* read number of MDT out of SERCOS III header */
940
941   if(t_phase & 0x80) /* communication phase switching in progress */
942   {
943     col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP?s -> CP%u",
944           (t_phase&0x0f));
945   }
946   else /* communication as usual */
947   {
948     col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP%u",
949           (t_phase&0x0f));
950   }
951
952   ti = proto_tree_add_text(tree, tvb, 0, -1, "MDT%u", telno);
953   subtree = proto_item_add_subtree(ti, ett_siii_mdt);
954
955   dissect_siii_mst(tvb, pinfo, subtree); /* dissect SERCOS III header */
956
957   switch(t_phase) /* call the MDT dissector depending on the current communication phase */
958   {
959   case COMMUNICATION_PHASE_0: /* CP0 */
960     tvb_n = tvb_new_subset(tvb, 6, 40, 40);
961     dissect_siii_mdt_cp0(tvb_n, pinfo, subtree);
962   break;
963
964   case COMMUNICATION_PHASE_1: /* CP1 */
965   case COMMUNICATION_PHASE_2: /* CP2 */
966     tvb_n = tvb_new_subset(tvb, 6, 1280, 1280);
967     dissect_siii_mdt_cp1_2(tvb_n, pinfo, subtree, telno);
968   break;
969
970   case COMMUNICATION_PHASE_3: /* CP3 */
971   case COMMUNICATION_PHASE_4: /* CP4 */
972     tvb_n = tvb_new_subset_remaining(tvb, 6);
973     dissect_siii_mdt_cp3_4(tvb_n, pinfo, subtree, telno);
974   break;
975
976   default:
977     proto_tree_add_text(tree, tvb, 6, -1, "CP is unknown");
978   }
979 }
980
981 void dissect_siii_at_svc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint devno _U_) /* devno will be used in later versions */
982 {
983   proto_tree* subtree;
984   proto_item* ti;
985
986   ti = proto_tree_add_item(tree, hf_siii_at_svch_stat, tvb, 0, 2, ENC_LITTLE_ENDIAN);
987   subtree = proto_item_add_subtree(ti, ett_siii_at_svcstat);
988
989   proto_tree_add_item(subtree, hf_siii_at_svch_valid, tvb, 0, 2, ENC_LITTLE_ENDIAN);
990   proto_tree_add_item(subtree, hf_siii_at_svch_error, tvb, 0, 2, ENC_LITTLE_ENDIAN);
991   proto_tree_add_item(subtree, hf_siii_at_svch_busy, tvb, 0, 2, ENC_LITTLE_ENDIAN);
992   proto_tree_add_item(subtree, hf_siii_at_svch_ahs, tvb, 0, 2, ENC_LITTLE_ENDIAN);
993
994   proto_tree_add_item(tree, hf_siii_at_svch_info, tvb, 2, 4, ENC_NA);
995 }
996
997 void dissect_siii_at_devstat(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
998 {
999   proto_tree* subtree;
1000   proto_item* ti;
1001
1002   ti = proto_tree_add_item(tree, hf_siii_at_dev_status, tvb, 0, 2, ENC_LITTLE_ENDIAN);
1003   subtree = proto_item_add_subtree(ti, ett_siii_at_devstatus);
1004
1005   proto_tree_add_item(subtree, hf_siii_at_dev_status_commwarning, tvb, 0, 2, TRUE);
1006   proto_tree_add_item(subtree, hf_siii_at_dev_status_change_topology, tvb, 0, 2, TRUE);
1007   proto_tree_add_item(subtree, hf_siii_at_dev_status_top_status, tvb, 0, 2, TRUE);
1008   proto_tree_add_item(subtree, hf_siii_at_dev_status_inactive_port_status, tvb, 0, 2, TRUE);
1009   proto_tree_add_item(subtree, hf_siii_at_dev_status_errorconnection, tvb, 0, 2, TRUE);
1010   proto_tree_add_item(subtree, hf_siii_at_dev_status_slave_valid, tvb, 0, 2, TRUE);
1011   proto_tree_add_item(subtree, hf_siii_at_dev_status_proc_command_change, tvb, 0, 2, TRUE);
1012   proto_tree_add_item(subtree, hf_siii_at_dev_status_parameterization_level_active, tvb, 0, 2, TRUE);
1013 }
1014
1015 void dissect_siii_at_hp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1016 {
1017   proto_tree* subtree;
1018   proto_tree* subtree2;
1019   proto_item* ti;
1020
1021   ti = proto_tree_add_text(tree, tvb, 0, 8, "Hot-Plug");
1022   subtree = proto_item_add_subtree(ti, ett_siii_at_hp);
1023
1024   proto_tree_add_item(subtree, hf_siii_at_hotplug_address, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1025
1026   ti = proto_tree_add_item(subtree, hf_siii_at_hp_stat, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1027   subtree2 = proto_item_add_subtree(ti, ett_siii_at_hp_stat);
1028
1029   proto_tree_add_item(subtree2, hf_siii_at_hotplug_status_error, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1030   proto_tree_add_item(subtree2, hf_siii_at_hotplug_status_hp0_finished, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1031   proto_tree_add_item(subtree2, hf_siii_at_hotplug_status_param, tvb, 2, 2, ENC_LITTLE_ENDIAN);
1032
1033   proto_tree_add_item(subtree, hf_siii_at_hp_info, tvb, 4, 4, ENC_NA);
1034 }
1035
1036 static void dissect_siii_at_cp0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1037 {
1038   guint16 seqcnt; /* sequence counter */
1039   guint16 tfield; /* topology field for sercos addresses */
1040   guint16 i;
1041   char devices[]="Recognized Devices"; /* fixme: it would be nice to have this as subtree */
1042   static char outbuf[200];
1043
1044   proto_tree_add_text(tree, tvb, 0, 1024, "%s", devices);
1045
1046   /* check sequence count field */
1047   seqcnt = tvb_get_letohs(tvb, 0);
1048   g_snprintf(outbuf, sizeof(outbuf), "Number of Devices: %u", (0x1FF & seqcnt)-1);
1049   proto_tree_add_text(tree, tvb, 0, 2, "%s", outbuf);
1050
1051   /* check SERCOS address of each topology field */
1052   for(i=1;i < MAX_SERCOS_DEVICES; ++i)
1053   {
1054     tfield = tvb_get_letohs(tvb, i*2);
1055
1056     if(tfield == 0)
1057     {
1058       g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: No SERCOS Address", i);
1059     }
1060     else if(tfield == 0xFFFF)
1061     {
1062       g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: No Device", i);
1063     }
1064     else
1065     {
1066       g_snprintf(outbuf, sizeof(outbuf), "Device Address %u: %u", i, tfield);
1067     }
1068     proto_tree_add_text(tree, tvb, i*2, 2, "%s", outbuf);
1069   }
1070 }
1071
1072 static void dissect_siii_at_cp1_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
1073 {
1074   guint devstart = telno * SERCOS_SLAVE_GROUP_SIZE; /* AT0: slaves 0-127; AT1: slaves 128-255; ... */
1075   tvbuff_t* tvb_n;
1076
1077   guint idx;
1078
1079   proto_item* ti; /* temporary item */
1080   proto_tree* subtree;
1081   proto_tree* subtree_svc;
1082   proto_tree* subtree_devstat;
1083
1084   ti = proto_tree_add_text(tree, tvb, 0, SERCOS_SLAVE_GROUP_SIZE * 6, "Service Channel");
1085   subtree_svc = proto_item_add_subtree(ti, ett_siii_at_svc);
1086
1087   ti = proto_tree_add_text(tree, tvb, SERCOS_SLAVE_GROUP_SIZE * 6, 512, "Device Status");
1088   subtree_devstat = proto_item_add_subtree(ti, ett_siii_at_devstats);
1089
1090   for(idx = 0; idx < SERCOS_SLAVE_GROUP_SIZE; ++idx) /* each AT of CP1/2 has data of 128 different slaves */
1091   {
1092     tvb_n = tvb_new_subset(tvb, 6 * idx, 6, 6); /* subset for service channel data */
1093
1094     ti = proto_tree_add_text(subtree_svc, tvb_n, 0, 6, "Device %u", idx + devstart);
1095     subtree = proto_item_add_subtree(ti, ett_siii_at_svc_channel);
1096     dissect_siii_at_svc(tvb_n, pinfo, subtree, idx + devstart);
1097
1098     tvb_n = tvb_new_subset(tvb, SERCOS_SLAVE_GROUP_SIZE * 6 + 4 * idx, 2, 2); /* subset for device status information */
1099
1100     ti = proto_tree_add_text(subtree_devstat, tvb_n, 0, 2, "Device %u", idx + devstart);
1101     subtree = proto_item_add_subtree(ti, ett_siii_at_dev_status);
1102     dissect_siii_at_devstat(tvb_n, pinfo, subtree);
1103   }
1104 }
1105
1106 static void dissect_siii_at_cp3_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint telno)
1107 {
1108   if(0 == telno) /* dissect hotplug field in AT0 only */
1109     dissect_siii_at_hp(tvb, pinfo, tree);
1110
1111   /* offsets of service channel, device status and connections are unknown
1112    * this data could be extracted from svc communication during CP2
1113    */
1114   proto_tree_add_text(tree, tvb, 0, 0, "Service Channels");  
1115   proto_tree_add_text(tree, tvb, 0, 0, "Device Status");
1116 }
1117
1118
1119 void dissect_siii_at(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1120 {
1121   proto_item*  ti; /* temporary item */
1122   proto_tree* subtree;
1123   tvbuff_t* tvb_n;
1124
1125   guint8 phase;
1126   guint telno;
1127
1128   phase = (tvb_get_guint8(tvb, 1)&0x8F); /* read communication phase out of SERCOS III header*/
1129   telno = (tvb_get_guint8(tvb, 0) & 0xF); /* read number of AT out of SERCOS III header */
1130
1131   col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIII AT");
1132
1133   if(phase & 0x80) /* communication phase switching in progress */
1134   {
1135     col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP?s -> CP%u",
1136           (phase&0x0f));
1137   }
1138   else /* communication as usual */
1139   {
1140      col_append_fstr(pinfo->cinfo, COL_INFO, " Phase=CP%u",
1141           (phase&0x0f));
1142   }
1143
1144   ti = proto_tree_add_text(tree, tvb, 0, -1, "AT%u", telno);
1145   subtree = proto_item_add_subtree(ti, ett_siii_at);
1146
1147   dissect_siii_mst(tvb, pinfo, subtree); /* dissect SERCOS III header */
1148
1149     switch(phase) /* call the AT dissector depending on the current communication phase */
1150     {
1151     case COMMUNICATION_PHASE_0: /* CP0 */
1152       tvb_n = tvb_new_subset(tvb, 6, 1024, 1024);
1153       dissect_siii_at_cp0(tvb_n, pinfo, subtree);
1154     break;
1155
1156     case COMMUNICATION_PHASE_1: /* CP1 */
1157     case COMMUNICATION_PHASE_2: /* CP2 */
1158       tvb_n = tvb_new_subset(tvb, 6, 1280, 1280);
1159       dissect_siii_at_cp1_2(tvb_n, pinfo, subtree, telno);
1160     break;
1161
1162     case COMMUNICATION_PHASE_3: /* CP3 */
1163     case COMMUNICATION_PHASE_4: /* CP4 */
1164       tvb_n = tvb_new_subset_remaining(tvb, 6);
1165       dissect_siii_at_cp3_4(tvb_n, pinfo, subtree, telno);
1166     break;
1167
1168     default:
1169       proto_tree_add_text(tree, tvb, 6, -1, "CP is unknown");
1170     break;
1171     }
1172 }
1173
1174 /* Main dissector entry */
1175 static void
1176 dissect_siii(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1177 {
1178   proto_item*  ti;
1179   proto_tree*  siii_tree;
1180   guint    type;
1181   char* tel_ch="?";
1182   char* tel_type="?";
1183   guint tel_no = 0;
1184
1185   /* setup columns */
1186   col_set_str(pinfo->cinfo, COL_PROTOCOL, "SERCOS III V1.1");
1187   col_clear(pinfo->cinfo, COL_INFO);
1188
1189   /*
1190    * In case the packet is a protocol encoded in the basic SercosIII transport stream,
1191    * give that protocol a chance to make a heuristic dissection, before we continue
1192    * to dissect it as a normal SercosIII packet.
1193    */
1194   if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree))
1195     return;
1196
1197   /* check what we got on our hand */
1198   type = tvb_get_guint8(tvb, 0);
1199   if(type&0x80) /* primary or secondary channel */
1200     tel_ch="S";
1201   else
1202     tel_ch="P";
1203
1204   if(type&0x40) /* master data telegram (mdt) or slave telegram (at) */
1205     tel_type="AT ";
1206   else
1207     tel_type="MDT";
1208
1209   tel_no = type &0xF; /* even though it's reserved (the V1.1 spec states that it is reserved for additional MDT/AT) */
1210
1211   col_append_fstr(pinfo->cinfo, COL_INFO, "%s%u Channel=%s", tel_type, tel_no, tel_ch);
1212
1213   ti = proto_tree_add_item(tree, proto_siii, tvb, 0, -1, FALSE);
1214
1215   siii_tree = proto_item_add_subtree(ti, ett_siii);
1216
1217    /* enter the specific dissector for AT or MDT */
1218   if(type & 0x40)
1219     dissect_siii_at(tvb, pinfo, siii_tree);
1220   else
1221     dissect_siii_mdt(tvb, pinfo, siii_tree);
1222 }
1223
1224 void
1225 proto_register_sercosiii(void)
1226 {
1227   static hf_register_info hf[] = {
1228
1229     { &hf_siii_mdt_version,
1230       { "Communication Version", "siii.mdt.version",
1231       FT_UINT32, BASE_HEX, NULL, 0,
1232       NULL, HFILL }
1233     },
1234     { &hf_siii_mdt_version_revision,
1235       { "Revision Number", "siii.mdt.version.revision",
1236       FT_UINT32, BASE_HEX, NULL, 0x7F,
1237       NULL, HFILL }
1238     },
1239     { &hf_siii_mdt_version_num_mdt_at_cp1_2,
1240       { "Number of MDTs and ATS in CP1 and CP2", "siii.mdt.version.num_mdt_at_cp1_2",
1241       FT_UINT32, BASE_HEX, VALS(siii_mdt_version_num_mdtat_cp1_2_text), 0x30000,
1242       NULL, HFILL }
1243     },
1244     { &hf_siii_mdt_version_initprocvers,
1245       { "Initialization Procedure Version Number", "siii.mdt.version.initprocvers",
1246       FT_UINT32, BASE_HEX, VALS(siii_mdt_version_initprocvers_text), 0xFF00,
1247       NULL, HFILL }
1248     },
1249
1250     { &hf_siii_mdt_dev_control_top_control,
1251       { "Topology Control", "siii.mdt.devcontrol.topcontrol",
1252       FT_UINT16, BASE_DEC, VALS(siii_mdt_devcontrol_topcontrol_text), 3<<(12),
1253       NULL, HFILL }
1254     },
1255     { &hf_siii_at_dev_control_ident,
1256       { "Identification", "siii.mdt.devcontrol.identrequest",
1257       FT_UINT16, BASE_DEC, NULL, 0x8000,
1258       NULL, HFILL }
1259     },
1260     { &hf_siii_mdt_dev_control_change_topology,
1261       { "Changing Topology", "siii.mdt.devcontrol.topologychange",
1262       FT_UINT16, BASE_DEC, NULL, 1<<14,
1263       NULL, HFILL }
1264     },
1265     { &hf_siii_mdt_dev_control,
1266       { "Word", "siii.mdt.devcontrol",
1267       FT_UINT16, BASE_DEC, NULL, 0,
1268       NULL, HFILL }
1269     },
1270
1271     { &hf_siii_at_dev_status,
1272       { "Word", "siii.at.devstatus",
1273       FT_UINT16, BASE_HEX, NULL, 0,
1274       NULL, HFILL }
1275     },
1276
1277     { &hf_siii_at_dev_status_commwarning,
1278       { "Communication Warning", "siii.at.devstatus.commwarning",
1279       FT_UINT16, BASE_DEC, NULL, 1<<15,
1280       NULL, HFILL }
1281     },
1282
1283     { &hf_siii_at_dev_status_change_topology,
1284       { "Topology Change", "siii.at.devstatus.topologychanged",
1285       FT_UINT16, BASE_DEC, NULL, 1<<14,
1286       NULL, HFILL }
1287     },
1288     { &hf_siii_at_dev_status_top_status,
1289       { "Topology Status", "siii.at.devstatus.topstatus",
1290       FT_UINT16, BASE_DEC, VALS(siii_at_devstatus_topstatus_text), 0x3<<(12),
1291       NULL, HFILL }
1292     },
1293     { &hf_siii_at_dev_status_inactive_port_status,
1294       { "Port 1 Status", "siii.at.devstatus.inactportstatus",
1295       FT_UINT16, BASE_DEC, VALS(siii_at_devstatus_inactiveportstatus_text), 0x3<<(10),
1296       NULL, HFILL }
1297     },
1298     { &hf_siii_at_dev_status_errorconnection,
1299       { "Topology Status", "siii.at.devstatus.errorconnection",
1300       FT_UINT16, BASE_DEC, VALS(siii_at_devstatus_errorconnection_text), 1<<9,
1301       NULL, HFILL }
1302     },
1303     { &hf_siii_at_dev_status_slave_valid,
1304       { "Slave data valid", "siii.at.devstatus.slavevalid",
1305       FT_UINT16, BASE_DEC, NULL, 1<<8,
1306       NULL, HFILL }
1307     },
1308     { &hf_siii_at_dev_status_proc_command_change,
1309       { "Procedure Command Change", "siii.at.devstatus.proccmdchange",
1310       FT_UINT16, BASE_DEC, VALS(siii_at_dev_status_proc_command_change_text), 1<<5,
1311       NULL, HFILL }
1312     },
1313     { &hf_siii_at_dev_status_parameterization_level_active,
1314       { "Parameterization level active", "siii.at.devstatus.paralevelactive",
1315       FT_UINT16, BASE_DEC, NULL, 1<<4,
1316       NULL, HFILL }
1317     },
1318
1319     { &hf_siii_mdt_svch_ctrl,
1320       {"SvcCtrl", "siii.mdt.svch.ctrl",
1321       FT_UINT16, BASE_HEX, NULL, 0,
1322       NULL, HFILL }
1323     },
1324     { &hf_siii_at_svch_stat,
1325       {"SvcStat", "siii.mdt.svch.stat",
1326       FT_UINT16, BASE_HEX, NULL, 0,
1327       NULL, HFILL }
1328     },
1329     { &hf_siii_mdt_svch_info,
1330       {"Svc Info", "siii.mdt.svch.info",
1331       FT_BYTES, BASE_NONE, NULL, 0,
1332       NULL, HFILL }
1333     },
1334     { &hf_siii_at_svch_info,
1335       {"Svc Info", "siii.at.svch.info",
1336       FT_BYTES, BASE_NONE, NULL, 0,
1337       NULL, HFILL }
1338     },
1339     { &hf_siii_mdt_svch_idn,
1340       {"IDN", "siii.mdt.svch.idn",
1341       FT_UINT32, BASE_HEX, VALS(siii_mdt_idn_text), 0,
1342       NULL, HFILL }
1343     },
1344     { &hf_siii_mdt_svch_dbe,
1345       { "Data block element", "siii.mdt.svch.dbe",
1346       FT_UINT16, BASE_DEC, VALS(siii_mdt_svch_dbe_text), 0x38,
1347       NULL, HFILL }
1348     },
1349     { &hf_siii_mdt_svch_eot,
1350       {"End of element transmission", "siii.mdt.svch.eot",
1351       FT_UINT16, BASE_DEC, VALS(siii_mdt_svch_eot_text), 0x04,
1352       NULL, HFILL }
1353     },
1354     { &hf_siii_mdt_svch_rw,
1355       {"Read/Write", "siii.mdt.svch.rw",
1356       FT_UINT16, BASE_DEC, VALS(siii_mdt_svch_rw_text), 0x02,
1357       NULL, HFILL }
1358     },
1359     { &hf_siii_mdt_svch_mhs,
1360       {"Master Handshake", "siii.mdt.svch.mhs",
1361       FT_UINT16, BASE_DEC, NULL, 0x01,
1362       NULL, HFILL }
1363     },
1364     { &hf_siii_at_svch_valid,
1365       { "SVC process", "siii.mdt.svch.proc",
1366       FT_UINT16, BASE_DEC, VALS(siii_at_svch_valid_text), 0x08,
1367       NULL, HFILL }
1368     },
1369     { &hf_siii_at_svch_error,
1370       {"SVC Error", "siii.mdt.svch.error",
1371       FT_UINT16, BASE_DEC, VALS(siii_at_svch_error_text), 0x04,
1372       NULL, HFILL }
1373     },
1374     { &hf_siii_at_svch_busy,
1375       {"Busy", "siii.mdt.svch.busy",
1376       FT_UINT16, BASE_DEC, VALS(siii_at_svch_busy_text), 0x02,
1377       NULL, HFILL }
1378     },
1379     { &hf_siii_at_svch_ahs,
1380       {"Handshake", "siii.at.svch.ahs",
1381       FT_UINT16, BASE_DEC, NULL, 0x01,
1382       NULL, HFILL }
1383     },
1384     { &hf_siii_svch_data_telofs_telno,
1385       {"Telegram Number", "siii.mdt.svch.data.telassign.telno",
1386       FT_UINT16, BASE_DEC, NULL, 0xF000,
1387       NULL, HFILL }
1388     },
1389     { &hf_siii_svch_data_telofs_mdt_at,
1390       {"Telegram Type", "siii.mdt.svch.data.telassign.mdt_at",
1391       FT_UINT16, BASE_DEC, VALS(siii_svch_data_mdt_at_text), 0x0800,
1392       NULL, HFILL }
1393     },
1394     { &hf_siii_svch_data_telofs_offset,
1395       {"Telegram Offset", "siii.mdt.svch.data.telassign.offset",
1396       FT_UINT16, BASE_DEC, NULL, 0x07FF,
1397       NULL, HFILL }
1398     },
1399     { &hf_siii_svch_data_proccmd_proccmdexec,
1400       {"Procedure Command Execution", "siii.mdt.svch.data.proccmd.interrupt",
1401       FT_UINT16, BASE_DEC, VALS(siii_svch_data_proccmd_proccmdexec_text), 0x0002,
1402       NULL, HFILL }
1403     },
1404     { &hf_siii_svch_data_proccmd_proccmd,
1405       {"Procedure Command", "siii.mdt.svch.data.proccmd.set",
1406       FT_UINT16, BASE_DEC, VALS(siii_svch_data_proccmd_proccmd_text), 0x0001,
1407       NULL, HFILL }
1408     },
1409
1410     { &hf_siii_mst_channel,
1411       { "Channel", "siii.channel",
1412         FT_UINT8, BASE_DEC, VALS(siii_mst_channel_text), 0x80,
1413         NULL, HFILL }
1414     },
1415     { &hf_siii_mst_type,
1416       { "Telegram Type" , "siii.type",
1417         FT_UINT8, BASE_DEC, VALS(siii_mst_type_text), 0x40,
1418         NULL, HFILL }
1419     },
1420     { &hf_siii_mst_cyclecntvalid,
1421       { "Cycle Count Valid", "siii.cyclecntvalid",
1422         FT_UINT8, BASE_DEC, VALS(siii_mst_cyclecntvalid_text), 0x20,
1423         NULL, HFILL }
1424     },
1425     { &hf_siii_mst_telno,
1426       { "Telegram Number", "siii.telno",
1427         FT_UINT8, BASE_DEC, NULL, 0x0F,
1428         NULL, HFILL }
1429     },
1430     { &hf_siii_mst_phase,
1431       { "Phase", "siii.mst.phase",
1432         FT_UINT8, BASE_HEX, VALS(siii_mst_phase_text), 0x8F,    /* CHANGED: SB: new value is 0x8F for masking out phase */
1433         NULL, HFILL }
1434     },
1435     { &hf_siii_mst_cyclecnt,
1436       { "Cycle Cnt", "siii.mst.cyclecnt",
1437         FT_UINT8, BASE_DEC, NULL, 0x70,    /* CHANGED: SB: new value is 0x70 for masking out cycle cnt */
1438         NULL, HFILL }
1439     },
1440     { &hf_siii_mst_crc32,
1441       { "CRC32", "siii.mst.crc32",
1442         FT_UINT32, BASE_HEX, NULL, 0,
1443         NULL, HFILL }
1444     },
1445
1446     { &hf_siii_mdt_hotplug_address,
1447       {"Sercos address", "siii.mdt.hp.sercosaddress",
1448         FT_UINT16, BASE_HEX, NULL, 0,
1449         NULL, HFILL }
1450     },
1451     { &hf_siii_mdt_hp_ctrl,
1452       {"HP control", "siii.mdt.hp.ctrl",
1453         FT_UINT16, BASE_HEX, NULL, 0,
1454         NULL, HFILL }
1455     },
1456     { &hf_siii_mdt_hp_info,
1457       {"HP info", "siii.mdt.hp.info",
1458         FT_BYTES, BASE_NONE, NULL, 0,
1459         NULL, HFILL }
1460     },
1461     { &hf_siii_at_hotplug_address,
1462       {"Sercos address", "siii.at.hp.sercosaddress",
1463         FT_UINT16, BASE_HEX, NULL, 0,
1464         NULL, HFILL }
1465     },
1466     { &hf_siii_at_hp_stat,
1467       {"HP status", "siii.mdt.hp.stat",
1468         FT_UINT16, BASE_HEX, NULL, 0,
1469         NULL, HFILL }
1470     },
1471     { &hf_siii_at_hp_info,
1472       {"HP info", "siii.at.hp.info",
1473         FT_BYTES, BASE_NONE, NULL, 0,
1474         NULL, HFILL }
1475     },
1476     { &hf_siii_mdt_hotplug_control_param,
1477       {"Parameter", "siii.mdt.hp.parameter",
1478         FT_UINT16, BASE_DEC, VALS(siii_mdt_hotplug_control_functioncode_text), 0xFF,
1479         NULL, HFILL }
1480     },
1481     { &hf_siii_mdt_hotplug_control_svc_switch,
1482       {"Switch to SVC", "siii.mdt.hp.switch",
1483         FT_UINT16, BASE_DEC, VALS(siii_mdt_hotplug_control_svc_switch_text), 0x100,
1484         NULL, HFILL }
1485     },
1486
1487     { &hf_siii_at_hotplug_status_param,
1488       {"Parameter Received", "siii.at.hp.parameter",
1489         FT_UINT16, BASE_DEC, VALS(siii_mdt_hotplug_status_ackcode_text), 0xFF,
1490         NULL, HFILL }
1491     },
1492     { &hf_siii_at_hotplug_status_hp0_finished,
1493       {"HP/SVC", "siii.at.hp.hp0_finished",
1494         FT_UINT16, BASE_DEC, NULL, 0x100,
1495         NULL, HFILL }
1496     },
1497     { &hf_siii_at_hotplug_status_error,
1498       {"Error", "siii.at.hp.error",
1499         FT_UINT16, BASE_DEC, VALS(siii_at_hotplug_status_error_text), 0x200,
1500         NULL, HFILL }
1501     }
1502   };
1503
1504   /* Setup protocol subtree array */
1505   static gint *ett[] = {
1506     &ett_siii,
1507     &ett_siii_header,
1508
1509     &ett_siii_mdt,
1510     &ett_siii_mdt_version,
1511     &ett_siii_mdt_svc,
1512     &ett_siii_mdt_devctrls,
1513     &ett_siii_mdt_svc_channel,
1514     &ett_siii_mdt_dev_control,
1515
1516     &ett_siii_at,
1517     &ett_siii_at_svc,
1518     &ett_siii_at_devstats,
1519     &ett_siii_at_svc_channel,
1520     &ett_siii_at_dev_status,
1521
1522     &ett_siii_mdt_devctrl,
1523     &ett_siii_at_devstatus,
1524
1525     &ett_siii_mdt_svcctrl,
1526     &ett_siii_mdt_svcinfo,
1527     &ett_siii_at_svcstat,
1528     &ett_siii_at_svcinfo,
1529     &ett_siii_mdt_svch_data_error_info,
1530     &ett_siii_mdt_svch_data,
1531
1532     &ett_siii_mst,
1533     &ett_siii_mst_teltype,
1534     &ett_siii_mst_phase,
1535
1536     &ett_siii_mdt_hp,
1537     &ett_siii_at_hp,
1538     &ett_siii_mdt_hp_ctrl,
1539     &ett_siii_mdt_hp_info,
1540     &ett_siii_at_hp_stat,
1541     &ett_siii_at_hp_info
1542   };
1543
1544
1545   /* Register the protocol name and description */
1546   proto_siii = proto_register_protocol("SERCOS III V1.1",
1547       "SERCOS III V1.1", "siii");
1548
1549   register_dissector("sercosiii", dissect_siii, proto_siii);
1550
1551   /* subdissector code */
1552   register_heur_dissector_list("sercosiii", &heur_subdissector_list);
1553
1554   /* Required function calls to register the header fields and subtrees used */
1555   proto_register_field_array(proto_siii, hf, array_length(hf));
1556   proto_register_subtree_array(ett, array_length(ett));
1557 }
1558
1559 void
1560 proto_reg_handoff_sercosiii(void)
1561 {
1562   dissector_handle_t siii_handle;
1563
1564   siii_handle = create_dissector_handle(dissect_siii, proto_siii);
1565   dissector_add_uint("ethertype", ETHERTYPE_SERCOS, siii_handle);
1566 }