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 2019/08/07 14:58:44 UTC

[plc4x] branch feature/implement-df1-driver updated (3326555 -> 817085a)

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

cdutz pushed a change to branch feature/implement-df1-driver
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from 3326555  Added TestClass EndtoEnt. Added dependency to HelloPlc4X.
     new 376101d  - Simplified the mspec for the DF1 protocol - Added a "terminated" type of arrayField - Made the ReadBuffer endianness aware - Made the testsuite endianness aware
     new f7ee259  Matching pattern tests for serial/DF1 added
     new ef3edea  Plc4XDf1Protocol
     new c495592  pom modified for asciidoc
     new 1e73e20  Merge branch 'feature/implement-df1-driver' of github.com:vemmert/plc4x into feature/implement-df1-driver
     new 817085a  - Updated the current Netty driver prototype to work with the latest code generation updates.

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../language/java/JavaLanguageTemplateHelper.java  |  58 ++++++++-
 .../main/resources/templates/java/io-template.ftlh |  62 +++++++---
 .../plugins/codegenerator/language/mspec/MSpec.g4  |   2 +
 .../mspec/model/fields/DefaultArrayField.java      |   5 -
 .../mspec/parser/MessageFormatListener.java        |   6 +-
 plc4j/examples/hello-world-plc4x/pom.xml           |   1 +
 .../java/base/connection/SerialChannelFactory.java |   5 +-
 plc4j/protocols/pom.xml                            |   2 +-
 .../org/apache/plc4x/java/utils/ReadBuffer.java    |  39 ++++++-
 .../org/apache/plc4x/java/utils/WriteBuffer.java   |   8 +-
 .../protocol/test/ProtocolTestsuiteRunner.java     |  14 +--
 .../protocol/test/model/ProtocolTestsuite.java     |   8 +-
 .../src/main/resources/schemas/testsuite.xsd       |   1 +
 pom.xml                                            |   2 +-
 .../main/resources/protocols/df1/protocol.mspec    |  43 +++----
 sandbox/test-java-df1-driver/pom.xml               |  48 +++++++-
 .../org/apache/plc4x/java/df1/DF1PlcDriver.java    |   4 +-
 .../java/org/apache/plc4x/java/df1/Df1Field.java   |  36 +++---
 .../java/df1/connection/SerialDf1Connection.java   |  40 ++++++-
 .../plc4x/java/df1/protocol/Df1Protocol.java       |  46 ++++----
 .../plc4x/java/df1/protocol/Plc4XDf1Protocol.java  |  33 +++++-
 .../org/apache/plc4x/java/df1/util/DF1Utils.java   | 129 +++++++++++++++++++++
 .../plc4x/java/df1/util/Df1FieldHandler.java       |   3 +-
 .../org/apache/plc4x/protocol/df1/DF1Utils.java    |  84 --------------
 .../apache/plc4x/java/df1/DF1PlcDriverTest.java    |  37 +++---
 .../plc4x/protocol/df1/BenchmarkGeneratedDf1.java  |   7 +-
 .../plc4x/protocol/df1/BenchmarkManualDf1.java     |  36 +++---
 .../org/apache/plc4x/protocol/df1/Df1Test.java}    |   8 +-
 .../apache/plc4x/protocol/df1/EndToEndTest.java    |   9 +-
 .../org/apache/plc4x/protocol/df1}/IOTest.java     |  32 +++--
 .../src/test/resources/testsuite/Df1Testsuite.xml  |  81 +++++++++++++
 31 files changed, 611 insertions(+), 278 deletions(-)
 copy plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/mock/MockField.java => sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java (57%)
 create mode 100644 sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/DF1Utils.java
 delete mode 100644 sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
 copy plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/mock/MockField.java => sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java (56%)
 copy sandbox/{test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip/KNXNetIpTest.java => test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/Df1Test.java} (82%)
 copy sandbox/{test-java-knxnetip-driver/src/test/java/org/apache/plc4x/java/knxnetip => test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1}/IOTest.java (80%)
 create mode 100644 sandbox/test-java-df1-driver/src/test/resources/testsuite/Df1Testsuite.xml


[plc4x] 02/06: Plc4XDf1Protocol

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ef3edeacffc3cc7c8f5b2e9b4a62c1a004cce887
Author: v.emmert <v....@pragmaticminds.de>
AuthorDate: Wed Aug 7 16:00:18 2019 +0200

    Plc4XDf1Protocol
---
 .../java/base/connection/SerialChannelFactory.java |  5 ++--
 pom.xml                                            |  5 ++--
 sandbox/test-java-df1-driver/pom.xml               | 17 ++++++++++-
 .../org/apache/plc4x/java/df1/DF1PlcDriver.java    |  2 +-
 .../java/org/apache/plc4x/java/df1/Df1Field.java   | 33 ++++++++++++++++++++++
 .../plc4x/java/df1/protocol/Df1Protocol.java       | 10 +++++++
 .../plc4x/java/df1/protocol/Plc4XDf1Protocol.java  | 30 ++++++++++++++++++--
 .../plc4x/java/df1/util/Df1FieldHandler.java       |  3 +-
 .../plc4x/protocol/df1/BenchmarkManualDf1.java     |  7 +++--
 .../apache/plc4x/protocol/df1/EndToEndTest.java    |  4 +--
 10 files changed, 102 insertions(+), 14 deletions(-)

diff --git a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
index 6f93828..79185de 100644
--- a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
+++ b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
@@ -25,6 +25,7 @@ import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.jsc.JSerialCommChannel;
 import io.netty.channel.jsc.JSerialCommDeviceAddress;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.oio.OioEventLoopGroup;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 
@@ -45,8 +46,8 @@ public class SerialChannelFactory implements ChannelFactory {
             Bootstrap bootstrap = new Bootstrap();
             bootstrap.group(new OioEventLoopGroup());
             bootstrap.channel(JSerialCommChannel.class);
-            bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
-            bootstrap.option(ChannelOption.TCP_NODELAY, true);
+//            bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
+//            bootstrap.option(ChannelOption.TCP_NODELAY, true);
             bootstrap.handler(channelHandler);
             // Start the client.
             ChannelFuture f = bootstrap.connect(address).sync();
diff --git a/pom.xml b/pom.xml
index eae37c6..73c14ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -145,7 +145,7 @@
     <lucene.version>8.0.0</lucene.version>
     <metrics-core.version>3.1.2</metrics-core.version>
     <mockito.version>2.24.5</mockito.version>
-    <netty.version>4.1.35.Final</netty.version>
+    <netty.version>4.1.13.Final</netty.version>
     <netty-transport-jserialcomm.version>1.0.0</netty-transport-jserialcomm.version>
     <owasp-dependency-check.version>5.0.0-M1</owasp-dependency-check.version>
     <pcap4j.version>1.7.3</pcap4j.version>
@@ -1196,6 +1196,7 @@
               However this config section is used by the asciidoctor site plugin extension. So plead
               ignore this error, it's actually ok.
             -->
+            <!--
             <asciidoc>
               <attributes>
                 <source-highlighter>prettify</source-highlighter>
@@ -1205,7 +1206,7 @@
               <requires>
                 <require>asciidoctor-diagram</require>
               </requires>
-            </asciidoc>
+            </asciidoc>-->
           </configuration>
           <dependencies>
             <!-- All dependencies needed by the reflow skin -->
diff --git a/sandbox/test-java-df1-driver/pom.xml b/sandbox/test-java-df1-driver/pom.xml
index 7159072..4d6d1ff 100644
--- a/sandbox/test-java-df1-driver/pom.xml
+++ b/sandbox/test-java-df1-driver/pom.xml
@@ -121,9 +121,24 @@
     <dependency>
       <groupId>com.fazecast</groupId>
       <artifactId>jSerialComm</artifactId>
-      <version>2.5.1</version>
+      <version>1.3.11</version>
     </dependency>
 
+    <!-- Logging
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>log4j-over-slf4j</artifactId>
+      <version>1.7.25</version>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+    </dependency>-->
+
     <dependency>
       <groupId>org.apache.plc4x</groupId>
       <artifactId>plc4x-protocols-df1</artifactId>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
index 1988e72..e7d8d64 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
@@ -67,7 +67,7 @@ public class DF1PlcDriver implements PlcDriver {
 
     @Override
     public PlcConnection connect(String url, PlcAuthentication authentication) throws PlcConnectionException {
-        throw new PlcConnectionException("DF1 connections don't support authentication.");
+        throw new PlcConnectionException("DF1 connections doesn't support authentication.");
     }
 
 }
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java
new file mode 100644
index 0000000..43c8e4e
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java
@@ -0,0 +1,33 @@
+package org.apache.plc4x.java.df1;
+
+import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.df1.fields.DataType;
+
+public class Df1Field implements PlcField {
+
+    private final int address;
+    private final int size;
+    private final DataType dataType;
+
+    public Df1Field(int address, int size, DataType dataType) {
+        this.address = address;
+        this.size = size;
+        this.dataType = dataType;
+    }
+
+    public int getAddress() {
+        return address;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public DataType getDataType() {
+        return dataType;
+    }
+
+    public static PlcField of(String fieldQuery) {
+        return new Df1Field(11, 2, DataType.INTEGER);
+    }
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
index bbeece2..1015a7e 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
@@ -50,6 +50,10 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
     }
 
     @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+    }
+
+    @Override
     protected void encode(ChannelHandlerContext ctx, DF1Symbol msg, ByteBuf out) throws Exception {
         // Remember the size of the request as we need this to decode the response.
         if(msg instanceof DF1SymbolMessageFrameStart) {
@@ -140,4 +144,10 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
         out.add(resp);
     }
 
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        cause.printStackTrace();
+        ctx.close();
+        //super.exceptionCaught(ctx, cause);
+    }
 }
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
index 9a35c53..98a7a38 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
@@ -19,22 +19,46 @@
 package org.apache.plc4x.java.df1.protocol;
 
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
 import org.apache.plc4x.java.base.messages.PlcRequestContainer;
-import org.apache.plc4x.java.df1.DF1Symbol;
+import org.apache.plc4x.java.df1.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Symbol, PlcRequestContainer> {
 
+    private static final Logger logger = LoggerFactory.getLogger(Plc4XDf1Protocol.class);
+
+    private final AtomicInteger transactionId = new AtomicInteger(0);
+
     @Override
     protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
-
+        if (msg.getRequest() instanceof PlcReadRequest) {
+            for (PlcField field : ((PlcReadRequest) msg.getRequest()).getFields()) {
+                if (!(field instanceof Df1Field)) {
+                    throw new IllegalArgumentException("Invalid field type found inside Df1 Request");
+                }
+                int address = ((Df1Field) field).getAddress();
+                short size = (short) ((Df1Field) field).getAddress();
+                int transactionId = this.transactionId.getAndIncrement();
+                logger.debug("Creating request for offset {}, with length {} and transaction id {}", address, size, transactionId);
+                // TODO: differentiate commands
+                DF1SymbolMessageFrameStart frameStart = new DF1SymbolMessageFrameStart((short) 0x09, (short) 0x00, new DF1ReadRequest((short) 0x00, transactionId, address, size));
+                out.add(frameStart);
+            }
+        } else {
+            throw new IllegalStateException("This should not happen!");
+        }
     }
 
     @Override
     protected void decode(ChannelHandlerContext ctx, DF1Symbol msg, List<Object> out) throws Exception {
-
+        System.out.println("Hello");
     }
 
 }
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java
index 52e8bfc..4b92194 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/Df1FieldHandler.java
@@ -22,12 +22,13 @@ import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
 import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.base.connection.DefaultPlcFieldHandler;
 import org.apache.plc4x.java.base.messages.items.BaseDefaultFieldItem;
+import org.apache.plc4x.java.df1.Df1Field;
 
 public class Df1FieldHandler extends DefaultPlcFieldHandler {
 
     @Override
     public PlcField createField(String fieldQuery) throws PlcInvalidFieldException {
-        return null;
+        return Df1Field.of(fieldQuery);
     }
 
     @Override
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
index 3174170..fdc26b3 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
@@ -98,14 +98,13 @@ public class BenchmarkManualDf1 {
 //        comPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
 
         System.out.print(comPort.getSystemPortName() + " | ");
-        System.out.print(comPort.getPortDescription() + " | ");
+        //System.out.print(comPort.getPortDescription() + " | ");
         System.out.print(comPort.getDescriptivePortName() + " | Baud rate: ");
         System.out.println(comPort.getBaudRate());
 //        System.out.println(comPort.getReadTimeout());
 //        System.out.println(comPort.getWriteTimeout());
 
 
-        System.exit(0);
 
 //        DF1SymbolIO df1message = new DF1SymbolIO();
 
@@ -159,6 +158,10 @@ public class BenchmarkManualDf1 {
         comPort.writeBytes(c_ETX, 1);
 
 
+        comPort.closePort();
+        System.exit(0);
+
+
 //        int[] crcmsg = {c_DST[0], c_SRC[0], c_CMD[0], c_STS[0], c_TNS[0], c_TNS[1], c_ADR[0], c_ADR[1], c_SZE[0], c_ETX[0]}; // fullduplex CRC
         int[] crcmsg = {c_DST[0], c_SRC[0], c_CMD[0], c_STS[0], c_TNS[0], c_TNS[1], c_FNC[0], c_ETX[0]};                       // diagnostic status request
 //        int[] crcmsg = {0x11, 0x02, 0x09, 0x00, 0x01, 0x00, 0x41, 0x00, 0x12, 0x00, 0x0c, 0x03}; // halfduplex CRC
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
index 3a5f96d..4a52437 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
@@ -26,7 +26,6 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 
 import java.util.concurrent.TimeUnit;
-
 /**
  * TODO write comment
  *
@@ -40,11 +39,12 @@ public class EndToEndTest {
         try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial:///COM4")) {
             PlcReadRequest request = plcConnection.readRequestBuilder()
                 .addItem("erstes", "17:INTEGER")
+                .addItem("zweites", "17:INTEGER")
                 .build();
 
             PlcReadResponse response = request.execute().get(1, TimeUnit.SECONDS);
 
-            System.out.println(request);
+            System.out.println(response);
         } catch (PlcConnectionException e) {
             e.printStackTrace();
         } catch (Exception e) {


[plc4x] 04/06: - Simplified the mspec for the DF1 protocol - Added a "terminated" type of arrayField - Made the ReadBuffer endianness aware - Made the testsuite endianness aware

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 376101d1ef939b3d1e191b4c5d467117af596b3a
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 7 16:26:29 2019 +0200

    - Simplified the mspec for the DF1 protocol
    - Added a "terminated" type of arrayField
    - Made the ReadBuffer endianness aware
    - Made the testsuite endianness aware
---
 .../language/java/JavaLanguageTemplateHelper.java  |  58 ++++++++-
 .../main/resources/templates/java/io-template.ftlh |  62 +++++++---
 .../plugins/codegenerator/language/mspec/MSpec.g4  |   2 +
 .../mspec/model/fields/DefaultArrayField.java      |   5 -
 .../mspec/parser/MessageFormatListener.java        |   6 +-
 plc4j/examples/hello-world-plc4x/pom.xml           |   1 +
 .../org/apache/plc4x/java/utils/ReadBuffer.java    |  39 ++++++-
 .../org/apache/plc4x/java/utils/WriteBuffer.java   |   8 +-
 .../protocol/test/ProtocolTestsuiteRunner.java     |  14 +--
 .../protocol/test/model/ProtocolTestsuite.java     |   8 +-
 .../src/main/resources/schemas/testsuite.xsd       |   1 +
 .../main/resources/protocols/df1/protocol.mspec    |  43 +++----
 sandbox/test-java-df1-driver/pom.xml               |  31 ++++-
 .../plc4x/java/df1/protocol/Df1Protocol.java       |  16 +--
 .../org/apache/plc4x/java/df1/util/DF1Utils.java   | 129 +++++++++++++++++++++
 .../org/apache/plc4x/protocol/df1/DF1Utils.java    |  84 --------------
 .../plc4x/protocol/df1/BenchmarkGeneratedDf1.java  |   7 +-
 .../plc4x/protocol/df1/BenchmarkManualDf1.java     |   1 -
 .../org/apache/plc4x/protocol/df1/Df1Test.java     |  30 +++++
 .../apache/plc4x/protocol/df1/EndToEndTest.java    |   3 +-
 .../java/org/apache/plc4x/protocol/df1/IOTest.java |  99 ++++++++++++++++
 .../src/test/resources/testsuite/Df1Testsuite.xml  |  81 +++++++++++++
 22 files changed, 554 insertions(+), 174 deletions(-)

diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index bf293a6..034a690 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -376,6 +376,14 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
         return arrayField.getLengthType() == ArrayField.LengthType.COUNT;
     }
 
+    public boolean isLengthArray(ArrayField arrayField) {
+        return arrayField.getLengthType() == ArrayField.LengthType.LENGTH;
+    }
+
+    public boolean isTerminatedArray(ArrayField arrayField) {
+        return arrayField.getLengthType() == ArrayField.LengthType.TERMINATED;
+    }
+
     public String toSwitchExpression(String expression) {
         StringBuilder sb = new StringBuilder();
         Pattern pattern = Pattern.compile("([^\\.]*)\\.([a-zA-Z\\d]+)(.*)");
@@ -390,8 +398,8 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
         return sb.toString();
     }
 
-    public String toDeserializationExpression(Term term) {
-        return toExpression(term, this::toVariableDeserializationExpression);
+    public String toDeserializationExpression(Term term, Argument[] parserArguments) {
+        return toExpression(term, term1 -> toVariableDeserializationExpression(term1, parserArguments));
     }
 
     public String toSerializationExpression(Term term, Argument[] parserArguments) {
@@ -450,7 +458,7 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
         }
     }
 
-    private String toVariableDeserializationExpression(Term term) {
+    private String toVariableDeserializationExpression(Term term, Argument[] parserArguments) {
         VariableLiteral vl = (VariableLiteral) term;
         // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
         if("CAST".equals(vl.getName())) {
@@ -458,10 +466,47 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
             if((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
                 throw new RuntimeException("A CAST expression expects exactly two arguments.");
             }
-            sb.append("(").append(toVariableDeserializationExpression(vl.getArgs().get(0)))
+            sb.append("(").append(toVariableDeserializationExpression(vl.getArgs().get(0), parserArguments))
                 .append(", ").append(((VariableLiteral) vl.getArgs().get(1)).getName()).append(".class)");
             return sb.toString() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
         }
+        else if("STATIC_CALL".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder();
+            if(!(vl.getArgs().get(0) instanceof StringLiteral)) {
+                throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
+            }
+            String methodName = ((StringLiteral) vl.getArgs().get(0)).getValue();
+            methodName = methodName.substring(1, methodName.length() - 1);
+            sb.append(methodName).append("(");
+            for(int i = 1; i < vl.getArgs().size(); i++) {
+                Term arg = vl.getArgs().get(i);
+                if(i > 1) {
+                    sb.append(", ");
+                }
+                if(arg instanceof VariableLiteral) {
+                    VariableLiteral va = (VariableLiteral) arg;
+                    // "io" is the default name of the reader argument which is always available.
+                    boolean isDeserializerArg = "io".equals(va.getName());
+                    if(parserArguments != null) {
+                        for (Argument parserArgument : parserArguments) {
+                            if (parserArgument.getName().equals(va.getName())) {
+                                isDeserializerArg = true;
+                                break;
+                            }
+                        }
+                    }
+                    if(isDeserializerArg) {
+                        sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
+                    } else {
+                        sb.append(toVariableDeserializationExpression(va, null));
+                    }
+                } else if(arg instanceof StringLiteral) {
+                    sb.append(((StringLiteral) arg).getValue());
+                }
+            }
+            sb.append(")");
+            return sb.toString();
+        }
         // All uppercase names are not fields, but utility methods.
         else if(vl.getName().equals(vl.getName().toUpperCase())) {
             StringBuilder sb = new StringBuilder(vl.getName());
@@ -472,7 +517,7 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
                     if(!firstArg) {
                         sb.append(", ");
                     }
-                    sb.append(toVariableDeserializationExpression(arg));
+                    sb.append(toVariableDeserializationExpression(arg, parserArguments));
                     firstArg = false;
                 }
                 sb.append(")");
@@ -499,7 +544,8 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
                 }
                 if(arg instanceof VariableLiteral) {
                     VariableLiteral va = (VariableLiteral) arg;
-                    boolean isSerializerArg = false;
+                    // "io" and "value" are always available in every parser.
+                    boolean isSerializerArg = "io".equals(va.getName()) || "value".equals(va.getName());
                     if(parserArguments != null) {
                         for (Argument parserArgument : parserArguments) {
                             if (parserArgument.getName().equals(va.getName())) {
diff --git a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
index 33d0696..82a8056 100644
--- a/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/io-template.ftlh
@@ -78,32 +78,59 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
     <#case "array">
 
         // Array field
+        <#-- Only update curPos if the length expression uses it -->
         <#if field.lengthExpression.contains("curPos")>
         curPos = io.getPos() - startPos;
         </#if>
-        int ${field.name}Size = ${helper.toDeserializationExpression(field.lengthExpression)};
+        <#-- If this is a count array, we can directly initialize an array with the given size -->
         <#if helper.isCountArray(field)>
-        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[${field.name}Size];
-        for(int i = 0; i < ${field.name}Size; i++) {
+        // Count array
+        int _${field.name}Count = ${helper.toDeserializationExpression(field.lengthExpression, type.parserArguments)};
+        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[_${field.name}Count];
+        for(int i = 0; i < _${field.name}Count; i++) {
             ${field.name}[i] = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>${parserArgument}<#sep>, </#sep></#list></#if>)</#if>;
         }
+        <#-- In all other cases do we have to work with a list, that is later converted to an array -->
         <#else>
-        List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}> ${field.name}List = <#if helper.isCountArray(field)>new ArrayList<>(size)<#else>new LinkedList<>()</#if>;
-        int ${field.name}EndPos = io.getPos() + ${field.name}Size;
+            <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
+            <#if helper.isLengthArray(field)>
+        // Length array
+        int _${field.name}Length = ${helper.toDeserializationExpression(field.lengthExpression, type.parserArguments)};
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+        int ${field.name}EndPos = io.getPos() + _${field.name}Length;
         while(io.getPos() < ${field.name}EndPos) {
+            _${field.name}List.add(<#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toDeserializationExpression(parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+            <#-- After parsing, update the current position, but only if it's needed -->
             <#if field.lengthExpression.contains("curPos")>
             curPos = io.getPos() - startPos;
             </#if>
-            ${field.name}List.add(<#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toDeserializationExpression(parserArgument)})<#sep>, </#sep></#list></#if>)</#if>);
         }
-        <#if helper.isSimpleType(field.type)>
-        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[${field.name}List.size()];
-        for(int i = 0; i < ${field.name}List.size(); i++) {
-            ${field.name}[i] = (${helper.getLanguageTypeNameForField(field)}) ${field.name}List.get(i);
+            <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
+            <#elseif helper.isTerminatedArray(field)>
+        // Terminated array
+        List<${helper.getNonPrimitiveLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+        while(!((boolean) (${helper.toDeserializationExpression(field.lengthExpression, type.parserArguments)}))) {
+            _${field.name}List.add(<#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toDeserializationExpression(parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+
+            <#-- After parsing, update the current position, but only if it's needed -->
+            <#if field.lengthExpression.contains("curPos")>
+            curPos = io.getPos() - startPos;
+            </#if>
         }
-        <#else>
-        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = ${field.name}List.toArray(new ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[0]);
-        </#if>
+            </#if>
+            <#--
+                Convert the list into an array. However if the array is of a primitive
+                type we have to iterate over it's elements and explicitly cast them.
+                Otherwise a simple toArray call is fine.
+            -->
+            <#if helper.isSimpleType(field.type)>
+        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[_${field.name}List.size()];
+        for(int i = 0; i < _${field.name}List.size(); i++) {
+            ${field.name}[i] = (${helper.getLanguageTypeNameForField(field)}) _${field.name}List.get(i);
+        }
+            <#else>
+        ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = _${field.name}List.toArray(new ${helper.getNonPrimitiveLanguageTypeNameForField(field)}[0]);
+            </#if>
         </#if>
         <#break>
     <#case "const">
@@ -128,7 +155,7 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
 
         // Optional Field (Can be skipped, if a given expression evaluates to false)
         ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForType(field.type)};
-        if(${helper.toDeserializationExpression(field.conditionExpression)}) {
+        if(${helper.toDeserializationExpression(field.conditionExpression, type.parserArguments)}) {
             ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io);</#if>;
         }
         <#break>
@@ -145,7 +172,7 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
     <#case "simple">
 
         // Simple field
-        ${helper.getLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toDeserializationExpression(parserArgument)})<#sep>, </#sep></#list></#if>)</#if>;
+        ${helper.getLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleType(field.type)>io.${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name?uncap_first}IO.parse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toDeserializationExpression(parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>;
         <#break>
     <#case "switch">
 
@@ -240,7 +267,7 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
         <#if helper.isSimpleType(field.type)>
         io.${helper.getWriteBufferReadMethodCall(field.type, "(" + field.name + ")")};
         <#else>
-        ${field.type.name?uncap_first}IO.serialize(io, ${field.name}<#if field.params?has_content>, <#list field.params as term>(${helper.getArgumentType(field.type, term?index)}) (${helper.toDeserializationExpression(term)})<#sep>, </#sep></#list></#if>);
+        ${field.type.name?uncap_first}IO.serialize(io, ${field.name}<#if field.params?has_content>, <#list field.params as term>(${helper.getArgumentType(field.type, term?index)}) (${helper.toDeserializationExpression(term, type.parserArguments)})<#sep>, </#sep></#list></#if>);
         </#if>
         <#break>
     <#case "switch">
@@ -255,9 +282,6 @@ public class ${typeName}IO implements MessageIO<${typeName}<#if helper.isDiscrim
 </#switch>
 </#list>
     }
-    public static int CRC(Object... args) {
-        return 0;
-    }
 
     private static int COUNT(Object obj) {
         if(obj.getClass().isArray()) {
diff --git a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4 b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
index 374894b..3b50253 100644
--- a/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
+++ b/build-utils/protocol-base-mspec/src/main/antlr4/org/apache/plc4x/plugins/codegenerator/language/mspec/MSpec.g4
@@ -148,6 +148,7 @@ fragment HexDigit
 arrayType
  : K_COUNT
  | K_LENGTH
+ | K_TERMINATED
  ;
 
 idExpression
@@ -170,6 +171,7 @@ K_TYPE_SWITCH : 'typeSwitch';
 
 K_COUNT : 'count';
 K_LENGTH : 'length';
+K_TERMINATED : 'terminated';
 
 K_BIT : 'bit';
 K_INT : 'int';
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
index 4a06206..83737f8 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/fields/DefaultArrayField.java
@@ -60,9 +60,4 @@ public class DefaultArrayField implements ArrayField {
         return params;
     }
 
-    public static enum LengthType {
-        COUNT,
-        LENGTH
-    }
-
 }
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index 5a6441c..aeec697 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -96,8 +96,12 @@ public class MessageFormatListener extends MSpecBaseListener {
         ArrayField.LengthType lengthType;
         if(ctx.lengthType.K_COUNT() != null) {
             lengthType = ArrayField.LengthType.COUNT;
-        } else {
+        } else if(ctx.lengthType.K_LENGTH() != null){
             lengthType = ArrayField.LengthType.LENGTH;
+        } else if(ctx.lengthType.K_TERMINATED() != null) {
+            lengthType = ArrayField.LengthType.TERMINATED;
+        } else {
+            throw new RuntimeException("Unsupported lenghtType for arrayField");
         }
         String lengthExpressionString = ctx.lengthExpression.expr.getText();
         InputStream inputStream = IOUtils.toInputStream(lengthExpressionString);
diff --git a/plc4j/examples/hello-world-plc4x/pom.xml b/plc4j/examples/hello-world-plc4x/pom.xml
index e3295da..eaee6fe 100644
--- a/plc4j/examples/hello-world-plc4x/pom.xml
+++ b/plc4j/examples/hello-world-plc4x/pom.xml
@@ -91,6 +91,7 @@
           <usedDependencies combine.children="append">
             <usedDependency>org.apache.plc4x:plc4j-driver-s7</usedDependency>
             <usedDependency>org.apache.plc4x:plc4j-driver-simulated</usedDependency>
+            <usedDependency>org.apache.plc4x.sandbox:test-java-df1-driver</usedDependency>
             <usedDependency>org.slf4j:log4j-over-slf4j</usedDependency>
           </usedDependencies>
         </configuration>
diff --git a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
index 283e1b3..43ac53c 100644
--- a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
+++ b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/ReadBuffer.java
@@ -28,17 +28,39 @@ import java.math.BigInteger;
 
 public class ReadBuffer {
 
-    private MyDefaultBitInput bi;
+    private final MyDefaultBitInput bi;
+    private final boolean littleEndian;
 
     public ReadBuffer(byte[] input) {
+        this(input, true);
+    }
+
+    public ReadBuffer(byte[] input, boolean littleEndian) {
         ArrayByteInput abi = new ArrayByteInput(input);
         bi = new MyDefaultBitInput(abi);
+        this.littleEndian = littleEndian;
     }
 
     public int getPos() {
         return (int) bi.getPos();
     }
 
+    public byte peekByte(int offset) throws ParseException {
+        // Remember the old index.
+        int oldIndex = bi.getDelegate().getIndex();
+        try {
+            // Set the delegate to the desired position.
+            bi.getDelegate().index(oldIndex + offset);
+            // Read the byte.
+            return bi.readByte(false, 8);
+        } catch (IOException e) {
+            throw new ParseException("Error reading", e);
+        } finally {
+            // Reset the delegate to the old index.
+            bi.getDelegate().index(oldIndex);
+        }
+    }
+
     public boolean readBit() throws ParseException {
         try {
             return bi.readBoolean();
@@ -83,6 +105,9 @@ public class ReadBuffer {
             throw new ParseException("unsigned int can only contain max 16 bits");
         }
         try {
+            if(!littleEndian) {
+                return Integer.reverseBytes(bi.readInt(true, bitLength)) >> 16;
+            }
             return bi.readInt(true, bitLength);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -97,6 +122,9 @@ public class ReadBuffer {
             throw new ParseException("unsigned long can only contain max 32 bits");
         }
         try {
+            if(!littleEndian) {
+                return Long.reverseBytes(bi.readLong(true, bitLength)) >> 32;
+            }
             return bi.readLong(true, bitLength);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -129,6 +157,9 @@ public class ReadBuffer {
             throw new ParseException("short can only contain max 16 bits");
         }
         try {
+            if(!littleEndian) {
+                return Short.reverseBytes(bi.readShort(false, bitLength));
+            }
             return bi.readShort(false, bitLength);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -143,6 +174,9 @@ public class ReadBuffer {
             throw new ParseException("int can only contain max 32 bits");
         }
         try {
+            if(!littleEndian) {
+                return Integer.reverseBytes(bi.readInt(false, bitLength));
+            }
             return bi.readInt(false, bitLength);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
@@ -157,6 +191,9 @@ public class ReadBuffer {
             throw new ParseException("long can only contain max 64 bits");
         }
         try {
+            if(!littleEndian) {
+                return Long.reverseBytes(bi.readLong(false, bitLength));
+            }
             return bi.readLong(false, bitLength);
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
diff --git a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
index bc10358..8c14102 100644
--- a/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
+++ b/plc4j/utils/driver-base-java/src/main/java/org/apache/plc4x/java/utils/WriteBuffer.java
@@ -30,10 +30,10 @@ import java.nio.ByteBuffer;
 
 public class WriteBuffer {
 
-    private ByteBuffer bb;
-    private BufferByteOutput bbo;
-    private BitOutput bo;
-    private boolean littleEndian;
+    private final ByteBuffer bb;
+    private final BufferByteOutput bbo;
+    private final BitOutput bo;
+    private final boolean littleEndian;
 
     public WriteBuffer(int size) {
         this(size, true);
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java
index f85d3af..50dbc41 100644
--- a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/ProtocolTestsuiteRunner.java
@@ -59,7 +59,7 @@ public class ProtocolTestsuiteRunner {
             String testcaseName = testcase.getName();
             String testcaseLabel = testSuite.getName() + ": " + testcaseName;
             DynamicTest test = DynamicTest.dynamicTest(testcaseLabel, () ->
-                run(testcase)
+                run(testSuite, testcase)
             );
             dynamicTests.add(test);
         }
@@ -71,6 +71,7 @@ public class ProtocolTestsuiteRunner {
             SAXReader reader = new SAXReader();
             Document document = reader.read(testsuiteDocumentXml);
             Element testsuiteXml = document.getRootElement();
+            boolean littleEndian = !"true".equals(testsuiteXml.attributeValue("bigEndian"));
             Element testsuiteName = testsuiteXml.element(new QName("name"));
             List<Element> testcasesXml = testsuiteXml.elements(new QName("testcase"));
             List<Testcase> testcases = new ArrayList<>(testcasesXml.size());
@@ -89,7 +90,7 @@ public class ProtocolTestsuiteRunner {
                 testcases.add(new Testcase(name, description, raw, rootType, xmlElement));
             }
             LOGGER.info(String.format("Found %d testcases.", testcases.size()));
-            return new ProtocolTestsuite(testsuiteName.getTextTrim(), testcases);
+            return new ProtocolTestsuite(testsuiteName.getTextTrim(), testcases, littleEndian);
         } catch (DocumentException e) {
             throw new ProtocolTestsuiteException("Error parsing testsuite xml", e);
         } catch (DecoderException e) {
@@ -97,9 +98,9 @@ public class ProtocolTestsuiteRunner {
         }
     }
 
-    private void run(Testcase testcase) throws ProtocolTestsuiteException {
+    private void run(ProtocolTestsuite testSuite, Testcase testcase) throws ProtocolTestsuiteException {
         ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
-        ReadBuffer readBuffer = new ReadBuffer(testcase.getRaw());
+        ReadBuffer readBuffer = new ReadBuffer(testcase.getRaw(), testSuite.isLittleEndian());
         String referenceXml = testcase.getXml().elements().get(0).asXML();
 
         MessageIO messageIO = getMessageIOForTestcase(testcase);
@@ -108,10 +109,9 @@ public class ProtocolTestsuiteRunner {
             String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(msg);
             Diff diff = DiffBuilder.compare(referenceXml).withTest(xmlString).ignoreWhitespace().build();
             if(diff.hasDifferences()) {
-                // TODO: Add some more information ...
-                throw new ProtocolTestsuiteException("Differences were found after parsing.");
+                throw new ProtocolTestsuiteException("Differences were found after parsing.\n" + diff.toString());
             }
-            WriteBuffer writeBuffer = new WriteBuffer(((SizeAware) msg).getLengthInBytes());
+            WriteBuffer writeBuffer = new WriteBuffer(((SizeAware) msg).getLengthInBytes(), testSuite.isLittleEndian());
             messageIO.serialize(writeBuffer, msg);
             byte[] data = writeBuffer.getData();
             if(!Arrays.equals(testcase.getRaw(), data)) {
diff --git a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java
index 68b0ffe..83de706 100644
--- a/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java
+++ b/plc4j/utils/protocol-test-utils/src/main/java/org/apache/plc4x/protocol/test/model/ProtocolTestsuite.java
@@ -25,10 +25,12 @@ public class ProtocolTestsuite {
 
     private final String name;
     private final List<Testcase> testcases;
+    private final boolean littleEndian;
 
-    public ProtocolTestsuite(String name, List<Testcase> testcases) {
+    public ProtocolTestsuite(String name, List<Testcase> testcases, boolean littleEndian) {
         this.name = name;
         this.testcases = testcases;
+        this.littleEndian = littleEndian;
     }
 
     public String getName() {
@@ -39,4 +41,8 @@ public class ProtocolTestsuite {
         return testcases;
     }
 
+    public boolean isLittleEndian() {
+        return littleEndian;
+    }
+
 }
diff --git a/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd b/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd
index 5ef4977..58c099b 100644
--- a/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd
+++ b/plc4j/utils/protocol-test-utils/src/main/resources/schemas/testsuite.xsd
@@ -48,6 +48,7 @@
                     </xs:complexType>
                 </xs:element>
             </xs:sequence>
+            <xs:attribute name="bigEndian" type="xs:boolean"/>
         </xs:complexType>
     </xs:element>
 
diff --git a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
index d63974c..5e997fb 100644
--- a/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
+++ b/protocols/df1/src/main/resources/protocols/df1/protocol.mspec
@@ -17,32 +17,17 @@
 // under the License.
 //
 
-
-[type 'ReadRequest'
-    [field    DF1Symbol    'messageFrameStart' ['0', 'null']]
-    [field    DF1Symbol    'messageFrameEnd' ['0', 'messageFrameStart']]
-]
-
-[type 'ReadResponse' [uint 8 'payloadSize']
-    [field    DF1Symbol    'messageFrameStart' ['payloadSize', 'null']]
-    [field    DF1Symbol    'messageFrameEnd' ['0', 'messageFrameStart']]
-]
-
-[type 'Result'
-    [field    DF1Symbol    'result' ['0', 'null']]
-]
-
-[discriminatedType 'DF1Symbol' [uint 8 'payloadSize', DF1SymbolMessageFrameStart 'messageStartSymbol']
+[discriminatedType 'DF1Symbol'
     [const            uint 8       'messageStart' '0x10']
     [discriminator    uint 8       'symbolType']
     [typeSwitch 'symbolType'
-        ['0x02' DF1SymbolMessageFrameStart
+        ['0x02' DF1SymbolMessageFrame
             [field    uint 8       'destinationAddress']
             [field    uint 8       'sourceAddress']
-            [field    DF1Command   'command' ['payloadSize']]
-        ]
-        ['0x03' DF1SymbolMessageFrameEnd
-            [implicit uint 16      'crc' 'STATIC_CALL("org.apache.plc4x.protocol.df1.DF1Utils.CRCCheck", discriminatorValues[0], messageStartSymbol)']
+            [field    DF1Command   'command']
+            [const    uint 8       'messageEnd' '0x10']
+            [const    uint 8       'endTransaction' '0x03']
+            [implicit uint 16      'crc' 'STATIC_CALL("org.apache.plc4x.java.df1.util.DF1Utils.CRCCheck", value)']
         ]
         ['0x06' DF1SymbolMessageFrameACK
         ]
@@ -51,17 +36,17 @@
     ]
 ]
 
-[discriminatedType 'DF1Command' [uint 8 'payloadSize']
-    [discriminator uint 8  'commandType']
+[discriminatedType 'DF1Command'
+    [discriminator uint 8  'commandCode']
     [field    uint 8       'status']
     [field    uint 16      'transactionCounter']
-    [typeSwitch 'commandType'
-        ['0x01' DF1ReadRequest
-         [field uint 16    'address']
-         [field uint 8     'size']
+    [typeSwitch 'commandCode'
+        ['0x01' DF1UnprotectedReadRequest
+            [field uint 16    'address']
+            [field uint 8     'size']
         ]
-        ['0x41' DF1ReadResponse
-         [arrayField uint 8 'data' length 'payloadSize']
+        ['0x41' DF1UnprotectedReadResponse
+            [arrayField uint 8 'data' terminated 'STATIC_CALL("org.apache.plc4x.java.df1.util.DF1Utils.dataTerminate", io)']
         ]
     ]
 ]
diff --git a/sandbox/test-java-df1-driver/pom.xml b/sandbox/test-java-df1-driver/pom.xml
index 7159072..904ef55 100644
--- a/sandbox/test-java-df1-driver/pom.xml
+++ b/sandbox/test-java-df1-driver/pom.xml
@@ -132,10 +132,37 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-protocol-test-utils</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.dataformat</groupId>
+      <artifactId>jackson-dataformat-xml</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.platform</groupId>
+      <artifactId>junit-platform-launcher</artifactId>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 
 </project>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
index bbeece2..31a9024 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
@@ -23,9 +23,9 @@ import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.ChannelHandlerContext;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.base.PlcByteToMessageCodec;
-import org.apache.plc4x.java.df1.DF1ReadRequest;
 import org.apache.plc4x.java.df1.DF1Symbol;
-import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
+import org.apache.plc4x.java.df1.DF1SymbolMessageFrame;
+import org.apache.plc4x.java.df1.DF1UnprotectedReadRequest;
 import org.apache.plc4x.java.df1.io.DF1SymbolIO;
 import org.apache.plc4x.java.utils.ReadBuffer;
 import org.apache.plc4x.java.utils.WriteBuffer;
@@ -52,12 +52,12 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
     @Override
     protected void encode(ChannelHandlerContext ctx, DF1Symbol msg, ByteBuf out) throws Exception {
         // Remember the size of the request as we need this to decode the response.
-        if(msg instanceof DF1SymbolMessageFrameStart) {
-            DF1SymbolMessageFrameStart frameStart = (DF1SymbolMessageFrameStart) msg;
-            if(frameStart.getCommand() instanceof DF1ReadRequest) {
-                DF1ReadRequest readRequest = (DF1ReadRequest) frameStart.getCommand();
-                int transactionCounter = readRequest.getTransactionCounter();
-                readRequestSizes.put(transactionCounter, readRequest.getSize());
+        if(msg instanceof DF1SymbolMessageFrame) {
+            DF1SymbolMessageFrame frame = (DF1SymbolMessageFrame) msg;
+            if(frame.getCommand() instanceof DF1UnprotectedReadRequest) {
+                DF1UnprotectedReadRequest unprotectedReadRequest = (DF1UnprotectedReadRequest) frame.getCommand();
+                int transactionCounter = unprotectedReadRequest.getTransactionCounter();
+                readRequestSizes.put(transactionCounter, unprotectedReadRequest.getSize());
             }
         }
 
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/DF1Utils.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/DF1Utils.java
new file mode 100644
index 0000000..1d36d65
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/util/DF1Utils.java
@@ -0,0 +1,129 @@
+/*
+ * 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.java.df1.util;
+
+import org.apache.plc4x.java.df1.DF1Symbol;
+import org.apache.plc4x.java.df1.DF1SymbolMessageFrame;
+import org.apache.plc4x.java.df1.DF1UnprotectedReadRequest;
+import org.apache.plc4x.java.df1.DF1UnprotectedReadResponse;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
+
+public class DF1Utils {
+
+    public static short CRCCheck(Object... args) {
+        DF1Symbol symbol = (DF1Symbol) args[0];
+        if(symbol instanceof DF1SymbolMessageFrame) {
+            DF1SymbolMessageFrame messageFrame = (DF1SymbolMessageFrame) symbol;
+
+            short destinationAddress = messageFrame.getDestinationAddress();
+            short sourceAddress = messageFrame.getSourceAddress();
+            short commandDiscriminatorValues = (short) messageFrame.getCommand().getDiscriminatorValues()[0];
+            short status = messageFrame.getCommand().getStatus();
+            int   counter = messageFrame.getCommand().getTransactionCounter();
+            if(messageFrame.getCommand() instanceof DF1UnprotectedReadRequest) {
+                DF1UnprotectedReadRequest unprotectedReadRequestCommand = (DF1UnprotectedReadRequest) messageFrame.getCommand();
+                try {
+                    WriteBuffer writeBuffer = new WriteBuffer(10, false);
+                    writeBuffer.writeUnsignedShort(8, destinationAddress);
+                    writeBuffer.writeUnsignedShort(8, sourceAddress);
+                    writeBuffer.writeUnsignedShort(8, commandDiscriminatorValues);
+                    writeBuffer.writeUnsignedShort(8, status);
+                    writeBuffer.writeUnsignedInt(16, (short) counter);
+                    writeBuffer.writeUnsignedInt(16, (short) unprotectedReadRequestCommand.getAddress());
+                    writeBuffer.writeUnsignedShort(8, (byte) unprotectedReadRequestCommand.getSize());
+                    writeBuffer.writeUnsignedShort(8, (byte) 0x03);
+
+                    byte[] data = writeBuffer.getData();
+
+                    int tmp = 0;
+                    int crcL, crcR;
+
+                    for (int newByte : data) {
+                        crcL = tmp >> 8;
+                        crcR = tmp & 0xFF;
+                        tmp = (crcL << 8) + (newByte ^ crcR);
+                        for (int j=0; j<8; j++)
+                            if (tmp % 2 == 1) {     // check if LSB shifted out is 1 or 0
+                                tmp = tmp >> 1;
+                                tmp = tmp ^ 0xA001;
+                            } else {
+                                tmp = tmp >> 1;
+                            }
+                    }
+
+                    return (short) tmp;
+                } catch (ParseException e) {
+                    throw new RuntimeException("Something wen't wrong during the CRC check", e);
+                }
+            } else if(messageFrame.getCommand() instanceof DF1UnprotectedReadResponse) {
+                DF1UnprotectedReadResponse unprotectedReadResponseCommand = (DF1UnprotectedReadResponse) messageFrame.getCommand();
+                try {
+                    WriteBuffer writeBuffer = new WriteBuffer(10, false);
+                    writeBuffer.writeUnsignedShort(8, destinationAddress);
+                    writeBuffer.writeUnsignedShort(8, sourceAddress);
+                    writeBuffer.writeUnsignedShort(8, commandDiscriminatorValues);
+                    writeBuffer.writeUnsignedShort(8, status);
+                    writeBuffer.writeUnsignedInt(16, (short) counter);
+                    for (short data : unprotectedReadResponseCommand.getData()) {
+                        writeBuffer.writeUnsignedShort(8,  data);
+                    }
+                    writeBuffer.writeUnsignedShort(8, (byte) 0x03);
+
+                    byte[] data = writeBuffer.getData();
+
+                    int tmp = 0;
+                    int crcL, crcR;
+
+                    for (int newByte : data) {
+                        crcL = tmp >> 8;
+                        crcR = tmp & 0xFF;
+                        tmp = (crcL << 8) + (newByte ^ crcR);
+                        for (int j=0; j<8; j++)
+                            if (tmp % 2 == 1) {     // check if LSB shifted out is 1 or 0
+                                tmp = tmp >> 1;
+                                tmp = tmp ^ 0xA001;
+                            } else {
+                                tmp = tmp >> 1;
+                            }
+                    }
+
+                    return (short) tmp;
+                } catch (ParseException e) {
+                    throw new RuntimeException("Something wen't wrong during the CRC check", e);
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    public static boolean dataTerminate(ReadBuffer io) {
+        try {
+            if ((io.peekByte(0) == (byte) 0x10) && (io.peekByte(1) == (byte) 0x03)) {
+                return true;
+            }
+        } catch (ParseException e) {
+            // Just ignore and return false.
+        }
+        return false;
+    }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
deleted file mode 100644
index a85ab8f..0000000
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/DF1Utils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.java.df1.DF1ReadRequest;
-import org.apache.plc4x.java.df1.DF1Symbol;
-import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
-import org.apache.plc4x.java.utils.ParseException;
-import org.apache.plc4x.java.utils.WriteBuffer;
-
-import java.nio.ByteBuffer;
-
-public class DF1Utils {
-
-    public static short CRCCheck(Object... args) {
-        DF1Symbol symbol = (DF1Symbol) args[1];
-        short messageType = (short) args[0];
-        if(symbol instanceof DF1SymbolMessageFrameStart) {
-            DF1SymbolMessageFrameStart messageFrameStart = (DF1SymbolMessageFrameStart) symbol;
-
-            short destinationAddress = messageFrameStart.getDestinationAddress();
-            short sourceAddress = messageFrameStart.getSourceAddress();
-            short commandDiscriminatorValues = (short) messageFrameStart.getCommand().getDiscriminatorValues()[0];
-            short status = messageFrameStart.getCommand().getStatus();
-            int   counter = messageFrameStart.getCommand().getTransactionCounter();
-            if(messageFrameStart.getCommand() instanceof DF1ReadRequest) {
-                DF1ReadRequest readRequestCommand = (DF1ReadRequest) messageFrameStart.getCommand();
-
-                try {
-                    WriteBuffer writeBuffer = new WriteBuffer(10, false);
-                    writeBuffer.writeUnsignedShort(8, destinationAddress);
-                    writeBuffer.writeUnsignedShort(8, sourceAddress);
-                    writeBuffer.writeUnsignedShort(8, commandDiscriminatorValues);
-                    writeBuffer.writeUnsignedShort(8, status);
-                    writeBuffer.writeUnsignedInt(16, (short) counter);
-                    writeBuffer.writeUnsignedInt(16, (short) readRequestCommand.getAddress());
-                    writeBuffer.writeUnsignedShort(8, (byte) readRequestCommand.getSize());
-                    writeBuffer.writeUnsignedShort(8, (byte) messageType);
-
-                    byte[] data = writeBuffer.getData();
-
-                    int tmp = 0;
-                    int crcL, crcR;
-
-                    for (int newByte : data) {
-                        crcL = tmp >> 8;
-                        crcR = tmp & 0xFF;
-                        tmp = (crcL << 8) + (newByte ^ crcR);
-                        for (int j=0; j<8; j++)
-                            if (tmp % 2 == 1) {     // check if LSB shifted out is 1 or 0
-                                tmp = tmp >> 1;
-                                tmp = tmp ^ 0xA001;
-                            } else {
-                                tmp = tmp >> 1;
-                            }
-                    }
-
-                    return (short) tmp;
-                } catch (ParseException e) {
-                    throw new RuntimeException("Something wen't wrong during the CRC check", e);
-                }
-            }
-        }
-
-        return 0;
-    }
-
-}
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
index e092cb6..27c9be2 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
@@ -21,16 +21,13 @@ package org.apache.plc4x.protocol.df1;
 
 import com.fazecast.jSerialComm.SerialPort;
 import org.apache.plc4x.java.df1.*;
-import org.apache.plc4x.java.df1.io.ReadRequestIO;
-import org.apache.plc4x.java.df1.io.ReadResponseIO;
-import org.apache.plc4x.java.df1.io.ResultIO;
 import org.apache.plc4x.java.utils.ReadBuffer;
 import org.apache.plc4x.java.utils.WriteBuffer;
 
 public class BenchmarkGeneratedDf1 {
 
     public static void main(String[] args) throws Exception {
-        // Manually build a message
+        /*// Manually build a message
         ReadRequest readRequest = new ReadRequest(new DF1SymbolMessageFrameStart((short) 0x09, (short) 0x00, new DF1ReadRequest((short) 0x00, 0x01, 0x0B, (short) 0x02)), new DF1SymbolMessageFrameEnd());
 
         // Serialize the message
@@ -78,7 +75,7 @@ public class BenchmarkGeneratedDf1 {
             System.out.println("Didn't get an ACK");
         }
 
-        comPort.closePort();
+        comPort.closePort();*/
     }
 
 }
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
index c2571fe..f832798 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
@@ -22,7 +22,6 @@ package org.apache.plc4x.protocol.df1;
 import com.fazecast.jSerialComm.SerialPort;
 import org.apache.plc4x.java.df1.DF1Command;
 import org.apache.plc4x.java.df1.DF1Symbol;
-import org.apache.plc4x.java.df1.DF1SymbolMessageFrameStart;
 import org.apache.plc4x.java.df1.io.DF1SymbolIO;
 import org.apache.plc4x.java.utils.ReadBuffer;
 
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/Df1Test.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/Df1Test.java
new file mode 100644
index 0000000..bcadf1a
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/Df1Test.java
@@ -0,0 +1,30 @@
+/*
+  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.protocol.test.ProtocolTestsuiteRunner;
+
+public class Df1Test extends ProtocolTestsuiteRunner {
+
+    public Df1Test() {
+        super("/testsuite/Df1Testsuite.xml");
+    }
+
+}
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
index 954d092..e35fcce 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.junit.jupiter.api.Test;
 
 import java.util.concurrent.TimeUnit;
 
@@ -35,7 +36,7 @@ import java.util.concurrent.TimeUnit;
  */
 public class EndToEndTest {
 
-    @org.junit.Test
+    @Test
     public void helloDf1() {
         try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial///dev/cu.usbserial-AL065SUZ")) {
             PlcReadRequest request = plcConnection.readRequestBuilder()
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/IOTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/IOTest.java
new file mode 100644
index 0000000..18543cc
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/IOTest.java
@@ -0,0 +1,99 @@
+/*
+ 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 com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.plc4x.java.df1.DF1Symbol;
+import org.apache.plc4x.java.df1.io.DF1SymbolIO;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.junit.jupiter.api.Test;
+
+public class IOTest {
+
+    @Test
+    public void testXml() throws Exception {
+        byte[] rData = Hex.decodeHex("10020A0941000100FFFF1003473D");
+        ObjectMapper mapper = new XmlMapper().enableDefaultTyping();
+        ReadBuffer rBuf = new ReadBuffer(rData);
+        DF1Symbol symbol = new DF1SymbolIO().parse(rBuf);
+        String xml = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(symbol);
+        System.out.println(xml);
+        DF1Symbol symbol2 = mapper.readValue(xml, DF1Symbol.class);
+        System.out.println(symbol2);
+    }
+
+    @Test
+    public void testJson() throws Exception {
+        byte[] rData = Hex.decodeHex("10020900010001001100021003ABE2");
+        ObjectMapper mapper = new ObjectMapper().enableDefaultTyping();
+        ReadBuffer rBuf = new ReadBuffer(rData);
+        DF1Symbol symbol = new DF1SymbolIO().parse(rBuf);
+        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(symbol);
+        System.out.println(json);
+        DF1Symbol symbol2 = mapper.readValue(json, DF1Symbol.class);
+        System.out.println(symbol2);
+    }
+
+    /*@Test
+    public void testParser() throws Exception {
+        byte[] rData = Hex.decodeHex("0610020500180801c0a82a46c4090801c0a82a46c40a0203");
+        long start = System.currentTimeMillis();
+        int numRunsParse = 20000;
+
+        KNXNetIPMessageIO knxNetIPMessageIO = new KNXNetIPMessageIO();
+
+        // Benchmark the parsing code
+        KNXNetIPMessage packet = null;
+        for(int i = 0; i < numRunsParse; i++) {
+            ReadBuffer rBuf = new ReadBuffer(rData);
+            packet = knxNetIPMessageIO.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 = 20000;
+        byte[] oData = null;
+        for(int i = 0; i < numRunsSerialize; i++) {
+            WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
+            knxNetIPMessageIO.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");
+        }
+    }*/
+
+}
diff --git a/sandbox/test-java-df1-driver/src/test/resources/testsuite/Df1Testsuite.xml b/sandbox/test-java-df1-driver/src/test/resources/testsuite/Df1Testsuite.xml
new file mode 100644
index 0000000..b0691ef
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/test/resources/testsuite/Df1Testsuite.xml
@@ -0,0 +1,81 @@
+<?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.
+  -->
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/testsuite.xsd"
+                bigEndian="true">
+
+  <name>Allen-Bradley DF1</name>
+
+  <testcase>
+    <name>Unprotected Read Address Request</name>
+    <raw>10020900010001001100021003546F</raw>
+    <root-type>DF1Symbol</root-type>
+    <xml>
+      <DF1SymbolMessageFrame className="org.apache.plc4x.java.df1.DF1SymbolMessageFrame">
+        <destinationAddress>9</destinationAddress>
+        <sourceAddress>0</sourceAddress>
+        <command className="org.apache.plc4x.java.df1.DF1UnprotectedReadRequest">
+          <status>0</status>
+          <transactionCounter>1</transactionCounter>
+          <address>17</address>
+          <size>2</size>
+        </command>
+      </DF1SymbolMessageFrame>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>Unprotected Read Address Response</name>
+    <raw>10020A0941000100FFFF1003DFB9</raw>
+    <root-type>DF1Symbol</root-type>
+    <xml>
+      <DF1SymbolMessageFrame className="org.apache.plc4x.java.df1.DF1SymbolMessageFrame">
+        <destinationAddress>10</destinationAddress>
+        <sourceAddress>9</sourceAddress>
+        <command className="org.apache.plc4x.java.df1.DF1UnprotectedReadResponse">
+          <status>0</status>
+          <transactionCounter>1</transactionCounter>
+          <data>
+            <data>255</data>
+            <data>255</data>
+          </data>
+        </command>
+      </DF1SymbolMessageFrame>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>ACK Response</name>
+    <raw>1006</raw>
+    <root-type>DF1Symbol</root-type>
+    <xml>
+      <DF1SymbolMessageFrameACK className="org.apache.plc4x.java.df1.DF1SymbolMessageFrameACK"/>
+    </xml>
+  </testcase>
+
+  <testcase>
+    <name>NACK Response</name>
+    <raw>1015</raw>
+    <root-type>DF1Symbol</root-type>
+    <xml>
+      <DF1SymbolMessageFrameNAK className="org.apache.plc4x.java.df1.DF1SymbolMessageFrameNAK"/>
+    </xml>
+  </testcase>
+
+</test:testsuite>
\ No newline at end of file


[plc4x] 03/06: pom modified for asciidoc

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c4955924b28dabd02335560be6487497969d0302
Author: v.emmert <v....@pragmaticminds.de>
AuthorDate: Wed Aug 7 16:05:05 2019 +0200

    pom modified for asciidoc
---
 pom.xml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index 73c14ae..51d3a23 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1196,7 +1196,6 @@
               However this config section is used by the asciidoctor site plugin extension. So plead
               ignore this error, it's actually ok.
             -->
-            <!--
             <asciidoc>
               <attributes>
                 <source-highlighter>prettify</source-highlighter>
@@ -1206,7 +1205,7 @@
               <requires>
                 <require>asciidoctor-diagram</require>
               </requires>
-            </asciidoc>-->
+            </asciidoc>
           </configuration>
           <dependencies>
             <!-- All dependencies needed by the reflow skin -->


[plc4x] 05/06: Merge branch 'feature/implement-df1-driver' of github.com:vemmert/plc4x into feature/implement-df1-driver

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1e73e208c9bd96db506d4752d51b7711d36211b7
Merge: 376101d c495592
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 7 16:27:21 2019 +0200

    Merge branch 'feature/implement-df1-driver' of github.com:vemmert/plc4x into feature/implement-df1-driver

 .../java/base/connection/SerialChannelFactory.java |  5 ++--
 pom.xml                                            |  2 +-
 sandbox/test-java-df1-driver/pom.xml               | 17 ++++++++++-
 .../org/apache/plc4x/java/df1/DF1PlcDriver.java    |  4 +--
 .../java/org/apache/plc4x/java/df1/Df1Field.java   | 33 ++++++++++++++++++++
 .../plc4x/java/df1/protocol/Df1Protocol.java       | 10 +++++++
 .../plc4x/java/df1/protocol/Plc4XDf1Protocol.java  | 30 +++++++++++++++++--
 .../plc4x/java/df1/util/Df1FieldHandler.java       |  3 +-
 .../apache/plc4x/java/df1/DF1PlcDriverTest.java    | 26 ++++++++++++++++
 .../plc4x/protocol/df1/BenchmarkManualDf1.java     | 35 ++++++++++++----------
 .../apache/plc4x/protocol/df1/EndToEndTest.java    |  6 ++--
 11 files changed, 143 insertions(+), 28 deletions(-)

diff --cc sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
index 31a9024,1015a7e..92ae07d
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
@@@ -50,14 -50,18 +50,18 @@@ public class Df1Protocol extends PlcByt
      }
  
      @Override
+     public void channelActive(ChannelHandlerContext ctx) throws Exception {
+     }
+ 
+     @Override
      protected void encode(ChannelHandlerContext ctx, DF1Symbol msg, ByteBuf out) throws Exception {
          // Remember the size of the request as we need this to decode the response.
 -        if(msg instanceof DF1SymbolMessageFrameStart) {
 -            DF1SymbolMessageFrameStart frameStart = (DF1SymbolMessageFrameStart) msg;
 -            if(frameStart.getCommand() instanceof DF1ReadRequest) {
 -                DF1ReadRequest readRequest = (DF1ReadRequest) frameStart.getCommand();
 -                int transactionCounter = readRequest.getTransactionCounter();
 -                readRequestSizes.put(transactionCounter, readRequest.getSize());
 +        if(msg instanceof DF1SymbolMessageFrame) {
 +            DF1SymbolMessageFrame frame = (DF1SymbolMessageFrame) msg;
 +            if(frame.getCommand() instanceof DF1UnprotectedReadRequest) {
 +                DF1UnprotectedReadRequest unprotectedReadRequest = (DF1UnprotectedReadRequest) frame.getCommand();
 +                int transactionCounter = unprotectedReadRequest.getTransactionCounter();
 +                readRequestSizes.put(transactionCounter, unprotectedReadRequest.getSize());
              }
          }
  
diff --cc sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
index e35fcce,4a52437..08b7b89
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
@@@ -24,10 -24,8 +24,9 @@@ import org.apache.plc4x.java.api.PlcCon
  import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
  import org.apache.plc4x.java.api.messages.PlcReadRequest;
  import org.apache.plc4x.java.api.messages.PlcReadResponse;
 +import org.junit.jupiter.api.Test;
  
  import java.util.concurrent.TimeUnit;
- 
  /**
   * TODO write comment
   *
@@@ -36,11 -34,12 +35,12 @@@
   */
  public class EndToEndTest {
  
 -    @org.junit.Test
 +    @Test
      public void helloDf1() {
-         try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial///dev/cu.usbserial-AL065SUZ")) {
+         try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial:///COM4")) {
              PlcReadRequest request = plcConnection.readRequestBuilder()
                  .addItem("erstes", "17:INTEGER")
+                 .addItem("zweites", "17:INTEGER")
                  .build();
  
              PlcReadResponse response = request.execute().get(1, TimeUnit.SECONDS);


[plc4x] 01/06: Matching pattern tests for serial/DF1 added

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f7ee2597f410f024770353c7e026586229ae3892
Author: v.emmert <v....@pragmaticminds.de>
AuthorDate: Wed Aug 7 10:39:51 2019 +0200

    Matching pattern tests for serial/DF1 added
---
 plc4j/examples/hello-world-plc4x/pom.xml           |  1 +
 .../org/apache/plc4x/java/df1/DF1PlcDriver.java    |  2 +-
 .../apache/plc4x/java/df1/DF1PlcDriverTest.java    | 26 +++++++++++++++++++
 .../plc4x/protocol/df1/BenchmarkManualDf1.java     | 30 ++++++++++++----------
 .../apache/plc4x/protocol/df1/EndToEndTest.java    |  2 +-
 5 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/plc4j/examples/hello-world-plc4x/pom.xml b/plc4j/examples/hello-world-plc4x/pom.xml
index e3295da..eaee6fe 100644
--- a/plc4j/examples/hello-world-plc4x/pom.xml
+++ b/plc4j/examples/hello-world-plc4x/pom.xml
@@ -91,6 +91,7 @@
           <usedDependencies combine.children="append">
             <usedDependency>org.apache.plc4x:plc4j-driver-s7</usedDependency>
             <usedDependency>org.apache.plc4x:plc4j-driver-simulated</usedDependency>
+            <usedDependency>org.apache.plc4x.sandbox:test-java-df1-driver</usedDependency>
             <usedDependency>org.slf4j:log4j-over-slf4j</usedDependency>
           </usedDependencies>
         </configuration>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
index fd8e0c6..1988e72 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/DF1PlcDriver.java
@@ -31,7 +31,7 @@ import java.util.regex.Pattern;
 public class DF1PlcDriver implements PlcDriver {
 
     public static final Pattern INET_ADDRESS_PATTERN = Pattern.compile("tcp://(?<host>[\\w.]+)(:(?<port>\\d*))?");
-    public static final Pattern SERIAL_PATTERN = Pattern.compile("serial://(?<serialDefinition>((?!/\\d).)*)");
+    public static final Pattern SERIAL_PATTERN = Pattern.compile("serial://(?<serialDefinition>/?[a-zA-Z0-9/]*)");
     public static final Pattern DF1_URI_PATTERN = Pattern.compile("^df1:(" + INET_ADDRESS_PATTERN + "|" + SERIAL_PATTERN + ")/?" + "(?<params>\\?.*)?");
 
     @Override
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java
new file mode 100644
index 0000000..ae9e470
--- /dev/null
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java
@@ -0,0 +1,26 @@
+package org.apache.plc4x.java.df1;
+
+import org.junit.Test;
+
+import java.util.regex.Matcher;
+
+import static org.apache.plc4x.java.df1.DF1PlcDriver.DF1_URI_PATTERN;
+import static org.apache.plc4x.java.df1.DF1PlcDriver.SERIAL_PATTERN;
+import static org.junit.Assert.*;
+
+public class DF1PlcDriverTest {
+
+    @Test
+    public void matchExpression() {
+        Matcher matcher = SERIAL_PATTERN.matcher("serial:///COM4");
+
+        assertTrue(matcher.matches());
+    }
+
+    @Test
+    public void matchExpression2() {
+        Matcher matcher = DF1_URI_PATTERN.matcher("df1:serial:///COM4");
+
+        assertTrue(matcher.matches());
+    }
+}
\ No newline at end of file
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
index c2571fe..3174170 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/BenchmarkManualDf1.java
@@ -76,18 +76,18 @@ public class BenchmarkManualDf1 {
 //        }
 
 
-        byte[] rData = {0x10, 0x02, 0x00, 0x09, 0x41, 0x00, 0x01, 0x00, 0x1F, 0x1F, 0x10, 0x03, 0x1A, 0x2B};
-
- /*       DF1SymbolIO df1SymbolIO = new DF1SymbolIO();
-        DF1Symbol packet;
-        ReadBuffer rBuf = new ReadBuffer(rData);
-        int statusWord = (rData[7]<<8) + rData[6];
-        DF1Command messageCommand = new DF1Command((short)rData[5]); //,(short)statusWord);
-        DF1SymbolMessageFrameStart messageStart = new DF1SymbolMessageFrameStart((short)rData[3],(short)rData[2], messageCommand);
-        packet = df1SymbolIO.parse(rBuf, (short) (rData.length-12), messageStart);
-
-        System.out.println("x: " + packet);
-        System.exit(0);
+//        byte[] rData = {0x10, 0x02, 0x00, 0x09, 0x41, 0x00, 0x01, 0x00, 0x1F, 0x1F, 0x10, 0x03, 0x1A, 0x2B};
+//
+//        DF1SymbolIO df1SymbolIO = new DF1SymbolIO();
+//        DF1Symbol packet;
+//        ReadBuffer rBuf = new ReadBuffer(rData);
+//        int statusWord = (rData[7]<<8) + rData[6];
+//        DF1Command messageCommand = new DF1Command((short)rData[5]); //,(short)statusWord);
+//        DF1SymbolMessageFrameStart messageStart = new DF1SymbolMessageFrameStart((short)rData[3],(short)rData[2], messageCommand);
+//        packet = df1SymbolIO.parse(rBuf, (short) (rData.length-12), messageStart);
+//
+//        System.out.println("x: " + packet);
+//        System.exit(0);
 
 
 
@@ -105,7 +105,9 @@ public class BenchmarkManualDf1 {
 //        System.out.println(comPort.getWriteTimeout());
 
 
-        DF1SymbolIO df1message = new DF1SymbolIO();
+        System.exit(0);
+
+//        DF1SymbolIO df1message = new DF1SymbolIO();
 
 
         byte[] c_STX = {0x02};
@@ -198,7 +200,7 @@ public class BenchmarkManualDf1 {
             System.out.print(Integer.toHexString(c_RCV2) + " | "); }
         System.out.println("");
 
-        comPort.closePort();*/
+        comPort.closePort();
 
     }
 
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
index 954d092..3a5f96d 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/protocol/df1/EndToEndTest.java
@@ -37,7 +37,7 @@ public class EndToEndTest {
 
     @org.junit.Test
     public void helloDf1() {
-        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial///dev/cu.usbserial-AL065SUZ")) {
+        try (PlcConnection plcConnection = new PlcDriverManager().getConnection("df1:serial:///COM4")) {
             PlcReadRequest request = plcConnection.readRequestBuilder()
                 .addItem("erstes", "17:INTEGER")
                 .build();


[plc4x] 06/06: - Updated the current Netty driver prototype to work with the latest code generation updates.

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 817085a1793afd95c06c6eb1ac139bd5e1519886
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 7 16:58:30 2019 +0200

    - Updated the current Netty driver prototype to work with the latest code generation updates.
---
 plc4j/protocols/pom.xml                            |  2 +-
 .../java/org/apache/plc4x/java/df1/Df1Field.java   | 18 ++++++++++
 .../java/df1/connection/SerialDf1Connection.java   | 40 ++++++++++++++++++++--
 .../plc4x/java/df1/protocol/Df1Protocol.java       | 32 ++++++++---------
 .../plc4x/java/df1/protocol/Plc4XDf1Protocol.java  |  7 ++--
 .../apache/plc4x/java/df1/DF1PlcDriverTest.java    | 26 +++++++++++---
 6 files changed, 96 insertions(+), 29 deletions(-)

diff --git a/plc4j/protocols/pom.xml b/plc4j/protocols/pom.xml
index 6f776b7..1543985 100644
--- a/plc4j/protocols/pom.xml
+++ b/plc4j/protocols/pom.xml
@@ -36,7 +36,7 @@
   <modules>
     <module>driver-bases</module>
 
-    <module>ads</module>
+    <!--module>ads</module-->
     <module>delta-v</module>
     <module>ethernet-ip</module>
     <module>iso-on-tcp</module>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java
index 43c8e4e..7ca0536 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/Df1Field.java
@@ -1,3 +1,21 @@
+/*
+ * 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.java.df1;
 
 import org.apache.plc4x.java.api.model.PlcField;
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java
index de8803e..4a07499 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/connection/SerialDf1Connection.java
@@ -19,23 +19,59 @@
 package org.apache.plc4x.java.df1.connection;
 
 import io.netty.channel.*;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
+import org.apache.plc4x.java.base.connection.ChannelFactory;
 import org.apache.plc4x.java.base.connection.SerialChannelFactory;
 import org.apache.plc4x.java.base.events.ConnectedEvent;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.df1.protocol.Df1Protocol;
 import org.apache.plc4x.java.df1.protocol.Plc4XDf1Protocol;
 import org.apache.plc4x.java.df1.util.Df1FieldHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.CompletableFuture;
 
 public class SerialDf1Connection extends BaseDf1Connection implements PlcReader, PlcWriter {
 
+    private static final Logger logger = LoggerFactory.getLogger(SerialDf1Connection.class);
+
+    private short localAddr;
+    private short remoteAddr;
+
     public SerialDf1Connection(String comPortName, String params) {
-        super(new SerialChannelFactory(comPortName));
+        this(new SerialChannelFactory(comPortName), params);
+    }
+
+    public SerialDf1Connection(ChannelFactory channelFactory, String params) {
+        super(channelFactory, false);
+        this.localAddr = (short) 0x00;
+        this.remoteAddr = (short) 0x09;
+
+        // Override some of the settings, if they are asked for.
+        if (!StringUtils.isEmpty(params)) {
+            for (String param : params.split("&")) {
+                String[] paramElements = param.split("=");
+                String paramName = paramElements[0];
+                if (paramElements.length == 2) {
+                    String paramValue = paramElements[1];
+                    switch (paramName) {
+                        case "local-addr":
+                            this.localAddr = Short.parseShort(paramValue);
+                            break;
+                        case "remote-addr":
+                            this.remoteAddr = Short.parseShort(paramValue);
+                            break;
+                        default:
+                            logger.debug("Unknown parameter {} with value {}", paramName, paramValue);
+                    }
+                }
+            }
+        }
     }
 
     @Override
@@ -65,7 +101,7 @@ public class SerialDf1Connection extends BaseDf1Connection implements PlcReader,
                         }
                     }
                 });
-                pipeline.addLast(new Df1Protocol());
+                pipeline.addLast(new Df1Protocol(localAddr, remoteAddr));
                 pipeline.addLast(new Plc4XDf1Protocol());
             }
         };
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
index 92ae07d..9818ceb 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Df1Protocol.java
@@ -23,6 +23,7 @@ import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.ChannelHandlerContext;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.base.PlcByteToMessageCodec;
+import org.apache.plc4x.java.df1.DF1Command;
 import org.apache.plc4x.java.df1.DF1Symbol;
 import org.apache.plc4x.java.df1.DF1SymbolMessageFrame;
 import org.apache.plc4x.java.df1.DF1UnprotectedReadRequest;
@@ -36,17 +37,18 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
+public class Df1Protocol extends PlcByteToMessageCodec<DF1Command> {
 
     private static final Logger logger = LoggerFactory.getLogger(Df1Protocol.class);
 
+    private final short localAddr;
+    private final short remoteAddr;
     private final DF1SymbolIO df1SymbolIO;
 
-    private Map<Integer, Short> readRequestSizes;
-
-    public Df1Protocol() {
+    public Df1Protocol(short localAddr, short remoteAddr) {
+        this.localAddr = localAddr;
+        this.remoteAddr = remoteAddr;
         df1SymbolIO = new DF1SymbolIO();
-        readRequestSizes = new HashMap<>();
     }
 
     @Override
@@ -54,21 +56,14 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
     }
 
     @Override
-    protected void encode(ChannelHandlerContext ctx, DF1Symbol msg, ByteBuf out) throws Exception {
-        // Remember the size of the request as we need this to decode the response.
-        if(msg instanceof DF1SymbolMessageFrame) {
-            DF1SymbolMessageFrame frame = (DF1SymbolMessageFrame) msg;
-            if(frame.getCommand() instanceof DF1UnprotectedReadRequest) {
-                DF1UnprotectedReadRequest unprotectedReadRequest = (DF1UnprotectedReadRequest) frame.getCommand();
-                int transactionCounter = unprotectedReadRequest.getTransactionCounter();
-                readRequestSizes.put(transactionCounter, unprotectedReadRequest.getSize());
-            }
-        }
+    protected void encode(ChannelHandlerContext ctx, DF1Command msg, ByteBuf out) throws Exception {
+        // Create a new df1 frame for transmitting the command
+        DF1SymbolMessageFrame frame = new DF1SymbolMessageFrame(remoteAddr, localAddr, msg);
 
         // Serialize the message
         // TODO: Create the buffer with the correct size.
         WriteBuffer writeBuffer = new WriteBuffer(100);
-        df1SymbolIO.serialize(writeBuffer, msg);
+        df1SymbolIO.serialize(writeBuffer, frame);
         byte[] data = writeBuffer.getData();
 
         // Send the serialized data
@@ -106,7 +101,7 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
                             break;
                         }
                         case (short) 0x41: {
-                            int transactionCounter = in.getUnsignedShort(6);
+                            /*int transactionCounter = in.getUnsignedShort(6);
                             if(!readRequestSizes.containsKey(transactionCounter)) {
                                 logger.warn("Unknown transaction counter: {}", transactionCounter);
                                 if (logger.isDebugEnabled()) {
@@ -119,7 +114,8 @@ public class Df1Protocol extends PlcByteToMessageCodec<DF1Symbol> {
                             size = readRequestSizes.remove(transactionCounter);
                             if(in.readableBytes() < 8 + size) {
                                 return;
-                            }
+                            }*/
+                            // TODO: Let's just assume all is good for now ...
                             break;
                         }
                     }
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
index 98a7a38..d8be305 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/java/df1/protocol/Plc4XDf1Protocol.java
@@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Symbol, PlcRequestContainer> {
+public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Command, PlcRequestContainer> {
 
     private static final Logger logger = LoggerFactory.getLogger(Plc4XDf1Protocol.class);
 
@@ -48,8 +48,7 @@ public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Symbol, PlcReq
                 int transactionId = this.transactionId.getAndIncrement();
                 logger.debug("Creating request for offset {}, with length {} and transaction id {}", address, size, transactionId);
                 // TODO: differentiate commands
-                DF1SymbolMessageFrameStart frameStart = new DF1SymbolMessageFrameStart((short) 0x09, (short) 0x00, new DF1ReadRequest((short) 0x00, transactionId, address, size));
-                out.add(frameStart);
+                out.add(new DF1UnprotectedReadRequest((short) 0x00, transactionId, address, size));
             }
         } else {
             throw new IllegalStateException("This should not happen!");
@@ -57,7 +56,7 @@ public class Plc4XDf1Protocol extends PlcMessageToMessageCodec<DF1Symbol, PlcReq
     }
 
     @Override
-    protected void decode(ChannelHandlerContext ctx, DF1Symbol msg, List<Object> out) throws Exception {
+    protected void decode(ChannelHandlerContext ctx, DF1Command msg, List<Object> out) throws Exception {
         System.out.println("Hello");
     }
 
diff --git a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java
index ae9e470..fa58a5e 100644
--- a/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java
+++ b/sandbox/test-java-df1-driver/src/test/java/org/apache/plc4x/java/df1/DF1PlcDriverTest.java
@@ -1,12 +1,30 @@
+/*
+ * 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.java.df1;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 import java.util.regex.Matcher;
 
 import static org.apache.plc4x.java.df1.DF1PlcDriver.DF1_URI_PATTERN;
 import static org.apache.plc4x.java.df1.DF1PlcDriver.SERIAL_PATTERN;
-import static org.junit.Assert.*;
 
 public class DF1PlcDriverTest {
 
@@ -14,13 +32,13 @@ public class DF1PlcDriverTest {
     public void matchExpression() {
         Matcher matcher = SERIAL_PATTERN.matcher("serial:///COM4");
 
-        assertTrue(matcher.matches());
+        Assertions.assertTrue(matcher.matches());
     }
 
     @Test
     public void matchExpression2() {
         Matcher matcher = DF1_URI_PATTERN.matcher("df1:serial:///COM4");
 
-        assertTrue(matcher.matches());
+        Assertions.assertTrue(matcher.matches());
     }
 }
\ No newline at end of file