You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2020/10/21 13:42:20 UTC

[plc4x] 02/08: Cherry Picked commit to add Simotion Syntax to S7 Driver. Migrated everything to "native" decoding without mspec.

This is an automated email from the ASF dual-hosted git repository.

jfeinauer pushed a commit to branch rel/0.6
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 09585ba5ebe5b5f9f953ac8ef2e2cdffd209bd09
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Tue Jul 28 20:53:13 2020 +0200

    Cherry Picked commit to add Simotion Syntax to S7 Driver.
    Migrated everything to "native" decoding without mspec.
---
 plc4j/drivers/s7/pom.xml                           |   1 -
 .../org/apache/plc4x/java/s7/model/S7Field.java    |  29 ++-
 .../s7/src/main/resources/protocols/s7/s7.mspec    | 233 ++++++++++++++++-----
 3 files changed, 212 insertions(+), 51 deletions(-)

diff --git a/plc4j/drivers/s7/pom.xml b/plc4j/drivers/s7/pom.xml
index 7a87d0c..02f12ca 100644
--- a/plc4j/drivers/s7/pom.xml
+++ b/plc4j/drivers/s7/pom.xml
@@ -116,7 +116,6 @@
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
       <version>1.12</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
index 8f7f63c..d539bdf 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/model/S7Field.java
@@ -47,6 +47,9 @@ public class S7Field implements PlcField {
     private static final Pattern DATA_BLOCK_SHORT_PATTERN =
         Pattern.compile("^%DB(?<blockNumber>\\d{1,5}):(?<byteOffset>\\d{1,7})(.(?<bitOffset>[0-7]))?:(?<dataType>[a-zA-Z_]+)(\\[(?<numElements>\\d+)])?");
 
+    private static final Pattern SIMOTION_ADDRESS_PATTERN =
+        Pattern.compile("[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}");
+
     private static final String DATA_TYPE = "dataType";
     private static final String TRANSFER_SIZE_CODE = "transferSizeCode";
     private static final String BLOCK_NUMBER = "blockNumber";
@@ -98,7 +101,8 @@ public class S7Field implements PlcField {
     public static boolean matches(String fieldString) {
         return DATA_BLOCK_ADDRESS_PATTERN.matcher(fieldString).matches() ||
             ADDRESS_PATTERN.matcher(fieldString).matches() ||
-            DATA_BLOCK_SHORT_PATTERN.matcher(fieldString).matches();
+            DATA_BLOCK_SHORT_PATTERN.matcher(fieldString).matches() ||
+            SIMOTION_ADDRESS_PATTERN.matcher(fieldString).matches();
     }
 
     /**
@@ -215,6 +219,29 @@ public class S7Field implements PlcField {
             }
             numElements = calcNumberOfElementsForIndividualTypes(numElements, dataType);
             return new S7Field(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
+        } else if (SIMOTION_ADDRESS_PATTERN.matcher(fieldString).matches()) {
+            matcher = SIMOTION_ADDRESS_PATTERN.matcher(fieldString);
+
+            boolean matches = matcher.matches();
+            assert matches;
+
+            try {
+                byte[] addressData = Hex.decodeHex(fieldString.replaceAll("[-]", ""));
+                ReadBuffer rb = new ReadBuffer(addressData);
+                // Read out values according to definition in mspec
+                final TransportSize transportSize = TransportSize.valueOf(rb.readByte(8));
+                final short numberOfElements = rb.readShort(16);
+                final short dbNumber = rb.readShort(16);
+                final MemoryArea memoryArea = MemoryArea.valueOf(rb.readByte(8));
+                assert 0x00 == rb.readByte(5);
+                final short byteAddress = rb.readShort(16);
+                final byte bitAddress = rb.readByte(3);
+
+                return new S7Field(transportSize, memoryArea, dbNumber, byteAddress, bitAddress,
+                    numberOfElements);
+            } catch (ParseException | DecoderException e) {
+                throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
+            }
         }
         throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
     }
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 31b588c..e428620 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -99,20 +99,24 @@
     [discriminator uint 8  'messageType']
     [reserved      uint 16 '0x0000']
     [simple        uint 16 'tpduReference']
-    [implicit      uint 16 'parameterLength' 'parameter.lengthInBytes']
-    [implicit      uint 16 'payloadLength'   'payload.lengthInBytes']
+    [implicit      uint 16 'parameterLength' 'parameter != null ? parameter.lengthInBytes : 0']
+    [implicit      uint 16 'payloadLength'   'payload != null ? payload.lengthInBytes : 0']
     [typeSwitch 'messageType'
         ['0x01' S7MessageRequest
         ]
-        ['0x03' S7MessageResponse
+        ['0x02' S7MessageResponse
+            [simple uint 8 'errorClass']
+            [simple uint 8 'errorCode']
+        ]
+        ['0x03' S7MessageResponseData
             [simple uint 8 'errorClass']
             [simple uint 8 'errorCode']
         ]
         ['0x07' S7MessageUserData
         ]
     ]
-    [simple S7Parameter 'parameter' ['messageType']]
-    [simple S7Payload   'payload'   ['messageType', 'parameter']]
+    [optional S7Parameter 'parameter' 'parameterLength > 0' ['messageType']]
+    [optional S7Payload   'payload'   'payloadLength > 0'   ['messageType', 'parameter']]
 ]
 
 ////////////////////////////////////////////////////////////////
@@ -208,14 +212,12 @@
 // Payloads
 
 [discriminatedType 'S7Payload' [uint 8 'messageType', S7Parameter 'parameter']
-    [typeSwitch 'parameter.discriminatorValues[0]', 'messageType'
-        ['0xF0' S7PayloadSetupCommunication]
-        ['0x04','0x01' S7PayloadReadVarRequest]
+    [typeSwitch 'parameter.parameterType', 'messageType'
         ['0x04','0x03' S7PayloadReadVarResponse
-            [array S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems']
+            [array S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems' ['lastItem']]
         ]
         ['0x05','0x01' S7PayloadWriteVarRequest
-            [array S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)']
+            [array S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)' ['lastItem']]
         ]
         ['0x05','0x03' S7PayloadWriteVarResponse
             [array S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
@@ -227,24 +229,24 @@
 ]
 
 // This is actually not quite correct as depending pon the transportSize the length is either defined in bits or bytes.
-[type 'S7VarPayloadDataItem'
-    [simple  uint 8             'returnCode']
-    [enum    DataTransportSize  'transportSize']
-    [simple  uint 16            'dataLength']
-    [array   uint 8             'data' count 'dataLength / 8']
-    [padding uint 8             'pad' '0x00' '(dataLength / 8) % 2 == 1']
+[type 'S7VarPayloadDataItem' [bit 'lastItem']
+    [enum     DataTransportErrorCode 'returnCode']
+    [enum     DataTransportSize      'transportSize']
+    [implicit uint 16                'dataLength' 'COUNT(data) * ((transportSize == DataTransportSize.BIT) ? 1 : (transportSize.sizeInBits ? 8 : 1))']
+    [array    int  8                 'data'       count 'transportSize.sizeInBits ? CEIL(dataLength / 8.0) : dataLength']
+    [padding  uint 8                 'pad'        '0x00' '!lastItem && ((COUNT(data) % 2) == 1)']
 ]
 
 [type 'S7VarPayloadStatusItem'
-    [simple uint 8 'returnCode']
+    [enum DataTransportErrorCode 'returnCode']
 ]
 
 [discriminatedType 'S7PayloadUserDataItem' [uint 4 'cpuFunctionType']
-    [simple   uint 8            'returnCode']
-    [enum     DataTransportSize 'transportSize']
-    [implicit uint 16           'dataLength' 'lengthInBytes - 4']
-    [simple   SzlId             'szlId']
-    [simple   uint 16           'szlIndex']
+    [enum     DataTransportErrorCode 'returnCode']
+    [enum     DataTransportSize      'transportSize']
+    [implicit uint 16                'dataLength' 'lengthInBytes - 4']
+    [simple   SzlId                  'szlId']
+    [simple   uint 16                'szlIndex']
     [typeSwitch 'cpuFunctionType'
         ['0x04' S7PayloadUserDataItemCpuFunctionReadSzlRequest
         ]
@@ -256,8 +258,115 @@
     ]
 ]
 
+[dataIo 'DataItem' [uint 8 'dataProtocolId']
+    [typeSwitch 'dataProtocolId'
+        // -----------------------------------------
+        // Bit
+        // -----------------------------------------
+        ['01' Boolean
+            [reserved uint 7 '0x00']
+            [simple   bit    'value']
+        ]
+
+        // -----------------------------------------
+        // Bit-strings
+        // -----------------------------------------
+        // 1 byte
+        ['11' List
+            [array bit 'value' count '8']
+        ]
+        // 2 byte (16 bit)
+        ['12' List
+            [array bit 'value' count '16']
+        ]
+        // 4 byte (32 bit)
+        ['13' List
+            [array bit 'value' count '32']
+        ]
+        // 8 byte (64 bit)
+        ['14' List
+            [array bit 'value' count '64']
+        ]
+
+        // -----------------------------------------
+        // Integers
+        // -----------------------------------------
+        // 8 bit:
+        ['21' Integer
+            [simple int 8 'value']
+        ]
+        ['22' Integer
+            [simple uint 8 'value']
+        ]
+        // 16 bit:
+        ['23' Integer
+            [simple int 16 'value']
+        ]
+        ['24' Integer
+            [simple uint 16 'value']
+        ]
+        // 32 bit:
+        ['25' Integer
+            [simple int 32 'value']
+        ]
+        ['26' Long
+            [simple uint 32 'value']
+        ]
+        // 64 bit:
+        ['27' Long
+            [simple int 64 'value']
+        ]
+        ['28' BigInteger
+            [simple uint 64 'value']
+        ]
+
+        // -----------------------------------------
+        // Floating point values
+        // -----------------------------------------
+        ['31' Float
+            [simple float 8.23  'value']
+        ]
+        ['32' Double
+            [simple float 11.52 'value']
+        ]
+
+        // -----------------------------------------
+        // Characters & Strings
+        // -----------------------------------------
+        ['41' String
+        ]
+        ['42' String
+        ]
+        ['43' String
+            [manual string 'UTF-8' 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String", io, _type.encoding)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String", io, _value, _type.encoding)' '_value.length + 2']
+        ]
+        ['44' String
+            [manual string 'UTF-16' 'value''STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String", io, _type.encoding)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String", io, _value, _type.encoding)' '(_value.length * 2) + 2']
+        ]
 
-[enum int 8 'COTPTpduSize' [uint 8 'sizeInBytes']
+        // -----------------------------------------
+        // TIA Date-Formats
+        // -----------------------------------------
+        ['51' Time
+            [manual time 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseTiaTime", io)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeTiaTime", io, _value)' '4']
+        ]
+        // TODO: Check if this is really 8 bytes
+        ['52' Time
+            [manual time 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseTiaLTime", io)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeTiaLTime", io, _value)' '8']
+        ]
+        ['53' Date
+            [manual date 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseTiaDate", io)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeTiaDate", io, _value)' '2']
+        ]
+        ['54' Time
+            [manual time 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseTiaTimeOfDay", io)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeTiaTimeOfDay", io, _value)' '4']
+        ]
+        ['55' DateTime
+            [manual dateTime 'value' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseTiaDateTime", io)' 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeTiaDateTime", io, _value)' '8']
+        ]
+    ]
+]
+
+[enum int 8 'COTPTpduSize' [uint 16 'sizeInBytes']
     ['0x07' SIZE_128 ['128']]
     ['0x08' SIZE_256 ['256']]
     ['0x09' SIZE_512 ['512']]
@@ -285,34 +394,51 @@
     ['0x09' OCTET_STRING    ['false']]
 ]
 
-[enum int 8 'TransportSize'  [uint 8 'sizeCode', uint 8 'sizeInBytes', TransportSize 'baseType', DataTransportSize 'dataTransportSize']
-    ['0x01' BOOL             ['X'              , '1'                 , 'null'                  , 'DataTransportSize.BIT']]
-    ['0x02' BYTE             ['B'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x04' WORD             ['W'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x06' DWORD            ['D'              , '4'                 , 'WORD'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x00' LWORD            ['X'              , '8'                 , 'null'                  , 'null']]
-    ['0x05' INT              ['W'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x05' UINT             ['W'              , '2'                 , 'INT'                   , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x02' SINT             ['B'              , '1'                 , 'INT'                   , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x02' USINT            ['B'              , '1'                 , 'INT'                   , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x07' DINT             ['D'              , '4'                 , 'INT'                   , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x07' UDINT            ['D'              , '4'                 , 'INT'                   , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x00' LINT             ['X'              , '8'                 , 'INT'                   , 'null']]
-    ['0x00' ULINT            ['X'              , '16'                , 'INT'                   , 'null']]
-    ['0x08' REAL             ['D'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x00' LREAL            ['X'              , '8'                 , 'REAL'                  , 'null']]
-    ['0x0B' TIME             ['X'              , '4'                 , 'null'                  , 'null']]
-    ['0x00' LTIME            ['X'              , '8'                 , 'TIME'                  , 'null']]
-    ['0x02' DATE             ['X'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x02' TIME_OF_DAY      ['X'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x02' DATE_AND_TIME    ['X'              , '8'                 , 'null'                  , 'null']]
-    ['0x03' CHAR             ['B'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x13' WCHAR            ['X'              , '2'                 , 'null'                  , 'null']]
-    ['0x03' STRING           ['X'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD']]
-    ['0x00' WSTRING          ['X'              , '1'                 , 'null'                  , 'null']]
+[enum int 8 'DeviceGroup'
+    ['0x01' PG_OR_PC]
+    ['0x02' OS      ]
+    ['0x03' OTHERS  ]
+]
+
+[enum int 8 'TransportSize'  [uint 8 'sizeCode', uint 8 'sizeInBytes', TransportSize 'baseType', DataTransportSize 'dataTransportSize', uint 8 'dataProtocolId', bit 'supported_S7_300', bit 'supported_S7_400', bit 'supported_S7_1200', bit 'supported_S7_1500', bit 'supported_LOGO']
+    // Bit Strings
+    ['0x01' BOOL             ['X'              , '1'                 , 'null'                  , 'DataTransportSize.BIT'              , '01'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x02' BYTE             ['B'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '11'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x04' WORD             ['W'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '12'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x06' DWORD            ['D'              , '4'                 , 'TransportSize.WORD'    , 'DataTransportSize.BYTE_WORD_DWORD'  , '13'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x00' LWORD            ['X'              , '8'                 , 'null'                  , 'null'                               , '14'                   , 'false'               , 'false'               , 'false'                , 'true'                 , 'false'             ]]
+
+    // Integer values
+    // INT and UINT moved out of order as the enum constant INT needs to be generated before it's used in java
+    ['0x05' INT              ['W'              , '2'                 , 'null'                  , 'DataTransportSize.INTEGER'          , '23'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x05' UINT             ['W'              , '2'                 , 'TransportSize.INT'     , 'DataTransportSize.INTEGER'          , '24'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+    // ...
+    ['0x02' SINT             ['B'              , '1'                 , 'TransportSize.INT'     , 'DataTransportSize.BYTE_WORD_DWORD'  , '21'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x02' USINT            ['B'              , '1'                 , 'TransportSize.INT'     , 'DataTransportSize.BYTE_WORD_DWORD'  , '22'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x07' DINT             ['D'              , '4'                 , 'TransportSize.INT'     , 'DataTransportSize.INTEGER'          , '25'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x07' UDINT            ['D'              , '4'                 , 'TransportSize.INT'     , 'DataTransportSize.INTEGER'          , '26'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x00' LINT             ['X'              , '8'                 , 'TransportSize.INT'     , 'null'                               , '27'                   , 'false'               , 'false'               , 'false'                , 'true'                 , 'false'             ]]
+    ['0x00' ULINT            ['X'              , '16'                , 'TransportSize.INT'     , 'null'                               , '28'                   , 'false'               , 'false'               , 'false'                , 'true'                 , 'false'             ]]
+
+    // Floating point values
+    ['0x08' REAL             ['D'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '31'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x30' LREAL            ['X'              , '8'                 , 'TransportSize.REAL'    , 'null'                               , '32'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'false'             ]]
+
+    // Characters and Strings
+    ['0x03' CHAR             ['B'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '41'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x13' WCHAR            ['X'              , '2'                 , 'null'                  , 'null'                               , '42'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x03' STRING           ['X'              , '1'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '43'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x00' WSTRING          ['X'              , '1'                 , 'null'                  , 'null'                               , '44'                   , 'false'               , 'false'               , 'true'                 , 'true'                 , 'true'              ]]
+
+    // Dates and time values
+    ['0x0B' TIME             ['X'              , '4'                 , 'null'                  , 'null'                               , '51'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x00' LTIME            ['X'              , '8'                 , 'TransportSize.TIME'    , 'null'                               , '52'                   , 'false'               , 'false'               , 'false'                , 'true'                 , 'false'             ]]
+    ['0x02' DATE             ['X'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '53'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x02' TIME_OF_DAY      ['X'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , '54'                   , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    ['0x02' DATE_AND_TIME    ['X'              , '8'                 , 'null'                  , 'null'                               , '55'                   , 'true'                , 'true'                , 'false'                , 'true'                 , 'false'             ]]
 ]
 
-[enum int 8 'MemoryArea'             [string 'shortName']
+[enum int 8 'MemoryArea'             [string 24 'utf8' 'shortName']
     ['0x1C' COUNTERS                 ['C']]
     ['0x1D' TIMERS                   ['T']]
     ['0x80' DIRECT_PERIPHERAL_ACCESS ['D']]
@@ -334,6 +460,15 @@
     ['0x09' OCTET_STRING        ['false']]
 ]
 
+[enum int 8 'DataTransportErrorCode'
+    ['0x00' RESERVED               ]
+    ['0xFF' OK                     ]
+    ['0x03' ACCESS_DENIED          ]
+    ['0x05' INVALID_ADDRESS        ]
+    ['0x06' DATA_TYPE_NOT_SUPPORTED]
+    ['0x0A' NOT_FOUND              ]
+]
+
 [enum int 4 'SzlModuleTypeClass'
     ['0x0' CPU]
     ['0x4' IM]