You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2021/07/28 19:13:41 UTC

[plc4x] branch develop updated: Fix for initial OPCUA sequence number, some servers don't start at 1

This is an automated email from the ASF dual-hosted git repository.

hutcheb 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 0f8c760  Fix for initial OPCUA sequence number, some servers don't start at 1
0f8c760 is described below

commit 0f8c76011b44c24b1af287cd8a75e0b05f10e880
Author: hutcheb <hu...@apache.org>
AuthorDate: Thu Jul 29 05:11:59 2021 +1000

    Fix for initial OPCUA sequence number, some servers don't start at 1
---
 .../org/apache/plc4x/java/opcua/context/SecureChannel.java | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
index a05069c..49a98ad 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/context/SecureChannel.java
@@ -45,6 +45,7 @@ import java.time.Duration;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 
@@ -113,7 +114,7 @@ public class SecureChannel {
     private CompletableFuture<Void> keepAlive;
     private int sendBufferSize;
     private int maxMessageSize;
-    private long senderSequenceNumber;
+    private AtomicLong senderSequenceNumber = new AtomicLong();
 
     public SecureChannel(DriverContext driverContext, OpcuaConfiguration configuration) {
         this.driverContext = driverContext;
@@ -181,6 +182,10 @@ public class SecureChannel {
                         if (p.getRequestId() == transactionId) {
                             try {
                                 messageBuffer.write(p.getMessage());
+                                if (!(senderSequenceNumber.incrementAndGet() == (p.getSequenceNumber()))) {
+                                    LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - {} != {}", senderSequenceNumber.incrementAndGet(), p.getSequenceNumber());
+                                    context.fireDisconnected();
+                                }
                             } catch (IOException e) {
                                 LOGGER.debug("Failed to store incoming message in buffer {}");
                                 throw new PlcRuntimeException("Error while sending message");
@@ -199,10 +204,7 @@ public class SecureChannel {
                             tokenId.set(opcuaResponse.getSecureTokenId());
                             channelId.set(opcuaResponse.getSecureChannelId());
 
-                            if (!(transactionId == (opcuaResponse.getSequenceNumber() + 1))) {
-                                LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - {} != {}", transactionId, opcuaResponse.getSequenceNumber() + 1);
-                                context.fireDisconnected();
-                            }
+
                             consumer.accept(messageBuffer.toByteArray());
                         }
                     });
@@ -322,7 +324,7 @@ public class SecureChannel {
                             ReadBuffer readBuffer = new ReadBufferByteBased(opcuaOpenResponse.getMessage(), true);
                             ExtensionObject message = ExtensionObjectIO.staticParse(readBuffer, false);
                             //Store the initial sequence number from the server. there's no requirement for the server and client to use the same starting number.
-                            senderSequenceNumber = opcuaOpenResponse.getSequenceNumber();
+                            senderSequenceNumber.set(opcuaOpenResponse.getSequenceNumber());
                             certificateThumbprint = opcuaOpenResponse.getReceiverCertificateThumbprint();
 
                             if (message.getBody() instanceof ServiceFault) {