Browse Source

Fix CTT errors for subscription sequence number handling

- rename subscription variable sequence number to nextSequenceNumber
- adjust logic
Martin Lang 6 years ago
parent
commit
25fd8bf0e4
2 changed files with 12 additions and 7 deletions
  1. 11 6
      src/server/ua_subscription.c
  2. 1 1
      src/server/ua_subscription.h

+ 11 - 6
src/server/ua_subscription.c

@@ -13,6 +13,7 @@
  *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
  *    Copyright 2017 (c) Ari Breitkreuz, fortiss GmbH
  *    Copyright 2017 (c) Mattias Bornhager
+ *    Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang)
  */
 
 #include "ua_server_internal.h"
@@ -81,6 +82,9 @@ UA_Subscription_new(UA_Session *session, UA_UInt32 subscriptionId) {
     newSub->session = session;
     newSub->subscriptionId = subscriptionId;
     newSub->state = UA_SUBSCRIPTIONSTATE_NORMAL; /* The first publish response is sent immediately */
+    /* Even if the first publish response is a keepalive the sequence number is 1.
+     * This can happen by a subscription without a monitored item (see CTT test scripts). */
+    newSub->nextSequenceNumber = 1;
     TAILQ_INIT(&newSub->retransmissionQueue);
     TAILQ_INIT(&newSub->notificationQueue);
     return newSub;
@@ -457,19 +461,20 @@ UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) {
     response->moreNotifications = moreNotifications;
     message->publishTime = response->responseHeader.timestamp;
 
-    /* Set the sequence number. The sequence number will be reused if there are
-     * no notifications (and this is a keepalive message). */
-    message->sequenceNumber = UA_Subscription_nextSequenceNumber(sub->sequenceNumber);
+    /* Set sequence number to message. Started at 1 which is given
+     * during creating a new subscription. The 1 is required for
+     * initial publish response with or without an monitored item. */
+    message->sequenceNumber = sub->nextSequenceNumber;
 
     if(notifications > 0) {
-        /* There are notifications. So we can't reuse the sequence number. */
-        sub->sequenceNumber = message->sequenceNumber;
-
         /* Put the notification message into the retransmission queue. This
          * needs to be done here, so that the message itself is included in the
          * available sequence numbers for acknowledgement. */
         retransmission->message = response->notificationMessage;
         UA_Subscription_addRetransmissionMessage(server, sub, retransmission);
+        /* Only if a notification was created, the sequence number must be increased.
+         * For a keepalive the sequence number can be reused. */
+        sub->nextSequenceNumber = UA_Subscription_nextSequenceNumber(sub->nextSequenceNumber);
     }
 
     /* Get the available sequence numbers from the retransmission queue */

+ 1 - 1
src/server/ua_subscription.h

@@ -170,7 +170,7 @@ struct UA_Subscription {
 
     /* Runtime information */
     UA_SubscriptionState state;
-    UA_UInt32 sequenceNumber;
+    UA_UInt32 nextSequenceNumber;
     UA_UInt32 currentKeepAliveCount;
     UA_UInt32 currentLifetimeCount;