You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/08/31 14:40:44 UTC

[plc4x] branch develop updated (ed563336a -> 9f3cc6d0d)

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

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


    from ed563336a build(deps): bump maven-dependency-tree from 3.1.1 to 3.2.0 (#480)
     new 865d5effc fix(plc4j/s7): Fixed the PLC4X272 test and made it run automatically.
     new 386189f4d fix(plc4j/spi): Added the missing "getObject" method to the PlcStruct
     new 9f3cc6d0d fix(plc4j/ads): Refactored the ADS driver to support reading of complex types.

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


Summary of changes:
 .../org/apache/plc4x/java/ads/field/AdsField.java  |   3 -
 .../plc4x/java/ads/field/AdsFieldHandler.java      |   2 -
 .../plc4x/java/ads/field/DirectAdsField.java       |  25 +-
 .../plc4x/java/ads/field/DirectAdsStringField.java |  16 +-
 .../plc4x/java/ads/field/SymbolicAdsField.java     |  38 +--
 .../java/ads/field/SymbolicAdsStringField.java     |  95 --------
 .../java/ads/model/AdsSubscriptionHandle.java      |   8 +-
 .../plc4x/java/ads/protocol/AdsProtocolLogic.java  | 261 ++++++++++++++++-----
 .../java/ads/readwrite/utils/StaticHelper.java     |   4 +
 .../issues/{PLC4X272.java => PLC4X272Test.java}    |   4 +-
 .../s7/src/test/resources/tests/PLC4X-272.xml      |  14 +-
 .../apache/plc4x/java/spi/values/PlcStruct.java    |   5 +
 12 files changed, 237 insertions(+), 238 deletions(-)
 delete mode 100644 plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsStringField.java
 rename plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/{PLC4X272.java => PLC4X272Test.java} (91%)


[plc4x] 03/03: fix(plc4j/ads): Refactored the ADS driver to support reading of complex types.

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

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

commit 9f3cc6d0d4f5686e51db1780bf2df12b0ce351c5
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 31 16:40:22 2022 +0200

    fix(plc4j/ads): Refactored the ADS driver to support reading of complex types.
---
 .../org/apache/plc4x/java/ads/field/AdsField.java  |   3 -
 .../plc4x/java/ads/field/AdsFieldHandler.java      |   2 -
 .../plc4x/java/ads/field/DirectAdsField.java       |  25 +-
 .../plc4x/java/ads/field/DirectAdsStringField.java |  16 +-
 .../plc4x/java/ads/field/SymbolicAdsField.java     |  38 +--
 .../java/ads/field/SymbolicAdsStringField.java     |  95 --------
 .../java/ads/model/AdsSubscriptionHandle.java      |   8 +-
 .../plc4x/java/ads/protocol/AdsProtocolLogic.java  | 261 ++++++++++++++++-----
 .../java/ads/readwrite/utils/StaticHelper.java     |   4 +
 9 files changed, 223 insertions(+), 229 deletions(-)

diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsField.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsField.java
index 8d5b1b274..f403d3983 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsField.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsField.java
@@ -18,12 +18,9 @@
  */
 package org.apache.plc4x.java.ads.field;
 
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
 import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.spi.utils.Serializable;
 
 public interface AdsField extends PlcField, Serializable {
 
-    AdsDataType getAdsDataType();
-
 }
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsFieldHandler.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsFieldHandler.java
index c94c1c3e8..447755620 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsFieldHandler.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/AdsFieldHandler.java
@@ -30,8 +30,6 @@ public class AdsFieldHandler implements PlcFieldHandler {
             return DirectAdsStringField.of(fieldQuery);
         } else if (DirectAdsField.matches(fieldQuery)) {
             return DirectAdsField.of(fieldQuery);
-        } else if (SymbolicAdsStringField.matches(fieldQuery)) {
-            return SymbolicAdsStringField.of(fieldQuery);
         } else if (SymbolicAdsField.matches(fieldQuery)) {
             return SymbolicAdsField.of(fieldQuery);
         }
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsField.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsField.java
index 7abef7f87..cb6f79793 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsField.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsField.java
@@ -18,9 +18,7 @@
  */
 package org.apache.plc4x.java.ads.field;
 
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
 
@@ -41,24 +39,24 @@ public class DirectAdsField implements AdsField {
 
     private final long indexOffset;
 
-    private final AdsDataType adsDataType;
+    private final String adsDataTypeName;
 
     private final int numberOfElements;
 
-    public DirectAdsField(long indexGroup, long indexOffset, AdsDataType adsDataType, Integer numberOfElements) {
+    public DirectAdsField(long indexGroup, long indexOffset, String adsDataTypeName, Integer numberOfElements) {
         //ByteValue.checkUnsignedBounds(indexGroup, 4);
         this.indexGroup = indexGroup;
         //ByteValue.checkUnsignedBounds(indexOffset, 4);
         this.indexOffset = indexOffset;
-        this.adsDataType = Objects.requireNonNull(adsDataType);
+        this.adsDataTypeName = Objects.requireNonNull(adsDataTypeName);
         this.numberOfElements = numberOfElements != null ? numberOfElements : 1;
         if (this.numberOfElements <= 0) {
             throw new IllegalArgumentException("numberOfElements must be greater then zero. Was " + this.numberOfElements);
         }
     }
 
-    public static DirectAdsField of(long indexGroup, long indexOffset, AdsDataType adsDataType, Integer numberOfElements) {
-        return new DirectAdsField(indexGroup, indexOffset, adsDataType, numberOfElements);
+    public static DirectAdsField of(long indexGroup, long indexOffset, String adsDataTypeName, Integer numberOfElements) {
+        return new DirectAdsField(indexGroup, indexOffset, adsDataTypeName, numberOfElements);
     }
 
     public static DirectAdsField of(String address) {
@@ -88,12 +86,11 @@ public class DirectAdsField implements AdsField {
         }
 
         String adsDataTypeString = matcher.group("adsDataType");
-        AdsDataType adsDataType = AdsDataType.valueOf(adsDataTypeString);
 
         String numberOfElementsString = matcher.group("numberOfElements");
         Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
 
-        return new DirectAdsField(indexGroup, indexOffset, adsDataType, numberOfElements);
+        return new DirectAdsField(indexGroup, indexOffset, adsDataTypeString, numberOfElements);
     }
 
     public static boolean matches(String address) {
@@ -108,14 +105,8 @@ public class DirectAdsField implements AdsField {
         return indexOffset;
     }
 
-    @Override
-    public AdsDataType getAdsDataType() {
-        return adsDataType;
-    }
-
-    @Override
-    public String getPlcDataType() {
-        return adsDataType.toString();
+    public String getAdsDataTypeName() {
+        return adsDataTypeName;
     }
 
     @Override
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsStringField.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsStringField.java
index d003c4612..04d4109cc 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsStringField.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/DirectAdsStringField.java
@@ -18,7 +18,6 @@
  */
 package org.apache.plc4x.java.ads.field;
 
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
@@ -37,13 +36,13 @@ public class DirectAdsStringField extends DirectAdsField implements AdsStringFie
 
     private final int stringLength;
 
-    public DirectAdsStringField(long indexGroup, long indexOffset, AdsDataType adsDataType, int stringLength, Integer numberOfElements) {
-        super(indexGroup, indexOffset, adsDataType, numberOfElements);
+    public DirectAdsStringField(long indexGroup, long indexOffset, String adsDataTypeName, int stringLength, Integer numberOfElements) {
+        super(indexGroup, indexOffset, adsDataTypeName, numberOfElements);
         this.stringLength = stringLength;
     }
 
-    public static DirectAdsStringField of(long indexGroup, long indexOffset, AdsDataType adsDataType, int stringLength, Integer numberOfElements) {
-        return new DirectAdsStringField(indexGroup, indexOffset, adsDataType, stringLength, numberOfElements);
+    public static DirectAdsStringField of(long indexGroup, long indexOffset, String adsDataTypeName, int stringLength, Integer numberOfElements) {
+        return new DirectAdsStringField(indexGroup, indexOffset, adsDataTypeName, stringLength, numberOfElements);
     }
 
     public static DirectAdsStringField of(String address) {
@@ -72,16 +71,15 @@ public class DirectAdsStringField extends DirectAdsField implements AdsStringFie
             indexOffset = Long.parseLong(indexOffsetString);
         }
 
-        String adsDataTypeString = matcher.group("adsDataType");
-        AdsDataType adsDataType = AdsDataType.valueOf(adsDataTypeString);
+        String adsDataTypeName = matcher.group("adsDataType");
 
         String stringLengthString = matcher.group("stringLength");
-        Integer stringLength = stringLengthString != null ? Integer.valueOf(stringLengthString) : null;
+        int stringLength = stringLengthString != null ? Integer.parseInt(stringLengthString) : 0;
 
         String numberOfElementsString = matcher.group("numberOfElements");
         Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
 
-        return new DirectAdsStringField(indexGroup, indexOffset, adsDataType, stringLength, numberOfElements);
+        return new DirectAdsStringField(indexGroup, indexOffset, adsDataTypeName, stringLength, numberOfElements);
     }
 
     public static boolean matches(String address) {
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsField.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsField.java
index 4d13dd92f..140b1fb60 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsField.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsField.java
@@ -18,7 +18,6 @@
  */
 package org.apache.plc4x.java.ads.field;
 
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
@@ -33,22 +32,12 @@ import java.util.regex.Pattern;
  */
 public class SymbolicAdsField implements AdsField {
 
-    private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^(?<symbolicAddress>.+):(?<adsDataType>\\w+)(\\[(?<numberOfElements>\\d+)])?");
+    private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^(?<symbolicAddress>.+)");
 
     private final String symbolicAddress;
 
-    private final AdsDataType adsDataType;
-
-    private final int numberOfElements;
-
-    public SymbolicAdsField(String symbolicAddress, AdsDataType adsDataType, Integer numberOfElements) {
+    public SymbolicAdsField(String symbolicAddress) {
         this.symbolicAddress = Objects.requireNonNull(symbolicAddress);
-        this.adsDataType = Objects.requireNonNull(adsDataType);
-        this.numberOfElements = numberOfElements != null ? numberOfElements : 1;
-        if (this.numberOfElements <= 0) {
-            throw new IllegalArgumentException("numberOfElements must be greater then zero. Was " + this.numberOfElements);
-        }
-
     }
 
     public static SymbolicAdsField of(String address) {
@@ -58,13 +47,7 @@ public class SymbolicAdsField implements AdsField {
         }
         String symbolicAddress = matcher.group("symbolicAddress");
 
-        String adsDataTypeString = matcher.group("adsDataType");
-        AdsDataType adsDataType = AdsDataType.valueOf(adsDataTypeString);
-
-        String numberOfElementsString = matcher.group("numberOfElements");
-        Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
-
-        return new SymbolicAdsField(symbolicAddress, adsDataType, numberOfElements);
+        return new SymbolicAdsField(symbolicAddress);
     }
 
     public static boolean matches(String address) {
@@ -75,21 +58,6 @@ public class SymbolicAdsField implements AdsField {
         return symbolicAddress;
     }
 
-    @Override
-    public AdsDataType getAdsDataType() {
-        return adsDataType;
-    }
-
-    @Override
-    public String getPlcDataType() {
-        return adsDataType.toString();
-    }
-
-    @Override
-    public int getNumberOfElements() {
-        return numberOfElements;
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) {
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsStringField.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsStringField.java
deleted file mode 100644
index ef064afb5..000000000
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/field/SymbolicAdsStringField.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   https://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.field;
-
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
-import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.spi.generation.SerializationException;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-
-import java.nio.charset.StandardCharsets;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * ADS address witch is defined by symbolic name (e.g. {@code Main.items[0]}).
- */
-public class SymbolicAdsStringField extends SymbolicAdsField implements AdsStringField {
-
-    private static final Pattern SYMBOLIC_ADDRESS_STRING_PATTERN = Pattern.compile("^(?<symbolicAddress>.+):(?<adsDataType>'STRING'|'WSTRING')\\((?<stringLength>\\d{1,3})\\)(\\[(?<numberOfElements>\\d+)])?");
-
-    private final int stringLength;
-
-    private SymbolicAdsStringField(String symbolicAddress, AdsDataType adsDataType, int stringLength, Integer numberOfElements) {
-        super(symbolicAddress, adsDataType, numberOfElements);
-        this.stringLength = stringLength;
-    }
-
-    public static SymbolicAdsStringField of(String address) {
-        Matcher matcher = SYMBOLIC_ADDRESS_STRING_PATTERN.matcher(address);
-        if (!matcher.matches()) {
-            throw new PlcInvalidFieldException(address, SYMBOLIC_ADDRESS_STRING_PATTERN, "{address}");
-        }
-        String symbolicAddress = matcher.group("symbolicAddress");
-
-        String adsDataTypeString = matcher.group("adsDataType");
-        AdsDataType adsDataType = AdsDataType.valueOf(adsDataTypeString);
-
-        String stringLengthString = matcher.group("stringLength");
-        Integer stringLength = stringLengthString != null ? Integer.valueOf(stringLengthString) : null;
-
-        String numberOfElementsString = matcher.group("numberOfElements");
-        Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
-
-        return new SymbolicAdsStringField(symbolicAddress, adsDataType, stringLength, numberOfElements);
-    }
-
-    public static boolean matches(String address) {
-        return SYMBOLIC_ADDRESS_STRING_PATTERN.matcher(address).matches();
-    }
-
-    @Override
-    public int getStringLength() {
-        return stringLength;
-    }
-
-    @Override
-    public String toString() {
-        return "SymbolicAdsStringField{" +
-            "symbolicAddress='" + getSymbolicAddress() + '\'' +
-            ", stringLength=" + stringLength +
-            '}';
-    }
-
-    @Override
-    public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.pushContext(getClass().getSimpleName());
-
-        String symbolicAddress = getSymbolicAddress();
-        writeBuffer.writeString("symbolicAddress", symbolicAddress.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), symbolicAddress);
-
-        writeBuffer.writeUnsignedLong("numberOfElements", 32, getNumberOfElements());
-
-        String dataType = getPlcDataType();
-        writeBuffer.writeString("dataType", dataType.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), dataType);
-
-        writeBuffer.writeInt("stringLength", 32, getStringLength());
-        writeBuffer.popContext(getClass().getSimpleName());
-    }
-}
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsSubscriptionHandle.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsSubscriptionHandle.java
index a1f89670d..b1dc8ff72 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsSubscriptionHandle.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsSubscriptionHandle.java
@@ -18,7 +18,7 @@
  */
 package org.apache.plc4x.java.ads.model;
 
-import org.apache.plc4x.java.ads.readwrite.AdsDataType;
+import org.apache.plc4x.java.ads.readwrite.AdsDataTypeTableEntry;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
 
@@ -28,11 +28,11 @@ public class AdsSubscriptionHandle extends DefaultPlcSubscriptionHandle {
 
     private final String plcFieldName;
 
-    private final AdsDataType adsDataType;
+    private final AdsDataTypeTableEntry adsDataType;
 
     private final Long notificationHandle;
 
-    public AdsSubscriptionHandle(PlcSubscriber plcSubscriber, String plcFieldName, AdsDataType adsDataType, Long notificationHandle) {
+    public AdsSubscriptionHandle(PlcSubscriber plcSubscriber, String plcFieldName, AdsDataTypeTableEntry adsDataType, Long notificationHandle) {
         super(plcSubscriber);
         this.plcFieldName = plcFieldName;
         this.adsDataType = adsDataType;
@@ -43,7 +43,7 @@ public class AdsSubscriptionHandle extends DefaultPlcSubscriptionHandle {
         return plcFieldName;
     }
 
-    public AdsDataType getAdsDataType() {
+    public AdsDataTypeTableEntry getAdsDataType() {
         return adsDataType;
     }
 
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index 3f2c09a9c..abe27b7f0 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -46,6 +46,8 @@ import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
+import org.apache.plc4x.java.spi.values.PlcList;
+import org.apache.plc4x.java.spi.values.PlcStruct;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,14 +74,14 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
     private final Map<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> consumers = new ConcurrentHashMap<>();
 
-    private final ConcurrentHashMap<SymbolicAdsField, DirectAdsField> symbolicFieldMapping;
+//    private final ConcurrentHashMap<SymbolicAdsField, DirectAdsField> symbolicFieldMapping;
     private final ConcurrentHashMap<SymbolicAdsField, CompletableFuture<Void>> pendingResolutionRequests;
 
     private final Map<String, AdsSymbolTableEntry> symbolTable;
     private final Map<String, AdsDataTypeTableEntry> dataTypeTable;
 
     public AdsProtocolLogic() {
-        symbolicFieldMapping = new ConcurrentHashMap<>();
+//        symbolicFieldMapping = new ConcurrentHashMap<>();
         pendingResolutionRequests = new ConcurrentHashMap<>();
         symbolTable = new HashMap<>();
         dataTypeTable = new HashMap<>();
@@ -410,18 +412,10 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
     protected CompletableFuture<PlcReadResponse> singleRead(PlcReadRequest readRequest, DirectAdsField directAdsField) {
         CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
 
-        long size;
-        if (directAdsField.getAdsDataType() == AdsDataType.STRING) {
-            // If an explicit size is given with the string, use this, if not use 256
-            size = (directAdsField instanceof AdsStringField) ?
-                ((AdsStringField) directAdsField).getStringLength() + 1 : 81;
-        } else if (directAdsField.getAdsDataType() == AdsDataType.WSTRING) {
-            // If an explicit size is given with the string, use this, if not use 512
-            size = (directAdsField instanceof AdsStringField) ?
-                ((long) ((AdsStringField) directAdsField).getStringLength() + 1) * 2 : 162;
-        } else {
-            size = directAdsField.getAdsDataType().getNumBytes();
-        }
+        String dataTypeName = directAdsField.getAdsDataTypeName();
+        AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+        long size = adsDataTypeTableEntry.getSize();
+
         AmsPacket amsPacket = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
             configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
             directAdsField.getIndexGroup(), directAdsField.getIndexOffset(),size * directAdsField.getNumberOfElements());
@@ -457,18 +451,9 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         // Calculate the expected size of the response data.
         long expectedResponseDataSize = directAdsFields.stream().mapToLong(
             field -> {
-                long size;
-                if (field.getAdsDataType() == AdsDataType.STRING) {
-                    // If an explicit size is given with the string, use this, if not use 256
-                    size = (field instanceof AdsStringField) ?
-                        ((AdsStringField) field).getStringLength() + 1 : 256;
-                } else if (field.getAdsDataType() == AdsDataType.WSTRING) {
-                    // If an explicit size is given with the string, use this, if not use 512
-                    size = (field instanceof AdsStringField) ?
-                        ((long) ((AdsStringField) field).getStringLength() + 1) * 2 : 512;
-                } else {
-                    size = field.getAdsDataType().getNumBytes();
-                }
+                String dataTypeName = field.getAdsDataTypeName();
+                AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+                long size = adsDataTypeTableEntry.getSize();
                 // Status code + payload size
                 return 4 + (size * field.getNumberOfElements());
             }).sum();
@@ -476,11 +461,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         // With multi-requests, the index-group is fixed and the index offset indicates the number of elements.
         AmsPacket amsPacket = new AdsReadWriteRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
             configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(),
-            0, getInvokeId(), ReservedIndexGroups.ADSIGRP_MULTIPLE_READ.getValue(), directAdsFields.size(), expectedResponseDataSize,
-            directAdsFields.stream().map(directAdsField -> new AdsMultiRequestItemRead(
-                    directAdsField.getIndexGroup(), directAdsField.getIndexOffset(),
-                    ((long) directAdsField.getAdsDataType().getNumBytes() * directAdsField.getNumberOfElements())))
-                .collect(Collectors.toList()), null);
+            0, getInvokeId(), ReservedIndexGroups.ADSIGRP_MULTIPLE_READ.getValue(), directAdsFields.size(),
+            expectedResponseDataSize, directAdsFields.stream().map(directAdsField -> {
+                String dataTypeName = directAdsField.getAdsDataTypeName();
+                AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+                long size = adsDataTypeTableEntry.getSize();
+                return new AdsMultiRequestItemRead(
+                        directAdsField.getIndexGroup(), directAdsField.getIndexOffset(),
+                        (size * directAdsField.getNumberOfElements()));
+            }).collect(Collectors.toList()), null);
         AmsTCPPacket amsTCPPacket = new AmsTCPPacket(amsPacket);
 
         // Start a new request-transaction (Is ended in the response-handler)
@@ -535,14 +524,20 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         if (readBuffer != null) {
             Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
             for (String fieldName : readRequest.getFieldNames()) {
-                AdsField field = (AdsField) readRequest.getField(fieldName);
+                DirectAdsField field;
+                if(readRequest.getField(fieldName) instanceof DirectAdsField) {
+                    field = (DirectAdsField) readRequest.getField(fieldName);
+                } else {
+                    SymbolicAdsField symbolicAdsField = (SymbolicAdsField) readRequest.getField(fieldName);
+                    field = getDirectAdsFieldForSymbolicName(symbolicAdsField);
+                }
                 // If the response-code was anything but OK, we don't need to parse the payload.
                 if (responseCodes.get(fieldName) != PlcResponseCode.OK) {
                     values.put(fieldName, new ResponseItem<>(responseCodes.get(fieldName), null));
                 }
                 // If the response-code was ok, parse the data returned.
                 else {
-                    values.put(fieldName, parsePlcValue(field, readBuffer));
+                    values.put(fieldName, parseResponseItem(field, readBuffer));
                 }
             }
             return new DefaultPlcReadResponse(readRequest, values);
@@ -559,34 +554,91 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         }
     }
 
-    private ResponseItem<PlcValue> parsePlcValue(AdsField field, ReadBuffer readBuffer) {
+    private ResponseItem<PlcValue> parseResponseItem(DirectAdsField field, ReadBuffer readBuffer) {
         try {
+            String dataTypeName = field.getAdsDataTypeName();
+            AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+            PlcValueType plcValueType = getPlcValueTypeForAdsDataType(adsDataTypeTableEntry);
+
             int strLen = 0;
-            if ((field.getAdsDataType() == AdsDataType.STRING) || (field.getAdsDataType() == AdsDataType.WSTRING)) {
+            if ((plcValueType == PlcValueType.STRING) || (plcValueType == PlcValueType.WSTRING)) {
                 strLen = (field instanceof AdsStringField) ? ((AdsStringField) field).getStringLength() : 256;
             }
             final int stringLength = strLen;
             if (field.getNumberOfElements() == 1) {
-                return new ResponseItem<>(PlcResponseCode.OK,
-                    DataItem.staticParse(readBuffer, field.getAdsDataType().getPlcValueType(), stringLength));
+                return new ResponseItem<>(PlcResponseCode.OK, parsePlcValue(plcValueType, adsDataTypeTableEntry, stringLength, readBuffer));
             } else {
                 // Fetch all
                 final PlcValue[] resultItems = IntStream.range(0, field.getNumberOfElements()).mapToObj(i -> {
                     try {
-                        return DataItem.staticParse(readBuffer, field.getAdsDataType().getPlcValueType(), stringLength);
+                        return parsePlcValue(plcValueType, adsDataTypeTableEntry, stringLength, readBuffer);
                     } catch (ParseException e) {
-                        LOGGER.warn("Error parsing field item of type: '{}' (at position {}})", field.getAdsDataType(), i, e);
+                        LOGGER.warn("Error parsing field item of type: '{}' (at position {}})", field.getAdsDataTypeName(), i, e);
                     }
                     return null;
                 }).toArray(PlcValue[]::new);
                 return new ResponseItem<>(PlcResponseCode.OK, IEC61131ValueHandler.of(resultItems));
             }
         } catch (Exception e) {
-            LOGGER.warn(String.format("Error parsing field item of type: '%s'", field.getAdsDataType()), e);
+            LOGGER.warn(String.format("Error parsing field item of type: '%s'", field.getAdsDataTypeName()), e);
             return new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null);
         }
     }
 
+    private PlcValue parsePlcValue(PlcValueType plcValueType, AdsDataTypeTableEntry adsDataTypeTableEntry, int stringLength, ReadBuffer readBuffer) throws ParseException {
+        switch (plcValueType) {
+            case Struct:
+                Map<String, PlcValue> properties = new HashMap<>();
+                int startPos = readBuffer.getPos();
+                int curPos = 0;
+                for (AdsDataTypeTableChildEntry child : adsDataTypeTableEntry.getChildren()) {
+                    if(child.getOffset() > curPos) {
+                        long skipBytes = child.getOffset() - curPos;
+                        for(long i = 0; i < skipBytes; i++) {
+                            readBuffer.readByte();
+                        }
+                    }
+                    String propertyName = child.getPropertyName();
+                    AdsDataTypeTableEntry propertyDataTypeTableEntry = dataTypeTable.get(child.getDataTypeName());
+                    PlcValueType propertyPlcValueType = getPlcValueTypeForAdsDataType(propertyDataTypeTableEntry);
+                    PlcValue propertyValue = parsePlcValue(propertyPlcValueType, propertyDataTypeTableEntry, stringLength, readBuffer);
+                    properties.put(propertyName, propertyValue);
+                    curPos = readBuffer.getPos() - startPos;
+                }
+                return new PlcStruct(properties);
+            case List:
+                return parseArrayLevel(adsDataTypeTableEntry, adsDataTypeTableEntry.getArrayInfo(), readBuffer);
+            default:
+                return DataItem.staticParse(readBuffer, plcValueType, stringLength);
+        }
+    }
+
+    private PlcValue parseArrayLevel(AdsDataTypeTableEntry adsDataTypeTableEntry, List<AdsDataTypeArrayInfo> arrayLayers, ReadBuffer readBuffer) throws ParseException {
+        // If this is the last layer of the Array, parse the values themselves.
+        if(arrayLayers.isEmpty()) {
+            String dataTypeName = adsDataTypeTableEntry.getDataTypeName();
+            dataTypeName = dataTypeName.substring(dataTypeName.lastIndexOf(" OF ") + 4);
+            int stringLength = 0;
+            if(dataTypeName.startsWith("STRING(")) {
+                stringLength = Integer.parseInt(dataTypeName.substring(7, dataTypeName.length() - 1));
+            } else if(dataTypeName.startsWith("WSTRING(")) {
+                stringLength = Integer.parseInt(dataTypeName.substring(8, dataTypeName.length() - 1));
+            }
+            AdsDataTypeTableEntry elementDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+            PlcValueType plcValueType = getPlcValueTypeForAdsDataType(elementDataTypeTableEntry);
+            return parsePlcValue(plcValueType, elementDataTypeTableEntry, stringLength, readBuffer);
+        }
+
+        List<PlcValue> elements = new ArrayList<>();
+        List<AdsDataTypeArrayInfo> arrayInfo = adsDataTypeTableEntry.getArrayInfo();
+        AdsDataTypeArrayInfo firstLayer = arrayInfo.get(0);
+        for(int i = 0; i < firstLayer.getNumElements(); i++) {
+            List<AdsDataTypeArrayInfo> remainingLayers = arrayInfo.subList(1, arrayInfo.size());
+            elements.add(parseArrayLevel(adsDataTypeTableEntry, remainingLayers, readBuffer));
+        }
+        return new PlcList(elements);
+    }
+
     @Override
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         // Get all ADS addresses in their resolved state.
@@ -650,7 +702,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
     protected CompletableFuture<PlcWriteResponse> singleWrite(PlcWriteRequest writeRequest, DirectAdsField directAdsField) {
         CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
 
-        final String fieldName = writeRequest.getFieldNames().iterator().next();
+/*        final String fieldName = writeRequest.getFieldNames().iterator().next();
         final AdsField plcField = (AdsField) writeRequest.getField(fieldName);
         final PlcValue plcValue = writeRequest.getPlcValue(fieldName);
         final int stringLength;
@@ -694,7 +746,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                 }));
         } catch (Exception e) {
             future.completeExceptionally(new PlcException("Error"));
-        }
+        }*/
         return future;
     }
 
@@ -703,7 +755,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Calculate the size of all fields together.
         // Calculate the expected size of the response data.
-        int expectedRequestDataSize = directAdsFields.stream().mapToInt(
+/*        int expectedRequestDataSize = directAdsFields.stream().mapToInt(
             field -> field.getAdsDataType().getNumBytes() * field.getNumberOfElements()).sum();
         byte[] writeBuffer = new byte[expectedRequestDataSize];
         int pos = 0;
@@ -762,7 +814,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                 }
                 // Finish the request-transaction.
                 transaction.endRequest();
-            }));
+            }));*/
         return future;
     }
 
@@ -845,15 +897,19 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         List<AmsTCPPacket> amsTCPPackets = subscribeRequest.getFields().stream()
             .map(field -> (DefaultPlcSubscriptionField) field)
-            .map(field -> new AmsTCPPacket(new AdsAddDeviceNotificationRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
-                configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(),
-                0, getInvokeId(),
-                symbolicFieldMapping.get((SymbolicAdsField) field.getPlcField()).getIndexGroup(),
-                symbolicFieldMapping.get((SymbolicAdsField) field.getPlcField()).getIndexOffset(),
-                (long) ((AdsField) field.getPlcField()).getAdsDataType().getNumBytes() * field.getNumberOfElements(),
-                field.getPlcSubscriptionType() == PlcSubscriptionType.CYCLIC ? 3 : 4, // if it's not cyclic, it's on change or event
-                0, // there is no api for that yet
-                field.getDuration().orElse(Duration.ZERO).toMillis())))
+            .map(field -> {
+                AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(((DirectAdsField) field.getPlcField()).getAdsDataTypeName());
+                DirectAdsField directAdsField = getDirectAdsFieldForSymbolicName(field);
+                return new AmsTCPPacket(new AdsAddDeviceNotificationRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
+                    configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(),
+                    0, getInvokeId(),
+                    directAdsField.getIndexGroup(),
+                    directAdsField.getIndexOffset(),
+                    adsDataTypeTableEntry.getSize() * field.getNumberOfElements(),
+                    field.getPlcSubscriptionType() == PlcSubscriptionType.CYCLIC ? 3 : 4, // if it's not cyclic, it's on change or event
+                    0, // there is no api for that yet
+                    field.getDuration().orElse(Duration.ZERO).toMillis()));
+            })
             .collect(Collectors.toList());
 
         Map<String, ResponseItem<PlcSubscriptionHandle>> responses = new HashMap<>();
@@ -887,12 +943,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                 .unwrap(responseAmsPacket -> (AdsAddDeviceNotificationResponse) responseAmsPacket.getUserdata())
                 .handle(response -> {
                     if (response.getResult() == ReturnCode.OK) {
+                        DefaultPlcSubscriptionField subscriptionField = (DefaultPlcSubscriptionField) subscriptionRequest.getField(fieldName);
+                        AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(((DirectAdsField) subscriptionField.getPlcField()).getAdsDataTypeName());
+
                         // Collect notification handle from individual response.
                         responses.put(fieldName, new ResponseItem<>(
                             parsePlcResponseCode(response.getResult()),
                             new AdsSubscriptionHandle(this,
                                 fieldName,
-                                ((AdsField) ((DefaultPlcSubscriptionField) subscriptionRequest.getField(fieldName)).getPlcField()).getAdsDataType(),
+                                adsDataTypeTableEntry,
                                 response.getNotificationHandle())));
 
                         // After receiving the last ADD_DEVICE_NOTIFICATION response, complete the PLC4X response.
@@ -1022,7 +1081,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
         ReadBufferByteBased readBuffer = new ReadBufferByteBased(data, ByteOrder.LITTLE_ENDIAN);
         values.put(subscriptionHandle.getPlcFieldName(), new ResponseItem<>(PlcResponseCode.OK,
-            DataItem.staticParse(readBuffer, subscriptionHandle.getAdsDataType().getPlcValueType(), data.length)));
+            DataItem.staticParse(readBuffer, getPlcValueTypeForAdsDataType(subscriptionHandle.getAdsDataType()), data.length)));
         return values;
     }
 
@@ -1052,7 +1111,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Find out for which of these symbolic addresses no resolution has been initiated.
         final List<SymbolicAdsField> symbolicFieldsNeedingResolution = referencedSymbolicFields.stream()
-            .filter(symbolicAdsField -> !symbolicFieldMapping.containsKey(symbolicAdsField))
+            .filter(symbolicAdsField -> getDirectAdsFieldForSymbolicName(symbolicAdsField) == null)
             .collect(Collectors.toList());
 
         // If there are unresolved symbolic addresses, initiate the resolution
@@ -1095,7 +1154,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                     List<DirectAdsField> directAdsFields = new ArrayList<>(fields.size());
                     for (PlcField field : fields) {
                         if (field instanceof SymbolicAdsField) {
-                            directAdsFields.add(symbolicFieldMapping.get(field));
+                            directAdsFields.add(getDirectAdsFieldForSymbolicName(field));
                         } else {
                             directAdsFields.add((DirectAdsField) field);
                         }
@@ -1107,7 +1166,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             // If all fields were resolved, we can continue instantly.
             future.complete(fields.stream().map(plcField -> {
                 if (plcField instanceof SymbolicAdsField) {
-                    return symbolicFieldMapping.get(plcField);
+                    return getDirectAdsFieldForSymbolicName(plcField);
                 } else {
                     return (DirectAdsField) plcField;
                 }
@@ -1146,10 +1205,12 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                         // Read the handle.
                         long handle = readBuffer.readUnsignedLong(32);
 
-                        DirectAdsField directAdsField = new DirectAdsField(
+/*                        DirectAdsField directAdsField = new DirectAdsField(
                             ReservedIndexGroups.ADSIGRP_SYM_VALBYHND.getValue(), handle,
-                            symbolicAdsField.getAdsDataType(), symbolicAdsField.getNumberOfElements());
-                        symbolicFieldMapping.put(symbolicAdsField, directAdsField);
+                            symbolicAdsField.getAdsDataTypeName(), symbolicAdsField.getNumberOfElements());*/
+
+                        // TODO: Find out how to read the datatype for the given symbolic field
+                        //symbolicFieldMapping.put(symbolicAdsField, directAdsField);
                         future.complete(null);
                     } catch (ParseException e) {
                         future.completeExceptionally(e);
@@ -1210,10 +1271,11 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                             // Read the handle.
                             long handle = readBuffer.readUnsignedLong(32);
 
-                            DirectAdsField directAdsField = new DirectAdsField(
+                            /*DirectAdsField directAdsField = new DirectAdsField(
                                 ReservedIndexGroups.ADSIGRP_SYM_VALBYHND.getValue(), handle,
-                                symbolicAdsField.getAdsDataType(), symbolicAdsField.getNumberOfElements());
-                            symbolicFieldMapping.put(symbolicAdsField, directAdsField);
+                                symbolicAdsField.getAdsDataTypeName(), symbolicAdsField.getNumberOfElements());*/
+                            // TODO: Find out how to read the datatype for the given symbolic field
+                            //symbolicFieldMapping.put(symbolicAdsField, directAdsField);
                         } else {
                             // TODO: Handle the case of unsuccessful resolution ..
                         }
@@ -1236,6 +1298,77 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         return invokeId;
     }
 
+    protected DirectAdsField getDirectAdsFieldForSymbolicName(PlcField field) {
+        if(field instanceof DirectAdsField) {
+            return (DirectAdsField) field;
+        }
+
+        SymbolicAdsField symbolicAdsField = (SymbolicAdsField) field;
+        String symbolicAddress = symbolicAdsField.getSymbolicAddress();
+        String[] addressParts = symbolicAddress.split("\\.");
+
+        // If the number of parts are less than 2, we can find the entry in the symbol table directly.
+        if(addressParts.length < 2) {
+            // We can't find it, so we need to resolve it.
+            if(!symbolTable.containsKey(symbolicAddress)) {
+                return null;
+            }
+
+            AdsSymbolTableEntry adsSymbolTableEntry = symbolTable.get(symbolicAddress);
+            AdsDataTypeTableEntry dataTypeTableEntry = dataTypeTable.get(adsSymbolTableEntry.getDataTypeName());
+            return new DirectAdsField(adsSymbolTableEntry.getGroup(), adsSymbolTableEntry.getOffset(),
+                dataTypeTableEntry.getDataTypeName(), dataTypeTableEntry.getArrayDimensions());
+        }
+        // Otherwise we'll have to crawl through the dataType definitions.
+        else {
+            String symbolName = addressParts[0] + "." + addressParts[1];
+            AdsSymbolTableEntry adsSymbolTableEntry = symbolTable.get(symbolName);
+            AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(adsSymbolTableEntry.getDataTypeName());
+            return resolveDirectAdsFieldForSymbolicNameFromDataType(
+                Arrays.asList(addressParts).subList(2, addressParts.length),
+                adsSymbolTableEntry.getGroup(), adsSymbolTableEntry.getOffset(), adsDataTypeTableEntry);
+        }
+    }
+
+    protected DirectAdsField resolveDirectAdsFieldForSymbolicNameFromDataType(List<String> remainingAddressParts, long currentGroup, long currentOffset, AdsDataTypeTableEntry adsDataTypeTableEntry) {
+        if(remainingAddressParts.isEmpty()) {
+            // TODO: Implement the Array support
+            return new DirectAdsField(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), null);
+        }
+
+        // Go through all children looking for a matching one.
+        for (AdsDataTypeTableChildEntry child : adsDataTypeTableEntry.getChildren()) {
+            if(child.getPropertyName().equals(remainingAddressParts.get(0))) {
+                AdsDataTypeTableEntry childAdsDataTypeTableEntry = dataTypeTable.get(child.getDataTypeName());
+                return resolveDirectAdsFieldForSymbolicNameFromDataType(
+                    remainingAddressParts.subList(1, remainingAddressParts.size()),
+                    currentGroup, currentOffset + child.getOffset(), childAdsDataTypeTableEntry);
+            }
+        }
+
+        throw new PlcRuntimeException(String.format("Couldn't find child with name '%s' for type '%s'",
+            remainingAddressParts.get(0), adsDataTypeTableEntry.getDataTypeName()));
+    }
+
+    protected PlcValueType getPlcValueTypeForAdsDataType(AdsDataTypeTableEntry dataTypeTableEntry) {
+        String dataTypeName = dataTypeTableEntry.getDataTypeName();
+        if(dataTypeName.startsWith("STRING(")) {
+            dataTypeName = "STRING";
+        } else if(dataTypeName.startsWith("WSTRING(")) {
+            dataTypeName = "WSTRING";
+        }
+        // First check, if this is a primitive type.
+        try {
+            return PlcValueType.valueOf(dataTypeName);
+        } catch (IllegalArgumentException e) {
+            // Then check if this is an array.
+            if(dataTypeTableEntry.getArrayDimensions() > 0) {
+                return PlcValueType.List;
+            }
+            return PlcValueType.Struct;
+       }
+    }
+
     protected byte[] getNullByteTerminatedArray(String value) {
         byte[] valueBytes = value.getBytes();
         byte[] nullTerminatedBytes = new byte[valueBytes.length + 1];
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java
index 8e0b02735..f0b874735 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java
@@ -47,6 +47,8 @@ public class StaticHelper {
                         break;
                     }
                 }
+                // Read the terminating byte.
+                readBuffer.readByte();
                 final byte[] byteArray = new byte[bytes.size()];
                 for (int i = 0; i < bytes.size(); i++) {
                     byteArray[i] = bytes.get(i);
@@ -68,6 +70,8 @@ public class StaticHelper {
                         break;
                     }
                 }
+                // Read the terminating byte.
+                readBuffer.readByte();
                 final byte[] byteArray = new byte[bytes.size()];
                 for (int i = 0; i < bytes.size(); i++) {
                     byteArray[i] = bytes.get(i);


[plc4x] 01/03: fix(plc4j/s7): Fixed the PLC4X272 test and made it run automatically.

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

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

commit 865d5effcda2ce3f9f6e505213e2150dfb6ad6af
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 31 16:38:47 2022 +0200

    fix(plc4j/s7): Fixed the PLC4X272 test and made it run automatically.
---
 .../readwrite/issues/{PLC4X272.java => PLC4X272Test.java}  |  4 ++--
 plc4j/drivers/s7/src/test/resources/tests/PLC4X-272.xml    | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272Test.java
similarity index 91%
rename from plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272.java
rename to plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272Test.java
index f6773e59e..d463ba9ef 100644
--- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272.java
+++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/issues/PLC4X272Test.java
@@ -20,9 +20,9 @@ package org.apache.plc4x.java.s7.readwrite.issues;
 
 import org.apache.plc4x.test.driver.DriverTestsuiteRunner;
 
-public class PLC4X272 extends DriverTestsuiteRunner {
+public class PLC4X272Test extends DriverTestsuiteRunner {
 
-    public PLC4X272() {
+    public PLC4X272Test() {
         super("/tests/PLC4X-272.xml");
     }
 
diff --git a/plc4j/drivers/s7/src/test/resources/tests/PLC4X-272.xml b/plc4j/drivers/s7/src/test/resources/tests/PLC4X-272.xml
index b9829f1c4..662901906 100644
--- a/plc4j/drivers/s7/src/test/resources/tests/PLC4X-272.xml
+++ b/plc4j/drivers/s7/src/test/resources/tests/PLC4X-272.xml
@@ -60,13 +60,6 @@
               </protocolClass>
             </COTPPacketConnectionRequest>
             <parameters isList="true">
-              <COTPParameter>
-                <parameterType dataType="uint" bitLength="8">194</parameterType>
-                <parameterLength dataType="uint" bitLength="8">2</parameterLength>
-                <COTPParameterCalledTsap>
-                  <tsapId dataType="uint" bitLength="16">256</tsapId>
-                </COTPParameterCalledTsap>
-              </COTPParameter>
               <COTPParameter>
                 <parameterType dataType="uint" bitLength="8">193</parameterType>
                 <parameterLength dataType="uint" bitLength="8">2</parameterLength>
@@ -74,6 +67,13 @@
                   <tsapId dataType="uint" bitLength="16">785</tsapId>
                 </COTPParameterCallingTsap>
               </COTPParameter>
+              <COTPParameter>
+                <parameterType dataType="uint" bitLength="8">194</parameterType>
+                <parameterLength dataType="uint" bitLength="8">2</parameterLength>
+                <COTPParameterCalledTsap>
+                  <tsapId dataType="uint" bitLength="16">256</tsapId>
+                </COTPParameterCalledTsap>
+              </COTPParameter>
               <COTPParameter>
                 <parameterType dataType="uint" bitLength="8">192</parameterType>
                 <parameterLength dataType="uint" bitLength="8">1</parameterLength>


[plc4x] 02/03: fix(plc4j/spi): Added the missing "getObject" method to the PlcStruct

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

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

commit 386189f4ddcedddb6c98aa105ec2927ff30289c5
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Aug 31 16:39:13 2022 +0200

    fix(plc4j/spi): Added the missing "getObject" method to the PlcStruct
---
 .../src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java    | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java
index 055ffb481..77f6c12b3 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java
@@ -39,6 +39,11 @@ public class PlcStruct extends PlcValueAdapter {
 
     private final Map<String, PlcValue> map;
 
+    @Override
+    public Object getObject() {
+        return map;
+    }
+
     @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
     public PlcStruct(@JsonProperty("map") Map<String, PlcValue> map) {
         this.map = Collections.unmodifiableMap(map);