diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /plugins/epan/ethercat | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/epan/ethercat')
-rw-r--r-- | plugins/epan/ethercat/AUTHORS | 5 | ||||
-rw-r--r-- | plugins/epan/ethercat/CMakeLists.txt | 70 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ams.c | 1245 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ams.h | 1153 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ecatmb.c | 1995 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ecatmb.h | 469 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-esl.c | 372 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ethercat-datagram.c | 3745 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ethercat-datagram.h | 36 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ethercat-frame.c | 153 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ethercat-frame.h | 33 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ioraw.c | 119 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-ioraw.h | 21 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-nv.c | 240 | ||||
-rw-r--r-- | plugins/epan/ethercat/packet-nv.h | 34 |
15 files changed, 9690 insertions, 0 deletions
diff --git a/plugins/epan/ethercat/AUTHORS b/plugins/epan/ethercat/AUTHORS new file mode 100644 index 00000000..8e9f8dae --- /dev/null +++ b/plugins/epan/ethercat/AUTHORS @@ -0,0 +1,5 @@ +Author : +Richard Kuemmel <r.kuemmel[AT]beckhoff.de> + +Updates and bugfixes: +Peter Johansson <peterjohansson73[AT]gmail.com> diff --git a/plugins/epan/ethercat/CMakeLists.txt b/plugins/epan/ethercat/CMakeLists.txt new file mode 100644 index 00000000..afa46e82 --- /dev/null +++ b/plugins/epan/ethercat/CMakeLists.txt @@ -0,0 +1,70 @@ +# CMakeLists.txt +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# SPDX-License-Identifier: GPL-2.0-or-later +# + +include(WiresharkPlugin) + +# Plugin name and version info (major minor micro extra) +set_module_info(ethercat 0 1 0 0) + +set(DISSECTOR_SRC + packet-ams.c + packet-ecatmb.c + packet-esl.c + packet-ethercat-datagram.c + packet-ethercat-frame.c + packet-ioraw.c + packet-nv.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set_source_files_properties( + ${PLUGIN_FILES} + PROPERTIES + COMPILE_FLAGS "${WERROR_COMMON_FLAGS}" +) + +register_plugin_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_wireshark_plugin_library(ethercat epan) + +target_link_libraries(ethercat epan) + +install_plugin(ethercat epan) + +file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") +CHECKAPI( + NAME + ethercat + SWITCHES + --group dissectors-prohibited + --group dissectors-restricted + SOURCES + ${DISSECTOR_SRC} + ${DISSECTOR_HEADERS} +) + +# +# Editor modelines - https://www.wireshark.org/tools/modelines.html +# +# Local variables: +# c-basic-offset: 8 +# tab-width: 8 +# indent-tabs-mode: t +# End: +# +# vi: set shiftwidth=8 tabstop=8 noexpandtab: +# :indentSize=8:tabSize=8:noTabs=false: +# diff --git a/plugins/epan/ethercat/packet-ams.c b/plugins/epan/ethercat/packet-ams.c new file mode 100644 index 00000000..b6246eb5 --- /dev/null +++ b/plugins/epan/ethercat/packet-ams.c @@ -0,0 +1,1245 @@ +/* packet-ams.c + * Routines for ethercat packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Include files */ + +#include "config.h" + +#include <epan/packet.h> + +#include "packet-ams.h" + +void proto_register_ams(void); +void proto_reg_handoff_ams(void); + +#define AMS_TCP_PORT 48898 /* Not IANA registered */ + +/* Define the ams proto */ +int proto_ams = -1; + +static dissector_handle_t amstcp_handle; + +/* Define the tree for ams */ +static int ett_ams = -1; +static int ett_ams_stateflags = -1; +static int ett_ams_adsreadrequest = -1; +static int ett_ams_adsreadresponse = -1; +static int ett_ams_adswriterequest = -1; +static int ett_ams_adswriteresponse = -1; +static int ett_ams_adsreadwriterequest = -1; +static int ett_ams_adsreadwriteresponse = -1; +static int ett_ams_adsreadstaterequest = -1; +static int ett_ams_adsreadstateresponse = -1; +static int ett_ams_adswritectrlrequest = -1; +static int ett_ams_adswritectrlresponse = -1; +static int ett_ams_adsreaddinforequest = -1; +static int ett_ams_adsreaddinforesponse = -1; +static int ett_ams_adsadddnrequest = -1; +static int ett_ams_adsadddnresponse = -1; +static int ett_ams_adsdeldnrequest = -1; +static int ett_ams_adsdeldnresponse = -1; +static int ett_ams_adsdnrequest = -1; + +static int hf_ams_sendernetid = -1; +static int hf_ams_senderport = -1; +static int hf_ams_targetnetid = -1; +static int hf_ams_targetport = -1; +static int hf_ams_cmdid = -1; +static int hf_ams_stateflags = -1; +static int hf_ams_stateresponse = -1; +static int hf_ams_statenoreturn = -1; +static int hf_ams_stateadscmd = -1; +static int hf_ams_statesyscmd = -1; +static int hf_ams_statehighprio = -1; +static int hf_ams_statetimestampadded = -1; +static int hf_ams_stateudp = -1; +static int hf_ams_stateinitcmd = -1; +static int hf_ams_statebroadcast = -1; +static int hf_ams_cbdata = -1; +static int hf_ams_errorcode = -1; +static int hf_ams_invokeid = -1; +static int hf_ams_data = -1; + +/*ads Commands */ +static int hf_ams_adsindexgroup = -1; +static int hf_ams_adsindexoffset = -1; +static int hf_ams_adscblength = -1; +static int hf_ams_adsreadrequest = -1; +static int hf_ams_adsreadresponse = -1; +static int hf_ams_adsinvokeid = -1; +static int hf_ams_adsresult = -1; +static int hf_ams_adsdata = -1; +static int hf_ams_adswriterequest = -1; +static int hf_ams_adswriteresponse = -1; +static int hf_ams_adsreadwriterequest = -1; +static int hf_ams_adsreadwriteresponse = -1; +static int hf_ams_adscbreadlength = -1; +static int hf_ams_adscbwritelength = -1; +static int hf_ams_adsstate = -1; +static int hf_ams_adsdevicestate = -1; +static int hf_ams_adsnotificationhandle = -1; +static int hf_ams_adsreadstaterequest = -1; +static int hf_ams_adsreadstateresponse = -1; +static int hf_ams_adswritectrlrequest = -1; +static int hf_ams_adswritectrlresponse = -1; +static int hf_ams_adsreaddinforequest = -1; +static int hf_ams_adsreaddinforesponse = -1; +static int hf_ams_adsadddnrequest = -1; +static int hf_ams_adsadddnresponse = -1; +static int hf_ams_adsdeldnrequest = -1; +static int hf_ams_adsdeldnresponse = -1; +static int hf_ams_adsdnrequest = -1; +/* static int hf_ams_adsdnresponse = -1; */ +/* static int hf_ams_adsnoteattrib = -1; */ +/* static int hf_ams_adsnoteblocks = -1; */ +/* static int hf_ams_adsversion = -1; */ +static int hf_ams_adsdevicename = -1; +static int hf_ams_adsversionversion = -1; +static int hf_ams_adsversionrevision = -1; +static int hf_ams_adsversionbuild = -1; +static int hf_ams_adsnoteblocksstamps = -1; +/* static int hf_ams_adsnoteblocksstamp = -1; */ +/* static int hf_ams_adstimestamp = -1; */ +/* static int hf_ams_adssamplecnt = -1; */ +/* static int hf_ams_adsnoteblockssample = -1; */ +static int hf_ams_adstransmode = -1; +static int hf_ams_adsmaxdelay = -1; +static int hf_ams_adscycletime = -1; +/* static int hf_ams_adscmpmax = -1; */ +/* static int hf_ams_adscmpmin = -1; */ + +static dissector_handle_t ams_handle; + +static const value_string TransMode[] = +{ + { 0, "NO TRANS"}, + { 1, "CLIENT CYCLE"}, + { 2, "CLIENT ON CHANGE"}, + { 3, "SERVER CYCLE"}, + { 4, "SERVER ON CHANGE"}, + { 10, "CLIENT FIRST REQUEST"}, + { 0, NULL } +}; + +static const value_string ErrorCode[] = +{ + { ERR_NOERROR, "NO ERROR"}, + { ERR_INTERNAL, "INTERNAL"}, + { ERR_NORTIME, "NO RTIME"}, + { ERR_ALLOCLOCKEDMEM, "ALLOC LOCKED MEM"}, + { ERR_INSERTMAILBOX, "INSERT MAILBOX"}, + { ERR_WRONGRECEIVEHMSG, "WRONGRECEIVEHMSG"}, + { ERR_TARGETPORTNOTFOUND, "TARGET PORT NOT FOUND"}, + { ERR_TARGETMACHINENOTFOUND, "TARGET MACHINE NOT FOUND"}, + { ERR_UNKNOWNCMDID, "UNKNOWN CMDID"}, + { ERR_BADTASKID, "BAD TASKID"}, + { ERR_NOIO, "NOIO"}, + { ERR_UNKNOWNAMSCMD, "UNKNOWN AMSCMD"}, + { ERR_WIN32ERROR, "WIN32 ERROR"}, + { ERR_PORTNOTCONNECTED, "PORT NOT CONNECTED"}, + { ERR_INVALIDAMSLENGTH, "INVALID AMS LENGTH"}, + { ERR_INVALIDAMSNETID, "INVALID AMS NETID"}, + { ERR_LOWINSTLEVEL, "LOW INST LEVEL"}, + { ERR_NODEBUGINTAVAILABLE, "NO DEBUG INT AVAILABLE"}, + { ERR_PORTDISABLED, "PORT DISABLED"}, + { ERR_PORTALREADYCONNECTED, "PORT ALREADY CONNECTED"}, + { ERR_AMSSYNC_W32ERROR, "AMSSYNC_W32ERROR"}, + { ERR_AMSSYNC_TIMEOUT, "AMSSYNC_TIMEOUT"}, + { ERR_AMSSYNC_AMSERROR, "AMSSYNC_AMSERROR"}, + { ERR_AMSSYNC_NOINDEXINMAP, "AMSSYNC_NOINDEXINMAP"}, + { ERR_INVALIDAMSPORT, "INVALID AMSPORT"}, + { ERR_NOMEMORY, "NO MEMORY"}, + { ERR_TCPSEND, "TCP SEND"}, + { ERR_HOSTUNREACHABLE, "HOST UNREACHABLE"}, + { ROUTERERR_NOLOCKEDMEMORY, "ROUTERERR_NOLOCKEDMEMORY"}, + { ROUTERERR_RESIZEMEMORY, "ROUTERERR_RESIZEMEMORY"}, + { ROUTERERR_MAILBOXFULL, "ROUTERERR_MAILBOXFULL"}, + { ROUTERERR_DEBUGBOXFULL, "ROUTERERR_DEBUGBOXFULL"}, + { ROUTERERR_UNKNOWNPORTTYPE, "ROUTERERR_UNKNOWNPORTTYPE"}, + { ROUTERERR_NOTINITIALIZED, "ROUTERERR_NOTINITIALIZED"}, + { ROUTERERR_PORTALREADYINUSE, "ROUTERERR_PORTALREADYINUSE"}, + { ROUTERERR_NOTREGISTERED, "ROUTERERR_NOTREGISTERED "}, + { ROUTERERR_NOMOREQUEUES, "ROUTERERR_NOMOREQUEUES"}, + { ROUTERERR_INVALIDPORT, "ROUTERERR_INVALIDPORT"}, + { ROUTERERR_NOTACTIVATED, "ROUTERERR_NOTACTIVATED"}, + { IOERR_INTERNAL, "IOERR_INTERNAL"}, + { IOERR_BADCARDNO, "IOERR_BADCARDNO"}, + { IOERR_INVALIDCARDADDR, "IOERR_INVALIDCARDADDR"}, + { IOERR_CDLLISTFULL, "IOERR_CDLLISTFULL"}, + { IOERR_BADCDLPARAM, "IOERR_BADCDLPARAM"}, + { IOERR_OPENIOFAILED, "IOERR_OPENIOFAILED"}, + { IOERR_RESETIOFAILED, "IOERR_RESETIOFAILED"}, + { IOERR_UNKNOWNDEVICE, "IOERR_UNKNOWNDEVICE"}, + { IOERR_UNKNOWNDEVICEID, "IOERR_UNKNOWNDEVICEID"}, + { IOERR_UNKNOWNIMAGEID, "IOERR_UNKNOWNIMAGEID"}, + { IOERR_GETIOSTATE, "IOERR_GETIOSTATE"}, + { IOERR_BADIMAGEID, "IOERR_BADIMAGEID"}, + { IOERR_NOMORECLIENTSPACE, "IOERR_NOMORECLIENTSPACE"}, + { IOERR_CLIENTINFONOTFOUND, "IOERR_CLIENTINFONOTFOUND"}, + { IOERR_CDLNOTINUSE, "IOERR_CDLNOTINUSE"}, + { IOERR_TIMEOUTWITHDEVICE, "IOERR_TIMEOUTWITHDEVICE"}, + { IOERR_C1220FUNC_1, "IOERR_C1220FUNC_1"}, + { IOERR_C1220FUNC_9, "IOERR_C1220FUNC_9"}, + { IOERR_C1220FUNC_C, "IOERR_C1220FUNC_C"}, + { IOERR_C1220FUNC_10, "IOERR_C1220FUNC_10"}, + { IOERR_C1220FUNC_1_MAXSEND, "IOERR_C1220FUNC_1_MAXSEND"}, + { IOERR_C1220FUNC_1_ADDRSET, "IOERR_C1220FUNC_1_ADDRSET"}, + { IOERR_C1220FUNC_1_BREAK, "IOERR_C1220FUNC_1_BREAK"}, + { IOERR_C1220FUNC_1_BREAK0, "IOERR_C1220FUNC_1_BREAK0"}, + { IOERR_C1220FUNC_1_BREAK1, "IOERR_C1220FUNC_1_BREAK1"}, + { IOERR_C1220FUNC_1_BREAK2, "IOERR_C1220FUNC_1_BREAK2"}, + { IOERR_C1220FUNC_1_BREAK3, "IOERR_C1220FUNC_1_BREAK3"}, + { IOERR_C1220FUNC_1_BREAK4, "IOERR_C1220FUNC_1_BREAK4"}, + { IOERR_C1220FUNC_1_BREAK5, "IOERR_C1220FUNC_1_BREAK5"}, + { IOERR_C1220FUNC_1_BREAK6, "IOERR_C1220FUNC_1_BREAK6"}, + { IOERR_C1220FUNC_1_BREAK7, "IOERR_C1220FUNC_1_BREAK7"}, + { IOERR_C1220FUNC_1_BREAK8, "IOERR_C1220FUNC_1_BREAK8"}, + { IOERR_C1220FUNC_1_BREAK9, "IOERR_C1220FUNC_1_BREAK9"}, + { IOERR_C1220FUNC_1_BREAK10, "IOERR_C1220FUNC_1_BREAK10"}, + { IOERR_C1220FUNC_1_BREAK11, "IOERR_C1220FUNC_1_BREAK11"}, + { IOERR_C1220FUNC_1_BREAK12, "IOERR_C1220FUNC_1_BREAK12"}, + { IOERR_C1220FUNC_1_BREAK13, "IOERR_C1220FUNC_1_BREAK13"}, + { IOERR_C1220FUNC_1_BREAK14, "IOERR_C1220FUNC_1_BREAK14"}, + { IOERR_C1220FUNC_1_BREAK15, "IOERR_C1220FUNC_1_BREAK15"}, + { IOERR_C1220FUNC_1_BREAK16, "IOERR_C1220FUNC_1_BREAK16"}, + { IOERR_SPC3DEVINITDP, "IOERR_SPC3DEVINITDP"}, + { IOERR_SPC3UPDATEOUTPUT, "IOERR_SPC3UPDATEOUTPUT"}, + { IOERR_CIF30READDIAG, "IOERR_CIF30READDIAG"}, + { IOERR_CIF30COMMNOTSTARTED, "IOERR_CIF30COMMNOTSTARTED"}, + { IOERR_CIF30SLAVEPARASIZE, "IOERR_CIF30SLAVEPARASIZE"}, + { IOERR_CIF30NOPARAS, "IOERR_CIF30NOPARAS"}, + { IOERR_CIF30SLAVEERROR, "IOERR_CIF30SLAVEERROR"}, + { IOERR_CIF30WATCHDOGEXPIRED, "IOERR_CIF30WATCHDOGEXPIRED"}, + { IOERR_UNKNOWNDEVICECMD, "IOERR_UNKNOWNDEVICECMD"}, + { IOERR_CIF40MESSAGEHANDLING, "IOERR_CIF40MESSAGEHANDLING"}, + { IOERR_CIF40PARAERROR, "IOERR_CIF40PARAERROR"}, + { IOERR_CIF40WATCHDOGEXPIRED, "IOERR_CIF40WATCHDOGEXPIRED"}, + { IOERR_CIF40FLAGERROR, "IOERR_CIF40FLAGERROR"}, + { IOERR_CIF40COMMNOTSTARTED, "IOERR_CIF40COMMNOTSTARTED"}, + { IOERR_CIF40READDIAG, "IOERR_CIF40READDIAG"}, + { IOERR_CIF40SLAVEERROR, "IOERR_CIF40SLAVEERROR"}, + { IOERR_CIF40GLOBALERROR, "IOERR_CIF40GLOBALERROR"}, + { IOERR_CIF40CONFIGLIST, "IOERR_CIF40CONFIGLIST"}, + { IOERR_CP5412A2SLAVEPARASIZE, "IOERR_CP5412A2SLAVEPARASIZE"}, + { IOERR_CP5412A2NOPARAS, "IOERR_CP5412A2NOPARAS"}, + { IOERR_CP5412A2SLAVEERROR, "IOERR_CP5412A2SLAVEERROR"}, + { IOERR_CP5412A2FATAL, "IOERR_CP5412A2FATAL"}, + { IOERR_CP5412A2MAILBOXUSED, "IOERR_CP5412A2MAILBOXUSED"}, + { IOERR_BEGINCONFIGWHILETICKER, "IOERR_BEGINCONFIGWHILETICKER"}, + { IOERR_UNEXPECTEDBOXCOUNT, "IOERR_UNEXPECTEDBOXCOUNT"}, + { IOERR_C1200CHECKADDR, "IOERR_C1200CHECKADDR"}, + { IOERR_C1200INTENSITYTEST, "IOERR_C1200INTENSITYTEST"}, + { IOERR_NOIMAGE, "IOERR_NOIMAGE"}, + { IOERR_INVALIDIMAGEOFFSSIZE, "IOERR_INVALIDIMAGEOFFSSIZE"}, + { IOERR_FORCESCOUNTEXCEEDEDMAXIMUM, "IOERR_FORCESCOUNTEXCEEDEDMAXIMUM"}, + { IOERR_SERCOSLIFECOUNTERERR, "IOERR_SERCOSLIFECOUNTERERR"}, + { IOERR_C1220NOTFOUND, "IOERR_C1220NOTFOUND"}, + { IOERR_AMSDEVICENOAMSINTF, "IOERR_AMSDEVICENOAMSINTF"}, + { IOERR_AMSDEVICEAMSCMDIDNOTSUPP, "IOERR_AMSDEVICEAMSCMDIDNOTSUPP"}, + { IOERR_AMSDEVICEAMSSERVICERUNNING, "IOERR_AMSDEVICEAMSSERVICERUNNING"}, + { IOERR_PLCINTERFACE_BUSY, "IOERR_PLCINTERFACE_BUSY"}, + { IOERR_PLCINTERFACE_FAULT, "IOERR_PLCINTERFACE_FAULT"}, + { IOERR_PLCINTERFACE_TIMEOUT, "IOERR_PLCINTERFACE_TIMEOUT"}, + { IOERR_PLCINTERFACE_RESETTIMEOUT, "IOERR_PLCINTERFACE_RESETTIMEOUT"}, + { IOERR_PLCINTERFACE_NODATAEXCH, "IOERR_PLCINTERFACE_NODATAEXCH"}, + { IOERR_PLCINTERFACE_RESET, "IOERR_PLCINTERFACE_RESET"}, + { IOERR_CP5412A2INVALIDADDR, "IOERR_CP5412A2INVALIDADDR"}, + { IOERR_CP5412A2INVALIDPORT, "IOERR_CP5412A2INVALIDPORT"}, + { IOERR_AMSDEVICEBADBOXNO, "IOERR_AMSDEVICEBADBOXNO"}, + { IOERR_AMSDEVICEBADTYPE, "IOERR_AMSDEVICEBADTYPE"}, + { IOERR_AMSDEVICEILLEGALADDRESS, "IOERR_AMSDEVICEILLEGALADDRESS"}, + { IOERR_CP5412A2INVALIDBOX, "IOERR_CP5412A2INVALIDBOX"}, + { IOERR_AMSDEVICEFIFOOVERFLOW, "IOERR_AMSDEVICEFIFOOVERFLOW"}, + { IOERR_AMSDEVICEAMSSEQUENCEERROR, "IOERR_AMSDEVICEAMSSEQUENCEERROR"}, + { IOERR_CP5412A2DPV1SYNTAXERROR, "IOERR_CP5412A2DPV1SYNTAXERROR"}, + { IOERR_CP5412A2DEVICENOTRUNNING, "IOERR_CP5412A2DEVICENOTRUNNING"}, + { IOERR_AMSDEVICENOTRUNNING, "IOERR_AMSDEVICENOTRUNNING"}, + { IOERR_AMSDEVICEBOXNOTDEFINED, "IOERR_AMSDEVICEBOXNOTDEFINED"}, + { IOERR_CP5412A2BADSERVICEPARA, "IOERR_CP5412A2BADSERVICEPARA"}, + { IOERR_CP5412A2FIFOOVERFLOW, "IOERR_CP5412A2FIFOOVERFLOW"}, + { IOERR_COMPORTOPENFAILED, "IOERR_COMPORTOPENFAILED"}, + { IOERR_CIF30BADMESSAGERESPONSE, "IOERR_CIF30BADMESSAGERESPONSE"}, + { IOERR_CIF30DELETEDATABASE, "IOERR_CIF30DELETEDATABASE"}, + { IOERR_CIF30STARTSEQFAILED, "IOERR_CIF30STARTSEQFAILED"}, + { IOERR_CIF30DOWNLOADFAILED, "IOERR_CIF30DOWNLOADFAILED"}, + { IOERR_CIF30ENDSEQFAILED, "IOERR_CIF30ENDSEQFAILED"}, + { IOERR_CIF30BUSLOADFAILED, "IOERR_CIF30BUSLOADFAILED"}, + { IOERR_PLCINTERFACE_RESETREQ, "IOERR_PLCINTERFACE_RESETREQ"}, + { IOERR_CP5412A2INVALIDCYCLETICKS, "IOERR_CP5412A2INVALIDCYCLETICKS"}, + { IOERR_CP5412A2DPBUSFAULT, "IOERR_CP5412A2DPBUSFAULT"}, + { IOERR_INVALIDTERMCONFIG, "IOERR_INVALIDTERMCONFIG"}, + { IOERR_SERCANSBREAK, "IOERR_SERCANSBREAK"}, + { IOERR_SERCANSPHASE0, "IOERR_SERCANSPHASE0"}, + { IOERR_SERCANSPHASE1, "IOERR_SERCANSPHASE1"}, + { IOERR_SERCANSPHASE2, "IOERR_SERCANSPHASE2"}, + { IOERR_SERCANSPHASE3, "IOERR_SERCANSPHASE3"}, + { IOERR_SERCANSPHASE4, "IOERR_SERCANSPHASE4"}, + { IOERR_SERCANSNCSERVICECHNFAILED, "IOERR_SERCANSNCSERVICECHNFAILED"}, + { IOERR_RESOURCECONFICT, "IOERR_RESOURCECONFICT"}, + { IOERR_C1220INITSTRINGCOMM, "IOERR_C1220INITSTRINGCOMM"}, + { IOERR_C1220REGSTRINGSLAVE, "IOERR_C1220REGSTRINGSLAVE"}, + { IOERR_C1220STRREGFAULT, "IOERR_C1220STRREGFAULT"}, + { IOERR_IOSTATEBUSY, "IOERR_IOSTATEBUSY"}, + { IOERR_IBSSCITWATCHDOGEXPIRED, "IOERR_IBSSCITWATCHDOGEXPIRED"}, + { IOERR_IBSSCITSYNCMAILBOXERROR, "IOERR_IBSSCITSYNCMAILBOXERROR"}, + { IOERR_IBSSCITCONFIRMDIAGERROR, "IOERR_IBSSCITCONFIRMDIAGERROR"}, + { IOERR_IBSSCITCREATECFGERROR, "IOERR_IBSSCITCREATECFGERROR"}, + { 0, NULL } +}; + +static const value_string AdsErrorMode[] = +{ + { ADSERR_NOERR, "NO ERROR", }, + { ADSERR_DEVICE_ERROR, "ERROR", }, + { ADSERR_DEVICE_SRVNOTSUPP, "SRV NOT SUPP", }, + { ADSERR_DEVICE_INVALIDGRP, "INVALID GRP", }, + { ADSERR_DEVICE_INVALIDOFFSET, "INVALID OFFSET", }, + { ADSERR_DEVICE_INVALIDACCESS, "INVALID ACCESS", }, + { ADSERR_DEVICE_INVALIDSIZE, "INVALID SIZE", }, + { ADSERR_DEVICE_INVALIDDATA, "INVALID DATA", }, + { ADSERR_DEVICE_NOTREADY, "NOT READY", }, + { ADSERR_DEVICE_BUSY, "BUSY", }, + { ADSERR_DEVICE_INVALIDCONTEXT, "INVALID CONTEXT", }, + { ADSERR_DEVICE_NOMEMORY, "NO MEMORY", }, + { ADSERR_DEVICE_INVALIDPARM, "INVALID PARM", }, + { ADSERR_DEVICE_NOTFOUND, "NOT FOUND", }, + { ADSERR_DEVICE_SYNTAX, "SYNTAX", }, + { ADSERR_DEVICE_INCOMPATIBLE, "INCOMPATIBLE", }, + { ADSERR_DEVICE_EXISTS, "EXISTS", }, + { ADSERR_DEVICE_SYMBOLNOTFOUND, "SYMBOL NOT FOUND", }, + { ADSERR_DEVICE_SYMBOLVERSIONINVALID, "SYMBOL VERSION INVALID", }, + { ADSERR_DEVICE_INVALIDSTATE, "INVALID STATE", }, + { ADSERR_DEVICE_TRANSMODENOTSUPP, "TRANS MODE NOT SUPP", }, + { ADSERR_DEVICE_NOTIFYHNDINVALID, "NOTIFY HND INVALID", }, + { ADSERR_DEVICE_CLIENTUNKNOWN, "CLIENT UNKNOWN", }, + { ADSERR_DEVICE_NOMOREHDLS, "NO MORE HDLS", }, + { ADSERR_DEVICE_INVALIDWATCHSIZE, "INVALID WATCHSIZE", }, + { ADSERR_DEVICE_NOTINIT, "NOT INIT", }, + { ADSERR_DEVICE_TIMEOUT, "TIMEOUT", }, + { ADSERR_DEVICE_NOINTERFACE, "NO INTERFACE", }, + { ADSERR_DEVICE_INVALIDINTERFACE, "INVALID INTERFACE", }, + { ADSERR_DEVICE_INVALIDCLSID, "INVALID CLSID", }, + { ADSERR_DEVICE_INVALIDOBJID, "INVALID OBJID", }, + { ADSERR_DEVICE_PENDING, "PENDING", }, + { ADSERR_DEVICE_ABORTED, "ABORTED", }, + { ADSERR_DEVICE_WARNING, "WARNING", }, + { ADSERR_DEVICE_INVALIDARRAYIDX, "INVALID ARRAY IDX", }, + { ADSERR_CLIENT_ERROR, "CLIENT ERROR", }, + { ADSERR_CLIENT_INVALIDPARM, "CLIENT INVALID PARM", }, + { ADSERR_CLIENT_LISTEMPTY, "CLIENT LIST EMPTY", }, + { ADSERR_CLIENT_VARUSED, "CLIENT VAR USED", }, + { ADSERR_CLIENT_DUPLINVOKEID, "CLIENT DUPL INVOKEID", }, + { ADSERR_CLIENT_SYNCTIMEOUT, "CLIENT SYNC TIMEOUT", }, + { ADSERR_CLIENT_W32ERROR, "CLIENT W32ERROR", }, + { ADSERR_CLIENT_TIMEOUTINVALID, "CLIENT TIMEOUT INVALID", }, + { ADSERR_CLIENT_PORTNOTOPEN, "CLIENT PORT NOT OPEN", }, + { ADSERR_CLIENT_NOAMSADDR, "CLIENT NO AMS ADDR", }, + { ADSERR_CLIENT_SYNCINTERNAL, "CLIENT SYNC INTERNAL", }, + { ADSERR_CLIENT_ADDHASH, "CLIENT ADD HASH", }, + { ADSERR_CLIENT_REMOVEHASH, "CLIENT REMOVE HASH", }, + { ADSERR_CLIENT_NOMORESYM, "CLIENT NO MORE SYM", }, + { ADSERR_CLIENT_SYNCRESINVALID, "CLIENT SYNC RES INVALID", }, + { ADSERR_CLIENT_SYNCPORTLOCKED, "CLIENT SYNC PORT LOCKED", }, + { 0, NULL } +}; + + +/* AMS Command Id + * https://infosys.beckhoff.com/english.php?content=../content/1033/tcadsamsspec/html/tcadsamsspec_adscmd_readstate.htm&id=10652 + */ +static const value_string AMS_CommandId_vals[] = +{ + { ADSSRVID_INVALID, "Invalid", }, + { ADSSRVID_READDEVICEINFO, "ADS Read Device Info", }, + { ADSSRVID_READ, "ADS Read", }, + { ADSSRVID_WRITE, "ADS Write", }, + { ADSSRVID_READSTATE, "ADS Read State", }, + { ADSSRVID_WRITECTRL, "ADS Write Control", }, + { ADSSRVID_ADDDEVICENOTE, "ADS Add Device Notification", }, + { ADSSRVID_DELDEVICENOTE, "ADS Delete Device Notification", }, + { ADSSRVID_DEVICENOTE, "ADS Device Notification", }, + { ADSSRVID_READWRITE, "ADS Read Write", }, + { 0, NULL } +}; + + +static void NetIdFormater(tvbuff_t *tvb, guint offset, char *szText, gint nMax) +{ + snprintf ( szText, nMax, "%d.%d.%d.%d.%d.%d", tvb_get_guint8(tvb, offset), + tvb_get_guint8(tvb, offset+1), + tvb_get_guint8(tvb, offset+2), + tvb_get_guint8(tvb, offset+3), + tvb_get_guint8(tvb, offset+4), + tvb_get_guint8(tvb, offset+5) + ); +} + + + +/*ams*/ +static gint dissect_ams_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) +{ + proto_item *ti, *anItem; + proto_tree *ams_tree = NULL, *ams_adstree, *ams_statetree; + guint ams_length = tvb_reported_length(tvb); + guint16 stateflags = 0; + guint16 cmdId = 0; + guint32 cbdata = 0; + + char szText[200]; + int nMax = sizeof(szText)-1; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMS"); + + col_clear(pinfo->cinfo, COL_INFO); + + if( ams_length < AmsHead_Len ) + return offset; + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ams, tvb, 0, -1, ENC_NA); + ams_tree = proto_item_add_subtree(ti, ett_ams); + + NetIdFormater(tvb, offset, szText, nMax); + proto_tree_add_string(ams_tree, hf_ams_targetnetid, tvb, offset, AmsNetId_Len, szText); + offset += AmsNetId_Len; + + proto_tree_add_item(ams_tree, hf_ams_targetport, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset += (int)sizeof(guint16); + + NetIdFormater(tvb, offset, szText, nMax); + proto_tree_add_string(ams_tree, hf_ams_sendernetid, tvb, offset, AmsNetId_Len, szText); + offset += AmsNetId_Len; + + proto_tree_add_item(ams_tree, hf_ams_senderport, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset += (int)sizeof(guint16); + + proto_tree_add_item(ams_tree, hf_ams_cmdid, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + cmdId = tvb_get_letohs(tvb, offset); + offset+=(int)sizeof(guint16); + + anItem = proto_tree_add_item(ams_tree, hf_ams_stateflags, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + ams_statetree = proto_item_add_subtree(anItem, ett_ams_stateflags); + proto_tree_add_item(ams_statetree, hf_ams_stateresponse,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_statenoreturn,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_stateadscmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_statesyscmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_statehighprio,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_statetimestampadded,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_stateudp,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_stateinitcmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_statetree, hf_ams_statebroadcast,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + stateflags = tvb_get_letohs(tvb, offset); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(ams_tree, hf_ams_cbdata, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + cbdata = tvb_get_letohl(tvb,offset); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_tree, hf_ams_errorcode, tvb, offset, (int)sizeof(guint32),ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_tree, hf_ams_invokeid, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + } + else + { + offset+=AmsHead_Len; + } + + if ( (stateflags & AMSCMDSF_ADSCMD) != 0 ) + { + /* ADS */ + if ( (stateflags & AMSCMDSF_RESPONSE) == 0 ) + { + /* Request */ + switch ( cmdId ) + { + case ADSSRVID_READ: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadrequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + } + } + } + break; + case ADSSRVID_WRITE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adswriterequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsWriteReq_Len - (int)sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA); + } + } + } + break; + case ADSSRVID_READWRITE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriterequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadWriteReq_Len - (int)sizeof(guint16)) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscbreadlength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscbwritelength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA); + } + } + } + break; + case ADSSRVID_READSTATE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Request"); + + if( tree && cbdata !=0 ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstaterequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadStateReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstaterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsinvokeid, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_WRITECTRL: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlrequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsWriteControlReq_Len - (int)sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA); + } + } + } + break; + case ADSSRVID_READDEVICEINFO: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Request"); + + if( tree && cbdata !=0 ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadDeviceInfoReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforequest); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_ADDDEVICENOTE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Add Device Notification Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnrequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsAddDeviceNotificationReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adstransmode, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsmaxdelay, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscycletime, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + } + } + } + break; + case ADSSRVID_DELDEVICENOTE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Request"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnrequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsDelDeviceNotificationReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_DEVICENOTE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Request"); + + if( tree ) + { + /*guint32 cbLength; + guint32 nStamps;*/ + + anItem = proto_tree_add_item(ams_tree, hf_ams_adsdnrequest, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsDeviceNotificationReq_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + /*cbLength = tvb_get_letohs(tvb, offset);*/ + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsnoteblocksstamps, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + /*nStamps = tvb_get_letohs(tvb, offset);*/ + offset+=(int)sizeof(guint32); + + /*ToDo: dissect noteblocks*/ + } + } + } + break; + } + } + else + { + /* Response */ + switch ( cmdId ) + { + case ADSSRVID_READ: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadRes_Len - (int)sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA); + } + } + } + break; + case ADSSRVID_WRITE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adswriteresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsWriteRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriteresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_READWRITE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriteresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadWriteRes_Len - (int)sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriteresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA); + } + } + } + break; + case ADSSRVID_READSTATE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstateresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadStateRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstateresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_WRITECTRL: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsWriteControlRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_READDEVICEINFO: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforesponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsReadDeviceInfoRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforesponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsversionversion, tvb, offset++, (int)sizeof(guint8), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_adstree, hf_ams_adsversionrevision, tvb, offset++, (int)sizeof(guint8), ENC_LITTLE_ENDIAN); + proto_tree_add_item(ams_adstree, hf_ams_adsversionbuild, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicename, tvb, offset, ams_length-offset, ENC_ASCII|ENC_NA); + } + } + } + break; + case ADSSRVID_ADDDEVICENOTE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsAddDeviceNotificationRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + case ADSSRVID_DELDEVICENOTE: + { + col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Response"); + + if( tree ) + { + anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnresponse, tvb, offset, ams_length-offset, ENC_NA); + if( ams_length-offset >= TAdsDelDeviceNotificationRes_Len ) + { + ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN); + } + } + } + break; + } + } + } + else + { + if ( (stateflags & AMSCMDSF_RESPONSE) == 0 ) + col_append_str(pinfo->cinfo, COL_INFO, "AMS Request"); + else + col_append_str(pinfo->cinfo, COL_INFO, "AMS Response"); + if( tree && ams_length-offset > 0 ) + proto_tree_add_item(ams_tree, hf_ams_data, tvb, offset, ams_length-offset, ENC_NA); + } + return offset; +} + +/*ams*/ +static gint dissect_ams(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + return dissect_ams_pdu(tvb, pinfo, tree, 0); +} + +static gint dissect_amstcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + if( TcpAdsParserHDR_Len > tvb_reported_length(tvb)) + return 0; + + return dissect_ams_pdu(tvb, pinfo, tree, TcpAdsParserHDR_Len); +} + +void proto_register_ams(void) +{ + static const true_false_string flags_set_truth = + { + "Set", + "Not set" + }; + + static hf_register_info hf[] = + { + { &hf_ams_sendernetid, + { "AMS Sender Net Id", "ams.sendernetid", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_senderport, + { "AMS Sender port", "ams.senderport", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_targetnetid, + { "AMS Target Net Id", "ams.targetnetid", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_targetport, + { "AMS Target port", "ams.targetport", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_cmdid, + { "CmdId", "ams.cmdid", + FT_UINT16, BASE_DEC, VALS(AMS_CommandId_vals), 0x0, + NULL, HFILL } + }, + { &hf_ams_stateflags, + { "StateFlags", "ams.stateflags", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_stateresponse, + { "RESPONSE", "ams.state_response", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_RESPONSE, + NULL, HFILL } + }, + { &hf_ams_statenoreturn, + { "NO RETURN", "ams.state_noreturn", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_NORETURN, + NULL, HFILL } + }, + { &hf_ams_stateadscmd, + { "ADS COMMAND", "ams.state_adscmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_ADSCMD, + NULL, HFILL } + }, + { &hf_ams_statesyscmd, + { "SYSTEM COMMAND", "ams.state_syscmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_SYSCMD, + NULL, HFILL } + }, + { &hf_ams_statehighprio, + { "HIGH PRIORITY COMMAND", "ams.state_highprio", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_HIGHPRIO, + NULL, HFILL } + }, + { &hf_ams_statetimestampadded, + { "TIMESTAMP ADDED", "ams.state_timestampadded", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_TIMESTAMPADDED, + NULL, HFILL } + }, + { &hf_ams_stateudp, + { "UDP COMMAND", "ams.state_udp", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_UDP, + NULL, HFILL } + }, + { &hf_ams_stateinitcmd, + { "INIT COMMAND", "ams.state_initcmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_INITCMD, + NULL, HFILL } + }, + { &hf_ams_statebroadcast, + { "BROADCAST", "ams.state_broadcast", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_BROADCAST, + NULL, HFILL } + }, + { &hf_ams_cbdata, + { "cbData", "ams.cbdata", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_errorcode, + { "ErrorCode", "ams.errorcode", + FT_UINT32, BASE_HEX, VALS(ErrorCode), 0x0, + NULL, HFILL } + }, + { &hf_ams_invokeid, + { "InvokeId", "ams.invokeid", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsdata, + { "Data", "ams.ads_data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_data, + { "Data", "ams.data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsindexgroup, + { "IndexGroup", "ams.ads_indexgroup", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsindexoffset, + { "IndexOffset", "ams.ads_indexoffset", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adscblength, + { "CbLength", "ams.ads_cblength", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadrequest, + { "ADS Read Request", "ams.ads_read_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadresponse, + { "ADS Read Response", "ams.ads_read_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsinvokeid, + { "InvokeId", "ams.ads_invokeid", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsresult, + { "Result", "ams.adsresult", + FT_UINT32, BASE_HEX, VALS(AdsErrorMode), 0x0, + NULL, HFILL } + }, + { &hf_ams_adswriterequest, + { "ADS Write Request", "ams.ads_write_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adswriteresponse, + { "ADS Write Response", "ams.ads_write_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadwriterequest, + { "ADS ReadWrite Request", "ams.ads_readwrite_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadwriteresponse, + { "ADS ReadWrite Response", "ams.ads_readwrite_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adscbreadlength, + { "CBReadLength", "ams.ads_cbreadlength", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adscbwritelength, + { "CBWriteLength", "ams.ads_cbwritelength", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsstate, + { "AdsState", "ams.ads_state", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsdevicestate, + { "DeviceState", "ams.ads_devicestate", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsnotificationhandle, + { "NotificationHandle", "ams.ads_notificationhandle", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadstaterequest, + { "ADS Read State Request", "ams.ads_readstate_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreadstateresponse, + { "ADS Read State Response", "ams.ads_readstate_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adswritectrlrequest, + { "ADS Write Ctrl Request", "ams.ads_writectrl_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adswritectrlresponse, + { "ADS Write Ctrl Response", "ams.ads_writectrl_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreaddinforequest, + { "ADS Read Device Info Request", "ams.ads_readdinfo_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsreaddinforesponse, + { "ADS Read Device Info Response", "ams.ads_readdinfo_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsadddnrequest, + { "ADS Add Device Notification Request", "ams.ads_adddn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsadddnresponse, + { "ADS Add Device Notification Response", "ams.ads_adddn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsdeldnrequest, + { "ADS Delete Device Notification Request", "ams.ads_deldn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsdeldnresponse, + { "ADS Delete Device Notification Response", "ams.ads_deldn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsdnrequest, + { "ADS Device Notification Request", "ams.ads_dn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ams_adsdnresponse, + { "ADS Device Notification Response", "ams.ads_dn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsnoteattrib, + { "InvokeId", "ams.ads_noteattrib", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsnoteblocks, + { "InvokeId", "ams.ads_noteblocks", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsversion, + { "ADS Version", "ams.ads_version", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_ams_adsdevicename, + { "Device Name","ams.ads_devicename", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsversionversion, + { "ADS Major Version", "ams.ads_versionversion", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsversionrevision, + { "ADS Minor Version", "ams.ads_versionrevision", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsversionbuild, + { "ADS Version Build", "ams.ads_versionbuild", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsnoteblocksstamps, + { "Count of Stamps", "ams.ads_noteblocksstamps", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ams_adsnoteblocksstamp, + { "Notification Stamp", "ams.ads_noteblocksstamp", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adstimestamp, + { "Time Stamp", "ams.ads_timestamp", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adssamplecnt, + { "Count of Stamps", "ams.ads_samplecnt", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adsnoteblockssample, + { "Notification Sample", "ams.ads_noteblockssample", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_ams_adstransmode, + { "Trans Mode", "ams.ads_transmode", + FT_UINT32, BASE_DEC, VALS(TransMode), 0x0, + NULL, HFILL } + }, + { &hf_ams_adsmaxdelay, + { "Max Delay", "ams.ads_maxdelay", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adscycletime, + { "Cycle Time", "ams.ads_cycletime", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ams_adscmpmax, + { "Cmp Mad", "ams.ads_cmpmax", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ams_adscmpmin, + { "Cmp Min", "ams.ads_cmpmin", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + } +#endif + }; + + static gint *ett[] = + { + &ett_ams, + &ett_ams_stateflags, + &ett_ams_adsreadrequest, + &ett_ams_adsreadresponse, + &ett_ams_adswriterequest, + &ett_ams_adswriteresponse, + &ett_ams_adsreadwriterequest, + &ett_ams_adsreadwriteresponse, + &ett_ams_adsreadstaterequest, + &ett_ams_adsreadstateresponse, + &ett_ams_adswritectrlrequest, + &ett_ams_adswritectrlresponse, + &ett_ams_adsreaddinforequest, + &ett_ams_adsreaddinforesponse, + &ett_ams_adsadddnrequest, + &ett_ams_adsadddnresponse, + &ett_ams_adsdeldnrequest, + &ett_ams_adsdeldnresponse, + &ett_ams_adsdnrequest + }; + + proto_ams = proto_register_protocol("AMS", "AMS", "ams"); + proto_register_field_array(proto_ams, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + ams_handle = register_dissector("ams", dissect_ams, proto_ams); + amstcp_handle = register_dissector("ams.tcp", dissect_amstcp, proto_ams ); +} + +/* The registration hand-off routing */ + +void proto_reg_handoff_ams(void) +{ + dissector_add_uint_with_preference("tcp.port", AMS_TCP_PORT, amstcp_handle); + dissector_add_uint("ecatf.type", 2, ams_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ams.h b/plugins/epan/ethercat/packet-ams.h new file mode 100644 index 00000000..199e1028 --- /dev/null +++ b/plugins/epan/ethercat/packet-ams.h @@ -0,0 +1,1153 @@ +/* packet-ams.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __PACKET_AMS_H__ +#define __PACKET_AMS_H__ + +/* FIXED PORTS */ + +#define AMSPORT_ROUTER 1 +#define AMSPORT_DEBUGGER 2 + +#define AMSPORT_LOGGER 100 +#define AMSPORT_EVENTLOG 110 +#define AMSPORT_R0_RTIME 200 +#define AMSPORT_R0_TRACE (AMSPORT_R0_RTIME+90) +#define AMSPORT_R0_IO 300 +#define AMSPORT_R0_SPS 400 +#define AMSPORT_R0_NC 500 +#define AMSPORT_R0_NCSAF 501 +#define AMSPORT_R0_NCSVB 511 +#define AMSPORT_R0_ISG 550 +#define AMSPORT_R0_CNC 600 +#define AMSPORT_R0_LINE 700 +#define AMSPORT_R0_PLC 800 +#define AMSPORT_R0_CAM 900 +#define AMSPORT_R0_CAMTOOL 950 + +#define AMSPORT_R0_IOPORTBEGIN 1000 +#define AMSPORT_R0_IOPORTEND 1199 + +#define AMSPORT_R0_USER 2000 + +#define AMSPORT_R3_SYSSERV 10000 +#define AMSPORT_R3_CTRLPROG 10000 +#define AMSPORT_R3_SYSCTRL 10001 +#define AMSPORT_R3_SYSSAMPLER 10100 +#define AMSPORT_R3_TCPRAWCONN 10200 +#define AMSPORT_R3_TCPIPSERVER 10201 +#define AMSPORT_R3_SYSMANAGER 10300 +#define AMSPORT_R3_SMSSERVER 10400 +#define AMSPORT_R3_MODBUSSERVER 10500 +#define AMSPORT_R3_PLCCONTROL 10800 +#define AMSPORT_R3_NCCTRL 11000 +#define AMSPORT_R3_NCINTERPRETER 11500 +#define AMSPORT_R3_STRECKECTRL 12000 +#define AMSPORT_R3_CAMCTRL 13000 +#define AMSPORT_R3_SCOPE 14000 +#define AMSPORT_R3_SINECH1 15000 +#define AMSPORT_R3_CONTROLNET 16000 +#define AMSPORT_R3_OPCSERVER 17000 +#define AMSPORT_R3_OPCCLIENT 17500 + +#define AMSPORT_R3_CUSTOMER_FIRST 25000 +#define AMSPORT_R3_CUSTOMER_LAST 25999 + +#define AMSPORT_FIRST 1 +#define AMSPORT_LAST 0xFFFE + +#define AMSPORT_UNFIXEDPORT 0 +#define AMSPORT_USEDEFAULT 0xFFFF + +#define AMSPORT_IOBOXBEGIN_USB 0x6E00 +#define AMSPORT_IOBOXEND_USB 0x6EFF +#define AMSPORT_IODEVBEGIN 0x7000 +#define AMSPORT_IODEVEND 0x70FF +#define AMSPORT_IOBOXBEGIN 0x7100 +#define AMSPORT_IOBOXEND 0x7FFF + +#define AMSPORT_FREEBEGIN 0x8000 +#define AMSPORT_FREEEND 0xBFFF + + +#define AMSPORT_NAMESIZE 31 + +/* Port types */ +typedef enum +{ + PORTTYPE_INVALID = -1, + PORTTYPE_ROUTER = 0x00, + PORTTYPE_R3PORT = 0x01, + PORTTYPE_R0CTRLPORT = 0x02, + PORTTYPE_R0TASKPORT = 0x03, + PORTTYPE_R0IOPORT = 0x04, + PORTTYPE_TPPORT = 0x05, + PORTTYPE_MAXVAL = 0xFF +}AMSPORT_TYPE; + +/* Command IDs */ + +#define AMSCMD_LOGMESSAGE 0x0001 +#define AMSCMD_ROUTERSHUTDOWN 0x0002 +#define AMSCMD_ROUTERACTIVATED 0x0003 +#define AMSCMD_SYSTEMREMOVED 0x0004 +#define AMSCMD_CLOSECONNECTION 0x0005 +#define AMSCMD_SIGNALSTART 0x00FB +#define AMSCMD_SIGNALSTOP 0x00FC +#define AMSCMD_HANDLERETAINDATA 0x00FD +#define AMSCMD_DEVICECONFIGID 0x00FE +#define AMSCMD_DOWNLOADSYMBOLS 0x00FF + +#define AMS_ERRLOGCMDS 0x100 + +#define AMS_TASKCMDS 0x500 +#define AMS_CTRLCMDS 0x600 + +#define AMS_ROUTERCMDS 0x900 +#define AMS_RTIMECMDS 0x1000 +#define AMS_TRACECMDS (AMS_RTIMECMDS+0x900) +#define AMS_IOCMDS 0x2000 +#define AMS_C1220CMDS (AMS_IOCMDS+0x100) +#define AMS_FCxxxxCMDS (AMS_IOCMDS+0x200) +#define AMS_SPSCMDS 0x3000 +#define AMS_NCCMDS 0x4000 +#define AMS_PLCCMDS 0x5000 +#define AMS_LINECMDS 0x6000 +#define AMS_CAMCMDS 0x7000 + +#define AMS_CMDSPECIFIC 0x8000 + + +#define AMSERRCODEISWARNING 0x80000000 + +/* Error Arrays */ + +#define ERR_ROUTERERRS 0x0500 +#define ERR_TASKERRS 0x0600 +#define ERR_ADSERRS 0x0700 +#define ERR_SYSSMPLERRS 0x0800 +#define ERR_RTIMEERRS 0x1000 +#define ERR_TRACEERRS (ERR_RTIMEERRS+0x900) +#define ERR_IOERRS 0x2000 +#define ERR_DPSLAVE (ERR_IOERRS+0x900) +#define ERR_CP5412A2 (ERR_IOERRS+0xA00) +#define ERR_ASP (ERR_IOERRS+0xB00) +#define ERR_CANSLAVE (ERR_IOERRS+0xC00) +#define ERR_CIF30 (ERR_IOERRS+0xD00) +#define ERR_IBSSLAVE (ERR_IOERRS+0xE00) +#define ERR_SPSERRS 0x3000 +#define ERR_NCERRS 0x4000 +#define ERR_PLCERRS 0x6000 +#define ERR_STRKERRS 0x7000 + +#define ERR_PRJSPECIFIC 0x7800 + +#define ERR_DRIVEERRS_C3D 0xD000 +#define ERR_DRIVEERRS_C2D 0xE000 +#define ERR_DRIVEERRS_C1D 0xF000 + + +/* Global Error codes */ +#define ERR_NOERROR 0 +#define ERR_INTERNAL 1 +#define ERR_NORTIME 2 +#define ERR_ALLOCLOCKEDMEM 3 +#define ERR_INSERTMAILBOX 4 +#define ERR_WRONGRECEIVEHMSG 5 +#define ERR_TARGETPORTNOTFOUND 6 +#define ERR_TARGETMACHINENOTFOUND 7 +#define ERR_UNKNOWNCMDID 8 +#define ERR_BADTASKID 9 +#define ERR_NOIO 10 +#define ERR_UNKNOWNAMSCMD 11 +#define ERR_WIN32ERROR 12 +#define ERR_PORTNOTCONNECTED 13 +#define ERR_INVALIDAMSLENGTH 14 +#define ERR_INVALIDAMSNETID 15 +#define ERR_LOWINSTLEVEL 16 +#define ERR_NODEBUGINTAVAILABLE 17 +#define ERR_PORTDISABLED 18 +#define ERR_PORTALREADYCONNECTED 19 +#define ERR_AMSSYNC_W32ERROR 20 +#define ERR_AMSSYNC_TIMEOUT 21 +#define ERR_AMSSYNC_AMSERROR 22 +#define ERR_AMSSYNC_NOINDEXINMAP 23 +#define ERR_INVALIDAMSPORT 24 +#define ERR_NOMEMORY 25 +#define ERR_TCPSEND 26 +#define ERR_HOSTUNREACHABLE 27 +#define ERR_INVALIDAMSFRAGMENT 28 + + +/* ROUTER */ +#define ROUTERERR_NOLOCKEDMEMORY 0 + ERR_ROUTERERRS +#define ROUTERERR_RESIZEMEMORY 1 + ERR_ROUTERERRS +#define ROUTERERR_MAILBOXFULL 2 + ERR_ROUTERERRS +#define ROUTERERR_DEBUGBOXFULL 3 + ERR_ROUTERERRS +#define ROUTERERR_UNKNOWNPORTTYPE 4 + ERR_ROUTERERRS +#define ROUTERERR_NOTINITIALIZED 5 + ERR_ROUTERERRS +#define ROUTERERR_PORTALREADYINUSE 6 + ERR_ROUTERERRS +#define ROUTERERR_NOTREGISTERED 7 + ERR_ROUTERERRS +#define ROUTERERR_NOMOREQUEUES 8 + ERR_ROUTERERRS +#define ROUTERERR_INVALIDPORT 9 + ERR_ROUTERERRS +#define ROUTERERR_NOTACTIVATED 10 + ERR_ROUTERERRS +#define ROUTERERR_FRAGMENTBOXFULL 11 + ERR_ROUTERERRS +#define ROUTERERR_FRAGMENTTIMEOUT 12 + ERR_ROUTERERRS +#define ROUTERERR_TOBEREMOVED 13 + ERR_ROUTERERRS + +#define TASKERR_UNKNOWNTASKTYPE 0 + ERR_TASKERRS +#define TASKERR_TASKTERMINATED 1 + ERR_TASKERRS +#define TASKERR_EVENTTIMEOUT 2 + ERR_TASKERRS + + +/* System Sampler */ +#define SMPLERR_INTERNAL 0 + ERR_SYSSMPLERRS +#define SMPLERR_INVALIDTYPE 1 + ERR_SYSSMPLERRS + + +/* RTIME */ +#define RTERR_INTERNAL 0 + ERR_RTIMEERRS +#define RTERR_BADTIMERPERIODS 1 + ERR_RTIMEERRS +#define RTERR_INVALIDTASKPTR 2 + ERR_RTIMEERRS +#define RTERR_INVALIDSTACKPTR 3 + ERR_RTIMEERRS +#define RTERR_PRIOEXISTS 4 + ERR_RTIMEERRS +#define RTERR_NOMORETCB 5 + ERR_RTIMEERRS +#define RTERR_NOMORESEMAS 6 + ERR_RTIMEERRS +#define RTERR_NOMOREQUEUES 7 + ERR_RTIMEERRS +#define RTERR_SHUTDOWNTIMEOUT 8 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOPCR 9 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOIDT 10 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOPHYSMEM 11 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSMAPERR 12 + ERR_RTIMEERRS +#define RTERR_EXTIRQALREADYDEF 13 + ERR_RTIMEERRS +#define RTERR_EXTIRQNOTDEF 14 + ERR_RTIMEERRS +#define RTERR_EXTIRQINSTALLFAILED 15 + ERR_RTIMEERRS +#define RTERR_IRQLNOTLESSOREQUAL 16 + ERR_RTIMEERRS +#define RTERR_SYSCLOCKFAILURE 17 + ERR_RTIMEERRS + + +/* TRACE */ +#define TRACEERR_REGISTRY 0 + ERR_TRACEERRS +#define TRACEERR_MEMMAP 1 + ERR_TRACEERRS +#define TRACEERR_NOTAVAIL 2 + ERR_TRACEERRS + + +/* IO */ +#define IOERR_INTERNAL (0 + ERR_IOERRS) +#define IOERR_BADCARDNO (1 + ERR_IOERRS) +#define IOERR_INVALIDCARDADDR (2 + ERR_IOERRS) +#define IOERR_CDLLISTFULL (3 + ERR_IOERRS) +#define IOERR_BADCDLPARAM (4 + ERR_IOERRS) +#define IOERR_OPENIOFAILED (5 + ERR_IOERRS) +#define IOERR_RESETIOFAILED (6 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICE (7 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICEID (8 + ERR_IOERRS) +#define IOERR_UNKNOWNIMAGEID (9 + ERR_IOERRS) +#define IOERR_GETIOSTATE (10 + ERR_IOERRS) +#define IOERR_BADIMAGEID (11 + ERR_IOERRS) +#define IOERR_NOMORECLIENTSPACE (12 + ERR_IOERRS) +#define IOERR_CLIENTINFONOTFOUND (13 + ERR_IOERRS) +#define IOERR_CDLNOTINUSE (14 + ERR_IOERRS) +#define IOERR_TIMEOUTWITHDEVICE (15 + ERR_IOERRS) +#define IOERR_C1220FUNC_1 (16 + ERR_IOERRS) +#define IOERR_C1220FUNC_9 (17 + ERR_IOERRS) +#define IOERR_C1220FUNC_C (18 + ERR_IOERRS) +#define IOERR_C1220FUNC_10 (19 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_MAXSEND (20 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_ADDRSET (21 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK (22 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK0 (23 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK1 (24 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK2 (25 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK3 (26 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK4 (27 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK5 (28 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK6 (29 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK7 (30 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK8 (31 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK9 (32 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK10 (33 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK11 (34 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK12 (35 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK13 (36 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK14 (37 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK15 (38 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK16 (39 + ERR_IOERRS) +#define IOERR_SPC3DEVINITDP (40 + ERR_IOERRS) +#define IOERR_SPC3UPDATEOUTPUT (41 + ERR_IOERRS) +#define IOERR_CIF30READDIAG (42 + ERR_IOERRS) +#define IOERR_CIF30COMMNOTSTARTED (43 + ERR_IOERRS) +#define IOERR_CIF30SLAVEPARASIZE (44 + ERR_IOERRS) +#define IOERR_CIF30NOPARAS (45 + ERR_IOERRS) +#define IOERR_CIF30SLAVEERROR (46 + ERR_IOERRS) +#define IOERR_CIF30WATCHDOGEXPIRED (47 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICECMD (48 + ERR_IOERRS) +#define IOERR_CIF40MESSAGEHANDLING (49 + ERR_IOERRS) +#define IOERR_CIF40PARAERROR (50 + ERR_IOERRS) +#define IOERR_CIF40WATCHDOGEXPIRED (51 + ERR_IOERRS) +#define IOERR_CIF40FLAGERROR (52 + ERR_IOERRS) +#define IOERR_CIF40COMMNOTSTARTED (53 + ERR_IOERRS) +#define IOERR_CIF40READDIAG (54 + ERR_IOERRS) +#define IOERR_CIF40SLAVEERROR (55 + ERR_IOERRS) +#define IOERR_CIF40GLOBALERROR (56 + ERR_IOERRS) +#define IOERR_CIF40CONFIGLIST (57 + ERR_IOERRS) +#define IOERR_CP5412A2SLAVEPARASIZE (58 + ERR_IOERRS) +#define IOERR_CP5412A2NOPARAS (59 + ERR_IOERRS) +#define IOERR_CP5412A2SLAVEERROR (60 + ERR_IOERRS) +#define IOERR_CP5412A2FATAL (61 + ERR_IOERRS) +#define IOERR_CP5412A2MAILBOXUSED (62 + ERR_IOERRS) +#define IOERR_BEGINCONFIGWHILETICKER (63 + ERR_IOERRS) +#define IOERR_UNEXPECTEDBOXCOUNT (64 + ERR_IOERRS) +#define IOERR_C1200CHECKADDR (65 + ERR_IOERRS) +#define IOERR_C1200INTENSITYTEST (66 + ERR_IOERRS) +#define IOERR_NOIMAGE (67 + ERR_IOERRS) +#define IOERR_INVALIDIMAGEOFFSSIZE (68 + ERR_IOERRS) +#define IOERR_FORCESCOUNTEXCEEDEDMAXIMUM (69 + ERR_IOERRS) +#define IOERR_SERCOSLIFECOUNTERERR (70 + ERR_IOERRS) +#define IOERR_C1220NOTFOUND (71 + ERR_IOERRS) +#define IOERR_AMSDEVICENOAMSINTF (72 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSCMDIDNOTSUPP (73 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSSERVICERUNNING (74 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_BUSY (75 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_FAULT (76 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_TIMEOUT (77 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESETTIMEOUT (78 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_NODATAEXCH (79 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESET (80 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDADDR (81 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDPORT (82 + ERR_IOERRS) +#define IOERR_AMSDEVICEBADBOXNO (83 + ERR_IOERRS) +#define IOERR_AMSDEVICEBADTYPE (84 + ERR_IOERRS) +#define IOERR_AMSDEVICEILLEGALADDRESS (85 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDBOX (86 + ERR_IOERRS) +#define IOERR_AMSDEVICEFIFOOVERFLOW (87 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSSEQUENCEERROR (88 + ERR_IOERRS) +#define IOERR_CP5412A2DPV1SYNTAXERROR (89 + ERR_IOERRS) +#define IOERR_CP5412A2DEVICENOTRUNNING (90 + ERR_IOERRS) +#define IOERR_AMSDEVICENOTRUNNING (91 + ERR_IOERRS) +#define IOERR_AMSDEVICEBOXNOTDEFINED (92 + ERR_IOERRS) +#define IOERR_CP5412A2BADSERVICEPARA (93 + ERR_IOERRS) +#define IOERR_CP5412A2FIFOOVERFLOW (94 + ERR_IOERRS) +#define IOERR_COMPORTOPENFAILED (95 + ERR_IOERRS) +#define IOERR_CIF30BADMESSAGERESPONSE (96 + ERR_IOERRS) +#define IOERR_CIF30DELETEDATABASE (97 + ERR_IOERRS) +#define IOERR_CIF30STARTSEQFAILED (98 + ERR_IOERRS) +#define IOERR_CIF30DOWNLOADFAILED (99 + ERR_IOERRS) +#define IOERR_CIF30ENDSEQFAILED (100 + ERR_IOERRS) +#define IOERR_CIF30BUSLOADFAILED (101 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESETREQ (102 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDCYCLETICKS (103 + ERR_IOERRS) +#define IOERR_CP5412A2DPBUSFAULT (104 + ERR_IOERRS) +#define IOERR_INVALIDTERMCONFIG (105 + ERR_IOERRS) +#define IOERR_SERCANSBREAK (106 + ERR_IOERRS) +#define IOERR_SERCANSPHASE0 (107 + ERR_IOERRS) +#define IOERR_SERCANSPHASE1 (108 + ERR_IOERRS) +#define IOERR_SERCANSPHASE2 (109 + ERR_IOERRS) +#define IOERR_SERCANSPHASE3 (110 + ERR_IOERRS) +#define IOERR_SERCANSPHASE4 (111 + ERR_IOERRS) +#define IOERR_SERCANSNCSERVICECHNFAILED (112 + ERR_IOERRS) +#define IOERR_RESOURCECONFICT (113 + ERR_IOERRS) +#define IOERR_C1220INITSTRINGCOMM (114 + ERR_IOERRS) +#define IOERR_C1220REGSTRINGSLAVE (115 + ERR_IOERRS) +#define IOERR_C1220STRREGFAULT (116 + ERR_IOERRS) +#define IOERR_IOSTATEBUSY (117 + ERR_IOERRS) +#define IOERR_IBSSCITWATCHDOGEXPIRED (118 + ERR_IOERRS) +#define IOERR_IBSSCITSYNCMAILBOXERROR (119 + ERR_IOERRS) +#define IOERR_IBSSCITCONFIRMDIAGERROR (120 + ERR_IOERRS) +#define IOERR_IBSSCITCREATECFGERROR (121 + ERR_IOERRS) +#define IOERR_IBSSCITCOMPLETEREADCFGERROR (122 + ERR_IOERRS) +#define IOERR_IBSSCITSTARTDATATRANSFERERROR (123 + ERR_IOERRS) +#define IOERR_IBSSCITSETFAULTINDICATION (124 + ERR_IOERRS) +#define IOERR_IBSSCITSETDEVICESTATEINDICATION (125 + ERR_IOERRS) +#define IOERR_IBSSCITSETBUSERRORINDICATION (126 + ERR_IOERRS) +#define IOERR_IBSSCITSTOPDATATRANSFERERROR (127 + ERR_IOERRS) +#define IOERR_IBSSCITSETVALUEINDICATION (128 + ERR_IOERRS) +#define IOERR_IBSSCITINITIATEREQ (129 + ERR_IOERRS) +#define IOERR_IBSSCITACTIVATECFGERROR (130 + ERR_IOERRS) +#define IOERR_IBSSCITCOMPACTLOADPDRLERROR (131 + ERR_IOERRS) +#define IOERR_IBSSCITCONTROLPARAMERROR (132 + ERR_IOERRS) +#define IOERR_IBSSCITDEACTIVATECFGERROR (133 + ERR_IOERRS) +#define IOERR_IBSSCITINVALIDPORT (134 + ERR_IOERRS) +#define IOERR_C1220FUNC_7_ADDRESSTEST (135 + ERR_IOERRS) +#define IOERR_FCXXXXMAILBOXUSED (136 + ERR_IOERRS) +#define IOERR_FCXXXXDPRAMTOOSMALL (137 + ERR_IOERRS) +#define IOERR_COMUPS_PORTINUSE (138 + ERR_IOERRS) +#define IOERR_COMUPS_NOUPSORNOPOWER (139 + ERR_IOERRS) +#define IOERR_COMUPS_LOWBATTERY (140 + ERR_IOERRS) +#define IOERR_UPS_ALREADY_EXISTS (141 + ERR_IOERRS) +#define IOERR_FCXXXXSTARTUPFAILED (142 + ERR_IOERRS) +#define IOERR_C1220GETSTRINGCOMMTXSTATEFAILED (143 + ERR_IOERRS) +#define IOERR_C1220SENDSTRINGTOSLAVEFAILED (144 + ERR_IOERRS) +#define IOERR_CP5613FIRMWARELOADFAILED (145 + ERR_IOERRS) +#define IOERR_CP5613DPOPENFAILED (146 + ERR_IOERRS) +#define IOERR_CP5613FATALERROR (147 + ERR_IOERRS) +#define IOERR_CP5613DPUSEROPENFAILED (148 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODESTOPFAILED (149 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODECLEARFAILED (150 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODEOPERATEFAILED (151 + ERR_IOERRS) +#define IOERR_CP5613NODATAAVAILABLE (152 + ERR_IOERRS) +#define IOERR_CP5613DPSERVICEFAILED (153 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODEOFFLINEFAILED (154 + ERR_IOERRS) +#define IOERR_CP5613DPUSERCLOSEFAILED (155 + ERR_IOERRS) +#define IOERR_CP5613DPCLOSEFAILED (156 + ERR_IOERRS) +#define IOERR_CP5613OTHERSERVICERETURNED (157 + ERR_IOERRS) +#define IOERR_CP5613DPOKASYNC (158 + ERR_IOERRS) +#define IOERR_CP5613DPERROREVENT (159 + ERR_IOERRS) +#define IOERR_CP5613DPERROREVENTNET (160 + ERR_IOERRS) +#define IOERR_CP5613DPERRORREQPAR (161 + ERR_IOERRS) +#define IOERR_CP5613DPERRORCI (162 + ERR_IOERRS) +#define IOERR_CP5613DPERRORRES (163 + ERR_IOERRS) +#define IOERR_CP5613DPERRORUSRABORT (164 + ERR_IOERRS) +#define IOERR_PKWSYNTAXERROR (165 + ERR_IOERRS) +#define IOERR_CP5412A2CDLCFGFAULT (166 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADCFGERROR (168 + ERR_IOERRS) +#define IOERR_IBSSCITLOADCFGERROR (169 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADCFGERROR (170 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADPDRLERROR (171 + ERR_IOERRS) +#define IOERR_IBSSCITLOADPDRLERROR (172 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADPDRLERROR (173 + ERR_IOERRS) +#define IOERR_IBSSCITDELETEOBJECTERROR (174 + ERR_IOERRS) +#define IOERR_IBSSCITCONTROLACTIVECFGGERROR (175 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADPDDLERROR (176 + ERR_IOERRS) +#define IOERR_IBSSCITLOADPDDLERROR (177 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADPDDLERROR (178 + ERR_IOERRS) +#define IOERR_NOMOREMAPSINIMAGE (179 + ERR_IOERRS) +#define IOERR_IBSSCITSETSLAVEINFOERROR (180 + ERR_IOERRS) +#define IOERR_CIF40NOTREADY (190 + ERR_IOERRS) +#define IOERR_C1220SETAMSNETIDFAILED (191 + ERR_IOERRS) +#define IOERR_AMSDEVICEIORESETACTIVE (192 + ERR_IOERRS) +#define IOERR_C1220INITPROGRAMMABLECDL (193 + ERR_IOERRS) +#define IOERR_FCXXXXINVALIDBOXNODOWNLOADED (194 + ERR_IOERRS) + + +#define IOERR_CP5412A2_RESET (4 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADBUSPARA (5 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADSLAVE (6 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADPRMDATA (7 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADCFGDATA (8 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADSLAVECDL (9 + ERR_CP5412A2) +#define IOERR_CP5412A2_ACTIVATESLAVE (10 + ERR_CP5412A2) +#define IOERR_CP5412A2_ADDSLAVE (11 + ERR_CP5412A2) +#define IOERR_CP5412A2_DELETESLAVE (12 + ERR_CP5412A2) +#define IOERR_CP5412A2_STARTDATAEXCH (13 + ERR_CP5412A2) +#define IOERR_CP5412A2_STOPDATAEXCH (14 + ERR_CP5412A2) +#define IOERR_CP5412A2_DEBUGDPM (15 + ERR_CP5412A2) + + +/* FC Box - stamndadisiert */ + +#define FCERR_FMNOERROR 0 +#define FCERR_FMDEACTIVATED 1 +#define FCERR_FMNOANSWER 2 +#define FCERR_FMMASTERLOCK 3 +#define FCERR_FMINVALIDRESPONSE 4 +#define FCERR_FMPRMFAULT 5 +#define FCERR_FMFEATURENOTSUPPORTED 6 +#define FCERR_FMCFGFAULT 7 +#define FCERR_FMSTATIONNOTREADY 8 +#define FCERR_FMSTATDIAG 9 +#define FCERR_FMDIAGOVERFLOW 10 +#define FCERR_FMPHYSICALFAULT 11 +#define FCERR_FMDATATRANSFERLEFT 12 +#define FCERR_FMSYNIFAULT 13 +#define FCERR_FMTELEGRAMFAULT 14 +#define FCERR_FMNORESSOURCES 15 +#define FCERR_FMSERVICENOTACTIVATED 16 +#define FCERR_FMUNEXPECTEDTELEGRAM 17 +#define FCERR_FMSTATIONREADY 18 +#define FCERR_FMADSSTARTUP 19 +#define FCERR_FMINVALIDINDICATION 20 +#define FCERR_FMSTATIONINFAULT 21 +#define FCERR_FMINDICATIONMISSED 22 +#define FCERR_FMWAITFORINDICATIONS 23 + +#define FCERR_FMFBUSSPECIFIC_1 40 +#define FCERR_FMFBUSSPECIFIC_2 41 +#define FCERR_FMFBUSSPECIFIC_3 42 +#define FCERR_FMFBUSSPECIFIC_4 43 +#define FCERR_FMFBUSSPECIFIC_5 44 +#define FCERR_FMFBUSSPECIFIC_6 45 +#define FCERR_FMFBUSSPECIFIC_7 46 +#define FCERR_FMFBUSSPECIFIC_8 47 +#define FCERR_FMFBUSSPECIFIC_9 48 + + +/* FC520x */ + +#define FCERR_FMFC520XHEARTBEATFAULT 40 +#define FCERR_FMFC520XSHUTDOWNRECEIVED 41 +#define FCERR_FMFC520XEKEYERROR_VENDOR 42 +#define FCERR_FMFC520XEKEYERROR_DEVTYPE 43 +#define FCERR_FMFC520XEKEYERROR_PRODCODE 44 +#define FCERR_FMFC520XEKEYERROR_REVISION 45 +#define FCERR_FMFC520XSTARTUPATTR 46 +#define FCERR_FMFC520XIOLENGTH_PROD 47 +#define FCERR_FMFC520XIOLENGTH_CONS 48 + +#define FCERR_FMFC520XDEVICEOPERATE_RUN 0 +#define FCERR_FMFC520XDEVICEOPERATE_IDLE 1 +#define FCERR_FMFC520XDEVICEDUPMAC 2 +#define FCERR_FMFC520XDEVICESELFTEST 3 +#define FCERR_FMFC520XDEVICESTANDBY 4 +#define FCERR_FMFC520XDEVICEMAJORFAULT 5 +#define FCERR_FMFC520XDEVICEMINORFAULT 6 +#define FCERR_FMFC520XDEVICEBUSSENSEFAIL 7 + +#define FCERR_FMFC520XCANBUSON 0x01 +#define FCERR_FMFC520XCANBUSOFF 0x02 +#define FCERR_FMFC520XCANWARNINGLIMIT 0x04 +#define FCERR_FMFC520XCANOVERRUN 0x08 + + +/* DP-Slave-Errors */ + +#define DPSLAVEERROR_NOERROR (FCERR_FMNOERROR + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONDEACTIVATED (FCERR_FMDEACTIVATED + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONNONEXISTENT (FCERR_FMNOANSWER + ERR_DPSLAVE) +#define DPSLAVEERROR_MASTERLOCK (FCERR_FMMASTERLOCK + ERR_DPSLAVE) +#define DPSLAVEERROR_INVALIDSLAVERESPONSE (FCERR_FMINVALIDRESPONSE + ERR_DPSLAVE) +#define DPSLAVEERROR_PRMFAULT (FCERR_FMPRMFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_NOTSUPPORTED (FCERR_FMFEATURENOTSUPPORTED + ERR_DPSLAVE) +#define DPSLAVEERROR_CFGFAULT (FCERR_FMCFGFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONNOTREADY (FCERR_FMSTATIONNOTREADY + ERR_DPSLAVE) +#define DPSLAVEERROR_STATDIAG (FCERR_FMSTATDIAG + ERR_DPSLAVE) +#define DPSLAVEERROR_DIAGOVERFLOW (FCERR_FMDIAGOVERFLOW + ERR_DPSLAVE) +#define DPSLAVEERROR_PHYSICALFAULT (FCERR_FMPHYSICALFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_TELEGRAMFAULT (FCERR_FMTELEGRAMFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_NORESSOURCES (FCERR_FMNORESSOURCES + ERR_DPSLAVE) +#define DPSLAVEERROR_SERVICENOTACTIVATED (FCERR_FMSERVICENOTACTIVATED + ERR_DPSLAVE) +#define DPSLAVEERROR_UNEXPECTEDTELEGRAM (FCERR_FMUNEXPECTEDTELEGRAM + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONREADY (FCERR_FMSTATIONREADY + ERR_DPSLAVE) +#define DPSLAVEERROR_ADSSTARTUP (FCERR_FMADSSTARTUP + ERR_DPSLAVE) + + +/* CAN-Node-Errors */ + +#define CANNODEERROR_NOERROR (0 + ERR_CANSLAVE) +#define CANNODEERROR_STATIONNONEXISTENT (1 + ERR_CANSLAVE) +#define CANNODEERROR_PRMFAULT (4 + ERR_CANSLAVE) +#define CANNODEERROR_CFGFAULT (6 + ERR_CANSLAVE) +#define CANNODEERROR_DEACTIVATED (8 + ERR_CANSLAVE) +#define CANNODEERROR_PREOPERATIONAL (12 + ERR_CANSLAVE) +#define CANNODEERROR_NOT_OPERATIONAL (13 + ERR_CANSLAVE) + + +/* IBS-Device-Errors */ + +#define IBSDEVICEERROR_NOERROR (0 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_STATIONDEACTIVATED (1 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_STATIONNONEXISTENT (2 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_CFGFAULT (6 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_DIAGOVERFLOW (10 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_PHYSICALFAULT (11 + ERR_IBSSLAVE) + + +/* PLC */ +#define PLCWRN_LOADINGBOOTPRJ ((0 + ERR_PLCERRS) | AMSERRCODEISWARNING) +#define PLCWRN_LOADINGRETAINDATA ((1 + ERR_PLCERRS) | AMSERRCODEISWARNING) + + +/* NC */ +#define ERR_NCR0MANERRS (ERR_NCERRS+0x0000) +#define ERR_NCCHNERRS (ERR_NCERRS+0x0100) + + +/* NC: R0-Manager Error Codes */ +#define NCERR_INTERNAL (0x0000 + ERR_NCR0MANERRS) +#define NCERR_NOMEMORY (0x0001 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNCHANNELID (0x0010 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNGROUPID (0x0011 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNAXISID (0x0012 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCODERID (0x0013 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNCONTROLLERID (0x0014 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEID (0x0015 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNTABULARID (0x0016 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNPLCTONCADDR (0x0020 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNNCTOPLCADDR (0x0021 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCINADDR (0x0022 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCOUTADDR (0x0023 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEINADDR (0x0024 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEOUTADDR (0x0025 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNDSLAVETYPE (0x0030 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNAXISTYPE (0x0031 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNCHNTYPE (0x0032 + ERR_NCR0MANERRS) + +#define NCERR_AXISINCOMPATIBLE (0x0040 + ERR_NCR0MANERRS) + +#define NCERR_CHANNELINCOMPLETE (0x0050 + ERR_NCR0MANERRS) +#define NCERR_GROUPINCOMPLETE (0x0051 + ERR_NCR0MANERRS) +#define NCERR_AXISINCOMPLETE (0x0052 + ERR_NCR0MANERRS) + +#define NCERR_CHANNELEXISTS (0x0060 + ERR_NCR0MANERRS) +#define NCERR_GROUPEXISTS (0x0061 + ERR_NCR0MANERRS) +#define NCERR_AXISEXISTS (0x0062 + ERR_NCR0MANERRS) +#define NCERR_TABULAREXISTS (0x0063 + ERR_NCR0MANERRS) + +#define NCERR_WRONGCHANNELINDEX (0x0070 + ERR_NCR0MANERRS) +#define NCERR_WRONGGROUPINDEX (0x0071 + ERR_NCR0MANERRS) + + +/* Channel Error Codes */ +#define NCCHNERR_GROUPINDEX (0x0001 + ERR_NCCHNERRS) +#define NCCHNERR_ADDR_GROUP (0x0002 + ERR_NCCHNERRS) +#define NCCHNERR_NO_PLCINTERFACE (0x0003 + ERR_NCCHNERRS) +#define NCCHNERR_ILLEGALMFUNCNR (0x0004 + ERR_NCCHNERRS) +#define NCCHNERR_NOMEMORY (0x0005 + ERR_NCCHNERRS) +#define NCCHNERR_ISBUSY (0x0006 + ERR_NCCHNERRS) +#define NCCHNERR_NOTSUPPORTED (0x0007 + ERR_NCCHNERRS) +#define NCCHNERR_ILLEGALSETTING (0x0008 + ERR_NCCHNERRS) + +#define NCCHNERR_NOFILE (0x0010 + ERR_NCCHNERRS) +#define NCCHNERR_ITPSYNTAXLT (0x0011 + ERR_NCCHNERRS) +#define NCCHNERR_ITPSYNTAXRT (0x0012 + ERR_NCCHNERRS) +#define NCCHNERR_SUBNOTFOUND (0x0013 + ERR_NCCHNERRS) +#define NCCHNERR_LOADBUFFERFULL (0x0014 + ERR_NCCHNERRS) +#define NCCHNERR_INVALIDIDENTIFIER (0x0015 + ERR_NCCHNERRS) +#define NCCHNERR_UNKNOWNIDENTIFIER (0x0016 + ERR_NCCHNERRS) +#define NCCHNERR_SUBINCOMPLETE (0x0017 + ERR_NCCHNERRS) + +#define NCCHNERR_ZERODIVIDE (0x0020 + ERR_NCCHNERRS) +#define NCCHNERR_BADCIRCLE (0x0021 + ERR_NCCHNERRS) +#define NCCHNERR_INVALIDOPERATION (0x0022 + ERR_NCCHNERRS) + +#define NCCHNERR_CALLSTACKOVR (0x0030 + ERR_NCCHNERRS) +#define NCCHNERR_CALLSTACKUDR (0x0031 + ERR_NCCHNERRS) +#define NCCHNERR_CALCSTACKOVR (0x0032 + ERR_NCCHNERRS) +#define NCCHNERR_CALCSTACKUDR (0x0033 + ERR_NCCHNERRS) + +#define NCCHNERR_REGINDEX (0x0040 + ERR_NCCHNERRS) +#define NCCHNERR_GFUNCINDEX (0x0041 + ERR_NCCHNERRS) +#define NCCHNERR_MFUNCINDEX (0x0042 + ERR_NCCHNERRS) +#define NCCHNERR_EXTENDEDADDR (0x0043 + ERR_NCCHNERRS) +#define NCCHNERR_INTERNALINDEXH (0x0044 + ERR_NCCHNERRS) +#define NCCHNERR_MDBACCESSINDEX (0x0045 + ERR_NCCHNERRS) + +#define NCTRAFOERR_CANNOTCHANGE (0x0050 + ERR_NCCHNERRS) +#define NCTRAFOERR_CANNOTCORRECT (0x0051 + ERR_NCCHNERRS) +#define NCTRAFOERR_PLANE (0x0052 + ERR_NCCHNERRS) +#define NCTRAFOERR_DPARAMINVALID (0x0053 + ERR_NCCHNERRS) +#define NCTRAFOERR_TOOLRADIUSINV (0x0054 + ERR_NCCHNERRS) +#define NCTRAFOERR_CHANGETOOLRAD (0x0055 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDOVERFLOW (0x0056 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDON (0x0057 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDCHECK (0x0058 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDUNEXPECTED (0x0059 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDNEGRADIUS (0x005A + ERR_NCCHNERRS) +#define NCTRAFOERR_CDOCCURED (0x005B + ERR_NCCHNERRS) +#define NCTRAFOERR_COOKEDTBLFULL (0x005C + ERR_NCCHNERRS) +#define NCTRAFOERR_TFTBLFULL (0x005D + ERR_NCCHNERRS) +#define NCTRAFOERR_EXECTFTBLFULL (0x005E + ERR_NCCHNERRS) +#define NCTRAFOERR_EXECTFT (0x005F + ERR_NCCHNERRS) + +#define NCBACKUPERR_WRITEDATA (0x0060 + ERR_NCCHNERRS) +#define NCBACKUPERR_TARGETENTRY (0x0061 + ERR_NCCHNERRS) + + +#define MACHINEIDENTRYDONTCARE 0xFF +#define AMS_NETIDLEN 23 + +typedef struct AmsNetId_ +{ + guint8 b[6]; +} AmsNetId; +#define AmsNetId_Len (int)sizeof(AmsNetId) + +typedef struct AmsAddr_ +{ + AmsNetId netId; + guint16 port; +} AmsAddr; + +typedef union ErrCodeUnion +{ + gint32 errCode; + gint32 hRcv; +} ErrCodeUnion; + +typedef union tUserUnion +{ + gint32 hUser; + struct + { + guint16 fragmentNo; + guint16 packetNo; + } a; +} UserUnion; + +typedef struct +{ + AmsAddr target; + AmsAddr sender; + guint16 cmdId; + guint16 stateFlags; + guint32 cbData; + + ErrCodeUnion anErrCodeUnion; + UserUnion aUserUnion; +} AmsHead; +#define AmsHead_Len (int)sizeof(AmsHead) + + +/* State flags */ + +#define AMSCMDSF_RESPONSE 0x0001 +#define AMSCMDSF_NORETURN 0x0002 +#define AMSCMDSF_ADSCMD 0x0004 +#define AMSCMDSF_SYSCMD 0x0008 +#define AMSCMDSF_HIGHPRIO 0x0010 +#define AMSCMDSF_TIMESTAMPADDED 0x0020 +#define AMSCMDSF_UDP 0x0040 +#define AMSCMDSF_INITCMD 0x0080 +#define AMSCMDSF_BROADCAST 0x8000 + + +/* AmsCmd */ + +typedef struct +{ + AmsHead head; +} AmsCmd, *PAmsCmd; + + +/* ADS */ + +#define ADS_FIXEDNAMESIZE 16 + + +/* ADS Service Ids */ +#define ADSSRVID_INVALID 0x00 +#define ADSSRVID_READDEVICEINFO 0x01 +#define ADSSRVID_READ 0x02 +#define ADSSRVID_WRITE 0x03 +#define ADSSRVID_READSTATE 0x04 +#define ADSSRVID_WRITECTRL 0x05 +#define ADSSRVID_ADDDEVICENOTE 0x06 +#define ADSSRVID_DELDEVICENOTE 0x07 +#define ADSSRVID_DEVICENOTE 0x08 +#define ADSSRVID_READWRITE 0x09 + +/* ADS reserved index groups */ +#define ADSIGRP_SYMTAB 0xF000 +#define ADSIGRP_SYMNAME 0xF001 +#define ADSIGRP_SYMVAL 0xF002 + +#define ADSIGRP_SYM_HNDBYNAME 0xF003 +#define ADSIGRP_SYM_VALBYNAME 0xF004 +#define ADSIGRP_SYM_VALBYHND 0xF005 +#define ADSIGRP_SYM_RELEASEHND 0xF006 +#define ADSIGRP_SYM_INFOBYNAME 0xF007 +#define ADSIGRP_SYM_VERSION 0xF008 +#define ADSIGRP_SYM_INFOBYNAMEEX 0xF009 + +#define ADSIGRP_SYM_DOWNLOAD 0xF00A +#define ADSIGRP_SYM_UPLOAD 0xF00B +#define ADSIGRP_SYM_UPLOADINFO 0xF00C +#define ADSIGRP_SYM_DOWNLOAD2 0xF00D +#define ADSIGRP_SYM_DT_UPLOAD 0xF00E +#define ADSIGRP_SYM_UPLOADINFO2 0xF00F + +#define ADSIGRP_SYMNOTE 0xF010 + +#define ADSIGRP_SYM_DT_INFOBYNAMEEX 0xF011 +#define ADSIGRP_SYM_ADDRBYHND 0xF012 + + +#define ADSIGRP_IOIMAGE_RWIB 0xF020 +#define ADSIGRP_IOIMAGE_RWIX 0xF021 +#define ADSIGRP_IOIMAGE_RISIZE 0xF025 + +#define ADSIGRP_IOIMAGE_RWOB 0xF030 +#define ADSIGRP_IOIMAGE_RWOX 0xF031 +#define ADSIGRP_IOIMAGE_ROSIZE 0xF035 +#define ADSIGRP_IOIMAGE_CLEARI 0xF040 +#define ADSIGRP_IOIMAGE_CLEARO 0xF050 + +#define ADSIGRP_IOIMAGE_RWIOB 0xF060 + +#define ADSIGRP_IOIMAGE_CREATE 0xF068 + +#define ADSIGRP_SUMUP_READ 0xF080 + +#define ADSIGRP_SUMUP_WRITE 0xF081 +#define ADS_SUMUP_IGRP(p, i) (((guint32*)p)[(i)*3+0]) +#define ADS_SUMUP_IOFFS(p, i) (((guint32*)p)[(i)*3+1]) +#define ADS_SUMUP_LENGTH(p, i) (((guint32*)p)[(i)*3+2]) + +#define ADSIGRP_DEVICE_DATA 0xF100 + #define ADSIOFFS_DEVDATA_ADSSTATE 0x0000 + #define ADSIOFFS_DEVDATA_DEVSTATE 0x0002 + #define ADSIOFFS_DEVDATA_CONFIGID 0x0004 + #define ADSIOFFS_DEVDATA_ADSVERSIONCHECK 0x0005 + +#define ADSIGRP_TASK_DATA 0xF200 +/* ADSIGRP_TASK_DATA reserved until 0xF2FF*/ + +#define ADSIGRP_CANOPEN_BEGIN 0xF300 +#define ADSIGRP_CANOPEN_SDO 0xF302 +#define ADSIGRP_CANOPEN_SDO_INFO_LIST 0xF3FC +#define ADSIGRP_CANOPEN_SDO_INFO_OBJ 0xF3FD +#define ADSIGRP_CANOPEN_SDO_INFO_ENTRY 0xF3FE +#define ADSIGRP_CANOPEN_END 0xF3FF + +#define ADSIGRP_ECAT_FOE_BEGIN 0xF400 +#define ADSIGRP_ECAT_FOE_FOPENREAD 0xF401 +#define ADSIGRP_ECAT_FOE_FOPENWRITE 0xF402 +#define ADSIGRP_ECAT_FOE_FCLOSE 0xF403 +#define ADSIGRP_ECAT_FOE_FREAD 0xF404 +#define ADSIGRP_ECAT_FOE_FWRITE 0xF405 +#define ADSIGRP_ECAT_FOE_PROGRESSINFO 0xF406 +#define ADSIGRP_ECAT_FOE_END 0xF41F + +#define ADSIGRP_ECAT_SOE 0xF420 + #define ADSIOFFS_ECAT_SOE_ELEMENT_MASK 0x00FF0000 + #define ADSIOFFS_ECAT_SOE_DATASTATE 0x00010000 + #define ADSIOFFS_ECAT_SOE_NAME 0x00020000 + #define ADSIOFFS_ECAT_SOE_ATTRIBUTE 0x00040000 + #define ADSIOFFS_ECAT_SOE_UNIT 0x00080000 + #define ADSIOFFS_ECAT_SOE_MIN 0x00100000 + #define ADSIOFFS_ECAT_SOE_MAX 0x00200000 + #define ADSIOFFS_ECAT_SOE_VALUE 0x00400000 + #define ADSIOFFS_ECAT_SOE_DEFAULT 0x00800000 + #define ADSIOFFS_ECAT_SOE_DRIVENO_MASK 0x07000000 + #define ADSIOFFS_ECAT_SOE_COMMAND 0x08000000 + +#define ADSIGRP_ECAT_VOE 0xF430 + + +typedef enum nAdsState +{ + ADSSTATE_INVALID =0, + ADSSTATE_IDLE =1, + ADSSTATE_RESET =2, + ADSSTATE_INIT =3, + ADSSTATE_START =4, + ADSSTATE_RUN =5, + ADSSTATE_STOP =6, + ADSSTATE_SAVECFG =7, + ADSSTATE_LOADCFG =8, + ADSSTATE_POWERFAILURE =9, + ADSSTATE_POWERGOOD =10, + ADSSTATE_ERROR =11, + ADSSTATE_SHUTDOWN =12, + ADSSTATE_SUSPEND =13, + ADSSTATE_RESUME =14, + ADSSTATE_CONFIG =15, + ADSSTATE_RECONFIG =16, + ADSSTATE_MAXSTATES +} ADSSTATE; + +typedef enum nAdsTransMode +{ + ADSTRANS_NOTRANS =0, + ADSTRANS_CLIENTCYCLE =1, + ADSTRANS_CLIENTONCHA =2, + ADSTRANS_SERVERCYCLE =3, + ADSTRANS_SERVERONCHA =4, + ADSTRANS_CLIENT1REQ =10, + ADSTRANS_MAXMODES +}ADSTRANSMODE; + + +/* ADS error codes */ +#define ADSERR_NOERR 0x00 + +#define ADSERR_DEVICE_ERROR (0x700) +#define ADSERR_DEVICE_SRVNOTSUPP (0x701) +#define ADSERR_DEVICE_INVALIDGRP (0x702) +#define ADSERR_DEVICE_INVALIDOFFSET (0x703) +#define ADSERR_DEVICE_INVALIDACCESS (0x704) +#define ADSERR_DEVICE_INVALIDSIZE (0x705) +#define ADSERR_DEVICE_INVALIDDATA (0x706) +#define ADSERR_DEVICE_NOTREADY (0x707) +#define ADSERR_DEVICE_BUSY (0x708) +#define ADSERR_DEVICE_INVALIDCONTEXT (0x709) +#define ADSERR_DEVICE_NOMEMORY (0x70A) +#define ADSERR_DEVICE_INVALIDPARM (0x70B) +#define ADSERR_DEVICE_NOTFOUND (0x70C) +#define ADSERR_DEVICE_SYNTAX (0x70D) +#define ADSERR_DEVICE_INCOMPATIBLE (0x70E) +#define ADSERR_DEVICE_EXISTS (0x70F) +#define ADSERR_DEVICE_SYMBOLNOTFOUND (0x710) +#define ADSERR_DEVICE_SYMBOLVERSIONINVALID (0x711) +#define ADSERR_DEVICE_INVALIDSTATE (0x712) +#define ADSERR_DEVICE_TRANSMODENOTSUPP (0x713) +#define ADSERR_DEVICE_NOTIFYHNDINVALID (0x714) +#define ADSERR_DEVICE_CLIENTUNKNOWN (0x715) +#define ADSERR_DEVICE_NOMOREHDLS (0x716) +#define ADSERR_DEVICE_INVALIDWATCHSIZE (0x717) +#define ADSERR_DEVICE_NOTINIT (0x718) +#define ADSERR_DEVICE_TIMEOUT (0x719) +#define ADSERR_DEVICE_NOINTERFACE (0x71A) +#define ADSERR_DEVICE_INVALIDINTERFACE (0x71B) +#define ADSERR_DEVICE_INVALIDCLSID (0x71C) +#define ADSERR_DEVICE_INVALIDOBJID (0x71D) +#define ADSERR_DEVICE_PENDING (0x71E) +#define ADSERR_DEVICE_ABORTED (0x71F) +#define ADSERR_DEVICE_WARNING (0x720) +#define ADSERR_DEVICE_INVALIDARRAYIDX (0x721) +#define ADSERR_DEVICE_SYMBOLNOTACTIVE (0x722) +#define ADSERR_DEVICE_ACCESSDENIED (0x723) + +#define ADSERR_CLIENT_ERROR (0x740) +#define ADSERR_CLIENT_INVALIDPARM (0x741) +#define ADSERR_CLIENT_LISTEMPTY (0x742) +#define ADSERR_CLIENT_VARUSED (0x743) +#define ADSERR_CLIENT_DUPLINVOKEID (0x744) +#define ADSERR_CLIENT_SYNCTIMEOUT (0x745) +#define ADSERR_CLIENT_W32ERROR (0x746) +#define ADSERR_CLIENT_TIMEOUTINVALID (0x747) +#define ADSERR_CLIENT_PORTNOTOPEN (0x748) +#define ADSERR_CLIENT_NOAMSADDR (0x749) +#define ADSERR_CLIENT_SYNCINTERNAL (0x750) +#define ADSERR_CLIENT_ADDHASH (0x751) +#define ADSERR_CLIENT_REMOVEHASH (0x752) +#define ADSERR_CLIENT_NOMORESYM (0x753) +#define ADSERR_CLIENT_SYNCRESINVALID (0x754) +#define ADSERR_CLIENT_SYNCPORTLOCKED (0x755) + + +#define FACILITY_TC_ADS 0x1811 +#define FACILITY_TC_CNC 0x1821 +#define FACILITY_TC_IO 0x1831 + + +#if 0 /* Unused ?? */ +#define ADS_E_ERROR (0x98110000L + ADSERR_DEVICE_ERROR) +#define ADS_E_SRVNOTSUPP (0x98110000L + ADSERR_DEVICE_SRVNOTSUPP) +#define ADS_E_INVALIDGRP (0x98110000L + ADSERR_DEVICE_INVALIDGRP) +#define ADS_E_INVALIDOFFSET (0x98110000L + ADSERR_DEVICE_INVALIDOFFSET) +#define ADS_E_INVALIDACCESS (0x98110000L + ADSERR_DEVICE_INVALIDACCESS) +#define ADS_E_INVALIDSIZE (0x98110000L + ADSERR_DEVICE_INVALIDSIZE) +#define ADS_E_INVALIDDATA (0x98110000L + ADSERR_DEVICE_INVALIDDATA) +#define ADS_E_NOTREADY (0x98110000L + ADSERR_DEVICE_NOTREADY) +#define ADS_E_BUSY (0x98110000L + ADSERR_DEVICE_BUSY) +#define ADS_E_INVALIDCONTEXT (0x98110000L + ADSERR_DEVICE_INVALIDCONTEXT) +#define ADS_E_NOMEMORY (0x98110000L + ADSERR_DEVICE_NOMEMORY) +#define ADS_E_INVALIDPARM (0x98110000L + ADSERR_DEVICE_INVALIDPARM) +#define ADS_E_NOTFOUND (0x98110000L + ADSERR_DEVICE_NOTFOUND) +#define ADS_E_SYNTAX (0x98110000L + ADSERR_DEVICE_SYNTAX) +#define ADS_E_INCOMPATIBLE (0x98110000L + ADSERR_DEVICE_INCOMPATIBLE) +#define ADS_E_EXISTS (0x98110000L + ADSERR_DEVICE_EXISTS) +#define ADS_E_SYMBOLNOTFOUND (0x98110000L + ADSERR_DEVICE_SYMBOLNOTFOUND) +#define ADS_E_SYMBOLVERSIONINVALID (0x98110000L + ADSERR_DEVICE_SYMBOLVERSIONINVALID) +#define ADS_E_INVALIDSTATE (0x98110000L + ADSERR_DEVICE_INVALIDSTATE) +#define ADS_E_TRANSMODENOTSUPP (0x98110000L + ADSERR_DEVICE_TRANSMODENOTSUPP) +#define ADS_E_NOTIFYHNDINVALID (0x98110000L + ADSERR_DEVICE_NOTIFYHNDINVALID) +#define ADS_E_CLIENTUNKNOWN (0x98110000L + ADSERR_DEVICE_CLIENTUNKNOWN) +#define ADS_E_NOMOREHDLS (0x98110000L + ADSERR_DEVICE_NOMOREHDLS) +#define ADS_E_INVALIDWATCHSIZE (0x98110000L + ADSERR_DEVICE_INVALIDWATCHSIZE) +#define ADS_E_NOTINIT (0x98110000L + ADSERR_DEVICE_NOTINIT) +#define ADS_E_TIMEOUT (0x98110000L + ADSERR_DEVICE_TIMEOUT) +#define ADS_E_NOINTERFACE (0x98110000L + ADSERR_DEVICE_NOINTERFACE) +#define ADS_E_INVALIDINTERFACE (0x98110000L + ADSERR_DEVICE_INVALIDINTERFACE) +#define ADS_E_INVALIDCLSID (0x98110000L + ADSERR_DEVICE_INVALIDCLSID) +#define ADS_E_INVALIDOBJID (0x98110000L + ADSERR_DEVICE_INVALIDOBJID) +#define ADS_E_PENDING (0x98110000L + ADSERR_DEVICE_PENDING) +#define ADS_E_ABORTED (0x98110000L + ADSERR_DEVICE_ABORTED) +#define ADS_E_WARNING (0x98110000L + ADSERR_DEVICE_WARNING) +#define ADS_E_INVALIDARRAYIDX (0x98110000L + ADSERR_DEVICE_INVALIDARRAYIDX) +#define ADS_E_SYMBOLNOTACTIVE (0x98110000L + ADSERR_DEVICE_SYMBOLNOTACTIVE) +#define ADS_E_ACCESSDENIED (0x98110000L + ADSERR_DEVICE_ACCESSDENIED) +#endif + +#ifndef ANYSIZE_ARRAY + #define ANYSIZE_ARRAY 1 +#endif + +/* ADS AMS command */ +/*typedef struct +{ + guint32 hNotification; + guint32 cbSampleSize; + guint8 data[ANYSIZE_ARRAY]; +} AdsNotificationSample, *PAdsNotificationSample;*/ +#define AdsNotificationSample_Min_Len 4 + +typedef struct +{ + guint32 invokeId; +} TAdsReadDeviceInfoReq; + +#define TAdsReadDeviceInfoReq_Len (int)sizeof(TAdsReadDeviceInfoReq) + +/*typedef struct +{ + guint16 adsState; + guint16 deviceState; + guint32 cbLength; + guint16 firstDataWord; +} TAdsWriteControlReq, TAdsWriteControlInd;*/ +#define TAdsWriteControlReq_Len 10 + +typedef struct +{ + guint32 invokeId; +} TAdsReadStateReq; +#define TAdsReadStateReq_Len (int)sizeof(TAdsReadStateReq) + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbLength; +} TAdsReadReq; +#define TAdsReadReq_Len (int)sizeof(TAdsReadReq) + +/*typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbLength; + guint16 firstDataWord; +} TAdsWriteReq;*/ +#define TAdsWriteReq_Len 14 + +/* +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbReadLength; + guint32 cbWriteLength; + guint16 firstDataWord; +} TAdsReadWriteReq;*/ +#define TAdsReadWriteReq_Len 18 + +typedef struct +{ + guint32 cbLength; + guint32 nTransMode; + guint32 nMaxDelay; + guint32 nCycleTime; + guint8 nCmpMax[sizeof(double)]; + guint8 nCmpMin[sizeof(double)]; +} AdsNotificationAttrib; + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + AdsNotificationAttrib noteAttrib; +} TAdsAddDeviceNotificationReq; +#define TAdsAddDeviceNotificationReq_Len (int)sizeof(TAdsAddDeviceNotificationReq) + +typedef struct +{ + guint32 hNotification; +} TAdsDelDeviceNotificationReq; +#define TAdsDelDeviceNotificationReq_Len (int)sizeof(TAdsDelDeviceNotificationReq) + +typedef struct +{ + guint32 cbLength; + guint32 nStamps; +} TAdsDeviceNotificationReq; +#define TAdsDeviceNotificationReq_Len (int)sizeof(TAdsDeviceNotificationReq) + +typedef struct +{ + guint32 result; +} TAdsRes; +#define TAdsRes_Len (int)sizeof(TAdsRes) + +typedef struct +{ + guint8 version; + guint8 revision; + guint16 build; +} AdsVersion, *PAdsVersion; + +typedef struct +{ + guint32 result; + AdsVersion version; + char sName[ADS_FIXEDNAMESIZE]; +} TAdsReadDeviceInfoRes; +#define TAdsReadDeviceInfoRes_Len (int)sizeof(TAdsReadDeviceInfoRes) + +typedef struct +{ + guint32 result; +} TAdsWriteControlRes; +#define TAdsWriteControlRes_Len (int)sizeof(TAdsWriteControlRes) + +typedef struct +{ + guint32 result; + guint16 adsState; + guint16 deviceState; +} TAdsReadStateRes; +#define TAdsReadStateRes_Len (int)sizeof(TAdsReadStateRes) + +typedef struct +{ + guint32 result; + guint32 cbLength; + guint16 firstDataWord; +} TAdsReadRes; +#define TAdsReadRes_Len (int)sizeof(TAdsReadRes) + +typedef struct +{ + guint32 result; + guint32 cbLength; + guint16 firstDataWord; +} TAdsReadWriteRes; +#define TAdsReadWriteRes_Len (int)sizeof(TAdsReadWriteRes) + +typedef struct +{ + guint32 result; +} TAdsWriteRes; +#define TAdsWriteRes_Len (int)sizeof(TAdsWriteRes) + +typedef struct +{ + guint32 result; + guint32 handle; +} TAdsAddDeviceNotificationRes; +#define TAdsAddDeviceNotificationRes_Len (int)sizeof(TAdsAddDeviceNotificationRes) + +typedef struct +{ + guint32 result; +} TAdsDelDeviceNotificationRes; +#define TAdsDelDeviceNotificationRes_Len (int)sizeof(TAdsDelDeviceNotificationRes) + + +/* structure for decoding the header -----------------------------------------*/ +/*typedef struct +{ + guint16 reserved; + guint32 cbLength; +} TcpAdsParserHDR; +typedef TcpAdsParserHDR;*/ +#define TcpAdsParserHDR_Len 6 + + +#endif + + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ecatmb.c b/plugins/epan/ethercat/packet-ecatmb.c new file mode 100644 index 00000000..c5998540 --- /dev/null +++ b/plugins/epan/ethercat/packet-ecatmb.c @@ -0,0 +1,1995 @@ +/* packet-ecatmb.c + * Routines for EtherCAT packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Include files */ + +#include "config.h" + +#include <string.h> + +#include <epan/packet.h> +#include <epan/expert.h> + +#include "packet-ecatmb.h" + +#define BIT2BYTE(x) ((x+7)/8) +#define ENDOF(p) ((p)+1) /* pointer to end of *p */ + +void proto_register_ecat_mailbox(void); +void proto_reg_handoff_ecat_mailbox(void); + +static dissector_handle_t eth_handle; +static dissector_handle_t ams_handle; +static dissector_handle_t ecat_mailbox_handle; + +/* Define the EtherCAT mailbox proto */ +int proto_ecat_mailbox = -1; + +static int ett_ecat_mailbox = -1; +static int ett_ecat_mailbox_eoe = -1; +static int ett_ecat_mailbox_eoe_init = -1; +static int ett_ecat_mailbox_eoe_macfilter = -1; +static int ett_ecat_mailbox_eoe_macfilter_filter = -1; +static int ett_ecat_mailbox_eoe_macfilter_filtermask = -1; +static int ett_ecat_mailbox_coe = -1; +static int ett_ecat_mailbox_sdo = -1; +static int ett_ecat_mailbox_coe_sdoccs = -1; +static int ett_ecat_mailbox_coe_sdoscs = -1; +static int ett_ecat_mailbox_foe = -1; +static int ett_ecat_mailbox_foe_efw = -1; +static int ett_ecat_mailbox_soeflag = -1; +static int ett_ecat_mailbox_soe = -1; +static int ett_ecat_mailbox_fraghead = -1; +static int ett_ecat_mailbox_header = -1; + +static int hf_ecat_mailboxlength = -1; +static int hf_ecat_mailboxaddress = -1; +static int hf_ecat_mailboxpriority = -1; +static int hf_ecat_mailboxtype = -1; +static int hf_ecat_mailboxcounter = -1; +static int hf_ecat_mailbox_eoe = -1; +static int hf_ecat_mailbox_eoe_fraghead = -1; +static int hf_ecat_mailbox_eoe_type = -1; +static int hf_ecat_mailbox_eoe_fragno = -1; +static int hf_ecat_mailbox_eoe_offset = -1; +static int hf_ecat_mailbox_eoe_frame = -1; +static int hf_ecat_mailbox_eoe_last = -1; +static int hf_ecat_mailbox_eoe_timestampreq = -1; +static int hf_ecat_mailbox_eoe_timestampapp = -1; +static int hf_ecat_mailbox_eoe_fragment = -1; +static int hf_ecat_mailbox_eoe_init = -1; +static int hf_ecat_mailbox_eoe_init_contains_macaddr = -1; +static int hf_ecat_mailbox_eoe_init_contains_ipaddr = -1; +static int hf_ecat_mailbox_eoe_init_contains_subnetmask = -1; +static int hf_ecat_mailbox_eoe_init_contains_defaultgateway = -1; +static int hf_ecat_mailbox_eoe_init_contains_dnsserver = -1; +static int hf_ecat_mailbox_eoe_init_contains_dnsname = -1; +static int hf_ecat_mailbox_eoe_init_append_timestamp = -1; +static int hf_ecat_mailbox_eoe_init_macaddr = -1; +static int hf_ecat_mailbox_eoe_init_ipaddr = -1; +static int hf_ecat_mailbox_eoe_init_subnetmask = -1; +static int hf_ecat_mailbox_eoe_init_defaultgateway = -1; +static int hf_ecat_mailbox_eoe_init_dnsserver = -1; +static int hf_ecat_mailbox_eoe_init_dnsname = -1; +static int hf_ecat_mailbox_eoe_macfilter = -1; +static int hf_ecat_mailbox_eoe_macfilter_macfiltercount = -1; +static int hf_ecat_mailbox_eoe_macfilter_maskcount = -1; +static int hf_ecat_mailbox_eoe_macfilter_nobroadcasts = -1; +static int hf_ecat_mailbox_eoe_macfilter_filter; +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}; +static int hf_ecat_mailbox_eoe_macfilter_filtermask = -1; +static int hf_ecat_mailbox_eoe_macfilter_filtermasks[4] = {-1,-1,-1,-1}; +static int hf_ecat_mailbox_eoe_timestamp = -1; +static int hf_ecat_mailbox_coe = -1; +static int hf_ecat_mailbox_coe_number = -1; +static int hf_ecat_mailbox_coe_type = -1; +static int hf_ecat_mailbox_coe_sdoreq = -1; +static int hf_ecat_mailbox_coe_sdoccsid = -1; +static int hf_ecat_mailbox_coe_sdoccsid_sizeind = -1; +static int hf_ecat_mailbox_coe_sdoccsid_expedited = -1; +static int hf_ecat_mailbox_coe_sdoccsid_size0= -1; +static int hf_ecat_mailbox_coe_sdoccsid_size1= -1; +static int hf_ecat_mailbox_coe_sdoccsid_complete = -1; +static int hf_ecat_mailbox_coe_sdoccsds = -1; +static int hf_ecat_mailbox_coe_sdoccsds_lastseg = -1; +static int hf_ecat_mailbox_coe_sdoccsds_size = -1; +static int hf_ecat_mailbox_coe_sdoccsds_toggle = -1; +static int hf_ecat_mailbox_coe_sdoccsus = -1; +static int hf_ecat_mailbox_coe_sdoccsus_toggle = -1; +static int hf_ecat_mailbox_coe_sdoccsiu = -1; +/* static int hf_ecat_mailbox_coe_sdoccsiu_complete = -1; */ +static int hf_ecat_mailbox_coe_sdoidx = -1; +static int hf_ecat_mailbox_coe_sdoabortcode = -1; +static int hf_ecat_mailbox_coe_sdosub = -1; +static int hf_ecat_mailbox_coe_sdodata = -1; +static int hf_ecat_mailbox_coe_sdodata1 = -1; +static int hf_ecat_mailbox_coe_sdodata2 = -1; +static int hf_ecat_mailbox_coe_sdoldata = -1; +static int hf_ecat_mailbox_coe_sdolength = -1; +/* static int hf_ecat_mailbox_coe_sdoerror = -1; */ +static int hf_ecat_mailbox_coe_sdores = -1; +static int hf_ecat_mailbox_coe_sdoscsds = -1; +static int hf_ecat_mailbox_coe_sdoscsds_toggle = -1; +static int hf_ecat_mailbox_coe_sdoscsiu = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_sizeind = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_expedited = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_size0 = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_size1 = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_complete = -1; +static int hf_ecat_mailbox_coe_sdoscsus = -1; +static int hf_ecat_mailbox_coe_sdoscsus_lastseg = -1; +static int hf_ecat_mailbox_coe_sdoscsus_bytes = -1; +static int hf_ecat_mailbox_coe_sdoscsus_toggle = -1; +static int hf_ecat_mailbox_coe_sdoinfoopcode = -1; +static int hf_ecat_mailbox_coe_sdoinfofrag = -1; +static int hf_ecat_mailbox_coe_sdoinfolisttype = -1; +static int hf_ecat_mailbox_coe_sdoinfolist = -1; +static int hf_ecat_mailbox_coe_sdoinfoindex = -1; +static int hf_ecat_mailbox_coe_sdoinfosubindex = -1; +static int hf_ecat_mailbox_coe_sdoinfovalueinfo = -1; +static int hf_ecat_mailbox_coe_sdoinfoerrorcode = -1; +static int hf_ecat_mailbox_coe_sdoinfodatatype = -1; +static int hf_ecat_mailbox_coe_sdoinfomaxsub = -1; +static int hf_ecat_mailbox_coe_sdoinfoobjcode = -1; +static int hf_ecat_mailbox_coe_sdoinfoname = -1; +static int hf_ecat_mailbox_coe_sdoinfobitlen = -1; +static int hf_ecat_mailbox_coe_sdoinfoobjaccess = -1; +static int hf_ecat_mailbox_coe_sdoinfounittype = -1; +static int hf_ecat_mailbox_coe_sdoinfodefaultvalue = -1; +static int hf_ecat_mailbox_coe_sdoinfominvalue = -1; +static int hf_ecat_mailbox_coe_sdoinfomaxvalue = -1; +static int hf_ecat_mailboxdata = -1; +static int hf_ecat_mailbox_foe = -1; +static int hf_ecat_mailbox_foe_opmode = -1; +static int hf_ecat_mailbox_foe_filelength = -1; +static int hf_ecat_mailbox_foe_filename = -1; +static int hf_ecat_mailbox_foe_packetno = -1; +static int hf_ecat_mailbox_foe_errcode = -1; +static int hf_ecat_mailbox_foe_errtext = -1; +static int hf_ecat_mailbox_foe_busydone = -1; +static int hf_ecat_mailbox_foe_busyentire = -1; +static int hf_ecat_mailbox_foe_data = -1; +static int hf_ecat_mailbox_foe_efw = -1; +static int hf_ecat_mailbox_foe_efw_cmd = -1; +static int hf_ecat_mailbox_foe_efw_size = -1; +static int hf_ecat_mailbox_foe_efw_addresslw = -1; +static int hf_ecat_mailbox_foe_efw_addresshw = -1; +static int hf_ecat_mailbox_foe_efw_data = -1; +static int hf_ecat_mailbox_soe = -1; +static int hf_ecat_mailbox_soe_header = -1; + +static int hf_ecat_mailbox_soe_header_opcode = -1; +static int hf_ecat_mailbox_soe_header_incomplete = -1; +static int hf_ecat_mailbox_soe_header_error = -1; +static int hf_ecat_mailbox_soe_header_driveno = -1; +static int hf_ecat_mailbox_soe_header_datastate = -1; +static int hf_ecat_mailbox_soe_header_name = -1; +static int hf_ecat_mailbox_soe_header_attribute = -1; +static int hf_ecat_mailbox_soe_header_unit = -1; +static int hf_ecat_mailbox_soe_header_min = -1; +static int hf_ecat_mailbox_soe_header_max = -1; +static int hf_ecat_mailbox_soe_header_value = -1; +static int hf_ecat_mailbox_soe_header_reserved = -1; +static int hf_ecat_mailbox_soe_idn = -1; +static int hf_ecat_mailbox_soe_data = -1; +static int hf_ecat_mailbox_soe_frag = -1; +static int hf_ecat_mailbox_soe_error = -1; + +static expert_field ei_ecat_mailbox_error = EI_INIT; +static expert_field ei_ecat_mailbox_coe_error = EI_INIT; +static expert_field ei_ecat_mailbox_eoe_error = EI_INIT; +static expert_field ei_ecat_mailbox_soe_error = EI_INIT; +static expert_field ei_ecat_mailbox_foe_error = EI_INIT; + + +static const value_string EcMBoxType[] = +{ + { 0, "Invalid", }, + { 1, "AoE (Vendor specific; Beckhoff ADS over EtherCAT)", }, + { 2, "EoE (Ethernet over EtherCAT)", }, + { 3, "CoE (CANopen over EtherCAT)", }, + { 4, "FoE (File access over EtherCAT)", }, + { 5, "SoE (Servo profile over EtherCAT)", }, + { 15, "VoE (Vendor specific over EtherCAT)"}, + { 0x80+1, "AoE - Err", }, + { 0x80+2, "EoE - Err", }, + { 0x80+3, "CoE - Err", }, + { 0x80+4, "FoE - Err", }, + { 0x80+5, "SoE - Err", }, + { 0, NULL } +}; + +static const value_string FoEOpMode[] = +{ + { 1, "RRQ", }, + { 2, "WRQ", }, + { 3, "DATA", }, + { 4, "ACK", }, + { 5, "ERROR", }, + { 6, "BUSY", }, + { 0, NULL } +}; + +static const value_string FoEEfwCmd[] = +{ + { 1, "Memory Transfer", }, + { 2, "Write Code", }, + { 3, "Check device id", }, + { 4, "Checksum", }, + { 5, "Write code checksum", }, + { 6, "Set device id", }, + { 8, "Set code id", }, + { 9, "NOP", }, + { 10, "Checksum checksum", }, + { 11, "boot checksum", }, + { 0, NULL } +}; + +static const value_string SoeOpcode[] = +{ + { 0, "unused" }, + { 1, "readReq" }, + { 2, "readRes"}, + { 3, "writeReq"}, + { 4, "writeRes" }, + { 5, "notification" }, + { 6, "emergency"}, + { 0, NULL } +}; + +static const value_string EoEType[] = +{ + { EOE_TYPE_FRAME_FRAG, "Fragment" }, + { EOE_TYPE_TIMESTAMP_RES, "TimeStamp" }, + { EOE_TYPE_INIT_REQ, "Init Req"}, + { EOE_TYPE_INIT_RES, "Init Res"}, + { EOE_TYPE_MACFILTER_REQ, "MAC Req" }, + { EOE_TYPE_MACFILTER_RES, "MAC Res" }, + { 0, NULL } +}; + +static const value_string CANopenType[] = +{ + { ETHERCAT_COE_TYPE_EMERGENCY, "EMERGENCY" }, + { ETHERCAT_COE_TYPE_SDOREQ, "SDO Req" }, + { ETHERCAT_COE_TYPE_SDORES, "SDO Res"}, + { ETHERCAT_COE_TYPE_TXPDO, "TxPDO"}, + { ETHERCAT_COE_TYPE_RXPDO, "RxPDO" }, + { ETHERCAT_COE_TYPE_TXPDO_RTR, "TxPDO_RTR" }, + { ETHERCAT_COE_TYPE_RXPDO_RTR, "RxPDO_RTR" }, + { ETHERCAT_COE_TYPE_SDOINFO, "SDO Information" }, + { 0, NULL } +}; + +static const value_string CANopenSdoInfo[] = +{ + { ECAT_COE_INFO_OPCODE_LIST_Q, "List Req" }, + { ECAT_COE_INFO_OPCODE_LIST_S, "List Res" }, + { ECAT_COE_INFO_OPCODE_OBJ_Q, "Obj Req"}, + { ECAT_COE_INFO_OPCODE_OBJ_S, "Obj Res"}, + { ECAT_COE_INFO_OPCODE_ENTRY_Q, "Entry Req" }, + { ECAT_COE_INFO_OPCODE_ENTRY_S, "Entry Res" }, + { ECAT_COE_INFO_OPCODE_ERROR_S, "Error Res" }, + { 0, NULL } +}; + +static const true_false_string tfs_complete = +{ + "Complete", "Legacy" +}; + +void init_mbx_header(PETHERCAT_MBOX_HEADER pMbox, tvbuff_t *tvb, gint offset) +{ + pMbox->Length = tvb_get_letohs(tvb, offset); offset+=2; + pMbox->Address = tvb_get_letohs(tvb, offset); offset+=2; + pMbox->aControlUnion.Control = tvb_get_letohs(tvb, offset); +} + +static void init_eoe_header(PETHERCAT_EOE_HEADER pEoE, tvbuff_t *tvb, gint offset) +{ + pEoE->anEoeHeaderInfoUnion.Info = tvb_get_letohs(tvb, offset); offset+=2; + pEoE->anEoeHeaderDataUnion.Result = tvb_get_letohs(tvb, offset); +} + +static void init_foe_header(PETHERCAT_FOE_HEADER pFoE, tvbuff_t *tvb, gint offset) +{ + pFoE->OpMode = tvb_get_guint8(tvb, offset++); + pFoE->Reserved1 = tvb_get_guint8(tvb, offset++); + pFoE->aFoeHeaderDataUnion.FileLength = tvb_get_letohl(tvb, offset); +} + +static void init_soe_header(PETHERCAT_SOE_HEADER pSoE, tvbuff_t *tvb, gint offset) +{ + pSoE->anSoeHeaderControlUnion.v2.Control = tvb_get_guint8(tvb, offset++); + pSoE->anSoeHeaderControlUnion.v2.Element = tvb_get_guint8(tvb, offset++); + pSoE->anSoeHeaderDataUnion.FragmentsLeft = tvb_get_letohs(tvb, offset); +} + +static void init_coe_header(PETHERCAT_COE_HEADER pCoE, tvbuff_t *tvb, gint offset) +{ + pCoE->header = tvb_get_letohs(tvb, offset); +} + +static void init_sdo_header(PETHERCAT_SDO_HEADER pSdo, tvbuff_t *tvb, gint offset) +{ + pSdo->anSdoHeaderUnion.CS = tvb_get_guint8(tvb, offset++); + pSdo->Index = tvb_get_letohs(tvb, offset);offset+=2; + pSdo->SubIndex = tvb_get_guint8(tvb, offset++); + pSdo->Data = tvb_get_letohl(tvb, offset); +} + +static void init_sdo_info_header(PETHERCAT_SDO_INFO_HEADER pInfo, tvbuff_t *tvb, gint offset) +{ + pInfo->anSdoControlUnion.Control = tvb_get_guint8(tvb, offset++); + pInfo->Reserved = tvb_get_guint8(tvb, offset); + pInfo->FragmentsLeft = 2; +} + +static void CANopenSdoReqFormatter(PETHERCAT_SDO_HEADER pSdo, char *szText, gint nMax) +{ + switch ( pSdo->anSdoHeaderUnion.Idq.Ccs ) + { + case SDO_CCS_INITIATE_DOWNLOAD: + snprintf ( szText, nMax, "SDO Req : 'Initiate Download' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index, pSdo->SubIndex); + break; + case SDO_CCS_INITIATE_UPLOAD: + snprintf ( szText, nMax, "SDO Req : 'Initiate Upload' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index, pSdo->SubIndex); + break; + case SDO_CCS_DOWNLOAD_SEGMENT: + snprintf ( szText, nMax, "SDO Req : 'Download Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + case SDO_CCS_UPLOAD_SEGMENT: + snprintf ( szText, nMax, "SDO Req : 'Upload Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + case SDO_CCS_ABORT_TRANSFER: + snprintf ( szText, nMax, "SDO Req : 'Abort Transfer' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + default: + snprintf ( szText, nMax, "SDO Req : Ccs %d", pSdo->anSdoHeaderUnion.Idq.Ccs); + } +} + +static void FoeFormatter(tvbuff_t *tvb, wmem_allocator_t *scope, gint offset, char *szText, gint nMax, guint foe_length) +{ + ETHERCAT_FOE_HEADER foe; + char *tmp = NULL; + + init_foe_header(&foe, tvb, offset); + + switch ( foe.OpMode ) + { + case ECAT_FOE_OPMODE_RRQ: + case ECAT_FOE_OPMODE_WRQ: + case ECAT_FOE_OPMODE_ERR: + if ( foe_length > ETHERCAT_FOE_HEADER_LEN ) { + tmp = tvb_get_string_enc(scope, tvb, offset+ETHERCAT_FOE_HEADER_LEN, MIN(foe_length-ETHERCAT_FOE_HEADER_LEN, 49), ENC_ASCII); + } + break; + } + + switch ( foe.OpMode ) + { + case ECAT_FOE_OPMODE_RRQ: + snprintf ( szText, nMax, "FoE RRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp ? tmp : ""); + break; + case ECAT_FOE_OPMODE_WRQ: + snprintf ( szText, nMax, "FoE WRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp ? tmp : ""); + break; + case ECAT_FOE_OPMODE_DATA: + snprintf ( szText, nMax, "FoE DATA (%d) : %d Bytes", foe.aFoeHeaderDataUnion.v.PacketNo, foe_length-ETHERCAT_FOE_HEADER_LEN); + break; + case ECAT_FOE_OPMODE_ACK: + snprintf ( szText, nMax, "FoE ACK (%d)", foe.aFoeHeaderDataUnion.v.PacketNo); + break; + case ECAT_FOE_OPMODE_ERR: + snprintf ( szText, nMax, "FoE ERR (%d) : '%s'", foe.aFoeHeaderDataUnion.ErrorCode, tmp ? tmp : ""); + break; + case ECAT_FOE_OPMODE_BUSY: + if ( foe.aFoeHeaderDataUnion.v2.Entire > 0 ) + snprintf ( szText, nMax, "FoE BUSY (%d%%)", ((guint32)foe.aFoeHeaderDataUnion.v2.Done*100)/foe.aFoeHeaderDataUnion.v2.Entire); + else + snprintf ( szText, nMax, "FoE BUSY (%d/%d)", foe.aFoeHeaderDataUnion.v2.Done, foe.aFoeHeaderDataUnion.v2.Entire); + break; + default: + snprintf ( szText, nMax, "FoE Unknown"); + } +} + +static void SoEIdToString( char* txt, guint16 id, int nMax) +{ + if ( id & 0x8000 ) + snprintf(txt, nMax, "P-%d-%04d", (id>>12) & 0x0007, id & 0x0FFF ); + else + snprintf(txt, nMax, "S-%d-%04d", id>>12, id & 0x0FFF ); +} + +static void SoeFormatter(tvbuff_t *tvb, gint offset, char *szText, gint nMax, guint soe_length) +{ + ETHERCAT_SOE_HEADER soe; + char tmp[50]; + char elm[50]; + memset(tmp, 0, sizeof(tmp)); + + init_soe_header(&soe, tvb, offset); + offset+=ETHERCAT_SOE_HEADER_LEN; + + if ( !soe.anSoeHeaderControlUnion.v.Error ) + { + if ( !soe.anSoeHeaderControlUnion.v.InComplete ) + { + SoEIdToString(tmp, soe.anSoeHeaderDataUnion.IDN, sizeof(tmp)-1); + elm[0] = '\0'; + if ( soe.anSoeHeaderControlUnion.v.DataState ) + (void) g_strlcat(elm, "D", 50); + if ( soe.anSoeHeaderControlUnion.v.Name ) + (void) g_strlcat(elm, "N", 50); + if ( soe.anSoeHeaderControlUnion.v.Attribute ) + (void) g_strlcat(elm, "A", 50); + if ( soe.anSoeHeaderControlUnion.v.Unit ) + (void) g_strlcat(elm, "U", 50); + if ( soe.anSoeHeaderControlUnion.v.Min ) + (void) g_strlcat(elm, "I", 50); + if ( soe.anSoeHeaderControlUnion.v.Max ) + (void) g_strlcat(elm, "X", 50); + if ( soe.anSoeHeaderControlUnion.v.Value ) + (void) g_strlcat(elm, "V", 50); + switch ( soe.anSoeHeaderControlUnion.v.OpCode ) + { + case ECAT_SOE_OPCODE_RRQ: + snprintf ( szText, nMax, "SoE: RRQ (%s, '%s')", tmp, elm); + break; + case ECAT_SOE_OPCODE_RRS: + snprintf ( szText, nMax, "SoE: RRS (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN)); + break; + case ECAT_SOE_OPCODE_WRS: + snprintf ( szText, nMax, "SoE: WRS (%s, '%s')", tmp, elm); + break; + case ECAT_SOE_OPCODE_WRQ: + snprintf ( szText, nMax, "SoE: WRQ (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN)); + break; + case ECAT_SOE_OPCODE_NFC: + snprintf ( szText, nMax, "SoE: NFC (%s, '%s') : %u Bytes", tmp, elm, (guint)(soe_length-ETHERCAT_SOE_HEADER_LEN)); + break; + case 6: + snprintf ( szText, nMax, "SoE: EMGCY"); + break; + default: + snprintf ( szText, nMax, "SoE:"); + } + } + else + snprintf ( szText, nMax, "SoE: FragmentsLeft %d", soe.anSoeHeaderDataUnion.FragmentsLeft); + } + else + snprintf ( szText, nMax, "SoE: Error %04x", tvb_get_letohs(tvb, offset)); +} + +/* ethercat mailbox */ +static void dissect_ecat_coe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_coe_tree = NULL, *ecat_sdo_tree, *ecat_coe_sdoccs_tree, *ecat_coe_sdoscs_tree; + + proto_item *anItem = NULL, *aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint coe_length = tvb_reported_length(tvb)-offset; + guint16 len; + + if( tree ) + { + anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_coe, tvb, offset, coe_length, NULL, "CoE"); + aparent = proto_item_get_parent(anItem); + proto_item_append_text(aparent,":CoE "); + } + + col_append_str(pinfo->cinfo, COL_INFO, "CoE "); + + if( coe_length >= ETHERCAT_COE_HEADER_LEN ) + { + ETHERCAT_COE_HEADER coe; + init_coe_header(&coe, tvb, offset); + if( tree ) + { + ecat_coe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe); + + proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_number, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.v.Number); + proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_type, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.v.Type); + } + + offset += ETHERCAT_COE_HEADER_LEN; + + switch (coe.v.Type) + { + case ETHERCAT_COE_TYPE_SDOREQ: + { + ETHERCAT_SDO_HEADER sdo; + + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN ) + { + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Req - invalid length"); + expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Req - invalid length"); + break; + } + + init_sdo_header(&sdo, tvb, offset); + + CANopenSdoReqFormatter(&sdo, szText, nMax); + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + proto_item_append_text(aparent, "%s", szText); + + anItem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_sdoreq, tvb, offset, 1, sdo.anSdoHeaderUnion.Idq.Ccs); + proto_item_set_text(anItem, "%s", szText); + ecat_sdo_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_sdo); + + switch ( sdo.anSdoHeaderUnion.Idq.Ccs ) + { + case SDO_CCS_INITIATE_DOWNLOAD: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsid, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_sizeind, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_expedited, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size0, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN); + if ( sdo.anSdoHeaderUnion.Idq.SizeInd && !sdo.anSdoHeaderUnion.Idq.Expedited ) + { + len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN; + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + offset+=ETHERCAT_SDO_HEADER_LEN; + if ( len > 0 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, ENC_NA); + } + else + { + if ( sdo.anSdoHeaderUnion.Idq.Size == 3 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, ENC_LITTLE_ENDIAN); + else if ( sdo.anSdoHeaderUnion.Idq.Size == 2 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); + else + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + } + break; + case SDO_CCS_INITIATE_UPLOAD: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsiu, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN); + + break; + case SDO_CCS_DOWNLOAD_SEGMENT: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsds, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_lastseg, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_size, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=1; + + if ( coe_length-offset > 0 ) + { + anItem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, ENC_NA); + proto_item_append_text(anItem, "(len = %d)", coe_length-offset); + } + break; + case SDO_CCS_UPLOAD_SEGMENT: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsus, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoccs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoccs); + proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsus_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + break; + case SDO_CCS_ABORT_TRANSFER: + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoabortcode, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + break; + } + } + } + break; + + case ETHERCAT_COE_TYPE_SDORES: + { + ETHERCAT_SDO_HEADER sdo; + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN ) + { + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Res - invalid length"); + expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Res - invalid length"); + break; + } + + init_sdo_header(&sdo, tvb, offset); + + col_append_fstr(pinfo->cinfo, COL_INFO, "SDO Res: Scs %d", sdo.anSdoHeaderUnion.Ids.Scs); + if( tree ) + { + proto_tree_add_uint_format_value(ecat_coe_tree, hf_ecat_mailbox_coe_sdores, tvb, offset, 1, sdo.anSdoHeaderUnion.Ids.Scs, + "Scs %d", sdo.anSdoHeaderUnion.Ids.Scs); + ecat_sdo_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_sdo); + + switch ( sdo.anSdoHeaderUnion.Ids.Scs ) + { + case SDO_SCS_INITIATE_DOWNLOAD: + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN); + break; + case SDO_SCS_INITIATE_UPLOAD: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsiu, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_sizeind, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_expedited, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size0, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_complete, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, ENC_LITTLE_ENDIAN); + if ( sdo.anSdoHeaderUnion.Ius.SizeInd && !sdo.anSdoHeaderUnion.Ius.Expedited ) + { + len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN; + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + offset+=ETHERCAT_SDO_HEADER_LEN; + if ( len > 0 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, ENC_NA); + } + else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 3 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, ENC_LITTLE_ENDIAN); + else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 2 ) + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); + else + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + break; + case SDO_SCS_DOWNLOAD_SEGMENT: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsds, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsds_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + break; + case SDO_SCS_UPLOAD_SEGMENT: + anItem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsus, tvb, offset, 1, ENC_LITTLE_ENDIAN); + ecat_coe_sdoscs_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_coe_sdoscs); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_lastseg, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_bytes, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_toggle, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=1; + + if ( coe_length-offset> 0 ) + { + anItem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, ENC_NA); + proto_item_append_text(anItem, "(len = %d)", coe_length-offset); + } + break; + } + } + } + break; + + case ETHERCAT_COE_TYPE_SDOINFO: + { + ETHERCAT_SDO_INFO_HEADER info; + + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_INFO_LISTREQ_LEN ) + { + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Info - invalid length"); + expert_add_info_format(pinfo, ecat_coe_tree, &ei_ecat_mailbox_coe_error, "Sdo Info - invalid length"); + break; + } + + memset(&info, 0x0, sizeof(info)); + init_sdo_info_header(&info, tvb, offset); + + col_append_str(pinfo->cinfo, COL_INFO, val_to_str(info.anSdoControlUnion.v.OpCode & 0x7F, CANopenSdoInfo, "%d (Unknown)")); + if ( info.anSdoControlUnion.v.InComplete ) + col_append_str(pinfo->cinfo, COL_INFO, " - More Follows"); + + if( tree ) + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoopcode, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + offset++; /*Reserved*/ + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfofrag, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + switch ( info.anSdoControlUnion.v.OpCode ) + { + case ECAT_COE_INFO_OPCODE_LIST_Q: + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, ENC_LITTLE_ENDIAN); + } + break; + case ECAT_COE_INFO_OPCODE_LIST_S: + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolist, tvb, offset, coe_length-offset, ENC_NA); + } + break; + case ECAT_COE_INFO_OPCODE_OBJ_Q: + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN); + break; + case ECAT_COE_INFO_OPCODE_OBJ_S: + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxsub, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjcode, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, ENC_ASCII|ENC_NA); + } + break; + case ECAT_COE_INFO_OPCODE_ENTRY_Q: + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset, 1, ENC_LITTLE_ENDIAN); + } + break; + case ECAT_COE_INFO_OPCODE_ENTRY_S: + { + guint16 objlen; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfobitlen, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjaccess, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x08) != 0 ) + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfounittype, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x10) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodefaultvalue, tvb, offset, objlen, ENC_NA); + offset+=objlen; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x20) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfominvalue, tvb, offset, objlen, ENC_NA); + offset+=objlen; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x40) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxvalue, tvb, offset, objlen, ENC_NA); + offset+=objlen; + } + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, ENC_ASCII|ENC_NA); + } + break; + case ECAT_COE_INFO_OPCODE_ERROR_S: + { + proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoerrorcode, tvb, offset, 4, ENC_LITTLE_ENDIAN); + } + break; + } + } + } + break; + } + } + else + { + col_append_str(pinfo->cinfo, COL_INFO, "- invalid length"); + expert_add_info(pinfo, tree, &ei_ecat_mailbox_coe_error); + } +} + +static void dissect_ecat_soe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_soeflag_tree, *ecat_soe_tree; + + proto_item *anItem = NULL ,*aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint soe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + anItem = proto_tree_add_item(tree, hf_ecat_mailbox_soe, tvb, offset, soe_length, ENC_NA); + + aparent = proto_item_get_parent(anItem); + proto_item_append_text(aparent,":SoE "); + } + + if( soe_length >= ETHERCAT_SOE_HEADER_LEN ) + { + SoeFormatter(tvb, offset, szText, nMax, soe_length); + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + ETHERCAT_SOE_HEADER soe; + init_soe_header(&soe, tvb, offset); + + proto_item_append_text(aparent, "%s", szText); + proto_item_set_text(anItem, "%s", szText); + + ecat_soe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_soe); + anItem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_header, tvb, offset , 2, ENC_LITTLE_ENDIAN); + + ecat_soeflag_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_soeflag); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_opcode, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_incomplete, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_error, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_driveno, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_datastate, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_name, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_attribute, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_unit, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_min, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_max, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_value, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + if ( !soe.anSoeHeaderControlUnion.v.Error ) + { + if ( !soe.anSoeHeaderControlUnion.v.InComplete ) + { + switch (soe.anSoeHeaderControlUnion.v.OpCode) + { + case ECAT_SOE_OPCODE_RRQ: + case ECAT_SOE_OPCODE_WRS: + proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN); + break; + case ECAT_SOE_OPCODE_RRS: + case ECAT_SOE_OPCODE_WRQ: + case ECAT_SOE_OPCODE_NFC: + proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, ENC_NA); + break; + } + } + else + { + proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_frag, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, ENC_NA); + } + } + else + { + proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_ecat_mailbox_soe_error, tvb, offset, 2, ENC_LITTLE_ENDIAN); + } + } + } + else + { + col_append_str(pinfo->cinfo, COL_INFO, "SoE - invalid length"); + expert_add_info(pinfo, tree, &ei_ecat_mailbox_soe_error); + } +} + +static void dissect_ecat_eoe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_eoe_tree = 0, *ecat_fraghead_tree, *ecat_eoe_init_tree, *ecat_eoe_macfilter_tree, + *ecat_eoe_macfilter_filter_tree; + tvbuff_t *next_tvb; + proto_item *anItem = NULL, *aparent = NULL; + int nCnt; + + guint eoe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_eoe, tvb, offset, eoe_length, NULL, "EoE Fragment"); + + aparent = proto_item_get_parent(anItem); + proto_item_append_text(aparent,":EoE "); + } + + if( eoe_length >= ETHERCAT_EOE_HEADER_LEN ) + { + ETHERCAT_EOE_HEADER eoe; + init_eoe_header(&eoe, tvb, offset); + if ( eoe.anEoeHeaderInfoUnion.v.Type == EOE_TYPE_FRAME_FRAG ) + col_append_fstr(pinfo->cinfo, COL_INFO, "EoE-Frag %d", eoe.anEoeHeaderDataUnion.v.Fragment); + else + col_append_str(pinfo->cinfo, COL_INFO, "EoE"); + + { /* Do the following even 'if (tree == NULL)' since a call_dissector() is done */ + ecat_eoe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe); + + anItem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fraghead, tvb, offset, 4, ENC_NA); + ecat_fraghead_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_fraghead); + + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_type, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.Type); + + switch ( eoe.anEoeHeaderInfoUnion.v.Type ) + { + case EOE_TYPE_FRAME_FRAG: + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_fragno, tvb, offset, 4, eoe.anEoeHeaderDataUnion.v.Fragment); + + if (eoe.anEoeHeaderDataUnion.v.Fragment == 0) + { + proto_tree_add_uint_format(ecat_fraghead_tree, hf_ecat_mailbox_eoe_offset, tvb, offset, 4, 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer, + "BufferSize: %d", 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer); + } + else + { + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_offset, tvb, offset, 4, 32*eoe.anEoeHeaderDataUnion.v.OffsetBuffer); + } + + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_frame, tvb, offset, 4, eoe.anEoeHeaderDataUnion.v.FrameNo); + + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_last, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.LastFragment); + + if ( eoe.anEoeHeaderInfoUnion.v.TimeStampRequested ) + { + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampreq, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.TimeStampRequested); + } + + if ( eoe.anEoeHeaderInfoUnion.v.TimeStampAppended ) + { + proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampapp, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.v.TimeStampAppended); + } + + offset+=ETHERCAT_EOE_HEADER_LEN; + proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fragment, tvb, offset, eoe_length-offset, ENC_NA); + + if ( eoe.anEoeHeaderDataUnion.v.Fragment == 0 ) + { + next_tvb = tvb_new_subset_length(tvb, offset, eoe_length-offset); + call_dissector( eth_handle, next_tvb, pinfo, ecat_eoe_tree); + } + + if ( eoe.anEoeHeaderInfoUnion.v.TimeStampAppended ) + { + 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); + } + break; + + case EOE_TYPE_TIMESTAMP_RES: + 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); + break; + + case EOE_TYPE_INIT_REQ: + offset+=ETHERCAT_EOE_HEADER_LEN; + 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); + if( eoe_length-offset >= ETHERCAT_EOE_INIT_LEN ) + { + ecat_eoe_init_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_init); + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_macaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_ipaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_subnetmask, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_defaultgateway, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsserver, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsname, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_append_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_macaddr, tvb, offset, ETHERNET_ADDRESS_LEN, ENC_NA); + offset+=ETHERNET_ADDRESS_LEN; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_ipaddr, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_subnetmask, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_defaultgateway, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsserver, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsname, tvb, offset, 32, ENC_ASCII|ENC_NA); + } + else + { + proto_item_append_text(anItem, " - Invalid length!"); + expert_add_info(pinfo, anItem, &ei_ecat_mailbox_eoe_error); + } + break; + + case EOE_TYPE_MACFILTER_REQ: + { + EoeMacFilterOptionsUnion options; + offset+=ETHERCAT_EOE_HEADER_LEN; + 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); + if( eoe_length-offset >= ETHERCAT_EOE_MACFILTER_LEN ) + { + proto_tree *ecat_eoe_macfilter_filtermask_tree; + + ecat_eoe_macfilter_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter); + + /* XXX: Is the field containing EoeMacFilterOptionsUnion 4 bytes or 2 bytes ? */ + /* sizeof EoeMacFilterOptionsUnion = 2 bytes but the code below */ + /* originally used a field width of 4 bytes. */ + /* Given the size of the union, the code below was changed to */ + /* use a field width of 2 bytes. */ + /* The hf[] entries were also changed to match the union struct */ + proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_macfiltercount, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_maskcount, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_nobroadcasts, tvb, offset, /*4*/ 2, ENC_LITTLE_ENDIAN); + options.Options = tvb_get_letohs(tvb, offset); + offset+=/*4*/ 2; + + anItem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_filter, tvb, offset, 16*ETHERNET_ADDRESS_LEN, ENC_NA); + ecat_eoe_macfilter_filter_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter_filter); + for( nCnt=0; nCnt<options.v.MacFilterCount; nCnt++) + 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); + offset+=16*ETHERNET_ADDRESS_LEN; + + anItem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_filtermask, tvb, offset, 4*4, ENC_NA); + ecat_eoe_macfilter_filtermask_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_eoe_macfilter_filtermask); + for( nCnt=0; nCnt<options.v.MacFilterMaskCount; nCnt++) + proto_tree_add_item(ecat_eoe_macfilter_filtermask_tree, hf_ecat_mailbox_eoe_macfilter_filtermasks[nCnt], tvb, offset+nCnt*4, 4, ENC_NA); + } + else + { + proto_item_append_text(anItem, " - Invalid length!"); + expert_add_info(pinfo, anItem, &ei_ecat_mailbox_eoe_error); + } + } + break; + + case EOE_TYPE_INIT_RES: + case EOE_TYPE_MACFILTER_RES: + break; + } + } + + col_prepend_fstr(pinfo->cinfo, COL_INFO, "EoE("); + + col_prepend_fstr(pinfo->cinfo, COL_PROTOCOL, "EoE-"); + } + else + { + expert_add_info(pinfo, tree, &ei_ecat_mailbox_eoe_error); + col_append_str(pinfo->cinfo, COL_INFO, "EoE - invalid length!"); + } +} + +static void dissect_ecat_foe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_foe_tree,*ecat_foe_efw_tree; + + proto_item *anItem= NULL,*aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint foe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + anItem = proto_tree_add_bytes_format(tree, hf_ecat_mailbox_foe, tvb, offset, foe_length, NULL, "Foe"); + + aparent = proto_item_get_parent(anItem); + proto_item_append_text(aparent,": FoE"); + } + + if( foe_length >= ETHERCAT_FOE_HEADER_LEN ) + { + FoeFormatter(tvb, pinfo->pool, offset, szText, nMax, foe_length); + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + ETHERCAT_FOE_HEADER foe; + init_foe_header(&foe, tvb, offset); + + ecat_foe_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_foe); + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_opmode, tvb, offset++, 1, ENC_LITTLE_ENDIAN); + offset++; /*Reserved1;*/ + + switch (foe.OpMode) + { + case ECAT_FOE_OPMODE_RRQ: + case ECAT_FOE_OPMODE_WRQ: + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filelength, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filename, tvb, offset, foe_length-offset, ENC_ASCII|ENC_NA); + break; + + case ECAT_FOE_OPMODE_DATA: + { + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=4; /*+2 for Reserved2*/ + + if( foe_length-offset >= sizeof(TEFWUPDATE_HEADER) ) + { + anItem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_efw, tvb, offset, foe_length-offset, ENC_NA); + ecat_foe_efw_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox_foe_efw); + proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_cmd, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_size, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresslw, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresshw, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_data, tvb, offset, foe_length-offset, ENC_NA); + } + else + { + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_data, tvb, offset, foe_length-offset, ENC_NA); + } + } + break; + + case ECAT_FOE_OPMODE_ACK: + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, ENC_LITTLE_ENDIAN); + break; + + case ECAT_FOE_OPMODE_ERR: + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errcode, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errtext, tvb, offset, foe_length-offset, ENC_ASCII|ENC_NA); + break; + + case ECAT_FOE_OPMODE_BUSY: + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busydone, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busyentire, tvb, offset, 2, ENC_LITTLE_ENDIAN); + break; + } + } + } + else + { + col_append_str(pinfo->cinfo, COL_INFO, "FoE - invalid length"); + expert_add_info(pinfo, tree, &ei_ecat_mailbox_foe_error); + } +} + +static int dissect_ecat_mailbox(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_tree *ecat_mailbox_tree = NULL; + proto_tree *ecat_mailbox_header_tree = NULL; + tvbuff_t *next_tvb; + proto_item *anItem; + gint offset = 0; + + gint mailbox_length = tvb_reported_length(tvb); + + if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN ) + { + ETHERCAT_MBOX_HEADER hdr; + + init_mbx_header(&hdr, tvb, offset); + + col_append_str(pinfo->cinfo, COL_INFO, " Mbx("); + + /* Create the mailbox sub tree */ + anItem = proto_tree_add_item(tree, proto_ecat_mailbox, tvb, 0, ETHERCAT_MBOX_HEADER_LEN+hdr.Length, ENC_NA); + ecat_mailbox_tree = proto_item_add_subtree(anItem, ett_ecat_mailbox); + + /* Create a mailbox header subtree */ + ecat_mailbox_header_tree = proto_tree_add_subtree(ecat_mailbox_tree, tvb, offset, ETHERCAT_MBOX_HEADER_LEN, ett_ecat_mailbox_header, NULL, "Header"); + + /* Add length information to the mailbox header */ + proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxlength, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + /* Add address information to the mailbox header */ + proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxaddress, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset+=2; + + /* Add priority information to the mailbox header */ + proto_tree_add_item(ecat_mailbox_header_tree, hf_ecat_mailboxpriority, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset+=1; + + /* Add type information to the mailbox header */ + proto_tree_add_uint(ecat_mailbox_header_tree, hf_ecat_mailboxtype, tvb, offset, 1, hdr.aControlUnion.v.Type); + + /* Add counter information to the mailbox header */ + proto_tree_add_uint(ecat_mailbox_header_tree, hf_ecat_mailboxcounter, tvb, offset, 1, hdr.aControlUnion.v.Counter); + offset++; + + if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN + hdr.Length ) + { + next_tvb = tvb_new_subset_length (tvb, offset, hdr.Length); + switch ( hdr.aControlUnion.v.Type ) + { + case ETHERCAT_MBOX_TYPE_ADS: + call_dissector(ams_handle, next_tvb, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_EOE: + dissect_ecat_eoe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_COE: + dissect_ecat_coe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_FOE: + dissect_ecat_foe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_SOE: + dissect_ecat_soe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + default: + proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxdata, tvb, offset, hdr.Length, ENC_NA); + } + } + else + { + anItem =proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxdata, tvb, offset, mailbox_length-ETHERCAT_MBOX_HEADER_LEN, ENC_NA); + 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); + } + col_append_str(pinfo->cinfo, COL_INFO, ")"); + } + return tvb_captured_length(tvb); +} + +void proto_register_ecat_mailbox(void) +{ + static const true_false_string flags_set_truth = + { + "Set", + "Not set" + }; + + static hf_register_info hf[] = + { + { &hf_ecat_mailboxlength, + { "Length", "ecat_mailbox.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailboxaddress, + { "Address", "ecat_mailbox.address", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailboxpriority, + { "Priority", "ecat_mailbox.priority", + FT_UINT8, BASE_DEC, NULL, 0x03, + NULL, HFILL } + }, + { &hf_ecat_mailboxtype, + { "Type", "ecat_mailbox.type", + FT_UINT8, BASE_DEC, VALS(EcMBoxType), 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailboxcounter, + { "Counter", "ecat_mailbox.counter", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe, + { "EoE Fragment", "ecat_mailbox.eoe", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_fraghead, + { "Header", "ecat_mailbox.eoe.fraghead", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_type, + { "Type", "ecat_mailbox.eoe.type", + FT_UINT32, BASE_DEC, VALS(EoEType), 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_fragno, + { "FragNo", "ecat_mailbox.eoe.fragno", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_offset, + { "Offset", "ecat_mailbox.eoe.offset", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} + }, + { &hf_ecat_mailbox_eoe_frame, + { "FrameNo", "ecat_mailbox.eoe.frame", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_last, + { "Last Fragment", "ecat_mailbox.eoe.last", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_timestampapp, + { "Time Stamp Appended", "ecat_mailbox.eoe.timestampapp", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_timestampreq, + { "Time Stamp Requested", "ecat_mailbox.eoe.timestampreq", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_fragment, + { "EoE Frag Data", "ecat_mailbox.eoe.fragment", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init, + { "Init", "ecat_mailbox.eoe.init", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_macaddr, + { "MacAddr", "ecat_mailbox.eoe.init.contains_macaddr", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000001, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_ipaddr, + { "IpAddr", "ecat_mailbox.eoe.init.contains_ipaddr", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000002, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_subnetmask, + { "SubnetMask", "ecat_mailbox.eoe.init.contains_subnetmask", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000004, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_defaultgateway, + { "DefaultGateway", "ecat_mailbox.eoe.init.contains_defaultgateway", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000008, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_dnsserver, + { "DnsServer", "ecat_mailbox.eoe.init.contains_dnsserver", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000010, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_dnsname, + { "DnsName", "ecat_mailbox.eoe.init.contains_dnsname", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000020, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_append_timestamp, + { "AppendTimeStamp", "ecat_mailbox.eoe.init.append_timestamp", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00010000, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_macaddr, + { "Mac Addr", "ecat_mailbox.eoe.init.macaddr", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_ipaddr, + { "Ip Addr", "ecat_mailbox.eoe.init.ipaddr", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_subnetmask, + { "Subnet Mask", "ecat_mailbox.eoe.init.subnetmask", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_defaultgateway, + { "Default Gateway", "ecat_mailbox.eoe.init.defaultgateway", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_dnsserver, + { "Dns Server", "ecat_mailbox.eoe.init.dnsserver", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_init_dnsname, + { "Dns Name", "ecat_mailbox.eoe.init.dnsname", + FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter, + { "Mac Filter", "ecat_mailbox.eoe.macfilter", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + + /* XXX: The following 3 fields may not be specified correctly */ + /* See related comment above */ + { &hf_ecat_mailbox_eoe_macfilter_macfiltercount, + { "Mac Filter Count", "ecat_mailbox.eoe.macfilter.macfiltercount", + FT_UINT16, BASE_DEC, NULL, 0xF000, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_maskcount, + { "Mac Filter Mask Count", "ecat_mailbox.eoe.macfilter.maskcount", + FT_UINT16, BASE_DEC, NULL, 0x0C00, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_nobroadcasts, + { "No Broadcasts", "ecat_mailbox.eoe.macfilter.nobroadcasts", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0100, NULL, HFILL } + }, + /* ... */ + + { &hf_ecat_mailbox_eoe_macfilter_filter, + { "Filter", "ecat_mailbox.eoe.macfilter.filter", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[0], + { "Filter 0", "ecat_mailbox.eoe.macfilter.filter0", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[1], + { "Filter 1", "ecat_mailbox.eoe.macfilter.filter1", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[2], + { "Filter 2", "ecat_mailbox.eoe.macfilter.filter2", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[3], + { "Filter 3", "ecat_mailbox.eoe.macfilter.filter3", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[4], + { "Filter 4", "ecat_mailbox.eoe.macfilter.filter4", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[5], + { "Filter 5", "ecat_mailbox.eoe.macfilter.filter5", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[6], + { "Filter 6", "ecat_mailbox.eoe.macfilter.filter6", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[7], + { "Filter 7", "ecat_mailbox.eoe.macfilter.filter7", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[8], + { "Filter 8", "ecat_mailbox.eoe.macfilter.filter8", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[9], + { "Filter 9", "ecat_mailbox.eoe.macfilter.filter9", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[10], + { "Filter 10", "ecat_mailbox.eoe.macfilter.filter10", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[11], + { "Filter 11", "ecat_mailbox.eoe.macfilter.filter11", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[12], + { "Filter 12", "ecat_mailbox.eoe.macfilter.filter12", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[13], + { "Filter 13", "ecat_mailbox.eoe.macfilter.filter13", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[14], + { "Filter 14", "ecat_mailbox.eoe.macfilter.filter14", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[15], + { "Filter 15", "ecat_mailbox.eoe.macfilter.filter15", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermask, + { "Filter Mask", "ecat_mailbox.eoe.macfilter.filtermask", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[0], + { "Mask 0", "ecat_mailbox.eoe.macfilter.filtermask0", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[1], + { "Mask 1", "ecat_mailbox.eoe.macfilter.filtermask1", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[2], + { "Mask 2", "ecat_mailbox.eoe.macfilter.filtermask2", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[3], + { "Mask 3", "ecat_mailbox.eoe.macfilter.filtermask3", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_eoe_timestamp, + { "Time Stamp", "ecat_mailbox.eoe.timestamp", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe, + { "CoE", "ecat_mailbox.coe", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_number, + { "Number", "ecat_mailbox.coe.number", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_type, + { "Type", "ecat_mailbox.coe.type", + FT_UINT16, BASE_DEC, VALS(CANopenType), 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoreq, + { "SDO Req", "ecat_mailbox.coe.sdoreq", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid, + { "Initiate Download", "ecat_mailbox.coe.sdoccsid", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_sizeind, + { "Size Ind.", "ecat_mailbox.coe.sdoccsid.sizeind", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x01, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_expedited, + { "Expedited", "ecat_mailbox.coe.sdoccsid.expedited", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x02, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_size0, + { "Bytes", "ecat_mailbox.coe.sdoccsid.size0", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x04, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_size1, + { "Bytes", "ecat_mailbox.coe.sdoccsid.size1", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x08, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_complete, + { "Access", "ecat_mailbox.coe.sdoccsid.complete", + FT_BOOLEAN, 8, TFS(&tfs_complete), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds, + { "Download Segment", "ecat_mailbox.coe.sdoccsds", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_lastseg, + { "Last Segment", "ecat_mailbox.coe.sdoccsds.lastseg", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x01, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_size, + { "Size", "ecat_mailbox.coe.sdoccsds.size", + FT_UINT8, BASE_DEC, NULL, 0x0E, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsds.toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsiu, + { "Init Upload", "ecat_mailbox.coe.sdoccsiu", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ecat_mailbox_coe_sdoccsiu_complete, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsiu.complete", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x10, + NULL, HFILL } + }, +#endif + { &hf_ecat_mailbox_coe_sdoccsus, + { "Upload Segment", "ecat_mailbox.coe.sdoccsus", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsus_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsus_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoidx, + { "Index", "ecat_mailbox.coe.sdoidx", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoabortcode, + { "Abort code", "ecat_mailbox.coe.abortcode", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdosub, + { "SubIndex", "ecat_mailbox.coe.sdosub", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata, + { "Data", "ecat_mailbox.coe.sdodata", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata1, + { "Data", "ecat_mailbox.coe.sdodata", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata2, + { "Data", "ecat_mailbox.coe.sdodata", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoldata, + { "Data", "ecat_mailbox.coe.dsoldata", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdolength, + { "Length", "ecat_mailbox.coe.sdolength", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ecat_mailbox_coe_sdoerror, + { "SDO Error", "ecat_mailbox.coe.sdoerror", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_ecat_mailbox_coe_sdores, + { "SDO Res", "ecat_mailbox.coe.sdores", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu, + { "Initiate Upload Response", "ecat_mailbox.coe.sdoscsiu", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_sizeind, + { "Size Ind.", "ecat_mailbox.coe.sdoscsiu_sizeind", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x01, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_expedited, + { "Expedited", "ecat_mailbox.coe.sdoscsiu_expedited", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x02, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_size0, + { "Bytes", "ecat_mailbox.coe.sdoscsiu_size0", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x04, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_size1, + { "Bytes", "ecat_mailbox.coe.sdoscsiu_size1", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x08, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_complete, + { "Access", "ecat_mailbox.coe.sdoscsiu_complete", + FT_BOOLEAN, 8, TFS(&tfs_complete), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsds, + { "Download Segment Response", "ecat_mailbox.coe.sdoscsds", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsds_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoscsds_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus, + { "Upload Segment", "ecat_mailbox.coe.sdoscsus", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_lastseg, + { "Last Segment", "ecat_mailbox.coe.sdoscsus_lastseg", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x01, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_bytes, + { "Bytes", "ecat_mailbox.coe.sdoscsus_bytes", + FT_UINT8, BASE_DEC, NULL, 0x0E, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoscsus_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x10, + NULL, HFILL } + }, + { &hf_ecat_mailbox_coe_sdoinfoopcode, + { "Info OpCode", "ecat_mailbox.coe.sdoinfoopcode", + FT_UINT8, BASE_DEC, VALS(CANopenSdoInfo), 0x0, + NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfofrag, + { "Info Frag Left", "ecat_mailbox.coe.sdoinfofrag", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfolisttype, + { "Info List Type", "ecat_mailbox.coe.sdoinfolisttype", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfolist, + { "Info List", "ecat_mailbox.coe.sdoinfolist", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoindex, + { "Info Obj Index", "ecat_mailbox.coe.sdoinfoindex", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfosubindex, + { "Info Obj SubIdx", "ecat_mailbox.coe.sdoinfosubindex", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfovalueinfo, + { "Info Obj ValueInfo", "ecat_mailbox.coe.sdoinfovalueinfo", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoerrorcode, + { "Info Error Code", "ecat_mailbox.coe.sdoinfoerrorcode", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfodatatype, + { "Info Data Type", "ecat_mailbox.coe.sdoinfodatatype", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfomaxsub, + { "Info Max SubIdx", "ecat_mailbox.coe.sdoinfomaxsub", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoobjcode, + { "Info Obj Code", "ecat_mailbox.coe.sdoinfoobjcode", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoname, + { "Info Name", "ecat_mailbox.coe.sdoinfoname", + FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfobitlen, + { "Info Bit Len", "ecat_mailbox.coe.sdoinfobitlen", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoobjaccess, + { "Info Obj Access", "ecat_mailbox.coe.sdoinfoobjaccess", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfounittype, + { "Info Data Type", "ecat_mailbox.coe.sdoinfounittype", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfodefaultvalue, + { "Info Default Val", "ecat_mailbox.coe.sdoinfodefaultvalue", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfominvalue, + { "Info Min Val", "ecat_mailbox.coe.sdoinfominvalue", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfomaxvalue, + { "Info Max Val", "ecat_mailbox.coe.sdoinfomaxvalue", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }, + }, + { &hf_ecat_mailboxdata, + { "MB Data", "ecat_mailbox.data", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe, + { "Foe", "ecat_mailbox.foe", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_opmode, + { "Foe OpMode", "ecat_mailbox.foe_opmode", + FT_UINT8, BASE_HEX, VALS(FoEOpMode), 0x0, "Op modes", HFILL } + }, + { &hf_ecat_mailbox_foe_filelength, + { "Foe FileLength", "ecat_mailbox.foe_filelength", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_filename, + { "Foe FileName", "ecat_mailbox.foe_filename", + FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_packetno, + { "Foe PacketNo", "ecat_mailbox.foe_packetno", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_errcode, + { "Foe ErrorCode", "ecat_mailbox.foe_errcode", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_errtext, + { "Foe ErrorString", "ecat_mailbox.foe_errtext", + FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_busydone, + { "Foe BusyDone", "ecat_mailbox.foe_busydone", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_busyentire, + { "Foe BusyEntire", "ecat_mailbox.foe_busyentire", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_data, + { "Foe Data", "ecat_mailbox.foe_busydata", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw, + { "Firmware", "ecat_mailbox.foe.efw", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw_cmd, + { "Cmd", "ecat_mailbox.foe.efw.cmd", + FT_UINT16, BASE_HEX, VALS(FoEEfwCmd), 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw_size, + { "Size", "ecat_mailbox.foe.efw.size", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw_addresslw, + { "AddressLW", "ecat_mailbox.foe.efw.addresslw", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw_addresshw, + { "AddressHW", "ecat_mailbox.foe.efw.addresshw", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_foe_efw_data, + { "Data", "ecat_mailbox.foe.efw.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe, + { "Soe", "ecat_mailbox.soe", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header, + { "Soe Header", "ecat_mailbox.soe_header", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_opcode, + { "SoE OpCode", "ecat_mailbox.soe_opcode", + FT_UINT16, BASE_DEC, VALS(SoeOpcode), 0x0007, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_incomplete, + { "More Follows...", "ecat_mailbox.soe_header_incomplete", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0008, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_error, + { "Error", "ecat_mailbox.soe_header_error", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0010, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_driveno, + { "Drive No", "ecat_mailbox.soe_header_driveno", + FT_UINT16, BASE_DEC, NULL, 0x00e0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_datastate, + { "Datastate", "ecat_mailbox.soe_header_datastate", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0100, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_name, + { "Name", "ecat_mailbox.soe_header_name", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0200, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_attribute, + { "Attribute", "ecat_mailbox.soe_header_attribute", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0400, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_unit, + { "Unit", "ecat_mailbox.soe_header_unit", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0800, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_min, + { "Min", "ecat_mailbox.soe_header_min", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x1000, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_max, + { "Max", "ecat_mailbox.soe_header_max", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x2000, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_value, + { "Value", "ecat_mailbox.soe_header_value", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x4000, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_header_reserved, + { "Reserved", "ecat_mailbox.soe_header_reserved", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x8000, + NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_idn, + { "SoE IDN", "ecat_mailbox.soe_idn", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_data, + { "SoE Data", "ecat_mailbox.soe_data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_frag, + { "SoE FragLeft", "ecat_mailbox.soe_frag", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_mailbox_soe_error, + { "SoE Error", "ecat_mailbox.soe_error", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + } + }; + + static gint *ett[] = + { + &ett_ecat_mailbox, + &ett_ecat_mailbox_eoe, + &ett_ecat_mailbox_eoe_init, + &ett_ecat_mailbox_eoe_macfilter, + &ett_ecat_mailbox_eoe_macfilter_filter, + &ett_ecat_mailbox_eoe_macfilter_filtermask, + &ett_ecat_mailbox_coe, + &ett_ecat_mailbox_sdo, + &ett_ecat_mailbox_coe_sdoccs, + &ett_ecat_mailbox_coe_sdoscs, + &ett_ecat_mailbox_foe, + &ett_ecat_mailbox_foe_efw, + &ett_ecat_mailbox_soeflag, + &ett_ecat_mailbox_soe, + &ett_ecat_mailbox_fraghead, + &ett_ecat_mailbox_header + }; + + static ei_register_info ei[] = + { + { &ei_ecat_mailbox_error, { "ecat_mailbox.invalid", PI_MALFORMED, PI_ERROR, "Malformed mailbox data", EXPFILL } }, + { &ei_ecat_mailbox_coe_error, { "ecat_mailbox.coe.invalid", PI_MALFORMED, PI_ERROR, "Malformed CoE data", EXPFILL } }, + { &ei_ecat_mailbox_foe_error, { "ecat_mailbox.foe.invalid", PI_MALFORMED, PI_ERROR, "Malformed FoE data", EXPFILL } }, + { &ei_ecat_mailbox_soe_error, { "ecat_mailbox.soe.invalid", PI_MALFORMED, PI_ERROR, "Malformed SoE data", EXPFILL } }, + { &ei_ecat_mailbox_eoe_error, { "ecat_mailbox.eoe.invalid", PI_MALFORMED, PI_ERROR, "Malformed EoE data", EXPFILL } }, + }; + + expert_module_t *expert_module; + + proto_ecat_mailbox = proto_register_protocol("EtherCAT Mailbox Protocol", + "ECAT_MAILBOX", "ecat_mailbox"); + + expert_module = expert_register_protocol(proto_ecat_mailbox); + expert_register_field_array(expert_module, ei, array_length(ei)); + + proto_register_field_array(proto_ecat_mailbox, hf,array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + ecat_mailbox_handle = register_dissector("ecat_mailbox", dissect_ecat_mailbox, proto_ecat_mailbox); +} + +void proto_reg_handoff_ecat_mailbox(void) +{ + /* Register this dissector as a sub dissector to E88A4 based on ether type. */ + dissector_add_uint("ecatf.type", 5, ecat_mailbox_handle); + + eth_handle = find_dissector_add_dependency("eth_withoutfcs", proto_ecat_mailbox); + ams_handle = find_dissector_add_dependency("ams", proto_ecat_mailbox); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ecatmb.h b/plugins/epan/ethercat/packet-ecatmb.h new file mode 100644 index 00000000..54dce708 --- /dev/null +++ b/plugins/epan/ethercat/packet-ecatmb.h @@ -0,0 +1,469 @@ +/* packet-ecatmb.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef _PACKET_ECATMAILBOX_H_ +#define _PACKET_ECATMAILBOX_H_ + +#include <ws_diag_control.h> +DIAG_OFF_PEDANTIC + +/* Ensure the same data layout for all platforms */ + +typedef struct TETHERNET_ADDRESS +{ + guint8 b[6]; +} ETHERNET_ADDRESS, *PETHERNET_ADDRESS; +#define ETHERNET_ADDRESS_LEN ((int) sizeof(ETHERNET_ADDRESS)) + +/* Mailbox*/ +#define ETHERCAT_MBOX_TYPE_ADS 1 /* AMS/ADS header follows*/ +#define ETHERCAT_MBOX_TYPE_EOE 2 /* ETHERCAT_EOE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_COE 3 /* ETHERCAT_COE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_FOE 4 /* ETHERCAT_FOE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_SOE 5 /* ETHERCAT_SOE_HEADER follows*/ + +typedef union tMbxHeaderControlUnion +{ + guint16 Control; + struct + { + guint16 Channel : 6; /* optional communication channels (default = 0)*/ + guint16 Priority : 2; /* optional communication priority (default = 0)*/ + guint16 Type : 4; /* TETHERCAT_MBOX_TYPE_xxx*/ + guint16 Counter : 3; /* 0 = counter not used (old version)*/ + guint16 Unsupported : 1; /* unsupported protocol detected*/ + } v; +} MbxHeaderControlUnion; + +typedef struct TETHERCAT_MBOX_HEADER +{ + guint16 Length; /* following bytes*/ + guint16 Address; /* S->M: phys addr of destination; M->S: phys addr of source; 0 = master*/ + MbxHeaderControlUnion aControlUnion; +} ETHERCAT_MBOX_HEADER, *PETHERCAT_MBOX_HEADER; + +#define ETHERCAT_MBOX_HEADER_LEN ((int) sizeof(ETHERCAT_MBOX_HEADER)) + +/* EoE*/ +#define ETHERNET_FRAMENO_MASK 0x0000000F + +#define EOE_TYPE_FRAME_FRAG 0 /* ETHERCAT_EOE_HEADER followed by frame fragment (ETHERCAT_EOE_TIMESTAMP may included) */ +#define EOE_TYPE_TIMESTAMP_RES 1 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_TIMESTAMP */ +#define EOE_TYPE_INIT_REQ 2 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_INIT */ +#define EOE_TYPE_INIT_RES 3 /* ETHERCAT_EOE_HEADER */ +#define EOE_TYPE_MACFILTER_REQ 4 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_MACFILTER */ +#define EOE_TYPE_MACFILTER_RES 5 /* ETHERCAT_EOE_HEADER */ + +#define EOE_RESULT_NOERROR 0x0000 +#define EOE_RESULT_UNSPECIFIED_ERROR 0x0001 +#define EOE_RESULT_UNSUPPORTED_TYPE 0x0002 +#define EOE_RESULT_NO_IP_SUPPORT 0x0201 +#define EOE_RESULT_NO_MACFILTERMASK_SUPPORT 0x0401 + + +/*typedef struct TETHERCAT_EOE_INIT +{ + guint32 ContainsMacAddr :1; + guint32 ContainsIpAddr :1; + guint32 ContainsSubnetMask :1; + guint32 ContainsDefaultGateway :1; + guint32 ContainsDnsServer :1; + guint32 ContainsDnsName :1; + guint32 Reserved :26; + ETHERNET_ADDRESS MacAddr; + guint32 IpAddr; + guint32 SubnetMask; + guint32 DefaultGateway; + guint32 DnsServer; + char DnsName[32]; +} ETHERCAT_EOE_INIT, *PETHERCAT_EOE_INIT;*/ +#define ETHERCAT_EOE_INIT_LEN 58 /*sizeof(ETHERCAT_EOE_INIT)*/ + +typedef union tEoeMacFilterOptionsUnion +{ + struct + { + guint16 MacFilterCount :4; + guint16 MacFilterMaskCount :2; + guint16 Reserved1 :1; + guint16 NoBroadcasts :1; + guint16 Reserved2 :8; + } v; + guint16 Options; +} EoeMacFilterOptionsUnion; + +typedef struct TETHERCAT_EOE_MACFILTER +{ + EoeMacFilterOptionsUnion anEoeMacFilterOptionsUnion; + ETHERNET_ADDRESS MacFilter[16]; + ETHERNET_ADDRESS MacFilterMask[4]; +} ETHERCAT_EOE_MACFILTER; +#define ETHERCAT_EOE_MACFILTER_LEN ((int) sizeof(ETHERCAT_EOE_MACFILTER)) + +typedef struct TETHERCAT_EOE_TIMESTAMP +{ + guint32 TimeStamp; /* 32 bit time stamp */ +} ETHERCAT_EOE_TIMESTAMP; +#define ETHERCAT_EOE_TIMESTAMP_LEN ((int) sizeof(ETHERCAT_EOE_TIMESTAMP)) + +typedef union tEoeHeaderDataUnion +{ + struct + { /* EOE_TYPE_FRAME_FRAG and EOE_TYPE_TIMESTAMP_RES only */ + guint16 Fragment : 6; /* fragment number (EOE_TYPE_FRAME_FRAG only) */ + guint16 OffsetBuffer : 6; /* byte offset multiplied by 32 (if Fragment != 0) (EOE_TYPE_FRAME_FRAG only) */ + /* buffer size multiplied by 32 (if Fragment == 0) (EOE_TYPE_FRAME_FRAG only) */ + guint16 FrameNo : 4; /* frame number (EOE_TYPE_FRAME_FRAG and EOE_TYPE_TIMESTAMP_RES only) */ + } v; + guint16 Result; /* EOE_TYPE_INIT_RES and EOE_TYPE_MACFILTER_RES only */ +} EoeHeaderDataUnion; + +typedef union tEoeHeaderInfoUnion +{ + struct + { + guint16 Type : 4; /* specifies following data */ + guint16 PortAssign : 4; /* 0 = unspecified, 1 = port 1 */ + guint16 LastFragment : 1; /* TRUE if last fragment (EOE_TYPE_FRAME_FRAG only) */ + guint16 TimeStampAppended : 1; /* 32 bit time stamp appended (EOE_TYPE_FRAME_FRAG with LastFragment=1 only) */ + guint16 TimeStampRequested : 1; /* time stamp response requested (EOE_TYPE_FRAME_FRAG only) */ + guint16 Reserved : 5; + } v; + guint16 Info; +} EoeHeaderInfoUnion; + +typedef struct TETHERCAT_EOE_HEADER +{ + EoeHeaderInfoUnion anEoeHeaderInfoUnion; + EoeHeaderDataUnion anEoeHeaderDataUnion; +} ETHERCAT_EOE_HEADER, *PETHERCAT_EOE_HEADER; +#define ETHERCAT_EOE_HEADER_LEN ((int) sizeof(ETHERCAT_EOE_HEADER)) + +/* CANopen*/ +#define ETHERCAT_COE_TYPE_EMERGENCY 1 +#define ETHERCAT_COE_TYPE_SDOREQ 2 +#define ETHERCAT_COE_TYPE_SDORES 3 +#define ETHERCAT_COE_TYPE_TXPDO 4 +#define ETHERCAT_COE_TYPE_RXPDO 5 +#define ETHERCAT_COE_TYPE_TXPDO_RTR 6 /* Remote transmission request of TXPDO (master requested)*/ +#define ETHERCAT_COE_TYPE_RXPDO_RTR 7 /* Remote transmission request of RXPDO (slave requested) */ +#define ETHERCAT_COE_TYPE_SDOINFO 8 + +typedef union TETHERCAT_COE_HEADER +{ + struct + { + guint16 Number : 9; /* e.g. PDO number*/ + guint16 Reserved : 3; /* = 0*/ + guint16 Type : 4; /* CANopen type*/ + } v; + guint16 header; +} ETHERCAT_COE_HEADER, *PETHERCAT_COE_HEADER; +#define ETHERCAT_COE_HEADER_LEN ((int) sizeof(ETHERCAT_COE_HEADER)) + + +typedef union tSdoHeaderUnion +{ + struct + { /* Initiate Download Request*/ + guint8 SizeInd : 1; + guint8 Expedited : 1; + guint8 Size : 2; + guint8 Complete : 1; + guint8 Ccs : 3; /* = 1*/ + } Idq; + struct + { /* Initiate Download Response*/ + guint8 Reserved : 5; + guint8 Scs : 3; /* = 3*/ + } Ids; + struct + { /* Download Segment Request*/ + guint8 LastSeg : 1; + guint8 Size : 3; + guint8 Toggle : 1; + guint8 Ccs : 3; /* = 0*/ + } Dsq; + struct + { /* Download Segment Response*/ + guint8 Reserved : 4; + guint8 Toggle : 1; + guint8 Scs : 3; /* = 1*/ + } Dss; + struct + { /* Initiate Upload Request*/ + guint8 Reserved : 4; + guint8 Complete : 1; + guint8 Ccs : 3; /* = 2*/ + } Iuq; + struct + { /* Initiate Upload Response*/ + guint8 SizeInd : 1; + guint8 Expedited : 1; + guint8 Size : 2; + guint8 Complete : 1; + guint8 Scs : 3; /* = 2*/ + } Ius; + struct + { /* Upload Segment Request*/ + guint8 Reserved : 4; + guint8 Toggle : 1; + guint8 Ccs : 3; /* = 3*/ + } Usq; + struct + { /* Upload Segment Response*/ + guint8 LastSeg : 1; + guint8 Bytes : 3; + guint8 Toggle : 1; + guint8 Scs : 3; /* = 0*/ + } Uss; + struct + { /* Abort Transfer*/ + guint8 Reserved : 5; + guint8 Ccs : 3; /* = 4*/ + } Abt; + guint8 CS; +} SdoHeaderUnion; + +typedef struct TETHERCAT_SDO_HEADER +{ + SdoHeaderUnion anSdoHeaderUnion; + + guint16 Index; + guint8 SubIndex; + guint32 Data; +} ETHERCAT_SDO_HEADER, *PETHERCAT_SDO_HEADER; + +#define ETHERCAT_SDO_HEADER_LEN 8 /* sizeof(ETHERCAT_SDO_HEADER)*/ + +#define SDO_CCS_DOWNLOAD_SEGMENT 0 +#define SDO_CCS_INITIATE_DOWNLOAD 1 +#define SDO_CCS_INITIATE_UPLOAD 2 +#define SDO_CCS_UPLOAD_SEGMENT 3 +#define SDO_CCS_ABORT_TRANSFER 4 + +#define SDO_SCS_UPLOAD_SEGMENT 0 +#define SDO_SCS_DOWNLOAD_SEGMENT 1 +#define SDO_SCS_INITIATE_UPLOAD 2 +#define SDO_SCS_INITIATE_DOWNLOAD 3 + +/* CoE SDO Information */ +#define ECAT_COE_INFO_OPCODE_LIST_Q 1 +#define ECAT_COE_INFO_OPCODE_LIST_S 2 +#define ECAT_COE_INFO_OPCODE_OBJ_Q 3 +#define ECAT_COE_INFO_OPCODE_OBJ_S 4 +#define ECAT_COE_INFO_OPCODE_ENTRY_Q 5 +#define ECAT_COE_INFO_OPCODE_ENTRY_S 6 +#define ECAT_COE_INFO_OPCODE_ERROR_S 7 + +#define ECAT_COE_INFO_LIST_TYPE_LENGTH 0 +#define ECAT_COE_INFO_LIST_TYPE_ALL 1 +#define ECAT_COE_INFO_LIST_TYPE_PDOMAP 2 +#define ECAT_COE_INFO_LIST_TYPE_BACKUP 3 + +#define ECAT_COE_INFO_OBJCODE_NULL 0 +#define ECAT_COE_INFO_OBJCODE_DOMAIN 2 +#define ECAT_COE_INFO_OBJCODE_DEFTYPE 5 +#define ECAT_COE_INFO_OBJCODE_DEFSTRUCT 6 +#define ECAT_COE_INFO_OBJCODE_VAR 7 +#define ECAT_COE_INFO_OBJCODE_ARRAY 8 +#define ECAT_COE_INFO_OBJCODE_RECORD 9 + +#define ECAT_COE_INFO_OBJCAT_OPTIONAL 0 +#define ECAT_COE_INFO_OBJCAT_MANDATORY 1 + +#define ECAT_COE_INFO_OBJACCESS_RO 0x07 +#define ECAT_COE_INFO_OBJACCESS_RW 0x3f + +typedef struct TETHERCAT_SDO_INFO_LIST +{ + guint16 ListType; /* == SDO_INFO_LIST_TYPE_XXX */ + struct + { + guint16 Index[1]; + } Res; +} ETHERCAT_SDO_INFO_LIST; + +typedef struct TETHERCAT_SDO_INFO_OBJ +{ + guint16 Index; + struct + { + guint16 DataType; /* refer to data type index */ + guint8 MaxSubIndex; /* max subIndex */ + guint8 ObjCode; /* defined in DS 301 (Table 37)*/ + char Name[1]; /* rest of mailbox data*/ + } Res; +} ETHERCAT_SDO_INFO_OBJ; + +typedef struct TETHERCAT_SDO_INFO_ENTRY +{ + guint16 Index; + guint8 SubIdx; + guint8 ValueInfo; /* bit0 = ObjAccess, bit1 = ObjCategory, bit2 = PdoMapping, bit3 = UnitType + bit4 = DefaultValue, bit5 = MinValue, bit6 = MaxValue*/ + struct + { + guint16 DataType; /* refer to data type index */ + guint16 BitLen; + guint16 ObjAccess; /* bit0 = read; bit1 = write; bit2 = const. bit3 = 'PRE-OP'; bit4 = 'SAFE-OP'; bit5 = 'OP'.*/ + } Res; +} ETHERCAT_SDO_INFO_ENTRY; + +typedef struct TETHERCAT_SDO_INFO_ERROR +{ + guint32 ErrorCode; + char ErrorText[1]; /* rest of mailbox data */ +} ETHERCAT_SDO_INFO_ERROR; + +typedef union tSdoInfoUnion +{ + ETHERCAT_SDO_INFO_LIST List; + ETHERCAT_SDO_INFO_OBJ Obj; + ETHERCAT_SDO_INFO_ENTRY Entry; + ETHERCAT_SDO_INFO_ERROR Error; + guint8 Data[1]; +} SdoInfoUnion; + +typedef union tSdoControlUnion +{ + struct + { + guint8 OpCode : 7; /* == SDO_INFO_TYPE_XXX */ + guint8 InComplete : 1; + } v; + guint8 Control; +} SdoControlUnion; + +typedef struct TETHERCAT_SDO_INFO_HEADER +{ + SdoControlUnion anSdoControlUnion; + guint8 Reserved; /* == 0 */ + guint16 FragmentsLeft; + SdoInfoUnion anSdoInfoUnion; +} ETHERCAT_SDO_INFO_HEADER, *PETHERCAT_SDO_INFO_HEADER; + +#define ETHERCAT_SDO_INFO_LISTREQ_LEN 6 /*offsetof(ETHERCAT_SDO_INFO_HEADER, anSdoInfoUnion.List.Res)*/ + +/* FoE (File Access over EtherCAT)*/ +#define ECAT_FOE_OPMODE_RRQ 1 +#define ECAT_FOE_OPMODE_WRQ 2 +#define ECAT_FOE_OPMODE_DATA 3 +#define ECAT_FOE_OPMODE_ACK 4 +#define ECAT_FOE_OPMODE_ERR 5 +#define ECAT_FOE_OPMODE_BUSY 6 + +#define ECAT_FOE_ERRCODE_NOTDEFINED 0 +#define ECAT_FOE_ERRCODE_NOTFOUND 1 +#define ECAT_FOE_ERRCODE_ACCESS 2 +#define ECAT_FOE_ERRCODE_DISKFULL 3 +#define ECAT_FOE_ERRCODE_ILLEAGAL 4 +#define ECAT_FOE_ERRCODE_PACKENO 5 +#define ECAT_FOE_ERRCODE_EXISTS 6 +#define ECAT_FOE_ERRCODE_NOUSER 7 +#define ECAT_FOE_ERRCODE_BOOTSTRAPONLY 8 +#define ECAT_FOE_ERRCODE_NOTINBOOTSTRAP 9 + +typedef union tFoeHeaderDataUnion +{ + guint32 FileLength; /* (RRQ, WRQ) = 0 if unknown */ + struct + { + guint16 PacketNo; /* (DATA, ACK)*/ + guint16 Reserved2; /* (DATA, ACK)*/ + } v; + guint32 ErrorCode; /* (ERR)*/ + struct + { + guint16 Done; /* (BUSY)*/ + guint16 Entire; /* (BUSY)*/ + } v2; +} FoeHeaderDataUnion; + +typedef struct TETHERCAT_FOE_HEADER +{ + guint8 OpMode; /* = 1 (RRQ), = 2 (WRQ), = 3 (DATA), = 4 (ACK), = 5 (ERR), = 6 (BUSY) */ + guint8 Reserved1; /* = 0 */ + + FoeHeaderDataUnion aFoeHeaderDataUnion; + /* typedef union tMailBoxDataUnion + { + char Name[] (RRQ, WRQ) rest of mailbox data + guint8 Data[] (DATA) rest of mailbox data (if OpMode = 3) + char ErrorText[] (ERR) rest of mailbox data + } MailBoxDataUnion;*/ +} ETHERCAT_FOE_HEADER, *PETHERCAT_FOE_HEADER; +#define ETHERCAT_FOE_HEADER_LEN 6 /*sizeof(ETHERCAT_FOE_HEADER)*/ + +typedef struct +{ + guint16 Cmd; + guint16 Size; + guint16 AddressLW; + guint16 AddressHW; +} TEFWUPDATE_HEADER; + + +/* SoE (SOE over EtherCAT)*/ +#define ECAT_SOE_OPCODE_RRQ 1 +#define ECAT_SOE_OPCODE_RRS 2 +#define ECAT_SOE_OPCODE_WRQ 3 +#define ECAT_SOE_OPCODE_WRS 4 +#define ECAT_SOE_OPCODE_NFC 5 + + +typedef union tSoeHeaderControlUnion +{ + struct + { + guint8 OpCode : 3; /* 0 = unused, 1 = readReq, 2 = readRes, 3 = writeReq, 4 = writeRes + 5 = notification (command changed notification)*/ + guint8 InComplete : 1; /* more follows*/ + guint8 Error : 1; /* an error word follows */ + guint8 DriveNo : 3; /* drive number */ + + guint8 DataState : 1; /* follows or requested */ + guint8 Name : 1; /* follows or requested */ + guint8 Attribute : 1; /* follows or requested */ + guint8 Unit : 1; /* follows or requested */ + guint8 Min : 1; /* follows or requested */ + guint8 Max : 1; /* follows or requested */ + guint8 Value : 1; /* follows or requested */ + guint8 Reserved : 1; + } v; + struct + { + guint8 Control; + guint8 Element; + } v2; +} SoeHeaderControlUnion; + +typedef union tSoeHeaderDataUnion +{ + guint16 IDN; /* SOE IDN if (InComplete==0) */ + guint16 FragmentsLeft; /* Pending fragments if (InComplete==1) */ +} SoeHeaderDataUnion; + +typedef struct TETHERCAT_SOE_HEADER +{ + SoeHeaderControlUnion anSoeHeaderControlUnion; + SoeHeaderDataUnion anSoeHeaderDataUnion; + /* typedef union tMailBoxDataUnion + { + guint8 Data[] rest of mailbox data if (Error==0) + guint16 ErrorCode if (Error==1) + } MailBoxDataUnion;*/ +} ETHERCAT_SOE_HEADER, *PETHERCAT_SOE_HEADER; +#define ETHERCAT_SOE_HEADER_LEN ((int) sizeof(ETHERCAT_SOE_HEADER)) + +extern void init_mbx_header(PETHERCAT_MBOX_HEADER pMbox, tvbuff_t *tvb, gint offset); + +DIAG_ON_PEDANTIC +#endif /* _PACKET_ECATMAILBOX_H_ */ diff --git a/plugins/epan/ethercat/packet-esl.c b/plugins/epan/ethercat/packet-esl.c new file mode 100644 index 00000000..75f269b4 --- /dev/null +++ b/plugins/epan/ethercat/packet-esl.c @@ -0,0 +1,372 @@ +/* packet-esl.c + * Routines for EtherCAT Switch Link disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1999 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <epan/packet.h> +#include <epan/prefs.h> + +void proto_register_esl(void); + +#if 0 +/* XXX: using bitfields is compiler dependent: See README.developer */ + +typedef union _EslFlagsUnion +{ + struct + { + guint16 port7 : 1; + guint16 port6 : 1; + guint16 port5 : 1; + guint16 port4 : 1; + guint16 port3 : 1; + guint16 port2 : 1; + guint16 port1 : 1; + guint16 port0 : 1; + guint16 extended : 1; + guint16 port11 : 1; + guint16 port10 : 1; + guint16 alignError : 1; + guint16 crcError : 1; + guint16 timeStampEna : 1; + guint16 port9 : 1; + guint16 port8 : 1; + }d; + struct + { + guint8 loPorts : 1; + guint8 flagsHiPorts : 1; + }lo_hi_flags; + guint flags; +} EslFlagsUnion; +#endif + +#define esl_port7_bitmask 0x0001 +#define esl_port6_bitmask 0x0002 +#define esl_port5_bitmask 0x0004 +#define esl_port4_bitmask 0x0008 +#define esl_port3_bitmask 0x0010 +#define esl_port2_bitmask 0x0020 +#define esl_port1_bitmask 0x0040 +#define esl_port0_bitmask 0x0080 +#define esl_extended_bitmask 0x0100 +#define esl_port11_bitmask 0x0200 +#define esl_port10_bitmask 0x0400 +#define esl_alignError_bitmask 0x0800 +#define esl_crcError_bitmask 0x1000 +#define esl_timeStampEna_bitmask 0x2000 +#define esl_port9_bitmask 0x4000 +#define esl_port8_bitmask 0x8000 + +#if 0 +typedef struct _EslHeader +{ + guint8 eslCookie[6]; /* 01 01 05 10 00 00 */ + EslFlagsUnion flags; + guint64 timeStamp; +} EslHeader, *PEslHeader; +#endif + + +#define SIZEOF_ESLHEADER 16 + +static dissector_handle_t eth_withoutfcs_handle; + +void proto_reg_handoff_esl(void); + +/* Define the esl proto */ +int proto_esl = -1; + +static int ett_esl = -1; + +static int hf_esl_timestamp = -1; +static int hf_esl_port = -1; +static int hf_esl_crcerror = -1; +static int hf_esl_alignerror = -1; + +/* Note: using external tfs strings apparently doesn't work in a plugin */ +static const true_false_string flags_yes_no = { + "yes", + "no" +}; + +#if 0 +/* XXX: using bitfields is compiler dependent: See README.developer */ +static guint16 flags_to_port(guint16 flagsValue) { + EslFlagsUnion flagsUnion; + flagsUnion.flags = flagsValue; + if ( flagsUnion.d.port0 ) + return 0; + else if ( flagsUnion.d.port1 ) + return 1; + else if ( flagsUnion.d.port2 ) + return 2; + else if ( flagsUnion.d.port3 ) + return 3; + else if ( flagsUnion.d.port4 ) + return 4; + else if ( flagsUnion.d.port5 ) + return 5; + else if ( flagsUnion.d.port6 ) + return 6; + else if ( flagsUnion.d.port7 ) + return 7; + else if ( flagsUnion.d.port8 ) + return 8; + else if ( flagsUnion.d.port9 ) + return 9; + + return -1; +} +#endif + +static guint16 flags_to_port(guint16 flagsValue) { + if ( (flagsValue & esl_port0_bitmask) != 0 ) + return 0; + else if ( (flagsValue & esl_port1_bitmask) != 0 ) + return 1; + else if ( (flagsValue & esl_port2_bitmask) != 0 ) + return 2; + else if ( (flagsValue & esl_port3_bitmask) != 0 ) + return 3; + else if ( (flagsValue & esl_port4_bitmask) != 0 ) + return 4; + else if ( (flagsValue & esl_port5_bitmask) != 0 ) + return 5; + else if ( (flagsValue & esl_port6_bitmask) != 0 ) + return 6; + else if ( (flagsValue & esl_port7_bitmask) != 0 ) + return 7; + else if ( (flagsValue & esl_port8_bitmask) != 0 ) + return 8; + else if ( (flagsValue & esl_port9_bitmask) != 0 ) + return 9; + else if ( (flagsValue & esl_port10_bitmask) != 0 ) + return 10; + else if ( (flagsValue & esl_port11_bitmask) != 0 ) + return 11; + + return -1; +} + +/*esl*/ +static int +dissect_esl_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_) { + + proto_item *ti = NULL; + proto_tree *esl_header_tree; + gint offset = 0; + + guint esl_length = tvb_reported_length(tvb); + if ( esl_length >= SIZEOF_ESLHEADER ) + { + if (tree) + { + guint16 flags; + + ti = proto_tree_add_item(tree, proto_esl, tvb, 0, SIZEOF_ESLHEADER, ENC_NA); + esl_header_tree = proto_item_add_subtree(ti, ett_esl); + offset+=6; + + flags = tvb_get_letohs(tvb, offset); + proto_tree_add_uint(esl_header_tree, hf_esl_port, tvb, offset, 2, flags_to_port(flags)); + + proto_tree_add_item(esl_header_tree, hf_esl_alignerror, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(esl_header_tree, hf_esl_crcerror, tvb, offset, 2, ENC_LITTLE_ENDIAN); + + offset+=2; + + proto_tree_add_item(esl_header_tree, hf_esl_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); + } + } + return tvb_captured_length(tvb); +} + +typedef struct _ref_time_frame_info +{ + frame_data *fd; + guint64 esl_ts; + nstime_t abs_ts; + guint32 num; +} ref_time_frame_info; + +static ref_time_frame_info ref_time_frame; + +static gboolean is_esl_header(tvbuff_t *tvb, gint offset) +{ + return tvb_get_guint8(tvb, offset) == 0x01 && + tvb_get_guint8(tvb, offset+1) == 0x01 && + tvb_get_guint8(tvb, offset+2) == 0x05 && + (tvb_get_guint8(tvb, offset+3) == 0x10 ||tvb_get_guint8(tvb, offset+3) == 0x11)&& + tvb_get_guint8(tvb, offset+4) == 0x00 && + tvb_get_guint8(tvb, offset+5) == 0x00; +} + +static void modify_times(tvbuff_t *tvb, gint offset, packet_info *pinfo) +{ + if ( ref_time_frame.fd == NULL ) + { + ref_time_frame.esl_ts = tvb_get_letoh64(tvb, offset+8); + ref_time_frame.fd = pinfo->fd; + ref_time_frame.num = pinfo->num; + ref_time_frame.abs_ts = pinfo->abs_ts; + } + else if ( !pinfo->fd->visited ) + { + guint64 nsecs = tvb_get_letoh64(tvb, offset+8) - ref_time_frame.esl_ts; + guint64 secs = nsecs/1000000000; + nstime_t ts; + nstime_t ts_delta; + + ts.nsecs = ref_time_frame.abs_ts.nsecs + (int)(nsecs-(secs*1000000000)); + if ( ts.nsecs > 1000000000 ) + { + ts.nsecs-=1000000000; + secs++; + } + + ts.secs = ref_time_frame.abs_ts.secs+(int)secs; + nstime_delta(&ts_delta, &ts, &pinfo->abs_ts); + + pinfo->abs_ts = ts; + pinfo->fd->abs_ts = ts; + nstime_add(&pinfo->rel_ts, &ts_delta); + } +} + +static gboolean +dissect_esl_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + static gboolean in_heur = FALSE; + gboolean result; + tvbuff_t *next_tvb; + guint esl_length = tvb_captured_length(tvb); + + if ( in_heur ) + return FALSE; + + in_heur = TRUE; + /*TRY */ + { + if ( ref_time_frame.fd != NULL && !pinfo->fd->visited && pinfo->num <= ref_time_frame.num ) + ref_time_frame.fd = NULL; + + /* Check that there's enough data */ + if ( esl_length < SIZEOF_ESLHEADER ) + return FALSE; + + /* check for Esl frame, this has a unique destination MAC from Beckhoff range + First 6 bytes must be: 01 01 05 10 00 00 */ + if ( is_esl_header(tvb, 0) ) + { + dissect_esl_header(tvb, pinfo, tree, data); + if ( eth_withoutfcs_handle != NULL ) + { + next_tvb = tvb_new_subset_remaining(tvb, SIZEOF_ESLHEADER); + call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree); + } + modify_times(tvb, 0, pinfo); + result = TRUE; + } + else if ( is_esl_header(tvb, esl_length-SIZEOF_ESLHEADER) ) + { + if ( eth_withoutfcs_handle != NULL ) + { + next_tvb = tvb_new_subset_length(tvb, 0, esl_length-SIZEOF_ESLHEADER); + call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree); + } + next_tvb = tvb_new_subset_length(tvb, esl_length-SIZEOF_ESLHEADER, SIZEOF_ESLHEADER); + dissect_esl_header(next_tvb, pinfo, tree, data); + modify_times(tvb, esl_length-SIZEOF_ESLHEADER, pinfo); + + result = TRUE; + } + else + { + result = FALSE; + } + } + /*CATCH_ALL{ + in_heur = FALSE; + RETHROW; + }ENDTRY;*/ + in_heur = FALSE; + return result; +} + +void +proto_register_esl(void) { + static hf_register_info hf[] = { + { &hf_esl_port, + { "Port", "esl.port", + FT_UINT16, BASE_DEC, NULL, 0x00, + NULL, HFILL } + }, + { &hf_esl_crcerror, + { "Crc Error", "esl.crcerror", + FT_BOOLEAN, 16, TFS(&flags_yes_no), esl_crcError_bitmask, + NULL, HFILL } + }, + { &hf_esl_alignerror, + { "Alignment Error", "esl.alignerror", + FT_BOOLEAN, 16, TFS(&flags_yes_no), esl_alignError_bitmask, + NULL, HFILL } + }, + { &hf_esl_timestamp, + { "timestamp", "esl.timestamp", + FT_UINT64, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + }; + + static gint *ett[] = { + &ett_esl, + }; + + module_t *esl_module; + + proto_esl = proto_register_protocol("EtherCAT Switch Link", + "ESL","esl"); + + esl_module = prefs_register_protocol_obsolete(proto_esl); + + prefs_register_obsolete_preference(esl_module, "enable"); + + proto_register_field_array(proto_esl,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); + + register_dissector("esl", dissect_esl_header, proto_esl); +} + +void +proto_reg_handoff_esl(void) { + static gboolean initialized = FALSE; + + if (!initialized) { + eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_esl); + heur_dissector_add("eth", dissect_esl_heur, "EtherCAT over Ethernet", "esl_eth", proto_esl, HEURISTIC_DISABLE); + initialized = TRUE; + } +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ethercat-datagram.c b/plugins/epan/ethercat/packet-ethercat-datagram.c new file mode 100644 index 00000000..6ba7c9e3 --- /dev/null +++ b/plugins/epan/ethercat/packet-ethercat-datagram.c @@ -0,0 +1,3745 @@ +/* packet-ethercat-datagram.c + * Routines for ethercat packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * https://download.beckhoff.com/download/document/io/ethercat-development-products/ethercat_esc_datasheet_sec1_technology_2i3.pdf + */ + +/* Include files */ + +#include "config.h" + +#include <epan/packet.h> + +#include "packet-ethercat-datagram.h" +#include "packet-ecatmb.h" + +void proto_register_ecat(void); +void proto_reg_handoff_ecat(void); + +static heur_dissector_list_t heur_subdissector_list; +static dissector_handle_t ecat_handle; +static dissector_handle_t ecat_mailbox_handle; + +/* Define the EtherCAT proto */ +static int proto_ecat_datagram = -1; + +/* Define the tree for EtherCAT */ +static int ett_ecat = -1; +static int ett_ecat_header = -1; +static int ett_ecat_dc = -1; +static int ett_ecat_length = -1; +static int ett_ecat_padding = -1; +static int ett_ecat_datagram_subtree = -1; +static int ett_ecat_reg_esc_features = -1; +static int ett_ecat_reg_dlctrl1 = -1; +static int ett_ecat_reg_dlctrl2 = -1; +static int ett_ecat_reg_dlctrl3 = -1; +static int ett_ecat_reg_dlctrl4 = -1; +static int ett_ecat_reg_dlstatus1 = -1; +static int ett_ecat_reg_dlstatus2 = -1; +static int ett_ecat_reg_alctrl = -1; +static int ett_ecat_reg_alstatus = -1; +static int ett_ecat_reg_pdictrl1 = -1; +static int ett_ecat_reg_pdictrl2 = -1; +static int ett_ecat_reg_ecat_mask = -1; +static int ett_ecat_reg_pdiL = -1; +static int ett_ecat_reg_ecat = -1; +static int ett_ecat_reg_pdi1 = -1; +static int ett_ecat_reg_crc0 = -1; +static int ett_ecat_reg_crc1 = -1; +static int ett_ecat_reg_crc2 = -1; +static int ett_ecat_reg_crc3 = -1; +static int ett_ecat_reg_wd_status = -1; +static int ett_ecat_reg_eeprom_assign = -1; +static int ett_ecat_reg_ctrlstat = -1; +static int ett_ecat_reg_mio_ctrlstat = -1; +static int ett_ecat_mio_addr = -1; +static int ett_ecat_mio_access = -1; +static int ett_ecat_mio_status0 = -1; +static int ett_ecat_mio_status1 = -1; +static int ett_ecat_mio_status2 = -1; +static int ett_ecat_mio_status3 = -1; +static int ett_ecat_reg_fmmu = -1; +static int ett_ecat_reg_syncman = -1; +static int ett_ecat_reg_syncman_ctrlstatus = -1; +static int ett_ecat_reg_syncman_sm_enable = -1; +static int ett_ecat_reg_dc_cycunitctrl = -1; +static int ett_ecat_dc_activation = -1; +static int ett_ecat_dc_activationstat = -1; +static int ett_ecat_dc_sync0_status = -1; +static int ett_ecat_dc_sync1_status = -1; +static int ett_ecat_dc_latch0_ctrl = -1; +static int ett_ecat_dc_latch1_ctrl = -1; +static int ett_ecat_dc_latch0_status = -1; +static int ett_ecat_dc_latch1_status = -1; + +static int hf_ecat_sub; +static int hf_ecat_sub_data[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_cmd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_idx[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_cnt[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_ado[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_adp[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_lad[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +/* static int hf_ecat_header = -1; */ +static int hf_ecat_data = -1; +static int hf_ecat_cnt = -1; +static int hf_ecat_cmd = -1; +static int hf_ecat_idx = -1; +static int hf_ecat_adp = -1; +static int hf_ecat_ado = -1; +static int hf_ecat_lad = -1; +/* static int hf_ecat_len = -1; */ +static int hf_ecat_int = -1; + +static int hf_ecat_sub_dc_diff_da[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_bd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_cb[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_cd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_ba[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_ca[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +static int hf_ecat_dc_diff_da = -1; +static int hf_ecat_dc_diff_bd = -1; +static int hf_ecat_dc_diff_cb = -1; +static int hf_ecat_dc_diff_cd = -1; +static int hf_ecat_dc_diff_ba = -1; +static int hf_ecat_dc_diff_ca = -1; + +static int hf_ecat_length_len = -1; +static int hf_ecat_length_r = -1; +static int hf_ecat_length_c = -1; +static int hf_ecat_length_m = -1; + +static int hf_ecat_padding = -1; + +static int hf_ecat_reg_revision = -1; +static int hf_ecat_reg_esc_type = -1; +static int hf_ecat_reg_esc_build = -1; +static int hf_ecat_reg_esc_fmmucnt = -1; +static int hf_ecat_reg_esc_smcnt = -1; +static int hf_ecat_reg_esc_ports = -1; +static int hf_ecat_reg_esc_dpram = -1; +static int hf_ecat_reg_esc_features = -1; +static int hf_ecat_reg_esc_features_fmmurestrict = -1; +static int hf_ecat_reg_esc_features_smaddrrestrict = -1; +static int hf_ecat_reg_esc_features_dcsupport = -1; +static int hf_ecat_reg_esc_features_dc64support = -1; +static int hf_ecat_reg_esc_features_ebuslowjitter = -1; +static int hf_ecat_reg_esc_features_ebusextlinkdetect = -1; +static int hf_ecat_reg_esc_features_miiextlinkdetect = -1; +static int hf_ecat_reg_esc_features_crcext = -1; +static int hf_ecat_reg_physaddr = -1; +static int hf_ecat_reg_physaddr2 = -1; +static int hf_ecat_reg_dlctrl1 = -1; +static int hf_ecat_reg_dlctrl1_killnonecat = -1; +static int hf_ecat_reg_dlctrl1_port0extlinkdetect = -1; +static int hf_ecat_reg_dlctrl1_port1extlinkdetect = -1; +static int hf_ecat_reg_dlctrl1_port2extlinkdetect = -1; +static int hf_ecat_reg_dlctrl1_port3extlinkdetect = -1; +static int hf_ecat_reg_dlctrl2 = -1; +static int hf_ecat_reg_dlctrl2_port0 = -1; +static int hf_ecat_reg_dlctrl2_port1 = -1; +static int hf_ecat_reg_dlctrl2_port2 = -1; +static int hf_ecat_reg_dlctrl2_port3 = -1; +static int hf_ecat_reg_dlctrl3 = -1; +static int hf_ecat_reg_dlctrl3_fifosize = -1; +static int hf_ecat_reg_dlctrl3_lowebusjit = -1; +static int hf_ecat_reg_dlctrl4 = -1; +static int hf_ecat_reg_dlctrl4_2ndaddress = -1; +static int hf_ecat_reg_dlstatus1 = -1; +static int hf_ecat_reg_dlstatus1_operation = -1; +static int hf_ecat_reg_dlstatus1_pdiwatchdog = -1; +static int hf_ecat_reg_dlstatus1_enhlinkdetect = -1; +static int hf_ecat_reg_dlstatus1_physlink_port0 = -1; +static int hf_ecat_reg_dlstatus1_physlink_port1 = -1; +static int hf_ecat_reg_dlstatus1_physlink_port2 = -1; +static int hf_ecat_reg_dlstatus1_physlink_port3 = -1; +static int hf_ecat_reg_dlstatus2 = -1; +static int hf_ecat_reg_dlstatus2_port0 = -1; +static int hf_ecat_reg_dlstatus2_port1 = -1; +static int hf_ecat_reg_dlstatus2_port2 = -1; +static int hf_ecat_reg_dlstatus2_port3 = -1; +static int hf_ecat_reg_regprotect = -1; +static int hf_ecat_reg_accessprotect = -1; +static int hf_ecat_reg_resetecat = -1; +static int hf_ecat_reg_resetpdi = -1; +static int hf_ecat_reg_regphysrwoffs = -1; +static int hf_ecat_reg_alctrl = -1; +static int hf_ecat_reg_alctrl_ctrl = -1; +static int hf_ecat_reg_alctrl_errack = -1; +static int hf_ecat_reg_alctrl_id = -1; +static int hf_ecat_reg_alstatus = -1; +static int hf_ecat_reg_alstatus_status = -1; +static int hf_ecat_reg_alstatus_err = -1; +static int hf_ecat_reg_alstatus_id = -1; +static int hf_ecat_reg_pdictrl1 = -1; +static int hf_ecat_reg_pdictrl1_pdi = -1; +static int hf_ecat_reg_pdictrl2 = -1; +static int hf_ecat_reg_pdictrl2_devemul = -1; +static int hf_ecat_reg_pdictrl2_enhlnkdetect = -1; +static int hf_ecat_reg_pdictrl2_dcsyncout = -1; +static int hf_ecat_reg_pdictrl2_dcsyncin = -1; +static int hf_ecat_reg_pdictrl2_enhlnkdetect0 = -1; +static int hf_ecat_reg_pdictrl2_enhlnkdetect1 = -1; +static int hf_ecat_reg_pdictrl2_enhlnkdetect2 = -1; +static int hf_ecat_reg_pdictrl2_enhlnkdetect3 = -1; +static int hf_ecat_reg_alstatuscode = -1; +static int hf_ecat_reg_ecat_mask = -1; +static int hf_ecat_reg_ecat_mask_latchevt = -1; +static int hf_ecat_reg_ecat_mask_escstatevt = -1; +static int hf_ecat_reg_ecat_mask_alstatevt = -1; +static int hf_ecat_reg_ecat_mask_sm0irq = -1; +static int hf_ecat_reg_ecat_mask_sm1irq = -1; +static int hf_ecat_reg_ecat_mask_sm2irq = -1; +static int hf_ecat_reg_ecat_mask_sm3irq = -1; +static int hf_ecat_reg_ecat_mask_sm4irq = -1; +static int hf_ecat_reg_ecat_mask_sm5irq = -1; +static int hf_ecat_reg_ecat_mask_sm6irq = -1; +static int hf_ecat_reg_ecat_mask_sm7irq = -1; +static int hf_ecat_reg_pdiL = -1; +static int hf_ecat_reg_pdiL_alctrl = -1; +static int hf_ecat_reg_pdiL_latchin = -1; +static int hf_ecat_reg_pdiL_sync0 = -1; +static int hf_ecat_reg_pdiL_sync1 = -1; +static int hf_ecat_reg_pdiL_smchg = -1; +static int hf_ecat_reg_pdiL_eepromcmdpen = -1; +static int hf_ecat_reg_pdiL_sm0 = -1; +static int hf_ecat_reg_pdiL_sm1 = -1; +static int hf_ecat_reg_pdiL_sm2 = -1; +static int hf_ecat_reg_pdiL_sm3 = -1; +static int hf_ecat_reg_pdiL_sm4 = -1; +static int hf_ecat_reg_pdiL_sm5 = -1; +static int hf_ecat_reg_pdiL_sm6 = -1; +static int hf_ecat_reg_pdiL_sm7 = -1; +static int hf_ecat_reg_pdiH = -1; +static int hf_ecat_reg_ecat = -1; +static int hf_ecat_reg_ecat_latchevt = -1; +static int hf_ecat_reg_ecat_escstatevt = -1; +static int hf_ecat_reg_ecat_alstatevt = -1; +static int hf_ecat_reg_ecat_sm0irq = -1; +static int hf_ecat_reg_ecat_sm1irq = -1; +static int hf_ecat_reg_ecat_sm2irq = -1; +static int hf_ecat_reg_ecat_sm3irq = -1; +static int hf_ecat_reg_ecat_sm4irq = -1; +static int hf_ecat_reg_ecat_sm5irq = -1; +static int hf_ecat_reg_ecat_sm6irq = -1; +static int hf_ecat_reg_ecat_sm7irq = -1; +static int hf_ecat_reg_pdi1 = -1; +static int hf_ecat_reg_pdi1_alctrl = -1; +static int hf_ecat_reg_pdi1_latchin = -1; +static int hf_ecat_reg_pdi1_sync0 = -1; +static int hf_ecat_reg_pdi1_sync1 = -1; +static int hf_ecat_reg_pdi1_smchg = -1; +static int hf_ecat_reg_pdi1_eepromcmdpen = -1; +static int hf_ecat_reg_pdi1_sm0 = -1; +static int hf_ecat_reg_pdi1_sm1 = -1; +static int hf_ecat_reg_pdi1_sm2 = -1; +static int hf_ecat_reg_pdi1_sm3 = -1; +static int hf_ecat_reg_pdi1_sm4 = -1; +static int hf_ecat_reg_pdi1_sm5 = -1; +static int hf_ecat_reg_pdi1_sm6 = -1; +static int hf_ecat_reg_pdi1_sm7 = -1; +static int hf_ecat_reg_pdi2 = -1; +static int hf_ecat_reg_crc0 = -1; +static int hf_ecat_reg_crc0_frame = -1; +static int hf_ecat_reg_crc0_rx = -1; +static int hf_ecat_reg_crc1 = -1; +static int hf_ecat_reg_crc1_frame = -1; +static int hf_ecat_reg_crc1_rx = -1; +static int hf_ecat_reg_crc2 = -1; +static int hf_ecat_reg_crc2_frame = -1; +static int hf_ecat_reg_crc2_rx = -1; +static int hf_ecat_reg_crc3 = -1; +static int hf_ecat_reg_crc3_frame = -1; +static int hf_ecat_reg_crc3_rx = -1; +static int hf_ecat_reg_crc_fwd0 = -1; +static int hf_ecat_reg_crc_fwd1 = -1; +static int hf_ecat_reg_crc_fwd2 = -1; +static int hf_ecat_reg_crc_fwd3 = -1; +static int hf_ecat_reg_processuniterr = -1; +static int hf_ecat_reg_pdierr = -1; +static int hf_ecat_reg_linklost0 = -1; +static int hf_ecat_reg_linklost1 = -1; +static int hf_ecat_reg_linklost2 = -1; +static int hf_ecat_reg_linklost3 = -1; +static int hf_ecat_reg_wd_divisor = -1; +static int hf_ecat_reg_wd_timepdi = -1; +static int hf_ecat_reg_wd_timesm = -1; +static int hf_ecat_reg_wd_status = -1; +static int hf_ecat_reg_wd_status_pdwatchdog = -1; +static int hf_ecat_reg_wd_cntsm = -1; +static int hf_ecat_reg_wd_cntpdi = -1; +static int hf_ecat_reg_eeprom_assign = -1; +static int hf_ecat_reg_eeprom_assign_ctrl = -1; +static int hf_ecat_reg_eeprom_assign_pdiaccess = -1; +static int hf_ecat_reg_eeprom_assign_status = -1; +static int hf_ecat_reg_ctrlstat = -1; +static int hf_ecat_reg_ctrlstat_wraccess = -1; +static int hf_ecat_reg_ctrlstat_eepromemul = -1; +static int hf_ecat_reg_ctrlstat_8bacc = -1; +static int hf_ecat_reg_ctrlstat_2bacc = -1; +static int hf_ecat_reg_ctrlstat_rdacc = -1; +static int hf_ecat_reg_ctrlstat_wracc = -1; +static int hf_ecat_reg_ctrlstat_reloadacc = -1; +static int hf_ecat_reg_ctrlstat_crcerr = -1; +static int hf_ecat_reg_ctrlstat_lderr = -1; +static int hf_ecat_reg_ctrlstat_cmderr = -1; +static int hf_ecat_reg_ctrlstat_wrerr = -1; +static int hf_ecat_reg_ctrlstat_busy = -1; +static int hf_ecat_reg_addrl = -1; +static int hf_ecat_reg_addrh = -1; +static int hf_ecat_reg_data0 = -1; +static int hf_ecat_reg_data1 = -1; +static int hf_ecat_reg_data2 = -1; +static int hf_ecat_reg_data3 = -1; +static int hf_ecat_reg_mio_ctrlstat = -1; +static int hf_ecat_reg_mio_ctrlstat_wracc1 = -1; +static int hf_ecat_reg_mio_ctrlstat_offsphy = -1; +static int hf_ecat_reg_mio_ctrlstat_rdacc = -1; +static int hf_ecat_reg_mio_ctrlstat_wracc2 = -1; +static int hf_ecat_reg_mio_ctrlstat_wrerr = -1; +static int hf_ecat_reg_mio_ctrlstat_busy = -1; +static int hf_ecat_reg_mio_addr = -1; +static int hf_ecat_reg_mio_addr_phyaddr = -1; +static int hf_ecat_reg_mio_addr_mioaddr = -1; +static int hf_ecat_reg_mio_data = -1; +static int hf_ecat_reg_mio_access = -1; +static int hf_ecat_reg_mio_access_ecatacc = -1; +static int hf_ecat_reg_mio_access_pdiacc = -1; +static int hf_ecat_reg_mio_access_forcereset = -1; +static int hf_ecat_reg_mio_status0 = -1; +static int hf_ecat_reg_mio_status0_physlink = -1; +static int hf_ecat_reg_mio_status0_link = -1; +static int hf_ecat_reg_mio_status0_linkstatuserr = -1; +static int hf_ecat_reg_mio_status0_readerr = -1; +static int hf_ecat_reg_mio_status0_linkpartnererr = -1; +static int hf_ecat_reg_mio_status0_phycfgupdated = -1; +static int hf_ecat_reg_mio_status1 = -1; +static int hf_ecat_reg_mio_status1_physlink = -1; +static int hf_ecat_reg_mio_status1_link = -1; +static int hf_ecat_reg_mio_status1_linkstatuserr = -1; +static int hf_ecat_reg_mio_status1_readerr = -1; +static int hf_ecat_reg_mio_status1_linkpartnererr = -1; +static int hf_ecat_reg_mio_status1_phycfgupdated = -1; +static int hf_ecat_reg_mio_status2 = -1; +static int hf_ecat_reg_mio_status2_physlink = -1; +static int hf_ecat_reg_mio_status2_link = -1; +static int hf_ecat_reg_mio_status2_linkstatuserr = -1; +static int hf_ecat_reg_mio_status2_readerr = -1; +static int hf_ecat_reg_mio_status2_linkpartnererr = -1; +static int hf_ecat_reg_mio_status2_phycfgupdated = -1; +static int hf_ecat_reg_mio_status3 = -1; +static int hf_ecat_reg_mio_status3_physlink = -1; +static int hf_ecat_reg_mio_status3_link = -1; +static int hf_ecat_reg_mio_status3_linkstatuserr = -1; +static int hf_ecat_reg_mio_status3_readerr = -1; +static int hf_ecat_reg_mio_status3_linkpartnererr = -1; +static int hf_ecat_reg_mio_status3_phycfgupdated = -1; +static int hf_ecat_reg_fmmu = -1; +static int hf_ecat_reg_fmmu_lstart = -1; +static int hf_ecat_reg_fmmu_llen = -1; +static int hf_ecat_reg_fmmu_lstartbit = -1; +static int hf_ecat_reg_fmmu_lendbit = -1; +static int hf_ecat_reg_fmmu_pstart = -1; +static int hf_ecat_reg_fmmu_pstartbit = -1; +static int hf_ecat_reg_fmmu_type = -1; +static int hf_ecat_reg_fmmu_typeread = -1; +static int hf_ecat_reg_fmmu_typewrite = -1; +static int hf_ecat_reg_fmmu_activate = -1; +static int hf_ecat_reg_fmmu_activate0 = -1; +static int hf_ecat_reg_syncman_ctrlstatus = -1; +static int hf_ecat_reg_syncman_pmode = -1; +static int hf_ecat_reg_syncman_access = -1; +static int hf_ecat_reg_syncman_irq_ecat = -1; +static int hf_ecat_reg_syncman_irq_pdi = -1; +static int hf_ecat_reg_syncman_wdt = -1; +static int hf_ecat_reg_syncman_irq_write = -1; +static int hf_ecat_reg_syncman_irq_read = -1; +static int hf_ecat_reg_syncman_1bufstate = -1; +static int hf_ecat_reg_syncman_3bufstate = -1; +static int hf_ecat_reg_syncman_sm_enable = -1; +static int hf_ecat_reg_syncman_enable = -1; +static int hf_ecat_reg_syncman_repeatreq = -1; +static int hf_ecat_reg_syncman_latchsmchg_ecat = -1; +static int hf_ecat_reg_syncman_latchsmchg_pdi = -1; +static int hf_ecat_reg_syncman_deactivate = -1; +static int hf_ecat_reg_syncman_repeatack = -1; +static int hf_ecat_reg_syncman = -1; +static int hf_ecat_reg_syncman_start = -1; +static int hf_ecat_reg_syncman_len = -1; +static int hf_ecat_reg_dc_recv0 = -1; +static int hf_ecat_reg_dc_recv1 = -1; +static int hf_ecat_reg_dc_recv2 = -1; +static int hf_ecat_reg_dc_recv3 = -1; +static int hf_ecat_reg_dc_systime = -1; +static int hf_ecat_reg_dc_systimeL = -1; +static int hf_ecat_reg_dc_systimeH = -1; +static int hf_ecat_reg_dc_recvtime64 = -1; +static int hf_ecat_reg_dc_systimeoffs = -1; +static int hf_ecat_reg_dc_systimeoffsl = -1; +static int hf_ecat_reg_dc_systimeoffsh = -1; +static int hf_ecat_reg_dc_systimedelay = -1; +static int hf_ecat_reg_dc_ctrlerr = -1; +static int hf_ecat_reg_dc_speedstart = -1; +static int hf_ecat_reg_dc_speeddiff = -1; +static int hf_ecat_reg_dc_fltdepth_systimediff = -1; +static int hf_ecat_reg_dc_fltdepth_speedcnt = -1; +static int hf_ecat_reg_dc_cycunitctrl = -1; +static int hf_ecat_reg_dc_cycunitctrl_access_cyclic = -1; +static int hf_ecat_reg_dc_cycunitctrl_access_latch0 = -1; +static int hf_ecat_reg_dc_cycunitctrl_access_latch1 = -1; +static int hf_ecat_reg_dc_activation = -1; +static int hf_ecat_reg_dc_activation_enablecyclic = -1; +static int hf_ecat_reg_dc_activation_gen_sync0 = -1; +static int hf_ecat_reg_dc_activation_gen_sync1 = -1; +static int hf_ecat_reg_dc_activation_autoactivation = -1; +static int hf_ecat_reg_dc_activation_stimeext = -1; +static int hf_ecat_reg_dc_activation_stimecheck = -1; +static int hf_ecat_reg_dc_activation_hlfrange = -1; +static int hf_ecat_reg_dc_activation_dblrange = -1; +static int hf_ecat_reg_dc_cycimpuls = -1; +static int hf_ecat_reg_dc_activationstat = -1; +static int hf_ecat_reg_dc_activationstat_sync0pend = -1; +static int hf_ecat_reg_dc_activationstat_sync1pend = -1; +static int hf_ecat_reg_dc_activationstat_stimeoutofrange = -1; +static int hf_ecat_reg_dc_sync0_status = -1; +static int hf_ecat_reg_dc_sync0_status_triggered = -1; +static int hf_ecat_reg_dc_sync1_status = -1; +static int hf_ecat_reg_dc_sync1_status_triggered = -1; +static int hf_ecat_reg_dc_starttime0 = -1; +static int hf_ecat_reg_dc_starttime1 = -1; +static int hf_ecat_reg_dc_cyctime0 = -1; +static int hf_ecat_reg_dc_cyctime1 = -1; +static int hf_ecat_reg_dc_latch0_ctrl_pos = -1; +static int hf_ecat_reg_dc_latch0_ctrl_neg = -1; +static int hf_ecat_reg_dc_latch1_ctrl_pos = -1; +static int hf_ecat_reg_dc_latch1_ctrl_neg = -1; +static int hf_ecat_reg_dc_latch0_status_eventpos = -1; +static int hf_ecat_reg_dc_latch0_status_eventneg = -1; +static int hf_ecat_reg_dc_latch0_status_pinstate = -1; +static int hf_ecat_reg_dc_latch1_status_eventpos = -1; +static int hf_ecat_reg_dc_latch1_status_eventneg = -1; +static int hf_ecat_reg_dc_latch1_status_pinstate = -1; +static int hf_ecat_reg_dc_latch0_ctrl = -1; +static int hf_ecat_reg_dc_latch1_ctrl = -1; +static int hf_ecat_reg_dc_latch0_status = -1; +static int hf_ecat_reg_dc_latch1_status = -1; +static int hf_ecat_reg_dc_latch0_pos = -1; +static int hf_ecat_reg_dc_latch0_neg = -1; +static int hf_ecat_reg_dc_latch1_pos = -1; +static int hf_ecat_reg_dc_latch1_neg = -1; +static int hf_ecat_reg_dc_rcvsyncmanchg = -1; +static int hf_ecat_reg_dc_pdismstart = -1; +static int hf_ecat_reg_dc_pdismchg = -1; + + +static const value_string EcCmdShort[] = +{ + { 0, "NOP" }, + { 1, "APRD" }, + { 2, "APWR" }, + { 3, "APRW" }, + { 4, "FPRD" }, + { 5, "FPWR" }, + { 6, "FPRW" }, + { 7, "BRD" }, + { 8, "BWR" }, + { 9, "BRW" }, + { 10, "LRD" }, + { 11, "LWR" }, + { 12, "LRW" }, + { 13, "ARMW" }, + { 14, "FRMW" }, + { 255, "EXT" }, + { 0, NULL } +}; + +static const value_string EcCmdLong[] = +{ + { 0, "No operation" }, + { 1, "Auto Increment Physical Read" }, + { 2, "Auto Increment Physical Write" }, + { 3, "Auto Increment Physical ReadWrite" }, + { 4, "Configured address Physical Read" }, + { 5, "Configured address Physical Write" }, + { 6, "Configured address Physical ReadWrite" }, + { 7, "Broadcast Read" }, + { 8, "Broadcast Write" }, + { 9, "Broadcast ReadWrite" }, + { 10, "Logical Read" }, + { 11, "Logical Write" }, + { 12, "Logical ReadWrite" }, + { 13, "Auto Increment Physical Read Multiple Write" }, + { 14, "Configured Address Physical Read Multiple Write" }, + { 255, "EXT" }, + { 0, NULL } +}; + +static const value_string ecat_subframe_reserved_vals[] = +{ + { 0, "Valid"}, + { 0, NULL} +}; + +static const true_false_string tfs_ecat_subframe_circulating_vals = +{ + "Frame has circulated once", "Frame is not circulating" +}; + +static const true_false_string tfs_ecat_subframe_more_vals = +{ + "More EtherCAT datagrams will follow", "Last EtherCAT datagram" +}; + +static const true_false_string tfs_ecat_fmmu_typeread = +{ + "Read in use", "Read ignore" +}; + +static const true_false_string tfs_ecat_fmmu_typewrite = +{ + "Write in use", "Write ignore" +}; + +static const true_false_string tfs_local_true_false = +{ + "True", "False", +}; + +static const true_false_string tfs_local_disabled_enabled = +{ + "Enabled", "Disabled", +}; + +static const true_false_string tfs_local_disable_enable = +{ + "Enable", "Disable", +}; + +static const true_false_string tfs_esc_reg_watchdog = +{ + "Okay", "Run out", +}; + + +static const char* convertEcCmdToText(int cmd, const value_string ec_cmd[]) +{ + return val_to_str(cmd, ec_cmd, "<UNKNOWN: %d>"); +} + +#define ENDOF(p) ((p)+1) /* pointer to end of *p*/ + +typedef enum +{ + EC_CMD_TYPE_NOP = 0, + EC_CMD_TYPE_APRD = 1, + EC_CMD_TYPE_APWR = 2, + EC_CMD_TYPE_APRW = 3, + EC_CMD_TYPE_FPRD = 4, + EC_CMD_TYPE_FPWR = 5, + EC_CMD_TYPE_FPRW = 6, + EC_CMD_TYPE_BRD = 7, + EC_CMD_TYPE_BWR = 8, + EC_CMD_TYPE_BRW = 9, + EC_CMD_TYPE_LRD = 10, + EC_CMD_TYPE_LWR = 11, + EC_CMD_TYPE_LRW = 12, + EC_CMD_TYPE_ARMW = 13, + EC_CMD_TYPE_FRMW = 14, + EC_CMD_TYPE_EXT = 255 +} EC_CMD_TYPE; + +/* Esc Feature Reg 8 */ +static int * const ecat_esc_reg_8[] = { + &hf_ecat_reg_esc_features_fmmurestrict, + &hf_ecat_reg_esc_features_smaddrrestrict, + &hf_ecat_reg_esc_features_dcsupport, + &hf_ecat_reg_esc_features_dc64support, + &hf_ecat_reg_esc_features_ebuslowjitter, + &hf_ecat_reg_esc_features_ebusextlinkdetect, + &hf_ecat_reg_esc_features_miiextlinkdetect, + &hf_ecat_reg_esc_features_crcext, + NULL +}; + +/* Esc Status Reg 100 */ +static int * const ecat_esc_reg_100[] = +{ + &hf_ecat_reg_dlctrl1_killnonecat, + &hf_ecat_reg_dlctrl1_port0extlinkdetect, + &hf_ecat_reg_dlctrl1_port1extlinkdetect, + &hf_ecat_reg_dlctrl1_port2extlinkdetect, + &hf_ecat_reg_dlctrl1_port3extlinkdetect, + NULL +}; + +/* Esc Status Reg 101 */ +static const value_string vals_esc_reg_101[] = { + { 0, "Auto loop" }, + { 1, "Auto close only" }, + { 2, "Loop open" }, + { 3, "Loop closed" }, + { 0, NULL }, +}; + +static int * const ecat_esc_reg_101[] = +{ + &hf_ecat_reg_dlctrl2_port0, + &hf_ecat_reg_dlctrl2_port1, + &hf_ecat_reg_dlctrl2_port2, + &hf_ecat_reg_dlctrl2_port3, + NULL +}; + +static int * const ecat_esc_reg_102[] = { + &hf_ecat_reg_dlctrl3_fifosize, + &hf_ecat_reg_dlctrl3_lowebusjit, + NULL +}; + +static int * const ecat_esc_reg_103[] = { + &hf_ecat_reg_dlctrl4_2ndaddress, + NULL +}; + +/* Esc Status Reg 110 */ +static int * const ecat_esc_reg_110[] = +{ + &hf_ecat_reg_dlstatus1_operation, + &hf_ecat_reg_dlstatus1_pdiwatchdog, + &hf_ecat_reg_dlstatus1_enhlinkdetect, + &hf_ecat_reg_dlstatus1_physlink_port0, + &hf_ecat_reg_dlstatus1_physlink_port1, + &hf_ecat_reg_dlstatus1_physlink_port2, + &hf_ecat_reg_dlstatus1_physlink_port3, + NULL +}; + +/* Esc Status Reg 111 */ +static const value_string vals_esc_reg_111[] = { + { 0, "Loop open, no link" }, + { 1, "Loop closed, no link" }, + { 2, "Loop open, with link" }, + { 3, "Loop closed, with link" }, + { 0, NULL}, +}; + +static int * const ecat_esc_reg_111[] = +{ + &hf_ecat_reg_dlstatus2_port0, + &hf_ecat_reg_dlstatus2_port1, + &hf_ecat_reg_dlstatus2_port2, + &hf_ecat_reg_dlstatus2_port3, + NULL +}; + +static const value_string vals_esc_reg_120[] = { + { 1, "INIT" }, + { 2, "PREOP" }, + { 3, "BOOTSTRAP" }, + { 4, "SAFEOP" }, + { 8, "OP" }, + { 0, NULL}, +}; + +static int * const ecat_esc_reg_120[] = { + &hf_ecat_reg_alctrl_ctrl, + &hf_ecat_reg_alctrl_errack, + &hf_ecat_reg_alctrl_id, + NULL +}; + +static int * const ecat_esc_reg_130[] = { + &hf_ecat_reg_alstatus_status, + &hf_ecat_reg_alstatus_err, + &hf_ecat_reg_alstatus_id, + NULL +}; + +static const value_string vals_esc_reg_140[] = { + { 0, "None" }, + { 1, "4 bit dig. input" }, + { 2, "4 bit dig. output" }, + { 3, "2 bit dig. in/output" }, + { 4, "dig. in/output" }, + { 5, "SPI slave" }, + { 7, "EtherCAT bridge" }, + { 8, "16 bit uC (async)" }, + { 9, "8 bit uC (async)" }, + { 10, "16 bit uC (sync)" }, + { 11, "8 bit uC (sync)" }, + { 16, "32/0 bit dig. in/output" }, + { 17, "24/8 bit dig. in/output" }, + { 18, "16/16 bit dig. in/output" }, + { 19, "8/24 bit dig. in/output" }, + { 20, "0/32 bit dig. in/output" }, + { 128, "On chip bus" }, + { 0, NULL}, +}; + +static int * const ecat_esc_reg_140[] = { + &hf_ecat_reg_pdictrl1_pdi, + NULL +}; + +static int * const ecat_esc_reg_141[] = { + &hf_ecat_reg_pdictrl2_devemul, + &hf_ecat_reg_pdictrl2_enhlnkdetect, + &hf_ecat_reg_pdictrl2_dcsyncout, + &hf_ecat_reg_pdictrl2_dcsyncin, + &hf_ecat_reg_pdictrl2_enhlnkdetect0, + &hf_ecat_reg_pdictrl2_enhlnkdetect1, + &hf_ecat_reg_pdictrl2_enhlnkdetect2, + &hf_ecat_reg_pdictrl2_enhlnkdetect3, + NULL +}; + +static int * const ecat_esc_reg_200[] = { + &hf_ecat_reg_ecat_mask_latchevt, + &hf_ecat_reg_ecat_mask_escstatevt, + &hf_ecat_reg_ecat_mask_alstatevt, + &hf_ecat_reg_ecat_mask_sm0irq, + &hf_ecat_reg_ecat_mask_sm1irq, + &hf_ecat_reg_ecat_mask_sm2irq, + &hf_ecat_reg_ecat_mask_sm3irq, + &hf_ecat_reg_ecat_mask_sm4irq, + &hf_ecat_reg_ecat_mask_sm5irq, + &hf_ecat_reg_ecat_mask_sm6irq, + &hf_ecat_reg_ecat_mask_sm7irq, + NULL +}; + +static int * const ecat_esc_reg_204[] = { + &hf_ecat_reg_pdiL_alctrl, + &hf_ecat_reg_pdiL_latchin, + &hf_ecat_reg_pdiL_sync0, + &hf_ecat_reg_pdiL_sync1, + &hf_ecat_reg_pdiL_smchg, + &hf_ecat_reg_pdiL_eepromcmdpen, + &hf_ecat_reg_pdiL_sm0, + &hf_ecat_reg_pdiL_sm1, + &hf_ecat_reg_pdiL_sm2, + &hf_ecat_reg_pdiL_sm3, + &hf_ecat_reg_pdiL_sm4, + &hf_ecat_reg_pdiL_sm5, + &hf_ecat_reg_pdiL_sm6, + &hf_ecat_reg_pdiL_sm7, + NULL +}; + +static int * const ecat_esc_reg_210[] = { + &hf_ecat_reg_ecat_latchevt, + &hf_ecat_reg_ecat_escstatevt, + &hf_ecat_reg_ecat_alstatevt, + &hf_ecat_reg_ecat_sm0irq, + &hf_ecat_reg_ecat_sm1irq, + &hf_ecat_reg_ecat_sm2irq, + &hf_ecat_reg_ecat_sm3irq, + &hf_ecat_reg_ecat_sm4irq, + &hf_ecat_reg_ecat_sm5irq, + &hf_ecat_reg_ecat_sm6irq, + &hf_ecat_reg_ecat_sm7irq, + NULL +}; + +static int * const ecat_esc_reg_220[] = { + &hf_ecat_reg_pdi1_alctrl, + &hf_ecat_reg_pdi1_latchin, + &hf_ecat_reg_pdi1_sync0, + &hf_ecat_reg_pdi1_sync1, + &hf_ecat_reg_pdi1_smchg, + &hf_ecat_reg_pdi1_eepromcmdpen, + &hf_ecat_reg_pdi1_sm0, + &hf_ecat_reg_pdi1_sm1, + &hf_ecat_reg_pdi1_sm2, + &hf_ecat_reg_pdi1_sm3, + &hf_ecat_reg_pdi1_sm4, + &hf_ecat_reg_pdi1_sm5, + &hf_ecat_reg_pdi1_sm6, + &hf_ecat_reg_pdi1_sm7, + NULL +}; + +static int * const ecat_esc_reg_300[] = { + &hf_ecat_reg_crc0_frame, + &hf_ecat_reg_crc0_rx, + NULL +}; + +static int * const ecat_esc_reg_302[] = { + &hf_ecat_reg_crc1_frame, + &hf_ecat_reg_crc1_rx, + NULL +}; + +static int * const ecat_esc_reg_304[] = { + &hf_ecat_reg_crc2_frame, + &hf_ecat_reg_crc2_rx, + NULL +}; + +static int * const ecat_esc_reg_306[] = { + &hf_ecat_reg_crc3_frame, + &hf_ecat_reg_crc3_rx, + NULL +}; + +static int * const ecat_esc_reg_440[] = { + &hf_ecat_reg_wd_status_pdwatchdog, + NULL +}; + +static const true_false_string tfs_esc_reg_500_0 = { + "Local uC", "ECAT" +}; + +static const true_false_string tfs_esc_reg_500_1 = { + "Reset Bit 501.0 to 0", "Do not change Bit 501.0" +}; + +static int * const ecat_esc_reg_500[] = { + &hf_ecat_reg_eeprom_assign_ctrl, + &hf_ecat_reg_eeprom_assign_pdiaccess, + &hf_ecat_reg_eeprom_assign_status, + NULL +}; + +static const true_false_string tfs_esc_reg_502_5 = { + "PDI emulates EEPROM", "Normal operation" +}; + +static int * const ecat_esc_reg_502[] = { + &hf_ecat_reg_ctrlstat_wraccess, + &hf_ecat_reg_ctrlstat_eepromemul, + &hf_ecat_reg_ctrlstat_8bacc, + &hf_ecat_reg_ctrlstat_2bacc, + &hf_ecat_reg_ctrlstat_rdacc, + &hf_ecat_reg_ctrlstat_wracc, + &hf_ecat_reg_ctrlstat_reloadacc, + &hf_ecat_reg_ctrlstat_crcerr, + &hf_ecat_reg_ctrlstat_lderr, + &hf_ecat_reg_ctrlstat_cmderr, + &hf_ecat_reg_ctrlstat_wrerr, + &hf_ecat_reg_ctrlstat_busy, + NULL +}; + +static int * const ecat_esc_reg_510[] = { + &hf_ecat_reg_mio_ctrlstat_wracc1, + &hf_ecat_reg_mio_ctrlstat_offsphy, + &hf_ecat_reg_mio_ctrlstat_rdacc, + &hf_ecat_reg_mio_ctrlstat_wracc2, + &hf_ecat_reg_mio_ctrlstat_wrerr, + &hf_ecat_reg_mio_ctrlstat_busy, + NULL +}; + +static int * const ecat_esc_reg_512[] = { + &hf_ecat_reg_mio_addr_phyaddr, + &hf_ecat_reg_mio_addr_mioaddr, + NULL +}; + +static int * const ecat_esc_reg_516[] = { + &hf_ecat_reg_mio_access_ecatacc, + &hf_ecat_reg_mio_access_pdiacc, + &hf_ecat_reg_mio_access_forcereset, + NULL +}; + +static int * const ecat_esc_reg_518[] = { + &hf_ecat_reg_mio_status0_physlink, + &hf_ecat_reg_mio_status0_link, + &hf_ecat_reg_mio_status0_linkstatuserr, + &hf_ecat_reg_mio_status0_readerr, + &hf_ecat_reg_mio_status0_linkpartnererr, + &hf_ecat_reg_mio_status0_phycfgupdated, + NULL +}; + +static int * const ecat_esc_reg_519[] = { + &hf_ecat_reg_mio_status1_physlink, + &hf_ecat_reg_mio_status1_link, + &hf_ecat_reg_mio_status1_linkstatuserr, + &hf_ecat_reg_mio_status1_readerr, + &hf_ecat_reg_mio_status1_linkpartnererr, + &hf_ecat_reg_mio_status1_phycfgupdated, + NULL +}; + +static int * const ecat_esc_reg_51A[] = { + &hf_ecat_reg_mio_status2_physlink, + &hf_ecat_reg_mio_status2_link, + &hf_ecat_reg_mio_status2_linkstatuserr, + &hf_ecat_reg_mio_status2_readerr, + &hf_ecat_reg_mio_status2_linkpartnererr, + &hf_ecat_reg_mio_status2_phycfgupdated, + NULL +}; + +static int * const ecat_esc_reg_51B[] = { + &hf_ecat_reg_mio_status3_physlink, + &hf_ecat_reg_mio_status3_link, + &hf_ecat_reg_mio_status3_linkstatuserr, + &hf_ecat_reg_mio_status3_readerr, + &hf_ecat_reg_mio_status3_linkpartnererr, + &hf_ecat_reg_mio_status3_phycfgupdated, + NULL +}; + +static const true_false_string tfs_ecat_fmmu_activate = +{ + "activated", "deactivated" +}; + +static int ecat_reg_600(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item* item; + proto_tree* subtree; + + item = proto_tree_add_item(tree, hf_ecat_reg_fmmu, tvb, offset, 16, ENC_NA); + subtree = proto_item_add_subtree(item, ett_ecat_reg_fmmu); + + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_lstart, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_llen, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_lstartbit, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_lendbit, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_pstart, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_pstartbit, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_type, tvb, offset, 1, ENC_NA); + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_typeread, tvb, offset, 1, ENC_NA); + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_typewrite, tvb, offset, 1, ENC_NA); + offset += 1; + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_activate, tvb, offset, 1, ENC_NA); + proto_tree_add_item(subtree, hf_ecat_reg_fmmu_activate0, tvb, offset, 1, ENC_NA); + + return 16; +} + +static int ecat_reg_800(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset) +{ + proto_item* item; + proto_tree* subtree; + + static int * const reg4[] = { + &hf_ecat_reg_syncman_pmode, + &hf_ecat_reg_syncman_access, + &hf_ecat_reg_syncman_irq_ecat, + &hf_ecat_reg_syncman_irq_pdi, + &hf_ecat_reg_syncman_wdt, + &hf_ecat_reg_syncman_irq_write, + &hf_ecat_reg_syncman_irq_read, + &hf_ecat_reg_syncman_1bufstate, + &hf_ecat_reg_syncman_3bufstate, + NULL + }; + static int * const reg6[] = { + &hf_ecat_reg_syncman_enable, + &hf_ecat_reg_syncman_repeatreq, + &hf_ecat_reg_syncman_latchsmchg_ecat, + &hf_ecat_reg_syncman_latchsmchg_pdi, + &hf_ecat_reg_syncman_deactivate, + &hf_ecat_reg_syncman_repeatack, + NULL + }; + + item = proto_tree_add_item(tree, hf_ecat_reg_syncman, tvb, offset, 8, ENC_NA); + subtree = proto_item_add_subtree(item, ett_ecat_reg_syncman); + + proto_tree_add_item(subtree, hf_ecat_reg_syncman_start, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_item(subtree, hf_ecat_reg_syncman_len, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_bitmask(subtree, tvb, offset, hf_ecat_reg_syncman_ctrlstatus, ett_ecat_reg_syncman_ctrlstatus, reg4, ENC_LITTLE_ENDIAN); + offset += 2; + proto_tree_add_bitmask(subtree, tvb, offset, hf_ecat_reg_syncman_sm_enable, ett_ecat_reg_syncman_sm_enable, reg6, ENC_LITTLE_ENDIAN); + + return 8; +} + +static const value_string vals_esc_reg_8041[] = { + { 0, "3 buffer" }, + { 2, "1 buffer" }, + { 3, "1 buffer direct" }, + { 0, NULL}, +}; + +static const value_string vals_esc_reg_8042[] = { + { 0, "Read" }, + { 1, "Write" }, + { 0, NULL}, +}; + +static const true_false_string tfs_esc_reg_8051 = { + "Written", "Read" +}; + +static const value_string vals_esc_reg_8052[] = { + { 0, "1. buffer" }, + { 1, "2. buffer" }, + { 2, "3. buffer" }, + { 3, "blocked (start)" }, + { 0, NULL}, +}; + + +static const true_false_string tfs_esc_reg_9801 = { + "PDI", "ECAT" +}; + +static int * const ecat_esc_reg_980[] = { + &hf_ecat_reg_dc_cycunitctrl_access_cyclic, + &hf_ecat_reg_dc_cycunitctrl_access_latch0, + &hf_ecat_reg_dc_cycunitctrl_access_latch1, + NULL +}; + +static int * const ecat_esc_reg_981[] = { + &hf_ecat_reg_dc_activation_enablecyclic, + &hf_ecat_reg_dc_activation_gen_sync0, + &hf_ecat_reg_dc_activation_gen_sync1, + &hf_ecat_reg_dc_activation_autoactivation, + &hf_ecat_reg_dc_activation_stimeext, + &hf_ecat_reg_dc_activation_stimecheck, + &hf_ecat_reg_dc_activation_hlfrange, + &hf_ecat_reg_dc_activation_dblrange, + NULL +}; + +static int * const ecat_esc_reg_984[] = { + &hf_ecat_reg_dc_activationstat_sync0pend, + &hf_ecat_reg_dc_activationstat_sync1pend, + &hf_ecat_reg_dc_activationstat_stimeoutofrange, + NULL +}; + +static int * const ecat_esc_reg_98e[] = { + &hf_ecat_reg_dc_sync0_status_triggered, + NULL +}; + +static int * const ecat_esc_reg_98f[] = { + &hf_ecat_reg_dc_sync1_status_triggered, + NULL +}; + +static const true_false_string tfs_esc_reg_9A8E1 = { + "Single event", "Continuous" +}; + +static int * const ecat_esc_reg_9a8[] = { + &hf_ecat_reg_dc_latch0_ctrl_pos, + &hf_ecat_reg_dc_latch0_ctrl_neg, + NULL +}; +static int * const ecat_esc_reg_9a9[] = { + &hf_ecat_reg_dc_latch1_ctrl_pos, + &hf_ecat_reg_dc_latch1_ctrl_neg, + NULL +}; + +static int * const ecat_esc_reg_9ae[] = { + &hf_ecat_reg_dc_latch0_status_eventpos, + &hf_ecat_reg_dc_latch0_status_eventneg, + &hf_ecat_reg_dc_latch0_status_pinstate, + NULL +}; +static int * const ecat_esc_reg_9af[] = { + &hf_ecat_reg_dc_latch1_status_eventpos, + &hf_ecat_reg_dc_latch1_status_eventneg, + &hf_ecat_reg_dc_latch1_status_pinstate, + NULL +}; + +typedef int register_dissect_func(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset); + +/* esc registers */ +typedef struct +{ + guint16 reg; + guint16 length; + guint16 repeat; + int* phf; + int* const *bitmask_info; + gint* pett; + register_dissect_func *dissect; +} ecat_esc_reg_info; + + +#define NO_SUBTREE_FILL NULL, NULL, NULL + +static ecat_esc_reg_info ecat_esc_registers [] = +{ + { 0x0000, 1, 1, &hf_ecat_reg_revision, NO_SUBTREE_FILL}, + { 0x0001, 1, 1, &hf_ecat_reg_esc_type, NO_SUBTREE_FILL}, + { 0x0002, 2, 1, &hf_ecat_reg_esc_build, NO_SUBTREE_FILL}, + { 0x0004, 1, 1, &hf_ecat_reg_esc_fmmucnt, NO_SUBTREE_FILL}, + { 0x0005, 1, 1, &hf_ecat_reg_esc_smcnt, NO_SUBTREE_FILL}, + { 0x0006, 1, 1, &hf_ecat_reg_esc_ports, NO_SUBTREE_FILL}, + { 0x0007, 1, 1, &hf_ecat_reg_esc_dpram, NO_SUBTREE_FILL}, + { 0x0008, 2, 1, &hf_ecat_reg_esc_features, ecat_esc_reg_8, &ett_ecat_reg_esc_features, NULL}, + { 0x0010, 2, 1, &hf_ecat_reg_physaddr, NO_SUBTREE_FILL}, + { 0x0012, 2, 1, &hf_ecat_reg_physaddr2, NO_SUBTREE_FILL}, + { 0x0020, 2, 1, &hf_ecat_reg_regprotect, NO_SUBTREE_FILL}, + { 0x0030, 2, 1, &hf_ecat_reg_accessprotect, NO_SUBTREE_FILL}, + { 0x0040, 1, 1, &hf_ecat_reg_resetecat, NO_SUBTREE_FILL}, + { 0x0041, 1, 1, &hf_ecat_reg_resetpdi, NO_SUBTREE_FILL}, + { 0x0100, 1, 1, &hf_ecat_reg_dlctrl1, ecat_esc_reg_100, &ett_ecat_reg_dlctrl1, NULL}, + { 0x0101, 1, 1, &hf_ecat_reg_dlctrl2, ecat_esc_reg_101, &ett_ecat_reg_dlctrl2, NULL}, + { 0x0102, 1, 1, &hf_ecat_reg_dlctrl3, ecat_esc_reg_102, &ett_ecat_reg_dlctrl3, NULL}, + { 0x0103, 1, 1, &hf_ecat_reg_dlctrl4, ecat_esc_reg_103, &ett_ecat_reg_dlctrl4, NULL}, + { 0x0108, 2, 1, &hf_ecat_reg_regphysrwoffs, NO_SUBTREE_FILL}, + { 0x0110, 1, 1, &hf_ecat_reg_dlstatus1, ecat_esc_reg_110, &ett_ecat_reg_dlstatus1, NULL}, + { 0x0111, 1, 1, &hf_ecat_reg_dlstatus2, ecat_esc_reg_111, &ett_ecat_reg_dlstatus2, NULL}, + { 0x0120, 2, 1, &hf_ecat_reg_alctrl, ecat_esc_reg_120, &ett_ecat_reg_alctrl, NULL}, + { 0x0130, 2, 1, &hf_ecat_reg_alstatus, ecat_esc_reg_130, &ett_ecat_reg_alstatus, NULL}, + { 0x0134, 2, 1, &hf_ecat_reg_alstatuscode, NO_SUBTREE_FILL}, + { 0x0140, 1, 1, &hf_ecat_reg_pdictrl1, ecat_esc_reg_140, &ett_ecat_reg_pdictrl1, NULL}, + { 0x0141, 1, 1, &hf_ecat_reg_pdictrl2, ecat_esc_reg_141, &ett_ecat_reg_pdictrl2, NULL}, + { 0x0200, 2, 1, &hf_ecat_reg_ecat_mask, ecat_esc_reg_200, &ett_ecat_reg_ecat_mask, NULL}, + { 0x0204, 2, 1, &hf_ecat_reg_pdiL, ecat_esc_reg_204, &ett_ecat_reg_pdiL, NULL}, + { 0x0206, 2, 1, &hf_ecat_reg_pdiH, NO_SUBTREE_FILL}, + { 0x0210, 2, 1, &hf_ecat_reg_ecat, ecat_esc_reg_210, &ett_ecat_reg_ecat, NULL}, + { 0x0220, 2, 1, &hf_ecat_reg_pdi1, ecat_esc_reg_220, &ett_ecat_reg_pdi1, NULL}, + { 0x0222, 2, 1, &hf_ecat_reg_pdi2, NO_SUBTREE_FILL}, + { 0x0300, 2, 1, &hf_ecat_reg_crc0, ecat_esc_reg_300, &ett_ecat_reg_crc0, NULL}, + { 0x0302, 2, 1, &hf_ecat_reg_crc1, ecat_esc_reg_302, &ett_ecat_reg_crc1, NULL}, + { 0x0304, 2, 1, &hf_ecat_reg_crc2, ecat_esc_reg_304, &ett_ecat_reg_crc2, NULL}, + { 0x0306, 2, 1, &hf_ecat_reg_crc3, ecat_esc_reg_306, &ett_ecat_reg_crc3, NULL}, + { 0x0308, 1, 1, &hf_ecat_reg_crc_fwd0, NO_SUBTREE_FILL}, + { 0x0309, 1, 1, &hf_ecat_reg_crc_fwd1, NO_SUBTREE_FILL}, + { 0x030A, 1, 1, &hf_ecat_reg_crc_fwd2, NO_SUBTREE_FILL}, + { 0x030B, 1, 1, &hf_ecat_reg_crc_fwd3, NO_SUBTREE_FILL}, + { 0x030C, 1, 1, &hf_ecat_reg_processuniterr, NO_SUBTREE_FILL}, + { 0x030D, 1, 1, &hf_ecat_reg_pdierr, NO_SUBTREE_FILL}, + { 0x0310, 1, 1, &hf_ecat_reg_linklost0, NO_SUBTREE_FILL}, + { 0x0311, 1, 1, &hf_ecat_reg_linklost1, NO_SUBTREE_FILL}, + { 0x0312, 1, 1, &hf_ecat_reg_linklost2, NO_SUBTREE_FILL}, + { 0x0313, 1, 1, &hf_ecat_reg_linklost3, NO_SUBTREE_FILL}, + { 0x0400, 2, 1, &hf_ecat_reg_wd_divisor, NO_SUBTREE_FILL}, + { 0x0410, 2, 1, &hf_ecat_reg_wd_timepdi, NO_SUBTREE_FILL}, + { 0x0420, 2, 1, &hf_ecat_reg_wd_timesm, NO_SUBTREE_FILL}, + { 0x0440, 1, 1, &hf_ecat_reg_wd_status, ecat_esc_reg_440, &ett_ecat_reg_wd_status, NULL}, + { 0x0442, 1, 1, &hf_ecat_reg_wd_cntsm, NO_SUBTREE_FILL}, + { 0x0443, 1, 1, &hf_ecat_reg_wd_cntpdi, NO_SUBTREE_FILL}, + { 0x0500, 2, 1, &hf_ecat_reg_eeprom_assign, ecat_esc_reg_500, &ett_ecat_reg_eeprom_assign, NULL}, + { 0x0502, 2, 1, &hf_ecat_reg_ctrlstat, ecat_esc_reg_502, &ett_ecat_reg_ctrlstat, NULL}, + { 0x0504, 2, 1, &hf_ecat_reg_addrl, NO_SUBTREE_FILL}, + { 0x0506, 2, 1, &hf_ecat_reg_addrh, NO_SUBTREE_FILL}, + { 0x0508, 2, 1, &hf_ecat_reg_data0, NO_SUBTREE_FILL}, + { 0x050a, 2, 1, &hf_ecat_reg_data1, NO_SUBTREE_FILL}, + { 0x050c, 2, 1, &hf_ecat_reg_data2, NO_SUBTREE_FILL}, + { 0x050e, 2, 1, &hf_ecat_reg_data3, NO_SUBTREE_FILL}, + { 0x0510, 2, 1, &hf_ecat_reg_mio_ctrlstat, ecat_esc_reg_510, &ett_ecat_reg_mio_ctrlstat, NULL}, + { 0x0512, 2, 1, &hf_ecat_reg_mio_addr, ecat_esc_reg_512, &ett_ecat_mio_addr, NULL}, + { 0x0514, 2, 1, &hf_ecat_reg_mio_data, NO_SUBTREE_FILL}, + { 0x0516, 2, 1, &hf_ecat_reg_mio_access, ecat_esc_reg_516, &ett_ecat_mio_access, NULL}, + { 0x0518, 1, 1, &hf_ecat_reg_mio_status0, ecat_esc_reg_518, &ett_ecat_mio_status0, NULL}, + { 0x0519, 1, 1, &hf_ecat_reg_mio_status1, ecat_esc_reg_519, &ett_ecat_mio_status1, NULL}, + { 0x051A, 1, 1, &hf_ecat_reg_mio_status2, ecat_esc_reg_51A, &ett_ecat_mio_status2, NULL}, + { 0x051B, 1, 1, &hf_ecat_reg_mio_status3, ecat_esc_reg_51B, &ett_ecat_mio_status3, NULL}, + { 0x0600, 16, 16, &hf_ecat_reg_fmmu, NULL, NULL, ecat_reg_600}, + { 0x0800, 8, 8, &hf_ecat_reg_syncman, NULL, NULL, ecat_reg_800}, + { 0x0900, 4, 1, &hf_ecat_reg_dc_recv0, NO_SUBTREE_FILL}, + { 0x0904, 4, 1, &hf_ecat_reg_dc_recv1, NO_SUBTREE_FILL}, + { 0x0908, 4, 1, &hf_ecat_reg_dc_recv2, NO_SUBTREE_FILL}, + { 0x090c, 4, 1, &hf_ecat_reg_dc_recv3, NO_SUBTREE_FILL}, + { 0x0910, 8, 1, &hf_ecat_reg_dc_systime, NO_SUBTREE_FILL}, + { 0x0910, 4, 1, &hf_ecat_reg_dc_systimeL, NO_SUBTREE_FILL}, + { 0x0914, 4, 1, &hf_ecat_reg_dc_systimeH, NO_SUBTREE_FILL}, + { 0x0918, 8, 1, &hf_ecat_reg_dc_recvtime64, NO_SUBTREE_FILL}, + { 0x0920, 8, 1, &hf_ecat_reg_dc_systimeoffs, NO_SUBTREE_FILL}, + { 0x0920, 4, 1, &hf_ecat_reg_dc_systimeoffsl, NO_SUBTREE_FILL}, + { 0x0924, 4, 1, &hf_ecat_reg_dc_systimeoffsh, NO_SUBTREE_FILL}, + { 0x0928, 4, 1, &hf_ecat_reg_dc_systimedelay, NO_SUBTREE_FILL}, + { 0x092c, 4, 1, &hf_ecat_reg_dc_ctrlerr, NO_SUBTREE_FILL}, + { 0x0930, 2, 1, &hf_ecat_reg_dc_speedstart, NO_SUBTREE_FILL}, + { 0x0932, 2, 1, &hf_ecat_reg_dc_speeddiff, NO_SUBTREE_FILL}, + { 0x0934, 1, 1, &hf_ecat_reg_dc_fltdepth_systimediff, NO_SUBTREE_FILL}, + { 0x0935, 1, 1, &hf_ecat_reg_dc_fltdepth_speedcnt, NO_SUBTREE_FILL}, + { 0x0980, 1, 1, &hf_ecat_reg_dc_cycunitctrl, ecat_esc_reg_980, &ett_ecat_reg_dc_cycunitctrl, NULL}, + { 0x0981, 1, 1, &hf_ecat_reg_dc_activation, ecat_esc_reg_981, &ett_ecat_dc_activation, NULL}, + { 0x0982, 2, 1, &hf_ecat_reg_dc_cycimpuls, NO_SUBTREE_FILL}, + { 0x0984, 1, 1, &hf_ecat_reg_dc_activationstat, ecat_esc_reg_984, &ett_ecat_dc_activationstat, NULL}, + { 0x098e, 1, 1, &hf_ecat_reg_dc_sync0_status, ecat_esc_reg_98e, &ett_ecat_dc_sync0_status, NULL}, + { 0x098f, 1, 1, &hf_ecat_reg_dc_sync1_status, ecat_esc_reg_98f, &ett_ecat_dc_sync1_status, NULL}, + { 0x0990, 8, 1, &hf_ecat_reg_dc_starttime0, NO_SUBTREE_FILL}, + { 0x0998, 8, 1, &hf_ecat_reg_dc_starttime1, NO_SUBTREE_FILL}, + { 0x09a0, 4, 1, &hf_ecat_reg_dc_cyctime0, NO_SUBTREE_FILL}, + { 0x09a4, 4, 1, &hf_ecat_reg_dc_cyctime1, NO_SUBTREE_FILL}, + { 0x09a8, 1, 1, &hf_ecat_reg_dc_latch0_ctrl, ecat_esc_reg_9a8, &ett_ecat_dc_latch0_ctrl, NULL}, + { 0x09a9, 1, 1, &hf_ecat_reg_dc_latch1_ctrl, ecat_esc_reg_9a9, &ett_ecat_dc_latch1_ctrl, NULL}, + { 0x09ae, 1, 1, &hf_ecat_reg_dc_latch0_status, ecat_esc_reg_9ae, &ett_ecat_dc_latch0_status, NULL}, + { 0x09af, 1, 1, &hf_ecat_reg_dc_latch1_status, ecat_esc_reg_9af, &ett_ecat_dc_latch1_status, NULL}, + { 0x09b0, 8, 1, &hf_ecat_reg_dc_latch0_pos, NO_SUBTREE_FILL}, + { 0x09b8, 8, 1, &hf_ecat_reg_dc_latch0_neg, NO_SUBTREE_FILL}, + { 0x09c0, 8, 1, &hf_ecat_reg_dc_latch1_pos, NO_SUBTREE_FILL}, + { 0x09c8, 8, 1, &hf_ecat_reg_dc_latch1_neg, NO_SUBTREE_FILL}, + { 0x09f0, 4, 1, &hf_ecat_reg_dc_rcvsyncmanchg, NO_SUBTREE_FILL}, + { 0x09f8, 4, 1, &hf_ecat_reg_dc_pdismstart, NO_SUBTREE_FILL}, + { 0x09fc, 4, 1, &hf_ecat_reg_dc_pdismchg, NO_SUBTREE_FILL}, + +}; + +/* esc dissector */ +static int dissect_esc_register(packet_info* pinfo, proto_tree *tree, tvbuff_t *tvb, gint offset, guint32 len, EcParserHDR* hdr, guint16 cnt) +{ + guint i; + gint r; + gint res = -1; + gint regOffset; + gint read = 0; + + if (len > 0 ) + { + switch ( hdr->cmd ) + { + case EC_CMD_TYPE_APRD: + case EC_CMD_TYPE_BRD: + case EC_CMD_TYPE_FPRD: + read = 1; + /* Fall through */ + case EC_CMD_TYPE_APWR: + case EC_CMD_TYPE_APRW: + case EC_CMD_TYPE_FPWR: + case EC_CMD_TYPE_FPRW: + case EC_CMD_TYPE_BWR: + case EC_CMD_TYPE_BRW: + case EC_CMD_TYPE_ARMW: + case EC_CMD_TYPE_FRMW: + for ( i=0; i<array_length(ecat_esc_registers); i++ ) + { + if ( hdr->anAddrUnion.a.ado + len< ecat_esc_registers[i].reg ) + break; + + regOffset = ecat_esc_registers[i].reg; + for ( r=0; r<ecat_esc_registers[i].repeat; r++ ) + { + if ( regOffset >= hdr->anAddrUnion.a.ado && regOffset+ecat_esc_registers[i].length <= (guint16)(hdr->anAddrUnion.a.ado + len) ) + { + if ( cnt > 0 || !read ) + { + if (ecat_esc_registers[i].dissect != NULL) + { + ecat_esc_registers[i].dissect(pinfo, tree, tvb, offset+(regOffset-hdr->anAddrUnion.a.ado)); + } + else if (ecat_esc_registers[i].bitmask_info != NULL) + { + proto_tree_add_bitmask(tree, tvb, offset+(regOffset-hdr->anAddrUnion.a.ado), *ecat_esc_registers[i].phf, + *ecat_esc_registers[i].pett, ecat_esc_registers[i].bitmask_info, ENC_LITTLE_ENDIAN); + } + else + { + proto_tree_add_item(tree, *ecat_esc_registers[i].phf, tvb, offset+(regOffset-hdr->anAddrUnion.a.ado), ecat_esc_registers[i].length, ENC_LITTLE_ENDIAN); + } + } + res = 0; + } + regOffset+=ecat_esc_registers[i].length; + } + } + break; + } + } + + return res; +} +static void init_EcParserHDR(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset) +{ + pHdr->cmd = tvb_get_guint8(tvb, offset++); + pHdr->idx = tvb_get_guint8(tvb, offset++); + pHdr->anAddrUnion.a.adp = tvb_get_letohs(tvb, offset); offset+=2; + pHdr->anAddrUnion.a.ado = tvb_get_letohs(tvb, offset); offset+=2; + pHdr->len = tvb_get_letohs(tvb, offset); offset+=2; + pHdr->intr = tvb_get_letohs(tvb, offset); +} + +static void init_dc_measure(guint32* pDC, tvbuff_t *tvb, gint offset) +{ + int i; + for ( i=0; i<4; i++ ) + { + pDC[i] = tvb_get_letohl(tvb, offset); + offset+=4; + } +} + +static guint16 get_wc(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset) +{ + return tvb_get_letohs(tvb, offset+EcParserHDR_Len+(pHdr->len&0x07ff)); +} + +static guint16 get_cmd_len(EcParserHDR* pHdr) +{ + return (EcParserHDR_Len+(pHdr->len&0x07ff)+2); /*Header + data + wc*/ +} + + +static void EcSummaryFormater(guint32 datalength, tvbuff_t *tvb, gint offset, char *szText, gint nMax) +{ + guint nSub=0; + guint nLen=0; + guint8 nCmds[4]; + guint nLens[4]; + EcParserHDR ecFirst; + EcParserHDR ecParser; + + guint suboffset=0; + + init_EcParserHDR(&ecFirst, tvb, offset); + + while ( suboffset < datalength ) + { + PEcParserHDR pEcParser; + if ( nSub > 0 ) + { + init_EcParserHDR(&ecParser, tvb, offset+suboffset); + pEcParser = &ecParser; + } + else + pEcParser = &ecFirst; + + if ( nSub < 4 ) + { + nCmds[nSub] = pEcParser->cmd; + nLens[nSub] = pEcParser->len&0x07ff; + } + nSub++; + nLen += (pEcParser->len&0x07ff); + /* bit 14 -- roundtrip */ + + if ( (pEcParser->len&0x8000) == 0 ) + break; + + suboffset+=get_cmd_len(pEcParser); + } + if ( nSub == 1 ) + { + guint16 len = ecFirst.len&0x07ff; + guint16 cnt = get_wc(&ecFirst, tvb, offset); + snprintf ( szText, nMax, "'%s': Len: %d, Adp 0x%x, Ado 0x%x, Wc %d ", + convertEcCmdToText(ecFirst.cmd, EcCmdShort), len, ecFirst.anAddrUnion.a.adp, ecFirst.anAddrUnion.a.ado, cnt ); + } + else if ( nSub == 2 ) + { + snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d ", + nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1]); + } + else if ( nSub == 3 ) + { + snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d, '%s': len %d", + nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1], convertEcCmdToText(nCmds[2], EcCmdShort), nLens[2]); + } + else if ( nSub == 4 ) + { + snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d, '%s': len %d, '%s': len %d", + nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1], convertEcCmdToText(nCmds[2], EcCmdShort), nLens[2], convertEcCmdToText(nCmds[3], EcCmdShort), nLens[3]); + } + else + snprintf ( szText, nMax, "%d Cmds, SumLen %d, '%s'... ", + nSub, nLen, convertEcCmdToText(ecFirst.cmd, EcCmdShort)); +} + +static void EcCmdFormatter(guint8 cmd, char *szText, gint nMax) +{ + gint idx=0; + const gchar *szCmd = try_val_to_str_idx((guint32)cmd, EcCmdLong, &idx); + + if ( idx != -1 ) + snprintf(szText, nMax, "Cmd : %d (%s)", cmd, szCmd); + else + snprintf(szText, nMax, "Cmd : %d (Unknown command)", cmd); +} + + +static void EcSubFormatter(tvbuff_t *tvb, gint offset, char *szText, gint nMax) +{ + EcParserHDR ecParser; + guint16 len, cnt; + + init_EcParserHDR(&ecParser, tvb, offset); + len = ecParser.len&0x07ff; + cnt = get_wc(&ecParser, tvb, offset); + + switch ( ecParser.cmd ) + { + case EC_CMD_TYPE_NOP: + case EC_CMD_TYPE_APRD: + case EC_CMD_TYPE_APWR: + case EC_CMD_TYPE_APRW: + case EC_CMD_TYPE_FPRD: + case EC_CMD_TYPE_FPWR: + case EC_CMD_TYPE_FPRW: + case EC_CMD_TYPE_BRD: + case EC_CMD_TYPE_BWR: + case EC_CMD_TYPE_BRW: + case EC_CMD_TYPE_ARMW: + case EC_CMD_TYPE_FRMW: + snprintf ( szText, nMax, "EtherCAT datagram: Cmd: '%s' (%d), Len: %d, Adp 0x%x, Ado 0x%x, Cnt %d", + convertEcCmdToText(ecParser.cmd, EcCmdShort), ecParser.cmd, len, ecParser.anAddrUnion.a.adp, ecParser.anAddrUnion.a.ado, cnt); + break; + case EC_CMD_TYPE_LRD: + case EC_CMD_TYPE_LWR: + case EC_CMD_TYPE_LRW: + snprintf ( szText, nMax, "EtherCAT datagram: Cmd: '%s' (%d), Len: %d, Addr 0x%x, Cnt %d", + convertEcCmdToText(ecParser.cmd, EcCmdShort), ecParser.cmd, len, ecParser.anAddrUnion.addr, cnt); + break; + case EC_CMD_TYPE_EXT: + snprintf ( szText, nMax, "EtherCAT datagram: Cmd: 'EXT' (%d), Len: %d", ecParser.cmd, len); + break; + default: + snprintf ( szText, nMax, "EtherCAT datagram: Cmd: 'Unknown' (%d), Len: %d", ecParser.cmd, len); + } +} + +/* Ethercat Datagram */ +static int dissect_ecat_datagram(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + tvbuff_t *next_tvb; + proto_item *ti, *aitem = NULL; + proto_tree *ecat_datagrams_tree = NULL; + guint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint ecLength=0; + guint subCount = 0; + const guint datagram_length = tvb_captured_length(tvb); + guint datagram_padding_bytes = 0; + EcParserHDR ecHdr; + heur_dtbl_entry_t *hdtbl_entry; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECAT"); + + col_clear(pinfo->cinfo, COL_INFO); + + /* If the data portion of an EtherCAT datagram is less than 44 bytes, then + it must have been padded with an additional n number of bytes to reach a + total Ethernet frame length of 64 bytes (Ethernet header + Ethernet Data + + FCS). Hence at least 44 bytes data shall always be available in any + EtherCAT datagram. */ + /* tvb_ensure_bytes_exist(tvb, offset, 44); + this is not correct, because the frame might have been captured before the + os added the padding bytes. E.g. in Windows the frames are captured on the + protocol layer. When another protocol driver sends a frame this frame does + not include the padding bytes. + */ + + /* Count the length of the individual EtherCAT datagrams (sub datagrams) + that are part of this EtherCAT frame. Stop counting when the current + sub datagram header tells that there are no more sub datagrams or when + there is no more data available in the PDU. */ + do + { + init_EcParserHDR(&ecHdr, tvb, ecLength); + ecLength += get_cmd_len(&ecHdr); + } while ((ecLength < datagram_length) && + (ecHdr.len & 0x8000)); + + /* Calculate the amount of padding data available in the PDU */ + datagram_padding_bytes = datagram_length - ecLength; + + EcSummaryFormater(ecLength, tvb, offset, szText, nMax); + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + /* Create the EtherCAT datagram(s) subtree */ + ti = proto_tree_add_item(tree, proto_ecat_datagram, tvb, 0, -1, ENC_NA); + ecat_datagrams_tree = proto_item_add_subtree(ti, ett_ecat); + + proto_item_append_text(ti,": %s", szText); + } + + /* Dissect all sub frames of this EtherCAT PDU */ + do + { + proto_tree *ecat_datagram_tree = NULL, *ecat_header_tree = NULL, *ecat_dc_tree = NULL; + + proto_item *hidden_item; + guint32 subsize; + guint32 suboffset; + guint32 len; + guint16 cnt; + ETHERCAT_MBOX_HEADER mbox; + + suboffset = offset; + init_EcParserHDR(&ecHdr, tvb, suboffset); + + subsize = get_cmd_len(&ecHdr); + len = ecHdr.len & 0x07ff; + cnt = get_wc(&ecHdr, tvb, suboffset); + + if( tree ) + { + /* Create the sub tree for the current datagram */ + EcSubFormatter(tvb, suboffset, szText, nMax); + ecat_datagram_tree = proto_tree_add_subtree(ecat_datagrams_tree, tvb, suboffset, subsize, ett_ecat_datagram_subtree, NULL, szText); + + /* Create a subtree placeholder for the Header */ + ecat_header_tree = proto_tree_add_subtree(ecat_datagram_tree, tvb, offset, EcParserHDR_Len, ett_ecat_header, NULL, "Header"); + + EcCmdFormatter(ecHdr.cmd, szText, nMax); + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_cmd, tvb, suboffset, 1, ENC_LITTLE_ENDIAN); + proto_item_set_text(aitem, "%s", szText); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_cmd[subCount], tvb, suboffset, 1, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + suboffset+=1; + + proto_tree_add_item(ecat_header_tree, hf_ecat_idx, tvb, suboffset, 1, ENC_LITTLE_ENDIAN); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_idx[subCount], tvb, suboffset, 1, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + suboffset+=1; + + switch ( ecHdr.cmd ) + { + case 10: + case 11: + case 12: + proto_tree_add_item(ecat_header_tree, hf_ecat_lad, tvb, suboffset, 4, ENC_LITTLE_ENDIAN); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_lad[subCount], tvb, suboffset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + + suboffset+=4; + break; + default: + proto_tree_add_item(ecat_header_tree, hf_ecat_adp, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_adp[subCount], tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + + suboffset+=2; + proto_tree_add_item(ecat_header_tree, hf_ecat_ado, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_ado[subCount], tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + + suboffset+=2; + } + + { + proto_tree *length_sub_tree; + + /* Add information about the length field (11 bit length, 3 bits + reserved, 1 bit circulating frame and 1 bit more in a sub tree */ + length_sub_tree = proto_tree_add_subtree_format(ecat_header_tree, tvb, suboffset, 2, + ett_ecat_length, NULL, "Length : %d (0x%x) - %s - %s", + len, len, ecHdr.len & 0x4000 ? "Roundtrip" : "No Roundtrip", ecHdr.len & 0x8000 ? "More Follows..." : "Last Sub Command"); + + proto_tree_add_item(length_sub_tree, hf_ecat_length_len, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(length_sub_tree, hf_ecat_length_r, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(length_sub_tree, hf_ecat_length_c, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(length_sub_tree, hf_ecat_length_m, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + + suboffset+=2; + } + + proto_tree_add_item(ecat_header_tree, hf_ecat_int, tvb, suboffset, 2, ENC_LITTLE_ENDIAN); + suboffset+=2; + } + else + { + suboffset+=EcParserHDR_Len; + } + + if ( (ecHdr.cmd == 1 || ecHdr.cmd == 4) && ecHdr.anAddrUnion.a.ado == 0x900 && ecHdr.len >= 16 && cnt > 0 ) + { + guint32 pDC[4]; + init_dc_measure(pDC, tvb, suboffset); + + ecat_dc_tree = proto_tree_add_subtree(ecat_datagram_tree, tvb, suboffset, len, ett_ecat_dc, NULL, "Dc"); + dissect_esc_register(pinfo, ecat_dc_tree, tvb, suboffset, len, &ecHdr, cnt); + + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, len, ENC_NA); + proto_item_set_hidden(aitem); + } + + if ( pDC[3] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_da, tvb, suboffset, 4, pDC[3] - pDC[0]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_da[subCount], tvb, suboffset, 4, pDC[3] - pDC[0]); + proto_item_set_hidden(hidden_item); + } + + if ( pDC[1] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_bd, tvb, suboffset, 4, pDC[1] - pDC[3]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_bd[subCount], tvb, suboffset, 4, pDC[1] - pDC[3]); + proto_item_set_hidden(hidden_item); + } + } + else if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cd, tvb, suboffset, 4, pDC[2] - pDC[3]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_cd[subCount], tvb, suboffset, 4, pDC[2] - pDC[3]); + proto_item_set_hidden(hidden_item); + } + } + } + if ( pDC[1] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ba, tvb, suboffset, 4, pDC[1] - pDC[0]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_ba[subCount], tvb, suboffset, 4, pDC[1] - pDC[0]); + proto_item_set_hidden(hidden_item); + } + if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cb, tvb, suboffset, 4, pDC[2] - pDC[1]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_cb[subCount], tvb, suboffset, 4, pDC[2] - pDC[1]); + proto_item_set_hidden(hidden_item); + } + } + } + else if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ca, tvb, suboffset, 4, pDC[2] - pDC[0]); + if( subCount < 10 ){ + hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_ca[subCount], tvb, suboffset, 4, pDC[2] - pDC[0]); + proto_item_set_hidden(hidden_item); + } + } + } + else if (dissect_esc_register(pinfo, ecat_datagram_tree, tvb, suboffset, len, &ecHdr, cnt) != 0) + { + guint startOfData = offset + EcParserHDR_Len; + guint dataLength = len; + + if ( len >= ETHERCAT_MBOX_HEADER_LEN && + ((ecHdr.cmd==EC_CMD_TYPE_FPWR || ecHdr.cmd == EC_CMD_TYPE_APWR || ecHdr.cmd == EC_CMD_TYPE_APRW || ecHdr.cmd == EC_CMD_TYPE_FPRW) || ((ecHdr.cmd==EC_CMD_TYPE_FPRD || ecHdr.cmd==EC_CMD_TYPE_APRD) && cnt==1) ) && + ecHdr.anAddrUnion.a.ado>=0x1000 + ) + { + init_mbx_header(&mbox, tvb, startOfData); + switch ( mbox.aControlUnion.v.Type ) + { + case ETHERCAT_MBOX_TYPE_EOE: + case ETHERCAT_MBOX_TYPE_ADS: + case ETHERCAT_MBOX_TYPE_FOE: + case ETHERCAT_MBOX_TYPE_COE: + case ETHERCAT_MBOX_TYPE_SOE: + if ( mbox.Length <= 1500 ) + { + guint MBoxLength = mbox.Length + ETHERCAT_MBOX_HEADER_LEN; + if ( MBoxLength > len ) + MBoxLength = len; + + next_tvb = tvb_new_subset_length(tvb, startOfData, MBoxLength); + call_dissector_only(ecat_mailbox_handle, next_tvb, pinfo, ecat_datagram_tree, NULL); + + startOfData += MBoxLength; + dataLength -= MBoxLength; + } + break; + } + } + if( dataLength > 0 ) + { + /* Allow sub dissectors to have a chance with this data */ + if(!dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, ecat_datagram_tree, &hdtbl_entry, NULL)) + { + /* No sub dissector did recognize this data, dissect it as data only */ + proto_tree_add_item(ecat_datagram_tree, hf_ecat_data, tvb, startOfData, dataLength, ENC_NA); + } + + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_data[subCount], tvb, startOfData, dataLength, ENC_NA); + proto_item_set_hidden(aitem); + } + } + } + + if( tree ) + { + proto_tree_add_item(ecat_datagram_tree, hf_ecat_cnt, tvb, offset + EcParserHDR_Len + len , 2, ENC_LITTLE_ENDIAN); + if( subCount < 10 ){ + aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_cnt[subCount], tvb, offset + EcParserHDR_Len + len , 2, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(aitem); + } + } + + offset+=subsize; + subCount++; + } while((offset < datagram_length) && + (ecHdr.len & 0x8000)); + + /* Add information that states which portion of the PDU that is pad bytes. + These are added just to get an Ethernet frame size of at least 64 bytes, + which is required by the protocol specification */ + if(datagram_padding_bytes > 0) + { + proto_tree_add_item(tree, hf_ecat_padding, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA); + } + return tvb_captured_length(tvb); +} + +void proto_register_ecat(void) +{ + static hf_register_info hf[] = + { + { &hf_ecat_sub, + { "EtherCAT Frame", "ecat.sub", FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ecat_header, + { "header", "ecat.header", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, +#endif + { &hf_ecat_sub_data[0], + { "Data", "ecat.sub1.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[1], + { "Data", "ecat.sub2.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[2], + { "Data", "ecat.sub3.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[3], + { "Data", "ecat.sub4.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[4], + { "Data", "ecat.sub5.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[5], + { "Data", "ecat.sub6.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[6], + { "Data", "ecat.sub7.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[7], + { "Data", "ecat.sub8.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[8], + { "Data", "ecat.sub9.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_data[9], + { "Data", "ecat.sub10.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_data, + { "Data", "ecat.data", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_cnt, + { "Working Cnt", "ecat.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "The working counter is increased once for each addressed device if at least one byte/bit of the data was successfully read and/or written by that device, it is increased once for every operation made by that device - read/write/read and write", HFILL } + }, + { &hf_ecat_sub_cnt[0], + { "Working Cnt", "ecat.sub1.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[1], + { "Working Cnt", "ecat.sub2.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[2], + { "Working Cnt", "ecat.sub3.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[3], + { "Working Cnt", "ecat.sub4.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[4], + { "Working Cnt", "ecat.sub5.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[5], + { "Working Cnt", "ecat.sub6.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[6], + { "Working Cnt", "ecat.sub7.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[7], + { "Working Cnt", "ecat.sub8.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[8], + { "Working Cnt", "ecat.sub9.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cnt[9], + { "Working Cnt", "ecat.sub10.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_cmd, + { "Command", "ecat.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[0], + { "Command", "ecat.sub1.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[1], + { "Command", "ecat.sub2.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[2], + { "Command", "ecat.sub3.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[3], + { "Command", "ecat.sub4.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[4], + { "Command", "ecat.sub5.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[5], + { "Command", "ecat.sub6.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[6], + { "Command", "ecat.sub7.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[7], + { "Command", "ecat.sub8.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[8], + { "Command", "ecat.sub9.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_cmd[9], + { "Command", "ecat.sub10.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmdShort), 0x0, NULL, HFILL } + }, + { &hf_ecat_idx, + { "Index", "ecat.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[0], + { "Index", "ecat.sub1.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[1], + { "Index", "ecat.sub2.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[2], + { "Index", "ecat.sub3.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[3], + { "Index", "ecat.sub4.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[4], + { "Index", "ecat.sub5.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[5], + { "Index", "ecat.sub6.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[6], + { "Index", "ecat.sub7.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[7], + { "Index", "ecat.sub8.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[8], + { "Index", "ecat.sub9.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_idx[9], + { "Index", "ecat.sub10.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_adp, + { "Slave Addr", "ecat.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[0], + { "Slave Addr", "ecat.sub1.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[1], + { "Slave Addr", "ecat.sub2.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[2], + { "Slave Addr", "ecat.sub3.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[3], + { "Slave Addr", "ecat.sub4.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[4], + { "Slave Addr", "ecat.sub5.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[5], + { "Slave Addr", "ecat.sub6.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[6], + { "Slave Addr", "ecat.sub7.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[7], + { "Slave Addr", "ecat.sub8.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[8], + { "Slave Addr", "ecat.sub9.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_adp[9], + { "Slave Addr", "ecat.sub10.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_ado, + { "Offset Addr", "ecat.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[0], + { "Offset Addr", "ecat.sub1.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[1], + { "Offset Addr", "ecat.sub2.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[2], + { "Offset Addr", "ecat.sub3.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[3], + { "Offset Addr", "ecat.sub4.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[4], + { "Offset Addr", "ecat.sub5.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[5], + { "Offset Addr", "ecat.sub6.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[6], + { "Offset Addr", "ecat.sub7.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[7], + { "Offset Addr", "ecat.sub8.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[8], + { "Offset Addr", "ecat.sub9.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_ado[9], + { "Offset Addr", "ecat.sub10.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_lad, + { "Log Addr", "ecat.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[0], + { "Log Addr", "ecat.sub1.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[1], + { "Log Addr", "ecat.sub2.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[2], + { "Log Addr", "ecat.sub3.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[3], + { "Log Addr", "ecat.sub4.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[4], + { "Log Addr", "ecat.sub5.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[5], + { "Log Addr", "ecat.sub6.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[6], + { "Log Addr", "ecat.sub7.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[7], + { "Log Addr", "ecat.sub8.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[8], + { "Log Addr", "ecat.sub9.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_lad[9], + { "Log Addr", "ecat.sub10.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, +#if 0 + { &hf_ecat_len, + { "Length", "ecat.len", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_ecat_int, + { "Interrupt", "ecat.int", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_da, + { "DC D-A", "ecat.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_bd, + { "DC B-D", "ecat.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_cb, + { "DC C-B", "ecat.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_cd, + { "DC C-D", "ecat.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_ba, + { "DC B-A", "ecat.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_dc_diff_ca, + { "DC C-A", "ecat.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[0], + { "DC D-A", "ecat.sub1.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[1], + { "DC D-A", "ecat.sub2.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[2], + { "DC D-A", "ecat.sub3.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[3], + { "DC D-A", "ecat.sub4.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[4], + { "DC D-A", "ecat.sub5.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[5], + { "DC D-A", "ecat.sub6.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[6], + { "DC D-A", "ecat.sub7.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[7], + { "DC D-A", "ecat.sub8.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[8], + { "DC D-A", "ecat.sub9.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_da[9], + { "DC D-A", "ecat.sub10.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + { &hf_ecat_sub_dc_diff_bd[0], + { "DC B-C", "ecat.sub1.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[1], + { "DC B-C", "ecat.sub2.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[2], + { "DC B-C", "ecat.sub3.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[3], + { "DC B-C", "ecat.sub4.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[4], + { "DC B-C", "ecat.sub5.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[5], + { "DC B-C", "ecat.sub6.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[6], + { "DC B-C", "ecat.sub7.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[7], + { "DC B-C", "ecat.sub8.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[8], + { "DC B-C", "ecat.sub9.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[9], + { "DC B-D", "ecat.sub10.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + { &hf_ecat_sub_dc_diff_cb[0], + { "DC C-B", "ecat.sub1.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[1], + { "DC C-B", "ecat.sub2.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[2], + { "DC C-B", "ecat.sub3.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[3], + { "DC C-B", "ecat.sub4.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[4], + { "DC C-B", "ecat.sub5.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[5], + { "DC C-B", "ecat.sub6.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[6], + { "DC C-B", "ecat.sub7.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[7], + { "DC C-B", "ecat.sub8.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[8], + { "DC C-B", "ecat.sub9.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[9], + { "DC C-B", "ecat.sub10.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + { &hf_ecat_sub_dc_diff_cd[0], + { "DC C-D", "ecat.sub1.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[1], + { "DC C-D", "ecat.sub2.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[2], + { "DC C-D", "ecat.sub3.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[3], + { "DC C-D", "ecat.sub4.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[4], + { "DC C-D", "ecat.sub5.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[5], + { "DC C-D", "ecat.sub6.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[6], + { "DC C-D", "ecat.sub7.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[7], + { "DC C-D", "ecat.sub8.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[8], + { "DC C-D", "ecat.sub9.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[9], + { "DC C-D", "ecat.sub10.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + { &hf_ecat_sub_dc_diff_ba[0], + { "DC B-A", "ecat.sub1.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[1], + { "DC B-A", "ecat.sub2.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[2], + { "DC B-A", "ecat.sub3.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[3], + { "DC B-A", "ecat.sub4.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[4], + { "DC B-A", "ecat.sub5.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[5], + { "DC B-A", "ecat.sub6.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[6], + { "DC B-A", "ecat.sub7.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[7], + { "DC B-A", "ecat.sub8.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[8], + { "DC B-A", "ecat.sub9.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[9], + { "DC B-A", "ecat.sub10.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + { &hf_ecat_sub_dc_diff_ca[0], + { "DC C-A", "ecat.sub1.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[1], + { "DC C-A", "ecat.sub2.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[2], + { "DC C-A", "ecat.sub3.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[3], + { "DC C-A", "ecat.sub4.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[4], + { "DC C-A", "ecat.sub5.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[5], + { "DC C-A", "ecat.sub6.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[6], + { "DC C-A", "ecat.sub7.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[7], + { "DC C-A", "ecat.sub8.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[8], + { "DC C-A", "ecat.sub9.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[9], + { "DC C-A", "ecat.sub10.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_length_len, + { "Length", "ecat.subframe.length", + FT_UINT16, BASE_DEC, NULL, 0x07ff, NULL, HFILL} + }, + { &hf_ecat_length_r, + { "Reserved", "ecat.subframe.reserved", + FT_UINT16, BASE_DEC, VALS(ecat_subframe_reserved_vals), 0x3800, NULL, HFILL} + }, + { &hf_ecat_length_c, + { "Round trip", "ecat.subframe.circulating", + FT_BOOLEAN, 16, TFS(&tfs_ecat_subframe_circulating_vals), 0x4000, NULL, HFILL} + }, + { &hf_ecat_length_m, + { "Last indicator", "ecat.subframe.more", + FT_BOOLEAN, 16, TFS(&tfs_ecat_subframe_more_vals), 0x8000, NULL, HFILL} + }, + { &hf_ecat_padding, + { "Pad bytes", "ecat.subframe.pad_bytes", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} + }, + + /* Registers */ + { &hf_ecat_reg_revision, + {"ESC Revision (0x0)", "ecat.reg.revision", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_type, + {"ESC Type (0x1)", "ecat.reg.type", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_build, + {"ESC Build (0x2)", "ecat.reg.build", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_fmmucnt, + {"ESC FMMU Cnt (0x4)", "ecat.reg.fmmucnt", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_smcnt, + {"ESC SM Cnt (0x5)", "ecat.reg.smcnt", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_ports, + {"ESC Ports (0x6)", "ecat.reg.ports", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_dpram, + {"ESC DPRAM (0x7)", "ecat.reg.dpram", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features, + {"ESC Features (0x8)", "ecat.reg.features", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_fmmurestrict, + {"FMMU bytewise restriction", "ecat.reg.features.fmmurestrict", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_smaddrrestrict, + {"SM addressing restriction", "ecat.reg.features.smaddrrestrict", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0002, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_dcsupport, + {"DC support", "ecat.reg.features.dcsupport", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0004, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_dc64support, + {"DC 64 bit support", "ecat.reg.features.dc64support", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0008, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_ebuslowjitter, + {"E-Bus low jitter", "ecat.reg.features.ebuslowjitter", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_ebusextlinkdetect, + {"E-Bus ext. link detection", "ecat.reg.features.ebusextlinkdetect", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_miiextlinkdetect, + {"MII ext. link detection", "ecat.reg.features.miiextlinkdetect", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0040, NULL, HFILL } + }, + { &hf_ecat_reg_esc_features_crcext, + {"CRC ext. detection", "ecat.reg.features.crcext", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0080, NULL, HFILL } + }, + { &hf_ecat_reg_physaddr, + {"Phys Addr (0x10)", "ecat.reg.physaddr", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_physaddr2, + {"Phys Addr 2nd (0x12)", "ecat.reg.physaddr2", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1, + {"ESC Ctrl (0x100)", "ecat.reg.dlctrl1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1_killnonecat, + {"Kill non EtherCAT frames", "ecat.reg.dlctrl1.killnonecat", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1_port0extlinkdetect, + {"Port 0 ext. link detection", "ecat.reg.dlctrl1.port0extlinkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1_port1extlinkdetect, + {"Port 1 ext. link detection", "ecat.reg.dlctrl1.port1extlinkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1_port2extlinkdetect, + {"Port 2 ext. link detection", "ecat.reg.dlctrl1.port2extlinkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x40, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl1_port3extlinkdetect, + {"Port 3 ext. link detection", "ecat.reg.dlctrl1.port3extlinkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x80, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl2, + {"ESC Ctrl (0x101)", "ecat.reg.dlcrtl2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl2_port0, + {"Port 0", "ecat.reg.dlcrtl2.port0", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_101), 0x03, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl2_port1, + {"Port 1", "ecat.reg.dlcrtl2.port1", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_101), 0x0C, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl2_port2, + {"Port 2", "ecat.reg.dlcrtl2.port2", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_101), 0x30, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl2_port3, + {"Port 3", "ecat.reg.dlcrtl2.port3", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_101), 0xC0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl3, + {"ESC Ctrl (0x102)", "ecat.reg.dlctrl3", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl3_fifosize, + {"Fifo size", "ecat.reg.dlctrl3.fifosize", + FT_UINT8, BASE_HEX, NULL, 0x07, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl3_lowebusjit, + {"Low E-Bus jitter", "ecat.reg.dlctrl3.lowebusjit", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl4, + {"ESC Ctrl (0x103)", "ecat.reg.dlctrl4", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlctrl4_2ndaddress, + {"Second address", "ecat.reg.dlctrl4.2ndaddress", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1, + {"ESC Status (0x110)", "ecat.reg.dlstatus1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_operation, + {"Operation", "ecat.reg.dlstatus1.operation", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_pdiwatchdog, + {"PDI watchdog", "ecat.reg.dlstatus1.pdiwatchdog", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_watchdog), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_enhlinkdetect, + {"Enh. Link Detection", "ecat.reg.dlstatus1.enhlinkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disabled_enabled), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_physlink_port0, + {"Physical link Port 0", "ecat.reg.dlstatus1.physlink.port0", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_physlink_port1, + {"Physical link Port 1", "ecat.reg.dlstatus1.physlink.port1", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_physlink_port2, + {"Physical link Port 2", "ecat.reg.dlstatus1.physlink.port2", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x40, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus1_physlink_port3, + {"Physical link Port 3", "ecat.reg.dlstatus1.physlink.port3", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x80, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus2, + {"ESC Status (0x111)", "ecat.reg.dlstatus2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus2_port0, + {"Port 0", "ecat.reg.dlstatus2.port0", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_111), 0x03, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus2_port1, + {"Port 1", "ecat.reg.dlstatus2.port1", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_111), 0x0C, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus2_port2, + {"Port 2", "ecat.reg.dlstatus2.port2", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_111), 0x30, NULL, HFILL } + }, + { &hf_ecat_reg_dlstatus2_port3, + {"Port 3", "ecat.reg.dlstatus2.port3", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_111), 0xC0, NULL, HFILL } + }, + { &hf_ecat_reg_regprotect, + {"Write Register Protect (0x20)", "ecat.reg.regprotect", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_accessprotect, + {"Access Protect (0x30)", "ecat.reg.accessprotect", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_resetecat, + {"ESC reset Ecat (0x40)", "ecat.reg.resetecat", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_resetpdi, + {"ESC reset Pdi (0x41)", "ecat.reg.resetpdi", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_regphysrwoffs, + {"Phys. RW Offset (0x108)", "ecat.regphysrwoffs", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_alctrl, + {"AL Ctrl (0x120)", "ecat.reg.alctrl", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_alctrl_ctrl, + {"Al Ctrl", "ecat.reg.alctrl.ctrl", + FT_UINT16, BASE_HEX, VALS(vals_esc_reg_120), 0x0f, NULL, HFILL } + }, + { &hf_ecat_reg_alctrl_errack, + {"Error Ack", "ecat.reg.alctrl.errack", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_alctrl_id, + {"Id", "ecat.reg.alctrl.id", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_alstatus, + {"AL Status (0x130)", "ecat.reg.alstatus", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_alstatus_status, + {"Al Status", "ecat.reg.alstatus.status", + FT_UINT16, BASE_HEX, VALS(vals_esc_reg_120), 0x000f, NULL, HFILL } + }, + { &hf_ecat_reg_alstatus_err, + {"Error", "ecat.reg.alstatus.err", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_alstatus_id, + {"Id", "ecat.reg.alstatus.id", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_alstatuscode, + {"AL Status Code (0x134)", "ecat.reg.alstatuscode", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl1, + {"PDI Ctrl (0x140)", "ecat.reg.pdictrl1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl1_pdi, + {"PDI", "ecat.reg.pdictrl1.pdi", + FT_UINT8, BASE_HEX, VALS(vals_esc_reg_140), 0xff, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2, + {"PDI Ctrl (0x141)", "ecat.reg.pdictrl2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_devemul, + {"Device emulation", "ecat.reg.pdictrl2.devemul", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_enhlnkdetect, + {"Enhanced link detection", "ecat.reg.pdictrl2.enhlnkdetect", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_dcsyncout, + {"Enable DC sync out", "ecat.reg.pdictrl2.dcsyncout", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_dcsyncin, + {"Enable DC latch in", "ecat.reg.pdictrl2.dcsyncin", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_enhlnkdetect0, + {"Enhanced link detection port 0", "ecat.reg.pdictrl2.enhlnkdetect0", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_enhlnkdetect1, + {"Enhanced link detection port 1", "ecat.reg.pdictrl2.enhlnkdetect1", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_enhlnkdetect2, + {"Enhanced link detection port 2", "ecat.reg.pdictrl2.enhlnkdetect2", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x40, NULL, HFILL } + }, + { &hf_ecat_reg_pdictrl2_enhlnkdetect3, + {"Enhanced link detection port 3", "ecat.reg.pdictrl2.enhlnkdetect3", + FT_BOOLEAN, 8, TFS(&tfs_local_disable_enable), 0x80, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask, + {"ECAT IRQ Mask (0x200)", "ecat.reg.irqmask.ecat_mask", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_latchevt, + {"Latch event", "ecat.reg.irqmask.ecat_mask.latchevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_escstatevt, + {"ESC Status event", "ecat.reg.irqmask.ecat_mask.escstatevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0004, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_alstatevt, + {"AL Status event", "ecat.reg.irqmask.ecat_mask.alstatevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0008, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm0irq, + {"SM 0 IRQ", "ecat.reg.irqmask.ecat_mask.sm0irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm1irq, + {"SM 1 IRQ", "ecat.reg.irqmask.ecat_mask.sm1irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm2irq, + {"SM 2 IRQ", "ecat.reg.irqmask.ecat_mask.sm2irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0400, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm3irq, + {"SM 3 IRQ", "ecat.reg.irqmask.ecat_mask.sm3irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm4irq, + {"SM 4 IRQ", "ecat.reg.irqmask.ecat_mask.sm4irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm5irq, + {"SM 5 IRQ", "ecat.reg.irqmask.ecat_mask.sm5irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x2000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm6irq, + {"SM 6 IRQ", "ecat.reg.irqmask.ecat_mask.sm6irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_mask_sm7irq, + {"SM 7 IRQ", "ecat.reg.irqmask.ecat_mask.sm7irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL, + {"PDI IRQ Mask L (0x204)", "ecat.reg.irqmask.pdiL", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_alctrl, + {"AL Ctrl", "ecat.reg.irqmask.pdiL.alctrl", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_latchin, + {"Latch input", "ecat.reg.irqmask.pdiL.latchin", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0002, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sync0, + {"SYNC 0", "ecat.reg.irqmask.pdiL.sync0", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0004, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sync1, + {"SYNC 1", "ecat.reg.irqmask.pdiL.sync1", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0008, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_smchg, + {"SM changed", "ecat.reg.irqmask.pdiL.smchg", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_eepromcmdpen, + {"EEPROM command pending", "ecat.reg.irqmask.pdiL.eepromcmdpen", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm0, + {"SM 0", "ecat.reg.irqmask.pdiL.sm0", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm1, + {"SM 1", "ecat.reg.irqmask.pdiL.sm1", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm2, + {"SM 2", "ecat.reg.irqmask.pdiL.sm2", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0400, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm3, + {"SM 3", "ecat.reg.irqmask.pdiL.sm3", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm4, + {"SM 4", "ecat.reg.irqmask.pdiL.sm4", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1000, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm5, + {"SM 5", "ecat.reg.irqmask.pdiL.sm5", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x2000, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm6, + {"SM 6", "ecat.reg.irqmask.pdiL.sm6", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_pdiL_sm7, + {"SM 7", "ecat.reg.irqmask.pdiL.sm7", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + { &hf_ecat_reg_pdiH, + {"PDI IRQ Mask H (0x206)", "ecat.reg.irqmask.pdiH", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_ecat, + {"ECAT IRQ (0x210)", "ecat.reg.irq.ecat", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_latchevt, + {"Latch event", "ecat.reg.irq.ecat.latchevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_escstatevt, + {"ESC Status event", "ecat.reg.irq.ecat.escstatevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0004, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_alstatevt, + {"AL Status event", "ecat.reg.irq.ecat.alstatevt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0008, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm0irq, + {"SM 0 IRQ", "ecat.reg.irq.ecat.sm0irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm1irq, + {"SM 1 IRQ", "ecat.reg.irq.ecat.sm1irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm2irq, + {"SM 2 IRQ", "ecat.reg.irq.ecat.sm2irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0400, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm3irq, + {"SM 3 IRQ", "ecat.reg.irq.ecat.sm3irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm4irq, + {"SM 4 IRQ", "ecat.reg.irq.ecat.sm4irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm5irq, + {"SM 5 IRQ", "ecat.reg.irq.ecat.sm5irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x2000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm6irq, + {"SM 6 IRQ", "ecat.reg.irq.ecat.sm6irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_ecat_sm7irq, + {"SM 7 IRQ", "ecat.reg.irq.ecat.sm7irq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1, + {"PDI IRQ 1 (0x220)", "ecat.reg.irq.pdi1", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_alctrl, + {"AL Ctrl", "ecat.reg.irq.pdi1.alctrl", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_latchin, + {"Latch input", "ecat.reg.irq.pdi1.latchin", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0002, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sync0, + {"SYNC 0", "ecat.reg.irq.pdi1.sync0", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0004, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sync1, + {"SYNC 1", "ecat.reg.irq.pdi1.sync1", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0008, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_smchg, + {"SM changed", "ecat.reg.irq.pdi1.smchg", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_eepromcmdpen, + {"EEPROM command pending", "ecat.reg.irq.pdi1.eepromcmdpen", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm0, + {"SM 0", "ecat.reg.irq.pdi1.sm0", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm1, + {"SM 1", "ecat.reg.irq.pdi1.sm1", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm2, + {"SM 2", "ecat.reg.irq.pdi1.sm2", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0400, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm3, + {"SM 3", "ecat.reg.irq.pdi1.sm3", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm4, + {"SM 4", "ecat.reg.irq.pdi1.sm4", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1000, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm5, + {"SM 5", "ecat.reg.irq.pdi1.sm5", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x2000, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm6, + {"SM 6", "ecat.reg.irq.pdi1.sm6", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_pdi1_sm7, + {"SM 7", "ecat.reg.irq.pdi1.sm7", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + { &hf_ecat_reg_pdi2, + {"PDI IRQ 2 (0x222)", "ecat.reg.irq.pdi2", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc0, + {"CRC 0 (0x300)", "ecat.reg.crc0", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc1, + {"CRC 1 (0x302)", "ecat.reg.crc1", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc2, + {"CRC 2 (0x304)", "ecat.reg.crc2", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc3, + {"CRC 3 (0x306)", "ecat.reg.crc3", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc0_frame, + {"Invalid frame", "ecat.reg.crc0.frame", + FT_UINT16, BASE_HEX, NULL, 0x00ff, NULL, HFILL } + }, + { &hf_ecat_reg_crc0_rx, + {"RX error", "ecat.reg.crc0.rx", + FT_UINT16, BASE_HEX, NULL, 0xff00, NULL, HFILL } + }, + { &hf_ecat_reg_crc1_frame, + {"Invalid frame", "ecat.reg.crc1.frame", + FT_UINT16, BASE_HEX, NULL, 0x00ff, NULL, HFILL } + }, + { &hf_ecat_reg_crc1_rx, + {"RX error", "ecat.reg.crc1.rx", + FT_UINT16, BASE_HEX, NULL, 0xff00, NULL, HFILL } + }, + { &hf_ecat_reg_crc2_frame, + {"Invalid frame", "ecat.reg.crc2.frame", + FT_UINT16, BASE_HEX, NULL, 0x00ff, NULL, HFILL } + }, + { &hf_ecat_reg_crc2_rx, + {"RX error", "ecat.reg.crc2.rx", + FT_UINT16, BASE_HEX, NULL, 0xff00, NULL, HFILL } + }, + { &hf_ecat_reg_crc3_frame, + {"Invalid frame", "ecat.reg.crc3.frame", + FT_UINT16, BASE_HEX, NULL, 0x00ff, NULL, HFILL } + }, + { &hf_ecat_reg_crc3_rx, + {"RX error", "ecat.reg.crc3.rx", + FT_UINT16, BASE_HEX, NULL, 0xff00, NULL, HFILL } + }, + { &hf_ecat_reg_crc_fwd0, + {"Forw. CRC 0 (0x308)", "ecat.reg.crc.fwd0", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc_fwd1, + {"Forw. CRC 1 (0x309)", "ecat.reg.crc.fwd1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc_fwd2, + {"Forw. CRC 2 (0x30A)", "ecat.reg.crc.fwd2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_crc_fwd3, + {"Forw. CRC 3 (0x30B)", "ecat.reg.crc.fwd3", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_processuniterr, + {"Process unit error (0x30C)", "ecat.reg.processuniterr", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_pdierr, + {"PDI error (0x30D)", "ecat.reg.pdierr", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_linklost0, + {"Link Lost 0 (0x310)", "ecat.reg.linklost0", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_linklost1, + {"Link Lost 1 (0x311)", "ecat.reg.linklost1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_linklost2, + {"Link Lost 2 (0x312)", "ecat.reg.linklost2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_linklost3, + {"Link Lost 3 (0x313)", "ecat.reg.linklost3", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_divisor, + {"WD Divisor (0x400)", "ecat.reg.wd.divisor", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_timepdi, + {"WD Time PDI (0x410)", "ecat.reg.wd.timepdi", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_timesm, + {"WD Time SM (0x420)", "ecat.reg.wd.timesm", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_status, + {"WD Status (0x440)", "ecat.reg.wd.status", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_status_pdwatchdog, + {"PD watchdog", "ecat.reg.wd.status.pdwatchdog", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_watchdog), 0x1, NULL, HFILL } + }, + { &hf_ecat_reg_wd_cntsm, + {"WD SM Counter (0x442)", "ecat.reg.wd.cntsm", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_wd_cntpdi, + {"WD PDI Counter (0x443)", "ecat.reg.wd.cntpdi", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_eeprom_assign, + {"EEPROM Assign (0x500)", "ecat.reg.eeprom.assign", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_eeprom_assign_ctrl, + {"EEPROM access ctrl", "ecat.reg.eeprom.assign.ctrl", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_500_0), 0x1, NULL, HFILL } + }, + { &hf_ecat_reg_eeprom_assign_pdiaccess, + {"Reset PDI access", "ecat.reg.eeprom.assign.pdiaccess", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_500_1), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_eeprom_assign_status, + {"EEPROM access status", "ecat.reg.eeprom.assign.status", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_500_0), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat, + {"EEPROM Ctrl/Status (0x502)", "ecat.reg.ctrlstat", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_wraccess, + {"Write access", "ecat.reg.ctrlstat.wraccess", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + /* Next 4 bits reserved */ + { &hf_ecat_reg_ctrlstat_eepromemul, + {"EEPROM emulation", "ecat.reg.ctrlstat.eepromemul", + FT_BOOLEAN, 16, TFS(&tfs_esc_reg_502_5), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_8bacc, + {"8 byte access", "ecat.reg.ctrlstat.8bacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0040, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_2bacc, + {"2 byte address", "ecat.reg.ctrlstat.2bacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0080, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_rdacc, + {"Read access", "ecat.reg.ctrlstat.rdacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_wracc, + {"Write access", "ecat.reg.ctrlstat.wracc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_reloadacc, + {"Reload access", "ecat.reg.ctrlstat.reloadacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0400, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_crcerr, + {"CRC error", "ecat.reg.ctrlstat.crcerr", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_lderr, + {"Load error", "ecat.reg.ctrlstat.lderr", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x1000, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_cmderr, + {"Cmd error", "ecat.reg.ctrlstat.cmderr", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x2000, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_wrerr, + {"Write error", "ecat.reg.ctrlstat.wrerr", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_ctrlstat_busy, + {"Busy", "ecat.reg.ctrlstat.busy", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + { &hf_ecat_reg_addrl, + {"EEPROM Address Lo (0x504)", "ecat.reg.addrl", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_addrh, + {"EEPROM Address Hi (0x506)", "ecat.reg.addrh", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_data0, + {"EEPROM Data 0 (0x508)", "ecat.reg.data0", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_data1, + {"EEPROM Data 1 (0x50A)", "ecat.reg.data1", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_data2, + {"EEPROM Data 2 (0x50c)", "ecat.reg.data2", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_data3, + {"EEPROM Data 3 (0x50e)", "ecat.reg.data3", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + + { &hf_ecat_reg_mio_ctrlstat, + {"Phy MIO Ctrl/Status (0x510)", "ecat.reg.mio.ctrlstat", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + /* TODO: check these masks (ecat_esc_reg_510) against spec. + * In particular hf_ecat_reg_mio_ctrlstat_offsphy is non-contiguous and overlaps wracc1 */ + { &hf_ecat_reg_mio_ctrlstat_wracc1, + {"Write access", "ecat.reg.mio.ctrlstat.wracc1", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_mio_ctrlstat_offsphy, + {"Offset Phy offset", "ecat.reg.mio.ctrlstat.offsphy", + FT_UINT16, BASE_HEX, NULL, 0x008f, NULL, HFILL } + }, + { &hf_ecat_reg_mio_ctrlstat_rdacc, + {"Read access", "ecat.reg.mio.ctrlstat.rdacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_mio_ctrlstat_wracc2, + {"Write access", "ecat.reg.mio.ctrlstat.wracc2", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_mio_ctrlstat_wrerr, + {"Write error", "ecat.reg.mio.ctrlstat.wrerr", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x4000, NULL, HFILL } + }, + { &hf_ecat_reg_mio_ctrlstat_busy, + {"Busy", "ecat.reg.mio.ctrlstat.busy", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x8000, NULL, HFILL } + }, + + { &hf_ecat_reg_mio_addr, + {"Phy MIO Address (0x512)", "ecat.reg.mio.addr", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_addr_phyaddr, + {"Phy address", "ecat.reg.mio.addr.phyaddr", + FT_UINT16, BASE_HEX, NULL, 0x000F, NULL, HFILL } + }, + { &hf_ecat_reg_mio_addr_mioaddr, + {"MIO address", "ecat.reg.mio.addr.mioaddr", + FT_UINT16, BASE_HEX, NULL, 0x0F00, NULL, HFILL } + }, + { &hf_ecat_reg_mio_data, + {"Phy MIO Data (0x514)", "ecat.reg.mio.data", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_access, + {"MIO access (0x516)", "ecat.reg.mio.access", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_access_ecatacc, + {"ECAT claims exclusive access", "ecat.reg.mio.access.ecatacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_mio_access_pdiacc, + {"PDI has access to MII management", "ecat.reg.mio.access.pdiacc", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_mio_access_forcereset, + {"Force PDI to reset 0517.0", "ecat.reg.mio.access.forcereset", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0, + {"MIO port status 0 (0x518)", "ecat.reg.mio.status0", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_physlink, + {"Physical link detected", "ecat.reg.mio.status0.physlink", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_link, + {"Link detected", "ecat.reg.mio.status0.link", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_linkstatuserr, + {"Link status error", "ecat.reg.mio.status0.linkstatuserr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_readerr, + {"Read error", "ecat.reg.mio.status0.readerr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_linkpartnererr, + {"Link partner error", "ecat.reg.mio.status0.linkpartnererr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status0_phycfgupdated, + {"Phy config updated", "ecat.reg.mio.status0.phycfgupdated", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1, + {"MIO port status 1 (0x519)", "ecat.reg.mio.status1", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_physlink, + {"Physical link detected", "ecat.reg.mio.status1.physlink", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_link, + {"Link detected", "ecat.reg.mio.status1.link", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_linkstatuserr, + {"Link status error", "ecat.reg.mio.status1.linkstatuserr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_readerr, + {"Read error", "ecat.reg.mio.status1.readerr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_linkpartnererr, + {"Link partner error", "ecat.reg.mio.status1.linkpartnererr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status1_phycfgupdated, + {"Phy config updated", "ecat.reg.mio.status1.phycfgupdated", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2, + {"MIO port status 2 (0x51A)", "ecat.reg.mio.status2", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_physlink, + {"Physical link detected", "ecat.reg.mio.status2.physlink", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_link, + {"Link detected", "ecat.reg.mio.status2.link", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_linkstatuserr, + {"Link status error", "ecat.reg.mio.status2.linkstatuserr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_readerr, + {"Read error", "ecat.reg.mio.status2.readerr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_linkpartnererr, + {"Link partner error", "ecat.reg.mio.status2.linkpartnererr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status2_phycfgupdated, + {"Phy config updated", "ecat.reg.mio.status2.phycfgupdated", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3, + {"MIO port status 3 (0x51B)", "ecat.reg.mio.status3", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_physlink, + {"Physical link detected", "ecat.reg.mio.status3.physlink", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_link, + {"Link detected", "ecat.reg.mio.status3.link", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_linkstatuserr, + {"Link status error", "ecat.reg.mio.status3.linkstatuserr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_readerr, + {"Read error", "ecat.reg.mio.status3.readerr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_linkpartnererr, + {"Link partner error", "ecat.reg.mio.status3.linkpartnererr", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_mio_status3_phycfgupdated, + {"Phy config updated", "ecat.reg.mio.status3.phycfgupdated", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu, + {"FMMU", "ecat.fmmu", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_lstart, + { "Log Start", "ecat.fmmu.lstart", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_llen, + { "Log Length", "ecat.fmmu.llen", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_lstartbit, + { "Log StartBit", "ecat.fmmu.lstartbit", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_lendbit, + { "Log EndBit", "ecat.fmmu.lendbit", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_pstart, + { "Phys Start", "ecat.fmmu.pstart", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_pstartbit, + { "Phys StartBit", "ecat.fmmu.pstartbit", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_type, + { "Type", "ecat.fmmu.type", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_typeread, + { "Type", "ecat.fmmu.typeread", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typeread), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_typewrite, + { "Type", "ecat.fmmu.typewrite", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typewrite), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_activate, + { "Activate", "ecat.fmmu.activate", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_fmmu_activate0, + { "FMMU", "ecat.fmmu.activate0", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_activate), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_syncman, + {"SyncManager", "ecat.syncman", + FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_start, + {"SM Start", "ecat.syncman.start", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_len, + {"SM Length", "ecat.syncman.len", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_ctrlstatus, + {"SM Ctrl/Status", "ecat.syncman.ctrlstatus", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_pmode, + {"OpMode", "ecat.syncman.opmode", + FT_UINT16, BASE_HEX, VALS(vals_esc_reg_8041), 0x0003, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_access, + {"Access", "ecat.syncman.access", + FT_UINT16, BASE_HEX, VALS(vals_esc_reg_8042), 0x000c, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_irq_ecat, + {"ECAT IRQ", "ecat.syncman.irq.ecat", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0010, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_irq_pdi, + {"PDI IRQ", "ecat.syncman.irq.pdi", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0020, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_wdt, + {"Watchdog trigger", "ecat.syncman.wdt", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0040, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_irq_write, + {"IRQ write", "ecat.syncman.irq.write", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_irq_read, + {"IRQ read", "ecat.syncman.irq.read", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_1bufstate, + {"1 buffer state", "ecat.syncman.1bufstate", + FT_BOOLEAN, 16, TFS(&tfs_esc_reg_8051), 0x0800, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_3bufstate, + {"3 buffer state", "ecat.syncman.3bufstate", + FT_UINT16, BASE_HEX, VALS(vals_esc_reg_8052), 0x3000, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_sm_enable, + {"SM Enable", "ecat.syncman.smenable", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_enable, + {"Enable", "ecat.syncman.enable", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0001, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_repeatreq, + {"Repeat request", "ecat.syncman.repeatreq", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0002, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_latchsmchg_ecat, + {"Latch SyncMan Change ECAT", "ecat.syncman.latchsmchg.ecat", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0040, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_latchsmchg_pdi, + {"Latch SyncMan Change PDI", "ecat.syncman.latchsmchg.pdi", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0080, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_deactivate, + {"Deactivate", "ecat.syncman.deactivate", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0100, NULL, HFILL } + }, + { &hf_ecat_reg_syncman_repeatack, + {"Repeat acknowledge", "ecat.syncman.repeatack", + FT_BOOLEAN, 16, TFS(&tfs_local_true_false), 0x0200, NULL, HFILL } + }, + { &hf_ecat_reg_dc_recv0, + {"DC RecvTime_0 (0x900)", "ecat.reg.dc.recv0", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_recv1, + {"DC RecvTime_1 (0x904)", "ecat.reg.dc.recv1", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_recv2, + {"DC RecvTime_2 (0x908)", "ecat.reg.dc.recv2", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_recv3, + {"DC RecvTime_3 (0x90c)", "ecat.reg.dc.recv3", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systime, + {"DC SysTime (0x910)", "ecat.reg.dc.systime", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimeL, + {"DC SysTime L (0x910)", "ecat.reg.dc.systimeL", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimeH, + {"DC SysTime H (0x914)", "ecat.reg.dc.systimeH", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_recvtime64, + {"DC RecvTime (0x918)", "ecat.reg.dc.recvtime64", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimeoffs, + {"DC SysTimeOffs (0x920)", "ecat.reg.dc.systimeoffs", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimeoffsl, + {"DC SysTimeOffs L (0x920)", "ecat.reg.dc.systimeoffsl", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimeoffsh, + {"DC SysTimeOffs H (0x924)", "ecat.reg.dc.systimeoffsh", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_systimedelay, + {"DC SysTimeDelay (0x928)", "ecat.reg.dc.systimedelay", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_ctrlerr, + {"DC CtrlError (0x92c)", "ecat.reg.dc.ctrlerr", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_speedstart, + {"DC SpeedStart (0x930)", "ecat.reg.dc.speedstart", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_speeddiff, + {"DC SpeedDiff (0x932)", "ecat.reg.dc.speeddiff", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_fltdepth_systimediff, + {"DC Filter Depth System Time difference (0x934)", "ecat.reg.dc.fltdepth.systimediff", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_fltdepth_speedcnt, + {"DC Filter Depth Speed counter (0x935)", "ecat.reg.dc.fltdepth.speedcnt", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cycunitctrl, + {"DC Cyclic Unit Control (0x980)", "ecat.reg.dc.cycunitctrl", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cycunitctrl_access_cyclic, + {"Write access cyclic", "ecat.reg.dc.cycunitctrl.access_cyclic", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9801), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cycunitctrl_access_latch0, + {"Write access latch 0", "ecat.reg.dc.cycunitctrl.access_latch0", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9801), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cycunitctrl_access_latch1, + {"Write access latch 1", "ecat.reg.dc.cycunitctrl.access_latch1", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9801), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation, + {"DC Activation (0x981)", "ecat.reg.dc.activation", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_enablecyclic, + {"Enable cyclic", "ecat.reg.dc.activation.enablecyclic", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_gen_sync0, + {"Generate SYNC 0", "ecat.reg.dc.activation.gen_sync0", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_gen_sync1, + {"Generate SYNC 1", "ecat.reg.dc.activation.gen_sync1", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_autoactivation, + {"Auto activation", "ecat.reg.dc.activation.autoactivation", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x08, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_stimeext, + {"Start time extension 32->64", "ecat.reg.dc.activation.stimeext", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x10, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_stimecheck, + {"Start time chheck", "ecat.reg.dc.activation.stimecheck", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x20, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_hlfrange, + {"Half range", "ecat.reg.dc.activation.hlfrange", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x40, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activation_dblrange, + {"Debug pulse", "ecat.reg.dc.activation.dblrange", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x80, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cycimpuls, + {"DC CycImpulse (0x982)", "ecat.reg.dc.cycimpuls", + FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activationstat, + {"DC Activation status (0x984)", "ecat.reg.dc.activationstat", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activationstat_sync0pend, + {"SYNC 0 pending", "ecat.reg.dc.activationstat.sync0pend", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activationstat_sync1pend, + {"SYNC 1 pending", "ecat.reg.dc.activationstat.sync1pend", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_activationstat_stimeoutofrange, + {"Start time out of range", "ecat.reg.dc.activationstat.stimeoutofrange", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_dc_sync0_status, + {"DC Sync0 Status (0x98e)", "ecat.reg.dc.sync0.status", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_sync0_status_triggered, + {"triggered", "ecat.reg.dc.sync0.status.triggered", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_sync1_status, + {"DC Sync0 Status1 (0x98f)", "ecat.reg.dc.sync1.status", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_sync1_status_triggered, + {"triggered", "ecat.reg.dc.sync1.status.triggered", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_starttime0, + {"DC StartTime0 (0x990)", "ecat.reg.dc.starttime0", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_starttime1, + {"DC StartTime1 (0x998)", "ecat.reg.dc.starttime1", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cyctime0, + {"DC CycTime0 (0x9a0)", "ecat.reg.dc.cyctime0", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_cyctime1, + {"DC CycTime1 (0x9a4)", "ecat.reg.dc.cyctime1", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_ctrl, + {"DC Latch0 Ctrl (0x9a8)", "ecat.reg.dc.latch0.ctrl", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_ctrl_pos, + {"pos", "ecat.reg.dc.latch0.ctrl.pos", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9A8E1), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_ctrl_neg, + {"neg", "ecat.reg.dc.latch0.ctrl.neg", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9A8E1), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_ctrl, + {"DC Latch1 Ctrl (0x9a9)", "ecat.reg.dc.latch1.ctrl", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_ctrl_pos, + {"pos", "ecat.reg.dc.latch1.ctrl.pos", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9A8E1), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_ctrl_neg, + {"neg", "ecat.reg.dc.latch1.ctrl.neg", + FT_BOOLEAN, 8, TFS(&tfs_esc_reg_9A8E1), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_status, + {"DC Latch0 Status (0x9ae)", "ecat.reg.dc.latch0.status", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_status_eventpos, + {"Event pos", "ecat.reg.dc.latch0.status.eventpos", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_status_eventneg, + {"Event neg", "ecat.reg.dc.latch0.status.eventneg", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_status_pinstate, + {"pin state", "ecat.reg.dc.latch0.status.pinstate", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_status, + {"DC Latch1 Status (0x9af)", "ecat.reg.dc.latch1.status", + FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_status_eventpos, + {"Event pos", "ecat.reg.dc.latch1.status.eventpos", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x01, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_status_eventneg, + {"Event neg", "ecat.reg.dc.latch1.status.eventneg", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x02, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_status_pinstate, + {"pin state", "ecat.reg.dc.latch1.status.pinstate", + FT_BOOLEAN, 8, TFS(&tfs_local_true_false), 0x04, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_pos, + {"DC Latch0 Pos (0x9b0)", "ecat.reg.dc.latch0.pos", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch0_neg, + {"DC Latch0 Neg (0x9b8)", "ecat.reg.dc.latch0.neg", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_pos, + {"DC Latch1 Pos (0x9c0)", "ecat.reg.dc.latch1.pos", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_latch1_neg, + {"DC Latch1 Neg (0x9c8)", "ecat.reg.dc.latch1.neg", + FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_rcvsyncmanchg, + {"DC RecvSyncManChange (0x9f0)", "ecat.reg.dc.rcvsyncmanchg", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_pdismstart, + {"DC PdiSyncManStart (0x9f8)", "ecat.reg.dc.pdismstart", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + { &hf_ecat_reg_dc_pdismchg, + {"DC PdiSyncManChange (0x9fc)", "ecat.reg.dc.pdismchg", + FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } + }, + }; + + static gint *ett[] = + { + &ett_ecat, + &ett_ecat_header, + &ett_ecat_dc, + &ett_ecat_length, + &ett_ecat_padding, + &ett_ecat_datagram_subtree, + &ett_ecat_reg_esc_features, + &ett_ecat_reg_dlctrl1, + &ett_ecat_reg_dlctrl2, + &ett_ecat_reg_dlctrl3, + &ett_ecat_reg_dlctrl4, + &ett_ecat_reg_dlstatus1, + &ett_ecat_reg_dlstatus2, + &ett_ecat_reg_alctrl, + &ett_ecat_reg_alstatus, + &ett_ecat_reg_pdictrl1, + &ett_ecat_reg_pdictrl2, + &ett_ecat_reg_ecat_mask, + &ett_ecat_reg_pdiL, + &ett_ecat_reg_ecat, + &ett_ecat_reg_pdi1, + &ett_ecat_reg_crc0, + &ett_ecat_reg_crc1, + &ett_ecat_reg_crc2, + &ett_ecat_reg_crc3, + &ett_ecat_reg_wd_status, + &ett_ecat_reg_eeprom_assign, + &ett_ecat_reg_ctrlstat, + &ett_ecat_reg_mio_ctrlstat, + &ett_ecat_mio_addr, + &ett_ecat_mio_access, + &ett_ecat_mio_status0, + &ett_ecat_mio_status1, + &ett_ecat_mio_status2, + &ett_ecat_mio_status3, + &ett_ecat_reg_fmmu, + &ett_ecat_reg_syncman, + &ett_ecat_reg_syncman_ctrlstatus, + &ett_ecat_reg_syncman_sm_enable, + &ett_ecat_reg_dc_cycunitctrl, + &ett_ecat_dc_activation, + &ett_ecat_dc_activationstat, + &ett_ecat_dc_sync0_status, + &ett_ecat_dc_sync1_status, + &ett_ecat_dc_latch0_ctrl, + &ett_ecat_dc_latch1_ctrl, + &ett_ecat_dc_latch0_status, + &ett_ecat_dc_latch1_status, + }; + + proto_ecat_datagram = proto_register_protocol("EtherCAT datagram(s)", "ECAT", "ecat"); + proto_register_field_array(proto_ecat_datagram, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + ecat_handle = register_dissector("ecat", dissect_ecat_datagram, proto_ecat_datagram); + + /* Sub dissector code */ + heur_subdissector_list = register_heur_dissector_list("ecat.data", proto_ecat_datagram); +} + +/* The registration hand-off routing */ +void proto_reg_handoff_ecat(void) +{ + /* Register this dissector as a sub dissector to EtherCAT frame based on + ether type. */ + dissector_add_uint("ecatf.type", 1 /* EtherCAT type */, ecat_handle); + + ecat_mailbox_handle = find_dissector_add_dependency("ecat_mailbox", proto_ecat_datagram); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ethercat-datagram.h b/plugins/epan/ethercat/packet-ethercat-datagram.h new file mode 100644 index 00000000..b1565cfe --- /dev/null +++ b/plugins/epan/ethercat/packet-ethercat-datagram.h @@ -0,0 +1,36 @@ +/* packet-ethercat-datagram.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef _PACKET_ETHERCAT_DATAGRAM_ +#define _PACKET_ETHERCAT_DATAGRAM_ + +/* structure for decoding the header -----------------------------------------*/ +typedef union +{ + struct + { + guint16 adp; + guint16 ado; + } a; + guint32 addr; +} EcParserAddrUnion; + +typedef struct _EcParser +{ + guint8 cmd; + guint8 idx; + EcParserAddrUnion anAddrUnion; + guint16 len; + guint16 intr; +} EcParserHDR, *PEcParserHDR; + +#define EcParserHDR_Len 10/*sizeof(EcParserHDR)*/ + +#endif /* _PACKET_ETHERCAT_DATAGRAM_ */ diff --git a/plugins/epan/ethercat/packet-ethercat-frame.c b/plugins/epan/ethercat/packet-ethercat-frame.c new file mode 100644 index 00000000..3de05942 --- /dev/null +++ b/plugins/epan/ethercat/packet-ethercat-frame.c @@ -0,0 +1,153 @@ +/* packet-ethercat-frame.c + * Routines for ethercat packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Include files */ + +#include "config.h" + +#include <epan/packet.h> +#include <epan/etypes.h> + +#include "packet-ethercat-frame.h" + +void proto_register_ethercat_frame(void); +void proto_reg_handoff_ethercat_frame(void); + +/* Define the Ethercat frame proto */ +static int proto_ethercat_frame = -1; + +static dissector_table_t ethercat_frame_dissector_table; + +static dissector_handle_t ethercat_frame_handle; + +/* Define the tree for the EtherCAT frame */ +static int ett_ethercat_frame = -1; +static int hf_ethercat_frame_length = -1; +static int hf_ethercat_frame_reserved = -1; +static int hf_ethercat_frame_type = -1; + +static const value_string EthercatFrameTypes[] = +{ + { 1, "EtherCAT command", }, + { 2, "ADS", }, + { 3, "RAW-IO", }, + { 4, "NV", }, + { 5, "Mailbox"}, + { 0, NULL } +}; + +static const value_string ethercat_frame_reserved_vals[] = +{ + { 0, "Valid"}, + { 1, "Invalid (must be zero for conformance with the protocol specification)"}, + { 0, NULL} +}; + +/* Ethercat Frame */ +static int dissect_ethercat_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + tvbuff_t *next_tvb; + proto_item *ti; + proto_tree *ethercat_frame_tree; + gint offset = 0; + EtherCATFrameParserHDR hdr; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECATF"); + + col_clear(pinfo->cinfo, COL_INFO); + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ethercat_frame, tvb, offset, EtherCATFrameParserHDR_Len, ENC_NA); + ethercat_frame_tree = proto_item_add_subtree(ti, ett_ethercat_frame); + + proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_length, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_reserved, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); + proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_type, tvb, offset, EtherCATFrameParserHDR_Len, ENC_LITTLE_ENDIAN); + } + hdr.hdr = tvb_get_letohs(tvb, offset); + offset = EtherCATFrameParserHDR_Len; + + /* The EtherCAT frame header has now been processed, allow sub dissectors to + handle the rest of the PDU. */ + next_tvb = tvb_new_subset_remaining (tvb, offset); + + if (!dissector_try_uint(ethercat_frame_dissector_table, hdr.v.protocol, + next_tvb, pinfo, tree)) + { + col_add_fstr (pinfo->cinfo, COL_PROTOCOL, "0x%04x", hdr.v.protocol); + /* No sub dissector wanted to handle this payload, decode it as general + data instead. */ + call_data_dissector(next_tvb, pinfo, tree); + } + return tvb_captured_length(tvb); +} + +void proto_register_ethercat_frame(void) +{ + static hf_register_info hf[] = + { + { &hf_ethercat_frame_length, + { "Length", "ecatf.length", + FT_UINT16, BASE_HEX, NULL, 0x07FF, + NULL, HFILL } + }, + + { &hf_ethercat_frame_reserved, + { "Reserved", "ecatf.reserved", + FT_UINT16, BASE_HEX, VALS(ethercat_frame_reserved_vals), 0x0800, + NULL, HFILL} + }, + + { &hf_ethercat_frame_type, + { "Type", "ecatf.type", + FT_UINT16, BASE_HEX, VALS(EthercatFrameTypes), 0xF000, + "E88A4 Types", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ethercat_frame + }; + + proto_ethercat_frame = proto_register_protocol("EtherCAT frame header", "ETHERCAT", "ecatf"); + proto_register_field_array(proto_ethercat_frame,hf,array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + ethercat_frame_handle = register_dissector("ecatf", dissect_ethercat_frame, proto_ethercat_frame); + + /* Define a handle (ecatf.type) for sub dissectors that want to dissect + the Ethercat frame ether type (E88A4) payload. */ + ethercat_frame_dissector_table = register_dissector_table("ecatf.type", "EtherCAT frame type", + proto_ethercat_frame, FT_UINT8, BASE_DEC); +} + +void proto_reg_handoff_ethercat_frame(void) +{ + dissector_add_uint("ethertype", ETHERTYPE_ECATF, ethercat_frame_handle); + dissector_add_uint_with_preference("udp.port", ETHERTYPE_ECATF, ethercat_frame_handle); + dissector_add_uint_with_preference("tcp.port", ETHERTYPE_ECATF, ethercat_frame_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ethercat-frame.h b/plugins/epan/ethercat/packet-ethercat-frame.h new file mode 100644 index 00000000..2bb8c19b --- /dev/null +++ b/plugins/epan/ethercat/packet-ethercat-frame.h @@ -0,0 +1,33 @@ +/* paket-ethercat-frame.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef _PACKET_ETHERCAT_FRAME_H +#define _PACKET_ETHERCAT_FRAME_H + +#include <ws_diag_control.h> + +/* structure for decoding the header -----------------------------------------*/ +DIAG_OFF_PEDANTIC +typedef union _EtherCATFrameParser +{ + struct + { + guint16 length : 11; + guint16 reserved : 1; + guint16 protocol : 4; + } v; + guint16 hdr; +} EtherCATFrameParserHDR; +DIAG_ON_PEDANTIC +typedef EtherCATFrameParserHDR *PEtherCATFrameParserHDR; + +#define EtherCATFrameParserHDR_Len (int)sizeof(EtherCATFrameParserHDR) + +#endif /* _PACKET_ETHERCAT_FRAME_H */ diff --git a/plugins/epan/ethercat/packet-ioraw.c b/plugins/epan/ethercat/packet-ioraw.c new file mode 100644 index 00000000..846ae01c --- /dev/null +++ b/plugins/epan/ethercat/packet-ioraw.c @@ -0,0 +1,119 @@ +/* packet-ioraw.c + * Routines for ethercat packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Include files */ + +#include "config.h" + +#include <epan/packet.h> + +#include "packet-ioraw.h" + +void proto_register_ioraw(void); +void proto_reg_handoff_ioraw(void); + +/* Define the ioraw proto */ +int proto_ioraw = -1; + +static int ett_ioraw = -1; + +static dissector_handle_t ioraw_handle; + +/* static int hf_ioraw_summary = -1; */ +static int hf_ioraw_header = -1; +static int hf_ioraw_data = -1; + +/*ioraw*/ +static void IoRawSummaryFormater( char *szText, int nMax) +{ + snprintf ( szText, nMax, "Raw IO Data" ); +} + +static int dissect_ioraw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_item *ti; + proto_tree *ioraw_tree; + gint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint ioraw_length = tvb_reported_length(tvb); + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "IO-RAW"); + + IoRawSummaryFormater(szText, nMax); + col_add_str(pinfo->cinfo, COL_INFO, szText); + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ioraw, tvb, 0, -1, ENC_NA); + ioraw_tree = proto_item_add_subtree(ti, ett_ioraw); + + proto_item_append_text(ti,": %s",szText); + proto_tree_add_item(ioraw_tree, hf_ioraw_header, tvb, offset, IoRawParserHDR_Len, ENC_NA); + offset+=IoRawParserHDR_Len; + + proto_tree_add_item(ioraw_tree, hf_ioraw_data, tvb, offset, ioraw_length - offset, ENC_NA); + } + return tvb_captured_length(tvb); +} + +void proto_register_ioraw(void) +{ + static hf_register_info hf[] = + { +#if 0 + { &hf_ioraw_summary, + { "Summary of the IoRaw Packet", "ioraw.summary", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_ioraw_header, { "Header", "ioraw.header", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ioraw_data, { "VarData", "ioraw.data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + } + }; + + static gint *ett[] = + { + &ett_ioraw + }; + + proto_ioraw = proto_register_protocol("TwinCAT IO-RAW", + "IO-RAW","ioraw"); + proto_register_field_array(proto_ioraw,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); + ioraw_handle = register_dissector("ioraw", dissect_ioraw, proto_ioraw); +} + +void proto_reg_handoff_ioraw(void) +{ + dissector_add_uint("ecatf.type", 3, ioraw_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-ioraw.h b/plugins/epan/ethercat/packet-ioraw.h new file mode 100644 index 00000000..48f942ef --- /dev/null +++ b/plugins/epan/ethercat/packet-ioraw.h @@ -0,0 +1,21 @@ +/* packet-ioraw.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef _PACKET_IORAW_H_ +#define _PACKET_IORAW_H_ + +/* headers are only used for size and offset calculation*/ +typedef struct _IoRawParser +{ + guint32 head; +} IoRawParserHDR, *PIoRawParserHDR; +#define IoRawParserHDR_Len (int)sizeof(IoRawParserHDR) + +#endif /* _PACKET_IORAW_H_*/ diff --git a/plugins/epan/ethercat/packet-nv.c b/plugins/epan/ethercat/packet-nv.c new file mode 100644 index 00000000..b9f5c0ce --- /dev/null +++ b/plugins/epan/ethercat/packet-nv.c @@ -0,0 +1,240 @@ +/* packet-nv.c + * Routines for ethercat packet disassembly + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* Include files */ + +#include "config.h" + +#include <epan/packet.h> + +#include "packet-nv.h" + +void proto_register_nv(void); +void proto_reg_handoff_nv(void); + +/* Define the nv proto */ +int proto_nv = -1; + +static dissector_handle_t nv_handle; + +static int ett_nv = -1; +static int ett_nv_header = -1; +static int ett_nv_var = -1; +static int ett_nv_varheader = -1; + +/* static int hf_nv_summary = -1; */ +static int hf_nv_header = -1; +static int hf_nv_publisher = -1; +static int hf_nv_count = -1; +static int hf_nv_cycleindex = -1; +static int hf_nv_variable = -1; +static int hf_nv_varheader = -1; +static int hf_nv_id = -1; +static int hf_nv_hash = -1; +static int hf_nv_length = -1; +static int hf_nv_quality = -1; +static int hf_nv_data = -1; + +/*nv*/ +static void NvSummaryFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + guint32 nvOffset = offset; + + snprintf ( szText, nMax, "Network Vars from %d.%d.%d.%d.%d.%d - %d Var(s)", + tvb_get_guint8(tvb, nvOffset), + tvb_get_guint8(tvb, nvOffset+1), + tvb_get_guint8(tvb, nvOffset+2), + tvb_get_guint8(tvb, nvOffset+3), + tvb_get_guint8(tvb, nvOffset+4), + tvb_get_guint8(tvb, nvOffset+5), + tvb_get_letohs(tvb, nvOffset+6)); +} + +static void NvPublisherFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + guint32 nvOffset = offset; + + snprintf ( szText, nMax, "Publisher %d.%d.%d.%d.%d.%d", + tvb_get_guint8(tvb, nvOffset), + tvb_get_guint8(tvb, nvOffset+1), + tvb_get_guint8(tvb, nvOffset+2), + tvb_get_guint8(tvb, nvOffset+3), + tvb_get_guint8(tvb, nvOffset+4), + tvb_get_guint8(tvb, nvOffset+5)); +} + +static void NvVarHeaderFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + snprintf ( szText, nMax, "Variable - Id = %d, Length = %d", + tvb_get_letohs(tvb, offset), + tvb_get_letohs(tvb, offset+4)); +} + +static int dissect_nv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_item *ti; + proto_tree *nv_tree, *nv_header_tree, *nv_var_tree,*nv_varheader_tree; + gint offset = 0; + char szText[200]; + int nMax = (int)sizeof(szText)-1; + + gint i; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "TC-NV"); + + col_clear(pinfo->cinfo, COL_INFO); + + NvSummaryFormater(tvb, offset, szText, nMax); + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if (tree) + { + guint16 nv_count; + + ti = proto_tree_add_item(tree, proto_nv, tvb, 0, -1, ENC_NA); + nv_tree = proto_item_add_subtree(ti, ett_nv); + proto_item_append_text(ti,": %s",szText); + + ti = proto_tree_add_item(nv_tree, hf_nv_header, tvb, offset, NvParserHDR_Len, ENC_NA); + + nv_header_tree = proto_item_add_subtree(ti, ett_nv_header); + + ti= proto_tree_add_item(nv_header_tree, hf_nv_publisher, tvb, offset, (int)sizeof(guint8)*6, ENC_NA); + NvPublisherFormater(tvb, offset, szText, nMax); + proto_item_set_text(ti, "%s", szText); + offset+=((int)sizeof(guint8)*6); + + proto_tree_add_item(nv_header_tree, hf_nv_count, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + nv_count = tvb_get_letohs(tvb, offset); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(nv_header_tree, hf_nv_cycleindex, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset = NvParserHDR_Len; + + for ( i=0; i < nv_count; i++ ) + { + guint16 var_length = tvb_get_letohs(tvb, offset+4); + + ti = proto_tree_add_item(nv_tree, hf_nv_variable, tvb, offset, ETYPE_88A4_NV_DATA_HEADER_Len+var_length, ENC_NA); + NvVarHeaderFormater(tvb, offset, szText, nMax); + proto_item_set_text(ti, "%s", szText); + + nv_var_tree = proto_item_add_subtree(ti, ett_nv_var); + ti = proto_tree_add_item(nv_var_tree, hf_nv_varheader, tvb, offset, ETYPE_88A4_NV_DATA_HEADER_Len, ENC_NA); + + nv_varheader_tree = proto_item_add_subtree(ti, ett_nv_varheader); + proto_tree_add_item(nv_varheader_tree, hf_nv_id, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(nv_varheader_tree, hf_nv_hash, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(nv_varheader_tree, hf_nv_length, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(nv_varheader_tree, hf_nv_quality, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); + offset+=(int)sizeof(guint16); + + proto_tree_add_item(nv_var_tree, hf_nv_data, tvb, offset, var_length, ENC_NA); + offset+=var_length; + } + } + return tvb_captured_length(tvb); +} + +void proto_register_nv(void) +{ + static hf_register_info hf[] = + { +#if 0 + { &hf_nv_summary, { "Summary of the Nv Packet", "tc_nv.summary", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, +#endif + { &hf_nv_header, { "Header", "tc_nv.header", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_publisher, { "Publisher", "tc_nv.publisher", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_count, { "Count", "tc_nv.count", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_cycleindex, { "CycleIndex", "tc_nv.cycleindex", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_variable, { "Variable", "tc_nv.variable", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_varheader, { "VarHeader", "tc_nv.varheader", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_id, { "Id", "tc_nv.id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_hash, { "Hash", "tc_nv.hash", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_length, { "Length", "tc_nv.length", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_quality, { "Quality", "tc_nv.quality", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_nv_data, { "Data", "tc_nv.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + }; + + static gint *ett[] = + { + &ett_nv, + &ett_nv_header, + &ett_nv_var, + &ett_nv_varheader + }; + + proto_nv = proto_register_protocol("TwinCAT NV", "TC-NV","tc_nv"); + proto_register_field_array(proto_nv,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); + nv_handle = register_dissector("tc_nv", dissect_nv, proto_nv); +} + +void proto_reg_handoff_nv(void) +{ + dissector_add_uint("ecatf.type", 4, nv_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local Variables: + * c-basic-offset: 3 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=3 tabstop=8 expandtab: + * :indentSize=3:tabSize=8:noTabs=true: + */ diff --git a/plugins/epan/ethercat/packet-nv.h b/plugins/epan/ethercat/packet-nv.h new file mode 100644 index 00000000..14eaee03 --- /dev/null +++ b/plugins/epan/ethercat/packet-nv.h @@ -0,0 +1,34 @@ +/* packet-nv.h + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef _PACKET_NV_H_ +#define _PACKET_NV_H_ + +/* Ensure the same data layout for all platforms*/ +typedef struct _ETYPE_88A4_NV_DATA_HEADER +{ + guint16 Id; + guint16 Hash; + guint16 Length; + guint16 Quality; +} ETYPE_88A4_NV_DATA_HEADER; +#define ETYPE_88A4_NV_DATA_HEADER_Len (int)sizeof(ETYPE_88A4_NV_DATA_HEADER) + +typedef struct _NvParserHDR +{ + guint8 Publisher[6]; + guint16 CountNV; + guint16 CycleIndex; + guint16 Reserved; +} NvParserHDR; +#define NvParserHDR_Len (int)sizeof(NvParserHDR) + +#endif /* _PACKET_NV_H_*/ |