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/08/30 14:53:35 UTC
(plc4x) branch develop updated: fix: [Bug]: Improve error handling in S7 large arrays #1741 If one part of a multi-part message is broken, treat all parts as equally broken.
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 5561f4daa7 fix: [Bug]: Improve error handling in S7 large arrays #1741 If one part of a multi-part message is broken, treat all parts as equally broken.
5561f4daa7 is described below
commit 5561f4daa7dc56d4fb797f9192a459521c44a113
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Fri Aug 30 16:53:28 2024 +0200
fix: [Bug]: Improve error handling in S7 large arrays #1741
If one part of a multi-part message is broken, treat all parts as equally broken.
---
.../java/s7/readwrite/optimizer/S7Optimizer.java | 73 +++++++++++++---------
1 file changed, 44 insertions(+), 29 deletions(-)
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
index 69a42f9003..3620413efd 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
@@ -40,6 +40,7 @@ import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
import org.apache.plc4x.java.spi.messages.utils.TagValueItem;
import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
import org.apache.plc4x.java.spi.utils.Serializable;
+import org.apache.plc4x.java.spi.values.PlcNull;
import org.apache.plc4x.java.spi.values.PlcRawByteArray;
import org.apache.plc4x.java.spi.values.PlcValueAdapter;
@@ -185,37 +186,51 @@ public class S7Optimizer extends BaseOptimizer {
S7Tag globalS7Tag = (S7Tag) readRequest.getTag(tagName);
S7Tag currentS7Tag = (S7Tag) curRequest.getTag(tagName);
if(currentS7Tag.getNumberOfElements() != globalS7Tag.getNumberOfElements()) {
- // We have to merge byte-array data differently.
- if(globalS7Tag.getDataType() == TransportSize.BYTE) {
- PlcRawByteArray existingItem;
- if (tagValues.containsKey(tagName)) {
- ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
- existingItem = (PlcRawByteArray) existingTagItem.getValue();
- } else {
- existingItem = new PlcRawByteArray(new byte[globalS7Tag.getNumberOfElements()]);
- tagValues.put(tagName, new ResponseItem<>(responseCode, existingItem));
+ if(responseCode == PlcResponseCode.OK) {
+ // We have to merge byte-array data differently.
+ if (globalS7Tag.getDataType() == TransportSize.BYTE) {
+ PlcRawByteArray existingItem;
+ if (tagValues.containsKey(tagName)) {
+ ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
+ // If a previous response was invalid, we'll discard this part of it too.
+ if(existingTagItem.getCode() != PlcResponseCode.OK) {
+ continue;
+ }
+ existingItem = (PlcRawByteArray) existingTagItem.getValue();
+ } else {
+ existingItem = new PlcRawByteArray(new byte[globalS7Tag.getNumberOfElements()]);
+ tagValues.put(tagName, new ResponseItem<>(responseCode, existingItem));
+ }
+ byte[] currentItemByteArray = value.getRaw();
+ int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
+ byte[] existingByteArray = existingItem.getRaw();
+ System.arraycopy(currentItemByteArray, 0, existingByteArray, elementOffset, currentItemByteArray.length);
}
- byte[] currentItemByteArray = value.getRaw();
- int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
- byte[] existingByteArray = existingItem.getRaw();
- System.arraycopy(currentItemByteArray, 0, existingByteArray, elementOffset, currentItemByteArray.length);
- }
- // Merge typical list-type responses.
- else {
- List<PlcValue> existingItems;
- if (tagValues.containsKey(tagName)) {
- ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
- existingItems = (List<PlcValue>) existingTagItem.getValue().getList();
- } else {
- existingItems = new ArrayList<>(Arrays.asList(new PlcValue[globalS7Tag.getNumberOfElements()]));
- PlcListModifiable mergedValue = new PlcListModifiable(existingItems);
- tagValues.put(tagName, new ResponseItem<>(responseCode, mergedValue));
- }
- List<? extends PlcValue> currentItems = value.getList();
- int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
- for (int i = 0; i < currentS7Tag.getNumberOfElements(); i++) {
- existingItems.set(i + elementOffset, currentItems.get(i));
+ // Merge typical list-type responses.
+ else {
+ List<PlcValue> existingItems;
+ if (tagValues.containsKey(tagName)) {
+ ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
+ // If a previous response was invalid, we'll discard this part of it too.
+ if(existingTagItem.getCode() != PlcResponseCode.OK) {
+ continue;
+ }
+ existingItems = (List<PlcValue>) existingTagItem.getValue().getList();
+ } else {
+ existingItems = new ArrayList<>(Arrays.asList(new PlcValue[globalS7Tag.getNumberOfElements()]));
+ PlcListModifiable mergedValue = new PlcListModifiable(existingItems);
+ tagValues.put(tagName, new ResponseItem<>(responseCode, mergedValue));
+ }
+ List<? extends PlcValue> currentItems = value.getList();
+ int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
+ for (int i = 0; i < currentS7Tag.getNumberOfElements(); i++) {
+ existingItems.set(i + elementOffset, currentItems.get(i));
+ }
}
+ } else {
+ // Even if a previous part was ok, if at least one part is invalid, we'll
+ // treat all parts equally broken.
+ tagValues.put(tagName, new ResponseItem<>(responseCode, new PlcNull()));
}
} else {
tagValues.put(tagName, new ResponseItem<>(responseCode, value));