Get rid of an unused variable.
[metze/wireshark/wip.git] / plugins / ethercat / packet-ecatmb.c
1 /* packet-ecatmb.c
2  * Routines for EtherCAT packet disassembly
3  *
4  * Copyright (c) 2007 by Beckhoff Automation GmbH
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 /* Include files */
26
27 #include "config.h"
28
29 #include <string.h>
30
31 #include <epan/packet.h>
32 #include <epan/expert.h>
33
34 #include "packet-ecatmb.h"
35
36 #define BIT2BYTE(x) ((x+7)/8)
37 #define ENDOF(p) ((p)+1) /* pointer to end of *p */
38
39 void proto_register_ecat_mailbox(void);
40 void proto_reg_handoff_ecat_mailbox(void);
41
42 static dissector_handle_t eth_handle;
43 static dissector_handle_t ams_handle;
44
45 /* Define the EtherCAT mailbox proto */
46 int proto_ecat_mailbox  = -1;
47
48 static int ett_ecat_mailbox = -1;
49 static int ett_ecat_mailbox_eoe = -1;
50 static int ett_ecat_mailbox_eoe_init = -1;
51 static int ett_ecat_mailbox_eoe_macfilter = -1;
52 static int ett_ecat_mailbox_eoe_macfilter_filter = -1;
53 static int ett_ecat_mailbox_eoe_macfilter_filtermask = -1;
54 static int ett_ecat_mailbox_coe = -1;
55 static int ett_ecat_mailbox_sdo = -1;
56 static int ett_ecat_mailbox_coe_sdoccs = -1;
57 static int ett_ecat_mailbox_coe_sdoscs = -1;
58 static int ett_ecat_mailbox_foe = -1;
59 static int ett_ecat_mailbox_foe_efw = -1;
60 static int ett_ecat_mailbox_soeflag = -1;
61 static int ett_ecat_mailbox_soe = -1;
62 static int ett_ecat_mailbox_fraghead = -1;
63 static int ett_ecat_mailbox_header = -1;
64
65 static int hf_ecat_mailboxlength = -1;
66 static int hf_ecat_mailboxaddress = -1;
67 static int hf_ecat_mailboxpriority = -1;
68 static int hf_ecat_mailboxtype = -1;
69 static int hf_ecat_mailboxcounter = -1;
70 static int hf_ecat_mailbox_eoe = -1;
71 static int hf_ecat_mailbox_eoe_fraghead = -1;
72 static int hf_ecat_mailbox_eoe_type = -1;
73 static int hf_ecat_mailbox_eoe_fragno = -1;
74 static int hf_ecat_mailbox_eoe_offset = -1;
75 static int hf_ecat_mailbox_eoe_frame = -1;
76 static int hf_ecat_mailbox_eoe_last = -1;
77 static int hf_ecat_mailbox_eoe_timestampreq = -1;
78 static int hf_ecat_mailbox_eoe_timestampapp = -1;
79 static int hf_ecat_mailbox_eoe_fragment = -1;
80 static int hf_ecat_mailbox_eoe_init = -1;
81 static int hf_ecat_mailbox_eoe_init_contains_macaddr = -1;
82 static int hf_ecat_mailbox_eoe_init_contains_ipaddr = -1;
83 static int hf_ecat_mailbox_eoe_init_contains_subnetmask = -1;
84 static int hf_ecat_mailbox_eoe_init_contains_defaultgateway = -1;
85 static int hf_ecat_mailbox_eoe_init_contains_dnsserver = -1;
86 static int hf_ecat_mailbox_eoe_init_contains_dnsname = -1;
87 static int hf_ecat_mailbox_eoe_init_append_timestamp = -1;
88 static int hf_ecat_mailbox_eoe_init_macaddr = -1;
89 static int hf_ecat_mailbox_eoe_init_ipaddr = -1;
90 static int hf_ecat_mailbox_eoe_init_subnetmask = -1;
91 static int hf_ecat_mailbox_eoe_init_defaultgateway = -1;
92 static int hf_ecat_mailbox_eoe_init_dnsserver = -1;
93 static int hf_ecat_mailbox_eoe_init_dnsname = -1;
94 static int hf_ecat_mailbox_eoe_macfilter = -1;
95 static int hf_ecat_mailbox_eoe_macfilter_macfiltercount = -1;
96 static int hf_ecat_mailbox_eoe_macfilter_maskcount = -1;
97 static int hf_ecat_mailbox_eoe_macfilter_nobroadcasts = -1;
98 static int hf_ecat_mailbox_eoe_macfilter_filter;
99 static int hf_ecat_mailbox_eoe_macfilter_filters[16] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
100 static int hf_ecat_mailbox_eoe_macfilter_filtermask = -1;
101 static int hf_ecat_mailbox_eoe_macfilter_filtermasks[4] = {-1,-1,-1,-1};
102 static int hf_ecat_mailbox_eoe_timestamp = -1;
103 static int hf_ecat_mailbox_coe = -1;
104 static int hf_ecat_mailbox_coe_number = -1;
105 static int hf_ecat_mailbox_coe_type = -1;
106 static int hf_ecat_mailbox_coe_sdoreq = -1;
107 static int hf_ecat_mailbox_coe_sdoccsid = -1;
108 static int hf_ecat_mailbox_coe_sdoccsid_sizeind = -1;
109 static int hf_ecat_mailbox_coe_sdoccsid_expedited = -1;
110 static int hf_ecat_mailbox_coe_sdoccsid_size0= -1;
111 static int hf_ecat_mailbox_coe_sdoccsid_size1= -1;
112 static int hf_ecat_mailbox_coe_sdoccsid_complete = -1;
113 static int hf_ecat_mailbox_coe_sdoccsds = -1;
114 static int hf_ecat_mailbox_coe_sdoccsds_lastseg = -1;
115 static int hf_ecat_mailbox_coe_sdoccsds_size = -1;
116 static int hf_ecat_mailbox_coe_sdoccsds_toggle = -1;
117 static int hf_ecat_mailbox_coe_sdoccsus = -1;
118 static int hf_ecat_mailbox_coe_sdoccsus_toggle = -1;
119 static int hf_ecat_mailbox_coe_sdoccsiu = -1;
120 /* static int hf_ecat_mailbox_coe_sdoccsiu_complete = -1; */
121 static int hf_ecat_mailbox_coe_sdoidx = -1;
122 static int hf_ecat_mailbox_coe_sdosub = -1;
123 static int hf_ecat_mailbox_coe_sdodata = -1;
124 static int hf_ecat_mailbox_coe_sdodata1 = -1;
125 static int hf_ecat_mailbox_coe_sdodata2 = -1;
126 static int hf_ecat_mailbox_coe_sdoldata = -1;
127 static int hf_ecat_mailbox_coe_sdolength = -1;
128 /* static int hf_ecat_mailbox_coe_sdoerror = -1; */
129 static int hf_ecat_mailbox_coe_sdores = -1;
130 static int hf_ecat_mailbox_coe_sdoscsds = -1;
131 static int hf_ecat_mailbox_coe_sdoscsds_toggle = -1;
132 static int hf_ecat_mailbox_coe_sdoscsiu = -1;
133 static int hf_ecat_mailbox_coe_sdoscsiu_sizeind = -1;
134 static int hf_ecat_mailbox_coe_sdoscsiu_expedited = -1;
135 static int hf_ecat_mailbox_coe_sdoscsiu_size0 = -1;
136 static int hf_ecat_mailbox_coe_sdoscsiu_size1 = -1;
137 static int hf_ecat_mailbox_coe_sdoscsiu_complete = -1;
138 static int hf_ecat_mailbox_coe_sdoscsus = -1;
139 static int hf_ecat_mailbox_coe_sdoscsus_lastseg = -1;
140 static int hf_ecat_mailbox_coe_sdoscsus_bytes = -1;
141 static int hf_ecat_mailbox_coe_sdoscsus_toggle = -1;
142 static int hf_ecat_mailbox_coe_sdoinfoopcode = -1;
143 static int hf_ecat_mailbox_coe_sdoinfofrag = -1;
144 static int hf_ecat_mailbox_coe_sdoinfolisttype = -1;
145 static int hf_ecat_mailbox_coe_sdoinfolist = -1;
146 static int hf_ecat_mailbox_coe_sdoinfoindex = -1;
147 static int hf_ecat_mailbox_coe_sdoinfosubindex = -1;
148 static int hf_ecat_mailbox_coe_sdoinfovalueinfo = -1;
149 static int hf_ecat_mailbox_coe_sdoinfoerrorcode = -1;
150 static int hf_ecat_mailbox_coe_sdoinfodatatype = -1;
151 static int hf_ecat_mailbox_coe_sdoinfomaxsub = -1;
152 static int hf_ecat_mailbox_coe_sdoinfoobjcode = -1;
153 static int hf_ecat_mailbox_coe_sdoinfoname = -1;
154 static int hf_ecat_mailbox_coe_sdoinfobitlen = -1;
155 static int hf_ecat_mailbox_coe_sdoinfoobjaccess = -1;
156 static int hf_ecat_mailbox_coe_sdoinfounittype = -1;
157 static int hf_ecat_mailbox_coe_sdoinfodefaultvalue = -1;
158 static int hf_ecat_mailbox_coe_sdoinfominvalue = -1;
159 static int hf_ecat_mailbox_coe_sdoinfomaxvalue = -1;
160 static int hf_ecat_mailboxdata = -1;
161 static int hf_ecat_mailbox_foe = -1;
162 static int hf_ecat_mailbox_foe_opmode = -1;
163 static int hf_ecat_mailbox_foe_filelength = -1;
164 static int hf_ecat_mailbox_foe_filename = -1;
165 static int hf_ecat_mailbox_foe_packetno = -1;
166 static int hf_ecat_mailbox_foe_errcode = -1;
167 static int hf_ecat_mailbox_foe_errtext = -1;
168 static int hf_ecat_mailbox_foe_busydone = -1;
169 static int hf_ecat_mailbox_foe_busyentire = -1;
170 static int hf_ecat_mailbox_foe_data = -1;
171 static int hf_ecat_mailbox_foe_efw = -1;
172 static int hf_ecat_mailbox_foe_efw_cmd = -1;
173 static int hf_ecat_mailbox_foe_efw_size = -1;
174 static int hf_ecat_mailbox_foe_efw_addresslw = -1;
175 static int hf_ecat_mailbox_foe_efw_addresshw = -1;
176 static int hf_ecat_mailbox_foe_efw_data = -1;
177 static int hf_ecat_mailbox_soe = -1;
178 static int hf_ecat_mailbox_soe_header = -1;
179
180 static int hf_ecat_mailbox_soe_header_opcode = -1;
181 static int hf_ecat_mailbox_soe_header_incomplete = -1;
182 static int hf_ecat_mailbox_soe_header_error = -1;
183 static int hf_ecat_mailbox_soe_header_driveno = -1;
184 static int hf_ecat_mailbox_soe_header_datastate = -1;
185 static int hf_ecat_mailbox_soe_header_name = -1;
186 static int hf_ecat_mailbox_soe_header_attribute = -1;
187 static int hf_ecat_mailbox_soe_header_unit = -1;
188 static int hf_ecat_mailbox_soe_header_min = -1;
189 static int hf_ecat_mailbox_soe_header_max = -1;
190 static int hf_ecat_mailbox_soe_header_value = -1;
191 static int hf_ecat_mailbox_soe_header_reserved = -1;
192 static int hf_ecat_mailbox_soe_idn = -1;
193 static int hf_ecat_mailbox_soe_data = -1;
194 static int hf_ecat_mailbox_soe_frag = -1;
195 static int hf_ecat_mailbox_soe_error = -1;
196
197 static expert_field ei_ecat_mailbox_error       = EI_INIT;
198 static expert_field ei_ecat_mailbox_coe_error   = EI_INIT;
199 static expert_field ei_ecat_mailbox_eoe_error   = EI_INIT;
200 static expert_field ei_ecat_mailbox_soe_error   = EI_INIT;
201 static expert_field ei_ecat_mailbox_foe_error   = EI_INIT;
202
203
204 static const value_string EcMBoxType[] =
205 {
206    {   0, "Invalid", },
207    {   1, "AoE (Vendor specific; Beckhoff ADS over EtherCAT)", },
208    {   2, "EoE (Ethernet over EtherCAT)", },
209    {   3, "CoE (CANopen over EtherCAT)", },
210    {   4, "FoE (File access over EtherCAT)", },
211    {   5, "SoE (Servo profile over EtherCAT)", },
212    {  15, "VoE (Vendor specific over EtherCAT)"},
213    {   0x80+1, "AoE - Err", },
214    {   0x80+2, "EoE - Err", },
215    {   0x80+3, "CoE - Err", },
216    {   0x80+4, "FoE - Err", },
217    {   0x80+5, "SoE - Err", },
218    {   0, NULL }
219 };
220
221 static const value_string FoEOpMode[] =
222 {
223    {   1, "RRQ", },
224    {   2, "WRQ", },
225    {   3, "DATA", },
226    {   4, "ACK", },
227    {   5, "ERROR", },
228    {   6, "BUSY", },
229    {   0,  NULL }
230 };
231
232 static const value_string FoEEfwCmd[] =
233 {
234    {   1, "Memory Transfer", },
235    {   2, "Write Code", },
236    {   3, "Check device id", },
237    {   4, "Checksum", },
238    {   5, "Write code checksum", },
239    {   6, "Set device id", },
240    {   8, "Set code id", },
241    {   9, "NOP", },
242    {  10, "Checksum checksum", },
243    {  11, "boot checksum", },
244    { 0, NULL }
245 };
246
247 static const value_string SoeOpcode[] =
248 {
249    {   0, "unused" },
250    {   1, "readReq" },
251    {   2, "readRes"},
252    {   3, "writeReq"},
253    {   4, "writeRes" },
254    {   5, "notification" },
255    {   6, "emergency"},
256    {   0, NULL }
257 };
258
259 static const value_string EoEType[] =
260 {
261    {   EOE_TYPE_FRAME_FRAG, "Fragment" },
262    {   EOE_TYPE_TIMESTAMP_RES, "TimeStamp" },
263    {   EOE_TYPE_INIT_REQ, "Init Req"},
264    {   EOE_TYPE_INIT_RES, "Init Res"},
265    {   EOE_TYPE_MACFILTER_REQ, "MAC Req" },
266    {   EOE_TYPE_MACFILTER_RES, "MAC Res" },
267    {   0, NULL }
268 };
269
270 static const value_string CANopenType[] =
271 {
272    {   ETHERCAT_COE_TYPE_EMERGENCY, "EMERGENCY" },
273    {   ETHERCAT_COE_TYPE_SDOREQ, "SDO Req" },
274    {   ETHERCAT_COE_TYPE_SDORES, "SDO Res"},
275    {   ETHERCAT_COE_TYPE_TXPDO, "TxPDO"},
276    {   ETHERCAT_COE_TYPE_RXPDO, "RxPDO" },
277    {   ETHERCAT_COE_TYPE_TXPDO_RTR, "TxPDO_RTR" },
278    {   ETHERCAT_COE_TYPE_RXPDO_RTR, "RxPDO_RTR" },
279    {   0, NULL }
280 };
281
282 static const value_string CANopenSdoInfo[] =
283 {
284    {   ECAT_COE_INFO_OPCODE_LIST_Q, "List Req" },
285    {   ECAT_COE_INFO_OPCODE_LIST_S, "List Res" },
286    {   ECAT_COE_INFO_OPCODE_OBJ_Q, "Obj Req"},
287    {   ECAT_COE_INFO_OPCODE_OBJ_S, "Obj Res"},
288    {   ECAT_COE_INFO_OPCODE_ENTRY_Q, "Entry Req" },
289    {   ECAT_COE_INFO_OPCODE_ENTRY_S, "Entry Res" },
290    {   ECAT_COE_INFO_OPCODE_ERROR_S, "Error Res" },
291    {   0, NULL }
292 };
293
294 static const true_false_string tfs_complete =
295 {
296    "Complete", "Legacy"
297 };
298
299 void init_mbx_header(PETHERCAT_MBOX_HEADER pMbox, tvbuff_t *tvb, gint offset)
300 {
301    pMbox->Length = tvb_get_letohs(tvb, offset); offset+=2;
302    pMbox->Address = tvb_get_letohs(tvb, offset); offset+=2;
303    pMbox->aControlUnion.Control = tvb_get_letohs(tvb, offset);
304 }
305
306 static void init_eoe_header(PETHERCAT_EOE_HEADER pEoE, tvbuff_t *tvb, gint offset)
307 {
308    pEoE->anEoeHeaderInfoUnion.Info = tvb_get_letohs(tvb, offset); offset+=2;
309    pEoE->anEoeHeaderDataUnion.Result = tvb_get_letohs(tvb, offset);
310 }
311
312 static void init_foe_header(PETHERCAT_FOE_HEADER pFoE, tvbuff_t *tvb, gint offset)
313 {
314    pFoE->OpMode = tvb_get_guint8(tvb, offset++);
315    pFoE->Reserved1 = tvb_get_guint8(tvb, offset++);
316    pFoE->aFoeHeaderDataUnion.FileLength = tvb_get_letohl(tvb, offset);
317 }
318
319 static void init_soe_header(PETHERCAT_SOE_HEADER pSoE, tvbuff_t *tvb, gint offset)
320 {
321    pSoE->anSoeHeaderControlUnion.v2.Control = tvb_get_guint8(tvb, offset++);
322    pSoE->anSoeHeaderControlUnion.v2.Element = tvb_get_guint8(tvb, offset++);
323    pSoE->anSoeHeaderDataUnion.FragmentsLeft = tvb_get_letohs(tvb, offset);
324 }
325
326 static void init_coe_header(PETHERCAT_COE_HEADER pCoE, tvbuff_t *tvb, gint offset)
327 {
328    pCoE->header = tvb_get_letohs(tvb, offset);
329 }
330
331 static void init_sdo_header(PETHERCAT_SDO_HEADER pSdo, tvbuff_t *tvb, gint offset)
332 {
333    pSdo->anSdoHeaderUnion.CS = tvb_get_guint8(tvb, offset++);
334    pSdo->Index = tvb_get_letohs(tvb, offset);offset+=2;
335    pSdo->SubIndex = tvb_get_guint8(tvb, offset++);
336    pSdo->Data = tvb_get_letohl(tvb, offset);
337 }
338
339 static void init_sdo_info_header(PETHERCAT_SDO_INFO_HEADER pInfo, tvbuff_t *tvb, gint offset)
340 {
341    pInfo->anSdoControlUnion.Control = tvb_get_guint8(tvb, offset++);
342    pInfo->Reserved = tvb_get_guint8(tvb, offset);
343    pInfo->FragmentsLeft = 2;
344 }
345
346 static void CANopenSdoReqFormatter(PETHERCAT_SDO_HEADER pSdo, char *szText, gint nMax)
347 {
348    switch ( pSdo->anSdoHeaderUnion.Idq.Ccs )
349    {
350    case SDO_CCS_INITIATE_DOWNLOAD:
351       g_snprintf ( szText, nMax, "SDO Req : 'Initiate Download' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index,  pSdo->SubIndex);
352       break;
353    case SDO_CCS_INITIATE_UPLOAD:
354       g_snprintf ( szText, nMax, "SDO Req : 'Initiate Upload' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index,  pSdo->SubIndex);
355       break;
356    case SDO_CCS_DOWNLOAD_SEGMENT:
357       g_snprintf ( szText, nMax, "SDO Req : 'Download Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs);
358       break;
359    case SDO_CCS_UPLOAD_SEGMENT:
360       g_snprintf ( szText, nMax, "SDO Req : 'Upload Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs);
361       break;
362    case SDO_CCS_ABORT_TRANSFER:
363       g_snprintf ( szText, nMax, "SDO Req : 'Abort Transfer' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs);
364       break;
365    default:
366       g_snprintf ( szText, nMax, "SDO Req : Ccs %d", pSdo->anSdoHeaderUnion.Idq.Ccs);
367    }
368 }
369
370 static void FoeFormatter(tvbuff_t *tvb, gint offset, char *szText, gint nMax, guint foe_length)
371 {
372    ETHERCAT_FOE_HEADER foe;
373    char tmp[50];
374    memset(tmp, 0, sizeof(tmp));
375
376    init_foe_header(&foe, tvb, offset);
377
378    switch ( foe.OpMode )
379    {
380    case ECAT_FOE_OPMODE_RRQ:
381    case ECAT_FOE_OPMODE_WRQ:
382    case ECAT_FOE_OPMODE_ERR:
383       if ( foe_length > ETHERCAT_FOE_HEADER_LEN )
384          tvb_memcpy(tvb, tmp, offset+ETHERCAT_FOE_HEADER_LEN, MIN(foe_length-ETHERCAT_FOE_HEADER_LEN, sizeof(tmp)-1));
385       break;
386    }
387
388    switch ( foe.OpMode )
389    {
390    case ECAT_FOE_OPMODE_RRQ:
391       g_snprintf ( szText, nMax, "FoE RRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp);
392       break;
393    case ECAT_FOE_OPMODE_WRQ:
394       g_snprintf ( szText, nMax, "FoE WRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp);
395       break;
396    case ECAT_FOE_OPMODE_DATA:
397       g_snprintf ( szText, nMax, "FoE DATA (%d) : %d Bytes", foe.aFoeHeaderDataUnion.v.PacketNo, foe_length-ETHERCAT_FOE_HEADER_LEN);
398       break;
399    case ECAT_FOE_OPMODE_ACK:
400       g_snprintf ( szText, nMax, "FoE ACK (%d)", foe.aFoeHeaderDataUnion.v.PacketNo);
401       break;
402    case ECAT_FOE_OPMODE_ERR:
403       g_snprintf ( szText, nMax, "FoE ERR (%d) : '%s'", foe.aFoeHeaderDataUnion.ErrorCode, tmp);
404       break;
405    case ECAT_FOE_OPMODE_BUSY:
406       if ( foe.aFoeHeaderDataUnion.v2.Entire > 0 )
407          g_snprintf ( szText, nMax, "FoE BUSY (%d%%)", ((guint32)foe.aFoeHeaderDataUnion.v2.Done*100)/foe.aFoeHeaderDataUnion.v2.Entire);
408       else
409          g_snprintf ( szText, nMax, "FoE BUSY (%d/%d)", foe.aFoeHeaderDataUnion.v2.Done, foe.aFoeHeaderDataUnion.v2.Entire);
410       break;
411    default:
412       g_snprintf ( szText, nMax, "FoE Unknown");
413    }
414 }
415
416 static void SoEIdToString( char* txt, guint16 id, int nMax)
417 {
418    if ( id & 0x8000 )
419       g_snprintf(txt, nMax, "P-%d-%04d", (id>>12) & 0x0007, id & 0x0FFF );
420    else
421       g_snprintf(txt, nMax, "S-%d-%04d", id>>12, id & 0x0FFF );
422 }
423
424 static void SoeFormatter(tvbuff_t *tvb, gint offset, char *szText, gint nMax, guint soe_length)
425 {
426    ETHERCAT_SOE_HEADER soe;
427    char tmp[50];
428    char elm[50];
429    memset(tmp, 0, sizeof(tmp));
430
431    init_soe_header(&soe, tvb, offset);
432    offset+=ETHERCAT_SOE_HEADER_LEN;
433
434    if ( !soe.anSoeHeaderControlUnion.v.Error )
435    {
436       if ( !soe.anSoeHeaderControlUnion.v.InComplete )
437       {
438          SoEIdToString(tmp, soe.anSoeHeaderDataUnion.IDN, sizeof(tmp)-1);
439          elm[0] = '\0';
440          if ( soe.anSoeHeaderControlUnion.v.DataState )
441             g_strlcat(elm, "D", 50);
442          if ( soe.anSoeHeaderControlUnion.v.Name )
443             g_strlcat(elm, "N", 50);
444          if ( soe.anSoeHeaderControlUnion.v.Attribute )
445             g_strlcat(elm, "A", 50);
446          if ( soe.anSoeHeaderControlUnion.v.Unit )
447             g_strlcat(elm, "U", 50);
448          if ( soe.anSoeHeaderControlUnion.v.Min )
449             g_strlcat(elm, "I", 50);
450          if ( soe.anSoeHeaderControlUnion.v.Max )
451             g_strlcat(elm, "X", 50);
452          if ( soe.anSoeHeaderControlUnion.v.Value )
453             g_strlcat(elm, "V", 50);
454          switch ( soe.anSoeHeaderControlUnion.v.OpCode )
455          {
456          case ECAT_SOE_OPCODE_RRQ:
457             g_snprintf ( szText, nMax, "SoE: RRQ (%s, '%s')", tmp, elm);
458             break;
459          case ECAT_SOE_OPCODE_RRS:
460             g_snprintf ( szText, nMax, "SoE: RRS (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN));
461             break;
462          case ECAT_SOE_OPCODE_WRS:
463             g_snprintf ( szText, nMax, "SoE: WRS (%s, '%s')", tmp, elm);
464             break;
465          case ECAT_SOE_OPCODE_WRQ:
466             g_snprintf ( szText, nMax, "SoE: WRQ (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN));
467             break;
468          case ECAT_SOE_OPCODE_NFC:
469             g_snprintf ( szText, nMax, "SoE: NFC (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN));
470             break;
471          case 6:
472             g_snprintf ( szText, nMax, "SoE: EMGCY");
473             break;
474          default:
475             g_snprintf ( szText, nMax, "SoE:");
476          }
477       }
478       else
479          g_snprintf ( szText, nMax, "SoE: FragmentsLeft %d", soe.anSoeHeaderDataUnion.FragmentsLeft);
480    }
481    else
482       g_snprintf ( szText, nMax, "SoE: Error %04x", tvb_get_letohs(tvb, offset));
483 }
484
485 /* ethercat mailbox */
486 static void dissect_ecat_coe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
487 {
488    proto_tree *ecat_coe_tree = NULL, *ecat_sdo_tree, *ecat_coe_sdoccs_tree, *ecat_coe_sdoscs_tree;
489
490    proto_item *anItem = NULL, *aparent = NULL;
491    char szText[200];
492    int nMax = sizeof(szText)-1;
493
494    guint coe_length = tvb_reported_length(tvb)-offset;
495    guint16 len;
496
497    if( tree )
498    {
499       anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_coe, tvb, offset, coe_length, NULL, "CoE");
500       aparent = proto_item_get_parent(anItem);
501       proto_item_append_text(aparent,":CoE ");
502    }
503
504    col_append_str(pinfo->cinfo, COL_INFO, "CoE ");
505
506    if( coe_length >= ETHERCAT_COE_HEADER_LEN )
507    {
508       ETHERCAT_COE_HEADER coe;
509       init_coe_header(&coe, tvb, offset);
510       if( tree )
511       {
512          ecat_coe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe);
513
514          proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_number, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.v.Number);
515          proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_type, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.v.Type);
516       }
517
518       offset += ETHERCAT_COE_HEADER_LEN;
519
520       switch (coe.v.Type)
521       {
522       case ETHERCAT_COE_TYPE_SDOREQ:
523          {
524             ETHERCAT_SDO_HEADER sdo;
525
526             if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN )
527             {
528                col_append_str(pinfo->cinfo, COL_INFO, "Sdo Req - invalid length");
529                expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Req - invalid length");
530                break;
531             }
532
533             init_sdo_header(&sdo, tvb, offset);
534
535             CANopenSdoReqFormatter(&sdo, szText, nMax);
536              col_append_str(pinfo->cinfo, COL_INFO, szText);
537
538             if( tree )
539             {
540                proto_item_append_text(aparent, "%s", szText);
541
542                anItem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_sdoreq, tvb, offset, 1, sdo.anSdoHeaderUnion.Idq.Ccs);
543                proto_item_set_text(anItem, "%s", szText);
544                ecat_sdo_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_sdo);
545
546                switch ( sdo.anSdoHeaderUnion.Idq.Ccs )
547                {
548                case SDO_CCS_INITIATE_DOWNLOAD:
549                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
550                   ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs);
551                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_sizeind, tvb, offset, 1, ENC_LITTLE_ENDIAN);
552                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_expedited, tvb, offset, 1, ENC_LITTLE_ENDIAN);
553                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size0, tvb, offset, 1, ENC_LITTLE_ENDIAN);
554                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
555                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN);
556
557                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
558                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
559                   if ( sdo.anSdoHeaderUnion.Idq.SizeInd && !sdo.anSdoHeaderUnion.Idq.Expedited )
560                   {
561                      len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN;
562                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
563                      offset+=ETHERCAT_SDO_HEADER_LEN;
564                      if ( len > 0 )
565                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, ENC_NA);
566                   }
567                   else
568                   {
569                      if ( sdo.anSdoHeaderUnion.Idq.Size == 3 )
570                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, ENC_LITTLE_ENDIAN);
571                      else if ( sdo.anSdoHeaderUnion.Idq.Size == 2 )
572                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, ENC_LITTLE_ENDIAN);
573                      else
574                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
575                   }
576                   break;
577                case SDO_CCS_INITIATE_UPLOAD:
578                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsiu, tvb, offset, 1, ENC_LITTLE_ENDIAN);
579                   ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs);
580                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN);
581
582                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
583                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
584
585                   break;
586                case SDO_CCS_DOWNLOAD_SEGMENT:
587                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsds, tvb, offset, 1, ENC_LITTLE_ENDIAN);
588                   ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs);
589                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_lastseg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
590                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
591                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN);
592                   offset+=1;
593
594                   if ( coe_length-offset > 0 )
595                   {
596                      anItem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, ENC_NA);
597                      proto_item_append_text(anItem, "(len = %d)", coe_length-offset);
598                   }
599                   break;
600                case SDO_CCS_UPLOAD_SEGMENT:
601                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsus, tvb, offset, 1, ENC_LITTLE_ENDIAN);
602                   ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs);
603                   proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsus_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN);
604                   break;
605                case SDO_CCS_ABORT_TRANSFER:
606                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
607                   break;
608                }
609             }
610          }
611          break;
612
613       case ETHERCAT_COE_TYPE_SDORES:
614          {
615             ETHERCAT_SDO_HEADER sdo;
616             if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN )
617             {
618                col_append_str(pinfo->cinfo, COL_INFO, "Sdo Res - invalid length");
619                expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Res - invalid length");
620                break;
621             }
622
623             init_sdo_header(&sdo, tvb, offset);
624
625             col_append_fstr(pinfo->cinfo, COL_INFO, "SDO Res: Scs %d", sdo.anSdoHeaderUnion.Ids.Scs);
626             if( tree )
627             {
628                proto_tree_add_uint_format_value(ecat_coe_tree, hf_ecat_mailbox_coe_sdores, tvb, offset, 1, sdo.anSdoHeaderUnion.Ids.Scs,
629                                             "Scs %d", sdo.anSdoHeaderUnion.Ids.Scs);
630                ecat_sdo_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_sdo);
631
632                switch ( sdo.anSdoHeaderUnion.Ids.Scs )
633                {
634                case SDO_SCS_INITIATE_DOWNLOAD:
635                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
636                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
637                   break;
638                case SDO_SCS_INITIATE_UPLOAD:
639                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsiu, tvb, offset, 1, ENC_LITTLE_ENDIAN);
640                   ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs);
641                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_sizeind, tvb, offset, 1, ENC_LITTLE_ENDIAN);
642                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_expedited, tvb, offset, 1, ENC_LITTLE_ENDIAN);
643                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size0, tvb, offset, 1, ENC_LITTLE_ENDIAN);
644                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
645                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN);
646
647                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
648                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
649                   if ( sdo.anSdoHeaderUnion.Ius.SizeInd && !sdo.anSdoHeaderUnion.Ius.Expedited )
650                   {
651                      len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN;
652                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
653                      offset+=ETHERCAT_SDO_HEADER_LEN;
654                      if ( len > 0 )
655                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, ENC_NA);
656                   }
657                   else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 3 )
658                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, ENC_LITTLE_ENDIAN);
659                   else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 2 )
660                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, ENC_LITTLE_ENDIAN);
661                   else
662                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
663                   break;
664                case SDO_SCS_DOWNLOAD_SEGMENT:
665                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsds, tvb, offset, 1, ENC_LITTLE_ENDIAN);
666                   ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs);
667                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsds_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN);
668                   break;
669                case SDO_SCS_UPLOAD_SEGMENT:
670                   anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsus, tvb, offset, 1, ENC_LITTLE_ENDIAN);
671                   ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs);
672                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_lastseg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
673                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_bytes, tvb, offset, 1, ENC_LITTLE_ENDIAN);
674                   proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN);
675                   offset+=1;
676
677                   if ( coe_length-offset> 0 )
678                   {
679                      anItem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, ENC_NA);
680                      proto_item_append_text(anItem, "(len = %d)", coe_length-offset);
681                   }
682                   break;
683                }
684             }
685          }
686          break;
687
688       case ETHERCAT_COE_TYPE_SDOINFO:
689          {
690             ETHERCAT_SDO_INFO_HEADER info;
691
692             if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_INFO_LISTREQ_LEN )
693             {
694                col_append_str(pinfo->cinfo, COL_INFO, "Sdo Info - invalid length");
695                expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Info - invalid length");
696                break;
697             }
698
699             memset(&info, 0x0, sizeof(info));
700             init_sdo_info_header(&info, tvb, offset);
701
702             col_append_str(pinfo->cinfo, COL_INFO, val_to_str(info.anSdoControlUnion.v.OpCode & 0x7F, CANopenSdoInfo, "%d (Unknown)"));
703             if ( (info.anSdoControlUnion.v.OpCode & 0x80) != 0 )
704                 col_append_str(pinfo->cinfo, COL_INFO, " - More Follows");
705
706             if( tree )
707             {
708                proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoopcode, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
709                offset++; /*Reserved*/
710
711                proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfofrag, tvb, offset, 2, ENC_LITTLE_ENDIAN);
712                offset+=2;
713
714                switch ( info.anSdoControlUnion.v.OpCode )
715                {
716                case ECAT_COE_INFO_OPCODE_LIST_Q:
717                   {
718                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
719                   }
720                   break;
721                case ECAT_COE_INFO_OPCODE_LIST_S:
722                   {
723                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
724                      offset+=2;
725
726                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolist, tvb, offset, coe_length-offset, ENC_NA);
727                   }
728                   break;
729                case ECAT_COE_INFO_OPCODE_OBJ_Q:
730                   proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
731                   break;
732                case ECAT_COE_INFO_OPCODE_OBJ_S:
733                   {
734                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
735                      offset+=2;
736
737                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
738                      offset+=2;
739
740                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxsub, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
741                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjcode, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
742
743                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, ENC_ASCII|ENC_NA);
744                   }
745                   break;
746                case ECAT_COE_INFO_OPCODE_ENTRY_Q:
747                   {
748                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
749                      offset+=2;
750
751                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
752                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset, 1, ENC_LITTLE_ENDIAN);
753                   }
754                   break;
755                case ECAT_COE_INFO_OPCODE_ENTRY_S:
756                   {
757                      guint16 objlen;
758
759                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
760                      offset+=2;
761
762                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
763                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
764
765                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
766                      offset+=2;
767
768                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfobitlen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
769                      offset+=2;
770
771                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjaccess, tvb, offset, 2, ENC_LITTLE_ENDIAN);
772                      offset+=2;
773
774                      if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x08) != 0 )
775                      {
776                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfounittype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
777                         offset+=2;
778                      }
779                      if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x10) != 0 )
780                      {
781                         objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen);
782                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodefaultvalue, tvb, offset, objlen, ENC_NA);
783                         offset+=objlen;
784                      }
785                      if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x20) != 0 )
786                      {
787                         objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen);
788                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfominvalue, tvb, offset, objlen, ENC_NA);
789                         offset+=objlen;
790                      }
791                      if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x40) != 0 )
792                      {
793                         objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen);
794                         proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxvalue, tvb, offset, objlen, ENC_NA);
795                         offset+=objlen;
796                      }
797                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, ENC_ASCII|ENC_NA);
798                   }
799                   break;
800                case ECAT_COE_INFO_OPCODE_ERROR_S:
801                   {
802                      proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoerrorcode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
803                   }
804                   break;
805                }
806             }
807          }
808          break;
809       }
810    }
811    else
812    {
813       col_append_str(pinfo->cinfo, COL_INFO, "- invalid length");
814       expert_add_info(pinfo, tree, &ei_ecat_mailbox_coe_error);
815    }
816 }
817
818 static void dissect_ecat_soe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
819 {
820    proto_tree *ecat_soeflag_tree, *ecat_soe_tree;
821
822    proto_item *anItem = NULL ,*aparent = NULL;
823    char szText[200];
824    int nMax = sizeof(szText)-1;
825
826    guint soe_length = tvb_reported_length(tvb)-offset;
827
828    if( tree )
829    {
830       anItem = proto_tree_add_item(tree, hf_ecat_mailbox_soe, tvb, offset, soe_length, ENC_NA);
831
832       aparent = proto_item_get_parent(anItem);
833       proto_item_append_text(aparent,":SoE ");
834    }
835
836    if( soe_length >= ETHERCAT_SOE_HEADER_LEN )
837    {
838       SoeFormatter(tvb, offset, szText, nMax, soe_length);
839       col_append_str(pinfo->cinfo, COL_INFO, szText);
840
841       if( tree )
842       {
843          ETHERCAT_SOE_HEADER soe;
844          init_soe_header(&soe, tvb, offset);
845
846          proto_item_append_text(aparent, "%s", szText);
847          proto_item_set_text(anItem, "%s", szText);
848
849          ecat_soe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_soe);
850          anItem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_header, tvb, offset , 2, ENC_LITTLE_ENDIAN);
851
852          ecat_soeflag_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_soeflag);
853          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_opcode, tvb, offset, 2, ENC_LITTLE_ENDIAN);
854          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_incomplete, tvb, offset, 2, ENC_LITTLE_ENDIAN);
855          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_error, tvb, offset, 2, ENC_LITTLE_ENDIAN);
856          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_driveno, tvb, offset, 2, ENC_LITTLE_ENDIAN);
857          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_datastate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
858          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_name, tvb, offset, 2, ENC_LITTLE_ENDIAN);
859          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_attribute, tvb, offset, 2, ENC_LITTLE_ENDIAN);
860          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_unit, tvb, offset, 2, ENC_LITTLE_ENDIAN);
861          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_min, tvb, offset, 2, ENC_LITTLE_ENDIAN);
862          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_max, tvb, offset, 2, ENC_LITTLE_ENDIAN);
863          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
864          proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
865          offset+=2;
866
867          if ( !soe.anSoeHeaderControlUnion.v.Error )
868          {
869             if ( !soe.anSoeHeaderControlUnion.v.InComplete )
870             {
871                switch (soe.anSoeHeaderControlUnion.v.OpCode)
872                {
873                case ECAT_SOE_OPCODE_RRQ:
874                case ECAT_SOE_OPCODE_WRS:
875                   proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
876                   break;
877                case ECAT_SOE_OPCODE_RRS:
878                case ECAT_SOE_OPCODE_WRQ:
879                case ECAT_SOE_OPCODE_NFC:
880                   proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
881                   offset+=2;
882                   proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, ENC_NA);
883                   break;
884                }
885             }
886             else
887             {
888                proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_frag, tvb, offset, 2, ENC_LITTLE_ENDIAN);
889                offset+=2;
890
891                proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, ENC_NA);
892             }
893          }
894          else
895          {
896             proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN);
897             proto_tree_add_item(tree, hf_ecat_mailbox_soe_error, tvb, offset, 2, ENC_LITTLE_ENDIAN);
898          }
899       }
900    }
901    else
902    {
903       col_append_str(pinfo->cinfo, COL_INFO, "SoE - invalid length");
904       expert_add_info(pinfo, tree, &ei_ecat_mailbox_soe_error);
905    }
906 }
907
908 static void dissect_ecat_eoe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
909 {
910    proto_tree *ecat_eoe_tree = 0, *ecat_fraghead_tree, *ecat_eoe_init_tree, *ecat_eoe_macfilter_tree,
911       *ecat_eoe_macfilter_filter_tree;
912    tvbuff_t *next_tvb;
913    proto_item *anItem = NULL, *aparent = NULL;
914    int nCnt;
915
916    guint eoe_length = tvb_reported_length(tvb)-offset;
917
918    if( tree )
919    {
920       anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_eoe, tvb, offset, eoe_length, NULL, "EoE Fragment");
921
922       aparent = proto_item_get_parent(anItem);
923       proto_item_append_text(aparent,":EoE ");
924    }
925
926    if( eoe_length >= ETHERCAT_EOE_HEADER_LEN )
927    {
928       ETHERCAT_EOE_HEADER eoe;
929       init_eoe_header(&eoe, tvb, offset);
930       if ( eoe.anEoeHeaderInfoUnion.v.Type == EOE_TYPE_FRAME_FRAG )
931           col_append_fstr(pinfo->cinfo, COL_INFO, "EoE-Frag %d", eoe.anEoeHeaderDataUnion.v.Fragment);
932       else
933           col_append_str(pinfo->cinfo, COL_INFO, "EoE");
934
935       { /* Do the following even 'if (tree == NULL)' since a call_dissector() is done */
936          ecat_eoe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe);
937
938          anItem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fraghead, tvb, offset, 4, ENC_NA);
939          ecat_fraghead_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_fraghead);
940
941          proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_type, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.Type);
942
943          switch ( eoe.anEoeHeaderInfoUnion.v.Type )
944          {
945          case EOE_TYPE_FRAME_FRAG:
946             proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_fragno, tvb, offset, 4, eoe.anEoeHeaderDataUnion.v.Fragment);
947
948             if (eoe.anEoeHeaderDataUnion.v.Fragment == 0)
949             {
950                 proto_tree_add_uint_format(ecat_fraghead_tree, hf_ecat_mailbox_eoe_offset, tvb, offset, 4, 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer,
951                     "BufferSize: %d", 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer);
952             }
953             else
954             {
955                 proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_offset, tvb, offset, 4, 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer);
956             }
957
958             proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_frame, tvb, offset, 4, eoe.anEoeHeaderDataUnion.v.FrameNo);
959
960             proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_last, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.LastFragment);
961
962             if ( eoe.anEoeHeaderInfoUnion.v.TimeStampRequested )
963             {
964                proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampreq, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.TimeStampRequested);
965             }
966
967             if ( eoe.anEoeHeaderInfoUnion.v.TimeStampAppended )
968             {
969                proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampapp, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.TimeStampAppended);
970             }
971
972             offset+=ETHERCAT_EOE_HEADER_LEN;
973             proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fragment, tvb, offset, eoe_length-offset, ENC_NA);
974
975             if ( eoe.anEoeHeaderDataUnion.v.Fragment == 0 )
976             {
977                next_tvb = tvb_new_subset_length(tvb, offset, eoe_length-offset);
978                call_dissector( eth_handle, next_tvb, pinfo, ecat_eoe_tree);
979             }
980
981             if ( eoe.anEoeHeaderInfoUnion.v.TimeStampAppended )
982             {
983                proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_timestamp, tvb, eoe_length-ETHERCAT_EOE_TIMESTAMP_LEN, ETHERCAT_EOE_TIMESTAMP_LEN, ENC_LITTLE_ENDIAN);
984             }
985             break;
986
987          case EOE_TYPE_TIMESTAMP_RES:
988             proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_timestamp, tvb, offset+ETHERCAT_EOE_HEADER_LEN, ETHERCAT_EOE_TIMESTAMP_LEN, ENC_LITTLE_ENDIAN);
989             break;
990
991          case EOE_TYPE_INIT_REQ:
992             offset+=ETHERCAT_EOE_HEADER_LEN;
993             anItem = proto_tree_add_item(ecat_fraghead_tree, hf_ecat_mailbox_eoe_init, tvb, offset, MIN(eoe_length-offset,ETHERCAT_EOE_INIT_LEN), ENC_NA);
994             if( eoe_length-offset >= ETHERCAT_EOE_INIT_LEN )
995             {
996                ecat_eoe_init_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_init);
997
998                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_macaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
999                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_ipaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1000                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_subnetmask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1001                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_defaultgateway, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1002                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsserver, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1003                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsname, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1004                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_append_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1005                offset+=4;
1006
1007                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_macaddr, tvb, offset, ETHERNET_ADDRESS_LEN, ENC_NA);
1008                offset+=ETHERNET_ADDRESS_LEN;
1009
1010                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_ipaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1011                offset+=4;
1012
1013                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_subnetmask, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1014                offset+=4;
1015
1016                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_defaultgateway, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1017                offset+=4;
1018
1019                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsserver, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1020                offset+=4;
1021
1022                proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsname, tvb, offset, 32, ENC_ASCII|ENC_NA);
1023             }
1024             else
1025             {
1026                proto_item_append_text(anItem, " - Invalid length!");
1027                expert_add_info(pinfo, anItem, &ei_ecat_mailbox_eoe_error);
1028             }
1029             break;
1030
1031          case EOE_TYPE_MACFILTER_REQ:
1032             {
1033                EoeMacFilterOptionsUnion options;
1034                offset+=ETHERCAT_EOE_HEADER_LEN;
1035                anItem = proto_tree_add_item(ecat_fraghead_tree, hf_ecat_mailbox_eoe_macfilter, tvb, offset, MIN(eoe_length-offset, ETHERCAT_EOE_MACFILTER_LEN), ENC_NA);
1036                if( eoe_length-offset >= ETHERCAT_EOE_MACFILTER_LEN )
1037                {
1038                   proto_tree *ecat_eoe_macfilter_filtermask_tree;
1039
1040                   ecat_eoe_macfilter_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter);
1041
1042                   /* XXX: Is the field containing EoeMacFilterOptionsUnion 4 bytes or 2 bytes ? */
1043                   /*      sizeof EoeMacFilterOptionsUnion = 2 bytes but the code below  */
1044                   /*      originally used a field width of 4 bytes.                     */
1045                   /*      Given the size of the union, the code below was changed to    */
1046                   /*       use a field width of 2 bytes.                                */
1047                   /*      The hf[] entries were also changed to match the union struct  */
1048                   proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_macfiltercount, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN);
1049                   proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_maskcount, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN);
1050                   proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_nobroadcasts, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN);
1051                   options.Options = tvb_get_letohs(tvb, offset);
1052                   offset+=/*4*/ 2;
1053
1054                   anItem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_filter, tvb, offset, 16*ETHERNET_ADDRESS_LEN, ENC_NA);
1055                   ecat_eoe_macfilter_filter_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter_filter);
1056                   for( nCnt=0; nCnt<options.v.MacFilterCount; nCnt++)
1057                      proto_tree_add_item(ecat_eoe_macfilter_filter_tree, hf_ecat_mailbox_eoe_macfilter_filters[nCnt], tvb, offset+nCnt*ETHERNET_ADDRESS_LEN, ETHERNET_ADDRESS_LEN, ENC_NA);
1058                   offset+=16*ETHERNET_ADDRESS_LEN;
1059
1060                   anItem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_filtermask, tvb, offset, 4*4, ENC_NA);
1061                   ecat_eoe_macfilter_filtermask_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter_filtermask);
1062                   for( nCnt=0; nCnt<options.v.MacFilterMaskCount; nCnt++)
1063                      proto_tree_add_item(ecat_eoe_macfilter_filtermask_tree, hf_ecat_mailbox_eoe_macfilter_filtermasks[nCnt], tvb, offset+nCnt*4, 4, ENC_NA);
1064                }
1065                else
1066                {
1067                   proto_item_append_text(anItem, " - Invalid length!");
1068                   expert_add_info(pinfo, anItem, &ei_ecat_mailbox_eoe_error);
1069                }
1070             }
1071             break;
1072
1073          case EOE_TYPE_INIT_RES:
1074          case EOE_TYPE_MACFILTER_RES:
1075             break;
1076          }
1077       }
1078
1079       col_prepend_fstr(pinfo->cinfo, COL_INFO, "EoE(");
1080
1081       col_prepend_fstr(pinfo->cinfo, COL_PROTOCOL, "EoE-");
1082    }
1083    else
1084    {
1085       expert_add_info(pinfo, tree, &ei_ecat_mailbox_eoe_error);
1086       col_append_str(pinfo->cinfo, COL_INFO, "EoE - invalid length!");
1087    }
1088 }
1089
1090 static void dissect_ecat_foe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
1091 {
1092    proto_tree *ecat_foe_tree,*ecat_foe_efw_tree;
1093
1094    proto_item *anItem= NULL,*aparent = NULL;
1095    char szText[200];
1096    int nMax = sizeof(szText)-1;
1097
1098    guint foe_length = tvb_reported_length(tvb)-offset;
1099
1100    if( tree )
1101    {
1102       anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_foe, tvb, offset, foe_length, NULL, "Foe");
1103
1104       aparent = proto_item_get_parent(anItem);
1105       proto_item_append_text(aparent,"FoE ");
1106    }
1107
1108    if( foe_length >= ETHERCAT_FOE_HEADER_LEN )
1109    {
1110       FoeFormatter(tvb, offset, szText, nMax, foe_length);
1111       col_append_str(pinfo->cinfo, COL_INFO, szText);
1112
1113       if( tree )
1114       {
1115          ETHERCAT_FOE_HEADER foe;
1116          init_foe_header(&foe, tvb, offset);
1117
1118          ecat_foe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_foe);
1119          proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_opmode, tvb, offset++, 1, ENC_LITTLE_ENDIAN);
1120          offset++; /*Reserved1;*/
1121
1122          switch (foe.OpMode)
1123          {
1124          case ECAT_FOE_OPMODE_RRQ:
1125          case ECAT_FOE_OPMODE_WRQ:
1126             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filelength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1127             offset+=4;
1128
1129             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filename, tvb, offset, foe_length-offset, ENC_ASCII|ENC_NA);
1130             break;
1131
1132          case ECAT_FOE_OPMODE_DATA:
1133             {
1134                proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1135                offset+=4; /*+2 for Reserved2*/
1136
1137                proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_data, tvb, offset, foe_length-offset, ENC_NA);
1138
1139                if( foe_length-offset >= sizeof(TEFWUPDATE_HEADER) )
1140                {
1141                   anItem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_efw, tvb, offset, foe_length-offset, ENC_NA);
1142                   ecat_foe_efw_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_foe_efw);
1143                   proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1144                   offset+=2;
1145
1146                   proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1147                   offset+=2;
1148
1149                   proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresslw, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1150                   offset+=2;
1151
1152                   proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresshw, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1153                   offset+=2;
1154
1155                   proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_data, tvb, offset, foe_length-offset, ENC_NA);
1156                }
1157             }
1158             break;
1159
1160          case ECAT_FOE_OPMODE_ACK:
1161             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1162             break;
1163
1164          case ECAT_FOE_OPMODE_ERR:
1165             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errcode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1166             offset+=4;
1167
1168             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errtext, tvb, offset, foe_length-offset, ENC_ASCII|ENC_NA);
1169             break;
1170
1171          case ECAT_FOE_OPMODE_BUSY:
1172             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busydone, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1173             offset+=2;
1174
1175             proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busyentire, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1176             break;
1177          }
1178       }
1179    }
1180    else
1181    {
1182       col_append_str(pinfo->cinfo, COL_INFO, "FoE - invalid length");
1183       expert_add_info(pinfo, tree, &ei_ecat_mailbox_foe_error);
1184    }
1185 }
1186
1187 static int dissect_ecat_mailbox(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1188 {
1189    proto_tree *ecat_mailbox_tree = NULL;
1190    proto_tree *ecat_mailbox_header_tree = NULL;
1191    tvbuff_t *next_tvb;
1192    proto_item *anItem;
1193    gint offset = 0;
1194
1195    gint mailbox_length = tvb_reported_length(tvb);
1196
1197    if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN )
1198    {
1199       ETHERCAT_MBOX_HEADER hdr;
1200
1201       init_mbx_header(&hdr, tvb, offset);
1202
1203       col_append_str(pinfo->cinfo, COL_INFO, " Mbx(");
1204
1205       /* Create the mailbox sub tree */
1206       anItem = proto_tree_add_item(tree, proto_ecat_mailbox, tvb, 0, ETHERCAT_MBOX_HEADER_LEN+hdr.Length, ENC_NA);
1207       ecat_mailbox_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox);
1208
1209       /* Create a mailbox header subtree */
1210       ecat_mailbox_header_tree = proto_tree_add_subtree(ecat_mailbox_tree, tvb, offset, ETHERCAT_MBOX_HEADER_LEN, ett_ecat_mailbox_header, NULL, "Header");
1211
1212       /* Add length information to the mailbox header */
1213       proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxlength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1214       offset+=2;
1215
1216       /* Add address information to the mailbox header */
1217       proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxaddress, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1218       offset+=2;
1219
1220       /* Add priority information to the mailbox header */
1221       proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxpriority, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1222       offset+=1;
1223
1224       /* Add type information to the mailbox header */
1225       proto_tree_add_uint(ecat_mailbox_header_tree, hf_ecat_mailboxtype, tvb, offset, 1, hdr.aControlUnion.v.Type);
1226
1227       /* Add counter information to the mailbox header */
1228       proto_tree_add_uint(ecat_mailbox_header_tree, hf_ecat_mailboxcounter, tvb, offset, 1, hdr.aControlUnion.v.Counter);
1229       offset++;
1230
1231       if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN + hdr.Length )
1232       {
1233          next_tvb = tvb_new_subset_length (tvb, offset, hdr.Length);
1234          switch ( hdr.aControlUnion.v.Type )
1235          {
1236          case ETHERCAT_MBOX_TYPE_ADS:
1237             call_dissector(ams_handle, next_tvb, pinfo, ecat_mailbox_tree);
1238             break;
1239
1240          case ETHERCAT_MBOX_TYPE_EOE:
1241             dissect_ecat_eoe(next_tvb, 0, pinfo, ecat_mailbox_tree);
1242             break;
1243
1244          case ETHERCAT_MBOX_TYPE_COE:
1245             dissect_ecat_coe(next_tvb, 0, pinfo, ecat_mailbox_tree);
1246             break;
1247
1248          case ETHERCAT_MBOX_TYPE_FOE:
1249             dissect_ecat_foe(next_tvb, 0, pinfo, ecat_mailbox_tree);
1250             break;
1251
1252          case ETHERCAT_MBOX_TYPE_SOE:
1253             dissect_ecat_soe(next_tvb, 0, pinfo, ecat_mailbox_tree);
1254             break;
1255
1256          default:
1257             proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxdata, tvb, offset, hdr.Length, ENC_NA);
1258          }
1259       }
1260       else
1261       {
1262          anItem =proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxdata, tvb, offset, mailbox_length-ETHERCAT_MBOX_HEADER_LEN, ENC_NA);
1263          expert_add_info_format(pinfo, anItem, &ei_ecat_mailbox_error,"Incorrect Mailbox data length(Expected:%d Actual:%d)", hdr.Length, mailbox_length-ETHERCAT_MBOX_HEADER_LEN);
1264       }
1265       col_append_str(pinfo->cinfo, COL_INFO, ")");
1266    }
1267    return tvb_captured_length(tvb);
1268 }
1269
1270 void proto_register_ecat_mailbox(void)
1271 {
1272    static const true_false_string flags_set_truth =
1273    {
1274       "Set",
1275       "Not set"
1276    };
1277
1278    static hf_register_info hf[] =
1279    {
1280       { &hf_ecat_mailboxlength,
1281       { "Length", "ecat_mailbox.length",
1282       FT_UINT16, BASE_DEC, NULL, 0x0,
1283       NULL, HFILL }
1284       },
1285       { &hf_ecat_mailboxaddress,
1286       { "Address", "ecat_mailbox.address",
1287       FT_UINT16, BASE_HEX, NULL, 0x0,
1288       NULL, HFILL }
1289       },
1290       { &hf_ecat_mailboxpriority,
1291       { "Priority", "ecat_mailbox.priority",
1292       FT_UINT8, BASE_DEC, NULL, 0x03,
1293       NULL, HFILL }
1294       },
1295       { &hf_ecat_mailboxtype,
1296       { "Type", "ecat_mailbox.type",
1297       FT_UINT8, BASE_DEC, VALS(EcMBoxType), 0x0,
1298       NULL, HFILL }
1299       },
1300       { &hf_ecat_mailboxcounter,
1301       { "Counter", "ecat_mailbox.counter",
1302       FT_UINT8, BASE_DEC, NULL, 0x0,
1303       NULL, HFILL }
1304       },
1305       { &hf_ecat_mailbox_eoe,
1306       { "EoE Fragment", "ecat_mailbox.eoe",
1307       FT_BYTES, BASE_NONE, NULL, 0x0,
1308       NULL, HFILL }
1309       },
1310       { &hf_ecat_mailbox_eoe_fraghead,
1311       { "Header", "ecat_mailbox.eoe.fraghead",
1312       FT_BYTES, BASE_NONE, NULL, 0x0,
1313       NULL, HFILL }
1314       },
1315       { &hf_ecat_mailbox_eoe_type,
1316       { "Type", "ecat_mailbox.eoe.type",
1317       FT_UINT32, BASE_DEC, VALS(EoEType), 0x0, NULL, HFILL }
1318       },
1319       { &hf_ecat_mailbox_eoe_fragno,
1320       { "FragNo", "ecat_mailbox.eoe.fragno",
1321       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1322       },
1323       { &hf_ecat_mailbox_eoe_offset,
1324       { "Offset", "ecat_mailbox.eoe.offset",
1325       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
1326       },
1327       { &hf_ecat_mailbox_eoe_frame,
1328       { "FrameNo", "ecat_mailbox.eoe.frame",
1329       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1330       },
1331       { &hf_ecat_mailbox_eoe_last,
1332       { "Last Fragment", "ecat_mailbox.eoe.last",
1333       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1334       },
1335       { &hf_ecat_mailbox_eoe_timestampapp,
1336       { "Time Stamp Appended", "ecat_mailbox.eoe.timestampapp",
1337       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1338       },
1339       { &hf_ecat_mailbox_eoe_timestampreq,
1340       { "Time Stamp Requested", "ecat_mailbox.eoe.timestampreq",
1341       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1342       },
1343       { &hf_ecat_mailbox_eoe_fragment,
1344       { "EoE Frag Data", "ecat_mailbox.eoe.fragment",
1345       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1346       },
1347       { &hf_ecat_mailbox_eoe_init,
1348       { "Init", "ecat_mailbox.eoe.init",
1349       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1350       },
1351       { &hf_ecat_mailbox_eoe_init_contains_macaddr,
1352       { "MacAddr", "ecat_mailbox.eoe.init.contains_macaddr",
1353       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000001, NULL, HFILL }
1354       },
1355       { &hf_ecat_mailbox_eoe_init_contains_ipaddr,
1356       { "IpAddr", "ecat_mailbox.eoe.init.contains_ipaddr",
1357       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000002, NULL, HFILL }
1358       },
1359       { &hf_ecat_mailbox_eoe_init_contains_subnetmask,
1360       { "SubnetMask", "ecat_mailbox.eoe.init.contains_subnetmask",
1361       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000004, NULL, HFILL }
1362       },
1363       { &hf_ecat_mailbox_eoe_init_contains_defaultgateway,
1364       { "DefaultGateway", "ecat_mailbox.eoe.init.contains_defaultgateway",
1365       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000008, NULL, HFILL }
1366       },
1367       { &hf_ecat_mailbox_eoe_init_contains_dnsserver,
1368       { "DnsServer", "ecat_mailbox.eoe.init.contains_dnsserver",
1369       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000010, NULL, HFILL }
1370       },
1371       { &hf_ecat_mailbox_eoe_init_contains_dnsname,
1372       { "DnsName", "ecat_mailbox.eoe.init.contains_dnsname",
1373       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000020, NULL, HFILL }
1374       },
1375       { &hf_ecat_mailbox_eoe_init_append_timestamp,
1376       { "AppendTimeStamp", "ecat_mailbox.eoe.init.append_timestamp",
1377       FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00010000, NULL, HFILL }
1378       },
1379       { &hf_ecat_mailbox_eoe_init_macaddr,
1380       { "Mac Addr", "ecat_mailbox.eoe.init.macaddr",
1381       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1382       },
1383       { &hf_ecat_mailbox_eoe_init_ipaddr,
1384       { "Ip Addr", "ecat_mailbox.eoe.init.ipaddr",
1385       FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1386       },
1387       { &hf_ecat_mailbox_eoe_init_subnetmask,
1388       { "Subnet Mask", "ecat_mailbox.eoe.init.subnetmask",
1389       FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1390       },
1391       { &hf_ecat_mailbox_eoe_init_defaultgateway,
1392       { "Default Gateway", "ecat_mailbox.eoe.init.defaultgateway",
1393       FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1394       },
1395       { &hf_ecat_mailbox_eoe_init_dnsserver,
1396       { "Dns Server", "ecat_mailbox.eoe.init.dnsserver",
1397       FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1398       },
1399       { &hf_ecat_mailbox_eoe_init_dnsname,
1400       { "Dns Name", "ecat_mailbox.eoe.init.dnsname",
1401       FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
1402       },
1403       { &hf_ecat_mailbox_eoe_macfilter,
1404       { "Mac Filter", "ecat_mailbox.eoe.macfilter",
1405       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1406       },
1407
1408       /* XXX: The following 3 fields may not be specified correctly */
1409       /*      See related comment above                             */
1410       { &hf_ecat_mailbox_eoe_macfilter_macfiltercount,
1411       { "Mac Filter Count", "ecat_mailbox.eoe.macfilter.macfiltercount",
1412         FT_UINT16, BASE_DEC, NULL, 0xF000, NULL, HFILL }
1413       },
1414       { &hf_ecat_mailbox_eoe_macfilter_maskcount,
1415       { "Mac Filter Mask Count", "ecat_mailbox.eoe.macfilter.maskcount",
1416         FT_UINT16, BASE_DEC, NULL, 0x0C00, NULL, HFILL }
1417       },
1418       { &hf_ecat_mailbox_eoe_macfilter_nobroadcasts,
1419       { "No Broadcasts", "ecat_mailbox.eoe.macfilter.nobroadcasts",
1420       FT_BOOLEAN, 16,  TFS(&flags_set_truth), 0x0100, NULL, HFILL }
1421       },
1422       /* ... */
1423
1424       { &hf_ecat_mailbox_eoe_macfilter_filter,
1425       { "Filter", "ecat_mailbox.eoe.macfilter.filter",
1426       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1427       },
1428       { &hf_ecat_mailbox_eoe_macfilter_filters[0],
1429       { "Filter 0", "ecat_mailbox.eoe.macfilter.filter0",
1430       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1431       },
1432       { &hf_ecat_mailbox_eoe_macfilter_filters[1],
1433       { "Filter 1", "ecat_mailbox.eoe.macfilter.filter1",
1434       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1435       },
1436       { &hf_ecat_mailbox_eoe_macfilter_filters[2],
1437       { "Filter 2", "ecat_mailbox.eoe.macfilter.filter2",
1438       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1439       },
1440       { &hf_ecat_mailbox_eoe_macfilter_filters[3],
1441       { "Filter 3", "ecat_mailbox.eoe.macfilter.filter3",
1442       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1443       },
1444       { &hf_ecat_mailbox_eoe_macfilter_filters[4],
1445       { "Filter 4", "ecat_mailbox.eoe.macfilter.filter4",
1446       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1447       },
1448       { &hf_ecat_mailbox_eoe_macfilter_filters[5],
1449       { "Filter 5", "ecat_mailbox.eoe.macfilter.filter5",
1450       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1451       },
1452       { &hf_ecat_mailbox_eoe_macfilter_filters[6],
1453       { "Filter 6", "ecat_mailbox.eoe.macfilter.filter6",
1454       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1455       },
1456       { &hf_ecat_mailbox_eoe_macfilter_filters[7],
1457       { "Filter 7", "ecat_mailbox.eoe.macfilter.filter7",
1458       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1459       },
1460       { &hf_ecat_mailbox_eoe_macfilter_filters[8],
1461       { "Filter 8", "ecat_mailbox.eoe.macfilter.filter8",
1462       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1463       },
1464       { &hf_ecat_mailbox_eoe_macfilter_filters[9],
1465       { "Filter 9", "ecat_mailbox.eoe.macfilter.filter9",
1466       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1467       },
1468       { &hf_ecat_mailbox_eoe_macfilter_filters[10],
1469       { "Filter 10", "ecat_mailbox.eoe.macfilter.filter10",
1470       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1471       },
1472       { &hf_ecat_mailbox_eoe_macfilter_filters[11],
1473       { "Filter 11", "ecat_mailbox.eoe.macfilter.filter11",
1474       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1475       },
1476       { &hf_ecat_mailbox_eoe_macfilter_filters[12],
1477       { "Filter 12", "ecat_mailbox.eoe.macfilter.filter12",
1478       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1479       },
1480       { &hf_ecat_mailbox_eoe_macfilter_filters[13],
1481       { "Filter 13", "ecat_mailbox.eoe.macfilter.filter13",
1482       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1483       },
1484       { &hf_ecat_mailbox_eoe_macfilter_filters[14],
1485       { "Filter 14", "ecat_mailbox.eoe.macfilter.filter14",
1486       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1487       },
1488       { &hf_ecat_mailbox_eoe_macfilter_filters[15],
1489       { "Filter 15", "ecat_mailbox.eoe.macfilter.filter15",
1490       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1491       },
1492       { &hf_ecat_mailbox_eoe_macfilter_filtermask,
1493       { "Filter Mask", "ecat_mailbox.eoe.macfilter.filtermask",
1494       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1495       },
1496       { &hf_ecat_mailbox_eoe_macfilter_filtermasks[0],
1497       { "Mask 0", "ecat_mailbox.eoe.macfilter.filtermask0",
1498       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1499       },
1500       { &hf_ecat_mailbox_eoe_macfilter_filtermasks[1],
1501       { "Mask 1", "ecat_mailbox.eoe.macfilter.filtermask1",
1502       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1503       },
1504       { &hf_ecat_mailbox_eoe_macfilter_filtermasks[2],
1505       { "Mask 2", "ecat_mailbox.eoe.macfilter.filtermask2",
1506       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1507       },
1508       { &hf_ecat_mailbox_eoe_macfilter_filtermasks[3],
1509       { "Mask 3", "ecat_mailbox.eoe.macfilter.filtermask3",
1510       FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
1511       },
1512       { &hf_ecat_mailbox_eoe_timestamp,
1513       { "Time Stamp", "ecat_mailbox.eoe.timestamp",
1514       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1515       },
1516       { &hf_ecat_mailbox_coe,
1517       { "CoE", "ecat_mailbox.coe",
1518       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1519       },
1520       { &hf_ecat_mailbox_coe_number,
1521       { "Number", "ecat_mailbox.coe.number",
1522       FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1523       },
1524       { &hf_ecat_mailbox_coe_type,
1525       { "Type", "ecat_mailbox.coe.type",
1526       FT_UINT16, BASE_DEC, VALS(CANopenType), 0x0, NULL, HFILL }
1527       },
1528       { &hf_ecat_mailbox_coe_sdoreq,
1529       { "SDO Req", "ecat_mailbox.coe.sdoreq",
1530       FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1531       },
1532       { &hf_ecat_mailbox_coe_sdoccsid,
1533       { "Initiate Download", "ecat_mailbox.coe.sdoccsid",
1534       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1535       },
1536       { &hf_ecat_mailbox_coe_sdoccsid_sizeind,
1537       { "Size Ind.", "ecat_mailbox.coe.sdoccsid.sizeind",
1538       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001,
1539       NULL, HFILL }
1540       },
1541       { &hf_ecat_mailbox_coe_sdoccsid_expedited,
1542       { "Expedited", "ecat_mailbox.coe.sdoccsid.expedited",
1543       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000002,
1544       NULL, HFILL }
1545       },
1546       { &hf_ecat_mailbox_coe_sdoccsid_size0,
1547       { "Bytes", "ecat_mailbox.coe.sdoccsid.size0",
1548       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000004,
1549       NULL, HFILL }
1550       },
1551       { &hf_ecat_mailbox_coe_sdoccsid_size1,
1552       { "Bytes", "ecat_mailbox.coe.sdoccsid.size1",
1553       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000008,
1554       NULL, HFILL }
1555       },
1556       { &hf_ecat_mailbox_coe_sdoccsid_complete,
1557       { "Access", "ecat_mailbox.coe.sdoccsid.complete",
1558       FT_BOOLEAN, 8, TFS(&tfs_complete), 0x00000010,
1559       NULL, HFILL }
1560       },
1561       { &hf_ecat_mailbox_coe_sdoccsds,
1562       { "Download Segment", "ecat_mailbox.coe.sdoccsds",
1563       FT_UINT8, BASE_HEX, NULL, 0x0,
1564       NULL, HFILL }
1565       },
1566       { &hf_ecat_mailbox_coe_sdoccsds_lastseg,
1567       { "Last Segment", "ecat_mailbox.coe.sdoccsds.lastseg",
1568       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001,
1569       NULL, HFILL }
1570       },
1571       { &hf_ecat_mailbox_coe_sdoccsds_size,
1572       { "Size", "ecat_mailbox.coe.sdoccsds.size",
1573       FT_UINT8, BASE_DEC, NULL, 0x0000000E,
1574       NULL, HFILL }
1575       },
1576       { &hf_ecat_mailbox_coe_sdoccsds_toggle,
1577       { "Toggle Bit", "ecat_mailbox.coe.sdoccsds.toggle",
1578       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010,
1579       NULL, HFILL }
1580       },
1581       { &hf_ecat_mailbox_coe_sdoccsiu,
1582       { "Init Upload", "ecat_mailbox.coe.sdoccsiu",
1583       FT_UINT8, BASE_HEX, NULL, 0x0,
1584       NULL, HFILL }
1585       },
1586 #if 0
1587       { &hf_ecat_mailbox_coe_sdoccsiu_complete,
1588       { "Toggle Bit", "ecat_mailbox.coe.sdoccsiu_complete",
1589       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010,
1590       NULL, HFILL }
1591       },
1592 #endif
1593       { &hf_ecat_mailbox_coe_sdoccsus,
1594       { "Upload Segment", "ecat_mailbox.coe.sdoccsus",
1595       FT_UINT8, BASE_HEX, NULL, 0x0,
1596       NULL, HFILL }
1597       },
1598       { &hf_ecat_mailbox_coe_sdoccsus_toggle,
1599       { "Toggle Bit", "ecat_mailbox.coe.sdoccsus_toggle",
1600       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010,
1601       NULL, HFILL }
1602       },
1603
1604       { &hf_ecat_mailbox_coe_sdoidx,
1605       { "Index", "ecat_mailbox.coe.sdoidx",
1606       FT_UINT16, BASE_HEX, NULL, 0x0,
1607       NULL, HFILL }
1608       },
1609       { &hf_ecat_mailbox_coe_sdosub,
1610       { "SubIndex", "ecat_mailbox.coe.sdosub",
1611       FT_UINT8, BASE_HEX, NULL, 0x0,
1612       NULL, HFILL }
1613       },
1614       { &hf_ecat_mailbox_coe_sdodata,
1615       { "Data", "ecat_mailbox.coe.sdodata",
1616       FT_UINT32, BASE_HEX, NULL, 0x0,
1617       NULL, HFILL }
1618       },
1619       { &hf_ecat_mailbox_coe_sdodata1,
1620       { "Data", "ecat_mailbox.coe.sdodata",
1621       FT_UINT8, BASE_HEX, NULL, 0x0,
1622       NULL, HFILL }
1623       },
1624       { &hf_ecat_mailbox_coe_sdodata2,
1625       { "Data", "ecat_mailbox.coe.sdodata",
1626       FT_UINT16, BASE_HEX, NULL, 0x0,
1627       NULL, HFILL }
1628       },
1629       { &hf_ecat_mailbox_coe_sdoldata,
1630       { "Data", "ecat_mailbox.coe.dsoldata",
1631       FT_BYTES, BASE_NONE, NULL, 0x0,
1632       NULL, HFILL }
1633       },
1634       { &hf_ecat_mailbox_coe_sdolength,
1635       { "Length", "ecat_mailbox.coe.sdolength",
1636       FT_UINT32, BASE_HEX, NULL, 0x0,
1637       NULL, HFILL }
1638       },
1639 #if 0
1640       { &hf_ecat_mailbox_coe_sdoerror,
1641       { "SDO Error", "ecat_mailbox.coe.sdoerror",
1642       FT_UINT32, BASE_HEX, NULL, 0x0,
1643       NULL, HFILL }
1644       },
1645 #endif
1646       { &hf_ecat_mailbox_coe_sdores,
1647       { "SDO Res", "ecat_mailbox.coe.sdores",
1648       FT_UINT8, BASE_DEC, NULL, 0x0,
1649       NULL, HFILL }
1650       },
1651       { &hf_ecat_mailbox_coe_sdoscsiu,
1652       { "Initiate Upload Response", "ecat_mailbox.coe.sdoscsiu",
1653       FT_UINT8, BASE_HEX, NULL, 0x0,
1654       NULL, HFILL }
1655       },
1656       { &hf_ecat_mailbox_coe_sdoscsiu_sizeind,
1657       { "Size Ind.", "ecat_mailbox.coe.sdoscsiu_sizeind",
1658       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001,
1659       NULL, HFILL }
1660       },
1661       { &hf_ecat_mailbox_coe_sdoscsiu_expedited,
1662       { "Expedited", "ecat_mailbox.coe.sdoscsiu_expedited",
1663       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000002,
1664       NULL, HFILL }
1665       },
1666       { &hf_ecat_mailbox_coe_sdoscsiu_size0,
1667       { "Bytes", "ecat_mailbox.coe.sdoscsiu_size0",
1668       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000004,
1669       NULL, HFILL }
1670       },
1671       { &hf_ecat_mailbox_coe_sdoscsiu_size1,
1672       { "Bytes", "ecat_mailbox.coe.sdoscsiu_size1",
1673       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000008,
1674       NULL, HFILL }
1675       },
1676       { &hf_ecat_mailbox_coe_sdoscsiu_complete,
1677       { "Access", "ecat_mailbox.coe.sdoscsiu_complete",
1678       FT_BOOLEAN, 8, TFS(&tfs_complete), 0x00000010,
1679       NULL, HFILL }
1680       },
1681       { &hf_ecat_mailbox_coe_sdoscsds,
1682       { "Download Segment Response", "ecat_mailbox.coe.sdoscsds",
1683       FT_UINT8, BASE_HEX, NULL, 0x0,
1684       NULL, HFILL }
1685       },
1686       { &hf_ecat_mailbox_coe_sdoscsds_toggle,
1687       { "Toggle Bit", "ecat_mailbox.coe.sdoscsds_toggle",
1688       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010,
1689       NULL, HFILL }
1690       },
1691       { &hf_ecat_mailbox_coe_sdoscsus,
1692       { "Upload Segment", "ecat_mailbox.coe.sdoscsus",
1693       FT_UINT8, BASE_HEX, NULL, 0x0,
1694       NULL, HFILL }
1695       },
1696       { &hf_ecat_mailbox_coe_sdoscsus_lastseg,
1697       { "Last Segment", "ecat_mailbox.coe.sdoscsus_lastseg",
1698       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001,
1699       NULL, HFILL }
1700       },
1701       { &hf_ecat_mailbox_coe_sdoscsus_bytes,
1702       { "Bytes", "ecat_mailbox.coe.sdoscsus_bytes",
1703       FT_UINT8, BASE_DEC, NULL, 0x0000000E,
1704       NULL, HFILL }
1705       },
1706       { &hf_ecat_mailbox_coe_sdoscsus_toggle,
1707       { "Toggle Bit", "ecat_mailbox.coe.sdoscsus_toggle",
1708       FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010,
1709       NULL, HFILL }
1710       },
1711       { &hf_ecat_mailbox_coe_sdoinfoopcode,
1712       { "Info OpCode", "ecat_mailbox.coe.sdoinfoopcode",
1713       FT_UINT8, BASE_DEC, VALS(CANopenSdoInfo), 0x0,
1714       NULL, HFILL },
1715       },
1716       { &hf_ecat_mailbox_coe_sdoinfofrag,
1717       { "Info Frag Left", "ecat_mailbox.coe.sdoinfofrag",
1718       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1719       },
1720       { &hf_ecat_mailbox_coe_sdoinfolisttype,
1721       { "Info List Type", "ecat_mailbox.coe.sdoinfolisttype",
1722       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1723       },
1724       { &hf_ecat_mailbox_coe_sdoinfolist,
1725       { "Info List", "ecat_mailbox.coe.sdoinfolist",
1726       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1727       },
1728       { &hf_ecat_mailbox_coe_sdoinfoindex,
1729       { "Info Obj Index", "ecat_mailbox.coe.sdoinfoindex",
1730       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1731       },
1732       { &hf_ecat_mailbox_coe_sdoinfosubindex,
1733       { "Info Obj SubIdx", "ecat_mailbox.coe.sdoinfosubindex",
1734       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
1735       },
1736       { &hf_ecat_mailbox_coe_sdoinfovalueinfo,
1737       { "Info Obj ValueInfo", "ecat_mailbox.coe.sdoinfovalueinfo",
1738       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
1739       },
1740       { &hf_ecat_mailbox_coe_sdoinfoerrorcode,
1741       { "Info Error Code", "ecat_mailbox.coe.sdoinfoerrorcode",
1742       FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
1743       },
1744       { &hf_ecat_mailbox_coe_sdoinfodatatype,
1745       { "Info Data Type", "ecat_mailbox.coe.sdoinfodatatype",
1746       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1747       },
1748       { &hf_ecat_mailbox_coe_sdoinfomaxsub,
1749       { "Info Max SubIdx", "ecat_mailbox.coe.sdoinfomaxsub",
1750       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
1751       },
1752       { &hf_ecat_mailbox_coe_sdoinfoobjcode,
1753       { "Info Obj Code", "ecat_mailbox.coe.sdoinfoobjcode",
1754       FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL },
1755       },
1756       { &hf_ecat_mailbox_coe_sdoinfoname,
1757       { "Info Name", "ecat_mailbox.coe.sdoinfoname",
1758       FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
1759       },
1760       { &hf_ecat_mailbox_coe_sdoinfobitlen,
1761       { "Info Bit Len", "ecat_mailbox.coe.sdoinfobitlen",
1762       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1763       },
1764       { &hf_ecat_mailbox_coe_sdoinfoobjaccess,
1765       { "Info Obj Access", "ecat_mailbox.coe.sdoinfoobjaccess",
1766       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1767       },
1768       { &hf_ecat_mailbox_coe_sdoinfounittype,
1769       { "Info Data Type", "ecat_mailbox.coe.sdoinfounittype",
1770       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL },
1771       },
1772       { &hf_ecat_mailbox_coe_sdoinfodefaultvalue,
1773       { "Info Default Val", "ecat_mailbox.coe.sdoinfodefaultvalue",
1774       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1775       },
1776       { &hf_ecat_mailbox_coe_sdoinfominvalue,
1777       { "Info Min Val", "ecat_mailbox.coe.sdoinfominvalue",
1778       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1779       },
1780       { &hf_ecat_mailbox_coe_sdoinfomaxvalue,
1781       { "Info Max Val", "ecat_mailbox.coe.sdoinfomaxvalue",
1782       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1783       },
1784       { &hf_ecat_mailboxdata,
1785       { "MB Data", "ecat_mailbox.data",
1786       FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1787       },
1788       { &hf_ecat_mailbox_foe,
1789       { "Foe", "ecat_mailbox.foe",
1790       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1791       },
1792       { &hf_ecat_mailbox_foe_opmode,
1793       { "Foe OpMode", "ecat_mailbox.foe_opmode",
1794       FT_UINT8, BASE_HEX, VALS(FoEOpMode), 0x0, "Op modes", HFILL }
1795       },
1796       { &hf_ecat_mailbox_foe_filelength,
1797       { "Foe FileLength" , "ecat_mailbox.foe_filelength",
1798       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1799       },
1800       { &hf_ecat_mailbox_foe_filename,
1801       { "Foe FileName", "ecat_mailbox.foe_filename",
1802       FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
1803       },
1804       { &hf_ecat_mailbox_foe_packetno,
1805       { "Foe PacketNo", "ecat_mailbox.foe_packetno",
1806       FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1807       },
1808       { &hf_ecat_mailbox_foe_errcode,
1809       { "Foe ErrorCode", "ecat_mailbox.foe_errcode",
1810       FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1811       },
1812       { &hf_ecat_mailbox_foe_errtext,
1813       { "Foe ErrorString", "ecat_mailbox.foe_errtext",
1814       FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
1815       },
1816       { &hf_ecat_mailbox_foe_busydone,
1817       { "Foe BusyDone", "ecat_mailbox.foe_busydone",
1818       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1819       },
1820       { &hf_ecat_mailbox_foe_busyentire,
1821       { "Foe BusyEntire", "ecat_mailbox.foe_busyentire",
1822       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1823       },
1824       { &hf_ecat_mailbox_foe_data,
1825       { "Foe Data", "ecat_mailbox.foe_busydata",
1826       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1827       },
1828       { &hf_ecat_mailbox_foe_efw,
1829       { "Firmware", "ecat_mailbox.foe.efw",
1830       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1831       },
1832       { &hf_ecat_mailbox_foe_efw_cmd,
1833       { "Cmd", "ecat_mailbox.foe.efw.cmd",
1834       FT_UINT16, BASE_HEX, VALS(FoEEfwCmd), 0x0, NULL, HFILL }
1835       },
1836       { &hf_ecat_mailbox_foe_efw_size,
1837       { "Size", "ecat_mailbox.foe.efw.size",
1838       FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1839       },
1840       { &hf_ecat_mailbox_foe_efw_addresslw,
1841       { "AddressLW", "ecat_mailbox.foe.efw.addresslw",
1842       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1843       },
1844       { &hf_ecat_mailbox_foe_efw_addresshw,
1845       { "AddressHW", "ecat_mailbox.foe.efw.addresshw",
1846       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1847       },
1848       { &hf_ecat_mailbox_foe_efw_data,
1849       { "Data", "ecat_mailbox.foe.efw.data",
1850       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1851       },
1852       { &hf_ecat_mailbox_soe,
1853       { "Soe", "ecat_mailbox.soe",
1854       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1855       },
1856       { &hf_ecat_mailbox_soe_header,
1857       { "Soe Header", "ecat_mailbox.soe_header",
1858       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1859       },
1860       { &hf_ecat_mailbox_soe_header_opcode,
1861       { "SoE OpCode", "ecat_mailbox.soe_opcode",
1862       FT_UINT16, BASE_DEC, VALS(SoeOpcode), 0x00000007, NULL, HFILL }
1863       },
1864       { &hf_ecat_mailbox_soe_header_incomplete,
1865       { "More Follows...", "ecat_mailbox.soe_header_incomplete",
1866       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000008, NULL, HFILL }
1867       },
1868       { &hf_ecat_mailbox_soe_header_error,
1869       { "Error", "ecat_mailbox.soe_header_error",
1870       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000010,
1871       NULL, HFILL }
1872       },
1873       { &hf_ecat_mailbox_soe_header_driveno,
1874       { "Drive No", "ecat_mailbox.soe_header_driveno",
1875       FT_UINT16, BASE_DEC, NULL, 0x000000e0, NULL, HFILL }
1876       },
1877       { &hf_ecat_mailbox_soe_header_datastate,
1878       { "Datastate", "ecat_mailbox.soe_header_datastate",
1879       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000100,
1880       NULL, HFILL }
1881       },
1882       { &hf_ecat_mailbox_soe_header_name,
1883       { "Name", "ecat_mailbox.soe_header_name",
1884       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000200,
1885       NULL, HFILL }
1886       },
1887       { &hf_ecat_mailbox_soe_header_attribute,
1888       { "Attribute", "ecat_mailbox.soe_header_attribute",
1889       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000400,
1890       NULL, HFILL }
1891       },
1892       { &hf_ecat_mailbox_soe_header_unit,
1893       { "Unit", "ecat_mailbox.soe_header_unit",
1894       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000800,
1895       NULL, HFILL }
1896       },
1897       { &hf_ecat_mailbox_soe_header_min,
1898       { "Min", "ecat_mailbox.soe_header_min",
1899       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00001000,
1900       NULL, HFILL }
1901       },
1902       { &hf_ecat_mailbox_soe_header_max,
1903       { "Max", "ecat_mailbox.soe_header_max",
1904       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00002000,
1905       NULL, HFILL }
1906       },
1907       { &hf_ecat_mailbox_soe_header_value,
1908       { "Value", "ecat_mailbox.soe_header_value",
1909       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00004000,
1910       NULL, HFILL }
1911       },
1912       { &hf_ecat_mailbox_soe_header_reserved,
1913       { "Reserved", "ecat_mailbox.soe_header_reserved",
1914       FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00008000,
1915       NULL, HFILL }
1916       },
1917       { &hf_ecat_mailbox_soe_idn,
1918       { "SoE IDN", "ecat_mailbox.soe_idn",
1919       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1920       },
1921       { &hf_ecat_mailbox_soe_data,
1922       { "SoE Data", "ecat_mailbox.soe_data",
1923       FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
1924       },
1925       { &hf_ecat_mailbox_soe_frag,
1926       { "SoE FragLeft", "ecat_mailbox.soe_frag",
1927       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1928       },
1929       { &hf_ecat_mailbox_soe_error,
1930       { "SoE Error", "ecat_mailbox.soe_error",
1931       FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1932       }
1933    };
1934
1935    static gint *ett[] =
1936    {
1937       &ett_ecat_mailbox,
1938       &ett_ecat_mailbox_eoe,
1939       &ett_ecat_mailbox_eoe_init,
1940       &ett_ecat_mailbox_eoe_macfilter,
1941       &ett_ecat_mailbox_eoe_macfilter_filter,
1942       &ett_ecat_mailbox_eoe_macfilter_filtermask,
1943       &ett_ecat_mailbox_coe,
1944       &ett_ecat_mailbox_sdo,
1945       &ett_ecat_mailbox_coe_sdoccs,
1946       &ett_ecat_mailbox_coe_sdoscs,
1947       &ett_ecat_mailbox_foe,
1948       &ett_ecat_mailbox_foe_efw,
1949       &ett_ecat_mailbox_soeflag,
1950       &ett_ecat_mailbox_soe,
1951       &ett_ecat_mailbox_fraghead,
1952       &ett_ecat_mailbox_header
1953    };
1954
1955    static ei_register_info ei[] =
1956    {
1957       { &ei_ecat_mailbox_error, { "ecat_mailbox.invalid", PI_MALFORMED, PI_ERROR, "Malformed mailbox data", EXPFILL } },
1958       { &ei_ecat_mailbox_coe_error, { "ecat_mailbox.coe.invalid", PI_MALFORMED, PI_ERROR, "Malformed CoE data", EXPFILL } },
1959       { &ei_ecat_mailbox_foe_error, { "ecat_mailbox.foe.invalid", PI_MALFORMED, PI_ERROR, "Malformed FoE data", EXPFILL } },
1960       { &ei_ecat_mailbox_soe_error, { "ecat_mailbox.soe.invalid", PI_MALFORMED, PI_ERROR, "Malformed SoE data", EXPFILL } },
1961       { &ei_ecat_mailbox_eoe_error, { "ecat_mailbox.eoe.invalid", PI_MALFORMED, PI_ERROR, "Malformed EoE data", EXPFILL } },
1962    };
1963
1964    expert_module_t *expert_module;
1965
1966    proto_ecat_mailbox = proto_register_protocol("EtherCAT Mailbox Protocol",
1967       "ECAT_MAILBOX", "ecat_mailbox");
1968
1969    expert_module = expert_register_protocol(proto_ecat_mailbox);
1970    expert_register_field_array(expert_module, ei, array_length(ei));
1971
1972    proto_register_field_array(proto_ecat_mailbox, hf,array_length(hf));
1973    proto_register_subtree_array(ett, array_length(ett));
1974
1975    register_dissector("ecat_mailbox", dissect_ecat_mailbox, proto_ecat_mailbox);
1976 }
1977
1978 void proto_reg_handoff_ecat_mailbox(void)
1979 {
1980    dissector_handle_t ecat_mailbox_handle;
1981
1982    /* Register this dissector as a sub dissector to E88A4 based on ether type. */
1983    ecat_mailbox_handle = find_dissector("ecat_mailbox");
1984    dissector_add_uint("ecatf.type", 5, ecat_mailbox_handle);
1985
1986    eth_handle = find_dissector("eth_withoutfcs");
1987    ams_handle = find_dissector("ams");
1988 }
1989
1990 /*
1991  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1992  *
1993  * Local Variables:
1994  * c-basic-offset: 3
1995  * tab-width: 8
1996  * indent-tabs-mode: nil
1997  * End:
1998  *
1999  * ex: set shiftwidth=3 tabstop=8 expandtab:
2000  * :indentSize=3:tabSize=8:noTabs=true:
2001  */