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 2025/11/05 14:57:25 UTC
(plc4x) 03/03: fix: Fixed a small issue in serializing STRING and WSTRING values.
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 ae5a5a259bc6c894043355929ff3f196ba9ab462
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Nov 5 15:57:10 2025 +0100
fix: Fixed a small issue in serializing STRING and WSTRING values.
fixes: #2328
---
.../java/s7/readwrite/protocol/S7ProtocolLogic.java | 3 +++
.../plc4x/java/s7/readwrite/utils/StaticHelper.java | 15 +++++++++++----
.../s7light/readwrite/protocol/S7ProtocolLogic.java | 21 ++++++++++++---------
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
index bc759e2c4b..d3ae7fbfbe 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
@@ -2055,6 +2055,9 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
private S7VarPayloadDataItem serializePlcValue(S7Tag tag, PlcValue plcValue) {
try {
DataTransportSize transportSize = tag.getDataType().getDataTransportSize();
+ // In the case of STRING, the default and the max stringLength are both 254. With WSTRING the default
+ // is also 254. For WSTRING, the max stringLength is 16382. Here we're only handling the default, the
+ // max is handled in the StaticHelper.
int stringLength = (tag instanceof S7StringFixedLengthTag) ? ((S7StringFixedLengthTag) tag).getStringLength() : 254;
ByteBuffer byteBuffer = null;
if((tag.getDataType() == TransportSize.BYTE) && (tag.getNumberOfElements() > 1)) {
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
index 709cfc7fcf..453d9c2b75 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
@@ -2690,12 +2690,13 @@ public class StaticHelper {
* the String as char arrays from your application.
*/
public static void serializeS7String(WriteBuffer io, PlcValue value, int stringLength, String encoding) {
- int maxStringLength = 0xFF & Math.min(stringLength, 250);
- int actStringLength = 0xFF & value.getString().length();
- actStringLength = Math.min(maxStringLength, actStringLength);
-
switch (encoding) {
case "UTF-8": {
+ // In the case of STRING, the default and the max stringLength is 254.
+ int maxStringLength = 0xFF & Math.min(stringLength, 254);
+ int actStringLength = 0xFF & value.getString().length();
+ actStringLength = Math.min(maxStringLength, actStringLength);
+
byte[] chars = new byte[maxStringLength];
byte[] actChars = value.getString().substring(0, actStringLength).getBytes(StandardCharsets.UTF_8);
System.arraycopy(actChars, 0, chars, 0, actChars.length);
@@ -2709,6 +2710,12 @@ public class StaticHelper {
break;
}
case "UTF-16": {
+ // In the case of WSTRING the default is also 254. However, the max stringLength is 16382.
+ // As we've settled the default handling in S7ProtocolLogic, we'll only handle the max here.
+ int maxStringLength = 0xFFFF & Math.min(stringLength, 16382);
+ int actStringLength = 0xFFFF & value.getString().length();
+ actStringLength = Math.min(maxStringLength, actStringLength);
+
byte[] chars = new byte[maxStringLength * 2];
byte[] actChars = value.getString().substring(0, actStringLength).getBytes(StandardCharsets.UTF_16BE);
System.arraycopy(actChars, 0, chars, 0, actChars.length);
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7light/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7light/readwrite/protocol/S7ProtocolLogic.java
index 357e7ea02a..a83d39bdf3 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7light/readwrite/protocol/S7ProtocolLogic.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7light/readwrite/protocol/S7ProtocolLogic.java
@@ -71,9 +71,9 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
super.setDriverContext(driverContext);
this.s7DriverContext = (S7DriverContext) driverContext;
// Initialize Transaction Manager.
- // Until the number of concurrent requests is successfully negotiated we set it to a
- // maximum of only one request being able to be sent at a time. During the login process
- // No concurrent requests can be sent anyway. It will be updated when receiving the
+ // Until the number of concurrent requests is successfully negotiated, we set it to a
+ // maximum of only one request being able to be sent at a time. During the login process,
+ // no concurrent requests can be sent anyway. It will be updated when receiving the
// S7ParameterSetupCommunication response.
this.tm = new RequestTransactionManager(1);
}
@@ -136,7 +136,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
// If the controller type is explicitly set, were finished with the login
// process. If it's set to ANY, we have to query the serial number information
- // in order to detect the type of PLC.
+ // to detect the type of PLC.
if (s7DriverContext.getControllerType() != ControllerType.ANY) {
// Send an event that connection setup is complete.
context.fireConnected();
@@ -225,7 +225,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
CompletableFuture<S7Message> responseFuture = new CompletableFuture<>();
// If the list of tags contains at least one STRING/WSTRING element,
- // we need to check the sizes of the string fields in a first request.
+ // we need to check the sizes of the string fields in the first request.
if (request.getTagNames().stream().anyMatch(t -> request.getTag(t) instanceof S7StringVarLengthTag)) {
responseFuture = performVarLengthStringWriteRequest((DefaultPlcWriteRequest) writeRequest);
}
@@ -776,6 +776,9 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
private S7VarPayloadDataItem serializePlcValue(S7Tag tag, PlcValue plcValue) {
try {
DataTransportSize transportSize = tag.getDataType().getDataTransportSize();
+ // In the case of STRING, the default and the max stringLength are both 254. With WSTRING the default
+ // is also 254. For WSTRING, the max stringLength is 16382. Here we're only handling the default, the
+ // max is handled in the StaticHelper.
int stringLength = (tag instanceof S7StringFixedLengthTag) ? ((S7StringFixedLengthTag) tag).getStringLength() : 254;
ByteBuffer byteBuffer = null;
if((tag.getDataType() == TransportSize.BYTE) && (tag.getNumberOfElements() > 1)) {
@@ -956,7 +959,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
private int getTpduId() {
int tpduId = tpduGenerator.getAndIncrement();
- // If we've reached the max value for a 16 bit transaction identifier, reset back to 1
+ // If we've reached the max value for a 16-bit transaction identifier, reset back to 1
if (tpduGenerator.get() == 0xFFFF) {
tpduGenerator.set(1);
}
@@ -964,7 +967,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
}
/**
- * A generic purpose error handler which terminates transaction and calls back given future with error message.
+ * A generic purpose error handler which terminates a transaction and calls back the given future with an error message.
*/
static class TransactionErrorCallback<T, E extends Throwable> implements Consumer<TimeoutException>, BiConsumer<TPKTPacket, E> {
@@ -1007,7 +1010,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
.collect(Collectors.toList());
List<S7VarRequestParameterItem> stringFields = new ArrayList<>(varLengthStringTags.size());
for (S7StringVarLengthTag varLengthStringTag : varLengthStringTags) {
- // For STRING, the header is 2 bytes (first byte contains the max length and the second the actual length)
+ // For STRING, the header is 2 bytes (The first byte contains the max length, and the second the actual length)
if (varLengthStringTag.getDataType() == TransportSize.STRING) {
stringFields.add(new S7VarRequestParameterItemAddress(
new S7AddressAny(
@@ -1019,7 +1022,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
varLengthStringTag.getBitOffset()
)));
}
- // For WSTRING, the header is 4 bytes (first word contains the max length and the second the actual length)
+ // For WSTRING, the header is 4 bytes (The first word contains the max length, and the second the actual length)
else if (varLengthStringTag.getDataType() == TransportSize.WSTRING) {
stringFields.add(new S7VarRequestParameterItemAddress(
new S7AddressAny(