You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cg...@apache.org on 2023/01/29 00:38:04 UTC
[plc4x] branch develop updated: Fix issue-701 for S7 driver. (#770)
This is an automated email from the ASF dual-hosted git repository.
cgarcia 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 fd8d1f4608 Fix issue-701 for S7 driver. (#770)
fd8d1f4608 is described below
commit fd8d1f4608fef510204f5300369fe6bded066d63
Author: César José García León <ce...@gmail.com>
AuthorDate: Sat Jan 28 20:37:53 2023 -0400
Fix issue-701 for S7 driver. (#770)
* Fix issue-701 for S7 driver.
* Fix symbol for hasNext parameter.
---------
Co-authored-by: César García <ce...@ceos.com.ve>
---
.../s7/readwrite/S7PayloadReadVarResponse.java | 2 +-
.../java/s7/readwrite/S7VarPayloadDataItem.java | 39 ++++++++++++++++++----
.../s7/readwrite/protocol/S7ProtocolLogic.java | 27 ++++++++++++---
plc4j/drivers/s7/src/test/java/S7IoTest.java | 3 +-
.../plc4x/java/spi/generation/StaticHelper.java | 4 +++
.../server/s7/protocol/S7Step7ServerAdapter.java | 6 ++--
.../s7/src/main/resources/protocols/s7/s7.mspec | 11 +++---
7 files changed, 71 insertions(+), 21 deletions(-)
diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7PayloadReadVarResponse.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7PayloadReadVarResponse.java
index c4209e3341..7b4551d234 100644
--- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7PayloadReadVarResponse.java
+++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7PayloadReadVarResponse.java
@@ -103,7 +103,7 @@ public class S7PayloadReadVarResponse extends S7Payload implements Message {
readCountArrayField(
"items",
new DataReaderComplexDefault<>(
- () -> S7VarPayloadDataItem.staticParse(readBuffer), readBuffer),
+ () -> S7VarPayloadDataItem.staticParse(readBuffer, (boolean) (true)), readBuffer),
CAST(parameter, S7ParameterReadVarResponse.class).getNumItems());
readBuffer.closeContext("S7PayloadReadVarResponse");
diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7VarPayloadDataItem.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7VarPayloadDataItem.java
index c61ffe226f..f08cb90ecd 100644
--- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7VarPayloadDataItem.java
+++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/S7VarPayloadDataItem.java
@@ -42,12 +42,19 @@ public class S7VarPayloadDataItem implements Message {
protected final DataTransportSize transportSize;
protected final byte[] data;
+ // Arguments.
+ protected final Boolean hasNext;
+
public S7VarPayloadDataItem(
- DataTransportErrorCode returnCode, DataTransportSize transportSize, byte[] data) {
+ DataTransportErrorCode returnCode,
+ DataTransportSize transportSize,
+ byte[] data,
+ Boolean hasNext) {
super();
this.returnCode = returnCode;
this.transportSize = transportSize;
this.data = data;
+ this.hasNext = hasNext;
}
public DataTransportErrorCode getReturnCode() {
@@ -102,7 +109,10 @@ public class S7VarPayloadDataItem implements Message {
// Padding Field (padding)
writePaddingField(
- "padding", (int) ((COUNT(data)) % (2)), (short) 0x00, writeUnsignedShort(writeBuffer, 8));
+ "padding",
+ (int) (((PADCOUNT(data, hasNext)) % (2))),
+ (short) 0x00,
+ writeUnsignedShort(writeBuffer, 8));
writeBuffer.popContext("S7VarPayloadDataItem");
}
@@ -132,7 +142,7 @@ public class S7VarPayloadDataItem implements Message {
}
// Padding Field (padding)
- int _timesPadding = (int) ((COUNT(data)) % (2));
+ int _timesPadding = (int) (((PADCOUNT(data, hasNext)) % (2)));
while (_timesPadding-- > 0) {
lengthInBits += 8;
}
@@ -143,10 +153,25 @@ public class S7VarPayloadDataItem implements Message {
public static S7VarPayloadDataItem staticParse(ReadBuffer readBuffer, Object... args)
throws ParseException {
PositionAware positionAware = readBuffer;
- return staticParse(readBuffer);
+ if ((args == null) || (args.length != 1)) {
+ throw new PlcRuntimeException(
+ "Wrong number of arguments, expected 1, but got " + args.length);
+ }
+ Boolean hasNext;
+ if (args[0] instanceof Boolean) {
+ hasNext = (Boolean) args[0];
+ } else if (args[0] instanceof String) {
+ hasNext = Boolean.valueOf((String) args[0]);
+ } else {
+ throw new PlcRuntimeException(
+ "Argument 0 expected to be of type Boolean or a string which is parseable but was "
+ + args[0].getClass().getName());
+ }
+ return staticParse(readBuffer, hasNext);
}
- public static S7VarPayloadDataItem staticParse(ReadBuffer readBuffer) throws ParseException {
+ public static S7VarPayloadDataItem staticParse(ReadBuffer readBuffer, Boolean hasNext)
+ throws ParseException {
readBuffer.pullContext("S7VarPayloadDataItem");
PositionAware positionAware = readBuffer;
int startPos = positionAware.getPos();
@@ -174,12 +199,12 @@ public class S7VarPayloadDataItem implements Message {
Math.toIntExact(
((transportSize.getSizeInBits()) ? CEIL((dataLength) / (8.0)) : dataLength)));
- readPaddingField(readUnsignedShort(readBuffer, 8), (int) ((COUNT(data)) % (2)));
+ readPaddingField(readUnsignedShort(readBuffer, 8), (int) (((PADCOUNT(data, hasNext)) % (2))));
readBuffer.closeContext("S7VarPayloadDataItem");
// Create the instance
S7VarPayloadDataItem _s7VarPayloadDataItem;
- _s7VarPayloadDataItem = new S7VarPayloadDataItem(returnCode, transportSize, data);
+ _s7VarPayloadDataItem = new S7VarPayloadDataItem(returnCode, transportSize, data, hasNext);
return _s7VarPayloadDataItem;
}
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 f36a06cd5f..9e7f790e49 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
@@ -324,12 +324,29 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
DefaultPlcWriteRequest request = (DefaultPlcWriteRequest) writeRequest;
List<S7VarRequestParameterItem> parameterItems = new ArrayList<>(request.getNumberOfTags());
List<S7VarPayloadDataItem> payloadItems = new ArrayList<>(request.getNumberOfTags());
- for (String tagName : request.getTagNames()) {
+
+ Iterator<String> iter = request.getTagNames().iterator();
+
+ String tagName = null;
+ while(iter.hasNext()) {
+ tagName = iter.next();
final S7Tag tag = (S7Tag) request.getTag(tagName);
final PlcValue plcValue = request.getPlcValue(tagName);
parameterItems.add(new S7VarRequestParameterItemAddress(encodeS7Address(tag)));
- payloadItems.add(serializePlcValue(tag, plcValue));
+ payloadItems.add(serializePlcValue(tag, plcValue, iter.hasNext()));
}
+
+
+// for (String tagName : request.getTagNames()) {
+// final S7Tag tag = (S7Tag) request.getTag(tagName);
+// final PlcValue plcValue = request.getPlcValue(tagName);
+// parameterItems.add(new S7VarRequestParameterItemAddress(encodeS7Address(tag)));
+// payloadItems.add(serializePlcValue(tag, plcValue));
+//
+// }
+
+
+
final int tpduId = tpduGenerator.getAndIncrement();
// If we've reached the max value for a 16 bit transaction identifier, reset back to 1
if (tpduGenerator.get() == 0xFFFF) {
@@ -347,7 +364,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
(short) tpduId
)
);
-
+
// Start a new request-transaction (Is ended in the response-handler)
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
transaction.submit(() -> context.sendRequest(tpktPacket)
@@ -897,7 +914,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
return new DefaultPlcWriteResponse(plcWriteRequest, responses);
}
- private S7VarPayloadDataItem serializePlcValue(S7Tag tag, PlcValue plcValue) {
+ private S7VarPayloadDataItem serializePlcValue(S7Tag tag, PlcValue plcValue, Boolean hasNext) {
try {
DataTransportSize transportSize = tag.getDataType().getDataTransportSize();
int stringLength = (tag instanceof S7StringTag) ? ((S7StringTag) tag).getStringLength() : 254;
@@ -914,7 +931,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
}
if (byteBuffer != null) {
byte[] data = byteBuffer.array();
- return new S7VarPayloadDataItem(DataTransportErrorCode.OK, transportSize, data);
+ return new S7VarPayloadDataItem(DataTransportErrorCode.OK, transportSize, data, hasNext);
}
} catch (SerializationException e) {
logger.warn("Error serializing tag item of type: '{}'", tag.getDataType().name(), e);
diff --git a/plc4j/drivers/s7/src/test/java/S7IoTest.java b/plc4j/drivers/s7/src/test/java/S7IoTest.java
index 2c23628e3d..86d3639c76 100644
--- a/plc4j/drivers/s7/src/test/java/S7IoTest.java
+++ b/plc4j/drivers/s7/src/test/java/S7IoTest.java
@@ -340,7 +340,8 @@ public class S7IoTest {
new S7VarPayloadDataItem(
DataTransportErrorCode.OK,
DataTransportSize.BIT,
- new byte[]{0x1}
+ new byte[]{0x1},
+ false
)
)
),
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
index 60e0fccd31..93883498a9 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/StaticHelper.java
@@ -121,5 +121,9 @@ public class StaticHelper {
public static int CEIL(double value) {
return (int) Math.ceil(value);
}
+
+ public static int PADCOUNT(Object obj, boolean hasNext) {
+ return hasNext ? COUNT(obj) : 0;
+ }
}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
index d50501e822..c10e27659c 100644
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
+++ b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
@@ -254,7 +254,7 @@ public class S7Step7ServerAdapter extends ChannelInboundHandlerAdapter {
final byte bitAddress = addressAny.getBitAddress();
switch (addressAny.getTransportSize()) {
case BOOL:
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BIT, new byte[]{1}));
+ payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BIT, new byte[]{1}, true));
break;
case INT:
case UINT: {
@@ -264,7 +264,7 @@ public class S7Step7ServerAdapter extends ChannelInboundHandlerAdapter {
byte[] data = new byte[2];
data[1] = (byte) (shortValue & 0xff);
data[0] = (byte) ((shortValue >> 8) & 0xff);
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data));
+ payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data, true));
break;
}
default: {
@@ -280,7 +280,7 @@ public class S7Step7ServerAdapter extends ChannelInboundHandlerAdapter {
addressAny.getNumberOfElements() : addressAny.getTransportSize().getSizeInBytes() * 8;
final BitSet bitSet = toBitSet(context.getDigitalInputs(), ioNumber, numElements);
final byte[] data = Arrays.copyOf(bitSet.toByteArray(), (numElements + 7) / 8);
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data));
+ payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data, true));
break;
}
}
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 33f3ccb79c..de32c36dbe 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -1,4 +1,4 @@
-/*
+'/*
* 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
@@ -223,7 +223,7 @@
[discriminatedType S7Payload (uint 8 messageType, S7Parameter parameter)
[typeSwitch parameter.parameterType, messageType
['0x04','0x03' S7PayloadReadVarResponse
- [array S7VarPayloadDataItem items count 'CAST(parameter, "S7ParameterReadVarResponse").numItems']
+ [array S7VarPayloadDataItem ('true') items count 'CAST(parameter, "S7ParameterReadVarResponse").numItems']
]
['0x05','0x01' S7PayloadWriteVarRequest
[array S7VarPayloadDataItem items count 'COUNT(CAST(parameter, "S7ParameterWriteVarRequest").items)']
@@ -238,12 +238,15 @@
]
// This is actually not quite correct as depending pon the transportSize the length is either defined in bits or bytes.
-[type S7VarPayloadDataItem
+//@param hasNext In the serialization process, if you have multiple write
+// requests the last element does not require padding.
+[type S7VarPayloadDataItem(bit hasNext)
[simple DataTransportErrorCode returnCode]
[simple DataTransportSize transportSize]
[implicit uint 16 dataLength 'COUNT(data) * ((transportSize == DataTransportSize.BIT) ? 1 : (transportSize.sizeInBits ? 8 : 1))']
[array byte data count 'transportSize.sizeInBits ? CEIL(dataLength / 8.0) : dataLength']
- [padding uint 8 pad '0x00' 'COUNT(data) % 2']
+ //[padding uint 8 pad '0x00' '(COUNT(data) % 2)']
+ [padding uint 8 pad '0x00' '(PADCOUNT(data, hasNext) % 2)']
]
[type S7VarPayloadStatusItem