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 2019/07/17 13:43:45 UTC

[plc4x] 01/01: [DF1] Added Initial Setup.

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

jfeinauer pushed a commit to branch implement-df1-protocol
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 5d17d47397245f01a3db0df4a6794b761961d76e
Author: julian <j....@pragmaticminds.de>
AuthorDate: Wed Jul 17 15:43:38 2019 +0200

    [DF1] Added Initial Setup.
---
 protocols/df1/pom.xml                              |  43 ++++
 .../org/apache/plc4x/protocol/df1/Df1Protocol.java |  46 +++++
 ...e.plc4x.plugins.codegenerator.protocol.Protocol |  19 ++
 .../main/resources/protocols/df1/protocol.mspec    | 221 +++++++++++++++++++++
 protocols/pom.xml                                  |   1 +
 sandbox/pom.xml                                    |   1 +
 sandbox/test-java-df1-driver/pom.xml               |  90 +++++++++
 .../plc4x/protocol/df1/BenchmarkGeneratedDf1.java  |  71 +++++++
 8 files changed, 492 insertions(+)

diff --git a/protocols/df1/pom.xml b/protocols/df1/pom.xml
new file mode 100644
index 0000000..3871b47
--- /dev/null
+++ b/protocols/df1/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4x-protocols</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4x-protocols-df1</artifactId>
+
+  <name>Protocols: Df1</name>
+  <description>Base protocol specifications for the AB Df1 protocol</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-protocol-base-mspec</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/protocols/df1/src/main/java/org/apache/plc4x/protocol/df1/Df1Protocol.java b/protocols/df1/src/main/java/org/apache/plc4x/protocol/df1/Df1Protocol.java
new file mode 100644
index 0000000..aa34abe
--- /dev/null
+++ b/protocols/df1/src/main/java/org/apache/plc4x/protocol/df1/Df1Protocol.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.plc4x.protocol.df1;
+
+import org.apache.plc4x.plugins.codegenerator.language.mspec.parser.MessageFormatParser;
+import org.apache.plc4x.plugins.codegenerator.protocol.Protocol;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
+
+import java.io.InputStream;
+import java.util.Map;
+
+public class Df1Protocol implements Protocol {
+
+    @Override
+    public String getName() {
+        return "df1";
+    }
+
+    @Override
+    public Map<String, ComplexTypeDefinition> getTypeDefinitions() throws GenerationException {
+        InputStream schemaInputStream = Df1Protocol.class.getResourceAsStream("/protocols/df1/protocol.mspec");
+        if(schemaInputStream == null) {
+            throw new GenerationException("Error loading message-format schema for protocol '" + getName() + "'");
+        }
+        return new MessageFormatParser().parse(schemaInputStream);
+    }
+
+}
diff --git a/protocols/df1/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol b/protocols/df1/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
new file mode 100644
index 0000000..60e98ea
--- /dev/null
+++ b/protocols/df1/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.plc4x.protocol.df1.Df1Protocol
\ No newline at end of file
diff --git a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
new file mode 100644
index 0000000..55b3679
--- /dev/null
+++ b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
@@ -0,0 +1,221 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+////////////////////////////////////////////////////////////////
+// IsoOnTcp/TPKT
+////////////////////////////////////////////////////////////////
+
+[type 'TPKTPacket'
+    [const    uint 8     'protocolId' '0x03']
+    [reserved uint 8     '0x00']
+    [implicit uint 16    'len'        'payload.lengthInBytes + 4']
+    [field    COTPPacket 'payload']
+]
+
+////////////////////////////////////////////////////////////////
+// COTP
+////////////////////////////////////////////////////////////////
+
+[discriminatedType 'COTPPacket'
+    [implicit      uint 8 'headerLength' 'lengthInBytes - (payload.lengthInBytes + 1)']
+    [discriminator uint 8 'tpduCode']
+    [typeSwitch 'tpduCode'
+        ['0xF0' COTPPacketData
+            [field bit    'eot']
+            [field uint 7 'tpduRef']
+        ]
+        ['0xE0' COTPPacketConnectionRequest
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0xD0' COTPPacketConnectionResponse
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0x80' COTPPacketDisconnectRequest
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0xC0' COTPPacketDisconnectResponse
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+        ]
+        ['0x70' COTPPacketTpduError
+            [field uint 16 'destinationReference']
+            [field uint 8  'rejectCause']
+        ]
+    ]
+    [arrayField COTPParameter 'parameters' length '(headerLength + 1) - curPos' ['(headerLength + 1) - curPos']]
+    [field      S7Message     'payload']
+]
+
+[discriminatedType 'COTPParameter' [uint 8 'rest']
+    [discriminator uint 8 'parameterType']
+    [typeSwitch 'parameterType'
+        ['0xC0' COTPParameterTpduSize
+            [field uint 8 'tpduSize']
+        ]
+        ['0xC1' COTPParameterCallingTsap
+            [field uint 16 'tsapId']
+        ]
+        ['0xC2' COTPParameterCalledTsap
+            [field uint 16 'tsapId']
+        ]
+        ['0xC3' COTPParameterChecksum
+            [field uint 8 'checksum']
+        ]
+        ['0xE0' COTPParameterDisconnectAdditionalInformation
+            [arrayField uint 8 'data' count 'rest']
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// S7
+////////////////////////////////////////////////////////////////
+
+[discriminatedType 'S7Message'
+    [const         uint 8  'protocolId'      '0x32']
+    [discriminator uint 8  'messageType']
+    [reserved      uint 16 '0x0000']
+    [field         uint 16 'tpduReference']
+    [implicit      uint 16 'parameterLength' 'parameter.lengthInBytes']
+    [implicit      uint 16 'payloadLength'   'payload.lengthInBytes']
+    [typeSwitch 'messageType'
+        ['0x01' S7MessageRequest
+        ]
+        ['0x03' S7MessageResponse
+            [field uint 8 'errorClass']
+            [field uint 8 'errorCode']
+        ]
+        ['0x07' S7MessageUserData
+        ]
+    ]
+    [field S7Parameter 'parameter' ['messageType']]
+    [field S7Payload   'payload'   ['messageType', 'parameter']]
+]
+
+////////////////////////////////////////////////////////////////
+// Parameters
+
+[discriminatedType 'S7Parameter' [uint 8 'messageType']
+    [discriminator uint 8 'parameterType']
+    [typeSwitch 'parameterType','messageType'
+        ['0xF0' S7ParameterSetupCommunication
+            [reserved uint 8  '0x00']
+            [field    uint 16 'maxAmqCaller']
+            [field    uint 16 'maxAmqCallee']
+            [field    uint 16 'pduLength']
+        ]
+        ['0x04','0x01' S7ParameterReadVarRequest
+            [implicit   uint 8                    'numItems' 'COUNT(items)']
+            [arrayField S7VarRequestParameterItem 'items'    count 'numItems']
+        ]
+        ['0x04','0x03' S7ParameterReadVarResponse
+            [field uint 8 'numItems']
+        ]
+        ['0x05','0x01' S7ParameterWriteVarRequest
+            [implicit   uint 8                    'numItems' 'COUNT(items)']
+            [arrayField S7VarRequestParameterItem 'items'    count 'numItems']
+        ]
+        ['0x05','0x03' S7ParameterWriteVarResponse
+            [field uint 8 'numItems']
+        ]
+        ['0x00','0x07' S7ParameterUserData
+            [implicit   uint 8       'numItems' 'COUNT(items)']
+            [arrayField UserDataItem 'items' count 'numItems']
+        ]
+    ]
+]
+
+[discriminatedType 'S7VarRequestParameterItem'
+    [discriminator uint 8 'parameterItemType']
+    [typeSwitch 'parameterItemType'
+        ['0x12' S7VarRequestParameterItemAddress
+            [implicit uint 8    'addressLength' 'address.lengthInBytes']
+            [field    S7Address 'address']
+        ]
+    ]
+]
+
+[discriminatedType 'S7Address'
+    [discriminator uint 8 'addressType']
+    [typeSwitch 'addressType'
+        ['0x10' S7AddressAny
+            [field    uint 8  'transportSize']
+            [field    uint 16 'numberOfElements']
+            [field    uint 16 'dbNumber']
+            [field    uint 8  'area']
+            [reserved uint 5  '0x00']
+            [field    uint 16 'byteAddress']
+            [field    uint 3  'bitAddress']
+        ]
+    ]
+]
+
+// TODO: CPUFunctions still need some love ...
+[discriminatedType 'UserDataItem'
+    [discriminator uint 8 'itemType']
+    [typeSwitch 'itemType'
+        ['0x12' UserDataItemCPUFunctions
+            [implicit      uint 8  'parameterLength' 'lengthInBytes']
+            [field         uint 16 'cpuFunctionType']
+            [field         uint 8  'subFunctionGroup']
+            [field         uint 8  'sequenceNumber']
+            [optionalField uint 8  'dataUnitReferenceNumber' 'parameterLength == 8']
+            [optionalField uint 8  'lastDataUnit' 'parameterLength == 8']
+            [optionalField uint 8  'errorCode' 'parameterLength == 8']
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// Payloads
+
+[discriminatedType 'S7Payload' [uint 8 'messageType', S7Parameter 'parameter']
+    [typeSwitch 'parameter.discriminatorValues[0]', 'messageType'
+        ['0xF0' S7PayloadSetupCommunication]
+        ['0x04','0x01' S7PayloadReadVarRequest]
+        ['0x04','0x03' S7PayloadReadVarResponse
+            [arrayField S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems']
+        ]
+        ['0x05','0x01' S7PayloadWriteVarRequest
+            [arrayField S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)']
+        ]
+        ['0x05','0x03' S7PayloadWriteVarResponse
+            [arrayField S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
+        ]
+        ['0x00','0x07' S7PayloadUserData
+        ]
+    ]
+]
+
+[type 'S7VarPayloadDataItem'
+    [field      uint 8  'returnCode']
+    [field      uint 8  'transportSize']
+    [field      uint 16 'dataLength']
+    [arrayField uint 8  'data' count 'dataLength']
+]
+
+[type 'S7VarPayloadStatusItem'
+    [field uint 8 'returnCode']
+]
\ No newline at end of file
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 8bf4c9c..8f59a67 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -192,6 +192,7 @@
   <modules>
     <module>knxnetip</module>
     <module>s7</module>
+    <module>df1</module>
   </modules>
 
   <profiles>
diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 12df32c..1a1f452 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -38,6 +38,7 @@
     <module>code-gen</module>
     <module>test-java-knxnetip-driver</module>
     <module>test-java-s7-driver</module>
+    <module>test-java-df1-driver</module>
   </modules>
 
 </project>
\ No newline at end of file
diff --git a/sandbox/test-java-df1-driver/pom.xml b/sandbox/test-java-df1-driver/pom.xml
new file mode 100644
index 0000000..ccfb11b
--- /dev/null
+++ b/sandbox/test-java-df1-driver/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x.sandbox</groupId>
+    <artifactId>plc4x-sandbox</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-java-df1-driver</artifactId>
+
+  <name>Sandbox: Test Generated Df1 Driver</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>test</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>df1</protocolName>
+              <languageName>java</languageName>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-driver-base-java</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-java</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-df1</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
new file mode 100644
index 0000000..0718330
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.plc4x.protocol.df1;import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.df1.TPKTPacket;
+import org.apache.plc4x.java.df1.io.TPKTPacketIO;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
+
+import java.util.Arrays;
+
+public class BenchmarkGeneratedDf1 {
+
+    public static void main(String[] args) throws Exception {
+        byte[] rData = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
+        long start = System.currentTimeMillis();
+        int numRunsParse = 2000000;
+        TPKTPacketIO tpktPacketIO = new TPKTPacketIO();
+
+        // Benchmark the parsing code
+        TPKTPacket packet = null;
+        for(int i = 0; i < numRunsParse; i++) {
+            ReadBuffer rBuf = new ReadBuffer(rData);
+            packet = tpktPacketIO.parse(rBuf);
+        }
+        long endParsing = System.currentTimeMillis();
+
+        System.out.println("Parsed " + numRunsParse + " packets in " + (endParsing - start) + "ms");
+        System.out.println("That's " + ((float) (endParsing - start) / numRunsParse) + "ms per packet");
+
+        // Benchmark the serializing code
+        int numRunsSerialize = 2000000;
+        byte[] oData = null;
+        for(int i = 0; i < numRunsSerialize; i++) {
+            WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
+            tpktPacketIO.serialize(wBuf, packet);
+            oData = wBuf.getData();
+        }
+        long endSerializing = System.currentTimeMillis();
+
+        System.out.println("Serialized " + numRunsSerialize + " packets in " + (endSerializing - endParsing) + "ms");
+        System.out.println("That's " + ((float) (endSerializing - endParsing) / numRunsSerialize) + "ms per packet");
+        if(!Arrays.equals(rData, oData)) {
+            for(int i = 0; i < rData.length; i++) {
+                if(rData[i] != oData[i]) {
+                    System.out.println("Difference in byte " + i);
+                }
+            }
+            System.out.println("Not equals");
+        } else {
+            System.out.println("Bytes equal");
+        }
+    }
+
+}