Browse Source

Added possibility to disable retransmission queue of sessions

The Micro Embedded UA profile allow devices to not support the
retransmission queue implemented by the session when DataChange
Subscriptions are supported. Previously there has been no possibility
to disable this queue. Disabling this queue can save some memory on
a resource constrained device.

Change-Id: I4e324b41f85bffdd0e640fb173f82c121a2044b5
Jonas Green 5 years ago
parent
commit
db5dc3d570
3 changed files with 31 additions and 22 deletions
  1. 6 5
      include/ua_server_config.h
  2. 1 0
      plugins/ua_config_default.c
  3. 24 17
      src/server/ua_subscription.c

+ 6 - 5
include/ua_server_config.h

@@ -1,6 +1,6 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  *    Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
@@ -155,6 +155,7 @@ struct UA_ServerConfig {
     UA_UInt32Range lifeTimeCountLimits;
     UA_UInt32Range keepAliveCountLimits;
     UA_UInt32 maxNotificationsPerPublish;
+    UA_Boolean enableRetransmissionQueue;
     UA_UInt32 maxRetransmissionQueueSize; /* 0 -> unlimited size */
 #ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
     UA_UInt32 maxEventsPerNode; /* 0 -> unlimited size */
@@ -200,10 +201,10 @@ struct UA_ServerConfig {
     /* Historical Access */
 #ifdef UA_ENABLE_HISTORIZING
     UA_HistoryDatabase historyDatabase;
-    
+
     UA_Boolean accessHistoryDataCapability;
     UA_UInt32  maxReturnDataValues; /* 0 -> unlimited size */
-    
+
     UA_Boolean accessHistoryEventsCapability;
     UA_UInt32  maxReturnEventValues; /* 0 -> unlimited size */
 
@@ -213,10 +214,10 @@ struct UA_ServerConfig {
 
     UA_Boolean replaceDataCapability;
     UA_Boolean replaceEventCapability;
-    
+
     UA_Boolean updateDataCapability;
     UA_Boolean updateEventCapability;
-    
+
     UA_Boolean deleteRawCapability;
     UA_Boolean deleteEventCapability;
     UA_Boolean deleteAtTimeDataCapability;

+ 1 - 0
plugins/ua_config_default.c

@@ -187,6 +187,7 @@ createDefaultConfig(void) {
     conf->lifeTimeCountLimits = UA_UINT32RANGE(3, 15000);
     conf->keepAliveCountLimits = UA_UINT32RANGE(1, 100);
     conf->maxNotificationsPerPublish = 1000;
+    conf->enableRetransmissionQueue = true;
     conf->maxRetransmissionQueueSize = 0; /* unlimited */
 #ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
     conf->maxEventsPerNode = 0; /* unlimited */

+ 24 - 17
src/server/ua_subscription.c

@@ -1,6 +1,6 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  *    Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  *    Copyright 2015 (c) Chris Iatrou
@@ -269,7 +269,7 @@ prepareNotificationMessage(UA_Server *server, UA_Subscription *sub,
     TAILQ_FOREACH_SAFE(notification, &sub->notificationQueue, globalEntry, notification_tmp) {
         if(totalNotifications >= notifications)
             break;
-        
+
         UA_MonitoredItem *mon = notification->mon;
 
         /* Remove from the queues and decrease the counters */
@@ -417,15 +417,17 @@ UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) {
     UA_NotificationMessage *message = &response->notificationMessage;
     UA_NotificationMessageEntry *retransmission = NULL;
     if(notifications > 0) {
-        /* Allocate the retransmission entry */
-        retransmission = (UA_NotificationMessageEntry*)UA_malloc(sizeof(UA_NotificationMessageEntry));
-        if(!retransmission) {
-            UA_LOG_WARNING_SESSION(&server->config.logger, sub->session,
-                                   "Subscription %u | Could not allocate memory for retransmission. "
-                                   "The subscription is late.", sub->subscriptionId);
-            sub->state = UA_SUBSCRIPTIONSTATE_LATE;
-            UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */
-            return;
+        if(server->config.enableRetransmissionQueue) {
+            /* Allocate the retransmission entry */
+            retransmission = (UA_NotificationMessageEntry*)UA_malloc(sizeof(UA_NotificationMessageEntry));
+            if(!retransmission) {
+                UA_LOG_WARNING_SESSION(&server->config.logger, sub->session,
+                                       "Subscription %u | Could not allocate memory for retransmission. "
+                                       "The subscription is late.", sub->subscriptionId);
+                sub->state = UA_SUBSCRIPTIONSTATE_LATE;
+                UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */
+                return;
+            }
         }
 
         /* Prepare the response */
@@ -434,7 +436,9 @@ UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) {
             UA_LOG_WARNING_SESSION(&server->config.logger, sub->session,
                                    "Subscription %u | Could not prepare the notification message. "
                                    "The subscription is late.", sub->subscriptionId);
-            UA_free(retransmission);
+            /* If the retransmission queue is enabled a retransmission message is allocated */
+            if(retransmission)
+                UA_free(retransmission);
             sub->state = UA_SUBSCRIPTIONSTATE_LATE;
             UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */
             return;
@@ -459,11 +463,14 @@ UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) {
     message->sequenceNumber = sub->nextSequenceNumber;
 
     if(notifications > 0) {
-        /* 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);
+        /* If the retransmission queue is enabled a retransmission message is allocated */
+        if(retransmission) {
+            /* 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);