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));