Browse Source

save last seen immediate subscription (#1359)

* fix #1356

* Update ua_services_subscription.c
StalderT 7 years ago
parent
commit
252677ee46
3 changed files with 35 additions and 7 deletions
  1. 32 7
      src/server/ua_services_subscription.c
  2. 2 0
      src/ua_session.c
  3. 1 0
      src/ua_session.h

+ 32 - 7
src/server/ua_services_subscription.c

@@ -474,14 +474,39 @@ Service_Publish(UA_Server *server, UA_Session *session,
 
     /* Answer immediately to a late subscription */
     UA_Subscription *immediate;
-    LIST_FOREACH(immediate, &session->serverSubscriptions, listEntry) {
-        if(immediate->state == UA_SUBSCRIPTIONSTATE_LATE) {
-            UA_LOG_DEBUG_SESSION(server->config.logger, session, "Subscription %u | "
-                                 "Response on a late subscription", immediate->subscriptionID);
-            UA_Subscription_publishCallback(server, immediate);
-            break;
-        }
+    UA_Boolean found = true; 
+    int loopCount = 1;
+
+    if (session->lastSeenSubscriptionID > 0){
+        /* If we found anything one the first loop or if there are LATE 
+         * in the list before lastSeenSubscriptionID and not LATE after 
+         * lastSeenSubscriptionID we need a second loop.
+         */
+        loopCount = 2;
+        /* We must find the last seen subscription id  */
+        found = false;
+    }
+
+    for(int i=0; i<loopCount; i++){
+       LIST_FOREACH(immediate, &session->serverSubscriptions, listEntry) {
+            if (!found){
+                if (session->lastSeenSubscriptionID == immediate->subscriptionID){
+                    found = true; 
+                }     
+            }else{
+                if(immediate->state == UA_SUBSCRIPTIONSTATE_LATE) {
+                    session->lastSeenSubscriptionID = immediate->subscriptionID;
+                    UA_LOG_DEBUG_SESSION(server->config.logger, session, "Subscription %u | "
+                                         "Response on a late subscription", immediate->subscriptionID);
+                    UA_Subscription_publishCallback(server, immediate);
+                    return;
+                }     
+            }     
+        }     
+        /* after the first loop, we can publish the first subscription with UA_SUBSCRIPTIONSTATE_LATE */
+        found = true;
     }
+    session->lastSeenSubscriptionID = 0;
 }
 
 static void

+ 2 - 0
src/ua_session.c

@@ -30,6 +30,7 @@ UA_Session adminSession = {
     {NULL}, /* .continuationPoints */
 #ifdef UA_ENABLE_SUBSCRIPTIONS
     0, /* .lastSubscriptionID */
+    0, /* .lastSeenSubscriptionID */
     {NULL}, /* .serverSubscriptions */
     {NULL, NULL}, /* .responseQueue */
 #endif
@@ -52,6 +53,7 @@ void UA_Session_init(UA_Session *session) {
 #ifdef UA_ENABLE_SUBSCRIPTIONS
     LIST_INIT(&session->serverSubscriptions);
     session->lastSubscriptionID = 0;
+    session->lastSeenSubscriptionID = 0;
     SIMPLEQ_INIT(&session->responseQueue);
 #endif
 }

+ 1 - 0
src/ua_session.h

@@ -56,6 +56,7 @@ struct UA_Session {
     LIST_HEAD(ContinuationPointList, ContinuationPointEntry) continuationPoints;
 #ifdef UA_ENABLE_SUBSCRIPTIONS
     UA_UInt32 lastSubscriptionID;
+    UA_UInt32 lastSeenSubscriptionID;
     LIST_HEAD(UA_ListOfUASubscriptions, UA_Subscription) serverSubscriptions;
     SIMPLEQ_HEAD(UA_ListOfQueuedPublishResponses, UA_PublishResponseEntry) responseQueue;
 #endif