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
The following commit(s) were added to refs/heads/develop by this push:
new 3a08112369 fix: [Bug]: The s7 driver causes issues when writing arrays
of bits fix: [Bug]: When reading an array of bits, the old s7 driver seems to
hang.
3a08112369 is described below
commit 3a081123699f7fc1c73ea9e778177e8c63b7a51e
Author: Christofer Dutz <[email protected]>
AuthorDate: Sun Aug 10 18:04:07 2025 +0200
fix: [Bug]: The s7 driver causes issues when writing arrays of bits
fix: [Bug]: When reading an array of bits, the old s7 driver seems to hang.
closes: #2214, #2215
---
.../s7/readwrite/protocol/S7ProtocolLogic.java | 31 +++++++++++++++++++++
.../readwrite/protocol/S7ProtocolLogic.java | 32 ++++++++++++++++++----
.../java/s7/readwrite/ManualS71200DriverTest.java | 12 ++++----
.../java/s7/readwrite/ManualS71200DriverTest2.java | 4 +--
4 files changed, 66 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 883f592aab..bc759e2c4b 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
@@ -2060,6 +2060,25 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
if((tag.getDataType() == TransportSize.BYTE) &&
(tag.getNumberOfElements() > 1)) {
byteBuffer = ByteBuffer.allocate(tag.getNumberOfElements());
byteBuffer.put(plcValue.getRaw());
+ } else if((tag.getDataType() == TransportSize.BOOL) &&
(tag.getNumberOfElements() > 1)) {
+ if(!(plcValue instanceof PlcList)) {
+ throw new PlcRuntimeException(String.format("Expected a
PlcList with %d PlcBOOL elements", tag.getNumberOfElements()));
+ }
+ PlcList plcList = (PlcList) plcValue;
+ int numBytes = (tag.getNumberOfElements() + 7) / 8;
+ byteBuffer = ByteBuffer.allocate(numBytes);
+ for (int i = 0; i < tag.getNumberOfElements(); i++) {
+ if(!(plcList.getIndex(i) instanceof PlcBOOL)) {
+ throw new PlcRuntimeException(String.format("Expected
a PlcList with %d PlcBOOL elements", tag.getNumberOfElements()));
+ }
+ PlcBOOL plcBOOL = (PlcBOOL) plcList.getIndex(i);
+ if(plcBOOL.getBoolean()) {
+ int curByte = i / 8;
+ int curBit = i % 8;
+ byteBuffer.put(curByte, (byte) (1 << curBit |
byteBuffer.get(curByte)));
+ }
+ }
+ transportSize = DataTransportSize.BYTE_WORD_DWORD;
} else {
for (int i = 0; i < tag.getNumberOfElements(); i++) {
int lengthInBits =
DataItem.getLengthInBits(plcValue.getIndex(i),
tag.getDataType().getDataProtocolId(), s7DriverContext.getControllerType(),
stringLength);
@@ -2104,6 +2123,15 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
// probably expecting to process the read raw data.
if(tag.getDataType() == TransportSize.BYTE) {
return new PlcRawByteArray(data);
+ } else if(tag.getDataType() == TransportSize.BOOL) {
+ final PlcValue[] resultItems = IntStream.range(0,
tag.getNumberOfElements()).mapToObj(i -> {
+ int bitOffset = i;
+ int byteOffset = bitOffset / 8;
+ bitOffset = bitOffset % 8;
+ boolean bitValue = ((data[byteOffset] >> bitOffset) &
0x01) != 0;
+ return PlcBOOL.of(bitValue);
+ }).toArray(PlcValue[]::new);
+ return DefaultPlcValueHandler.of(tag, resultItems);
} else {
// Fetch all
final PlcValue[] resultItems = IntStream.range(0,
tag.getNumberOfElements()).mapToObj(i -> {
@@ -2202,6 +2230,9 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
transportSize = TransportSize.CHAR;
int stringLength = (s7Tag instanceof S7StringFixedLengthTag) ?
((S7StringFixedLengthTag) s7Tag).getStringLength() : 254;
numElements = numElements * (stringLength + 2) * 2;
+ } else if ((transportSize == TransportSize.BOOL) &&
(s7Tag.getNumberOfElements() > 1)) {
+ numElements = (s7Tag.getNumberOfElements() + 7) / 8;
+ transportSize = TransportSize.BYTE;
}
if (transportSize.getCode() == 0x00) {
numElements = numElements * transportSize.getSizeInBytes();
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 939c2d97b2..357e7ea02a 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
@@ -608,7 +608,7 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
short errorClass;
short errorCode;
- S7ParameterUserDataItemCPUFunctions parameteritem;
+ S7ParameterUserDataItemCPUFunctions parameterItem;
if (responseMessage instanceof S7MessageResponseData) {
S7MessageResponseData messageResponseData =
(S7MessageResponseData) responseMessage;
errorClass = messageResponseData.getErrorClass();
@@ -620,9 +620,9 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
} else if (responseMessage instanceof S7MessageUserData) {
S7MessageUserData messageResponse = (S7MessageUserData)
responseMessage;
S7ParameterUserData parameters = (S7ParameterUserData)
messageResponse.getParameter();
- parameteritem = (S7ParameterUserDataItemCPUFunctions)
parameters.getItems().get(0);
+ parameterItem = (S7ParameterUserDataItemCPUFunctions)
parameters.getItems().get(0);
errorClass = 0;
- errorCode = parameteritem.getErrorCode().shortValue();
+ errorCode = parameterItem.getErrorCode().shortValue();
} else {
throw new PlcProtocolException("Unsupported message type " +
responseMessage.getClass().getName());
}
@@ -665,7 +665,7 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
// If the numbers of items don't match, we're in big trouble as the
only
// way to know how to interpret the responses is by aligning them with
the
- // items from the request as this information is not returned by the
PLC.
+ // items from the request as the PLC does not return this information.
if (plcReadRequest.getNumberOfTags() != payload.getItems().size()) {
throw new PlcProtocolException(
"The number of requested items doesn't match the number of
returned items");
@@ -781,6 +781,25 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
if((tag.getDataType() == TransportSize.BYTE) &&
(tag.getNumberOfElements() > 1)) {
byteBuffer = ByteBuffer.allocate(tag.getNumberOfElements());
byteBuffer.put(plcValue.getRaw());
+ } else if((tag.getDataType() == TransportSize.BOOL) &&
(tag.getNumberOfElements() > 1)) {
+ if(!(plcValue instanceof PlcList)) {
+ throw new PlcRuntimeException(String.format("Expected a
PlcList with %d PlcBOOL elements", tag.getNumberOfElements()));
+ }
+ PlcList plcList = (PlcList) plcValue;
+ int numBytes = (tag.getNumberOfElements() + 7) / 8;
+ byteBuffer = ByteBuffer.allocate(numBytes);
+ for (int i = 0; i < tag.getNumberOfElements(); i++) {
+ if(!(plcList.getIndex(i) instanceof PlcBOOL)) {
+ throw new PlcRuntimeException(String.format("Expected
a PlcList with %d PlcBOOL elements", tag.getNumberOfElements()));
+ }
+ PlcBOOL plcBOOL = (PlcBOOL) plcList.getIndex(i);
+ if(plcBOOL.getBoolean()) {
+ int curByte = i / 8;
+ int curBit = i % 8;
+ byteBuffer.put(curByte, (byte) (1 << curBit |
byteBuffer.get(curByte)));
+ }
+ }
+ transportSize = DataTransportSize.BYTE_WORD_DWORD;
} else {
for (int i = 0; i < tag.getNumberOfElements(); i++) {
int lengthInBits =
DataItem.getLengthInBits(plcValue.getIndex(i),
tag.getDataType().getDataProtocolId(), s7DriverContext.getControllerType(),
stringLength);
@@ -900,7 +919,7 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
}
/**
- * Currently we only support the S7 Any type of addresses. This helper
simply converts the S7Tag
+ * Currently, we only support the S7 Any type of addresses. This helper
simply converts the S7Tag
* from PLC4X into S7Address objects.
*
* @param tag S7Tag instance we need to convert into an S7Address
@@ -923,6 +942,9 @@ public class S7ProtocolLogic extends
Plc4xProtocolBase<TPKTPacket> {
transportSize = TransportSize.CHAR;
int stringLength = (s7Tag instanceof S7StringFixedLengthTag) ?
((S7StringFixedLengthTag) s7Tag).getStringLength() : 254;
numElements = numElements * (stringLength + 2) * 2;
+ } else if ((transportSize == TransportSize.BOOL) &&
(s7Tag.getNumberOfElements() > 1)) {
+ numElements = (s7Tag.getNumberOfElements() + 7) / 8;
+ transportSize = TransportSize.BYTE;
}
if (transportSize.getCode() == 0x00) {
numElements = numElements * transportSize.getSizeInBytes();
diff --git
a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
index 12f0c7df8d..3e506b186c 100644
---
a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
+++
b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
@@ -73,7 +73,7 @@ public class ManualS71200DriverTest extends ManualTest {
public static void main(String[] args) throws Exception {
ManualS71200DriverTest test = new
ManualS71200DriverTest("s7-light://192.168.23.30");
- test.addTestCase("%DB4:0.0:BOOL", new PlcBOOL(true));
+ /*test.addTestCase("%DB4:0.0:BOOL", new PlcBOOL(true));
test.addTestCase("%DB4:1:BYTE", new PlcBYTE(42));
test.addTestCase("%DB4:2:WORD", new PlcWORD(42424));
test.addTestCase("%DB4:4:DWORD", new PlcDWORD(4242442424L));
@@ -88,14 +88,14 @@ public class ManualS71200DriverTest extends ManualTest {
test.addTestCase("%DB4:136:CHAR", new PlcCHAR("H"));
test.addTestCase("%DB4:138:WCHAR", new PlcWCHAR("w"));
test.addTestCase("%DB4:140:STRING(10)", new PlcSTRING("hurz"));
- test.addTestCase("%DB4:396:WSTRING(10)", new PlcWSTRING("wolf"));
- //test.addTestCase("%DB4:140:STRING", new PlcSTRING("hurz"));
- //test.addTestCase("%DB4:396:WSTRING", new PlcWSTRING("wolf"));
- test.addTestCase("%DB4:58:TIME", new
PlcTIME(Duration.parse("PT1.234S")));
+ test.addTestCase("%DB4:396:WSTRING(10)", new PlcWSTRING("wolf"));*/
+ test.addTestCase("%DB4:140:STRING", new PlcSTRING("hurz"));
+ test.addTestCase("%DB4:396:WSTRING", new PlcWSTRING("wolf"));
+ /*test.addTestCase("%DB4:58:TIME", new
PlcTIME(Duration.parse("PT1.234S")));
test.addTestCase("%DB4:70:DATE", new
PlcDATE(LocalDate.parse("1998-03-28")));
test.addTestCase("%DB4:72:TIME_OF_DAY", new
PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123")));
test.addTestCase("%DB4:908:CHAR[5]", new PlcList(Arrays.asList(new
PlcCHAR("w"), new PlcCHAR("i"), new PlcCHAR("e"), new PlcCHAR("s"), new
PlcCHAR("e"))));
- test.addTestCase("%DB4:914:RAW_BYTE_ARRAY[11]", new
PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5,
(byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11}));
+ test.addTestCase("%DB4:914:RAW_BYTE_ARRAY[11]", new
PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5,
(byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11}));*/
// Disabled, as we currently only have the large-array-splitting for
read requests.
/*test.addTestCase("%DB4:926:DINT[100]", new PlcList(Arrays.asList(new
PlcDINT(1), new PlcDINT(2), new PlcDINT(3), new PlcDINT(4), new PlcDINT(5), new
PlcDINT(6), new PlcDINT(7), new PlcDINT(8), new PlcDINT(9),
new PlcDINT(0), new PlcDINT(1), new PlcDINT(2), new PlcDINT(3),
new PlcDINT(4), new PlcDINT(5), new PlcDINT(6), new PlcDINT(7), new PlcDINT(8),
new PlcDINT(9),
diff --git
a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest2.java
b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest2.java
index acd2347bbe..b03447968c 100644
---
a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest2.java
+++
b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest2.java
@@ -41,13 +41,13 @@ public class ManualS71200DriverTest2 extends ManualTest {
}
public static void main(String[] args) throws Exception {
- ManualS71200DriverTest2 test = new
ManualS71200DriverTest2("s7://192.168.23.30");
+ ManualS71200DriverTest2 test = new
ManualS71200DriverTest2("s7-light://192.168.23.30");
test.addTestCase("%I0.0:BOOL", new PlcBOOL(false));
test.addTestCase("%I0.1:BOOL", new PlcBOOL(true));
test.addTestCase("%I0.2:BOOL", new PlcBOOL(true));
test.addTestCase("%I0.3:BOOL", new PlcBOOL(false));
test.addTestCase("%I0.4:BOOL", new PlcBOOL(false));
- //test.addTestCase("%I0.0:BOOL[5]", new PlcList(new
ArrayList<>(List.of(new PlcBOOL(false), new PlcBOOL(true), new PlcBOOL(true),
new PlcBOOL(false), new PlcBOOL(false)))));
+ test.addTestCase("%I0.0:BOOL[10]", new PlcList(new
ArrayList<>(List.of(new PlcBOOL(false), new PlcBOOL(true), new PlcBOOL(true),
new PlcBOOL(false), new PlcBOOL(false), new PlcBOOL(false), new PlcBOOL(false),
new PlcBOOL(false), new PlcBOOL(false), new PlcBOOL(false)))));
long start = System.currentTimeMillis();
test.run();