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