nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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_add_dependency("eth_withoutfcs", proto_ecat_mailbox);
1987 ams_handle = find_dissector_add_dependency("ams", proto_ecat_mailbox);
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 */