You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2021/08/07 17:46:06 UTC

[plc4x] branch develop updated: - Continuned specing out the PROFINET protocol - Minor adjustement to the code templates for "length" type arrays to allow "long" lengths - Added a "STR_LEN" function to the static helper to provide the string length

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

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 977d98a  - Continuned specing out the PROFINET protocol - Minor adjustement to the code templates for "length" type arrays to allow "long" lengths - Added a "STR_LEN" function to the static helper to provide the string length
977d98a is described below

commit 977d98acd083a095f639c09a520936fa47d97d41
Author: cdutz <ch...@c-ware.de>
AuthorDate: Sat Aug 7 19:45:57 2021 +0200

    - Continuned specing out the PROFINET protocol
    - Minor adjustement to the code templates for "length" type arrays to allow "long" lengths
    - Added a "STR_LEN" function to the static helper to provide the string length
---
 .../templates/java/data-io-template.java.ftlh      |   4 +-
 .../resources/templates/java/io-template.java.ftlh |   8 +-
 .../plc4x/java/spi/generation/StaticHelper.java    |   7 +
 .../resources/protocols/profinet/profinet.mspec    | 187 +++++++++++++++++++++
 4 files changed, 200 insertions(+), 6 deletions(-)

diff --git a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
index 9df06ef..c1d2609 100644
--- a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
@@ -121,8 +121,8 @@ public class ${type.name}IO {
             <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
                             <#if helper.isLengthArrayField(field)>
             // Length array
-            int _${field.name}Length = ${helper.toParseExpression(field, field.loopExpression, type.parserArguments)};
-            int ${field.name}EndPos = readBuffer.getPos() + _${field.name}Length;
+            long _${field.name}Length = ${helper.toParseExpression(field, field.loopExpression, type.parserArguments)};
+            long ${field.name}EndPos = readBuffer.getPos() + _${field.name}Length;
             List<PlcValue> value = new LinkedList<>();
             while(readBuffer.getPos() < ${field.name}EndPos) {
                 value.add(
diff --git a/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
index 57b9ef3..c2230ac 100644
--- a/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/io-template.java.ftlh
@@ -221,9 +221,9 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
             <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
                 <#if helper.isLengthArrayField(field)>
         // Length array
-        int _${arrayField.name}Length = ${helper.toParseExpression(arrayField, arrayField.loopExpression, type.parserArguments)};
+        long _${arrayField.name}Length = ${helper.toParseExpression(arrayField, arrayField.loopExpression, type.parserArguments)};
         List<${helper.getNonPrimitiveLanguageTypeNameForField(arrayField)}> _${arrayField.name}List = new LinkedList<>();
-        int ${arrayField.name}EndPos = readBuffer.getPos() + _${arrayField.name}Length;
+        long ${arrayField.name}EndPos = readBuffer.getPos() + _${arrayField.name}Length;
         while(readBuffer.getPos() < ${arrayField.name}EndPos) {
             _${arrayField.name}List.add(<#if helper.isSimpleTypeReference(arrayField.type)><#assign simpleTypeReference = arrayField.type>${helper.getReadBufferReadMethodCall("", simpleTypeReference, "", arrayField)}<#else>${arrayField.type.name}IO.staticParse(readBuffer<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(arrayField.type, parserArgument?index), true)}) (${helper.toParseExpression(arrayF [...]
             <#-- After parsing, update the current position, but only if it's needed -->
@@ -337,9 +337,9 @@ public class ${type.name}IO implements <#if outputFlavor != "passive">MessageIO<
             <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
             <#if helper.isLengthArrayField(field)>
         // Length array
-        int _${manualArrayField.name}Length = ${helper.toParseExpression(manualArrayField, manualArrayField.loopExpression, type.parserArguments)};
+        long _${manualArrayField.name}Length = ${helper.toParseExpression(manualArrayField, manualArrayField.loopExpression, type.parserArguments)};
         List<${helper.getNonPrimitiveLanguageTypeNameForField(manualArrayField)}> _${manualArrayField.name}List = new LinkedList<>();
-        int ${manualArrayField.name}EndPos = readBuffer.getPos() + _${manualArrayField.name}Length;
+        long ${manualArrayField.name}EndPos = readBuffer.getPos() + _${manualArrayField.name}Length;
         while(readBuffer.getPos() < ${manualArrayField.name}EndPos) {
             _${manualArrayField.name}List.add((${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(manualArrayField, manualArrayField.parseExpression, type.parserArguments)}));
             <#-- After parsing, update the current position, but only if it's needed -->
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
index be6d658..6de232a 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
@@ -86,6 +86,13 @@ public class StaticHelper {
         throw new PlcRuntimeException("Unable to count object of type " + obj.getClass().getName());
     }
 
+    public static int STR_LEN(String str) {
+        if (str == null) {
+            return 0;
+        }
+        return str.length();
+    }
+
     public static <T> T CAST(Object obj, Class<T> clazz) {
         try {
             return clazz.cast(obj);
diff --git a/protocols/profinet/src/main/resources/protocols/profinet/profinet.mspec b/protocols/profinet/src/main/resources/protocols/profinet/profinet.mspec
index 2427e42..71912ed 100644
--- a/protocols/profinet/src/main/resources/protocols/profinet/profinet.mspec
+++ b/protocols/profinet/src/main/resources/protocols/profinet/profinet.mspec
@@ -27,6 +27,25 @@
 [discriminatedType 'EthernetFamePayload'
     [discriminator uint 16 'packetType']
     [typeSwitch 'packetType'
+        ['0x0800' IPv4
+            [const    uint 4    'version'                         '0x4'                      ]
+            [const    uint 4    'headerLength'                    '0x5'                      ]
+            [const    uint 6    'differentiatedServicesCodepoint' '0x00'                     ]
+            [const    uint 2    'explicitCongestionNotification'  '0x0'                      ]
+            [implicit uint 16   'totalLength'                     '20 + packet.lengthInBytes']
+            [simple   uint 15   'identification'                                             ]
+            [const    uint 3    'flags'                           '0x00'                     ]
+            [const    uint 13   'fragmentOffset'                  '0x00'                     ]
+            // Time to live: 64
+            [const    uint 8    'timeToLive'                      '0x40'                     ]
+            // Protocol: UDP
+            [const    uint 8    'protocol'                        '0x11'                     ]
+            // TODO: Implement
+            //[checksum uint 16   'headerChecksum'                                             ]
+            [simple   IpAddress 'sourceAddress'                                              ]
+            [simple   IpAddress 'destinationAddress'                                         ]
+            [simple   UdpPacket 'packet'                                                     ]
+        ]
         ['0x8100' VirtualLanEthernetFramePayload
             [simple VirtualLanPriority  'priority']
             [simple bit                 'ineligible']
@@ -39,6 +58,93 @@
     ]
 ]
 
+[type 'UdpPacket'
+    [simple   uint 16      'sourcePort'                                        ]
+    [simple   uint 16      'destinationPort'                                   ]
+    [implicit uint 16      'packetLength'    'lengthInBytes'                   ]
+    // TODO: Implement
+    //[checksum uint 16      'headerChecksum'                                    ]
+    [array    byte         'payload'         count           'packetLength - 8']
+]
+
+[discriminatedType 'DceRpcPacket'
+    [const         uint 8           'version'      '0x04'                 ]
+    [discriminator DceRpcPacketType 'packetType'                          ]
+    [typeSwitch 'packetType'
+        ['REQUEST'  DceRpcPacketRequest
+            // Flags: Idempotent
+            [const    uint 8           'flags1'            '0x20'         ]
+        ]
+
+        ['RESPONSE' DceRpcPacketResponse
+            [const    uint 8           'flags1'            '0x0A'         ]
+        ]
+    ]
+    [const    uint 8           'flags2'            '0x00'                 ]
+    // Byte Order: Little-Endian
+    [const    uint 4           'byteOder'          '0x1'                  ]
+    // Character Type: Ascii
+    [const    uint 4           'characterType'     '0x0'                  ]
+    // Floating Point Type: IEEE
+    [const    uint 8           'floatingPointType' '0x00'                 ]
+    [const    uint 8           'serialHigh'        '0x00'                 ]
+    // Some constants probably related to selecting the DCE/RPC objects
+    [const    uint 32          'uuid1'             '0xDEA00000'           ]
+    [const    uint 16          'uuid2'             '0x6C97'               ]
+    [const    uint 16          'uuid3'             '0x11D1'               ]
+    [const    uint 16          'uuid4'             '0x7182'               ]
+    [simple   uint 48          'uuid'                                     ]
+    [const    uint 32          'interface1'        '0xDEA00001'           ]
+    [const    uint 16          'interface2'        '0x6C97'               ]
+    [const    uint 16          'interface3'        '0x11D1'               ]
+    [const    uint 16          'interface4'        '0x7182'               ]
+    [const    uint 32          'interface5'        '0x7DDF4224 '          ]
+    [const    uint 16          'interface6'        '0xA000'               ]
+    [simple   uint 32          'activity'                                 ]
+    [const    uint 16          'activity2'         '0x0000'               ]
+    [const    uint 16          'activity3'         '0x1010'               ]
+    [const    uint 16          'activity4'         '0x8098'               ]
+    [const    uint 32          'activity5'         '0xA3A93D3C'           ]
+    [const    uint 16          'activity6'         '0x6D60'               ]
+    [simple   uint 32          'serverBootTime'                           ]
+    [const    uint 32          'interfaceVar'      '0x00000001'           ]
+    [simple   uint 32          'sequenceNumber'                           ]
+    [simple   Operation        'operation'                                ]
+    [const    uint 16          'interfaceHint'     '0xFFFF'               ]
+    [const    uint 16          'activityHint'      '0xFFFF'               ]
+    [implicit uint 16          'fragmentLength'    'payload.lengthInBytes']
+    [const    uint 16          'fragmentNum'       '0x0000'               ]
+    [const    uint 8           'authProto'         '0x00'                 ]
+    [const    uint 8           'serialLow'         '0x00'                 ]
+    [simple   ProfinetIoPacket 'payload'                                  ]
+]
+
+[type 'Uuid'
+    [array byte 'data' count '16']
+]
+
+[type 'IpAddress'
+    [array uint 8 'data' count '4']
+]
+
+[enum uint 8 'DceRpcPacketType'
+    ['0x00' REQUEST ]
+    ['0x02' RESPONSE]
+]
+
+[enum uint 16 'Operation'
+    ['0x0000' CONNECT]
+    ['0x0003' WRITE  ]
+]
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//
+//   PROFINET DCP
+//
+// Discovery and basic configuration
+//
+/////////////////////////////////////////////////////////////////////////////////////////
+
 // Page 90
 [discriminatedType 'DCP_PDU'
     [discriminator ProfinetFrameId  'frameId']
@@ -352,4 +458,85 @@
 
 [type 'MacAddress'
     [array uint 8 'address' count '6']
+]
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//
+//   PROFINET IO
+//
+// CM: Context Manager
+//
+/////////////////////////////////////////////////////////////////////////////////////////
+
+// Little Endian
+[type 'ProfinetIoPacket'
+    [simple uint 32        'argsMaximum']
+    [simple uint 32        'argsLength']
+    [simple uint 32        'arrayMaximumCount']
+    [simple uint 32        'arrayOffset']
+    [simple uint 32        'arrayActualCount']
+    [array ProfinetIoBlock 'blocks' length 'argsLength']
+]
+
+// Big Endian
+[type 'ProfinetIoBlock'
+    [discriminator PNBlockType 'blockType'                           ]
+    [implicit      uint 16     'blockLength'      'lengthInBytes - 4']
+    [simple        uint 8      'blockVersionHigh'                    ]
+    [simple        uint 8      'blockVersionLow'                     ]
+    [typeSwitch 'blockType'
+        ['AR_BLOCK_REQ' ProfinetIoBlockArBlockReq
+            [simple   PNArType          'arType'                                                 ]
+            [simple   Uuid              'arUuid'                                                 ]
+            [simple   uint 16           'sessionKey'                                             ]
+            [simple   MacAddress        'cmInitiatorMacAddr'                                     ]
+            [simple   Uuid              'cmInitiatorObjectUuid'                                  ]
+            // Begin ARProperties
+            [simple   bit               'pullModuleAlarmAllowed'                                 ]
+            [simple   bit               'nonLegacyStartupMode'                                   ]
+            [simple   bit               'combinedObjectContainerUsed'                            ]
+            [reserved uint 17           '0x00000'                                                ]
+            [simple   bit               'acknowledgeCompanionAr'                                 ]
+            [simple   PNCompanionArType 'companionArType'                                        ]
+            [simple   bit               'deviceAccess'                                           ]
+            [reserved uint 3            '0x0'                                                    ]
+            [simple   bit               'cmInitiator'                                            ]
+            [simple   bit               'supervisorTakeoverAllowed'                              ]
+            [simple   PNState           'state'                                                  ]
+            // End ARProperties
+            [simple   uint 16           'cmInitiatorActivityTimeoutFactor'                       ]
+            [simple   uint 16           'cmInitiatorUdpRtPort'                                   ]
+            [implicit uint 16           'stationNameLength'     'STR_LEN(cmInitiatorStationName)']
+            [simple   string            'stationNameLength * 8' 'cmInitiatorStationName'         ]
+        ]
+        ['IO_CR_BLOCK_REQ' ProfinetIoBlockIoCrBlockReq
+            [simple PNIoCrType          'ioCrType'     ]
+            [simple uint 16             'ioCrReference']
+            [simple uint 16             'lt'           ]
+            // Begin IOCRProperties
+            // TODO: To Be Continued ...
+            // End IOCRProperties
+        ]
+    ]
+]
+
+[enum uint 16 'PNBlockType'
+    ['0x0101' AR_BLOCK_REQ   ]
+    ['0x0102' IO_CR_BLOCK_REQ]
+]
+
+[enum uint 16 'PNArType'
+    ['0x0001' IO_CONTROLLER]
+]
+
+[enum uint 2 'PNCompanionArType'
+    ['0x0' SINGLE_AR]
+]
+
+[enum uint 3 'PNState'
+    ['0x1' ACTIVE]
+]
+
+[enum uint 16 'PNIoCrType'
+    ['0x0001' INPUT_CR]
 ]
\ No newline at end of file