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 2020/01/19 11:25:14 UTC

[plc4x] branch develop updated: - Added a method ARRAY_SIZE_IN_BYTES to the Static helper, which can calculate the size in bytes for array fields with complex type content.develop - Fixed a naming typo in the serial transport modules artifactId - Adjusted the java language template to make it possible to address the discriminator fields directly. - Refactored the Modbus spec to correctly address the discriminator values directly instead of using one "discriminator" field. - Added the skeleton for the Modbus driver.

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

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


The following commit(s) were added to refs/heads/develop by this push:
     new 55549dc  - Added a method ARRAY_SIZE_IN_BYTES to the Static helper, which can calculate the size in bytes for array fields with complex type content.develop - Fixed a naming typo in the serial transport modules artifactId - Adjusted the java language template to make it possible to address the discriminator fields directly. - Refactored the Modbus spec to correctly address the discriminator values directly instead of using one "discriminator" field. - Added the skeleton for the M [...]
55549dc is described below

commit 55549dce6ca900b246d5ba2c50df850eb0dafdd5
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Sun Jan 19 12:25:05 2020 +0100

    - Added a method ARRAY_SIZE_IN_BYTES to the Static helper, which can calculate the size in bytes for array fields with complex type content.develop
    - Fixed a naming typo in the serial transport modules artifactId
    - Adjusted the java language template to make it possible to address the discriminator fields directly.
    - Refactored the Modbus spec to correctly address the discriminator values directly instead of using one "discriminator" field.
    - Added the skeleton for the Modbus driver.
---
 .../language/java/JavaLanguageTemplateHelper.java  |   4 +
 .../plc4x/java/spi/generation/StaticHelper.java    |  17 +++
 plc4j/transports/serial/pom.xml                    |   2 +-
 .../main/resources/protocols/modbus/modbus.mspec   |  42 +++----
 sandbox/pom.xml                                    |   2 +
 sandbox/test-java-modbus-driver/pom.xml            | 129 +++++++++++++++++++++
 .../org/apache/plc4x/java/modbus/ModbusDriver.java |  50 ++++++++
 .../java/modbus/config/ModbusConfiguration.java    |  38 ++++++
 .../services/org.apache.plc4x.java.api.PlcDriver   |  19 +++
 .../org/apache/plc4x/java/modbus/ModbusIOTest.java |  29 +++++
 .../test/resources/testsuite/ModbusTestsuite.xml   |  46 ++++++++
 11 files changed, 356 insertions(+), 22 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 47ac6f2..2d3b660 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
@@ -645,6 +645,10 @@ public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHel
             sb.append(")");
             return sb.toString();
         }
+        // Discriminator values have to be handled a little differently.
+        else if(vl.getName().equals("DISCRIMINATOR_VALUES")) {
+            return "_value.getDiscriminatorValues()[" + vl.getIndex() + "]";
+        }
         // All uppercase names are not fields, but utility methods.
         else if(vl.getName().equals(vl.getName().toUpperCase())) {
             StringBuilder sb = new StringBuilder(vl.getName());
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
index 21b8e12..696e83a 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
@@ -22,6 +22,23 @@ import java.util.Collection;
 
 public class StaticHelper {
 
+    public static int ARRAY_SIZE_IN_BYTES(Object obj) {
+        if (obj.getClass().isArray() && !obj.getClass().getComponentType().isPrimitive()) {
+            Object[] arr = (Object[]) obj;
+            int numBytes = 0;
+            for (Object element : arr) {
+                if(element instanceof Message) {
+                    numBytes += ((Message) element).getLengthInBytes();
+                } else {
+                    throw new RuntimeException(
+                        "Array elements for array size in bytes must implement Message interface");
+                }
+            }
+            return numBytes;
+        }
+        throw new RuntimeException("Unable to calculate array size in bytes for type " + obj.getClass().getName());
+    }
+
     public static int COUNT(Object obj) {
         if (obj.getClass().isArray()) {
             if(obj.getClass().getComponentType() != null && obj.getClass().getComponentType().isPrimitive()) {
diff --git a/plc4j/transports/serial/pom.xml b/plc4j/transports/serial/pom.xml
index 864a879..7db53a1 100644
--- a/plc4j/transports/serial/pom.xml
+++ b/plc4j/transports/serial/pom.xml
@@ -27,7 +27,7 @@
     <version>0.7.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>plc4j-trannsport-serial</artifactId>
+  <artifactId>plc4j-transport-serial</artifactId>
   <name>PLC4J: Transports: Serial</name>
   <description>Base classes needed to implement plc4x drivers based on Serial connections.</description>
 
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index b23a810..cb3d44c 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -56,8 +56,8 @@
 ]
 
 [discriminatedType 'ModbusPDU' [bit 'response']
-    [discriminator  uint 7      'function']
-    [simple         bit         'error']
+    [implicit       uint 7      'function'  'DISCRIMINATOR_VALUES[1]']
+    [implicit       bit         'error'     'DISCRIMINATOR_VALUES[0]']
     [typeSwitch 'error','function','response'
         ['true'                     ModbusPduError
             [simple     uint 8      'exceptionCode']
@@ -69,7 +69,7 @@
             [simple     uint 16     'quantity']
         ]
         ['false','0x02','true'      ModbusPduReadDiscreteInputsResponse
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -78,7 +78,7 @@
             [simple     uint 16     'quantity']
         ]
         ['false','0x01','true'      ModbusPduReadCoilsResponse
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -94,7 +94,7 @@
         ['false','0x0F','false'     ModbusPduWriteMultipleCoilsRequest
             [simple     uint 16     'startingAddress']
             [simple     uint 16     'quantity']
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
         ['false','0x0F','true'      ModbusPduWriteMultipleCoilsResponse
@@ -108,7 +108,7 @@
             [simple     uint 16     'quantity']
         ]
         ['false','0x04','true'      ModbusPduReadInputRegistersResponse
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -117,7 +117,7 @@
             [simple     uint 16     'quantity']
         ]
         ['false','0x03','true'      ModbusPduReadHoldingRegistersResponse
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -133,7 +133,7 @@
         ['false','0x10','false'     ModbusPduWriteMultipleRegistersRequest
             [simple     uint 16     'startingAddress']
             [simple     uint 16     'quantity']
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
         ['false','0x10','true'      ModbusPduWriteMultipleRegistersResponse
@@ -146,11 +146,11 @@
             [simple     uint 16     'readQuantity']
             [simple     uint 16     'writeStartingAddress']
             [simple     uint 16     'writeQuantity']
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
         ['false','0x17','true'      ModbusPduReadWriteMultipleRegistersResponse
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -169,27 +169,27 @@
             [simple     uint 16     'fifoPointerAddress']
         ]
         ['false','0x18','true'      ModbusPduReadFifoQueueResponse
-            [implicit   uint 16     'byteCount'     'fifoValue.lengthInBytes + 2']
-            [implicit   uint 16     'fifoCount'     'fifoValue.lengthInBytes / 2']
+            [implicit   uint 16     'byteCount'     '(COUNT(fifoValue) * 2) + 2']
+            [implicit   uint 16     'fifoCount'     '(COUNT(fifoValue) * 2) / 2']
             [array      uint 16     'fifoValue'     count   'fifoCount']
         ]
 
         // File Record Access
         ['false','0x14','false'     ModbusPduReadFileRecordRequest
-            [implicit   uint 8      'byteCount'                 'items.lengthInBytes']
+            [implicit   uint 8      'byteCount'                 'ARRAY_SIZE_IN_BYTES(items)']
             [array      ModbusPduReadFileRecordRequestItem      'items' length 'byteCount']
         ]
         ['false','0x14','true'      ModbusPduReadFileRecordResponse
-            [implicit   uint 8      'byteCount'                 'items.lengthInBytes']
+            [implicit   uint 8      'byteCount'                 'ARRAY_SIZE_IN_BYTES(items)']
             [array      ModbusPduReadFileRecordResponseItem     'items' length 'byteCount']
         ]
 
         ['false','0x15','false'     ModbusPduWriteFileRecordRequest
-            [implicit   uint 8      'byteCount'                 'items.lengthInBytes']
+            [implicit   uint 8      'byteCount'                 'ARRAY_SIZE_IN_BYTES(items)']
             [array      ModbusPduWriteFileRecordRequestItem     'items' length 'byteCount']
         ]
         ['false','0x15','true'      ModbusPduWriteFileRecordResponse
-            [implicit   uint 8      'byteCount'                 'items.lengthInBytes']
+            [implicit   uint 8      'byteCount'                 'ARRAY_SIZE_IN_BYTES(items)']
             [array      ModbusPduWriteFileRecordResponseItem    'items' length 'byteCount']
         ]
 
@@ -217,7 +217,7 @@
         ['false','0x0C','false'     ModbusPduGetComEventLogRequest
         ]
         ['false','0x0C','true'      ModbusPduGetComEventLogResponse
-            [implicit   uint 8      'byteCount'    'events.lengthInBytes + 6']
+            [implicit   uint 8      'byteCount'    'COUNT(events) + 6']
             [simple     uint 16     'status']
             [simple     uint 16     'eventCount']
             [simple     uint 16     'messageCount']
@@ -228,7 +228,7 @@
         ]
         ['false','0x11','true'      ModbusPduReportServerIdResponse
             // TODO: This is not specified very well in the spec ... investigate.
-            [implicit   uint 8      'byteCount'     'value.lengthInBytes']
+            [implicit   uint 8      'byteCount'     'COUNT(value)']
             [array      int 8       'value'         count   'byteCount']
         ]
 
@@ -247,7 +247,7 @@
 ]
 
 [type 'ModbusPduReadFileRecordResponseItem'
-    [implicit   uint 8     'dataLength'     'data.lengthInBytes + 1']
+    [implicit   uint 8     'dataLength'     '(COUNT(data) * 2) + 1']
     [simple     uint 8     'referenceType']
     [array      uint 16    'data'           length  'dataLength - 1']
 ]
@@ -256,7 +256,7 @@
     [simple     uint 8     'referenceType']
     [simple     uint 16    'fileNumber']
     [simple     uint 16    'recordNumber']
-    [implicit   uint 16    'recordLength'   'recordData.lengthInBytes / 2']
+    [implicit   uint 16    'recordLength'   '(COUNT(recordData) * 2) / 2']
     [array      uint 16    'recordData'     length  'recordLength * 2']
 ]
 
@@ -264,6 +264,6 @@
     [simple     uint 8     'referenceType']
     [simple     uint 16    'fileNumber']
     [simple     uint 16    'recordNumber']
-    [implicit   uint 16    'recordLength'   'recordData.lengthInBytes / 2']
+    [implicit   uint 16    'recordLength'   '(COUNT(recordData) * 2) / 2']
     [array      uint 16    'recordData'     length  'recordLength * 2']
 ]
diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 438ae87..20b0e85 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -47,6 +47,8 @@
     <!--module>test-java-knxnetip-driver-passive</module-->
     <module>test-java-knxnetip-shared</module>
 
+    <module>test-java-modbus-driver</module>
+
     <module>test-java-s7-driver</module>
     <!--module>test-java-s7-driver-passive</module-->
 
diff --git a/sandbox/test-java-modbus-driver/pom.xml b/sandbox/test-java-modbus-driver/pom.xml
new file mode 100644
index 0000000..63f51a2
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x.sandbox</groupId>
+    <artifactId>plc4x-sandbox</artifactId>
+    <version>0.7.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-java-modbus-driver</artifactId>
+
+  <name>Sandbox: Test Generated Modbus Driver</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>modbus</protocolName>
+              <languageName>java</languageName>
+              <outputFlavor>read-write</outputFlavor>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-spi</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-tcp</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-serial</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-raw-socket</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-test-utils</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-pcap-socket</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-build-utils-language-java</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-protocols-modbus</artifactId>
+      <version>0.7.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
new file mode 100644
index 0000000..908865b
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/ModbusDriver.java
@@ -0,0 +1,50 @@
+/*
+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.modbus;
+
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.PlcDriver;
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+
+public class ModbusDriver implements PlcDriver {
+
+    public static final int MODBUS_IP_PORT = 502;
+
+    @Override
+    public String getProtocolCode() {
+        return null;
+    }
+
+    @Override
+    public String getProtocolName() {
+        return null;
+    }
+
+    @Override
+    public PlcConnection getConnection(String url) throws PlcConnectionException {
+        return null;
+    }
+
+    @Override
+    public PlcConnection getConnection(String url, PlcAuthentication authentication) throws PlcConnectionException {
+        return null;
+    }
+
+}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java
new file mode 100644
index 0000000..a423b66
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java
@@ -0,0 +1,38 @@
+/*
+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.modbus.config;
+
+import org.apache.plc4x.java.modbus.ModbusDriver;
+import org.apache.plc4x.java.spi.configuration.Configuration;
+import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration;
+
+public class ModbusConfiguration implements Configuration, TcpTransportConfiguration {
+
+    @Override
+    public int getDefaultPort() {
+        return ModbusDriver.MODBUS_IP_PORT;
+    }
+
+    @Override
+    public String toString() {
+        return "Configuration{" +
+            '}';
+    }
+
+}
diff --git a/sandbox/test-java-modbus-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.api.PlcDriver b/sandbox/test-java-modbus-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.api.PlcDriver
new file mode 100644
index 0000000..abed59a
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/src/main/resources/META-INF/services/org.apache.plc4x.java.api.PlcDriver
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.plc4x.java.modbus.ModbusDriver
diff --git a/sandbox/test-java-modbus-driver/src/test/java/org/apache/plc4x/java/modbus/ModbusIOTest.java b/sandbox/test-java-modbus-driver/src/test/java/org/apache/plc4x/java/modbus/ModbusIOTest.java
new file mode 100644
index 0000000..60c67b8
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/src/test/java/org/apache/plc4x/java/modbus/ModbusIOTest.java
@@ -0,0 +1,29 @@
+/*
+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.modbus;
+
+import org.apache.plc4x.test.protocol.ProtocolTestsuiteRunner;
+
+public class ModbusIOTest extends ProtocolTestsuiteRunner {
+
+    public ModbusIOTest() {
+        super("/testsuite/ModbusTestsuite.xml");
+    }
+
+}
diff --git a/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml b/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml
new file mode 100644
index 0000000..83a38dd
--- /dev/null
+++ b/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml
@@ -0,0 +1,46 @@
+<?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>Modbus</name>
+
+  <!--testcase>
+    <name>Search Request</name>
+    <raw>06100201000e0801c0a82a46ef8e</raw>
+    <root-type>KNXNetIPMessage</root-type>
+    <xml>
+      <SearchRequest className="org.apache.plc4x.java.knxnetip.readwrite.SearchRequest">
+        <hpaiIDiscoveryEndpoint>
+          <hostProtocolCode>1</hostProtocolCode>
+          <ipAddress>
+            <addr>
+              <addr>192</addr>
+              <addr>168</addr>
+              <addr>42</addr>
+              <addr>70</addr>
+            </addr>
+          </ipAddress>
+          <ipPort>61326</ipPort>
+        </hpaiIDiscoveryEndpoint>
+      </SearchRequest>
+    </xml>
+  </testcase-->
+
+</test:testsuite>
\ No newline at end of file