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 2019/12/11 13:44:00 UTC

[plc4x] branch feature/ams_ads_mpsec updated: moved to IO from generated code

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

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


The following commit(s) were added to refs/heads/feature/ams_ads_mpsec by this push:
     new 005c85b  moved to IO from generated code
005c85b is described below

commit 005c85b531b5ab1dea5243dc3de5208d14cdcd8a
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Dec 11 14:43:49 2019 +0100

    moved to IO from generated code
---
 sandbox/test-java-amsads-driver/pom.xml            |   4 +
 .../java/amsads/protocol/Ads2PayloadProtocol.java  | 341 ++-------------------
 .../amsads/protocol/Payload2SerialProtocol.java    | 170 ++++------
 .../java/amsads/protocol/Payload2TcpProtocol.java  |  58 +++-
 .../java/amsads/protocol/Plc4x2AdsProtocol.java    | 180 ++---------
 .../java/amsads/protocol/util/DigestUtil.java      |  13 -
 .../amsads/protocol/util/LittleEndianDecoder.java  |   2 +-
 .../amsads/protocol/util/LittleEndianEncoder.java  |   2 +-
 8 files changed, 161 insertions(+), 609 deletions(-)

diff --git a/sandbox/test-java-amsads-driver/pom.xml b/sandbox/test-java-amsads-driver/pom.xml
index 62e732d..7ef796e 100644
--- a/sandbox/test-java-amsads-driver/pom.xml
+++ b/sandbox/test-java-amsads-driver/pom.xml
@@ -86,6 +86,10 @@
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-configuration2</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.github.snksoft</groupId>
+      <artifactId>crc</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>io.netty</groupId>
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Ads2PayloadProtocol.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Ads2PayloadProtocol.java
index 3e29980..4926d17 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Ads2PayloadProtocol.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Ads2PayloadProtocol.java
@@ -22,20 +22,15 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
-import org.apache.commons.configuration2.Configuration;
-import org.apache.commons.configuration2.SystemConfiguration;
-import org.apache.plc4x.java.amsads.protocol.exception.AdsProtocolOverflowException;
-import org.apache.plc4x.java.amsads.readwrite.AmsHeader;
-import org.apache.plc4x.java.amsads.readwrite.AmsNetId;
+import org.apache.plc4x.java.amsads.protocol.exception.AdsException;
 import org.apache.plc4x.java.amsads.readwrite.AmsPacket;
-import org.apache.plc4x.java.amsads.readwrite.State;
-import org.apache.plc4x.java.amsads.readwrite.types.CommandId;
-import org.graalvm.compiler.nodes.Invoke;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsPacketIO;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -44,16 +39,6 @@ public class Ads2PayloadProtocol extends MessageToMessageCodec<ByteBuf, AmsPacke
 
     private static final Logger LOGGER = LoggerFactory.getLogger(Ads2PayloadProtocol.class);
 
-    private static final Configuration CONF = new SystemConfiguration();
-    private static final long MAX_NUM_STAMPS = CONF.getLong("plc4x.ads2payloadprotocol.max_num_stamps", 512L);
-    private static final long MAX_NUM_SAMPLES = CONF.getLong("plc4x.ads2payloadprotocol.max_num_samples", 1024L);
-    private static final long ADS_READ_COMMAND_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_read_command_max_bytes", 134217728L);
-    private static final long ADS_WRITE_COMMAND_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_write_command_max_bytes", 134217728L);
-    private static final long ADS_WRITE_CONTROL_COMMAND_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_write_control_command_max_bytes", 134217728L);
-    private static final long ADS_NOTIFICATION_SAMPLE_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_notification_sample_max_bytes", 134217728L);
-    private static final long ADS_READ_WRITE_COMMAND_REQUEST_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_read_write_command_request_max_bytes", 134217728L);
-    private static final long ADS_READ_WRITE_COMMAND_RESPONSE_MAX_BYTES = CONF.getLong("plc4x.ads2payloadprotocol.ads_read_write_command_response_max_bytes", 134217728L);
-
     private final ConcurrentMap<Long, AmsPacket> requests;
 
     public Ads2PayloadProtocol() {
@@ -68,320 +53,40 @@ public class Ads2PayloadProtocol extends MessageToMessageCodec<ByteBuf, AmsPacke
     }
 
     @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, AmsPacket amsPacket, List<Object> out) {
+    protected void encode(ChannelHandlerContext channelHandlerContext, AmsPacket amsPacket, List<Object> out) throws AdsException {
         LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
         Long invokeId = amsPacket.getAmsHeader().getInvokeId();
         if (invokeId != 0L) {
             requests.put(invokeId, amsPacket);
         }
-        out.add(amsPacket.getByteBuf());
+        WriteBuffer writeBuffer = new WriteBuffer(amsPacket.getLengthInBytes(), true);
+        try {
+            AmsPacketIO.serialize(writeBuffer, amsPacket);
+        } catch (ParseException e) {
+            throw new AdsException(invokeId, e);
+        }
+        out.add(writeBuffer.getData());
     }
 
     @Override
-    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) {
+    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws AdsException {
         if (byteBuf == Unpooled.EMPTY_BUFFER) {
             // Cleanup...
             reset();
             return;
         }
         LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
-        AmsNetId targetAmsNetId = AmsNetId.of(byteBuf);
-        AmsPort targetAmsPort = AmsPort.of(byteBuf);
-        AmsNetId sourceAmsNetId = AmsNetId.of(byteBuf);
-        AmsPort sourceAmsPort = AmsPort.of(byteBuf);
-        CommandId commandId = CommandId.of(byteBuf);
-        State stateId = State.of(byteBuf);
-        DataLength dataLength = DataLength.of(byteBuf);
-        AmsError errorCode = AmsError.of(byteBuf);
-        Invoke invoke = Invoke.of(byteBuf);
-        AmsPacket correlatedAmsPacket = requests.remove(invoke);
-        if (correlatedAmsPacket != null) {
-            LOGGER.debug("Correlated packet received {}", correlatedAmsPacket);
-        }
-        if (dataLength.getAsLong() > Integer.MAX_VALUE) {
-            throw new AdsProtocolOverflowException(Integer.class, dataLength.getAsLong());
-        }
-        ByteBuf commandBuffer = byteBuf.readBytes((int) dataLength.getAsLong());
-        AmsHeader amsHeader = AmsHeader.of(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, commandId, stateId, dataLength, errorCode, invoke);
-        final AmsPacket amsPacket;
-        switch (commandId) {
-            case INVALID:
-                amsPacket = handleInvalidCommand(commandBuffer, amsHeader);
-                break;
-            case ADS_READ_DEVICE_INFO:
-                amsPacket = handleADSReadDeviceInfoCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_READ:
-                amsPacket = handleADSReadCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_WRITE:
-                amsPacket = handleADSWriteCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_READ_STATE:
-                amsPacket = handleADSReadStateCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_WRITE_CONTROL:
-                amsPacket = handleADSWriteControlCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_ADD_DEVICE_NOTIFICATION:
-                amsPacket = handleADSAddDeviceNotificationCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_DELETE_DEVICE_NOTIFICATION:
-                amsPacket = handADSDeleteDeviceNotificationCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_DEVICE_NOTIFICATION:
-                amsPacket = handleADSDeviceNotificationCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case ADS_READ_WRITE:
-                amsPacket = handleADSReadWriteCommand(stateId, commandBuffer, amsHeader);
-                break;
-            case UNKNOWN:
-            default:
-                amsPacket = handleUnknownCommand(commandBuffer, amsHeader);
-        }
-        LOGGER.debug("Received amsPacket {}", amsPacket);
-        out.add(amsPacket);
-        if (commandBuffer.readableBytes() > 0) {
-            throw new IllegalStateException("Unread bytes left: " + commandBuffer.readableBytes());
-        }
-    }
-
-
-    private AmsPacket handleInvalidCommand(ByteBuf commandBuffer, AmsHeader amsHeader) {
-        return UnknownCommand.of(amsHeader, commandBuffer);
-    }
-
-    private AmsPacket handleADSReadDeviceInfoCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            amsPacket = AdsReadDeviceInfoRequest.of(amsHeader);
-        } else {
-            Result result = Result.of(commandBuffer);
-            MajorVersion majorVersion = MajorVersion.of(commandBuffer);
-            MinorVersion minorVersion = MinorVersion.of(commandBuffer);
-            Version version = Version.of(commandBuffer);
-            Device device = Device.of(commandBuffer);
-            amsPacket = AdsReadDeviceInfoResponse.of(amsHeader, result, majorVersion, minorVersion, version, device);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleADSReadCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            IndexGroup indexGroup = IndexGroup.of(commandBuffer);
-            IndexOffset indexOffset = IndexOffset.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            amsPacket = AdsReadRequest.of(amsHeader, indexGroup, indexOffset, length);
-        } else {
-            Result result = Result.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            if (length.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, length.getAsLong());
-            }
-            if (length.getAsLong() > ADS_READ_COMMAND_MAX_BYTES) {
-                throw new AdsProtocolOverflowException("ADS_READ_COMMAND_MAX_BYTES", ADS_READ_COMMAND_MAX_BYTES, length.getAsLong());
-            }
-            byte[] dataToRead = new byte[(int) length.getAsLong()];
-            commandBuffer.readBytes(dataToRead);
-            Data data = Data.of(dataToRead);
-            amsPacket = AdsReadResponse.of(amsHeader, result, length, data);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleADSWriteCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            IndexGroup indexGroup = IndexGroup.of(commandBuffer);
-            IndexOffset indexOffset = IndexOffset.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            if (length.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, length.getAsLong());
-            }
-            if (length.getAsLong() > ADS_WRITE_COMMAND_MAX_BYTES) {
-                throw new AdsProtocolOverflowException("ADS_WRITE_COMMAND_MAX_BYTES", ADS_WRITE_COMMAND_MAX_BYTES, length.getAsLong());
-            }
-            byte[] dataToRead = new byte[(int) length.getAsLong()];
-            commandBuffer.readBytes(dataToRead);
-            Data data = Data.of(dataToRead);
-            amsPacket = AdsWriteRequest.of(amsHeader, indexGroup, indexOffset, length, data);
-        } else {
-            Result result = Result.of(commandBuffer);
-            amsPacket = AdsWriteResponse.of(amsHeader, result);
-        }
-        return amsPacket;
-    }
-
-
-    private AmsPacket handleADSReadStateCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            amsPacket = AdsReadStateRequest.of(amsHeader);
-        } else {
-            Result result = Result.of(commandBuffer);
-            AdsState adsState = AdsState.of(commandBuffer);
-            DeviceState deviceState = DeviceState.of(commandBuffer);
-            amsPacket = AdsReadStateResponse.of(amsHeader, result, adsState, deviceState);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleADSWriteControlCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            AdsState adsState = AdsState.of(commandBuffer);
-            DeviceState deviceState = DeviceState.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            if (length.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, length.getAsLong());
-            }
-            if (length.getAsLong() > ADS_WRITE_CONTROL_COMMAND_MAX_BYTES) {
-                throw new AdsProtocolOverflowException("ADS_WRITE_CONTROL_COMMAND_MAX_BYTES", ADS_WRITE_CONTROL_COMMAND_MAX_BYTES, length.getAsLong());
-            }
-            byte[] dataToRead = new byte[(int) length.getAsLong()];
-            commandBuffer.readBytes(dataToRead);
-            Data data = Data.of(dataToRead);
-            amsPacket = AdsWriteControlRequest.of(amsHeader, adsState, deviceState, length, data);
-        } else {
-            Result result = Result.of(commandBuffer);
-            amsPacket = AdsWriteControlResponse.of(amsHeader, result);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleADSAddDeviceNotificationCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            IndexGroup indexGroup = IndexGroup.of(commandBuffer);
-            IndexOffset indexOffset = IndexOffset.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            TransmissionMode transmissionMode = TransmissionMode.of(commandBuffer);
-            MaxDelay maxDelay = MaxDelay.of(commandBuffer);
-            CycleTime cycleTime = CycleTime.of(commandBuffer);
-            commandBuffer.skipBytes(AdsAddDeviceNotificationRequest.Reserved.NUM_BYTES);
-            amsPacket = AdsAddDeviceNotificationRequest.of(amsHeader, indexGroup, indexOffset, length, transmissionMode, maxDelay, cycleTime);
-        } else {
-            Result result = Result.of(commandBuffer);
-            NotificationHandle notificationHandle = NotificationHandle.of(commandBuffer);
-            amsPacket = AdsAddDeviceNotificationResponse.of(amsHeader, result, notificationHandle);
-        }
-        return amsPacket;
-    }
 
-    private AmsPacket handADSDeleteDeviceNotificationCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            NotificationHandle notificationHandle = NotificationHandle.of(commandBuffer);
-            amsPacket = AdsDeleteDeviceNotificationRequest.of(amsHeader, notificationHandle);
-        } else {
-            Result result = Result.of(commandBuffer);
-            amsPacket = AdsDeleteDeviceNotificationResponse.of(amsHeader, result);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleADSDeviceNotificationCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            Length length = Length.of(commandBuffer);
-            if (length.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, length.getAsLong());
-            }
-            Stamps stamps = Stamps.of(commandBuffer);
-            if (stamps.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, stamps.getAsLong());
+        byte[] bytes = new byte[byteBuf.readableBytes()];
+        byteBuf.readBytes(bytes);
+        ReadBuffer readBuffer = new ReadBuffer(bytes);
+        while (readBuffer.getPos() < bytes.length) {
+            try {
+                AmsPacket packet = AmsPacketIO.parse(readBuffer);
+                out.add(packet);
+            } catch (Exception e) {
+                LOGGER.warn("Error decoding package: " + e.getMessage());
             }
-            // Note: the length includes the 4 Bytes of stamps which we read already so we substract.
-            ByteBuf adsDeviceNotificationBuffer = commandBuffer.readBytes((int) length.getAsLong() - Stamps.NUM_BYTES);
-            List<AdsStampHeader> adsStampHeaders = new ArrayList<>((int) stamps.getAsLong());
-            if (stamps.getAsLong() > MAX_NUM_STAMPS) {
-                throw new AdsProtocolOverflowException("MAX_NUM_STAMPS", MAX_NUM_STAMPS, length.getAsLong());
-            }
-            for (int i = 1; i <= stamps.getAsLong(); i++) {
-                AdsStampHeader adsStampHeader = handleStampHeader(adsDeviceNotificationBuffer);
-                adsStampHeaders.add(adsStampHeader);
-            }
-            amsPacket = AdsDeviceNotificationRequest.of(amsHeader, length, stamps, adsStampHeaders);
-        } else {
-            amsPacket = UnknownCommand.of(amsHeader, commandBuffer);
-        }
-        return amsPacket;
-    }
-
-    private AdsStampHeader handleStampHeader(ByteBuf adsDeviceNotificationBuffer) {
-        TimeStamp timeStamp = TimeStamp.of(adsDeviceNotificationBuffer);
-        Samples samples = Samples.of(adsDeviceNotificationBuffer);
-
-        List<AdsNotificationSample> adsNotificationSamples = new LinkedList<>();
-        if (samples.getAsLong() > MAX_NUM_SAMPLES) {
-            throw new AdsProtocolOverflowException("MAX_NUM_SAMPLES", MAX_NUM_SAMPLES, samples.getAsLong());
-        }
-        for (int i = 1; i <= samples.getAsLong(); i++) {
-            AdsNotificationSample adsNotificationSample = handleAdsNotificartionSample(adsDeviceNotificationBuffer);
-            adsNotificationSamples.add(adsNotificationSample);
-
         }
-        return AdsStampHeader.of(timeStamp, samples, adsNotificationSamples);
-    }
-
-    private AdsNotificationSample handleAdsNotificartionSample(ByteBuf adsDeviceNotificationBuffer) {
-        NotificationHandle notificationHandle = NotificationHandle.of(adsDeviceNotificationBuffer);
-        SampleSize sampleSize = SampleSize.of(adsDeviceNotificationBuffer);
-        if (sampleSize.getAsLong() > Integer.MAX_VALUE) {
-            throw new AdsProtocolOverflowException(Integer.class, sampleSize.getAsLong());
-        }
-        if (sampleSize.getAsLong() > ADS_NOTIFICATION_SAMPLE_MAX_BYTES) {
-            throw new AdsProtocolOverflowException("ADS_NOTIFICATION_SAMPLE_MAX_BYTES", ADS_NOTIFICATION_SAMPLE_MAX_BYTES, sampleSize.getAsLong());
-        }
-        // TODO: do we need a special marker class for: Notice: If your handle becomes invalid, one notification without data will be send once as advice.
-        byte[] dataToRead = new byte[(int) sampleSize.getAsLong()];
-        adsDeviceNotificationBuffer.readBytes(dataToRead);
-        Data data = Data.of(dataToRead);
-        return AdsNotificationSample.of(notificationHandle, sampleSize, data);
-    }
-
-    private AmsPacket handleADSReadWriteCommand(State stateId, ByteBuf commandBuffer, AmsHeader amsHeader) {
-        AmsPacket amsPacket;
-        if (stateId.isRequest()) {
-            IndexGroup indexGroup = IndexGroup.of(commandBuffer);
-            IndexOffset indexOffset = IndexOffset.of(commandBuffer);
-            ReadLength readLength = ReadLength.of(commandBuffer);
-            if (readLength.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, readLength.getAsLong());
-            }
-            WriteLength writeLength = WriteLength.of(commandBuffer);
-            if (writeLength.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, writeLength.getAsLong());
-            }
-            if (readLength.getAsLong() + writeLength.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, readLength.getAsLong() + writeLength.getAsLong());
-            }
-            if (readLength.getAsLong() > ADS_READ_WRITE_COMMAND_REQUEST_MAX_BYTES) {
-                throw new AdsProtocolOverflowException("ADS_READ_WRITE_COMMAND_REQUEST_MAX_BYTES", ADS_READ_WRITE_COMMAND_REQUEST_MAX_BYTES, readLength.getAsLong());
-            }
-            byte[] dataToRead = new byte[(int) readLength.getAsLong()];
-            commandBuffer.readBytes(dataToRead);
-            Data data = Data.of(dataToRead);
-            amsPacket = AdsReadWriteRequest.of(amsHeader, indexGroup, indexOffset, readLength, writeLength, data);
-        } else {
-            Result result = Result.of(commandBuffer);
-            Length length = Length.of(commandBuffer);
-            if (length.getAsLong() > Integer.MAX_VALUE) {
-                throw new AdsProtocolOverflowException(Integer.class, length.getAsLong());
-            }
-            if (length.getAsLong() > ADS_READ_WRITE_COMMAND_RESPONSE_MAX_BYTES) {
-                throw new AdsProtocolOverflowException("ADS_READ_WRITE_COMMAND_RESPONSE_MAX_BYTES", ADS_READ_WRITE_COMMAND_RESPONSE_MAX_BYTES, length.getAsLong());
-            }
-            byte[] dataToRead = new byte[(int) length.getAsLong()];
-            commandBuffer.readBytes(dataToRead);
-            Data data = Data.of(dataToRead);
-            amsPacket = AdsReadWriteResponse.of(amsHeader, result, length, data);
-        }
-        return amsPacket;
-    }
-
-    private AmsPacket handleUnknownCommand(ByteBuf commandBuffer, AmsHeader amsHeader) {
-        return UnknownCommand.of(amsHeader, commandBuffer);
     }
 }
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2SerialProtocol.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2SerialProtocol.java
index b0a5f4e..939fa17 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2SerialProtocol.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2SerialProtocol.java
@@ -25,10 +25,23 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
 import io.netty.util.ReferenceCountUtil;
 import io.netty.util.concurrent.ScheduledFuture;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.plc4x.java.amsads.protocol.exception.AdsException;
+import org.apache.plc4x.java.amsads.protocol.util.DigestUtil;
+import org.apache.plc4x.java.amsads.readwrite.AmsPacket;
+import org.apache.plc4x.java.amsads.readwrite.AmsSerialFrame;
+import org.apache.plc4x.java.amsads.readwrite.AmsTCPPacket;
+import org.apache.plc4x.java.amsads.readwrite.AmsTcpHeader;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsPacketIO;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsSerialFrameIO;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsTCPPacketIO;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,126 +59,63 @@ public class Payload2SerialProtocol extends MessageToMessageCodec<ByteBuf, ByteB
     private AtomicReference<ScheduledFuture<?>> currentRetryer = new AtomicReference<>();
 
     @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws PlcProtocolPayloadTooBigException {
-        if (amsPacket == Unpooled.EMPTY_BUFFER) {
-            // Cleanup...
-            ScheduledFuture<?> scheduledFuture = currentRetryer.get();
-            if (scheduledFuture != null) {
-                scheduledFuture.cancel(true);
-            }
-            return;
-        }
+    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws AdsException {
         LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
-        int fragmentNumber = fragmentCounter.getAndUpdate(value -> value > 255 ? 0 : ++value);
-        LOGGER.debug("Using fragmentNumber {} for {}", fragmentNumber, amsPacket);
-        UserData userData = UserData.of(amsPacket);
-        if (userData.getCalculatedLength() > 255) {
-            throw new PlcProtocolPayloadTooBigException("ADS/AMS", 255, (int) userData.getCalculatedLength(), amsPacket);
-        }
-        AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(FragmentNumber.of((byte) fragmentNumber), userData);
 
-        MutableInt retryCount = new MutableInt(0);
-        ScheduledFuture<?> oldRetryer = currentRetryer.get();
-        if (oldRetryer != null) {
-            oldRetryer.cancel(false);
+        byte[] bytes = amsPacket.array();
+        AmsPacket amsPacketSer;
+        try {
+            amsPacketSer = AmsPacketIO.parse(new ReadBuffer(bytes, true));
+        } catch (ParseException e) {
+            throw new AdsException(-1L, e);
         }
-        currentRetryer.set(channelHandlerContext.executor().scheduleAtFixedRate(() -> {
-            LOGGER.trace("Retrying {} the {} time", amsSerialFrame, retryCount);
-            int currentTry = retryCount.incrementAndGet();
-            if (currentTry > 10) {
-                // TODO: we might need to throw an exception to potentially cancel upstream waiting
-                channelHandlerContext.writeAndFlush(AmsSerialResetFrame.of(FragmentNumber.of((byte) fragmentNumber)));
-                PlcRuntimeException plcRuntimeException = new PlcRuntimeException("Retry exhausted after " + retryCount + " times");
-                channelHandlerContext.fireExceptionCaught(plcRuntimeException);
-                throw plcRuntimeException;
-            } else {
-                channelHandlerContext.writeAndFlush(amsSerialFrame);
-            }
-        }, 100, 100, TimeUnit.MILLISECONDS));
-        out.add(amsSerialFrame.getByteBuf());
-    }
 
-    @Override
-    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
-        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
-        if (byteBuf.readableBytes() < MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES) {
-            return;
-        }
-        MagicCookie magicCookie = MagicCookie.of(byteBuf);
-        TransmitterAddress transmitterAddress = TransmitterAddress.of(byteBuf);
-        ReceiverAddress receiverAddress = ReceiverAddress.of(byteBuf);
-        FragmentNumber fragmentNumber = FragmentNumber.of(byteBuf);
-        int expectedFrameNumber = fragmentCounter.get() - 1;
-        if (expectedFrameNumber < 0) {
-            expectedFrameNumber = 255;
-        }
-        if (fragmentNumber.getAsByte() != expectedFrameNumber) {
-            LOGGER.warn("Unexpected fragment {} received. Expected {}", fragmentNumber, expectedFrameNumber);
-        }
-        UserDataLength userDataLength = UserDataLength.of(byteBuf);
-        UserData userData;
-        byte userDataLengthAsByte = userDataLength.getAsByte();
-        if (byteBuf.readableBytes() < userDataLengthAsByte) {
-            return;
-        }
-        if (userDataLengthAsByte > 0) {
-            byte[] userDataByteArray = new byte[userDataLengthAsByte];
-            byteBuf.readBytes(userDataByteArray);
-            userData = UserData.of(userDataByteArray);
-        } else {
-            userData = UserData.EMPTY;
-        }
-        CRC crc = CRC.of(byteBuf);
 
-        // we don't need to retransmit
-        ScheduledFuture<?> scheduledFuture = currentRetryer.get();
-        if (scheduledFuture != null) {
-            scheduledFuture.cancel(false);
-        }
+        AmsSerialFrame amsSerialFrame = new AmsSerialFrame(
+            0x5A01,
+            (byte) 0,
+            (byte) 0,
+            (byte) 0,
+            (byte) amsPacketSer.getLengthInBytes(),
+            amsPacketSer,
+            DigestUtil.calculateCrc16(ArrayUtils.addAll(new byte[]{0x5A, 0x01, 0, 0, 0, (byte) amsPacketSer.getLengthInBytes()}, bytes))
+        );
 
-        Runnable postAction = null;
-        switch (magicCookie.getAsInt()) {
-            case AmsSerialFrame.ID:
-                AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData, crc);
-                LOGGER.debug("Ams Serial Frame received {}", amsSerialFrame);
-                postAction = () -> {
-                    // TODO: check if this is the right way to ack a package.
-                    ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(AmsSerialAcknowledgeFrame.of(transmitterAddress, receiverAddress, fragmentNumber).getByteBuf());
-                    // waiting for the ack-frame to be transmitted before we forward the package
-                    try {
-                        channelFuture.await();
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                        throw new PlcRuntimeException(e);
-                    }
-                    out.add(userData.getByteBuf());
-                };
-                break;
-            case AmsSerialAcknowledgeFrame.ID:
-                AmsSerialAcknowledgeFrame amsSerialAcknowledgeFrame = AmsSerialAcknowledgeFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
-                LOGGER.debug("Ams Serial ACK Frame received {}", amsSerialAcknowledgeFrame);
-                ReferenceCountUtil.release(byteBuf);
-                break;
-            case AmsSerialResetFrame.ID:
-                // TODO: how to react to a reset
-                AmsSerialResetFrame amsSerialResetFrame = AmsSerialResetFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
-                LOGGER.debug("Ams Serial Reset Frame received {}", amsSerialResetFrame);
-                ReferenceCountUtil.release(byteBuf);
-                break;
-            default:
-                throw new PlcProtocolException("Unknown type: " + magicCookie);
-        }
-        CRC calculatedCrc = CRC.of(DigestUtil.calculateCrc16(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData));
-        if (!crc.equals(calculatedCrc)) {
-            throw new PlcProtocolException("CRC checksum wrong. Got " + crc + " expected " + calculatedCrc);
+        WriteBuffer writeBuffer = new WriteBuffer(amsPacketSer.getLengthInBytes(), true);
+        try {
+            AmsSerialFrameIO.serialize(writeBuffer, amsSerialFrame);
+        } catch (ParseException e) {
+            throw new AdsException(amsPacketSer.getAmsHeader().getInvokeId(), e);
         }
+        out.add(writeBuffer.getData());
+    }
 
-        if (postAction != null) {
-            postAction.run();
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) {
+        if (byteBuf == Unpooled.EMPTY_BUFFER) {
+            // Cleanup...
+            return;
         }
+        LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
+        byte[] bytes = new byte[byteBuf.readableBytes()];
+        byteBuf.readBytes(bytes);
+        ReadBuffer readBuffer = new ReadBuffer(bytes);
+        while (readBuffer.getPos() < bytes.length) {
+            try {
+                AmsTCPPacket amsTCPPacket = AmsTCPPacketIO.parse(readBuffer);
+                AmsPacket amsPacket = amsTCPPacket.getUserdata();
 
-        if (byteBuf.readableBytes() > 0) {
-            throw new IllegalStateException("Unread bytes left: " + byteBuf.readableBytes());
+                WriteBuffer writeBuffer = new WriteBuffer(amsPacket.getLengthInBytes(), true);
+                try {
+                    AmsPacketIO.serialize(writeBuffer, amsPacket);
+                } catch (ParseException e) {
+                    throw new AdsException(amsPacket.getAmsHeader().getInvokeId(), e);
+                }
+                out.add(writeBuffer.getData());
+            } catch (Exception e) {
+                LOGGER.warn("Error decoding package: " + e.getMessage());
+            }
         }
     }
 }
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2TcpProtocol.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2TcpProtocol.java
index 780cc6f..7c95783 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2TcpProtocol.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Payload2TcpProtocol.java
@@ -22,8 +22,15 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
+import org.apache.plc4x.java.amsads.protocol.exception.AdsException;
+import org.apache.plc4x.java.amsads.readwrite.AmsPacket;
 import org.apache.plc4x.java.amsads.readwrite.AmsTCPPacket;
 import org.apache.plc4x.java.amsads.readwrite.AmsTcpHeader;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsPacketIO;
+import org.apache.plc4x.java.amsads.readwrite.io.AmsTCPPacketIO;
+import org.apache.plc4x.java.utils.ParseException;
+import org.apache.plc4x.java.utils.ReadBuffer;
+import org.apache.plc4x.java.utils.WriteBuffer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,9 +41,24 @@ public class Payload2TcpProtocol extends MessageToMessageCodec<ByteBuf, ByteBuf>
     private static final Logger LOGGER = LoggerFactory.getLogger(Payload2TcpProtocol.class);
 
     @Override
-    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) {
+    protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws AdsException {
         LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
-        out.add(AmsTCPPacket.of(UserData.of(amsPacket)).getByteBuf());
+
+        byte[] bytes = amsPacket.array();
+        AmsPacket amsPacketSer;
+        try {
+            amsPacketSer = AmsPacketIO.parse(new ReadBuffer(bytes, true));
+        } catch (ParseException e) {
+            throw new AdsException(-1L, e);
+        }
+
+        WriteBuffer writeBuffer = new WriteBuffer(amsPacketSer.getLengthInBytes(), true);
+        try {
+            AmsTCPPacketIO.serialize(writeBuffer, new AmsTCPPacket(new AmsTcpHeader(amsPacketSer.getLengthInBytes()), amsPacketSer));
+        } catch (ParseException e) {
+            throw new AdsException(amsPacketSer.getAmsHeader().getInvokeId(), e);
+        }
+        out.add(writeBuffer.getData());
     }
 
     @SuppressWarnings("unchecked")
@@ -47,21 +69,25 @@ public class Payload2TcpProtocol extends MessageToMessageCodec<ByteBuf, ByteBuf>
             return;
         }
         LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
-        if (byteBuf.readableBytes() < AmsTcpHeader.Reserved.NUM_BYTES + TcpLength.NUM_BYTES) {
-            // wait till we can read the length header
-            return;
-        }
-        if (byteBuf.readableBytes() < byteBuf.getUnsignedIntLE(AmsTcpHeader.Reserved.NUM_BYTES)) {
-            // wait till we have a complete ADS packet
-            return;
-        }
-        // Reserved
-        byteBuf.skipBytes(AmsTcpHeader.Reserved.NUM_BYTES);
-        TcpLength packetLength = TcpLength.of(byteBuf);
-        AmsTcpHeader amsTcpHeader = AmsTcpHeader.of(packetLength);
-        LOGGER.debug("AMS TCP Header {}", amsTcpHeader);
+        byte[] bytes = new byte[byteBuf.readableBytes()];
+        byteBuf.readBytes(bytes);
+        ReadBuffer readBuffer = new ReadBuffer(bytes);
+        while (readBuffer.getPos() < bytes.length) {
+            try {
+                AmsTCPPacket amsTCPPacket = AmsTCPPacketIO.parse(readBuffer);
+                AmsPacket amsPacket = amsTCPPacket.getUserdata();
 
-        out.add(byteBuf.readBytes((int) packetLength.getAsLong()));
+                WriteBuffer writeBuffer = new WriteBuffer(amsPacket.getLengthInBytes(), true);
+                try {
+                    AmsPacketIO.serialize(writeBuffer, amsPacket);
+                } catch (ParseException e) {
+                    throw new AdsException(amsPacket.getAmsHeader().getInvokeId(), e);
+                }
+                out.add(writeBuffer.getData());
+            } catch (Exception e) {
+                LOGGER.warn("Error decoding package: " + e.getMessage());
+            }
+        }
     }
 
 }
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Plc4x2AdsProtocol.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Plc4x2AdsProtocol.java
index 1664f40..1fbc73f 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Plc4x2AdsProtocol.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/Plc4x2AdsProtocol.java
@@ -21,11 +21,13 @@ package org.apache.plc4x.java.amsads.protocol;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.codec.MessageToMessageCodec;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.plc4x.java.amsads.model.AdsDataType;
 import org.apache.plc4x.java.amsads.model.AdsField;
 import org.apache.plc4x.java.amsads.model.DirectAdsField;
 import org.apache.plc4x.java.amsads.model.SymbolicAdsField;
 import org.apache.plc4x.java.amsads.protocol.exception.AdsException;
 import org.apache.plc4x.java.amsads.readwrite.*;
+import org.apache.plc4x.java.amsads.readwrite.types.CommandId;
 import org.apache.plc4x.java.api.exceptions.PlcException;
 import org.apache.plc4x.java.api.exceptions.PlcIoException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
@@ -142,9 +144,9 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
             throw new PlcProtocolException("PlcField not of type DirectAdsField: " + field.getClass());
         }
         DirectAdsField directAdsField = (DirectAdsField) field;
-        Long invokeId = Invoke.of(correlationBuilder.incrementAndGet());
-        IndexGroup indexGroup = IndexGroup.of(directAdsField.getIndexGroup());
-        IndexOffset indexOffset = IndexOffset.of(directAdsField.getIndexOffset());
+        long invokeId = correlationBuilder.incrementAndGet();
+        long indexGroup = directAdsField.getIndexGroup();
+        long indexOffset = directAdsField.getIndexOffset();
 
         BaseDefaultFieldItem fieldItem = writeRequest.getFieldItems().get(0);
         Object[] values = fieldItem.getValues();
@@ -156,8 +158,8 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
             LOGGER.debug("Requested AdsDatatype {} is exceeded by number of bytes {}. Limit {}.", directAdsField.getAdsDataType(), bytesToBeWritten, maxTheoreticalSize);
             throw new PlcProtocolPayloadTooBigException("ADS", maxTheoreticalSize, bytesToBeWritten, values);
         }
-        Data data = Data.of(bytes);
-        AmsPacket amsPacket = AdsWriteRequest.of(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, invokeId, indexGroup, indexOffset, data);
+        AdsWriteRequest data = new AdsWriteRequest(indexGroup, indexOffset, bytes.length, bytes);
+        AmsPacket amsPacket = new AmsPacket(new AmsHeader(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, CommandId.ADS_WRITE, new State(false, false, false, false, false, false, true, false, false), data.getDataLength(), 0, invokeId), data);
         LOGGER.debug("encoded write request {}", amsPacket);
         out.add(amsPacket);
         requests.put(invokeId, msg);
@@ -182,14 +184,14 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
             throw new PlcProtocolException("PlcField not of type DirectAdsField: " + field.getClass());
         }
         DirectAdsField directAdsField = (DirectAdsField) field;
-        Long invokeId = Invoke.of(correlationBuilder.incrementAndGet());
-        IndexGroup indexGroup = IndexGroup.of(directAdsField.getIndexGroup());
-        IndexOffset indexOffset = IndexOffset.of(directAdsField.getIndexOffset());
+        long invokeId = correlationBuilder.incrementAndGet();
+        long indexGroup = directAdsField.getIndexGroup();
+        long indexOffset = directAdsField.getIndexOffset();
         AdsDataType adsDataType = directAdsField.getAdsDataType();
         int numberOfElements = directAdsField.getNumberOfElements();
         int readLength = adsDataType.getTargetByteSize() * numberOfElements;
-        Length length = Length.of(readLength);
-        AmsPacket amsPacket = AdsReadRequest.of(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, invokeId, indexGroup, indexOffset, length);
+        AdsReadRequest data = new AdsReadRequest(indexGroup, indexOffset, readLength);
+        AmsPacket amsPacket = new AmsPacket(new AmsHeader(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, CommandId.ADS_READ, new State(false, false, false, false, false, false, true, false, false), data.getDataLength(), 0, invokeId), data);
         LOGGER.debug("encoded read request {}", amsPacket);
         out.add(amsPacket);
         requests.put(invokeId, msg);
@@ -203,18 +205,19 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
         AmsPacket amsPacket = (AmsPacket) plcProprietaryRequest.getProprietaryRequest();
         LOGGER.debug("encoded proprietary request {}", amsPacket);
         out.add(amsPacket);
-        requests.put(amsPacket.getAmsHeader().getInvokeId().getAsLong(), msg);
+        requests.put(amsPacket.getAmsHeader().getInvokeId(), msg);
     }
 
     @Override
     protected void decode(ChannelHandlerContext channelHandlerContext, AmsPacket amsPacket, List<Object> out) throws Exception {
         LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, amsPacket, out);
-        if (amsPacket instanceof AdsDeviceNotificationRequest) {
+        ADSData data = amsPacket.getData();
+        if (data instanceof AdsDeviceNotificationRequest) {
             LOGGER.debug("Received notification {}", amsPacket);
-            handleAdsDeviceNotificationRequest((AdsDeviceNotificationRequest) amsPacket);
+            handleAdsDeviceNotificationRequest((AdsDeviceNotificationRequest) data);
             return;
         }
-        PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> plcRequestContainer = requests.remove(amsPacket.getAmsHeader().getInvokeId().getAsLong());
+        PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> plcRequestContainer = requests.remove(amsPacket.getAmsHeader().getInvokeId());
         if (plcRequestContainer == null) {
             LOGGER.info("Unmapped packet received {}", amsPacket);
             return;
@@ -224,14 +227,14 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
 
         // Handle the response to a read request.
         if (request instanceof PlcReadRequest) {
-            if (amsPacket instanceof AdsReadResponse) {
-                response = decodeReadResponse((AdsReadResponse) amsPacket, plcRequestContainer);
+            if (data instanceof AdsReadResponse) {
+                response = decodeReadResponse((AdsReadResponse) data, plcRequestContainer);
             } else {
                 throw new PlcProtocolException("Wrong type correlated " + amsPacket);
             }
         } else if (request instanceof PlcWriteRequest) {
-            if (amsPacket instanceof AdsWriteResponse) {
-                response = decodeWriteResponse((AdsWriteResponse) amsPacket, plcRequestContainer);
+            if (data instanceof AdsWriteResponse) {
+                response = decodeWriteResponse((AdsWriteResponse) data, plcRequestContainer);
             } else {
                 throw new PlcProtocolException("Wrong type correlated " + amsPacket);
             }
@@ -283,14 +286,14 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
     }
 
     @SuppressWarnings("unchecked")
-    private InternalPlcResponse decodeReadResponse(AdsReadeResponse responseMessage, PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> requestContainer) {
+    private InternalPlcResponse decodeReadResponse(AdsReadResponse responseMessage, PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> requestContainer) {
         InternalPlcReadRequest plcReadRequest = (InternalPlcReadRequest) requestContainer.getRequest();
 
         // TODO: only single requests supported for now
         AdsField field = (AdsField) plcReadRequest.getFields().get(0);
 
         PlcResponseCode responseCode = decodeResponseCode(responseMessage.getResult());
-        byte[] bytes = responseMessage.getData().getBytes();
+        byte[] bytes = responseMessage.getData();
         BaseDefaultFieldItem<?> fieldItem = decodeData(field.getAdsDataType(), bytes);
 
         // TODO: does every item has the same ads response or is this whole aggregation broken?
@@ -309,137 +312,14 @@ public class Plc4x2AdsProtocol extends MessageToMessageCodec<AmsPacket, PlcReque
         return new DefaultPlcProprietaryResponse<>((InternalPlcProprietaryRequest) plcRequestContainer.getRequest(), amsPacket);
     }
 
-    private PlcResponseCode decodeResponseCode(Result result) {
-        switch (result.toAdsReturnCode()) {
-            case ADS_CODE_0:
-                return PlcResponseCode.OK;
-            case ADS_CODE_1:
-                return PlcResponseCode.INTERNAL_ERROR;
-            case ADS_CODE_2:
-            case ADS_CODE_3:
-            case ADS_CODE_4:
-            case ADS_CODE_5:
-                return PlcResponseCode.INTERNAL_ERROR;
-            case ADS_CODE_6:
-            case ADS_CODE_7:
-                return PlcResponseCode.INVALID_ADDRESS;
-            case ADS_CODE_8:
-            case ADS_CODE_9:
-            case ADS_CODE_10:
-            case ADS_CODE_11:
-            case ADS_CODE_12:
-            case ADS_CODE_13:
-            case ADS_CODE_14:
-            case ADS_CODE_15:
-            case ADS_CODE_16:
-            case ADS_CODE_17:
-            case ADS_CODE_18:
-            case ADS_CODE_19:
-            case ADS_CODE_20:
-            case ADS_CODE_21:
-            case ADS_CODE_22:
-            case ADS_CODE_23:
-            case ADS_CODE_24:
-            case ADS_CODE_25:
-            case ADS_CODE_26:
-            case ADS_CODE_27:
-            case ADS_CODE_28:
-            case ADS_CODE_1280:
-            case ADS_CODE_1281:
-            case ADS_CODE_1282:
-            case ADS_CODE_1283:
-            case ADS_CODE_1284:
-            case ADS_CODE_1285:
-            case ADS_CODE_1286:
-            case ADS_CODE_1287:
-            case ADS_CODE_1288:
-            case ADS_CODE_1289:
-            case ADS_CODE_1290:
-            case ADS_CODE_1291:
-            case ADS_CODE_1292:
-            case ADS_CODE_1293:
-            case ADS_CODE_1792:
-            case ADS_CODE_1793:
-            case ADS_CODE_1794:
-            case ADS_CODE_1795:
-            case ADS_CODE_1796:
-            case ADS_CODE_1797:
-            case ADS_CODE_1798:
-            case ADS_CODE_1799:
-            case ADS_CODE_1800:
-            case ADS_CODE_1801:
-            case ADS_CODE_1802:
-            case ADS_CODE_1803:
-            case ADS_CODE_1804:
-            case ADS_CODE_1805:
-            case ADS_CODE_1806:
-            case ADS_CODE_1807:
-            case ADS_CODE_1808:
-            case ADS_CODE_1809:
-            case ADS_CODE_1810:
-            case ADS_CODE_1811:
-            case ADS_CODE_1812:
-            case ADS_CODE_1813:
-            case ADS_CODE_1814:
-            case ADS_CODE_1815:
-            case ADS_CODE_1816:
-            case ADS_CODE_1817:
-            case ADS_CODE_1818:
-            case ADS_CODE_1819:
-            case ADS_CODE_1820:
-            case ADS_CODE_1821:
-            case ADS_CODE_1822:
-            case ADS_CODE_1823:
-            case ADS_CODE_1824:
-            case ADS_CODE_1825:
-            case ADS_CODE_1826:
-            case ADS_CODE_1827:
-            case ADS_CODE_1828:
-            case ADS_CODE_1836:
-            case ADS_CODE_1856:
-            case ADS_CODE_1857:
-            case ADS_CODE_1858:
-            case ADS_CODE_1859:
-            case ADS_CODE_1860:
-            case ADS_CODE_1861:
-            case ADS_CODE_1862:
-            case ADS_CODE_1863:
-            case ADS_CODE_1864:
-            case ADS_CODE_1872:
-            case ADS_CODE_1873:
-            case ADS_CODE_1874:
-            case ADS_CODE_1875:
-            case ADS_CODE_1876:
-            case ADS_CODE_1877:
-            case ADS_CODE_4096:
-            case ADS_CODE_4097:
-            case ADS_CODE_4098:
-            case ADS_CODE_4099:
-            case ADS_CODE_4100:
-            case ADS_CODE_4101:
-            case ADS_CODE_4102:
-            case ADS_CODE_4103:
-            case ADS_CODE_4104:
-            case ADS_CODE_4105:
-            case ADS_CODE_4106:
-            case ADS_CODE_4107:
-            case ADS_CODE_4108:
-            case ADS_CODE_4109:
-            case ADS_CODE_4110:
-            case ADS_CODE_4111:
-            case ADS_CODE_4112:
-            case ADS_CODE_4119:
-            case ADS_CODE_4120:
-            case ADS_CODE_4121:
-            case ADS_CODE_4122:
-            case ADS_CODE_10060:
-            case ADS_CODE_10061:
-            case ADS_CODE_10065:
-                return PlcResponseCode.INTERNAL_ERROR;
-            case UNKNOWN:
-                return PlcResponseCode.INTERNAL_ERROR;
+    private PlcResponseCode decodeResponseCode(long result) {
+        if (result == 0L) {
+            return PlcResponseCode.OK;
+        } else if (result == 0x7L) {
+            return PlcResponseCode.INVALID_ADDRESS;
+        } else {
+            return PlcResponseCode.INTERNAL_ERROR;
         }
-        throw new IllegalStateException(result.toAdsReturnCode() + " not mapped");
     }
 
 }
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/DigestUtil.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/DigestUtil.java
index fcd89bb..b3e9a62 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/DigestUtil.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/DigestUtil.java
@@ -19,7 +19,6 @@
 package org.apache.plc4x.java.amsads.protocol.util;
 
 import com.github.snksoft.crc.CRC;
-import org.apache.plc4x.java.ads.api.util.ByteReadable;
 
 public class DigestUtil {
 
@@ -39,18 +38,6 @@ public class DigestUtil {
         // Utility class
     }
 
-    public static int calculateCrc16(ByteReadable... byteReadables) {
-        if (byteReadables.length == 1) {
-            return calculateCrc16(byteReadables[0].getBytes());
-        }
-        long currentCrcValue = crc.init();
-        for (ByteReadable byteReadable : byteReadables) {
-            currentCrcValue = crc.update(currentCrcValue, byteReadable.getBytes());
-        }
-        short finalCrc = crc.finalCRC16(currentCrcValue);
-        return Short.toUnsignedInt(Short.reverseBytes(finalCrc));
-    }
-
     public static int calculateCrc16(byte[] bytes) {
         short finalCrc = (short) crc.calculateCRC(bytes);
         return Short.toUnsignedInt(Short.reverseBytes(finalCrc));
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianDecoder.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianDecoder.java
index 0cf9f8a..a530ca2 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianDecoder.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianDecoder.java
@@ -22,7 +22,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.NotImplementedException;
-import org.apache.plc4x.java.ads.model.AdsDataType;
+import org.apache.plc4x.java.amsads.model.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException;
 import org.apache.plc4x.java.base.messages.items.*;
 
diff --git a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianEncoder.java b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianEncoder.java
index 52852c5..9b6c1df 100644
--- a/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianEncoder.java
+++ b/sandbox/test-java-amsads-driver/src/main/java/org/apache/plc4x/java/amsads/protocol/util/LittleEndianEncoder.java
@@ -19,7 +19,7 @@
 package org.apache.plc4x.java.amsads.protocol.util;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.plc4x.java.ads.model.AdsDataType;
+import org.apache.plc4x.java.amsads.model.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;