You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2018/01/26 17:42:26 UTC

[incubator-plc4x] 01/01: first ADS Model implementation

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

sruehl pushed a commit to branch feature/Beckhoff_ADS_protocol
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit d25f18a368ece344f8ef5ab945745c2f38002269
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Fri Jan 26 18:42:19 2018 +0100

    first ADS Model implementation
---
 plc4j/protocols/{pom.xml => ads/LINKS.md}          |  24 +--
 plc4j/protocols/ads/pom.xml                        |  77 +++++++
 .../commands/ADSAddDeviceNotificationRequest.java  | 130 ++++++++++++
 .../commands/ADSAddDeviceNotificationResponse.java |  66 ++++++
 .../ADSDeleteDeviceNotificationRequest.java        |  54 +++++
 .../ADSDeleteDeviceNotificationResponse.java       |  53 +++++
 .../commands/ADSDeviceNotificationRequest.java     | 186 ++++++++++++++++
 .../commands/ADSDeviceNotificationResponse.java    |  39 ++++
 .../model/commands/ADSReadDeviceInfoRequest.java   |  40 ++++
 .../model/commands/ADSReadDeviceInfoResponse.java  | 100 +++++++++
 .../java/ads/model/commands/ADSReadRequest.java    |  79 +++++++
 .../java/ads/model/commands/ADSReadResponse.java   |  76 +++++++
 .../ads/model/commands/ADSReadStateRequest.java    |  41 ++++
 .../ads/model/commands/ADSReadStateResponse.java   |  53 +++++
 .../ads/model/commands/ADSReadWriteRequest.java    | 102 +++++++++
 .../ads/model/commands/ADSReadWriteResponse.java   |  78 +++++++
 .../ads/model/commands/ADSWriteControlRequest.java |  90 ++++++++
 .../model/commands/ADSWriteControlResponse.java    |  52 +++++
 .../java/ads/model/commands/ADSWriteRequest.java   |  89 ++++++++
 .../java/ads/model/commands/ADSWriteResponse.java  |  54 +++++
 .../plc4x/java/ads/model/generic/ADSData.java      |  31 +++
 .../plc4x/java/ads/model/generic/AMSHeader.java    | 234 +++++++++++++++++++++
 .../plc4x/java/ads/model/generic/AMSTCPHeader.java |  77 +++++++
 .../plc4x/java/ads/model/generic/AMSTCPPaket.java  |  66 ++++++
 .../plc4x/java/ads/model/util/ByteReadable.java    |  31 +++
 .../plc4x/java/ads/model/util/ByteValue.java       |  42 ++++
 plc4j/protocols/pom.xml                            |   1 +
 27 files changed, 1942 insertions(+), 23 deletions(-)

diff --git a/plc4j/protocols/pom.xml b/plc4j/protocols/ads/LINKS.md
similarity index 53%
copy from plc4j/protocols/pom.xml
copy to plc4j/protocols/ads/LINKS.md
index 415d22a..9b619c9 100644
--- a/plc4j/protocols/pom.xml
+++ b/plc4j/protocols/ads/LINKS.md
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <!--
 
   Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,25 +16,4 @@
   limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.plc4x</groupId>
-    <artifactId>plc4j</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>plc4j-protocols</artifactId>
-  <packaging>pom</packaging>
-
-  <name>PLC4J: Protocols</name>
-  <description>Wrapper project for all PLC4J protocol implementations.</description>
-
-  <modules>
-    <module>s7</module>
-  </modules>
-
-</project>
\ No newline at end of file
+SPEC ADS: https://infosys.beckhoff.com/english.php?content=../content/1033/tcadsamsspec/html/tcadsamsspec_intro.htm
diff --git a/plc4j/protocols/ads/pom.xml b/plc4j/protocols/ads/pom.xml
new file mode 100644
index 0000000..273084c
--- /dev/null
+++ b/plc4j/protocols/ads/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.plc4x</groupId>
+    <artifactId>plc4j-protocols</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4j-protocol-ads</artifactId>
+  <name>PLC4J: Protocol: ADS</name>
+  <description>Implementation of a PLC4X driver able to speak with Beckhoff ADS devices using the ADS protocol.</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-core</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <scope>runtime</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-buffer</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-transport</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationRequest.java
new file mode 100644
index 0000000..389c0b6
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationRequest.java
@@ -0,0 +1,130 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * A notification is created in an ADS device.
+ * <p>
+ * Note: We recommend to announce not more then 550 notifications per device.
+ * You can increase the payload by organizing the data in structures.
+ */
+public class ADSAddDeviceNotificationRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Index Group of the data, which should be sent per notification.
+     */
+    final IndexGroup indexGroup;
+    /**
+     * 4 bytes	Index Offset of the data, which should be sent per notification.
+     */
+    final IndexOffset indexOffset;
+    /**
+     * 4 bytes	Length of data in bytes, which should be sent per notification.
+     */
+    final Length length;
+    /**
+     * 4 bytes	See description of the structure ADSTRANSMODE at the ADS-DLL.
+     */
+    final TransmissionMode transmissionMode;
+    /**
+     * 4 bytes	At the latest after this time, the ADS Device Notification is called. The unit is 1ms.
+     */
+    final MaxDelay maxDelay;
+    /**
+     * 4 bytes	The ADS server checks if the value changes in this time slice. The unit is 1ms
+     */
+    final CycleTime cycleTime;
+    /**
+     * 16bytes	Must be set to 0
+     */
+    final Reserved reserved = Reserved.INSTANCE;
+
+    public ADSAddDeviceNotificationRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, IndexGroup indexGroup, IndexOffset indexOffset, Length length, TransmissionMode transmissionMode, MaxDelay maxDelay, CycleTime cycleTime) {
+        super(amstcpHeader, amsHeader);
+        this.indexGroup = indexGroup;
+        this.indexOffset = indexOffset;
+        this.length = length;
+        this.transmissionMode = transmissionMode;
+        this.maxDelay = maxDelay;
+        this.cycleTime = cycleTime;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(indexGroup, indexOffset, length, transmissionMode, maxDelay, cycleTime, reserved);
+    }
+
+    class IndexGroup extends ByteValue {
+        public IndexGroup(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class IndexOffset extends ByteValue {
+        public IndexOffset(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+  class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+   class TransmissionMode extends ByteValue {
+        public TransmissionMode(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    static class MaxDelay extends ByteValue {
+        public MaxDelay(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    static class CycleTime extends ByteValue {
+        public CycleTime(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+     static class Reserved extends ByteValue {
+
+        static final Reserved INSTANCE = new Reserved();
+
+        public Reserved() {
+            super((byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00);
+            assertLength(16);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationResponse.java
new file mode 100644
index 0000000..33297e2
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSAddDeviceNotificationResponse.java
@@ -0,0 +1,66 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * A notification is created in an ADS device.
+ */
+public class ADSAddDeviceNotificationResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final Result result;
+
+    /**
+     * 4 bytes	Handle of notification
+     */
+    final NotificationHandle notificationHandle;
+
+    public ADSAddDeviceNotificationResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result, NotificationHandle notificationHandle) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+        this.notificationHandle = notificationHandle;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result, notificationHandle);
+    }
+
+   class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+   class NotificationHandle extends ByteValue {
+        public NotificationHandle(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationRequest.java
new file mode 100644
index 0000000..61970e4
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationRequest.java
@@ -0,0 +1,54 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * One before defined notification is deleted in an ADS device.
+ */
+public class ADSDeleteDeviceNotificationRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Handle of notification
+     */
+    final NotificationHandle notificationHandle;
+
+    public ADSDeleteDeviceNotificationRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, NotificationHandle notificationHandle) {
+        super(amstcpHeader, amsHeader);
+        this.notificationHandle = notificationHandle;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(notificationHandle);
+    }
+
+
+   class NotificationHandle extends ByteValue {
+        public NotificationHandle(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationResponse.java
new file mode 100644
index 0000000..b9536d2
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeleteDeviceNotificationResponse.java
@@ -0,0 +1,53 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * One before defined notification is deleted in an ADS device.
+ */
+public class ADSDeleteDeviceNotificationResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final Result result;
+
+    public ADSDeleteDeviceNotificationResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result);
+    }
+
+   class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationRequest.java
new file mode 100644
index 0000000..c99bf12
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationRequest.java
@@ -0,0 +1,186 @@
+/*
+ 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.ads.model.commands;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * Data will carry forward independently from an ADS device to a Client
+ * <p>
+ * The data which are transfered at the Device Notification  are multiple nested into one another. The Notification Stream contains an array with elements of type AdsStampHeader. This array again contains elements of type AdsNotificationSample.
+ */
+public class ADSDeviceNotificationRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Size of data in byte.
+     */
+    final Length length;
+    /**
+     * 4 bytes	Number of elements of type AdsStampHeader.
+     */
+    final Stamps stamps;
+    /**
+     * n bytes	Array with elements of type AdsStampHeader.
+     */
+    final AdsStampHeader adsStampHeader;
+
+    public ADSDeviceNotificationRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Length length, Stamps stamps, AdsStampHeader adsStampHeader) {
+        super(amstcpHeader, amsHeader);
+        this.length = length;
+        this.stamps = stamps;
+        this.adsStampHeader = adsStampHeader;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(length, stamps, adsStampHeader);
+    }
+
+    class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Stamps extends ByteValue {
+        public Stamps(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class AdsStampHeader extends ByteValue {
+
+        /**
+         * 8 bytes	The timestamp is coded after the Windos FILETIME format. I.e. the value contains the number of the nano seconds, which passed since 1.1.1601. In addition, the local time change is not considered. Thus the time stamp is present as universal Coordinated time (UTC).
+         */
+        final TimeStamp timeStamp;
+        /**
+         * 4 bytes	Number of elements of type AdsNotificationSample.
+         */
+        final Samples samples;
+        /**
+         * n bytes	Array with elements of type AdsNotificationSample.
+         */
+        final AdsNotificationSample adsNotificationSample;
+
+        public AdsStampHeader(TimeStamp timeStamp, Samples samples, AdsNotificationSample adsNotificationSample) {
+            super(new byte[]{0x00});
+            this.timeStamp = timeStamp;
+            this.samples = samples;
+            this.adsNotificationSample = adsNotificationSample;
+        }
+
+        class TimeStamp extends ByteValue {
+
+            public TimeStamp(byte... value) {
+                super(value);
+                assertLength(8);
+            }
+        }
+
+        class Samples extends ByteValue {
+
+            public Samples(byte... value) {
+                super(value);
+                assertLength(4);
+            }
+        }
+
+        class AdsNotificationSample extends ByteValue {
+
+            /**
+             * 4 Bytes	Handle of notification.
+             */
+            final NotificationHandle notificationHandle;
+            /**
+             * 4 Bytes	Size of data range in bytes.
+             */
+            final SampleSize sampleSize;
+            /**
+             * n Bytes	Data
+             */
+            final Data data;
+
+            public AdsNotificationSample(NotificationHandle notificationHandle, SampleSize sampleSize, Data data) {
+                super((byte) 0x00);
+                this.notificationHandle = notificationHandle;
+                this.sampleSize = sampleSize;
+                this.data = data;
+            }
+
+            @Override
+            public byte[] getBytes() {
+                return getByteBuf().array();
+            }
+
+            @Override
+            public ByteBuf getByteBuf() {
+                return buildByteBuff(notificationHandle, sampleSize, data);
+            }
+
+            class NotificationHandle extends ByteValue {
+
+                public NotificationHandle(byte... value) {
+                    super(value);
+                    assertLength(4);
+                }
+            }
+
+            /**
+             * Notice: If your handle becomes invalid, one notification without data will be send once as advice.
+             */
+            class InvalidationNotificationHandle extends NotificationHandle {
+                public InvalidationNotificationHandle() {
+                }
+            }
+
+            class SampleSize extends ByteValue {
+
+                public SampleSize(byte... value) {
+                    super(value);
+                    assertLength(4);
+                }
+            }
+
+            class Data extends ByteValue {
+
+                public Data(byte... value) {
+                    super(value);
+                }
+            }
+        }
+
+        @Override
+        public byte[] getBytes() {
+            return getByteBuf().array();
+        }
+
+        @Override
+        public ByteBuf getByteBuf() {
+            return buildByteBuff(timeStamp, samples, adsNotificationSample);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationResponse.java
new file mode 100644
index 0000000..509b57e
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSDeviceNotificationResponse.java
@@ -0,0 +1,39 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+
+/**
+ * Data will carry forward independently from an ADS device to a Client
+ */
+public class ADSDeviceNotificationResponse extends AMSTCPPaket {
+
+    private ADSDeviceNotificationResponse() {
+        super(null, null);
+        // There is no {@link ADSDeviceNotificationResponse} specified
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return ADSData.EMPTY;
+    }
+
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoRequest.java
new file mode 100644
index 0000000..45ff657
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoRequest.java
@@ -0,0 +1,40 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+
+/**
+ * Reads the name and the version number of the ADS device.
+ *
+ * No additional data required
+ */
+public class ADSReadDeviceInfoRequest extends AMSTCPPaket {
+    public ADSReadDeviceInfoRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader) {
+        super(amstcpHeader, amsHeader);
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return ADSData.EMPTY;
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoResponse.java
new file mode 100644
index 0000000..b2c5385
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadDeviceInfoResponse.java
@@ -0,0 +1,100 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * Reads the name and the version number of the ADS device.
+ */
+public class ADSReadDeviceInfoResponse extends AMSTCPPaket {
+    /**
+     * 4 bytes	ADS error number.
+     */
+    final Result result;
+    /**
+     * Version	1 byte	Major version number
+     */
+    final MajorVersion majorVersion;
+    /**
+     * Version	1 byte	Minor version number
+     */
+    final MinorVersion minorVersion;
+    /**
+     * Build	2 bytes	Build number
+     */
+    final Version version;
+    /**
+     * Name	16 bytes	Name of ADS device
+     */
+    final Device device;
+
+    public ADSReadDeviceInfoResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result, MajorVersion majorVersion, MinorVersion minorVersion, Version version, Device device) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+        this.majorVersion = majorVersion;
+        this.minorVersion = minorVersion;
+        this.version = version;
+        this.device = device;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result, majorVersion, minorVersion, version, device);
+    }
+
+    static class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    static class MajorVersion extends ByteValue {
+        public MajorVersion(byte... value) {
+            super(value);
+            assertLength(1);
+        }
+    }
+
+    static class MinorVersion extends ByteValue {
+        public MinorVersion(byte... value) {
+            super(value);
+            assertLength(1);
+        }
+    }
+
+    static class Version extends ByteValue {
+        public Version(byte... value) {
+            super(value);
+            assertLength(2);
+        }
+    }
+
+    static class Device extends ByteValue {
+        public Device(byte... value) {
+            super(value);
+            assertLength(16);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadRequest.java
new file mode 100644
index 0000000..a5746d6
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadRequest.java
@@ -0,0 +1,79 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Read data can be read from an ADS device.  The data are addressed by the Index Group and the Index Offset
+ */
+public class ADSReadRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Index Group of the data which should be read.
+     */
+    final IndexGroup indexGroup;
+
+    /**
+     * 4 bytes	Index Offset of the data which should be read.
+     */
+    final IndexOffset indexOffset;
+
+    /**
+     * 4 bytes	Length of the data (in bytes) which should be read.
+     */
+    final Length length;
+
+    public ADSReadRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, IndexGroup indexGroup, IndexOffset indexOffset, Length length) {
+        super(amstcpHeader, amsHeader);
+        this.indexGroup = indexGroup;
+        this.indexOffset = indexOffset;
+        this.length = length;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(indexGroup, indexOffset, length);
+    }
+
+    class IndexGroup extends ByteValue {
+        public IndexGroup(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class IndexOffset extends ByteValue {
+        public IndexOffset(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+   class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadResponse.java
new file mode 100644
index 0000000..8be3bb8
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadResponse.java
@@ -0,0 +1,76 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Read data can be read from an ADS device
+ */
+public class ADSReadResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final Result result;
+    /**
+     * 4 bytes	Length of data which are supplied back.
+     */
+    final Length length;
+    /**
+     * n bytes	Data which are supplied back.
+     */
+    final Data data;
+
+    public ADSReadResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result, Length length, Data data) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+        this.length = length;
+        this.data = data;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result, length, data);
+    }
+
+    class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateRequest.java
new file mode 100644
index 0000000..15de095
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateRequest.java
@@ -0,0 +1,41 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+
+/**
+ * Reads the ADS status and the device status of an ADS device.
+ * <p>
+ * No additional data required
+ */
+public class ADSReadStateRequest extends AMSTCPPaket {
+    public ADSReadStateRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader) {
+        super(amstcpHeader, amsHeader);
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return ADSData.EMPTY;
+    }
+
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateResponse.java
new file mode 100644
index 0000000..ed334c7
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadStateResponse.java
@@ -0,0 +1,53 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * Reads the ADS status and the device status of an ADS device.
+ */
+public class ADSReadStateResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final Result result;
+
+    public ADSReadStateResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result);
+    }
+
+    class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteRequest.java
new file mode 100644
index 0000000..db1a7eb
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteRequest.java
@@ -0,0 +1,102 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Read Write data will be written to an ADS device. Additionally, data can be read from the ADS device.
+ * <p>
+ * The data which can be read are addressed by the Index Group and the Index Offset
+ */
+public class ADSReadWriteRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Index Group, in which the data should be written.
+     */
+    final IndexGroup indexGroup;
+    /**
+     * 4 bytes	Index Offset, in which the data should be written
+     */
+    final IndexOffset indexOffset;
+    /**
+     * 4 bytes	Length of data in bytes, which should be read.
+     */
+    final ReadLength readLength;
+    /**
+     * 4 bytes	Length of data in bytes, which should be written
+     */
+    final WriteLength writeLength;
+    /**
+     * n bytes	Data which are written in the ADS device.
+     */
+    final Data data;
+
+    public ADSReadWriteRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, IndexGroup indexGroup, IndexOffset indexOffset, ReadLength readLength, WriteLength writeLength, Data data) {
+        super(amstcpHeader, amsHeader);
+        this.indexGroup = indexGroup;
+        this.indexOffset = indexOffset;
+        this.readLength = readLength;
+        this.writeLength = writeLength;
+        this.data = data;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return ADSData.EMPTY;
+    }
+
+    class IndexGroup extends ByteValue {
+        public IndexGroup(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class IndexOffset extends ByteValue {
+        public IndexOffset(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class ReadLength extends ByteValue {
+        public ReadLength(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class WriteLength extends ByteValue {
+        public WriteLength(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteResponse.java
new file mode 100644
index 0000000..3b0409c
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSReadWriteResponse.java
@@ -0,0 +1,78 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Read Write data will be written to an ADS device. Additionally, data can be read from the ADS device.
+ */
+public class ADSReadWriteResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final Result result;
+
+    /**
+     * 4 bytes	Length of data which are supplied back.
+     */
+    final Length length;
+
+    /**
+     * n bytes	Data which are supplied back.
+     */
+    final Data data;
+
+    public ADSReadWriteResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, Result result, Length length, Data data) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+        this.length = length;
+        this.data = data;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return ADSData.EMPTY;
+    }
+
+    class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlRequest.java
new file mode 100644
index 0000000..b3c42ab
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlRequest.java
@@ -0,0 +1,90 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * Changes the ADS status and the device status of an ADS device.
+ * Additionally it is possible to send data to the ADS device to transfer further information.
+ * These data were not analysed from the current ADS devices (PLC, NC, ...)
+ */
+public class ADSWriteControlRequest extends AMSTCPPaket {
+
+    /**
+     * 2 bytes	New ADS status (see data type ADSSTATE of the ADS-DLL).
+     */
+    final ADSState adsState;
+    /**
+     * 2 bytes	New device status.
+     */
+    final DeviceState deviceState;
+    /**
+     * 4 bytes	Length of data in byte.
+     */
+    final Length length;
+    /**
+     * n bytes	Additional data which are sent to the ADS device
+     */
+    final Data data;
+
+    public ADSWriteControlRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, ADSState adsState, DeviceState deviceState, Length length, Data data) {
+        super(amstcpHeader, amsHeader);
+        this.adsState = adsState;
+        this.deviceState = deviceState;
+        this.length = length;
+        this.data = data;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(adsState, deviceState, length, data);
+    }
+
+    class ADSState extends ByteValue {
+        public ADSState(byte... value) {
+            super(value);
+            assertLength(2);
+        }
+    }
+
+    class DeviceState extends ByteValue {
+        public DeviceState(byte... value) {
+            super(value);
+            assertLength(2);
+        }
+    }
+
+    class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlResponse.java
new file mode 100644
index 0000000..04b1032
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteControlResponse.java
@@ -0,0 +1,52 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * Changes the ADS status and the device status of an ADS device.
+ */
+public class ADSWriteControlResponse extends AMSTCPPaket {
+    /**
+     * 4 bytes	ADS error number
+     */
+    final ADSReadResponse.Result result;
+
+    public ADSWriteControlResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, ADSReadResponse.Result result) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result);
+    }
+
+    class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteRequest.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteRequest.java
new file mode 100644
index 0000000..ac7b48d
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteRequest.java
@@ -0,0 +1,89 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Write data can be written to an ADS device. The data are addressed by the Index Group and the Index Offset.
+ */
+public class ADSWriteRequest extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	Index Group in which the data should be written
+     */
+    final IndexGroup indexGroup;
+    /**
+     * 4 bytes	Index Offset, in which the data should be written
+     */
+    final IndexOffset indexOffset;
+    /**
+     * 4 bytes	Length of data in bytes which are written
+     */
+    final Length length;
+    /**
+     * n bytes	Data which are written in the ADS device.
+     */
+    final Data data;
+
+    public ADSWriteRequest(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, IndexGroup indexGroup, IndexOffset indexOffset, Length length, Data data) {
+        super(amstcpHeader, amsHeader);
+        this.indexGroup = indexGroup;
+        this.indexOffset = indexOffset;
+        this.length = length;
+        this.data = data;
+    }
+
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(indexGroup, indexOffset, length, data);
+    }
+
+    class IndexGroup extends ByteValue {
+        public IndexGroup(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class IndexOffset extends ByteValue {
+        public IndexOffset(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Length extends ByteValue {
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteResponse.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteResponse.java
new file mode 100644
index 0000000..a440d92
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/commands/ADSWriteResponse.java
@@ -0,0 +1,54 @@
+/*
+ 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.ads.model.commands;
+
+import org.apache.plc4x.java.ads.model.generic.ADSData;
+import org.apache.plc4x.java.ads.model.generic.AMSHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPHeader;
+import org.apache.plc4x.java.ads.model.generic.AMSTCPPaket;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * With ADS Write data can be written to an ADS device.
+ */
+public class ADSWriteResponse extends AMSTCPPaket {
+
+    /**
+     * 4 bytes	ADS error number
+     */
+    final ADSReadResponse.Result result;
+
+    public ADSWriteResponse(AMSTCPHeader amstcpHeader, AMSHeader amsHeader, ADSReadResponse.Result result) {
+        super(amstcpHeader, amsHeader);
+        this.result = result;
+    }
+
+    @Override
+    public ADSData getAdsData() {
+        return buildADSData(result);
+    }
+
+    class Result extends ByteValue {
+        public Result(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/ADSData.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/ADSData.java
new file mode 100644
index 0000000..4fd766b
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/ADSData.java
@@ -0,0 +1,31 @@
+/*
+ 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.ads.model.generic;
+
+import org.apache.plc4x.java.ads.model.util.ByteReadable;
+
+/**
+ * ADS Data	n bytes	The ADS data range contains the parameter of the single ADS commands. The structure of the data array depends on the ADS command. Some ADS commands require no additional data.
+ */
+@FunctionalInterface
+public interface ADSData extends ByteReadable {
+
+    ADSData EMPTY = () -> new byte[0];
+
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSHeader.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSHeader.java
new file mode 100644
index 0000000..2dfd667
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSHeader.java
@@ -0,0 +1,234 @@
+/*
+ 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.ads.model.generic;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.apache.plc4x.java.ads.model.util.ByteReadable;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+import java.nio.ByteBuffer;
+
+/**
+ * AMS Header	32 bytes	The AMS/TCP-Header contains the addresses of the transmitter and receiver. In addition the AMS error code , the ADS command Id and some other information.
+ */
+public class AMSHeader implements ByteReadable {
+    /**
+     * This is the AMSNetId of the station, for which the packet is intended. Remarks see below.
+     */
+    final AMSNetId targetAmsNetId;
+    /**
+     * This is the AMSPort of the station, for which the packet is intended.
+     */
+    final AMSPort targetAmsPort;
+    /**
+     * This contains the AMSNetId of the station, from which the packet was sent.
+     */
+    final AMSNetId sourceAmsNetId;
+    /**
+     * This contains the AMSPort of the station, from which the packet was sent.
+     */
+    final AMSPort sourceAmsPort;
+
+    final Command commandId;
+
+    final State stateFlags;
+
+    final DataLength dataLength;
+
+    final Error code;
+
+    final Invoke invokeId;
+
+    final Data nData;
+
+    public AMSHeader(AMSNetId targetAmsNetId, AMSPort targetAmsPort, AMSNetId sourceAmsNetId, AMSPort sourceAmsPort, Command commandId, State stateFlags, DataLength dataLength, Error code, Invoke invokeId, Data nData) {
+        this.targetAmsNetId = targetAmsNetId;
+        this.targetAmsPort = targetAmsPort;
+        this.sourceAmsNetId = sourceAmsNetId;
+        this.sourceAmsPort = sourceAmsPort;
+        this.commandId = commandId;
+        this.stateFlags = stateFlags;
+        this.dataLength = dataLength;
+        this.code = code;
+        this.invokeId = invokeId;
+        this.nData = nData;
+    }
+
+    /**
+     * The AMSNetId consists of 6 bytes and addresses the transmitter or receiver. One possible AMSNetId would be e.g.. 172.16.17.10.1.1. The storage arrangement in this example is as follows:
+     * <p>
+     * _____0     1     2     3     4     5
+     * __+-----------------------------------+
+     * 0 | 127 |  16 |  17 |  10 |   1 |   1 |
+     * __+-----------------------------------+
+     * <p>
+     * <p>
+     * The AMSNetId is purely logical and has usually no relation to the IP address. The AMSNetId is configurated at the target system. At the PC for this the TwinCAT System Control is used. If you use other hardware, see the considering documentation for notes about settings of the AMS NetId.
+     */
+    public static class AMSNetId extends ByteValue {
+
+        public AMSNetId(int octed1, int octed2, int octed3, int octed4, int octed5, int octed6) {
+            super((byte) octed1, (byte) octed2, (byte) octed3, (byte) octed4, (byte) octed5, (byte) octed6);
+        }
+
+        public AMSNetId(byte... value) {
+            super(value);
+            assertLength(6);
+        }
+    }
+
+    public static class AMSPort extends ByteValue {
+
+        public AMSPort(int port) {
+            super(ByteBuffer.allocate(2).putInt(port).array());
+        }
+
+        public AMSPort(byte... value) {
+            super(value);
+            assertLength(2);
+        }
+    }
+
+    /**
+     * 2 bytes	see below.
+     */
+    enum Command implements ByteReadable {
+        Invalid(0x0000),
+        ADS_Read_Device_Info(0x0001),
+        ADS_Read(0x0002),
+        ADS_Write(0x0003),
+        ADS_Read_State(0x0004),
+        ADS_Write_Control(0x0005),
+        ADS_Add_Device_Notification(0x0006),
+        ADS_Delete_Device_Notification(0x0007),
+        ADS_Device_Notification(0x0008),
+        ADS_Read_Write(0x0009),
+        /**
+         * Other commands are not defined or are used internally. Therefore the Command Id  is only allowed to contain the above enumerated values!
+         */
+        UNKNOWN(0xffff);
+        final byte[] value;
+
+        Command(int value) {
+            this.value = ByteBuffer.allocate(4).putInt(value).array();
+        }
+
+        @Override
+        public byte[] getBytes() {
+            return value;
+        }
+    }
+
+    /**
+     * 2 bytes	see below.
+     * <p>
+     * State Flags
+     * Flag     Description
+     * 0x0001	0: Request / 1: Response
+     * 0x0004	ADS command
+     * The first bit marks, whether it´s a request or response. The third bit must be set to 1, to exchange data with ADS commands. The other bits are not defined or were used for other internal purposes.
+     * <p>
+     * Therefore the other bits must be set to 0!
+     * <p>
+     * Flag     Description
+     * 0x000x	TCP Protocol
+     * 0x004x	UDP Protocol
+     * Bit number 7 marks, if it should be transfered with TCP or UDP.
+     */
+    enum State implements ByteReadable {
+        ADS_REQUEST_TCP(0x0004),
+        ADS_RESPONSE_TCP(0x0005),
+        ADS_REQUEST_UDP(0x0044),
+        ADS_RESPONSE_UDP(0x0045);
+        final byte[] value;
+
+        State(int value) {
+            this.value = ByteBuffer.allocate(4).putInt(value).array();
+        }
+
+        @Override
+        public byte[] getBytes() {
+            return value;
+        }
+    }
+
+    /**
+     * 4 bytes	Size of the data range. The unit is byte.
+     */
+    static class DataLength extends ByteValue {
+        public DataLength(int length) {
+            super(ByteBuffer.allocate(4).putInt(length).array());
+        }
+
+        public DataLength(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    /**
+     * 4 bytes	AMS error number. See ADS Return Codes.
+     */
+    static class Error extends ByteValue {
+        public Error(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    /**
+     * 4 bytes	Free usable 32 bit array. Usually this array serves to send an Id. This Id makes is possible to assign a received response to a request, which was sent before.
+     */
+    static class Invoke extends ByteValue {
+        public Invoke(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+
+    /**
+     * bytes	Data range. The data range contains the parameter of the considering ADS commands.
+     */
+    static class Data extends ByteValue {
+        public Data(byte... value) {
+            super(value);
+        }
+    }
+
+    @Override
+    public byte[] getBytes() {
+        return getByteBuf().array();
+    }
+
+    @Override
+    public ByteBuf getByteBuf() {
+        return Unpooled.buffer()
+            .writeBytes(targetAmsNetId.getByteBuf())
+            .writeBytes(targetAmsPort.getByteBuf())
+            .writeBytes(sourceAmsNetId.getByteBuf())
+            .writeBytes(sourceAmsPort.getByteBuf())
+            .writeBytes(commandId.getByteBuf())
+            .writeBytes(stateFlags.getByteBuf())
+            .writeBytes(dataLength.getByteBuf())
+            .writeBytes(code.getByteBuf())
+            .writeBytes(invokeId.getByteBuf())
+            .writeBytes(nData.getByteBuf());
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPHeader.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPHeader.java
new file mode 100644
index 0000000..6f04d6b
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPHeader.java
@@ -0,0 +1,77 @@
+/*
+ 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.ads.model.generic;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.apache.plc4x.java.ads.model.util.ByteReadable;
+import org.apache.plc4x.java.ads.model.util.ByteValue;
+
+/**
+ * AMS/TCP Header	6 bytes	contains the length of the data packet.
+ */
+public class AMSTCPHeader implements ByteReadable {
+
+    final Reserved reserved;
+
+    final Length length;
+
+    public AMSTCPHeader(Length length) {
+        this.reserved = Reserved.CONSTANT;
+        this.length = length;
+    }
+
+    @Override
+    public byte[] getBytes() {
+        return getByteBuf().array();
+    }
+
+    @Override
+    public ByteBuf getByteBuf() {
+        return Unpooled.buffer()
+            .writeBytes(reserved.getByteBuf())
+            .writeBytes(length.getByteBuf());
+    }
+
+    /**
+     * Size: 2 bytes
+     * These bytes must be set to 0.
+     */
+    static class Reserved extends ByteValue {
+
+        static final Reserved CONSTANT = new Reserved();
+
+        public Reserved() {
+            super((byte) 0x00, (byte) 0x00);
+            assertLength(2);
+        }
+    }
+
+    /**
+     * Size: 4 bytes
+     * This array contains the length of the data packet. It consists of the AMS-Header and the enclosed ADS data. The unit is bytes.
+     */
+    static class Length extends ByteValue {
+
+        public Length(byte... value) {
+            super(value);
+            assertLength(4);
+        }
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPPaket.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPPaket.java
new file mode 100644
index 0000000..08896ca
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/generic/AMSTCPPaket.java
@@ -0,0 +1,66 @@
+/*
+ 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.ads.model.generic;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.apache.plc4x.java.ads.model.util.ByteReadable;
+
+public abstract class AMSTCPPaket implements ByteReadable {
+    final AMSTCPHeader amstcpHeader;
+
+    final AMSHeader amsHeader;
+
+    public AMSTCPPaket(AMSTCPHeader amstcpHeader, AMSHeader amsHeader) {
+        this.amstcpHeader = amstcpHeader;
+        this.amsHeader = amsHeader;
+    }
+
+    public AMSTCPHeader getAmstcpHeader() {
+        return amstcpHeader;
+    }
+
+    public AMSHeader getAmsHeader() {
+        return amsHeader;
+    }
+
+    public abstract ADSData getAdsData();
+
+    @Override
+    public byte[] getBytes() {
+        return getByteBuf().array();
+    }
+
+    @Override
+    public ByteBuf getByteBuf() {
+        return buildByteBuff(amstcpHeader, amsHeader, getAdsData());
+    }
+
+    protected ADSData buildADSData(ByteReadable... byteReadables) {
+        return () -> buildByteBuff(byteReadables).array();
+    }
+
+    protected ByteBuf buildByteBuff(ByteReadable... byteReadables) {
+        ByteBuf buffer = Unpooled.buffer();
+        for (ByteReadable byteReadable : byteReadables) {
+            buffer.writeBytes(byteReadable.getByteBuf());
+        }
+        return buffer;
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteReadable.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteReadable.java
new file mode 100644
index 0000000..9dcb118
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteReadable.java
@@ -0,0 +1,31 @@
+/*
+ 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.ads.model.util;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+
+public interface ByteReadable {
+
+    byte[] getBytes();
+
+    default ByteBuf getByteBuf() {
+        return Unpooled.buffer().writeBytes(getBytes());
+    }
+}
diff --git a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteValue.java b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteValue.java
new file mode 100644
index 0000000..2725c8a
--- /dev/null
+++ b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/util/ByteValue.java
@@ -0,0 +1,42 @@
+/*
+ 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.ads.model.util;
+
+import java.util.Objects;
+
+public class ByteValue implements ByteReadable {
+
+    final byte[] value;
+
+    public ByteValue(byte... value) {
+        Objects.requireNonNull(value);
+        this.value = value;
+    }
+
+    protected void assertLength(int length) {
+        if (value.length != length) {
+            throw new IllegalArgumentException("Expected length " + length + " got " + value.length);
+        }
+    }
+
+    @Override
+    public byte[] getBytes() {
+        return value;
+    }
+}
diff --git a/plc4j/protocols/pom.xml b/plc4j/protocols/pom.xml
index 415d22a..b3ec6a8 100644
--- a/plc4j/protocols/pom.xml
+++ b/plc4j/protocols/pom.xml
@@ -35,6 +35,7 @@
   <description>Wrapper project for all PLC4J protocol implementations.</description>
 
   <modules>
+    <module>ads</module>
     <module>s7</module>
   </modules>
 

-- 
To stop receiving notification emails like this one, please contact
sruehl@apache.org.