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 2024/02/10 09:50:54 UTC
(plc4x) branch fix/enum-discriminators updated (4740679109 -> bf3517f2f3)
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a change to branch fix/enum-discriminators
in repository https://gitbox.apache.org/repos/asf/plc4x.git
from 4740679109 fix: Got the testsuite working so far that I can now start investigating the main issue.
new 66807cb69c refactor: Changed PlcSINT to serialize to int and not as byte (So it matches the way the other numerical types are serialized to XML)
new e7d35278dc fix: Fixed an issue with serializing PlcStructs
new bf3517f2f3 fix: Fixed one of the problems when writing structs (Some times some leading padding bytes were needed) However there still seems to be an issue with writing WSTRINGs
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:
.../plc4x/java/ads/protocol/AdsProtocolLogic.java | 17 +++
.../org/apache/plc4x/java/spi/values/PlcSINT.java | 2 +-
.../apache/plc4x/java/spi/values/PlcStruct.java | 2 +-
.../internal/handlers/ApiRequestHandler.java | 144 ++++++++++++++++-
.../resources/protocols/ads/DriverTestsuite.xml | 170 ++++++++++++++++++++-
5 files changed, 325 insertions(+), 10 deletions(-)
(plc4x) 03/03: fix: Fixed one of the problems when writing structs (Some times some leading padding bytes were needed) However there still seems to be an issue with writing WSTRINGs
Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch fix/enum-discriminators
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit bf3517f2f39a7bd79e77d57c372def5795c70eb6
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Sat Feb 10 10:50:34 2024 +0100
fix: Fixed one of the problems when writing structs (Some times some leading padding bytes were needed) However there still seems to be an issue with writing WSTRINGs
---
.../plc4x/java/ads/protocol/AdsProtocolLogic.java | 17 +++
.../internal/handlers/ApiRequestHandler.java | 144 ++++++++++++++++-
.../resources/protocols/ads/DriverTestsuite.xml | 170 ++++++++++++++++++++-
3 files changed, 323 insertions(+), 8 deletions(-)
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 e66dd8b68d..ec16551b48 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
@@ -883,12 +883,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
int startPos = readBuffer.getPos();
int curPos = 0;
for (AdsDataTypeTableChildEntry child : adsDataTypeTableEntry.getChildren()) {
+ // In some cases the starting position of the data is not where we are expecting it.
+ // So we need to skip some bytes.
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);
@@ -900,6 +903,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
}
PlcValue propertyValue = parsePlcValue(propertyPlcValueType, propertyDataTypeTableEntry, strLen, readBuffer);
properties.put(propertyName, propertyValue);
+
curPos = readBuffer.getPos() - startPos;
}
return new PlcStruct(properties);
@@ -1151,13 +1155,26 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
throw new SerializationException("Expected a PlcStruct, but got a " + contextValue.getPlcValueType().name());
}
PlcStruct plcStruct = (PlcStruct) contextValue;
+ int startPos = writeBuffer.getPos();
+ int curPos = 0;
for (AdsDataTypeTableChildEntry child : dataType.getChildren()) {
AdsDataTypeTableEntry childDataType = dataTypeTable.get(child.getDataTypeName());
if (!plcStruct.hasKey(child.getPropertyName())) {
throw new SerializationException("PlcStruct is missing a child with the name " + child.getPropertyName());
}
+ // In some cases the starting position of the data is not where we are expecting it.
+ // So we need to add some fill-bytes.
+ if (child.getOffset() > curPos) {
+ long fillBytes = child.getOffset() - curPos;
+ for(long i = 0; i < fillBytes; i++) {
+ writeBuffer.writeByte("fillByte", (byte) 0x00);
+ }
+ }
+
PlcValue childValue = plcStruct.getValue(child.getPropertyName());
serializeInternal(childValue, childDataType, childDataType.getArrayInfo(), writeBuffer);
+
+ curPos = writeBuffer.getPos() - startPos;
}
}
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/internal/handlers/ApiRequestHandler.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/internal/handlers/ApiRequestHandler.java
index b3616289fa..764fbb8454 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/internal/handlers/ApiRequestHandler.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/internal/handlers/ApiRequestHandler.java
@@ -23,12 +23,17 @@ import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.apache.plc4x.java.spi.values.*;
import org.apache.plc4x.test.driver.exceptions.DriverTestsuiteException;
import org.apache.plc4x.test.driver.internal.utils.Synchronizer;
import org.dom4j.Element;
-import java.util.ArrayList;
-import java.util.List;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
public class ApiRequestHandler {
@@ -67,12 +72,21 @@ public class ApiRequestHandler {
if (payload.element("tags") != null) {
for (Element tagElement : payload.element("tags").elements("tag")) {
List<Element> valueElements = tagElement.elements("value");
- List<String> valueStrings = new ArrayList<>(valueElements.size());
+ List<Object> valueObjects = new ArrayList<>(valueElements.size());
for (Element valueElement : valueElements) {
- valueStrings.add(valueElement.getTextTrim());
+ // If the element is a simple text element, use this driectly.
+ if(valueElement.isTextOnly()) {
+ valueObjects.add(valueElement.getTextTrim());
+ }
+ // If the value is a "PlcValue" element, try to parse this.
+ else if (valueElement.elements() != null) {
+ for (Element element : valueElement.elements()) {
+ valueObjects.add(parsePlcValue(element));
+ }
+ }
}
builder.addTagAddress(tagElement.elementText("name"),
- tagElement.elementText("address"), valueStrings.toArray(new Object[0]));
+ tagElement.elementText("address"), valueObjects.toArray(new Object[0]));
}
}
final PlcWriteRequest plc4xRequest = builder.build();
@@ -94,4 +108,124 @@ public class ApiRequestHandler {
}
}
+ protected PlcValue parsePlcValue(Element element) {
+ switch (element.getName()) {
+ case "PlcStruct": {
+ Map<String, PlcValue> structContent = new LinkedHashMap<>();
+ for (Element field : element.elements()) {
+ String fieldName = field.getName();
+ if((field.elements() == null) || (field.elements().size() != 1)) {
+ throw new RuntimeException("Expected exactly one child element");
+ }
+ Element valueElement = field.elements().get(0);
+ PlcValue fieldValue = parsePlcValue(valueElement);
+ structContent.put(fieldName, fieldValue);
+ }
+ return new PlcStruct(structContent);
+ }
+ case "PlcList": {
+ // TODO: Implement this ...
+ }
+ case "PlcNULL": {
+ return new PlcNull();
+ }
+
+ case "PlcBOOL": {
+ return new PlcBOOL(element.getTextTrim());
+ }
+ case "PlcBYTE": {
+ return new PlcBYTE(element.getTextTrim());
+ }
+ case "PlcWORD": {
+ return new PlcWORD(element.getTextTrim());
+ }
+ case "PlcDWORD": {
+ return new PlcDWORD(element.getTextTrim());
+ }
+ case "PlcLWORD": {
+ return new PlcLWORD(element.getTextTrim());
+ }
+
+ case "PlcUSINT": {
+ return new PlcUSINT(element.getTextTrim());
+ }
+ case "PlcUINT": {
+ return new PlcUINT(element.getTextTrim());
+ }
+ case "PlcUDINT": {
+ return new PlcUDINT(element.getTextTrim());
+ }
+ case "PlcULINT": {
+ return new PlcULINT(element.getTextTrim());
+ }
+
+ case "PlcSINT": {
+ return new PlcSINT(element.getTextTrim());
+ }
+ case "PlcINT": {
+ return new PlcINT(element.getTextTrim());
+ }
+ case "PlcDINT": {
+ return new PlcDINT(element.getTextTrim());
+ }
+ case "PlcLINT": {
+ return new PlcLINT(element.getTextTrim());
+ }
+
+ case "PlcREAL": {
+ return new PlcREAL(element.getTextTrim());
+ }
+ case "PlcLREAL": {
+ return new PlcLREAL(element.getTextTrim());
+ }
+
+ case "PlcCHAR": {
+ return new PlcCHAR(element.getTextTrim());
+ }
+ case "PlcWCHAR": {
+ return new PlcWCHAR(element.getTextTrim());
+ }
+ case "PlcSTRING": {
+ return new PlcSTRING(element.getTextTrim());
+ }
+ case "PlcWSTRING": {
+ return new PlcWSTRING(element.getTextTrim());
+ }
+
+ case "PlcTIME": {
+ long milliseconds = Long.parseLong(element.getTextTrim());
+ return new PlcTIME(milliseconds);
+ }
+ case "PlcLTIME": {
+ return new PlcLTIME(Duration.parse(element.getTextTrim()));
+ }
+ case "PlcDATE": {
+ return new PlcDATE(LocalDate.parse(element.getTextTrim()));
+ }
+ case "PlcLDATE": {
+ return new PlcLDATE(LocalDate.parse(element.getTextTrim()));
+ }
+ case "PlcTIME_OF_DAY": {
+ return new PlcTIME_OF_DAY(LocalTime.parse(element.getTextTrim()));
+ }
+ case "PlcLTIME_OF_DAY": {
+ return new PlcLTIME_OF_DAY(LocalTime.parse(element.getTextTrim()));
+ }
+ case "PlcDATE_AND_TIME": {
+ return new PlcDATE_AND_TIME(LocalDateTime.parse(element.getTextTrim()));
+ }
+ case "PlcDATE_AND_LTIME": {
+ return new PlcDATE_AND_LTIME(LocalDateTime.parse(element.getTextTrim()));
+ }
+ case "PlcLDATE_AND_TIME": {
+ return new PlcLDATE_AND_TIME(LocalDateTime.parse(element.getTextTrim()));
+ }
+
+ /*case "PlcRAW_BYTE_ARRAY": {
+ return new PlcRAW_BYTE_ARRAY(element.getTextTrim());
+ }*/
+ default: throw new RuntimeException("Unsupported type of PlcValue " + element.getName());
+ }
+ }
+
}
diff --git a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
index 011ba553f2..cc73c96910 100644
--- a/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
+++ b/protocols/ads/src/test/resources/protocols/ads/DriverTestsuite.xml
@@ -1143,6 +1143,100 @@
</userdata>
</AmsTCPPacket>
</incoming-plc-message>
+ <api-response name="Report Read Response to application">
+ <PlcReadResponse>
+ <request>
+ <PlcReadRequest>
+ <PlcTagRequest>
+ <tags isList="true">
+ <hurz>
+ <SymbolicAdsTag>
+ <symbolicAddress dataType="string" bitLength="128" encoding="UTF-8">MAIN.hurz_Struct</symbolicAddress>
+ </SymbolicAdsTag>
+ </hurz>
+ </tags>
+ </PlcTagRequest>
+ </PlcReadRequest>
+ </request>
+ <values isList="true">
+ <hurz>
+ <ResponseItem>
+ <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
+ <value>
+ <PlcStruct>
+ <hurz_STRING>
+ <PlcSTRING dataType="string" bitLength="32" encoding="UTF-8">hurz</PlcSTRING>
+ </hurz_STRING>
+ <hurz_LTIME>
+ <PlcLTIME dataType="string" bitLength="192" encoding="UTF-8">PT24015H23M12.034002044S</PlcLTIME>
+ </hurz_LTIME>
+ <hurz_LWORD>
+ <PlcLWORD dataType="int" bitLength="64">4</PlcLWORD>
+ </hurz_LWORD>
+ <hurz_REAL>
+ <PlcREAL dataType="float" bitLength="32">13.0</PlcREAL>
+ </hurz_REAL>
+ <hurz_ULINT>
+ <PlcULINT dataType="int" bitLength="64">12</PlcULINT>
+ </hurz_ULINT>
+ <hurz_WSTRING>
+ <PlcWSTRING dataType="string" bitLength="80" encoding="UTF-8">wolf</PlcWSTRING>
+ </hurz_WSTRING>
+ <hurz_LINT>
+ <PlcLINT dataType="int" bitLength="64">11</PlcLINT>
+ </hurz_LINT>
+ <hurz_DATE_AND_TIME>
+ <PlcDATE_AND_TIME dataType="string" bitLength="152" encoding="UTF-8">1996-05-06T15:36:30</PlcDATE_AND_TIME>
+ </hurz_DATE_AND_TIME>
+ <hurz_UINT>
+ <PlcUINT dataType="int" bitLength="16">8</PlcUINT>
+ </hurz_UINT>
+ <hurz_SINT>
+ <PlcSINT dataType="int" bitLength="8">5</PlcSINT>
+ </hurz_SINT>
+ <hurz_USINT>
+ <PlcUSINT dataType="int" bitLength="8">6</PlcUSINT>
+ </hurz_USINT>
+ <hurz_LREAL>
+ <PlcLREAL dataType="float" bitLength="64">14.0</PlcLREAL>
+ </hurz_LREAL>
+ <hurz_TIME_OF_DAY>
+ <PlcTIME_OF_DAY dataType="string" bitLength="96" encoding="UTF-8">15:36:30.123</PlcTIME_OF_DAY>
+ </hurz_TIME_OF_DAY>
+ <hurz_BOOL>
+ <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
+ </hurz_BOOL>
+ <hurz_DINT>
+ <PlcDINT dataType="int" bitLength="32">9</PlcDINT>
+ </hurz_DINT>
+ <hurz_UDINT>
+ <PlcUDINT dataType="int" bitLength="32">10</PlcUDINT>
+ </hurz_UDINT>
+ <hurz_BYTE>
+ <PlcBYTE dataType="int" bitLength="8">1</PlcBYTE>
+ </hurz_BYTE>
+ <hurz_TIME>
+ <PlcTIME dataType="int" bitLength="32">1234</PlcTIME>
+ </hurz_TIME>
+ <hurz_DWORD>
+ <PlcDWORD dataType="int" bitLength="32">3</PlcDWORD>
+ </hurz_DWORD>
+ <hurz_INT>
+ <PlcINT dataType="int" bitLength="16">7</PlcINT>
+ </hurz_INT>
+ <hurz_WORD>
+ <PlcWORD dataType="int" bitLength="16">2</PlcWORD>
+ </hurz_WORD>
+ <hurz_DATE>
+ <PlcDATE dataType="string" bitLength="80" encoding="UTF-8">1978-03-28</PlcDATE>
+ </hurz_DATE>
+ </PlcStruct>
+ </value>
+ </ResponseItem>
+ </hurz>
+ </values>
+ </PlcReadResponse>
+ </api-response>
</steps>
</testcase>
@@ -1150,14 +1244,84 @@
<name>Single element write request for "Struct" type field</name>
<steps>
<api-request name="Receive Write Request from application">
- <TestReadRequest>
+ <TestWriteRequest>
<tags isList="true">
- <tag className="org.apache.plc4x.test.driver.internal.api.TestTag">
+ <tag className="org.apache.plc4x.test.driver.internal.api.TestValueTag">
<name>hurz</name>
<address>MAIN.hurz_Struct</address>
+ <value>
+ <PlcStruct>
+ <hurz_STRING>
+ <PlcSTRING dataType="string" bitLength="32" encoding="UTF-8">hurz</PlcSTRING>
+ </hurz_STRING>
+ <hurz_LTIME>
+ <PlcLTIME dataType="string" bitLength="192" encoding="UTF-8">PT24015H23M12.034002044S</PlcLTIME>
+ </hurz_LTIME>
+ <hurz_LWORD>
+ <PlcLWORD dataType="int" bitLength="64">4</PlcLWORD>
+ </hurz_LWORD>
+ <hurz_REAL>
+ <PlcREAL dataType="float" bitLength="32">13.0</PlcREAL>
+ </hurz_REAL>
+ <hurz_ULINT>
+ <PlcULINT dataType="int" bitLength="64">12</PlcULINT>
+ </hurz_ULINT>
+ <hurz_WSTRING>
+ <PlcWSTRING dataType="string" bitLength="80" encoding="UTF-8">wolf</PlcWSTRING>
+ </hurz_WSTRING>
+ <hurz_LINT>
+ <PlcLINT dataType="int" bitLength="64">11</PlcLINT>
+ </hurz_LINT>
+ <hurz_DATE_AND_TIME>
+ <PlcDATE_AND_TIME dataType="string" bitLength="152" encoding="UTF-8">1996-05-06T15:36:30</PlcDATE_AND_TIME>
+ </hurz_DATE_AND_TIME>
+ <hurz_UINT>
+ <PlcUINT dataType="int" bitLength="16">8</PlcUINT>
+ </hurz_UINT>
+ <hurz_SINT>
+ <PlcSINT dataType="int" bitLength="8">5</PlcSINT>
+ </hurz_SINT>
+ <hurz_USINT>
+ <PlcUSINT dataType="int" bitLength="8">6</PlcUSINT>
+ </hurz_USINT>
+ <hurz_LREAL>
+ <PlcLREAL dataType="float" bitLength="64">14.0</PlcLREAL>
+ </hurz_LREAL>
+ <hurz_TIME_OF_DAY>
+ <PlcTIME_OF_DAY dataType="string" bitLength="96" encoding="UTF-8">15:36:30.123</PlcTIME_OF_DAY>
+ </hurz_TIME_OF_DAY>
+ <hurz_BOOL>
+ <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
+ </hurz_BOOL>
+ <hurz_DINT>
+ <PlcDINT dataType="int" bitLength="32">9</PlcDINT>
+ </hurz_DINT>
+ <hurz_UDINT>
+ <PlcUDINT dataType="int" bitLength="32">10</PlcUDINT>
+ </hurz_UDINT>
+ <hurz_BYTE>
+ <PlcBYTE dataType="int" bitLength="8">1</PlcBYTE>
+ </hurz_BYTE>
+ <hurz_TIME>
+ <PlcTIME dataType="int" bitLength="32">1234</PlcTIME>
+ </hurz_TIME>
+ <hurz_DWORD>
+ <PlcDWORD dataType="int" bitLength="32">3</PlcDWORD>
+ </hurz_DWORD>
+ <hurz_INT>
+ <PlcINT dataType="int" bitLength="16">7</PlcINT>
+ </hurz_INT>
+ <hurz_WORD>
+ <PlcWORD dataType="int" bitLength="16">2</PlcWORD>
+ </hurz_WORD>
+ <hurz_DATE>
+ <PlcDATE dataType="string" bitLength="80" encoding="UTF-8">1978-03-28</PlcDATE>
+ </hurz_DATE>
+ </PlcStruct>
+ </value>
</tag>
</tags>
- </TestReadRequest>
+ </TestWriteRequest>
</api-request>
<outgoing-plc-message name="Send Ads Write Request">
<AmsTCPPacket>
(plc4x) 02/03: fix: Fixed an issue with serializing PlcStructs
Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch fix/enum-discriminators
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit e7d35278dc86ae437d015d8f28d0958d7a6abc0c
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Fri Feb 9 18:50:17 2024 +0100
fix: Fixed an issue with serializing PlcStructs
---
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcStruct.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 cb3393a5da..5b7469795d 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
@@ -94,7 +94,7 @@ public class PlcStruct extends PlcValueAdapter {
throw new PlcRuntimeException("Error serializing. List item doesn't implement XmlSerializable");
}
((Serializable) tagValue).serialize(writeBuffer);
- writeBuffer.pushContext(tagName);
+ writeBuffer.popContext(tagName);
}
writeBuffer.popContext("PlcStruct");
}
(plc4x) 01/03: refactor: Changed PlcSINT to serialize to int and not as byte (So it matches the way the other numerical types are serialized to XML)
Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch fix/enum-discriminators
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 66807cb69c59bb2b67cd3ae1a99d25418b0a099d
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Fri Feb 9 18:49:59 2024 +0100
refactor: Changed PlcSINT to serialize to int and not as byte (So it matches the way the other numerical types are serialized to XML)
---
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java
index 622d0e45b4..852da57090 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcSINT.java
@@ -254,7 +254,7 @@ public class PlcSINT extends PlcIECValue<Byte> {
@Override
public void serialize(WriteBuffer writeBuffer) throws SerializationException {
- writeBuffer.writeByte(getClass().getSimpleName(), value);
+ writeBuffer.writeInt(getClass().getSimpleName(), 8, value);
}
}