Browse Source

fix(PubSub): Publishing order of multiple DataSetFields

 - The order of DSF should be the same while creating and publishing and
   the existing implementation publishes reversely
 - Used TAILQ structure for DSF instead of LIST structure

Signed-off-by: Suriya Narayanan Parthasarathi Vimala <suriyanarayanan.pv@kalycito.com>

Change-Id: I4a32fd0cec5becb0457e4040d8b1d7c64aef9836
Suriya Narayanan Parthasarathi Vimala 4 years ago
parent
commit
112492f6bb

+ 2 - 2
src/pubsub/ua_pubsub.h

@@ -36,7 +36,7 @@ typedef struct UA_ReaderGroup UA_ReaderGroup;
 typedef struct{
     UA_PublishedDataSetConfig config;
     UA_DataSetMetaDataType dataSetMetaData;
-    LIST_HEAD(UA_ListOfDataSetField, UA_DataSetField) fields;
+    TAILQ_HEAD(UA_ListOfDataSetField, UA_DataSetField) fields;
     UA_NodeId identifier;
     UA_UInt16 fieldSize;
     UA_UInt16 promotedFieldsCount;
@@ -176,7 +176,7 @@ UA_WriterGroup_setPubSubState(UA_Server *server, UA_PubSubState state, UA_Writer
 typedef struct UA_DataSetField{
     UA_DataSetFieldConfig config;
     //internal fields
-    LIST_ENTRY(UA_DataSetField) listEntry;
+    TAILQ_ENTRY(UA_DataSetField) listEntry;
     UA_NodeId identifier;
     UA_NodeId publishedDataSet;             //ref to parent pds
     UA_FieldMetaData fieldMetaData;

+ 5 - 5
src/pubsub/ua_pubsub_manager.c

@@ -185,11 +185,11 @@ UA_Server_addPublishedDataSet(UA_Server *server, const UA_PublishedDataSetConfig
     server->pubSubManager.publishedDataSets = newPubSubDataSetField;
     UA_PublishedDataSet *newPubSubDataSet = &server->pubSubManager.publishedDataSets[(server->pubSubManager.publishedDataSetsSize)];
     memset(newPubSubDataSet, 0, sizeof(UA_PublishedDataSet));
-    LIST_INIT(&newPubSubDataSet->fields);
+    TAILQ_INIT(&newPubSubDataSet->fields);
     //workaround - fixing issue with queue.h and realloc.
     for(size_t n = 0; n < server->pubSubManager.publishedDataSetsSize; n++){
-        if(server->pubSubManager.publishedDataSets[n].fields.lh_first){
-            server->pubSubManager.publishedDataSets[n].fields.lh_first->listEntry.le_prev = &server->pubSubManager.publishedDataSets[n].fields.lh_first;
+        if(server->pubSubManager.publishedDataSets[n].fields.tqh_first){
+            server->pubSubManager.publishedDataSets[n].fields.tqh_first->listEntry.tqe_prev = &server->pubSubManager.publishedDataSets[n].fields.tqh_first;
         }
     }
     newPubSubDataSet->config = tmpPublishedDataSetConfig;
@@ -267,8 +267,8 @@ UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds) {
         }
         //workaround - fixing issue with queue.h and realloc.
         for(size_t n = 0; n < server->pubSubManager.publishedDataSetsSize; n++){
-            if(server->pubSubManager.publishedDataSets[n].fields.lh_first){
-                server->pubSubManager.publishedDataSets[n].fields.lh_first->listEntry.le_prev = &server->pubSubManager.publishedDataSets[n].fields.lh_first;
+            if(server->pubSubManager.publishedDataSets[n].fields.tqh_first){
+                server->pubSubManager.publishedDataSets[n].fields.tqh_first->listEntry.tqe_prev = &server->pubSubManager.publishedDataSets[n].fields.tqh_first;
             }
         }
     }

+ 1 - 1
src/pubsub/ua_pubsub_ns0.c

@@ -143,7 +143,7 @@ onRead(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
                 UA_calloc(publishedDataSet->fieldSize, sizeof(UA_PublishedVariableDataType));
             size_t counter = 0;
             UA_DataSetField *field;
-            LIST_FOREACH(field, &publishedDataSet->fields, listEntry) {
+            TAILQ_FOREACH(field, &publishedDataSet->fields, listEntry) {
                 pvd[counter].attributeId = UA_ATTRIBUTEID_VALUE;
                 pvd[counter].publishedVariable = field->config.field.variable.publishParameters.publishedVariable;
                 //UA_NodeId_copy(&field->config.field.variable.publishParameters.publishedVariable, &pvd[counter].publishedVariable);

+ 14 - 8
src/pubsub/ua_pubsub_writer.c

@@ -243,7 +243,7 @@ UA_Server_freezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId writ
         publishedDataSet->config.configurationFrozen = UA_TRUE;
         //DataSetFields freeze
         UA_DataSetField *dataSetField;
-        LIST_FOREACH(dataSetField, &publishedDataSet->fields, listEntry){
+        TAILQ_FOREACH(dataSetField, &publishedDataSet->fields, listEntry){
             dataSetField->config.configurationFrozen = UA_TRUE;
         }
     }
@@ -280,7 +280,7 @@ UA_Server_unfreezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId wr
         if(publishedDataSet->configurationFreezeCounter == 0){
             publishedDataSet->config.configurationFrozen = UA_FALSE;
             UA_DataSetField *dataSetField;
-            LIST_FOREACH(dataSetField, &publishedDataSet->fields, listEntry){
+            TAILQ_FOREACH(dataSetField, &publishedDataSet->fields, listEntry){
                 dataSetField->config.configurationFrozen = UA_FALSE;
             }
         }
@@ -393,7 +393,7 @@ UA_PublishedDataSet_clear(UA_Server *server, UA_PublishedDataSet *publishedDataS
     //delete PDS
     UA_DataSetMetaDataType_clear(&publishedDataSet->dataSetMetaData);
     UA_DataSetField *field, *tmpField;
-    LIST_FOREACH_SAFE(field, &publishedDataSet->fields, listEntry, tmpField) {
+    TAILQ_FOREACH_SAFE(field, &publishedDataSet->fields, listEntry, tmpField) {
         UA_Server_removeDataSetField(server, field->identifier);
     }
     UA_NodeId_clear(&publishedDataSet->identifier);
@@ -442,7 +442,13 @@ UA_Server_addDataSetField(UA_Server *server, const UA_NodeId publishedDataSet,
     newField->publishedDataSet = currentDataSet->identifier;
     //update major version of parent published data set
     currentDataSet->dataSetMetaData.configurationVersion.majorVersion = UA_PubSubConfigurationVersionTimeDifference();
-    LIST_INSERT_HEAD(&currentDataSet->fields, newField, listEntry);
+    /* The order of DataSetFields should be the same in both creating and publishing.
+     * So adding DataSetFields at the the end of the DataSets using TAILQ structure */
+    if (currentDataSet->fieldSize != 0)
+        TAILQ_INSERT_TAIL(&currentDataSet->fields, newField, listEntry);
+    else
+        TAILQ_INSERT_HEAD(&currentDataSet->fields, newField, listEntry);
+
     if(newField->config.field.variable.promotedField)
         currentDataSet->promotedFieldsCount++;
     currentDataSet->fieldSize++;
@@ -486,7 +492,7 @@ UA_Server_removeDataSetField(UA_Server *server, const UA_NodeId dsf) {
         UA_PubSubConfigurationVersionTimeDifference();
 
     UA_DataSetField_clear(currentField);
-    LIST_REMOVE(currentField, listEntry);
+    TAILQ_REMOVE(&parentPublishedDataSet->fields, currentField, listEntry);
     UA_free(currentField);
 
     result.result = UA_STATUSCODE_GOOD;
@@ -1006,7 +1012,7 @@ UA_DataSetField *
 UA_DataSetField_findDSFbyId(UA_Server *server, UA_NodeId identifier) {
     for(size_t i = 0; i < server->pubSubManager.publishedDataSetsSize; i++){
         UA_DataSetField *tmpField;
-        LIST_FOREACH(tmpField, &server->pubSubManager.publishedDataSets[i].fields, listEntry){
+        TAILQ_FOREACH(tmpField, &server->pubSubManager.publishedDataSets[i].fields, listEntry){
             if(UA_NodeId_equal(&tmpField->identifier, &identifier)){
                 return tmpField;
             }
@@ -1134,7 +1140,7 @@ UA_PubSubDataSetWriter_generateKeyFrameMessage(UA_Server *server, UA_DataSetMess
     /* Loop over the fields */
     size_t counter = 0;
     UA_DataSetField *dsf;
-    LIST_FOREACH(dsf, &currentDataSet->fields, listEntry) {
+    TAILQ_FOREACH(dsf, &currentDataSet->fields, listEntry) {
 
 #ifdef UA_ENABLE_JSON_ENCODING
         /* json: store the fieldNameAlias*/
@@ -1196,7 +1202,7 @@ UA_PubSubDataSetWriter_generateDeltaFrameMessage(UA_Server *server,
 
     UA_DataSetField *dsf;
     size_t counter = 0;
-    LIST_FOREACH(dsf, &currentDataSet->fields, listEntry) {
+    TAILQ_FOREACH(dsf, &currentDataSet->fields, listEntry) {
         /* Sample the value */
         UA_DataValue value;
         UA_DataValue_init(&value);

+ 2 - 2
tests/pubsub/check_pubsub_config_freeze.c

@@ -93,7 +93,7 @@ START_TEST(CreateAndLockConfiguration) {
     UA_PublishedDataSet *publishedDataSet = UA_PublishedDataSet_findPDSbyId(server, dataSetWriter->connectedDataSet);
     ck_assert(publishedDataSet->config.configurationFrozen == UA_TRUE);
     UA_DataSetField *dsf;
-    LIST_FOREACH(dsf ,&publishedDataSet->fields , listEntry){
+    TAILQ_FOREACH(dsf ,&publishedDataSet->fields , listEntry){
         ck_assert(dsf->config.configurationFrozen == UA_TRUE);
     }
     //set state to disabled and implicit unlock the configuration
@@ -157,7 +157,7 @@ START_TEST(CreateAndLockConfigurationWithExternalAPI) {
         UA_PublishedDataSet *publishedDataSet = UA_PublishedDataSet_findPDSbyId(server, dataSetWriter->connectedDataSet);
         ck_assert(publishedDataSet->config.configurationFrozen == UA_TRUE);
         UA_DataSetField *dsf;
-        LIST_FOREACH(dsf ,&publishedDataSet->fields , listEntry){
+        TAILQ_FOREACH(dsf ,&publishedDataSet->fields , listEntry){
             ck_assert(dsf->config.configurationFrozen == UA_TRUE);
         }
         //set state to disabled and implicit unlock the configuration