diff --git a/dotnet/report_new_dataset/Main.cs b/dotnet/report_new_dataset/Main.cs index 9c708c27..ce6ad8c4 100644 --- a/dotnet/report_new_dataset/Main.cs +++ b/dotnet/report_new_dataset/Main.cs @@ -46,13 +46,6 @@ namespace report_new_dataset { con.Connect(hostname, 102); - List serverDirectory = con.GetServerDirectory(false); - - foreach (string entry in serverDirectory) - { - Console.WriteLine("LD: " + entry); - } - // create a new data set List dataSetElements = new List(); @@ -62,7 +55,11 @@ namespace report_new_dataset dataSetElements.Add("simpleIOGenericIO/GGIO1.AnIn3.mag.f[MX]"); dataSetElements.Add("simpleIOGenericIO/GGIO1.AnIn4.mag.f[MX]"); - string dataSetReference = "simpleIOGenericIO/LLN0.ds1"; + // permanent (domain specific) data set + //string dataSetReference = "simpleIOGenericIO/LLN0.ds1"; + + // temporary (association specific) data set + string dataSetReference = "@newds"; // Note: this function will throw an exception when a data set with the same name already exists con.CreateDataSet(dataSetReference, dataSetElements); @@ -98,7 +95,7 @@ namespace report_new_dataset } // delete the data set - con.DeleteDataSet("simpleIOGenericIO/LLN0.ds1"); + con.DeleteDataSet(dataSetReference); con.Abort(); } diff --git a/src/iec61850/inc_private/mms_mapping.h b/src/iec61850/inc_private/mms_mapping.h index 7ffcaf46..b45b65e7 100644 --- a/src/iec61850/inc_private/mms_mapping.h +++ b/src/iec61850/inc_private/mms_mapping.h @@ -80,6 +80,9 @@ MmsMapping_startEventWorkerThread(MmsMapping* self); void MmsMapping_stopEventWorkerThread(MmsMapping* self); +DataSet* +MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableList variableList); + void MmsMapping_triggerReportObservers(MmsMapping* self, MmsValue* value, ReportInclusionFlag flag); diff --git a/src/iec61850/server/mms_mapping/mms_goose.c b/src/iec61850/server/mms_mapping/mms_goose.c index 256a38d8..6e9d44e5 100644 --- a/src/iec61850/server/mms_mapping/mms_goose.c +++ b/src/iec61850/server/mms_mapping/mms_goose.c @@ -103,8 +103,11 @@ MmsGooseControlBlock_destroy(MmsGooseControlBlock self) GLOBAL_FREEMEM(self->dataSetRef); if (self->dataSet != NULL) { - if (self->isDynamicDataSet) + if (self->isDynamicDataSet) { MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); + self->isDynamicDataSet = false; + self->dataSet = NULL; + } } MmsValue_delete(self->mmsValue); @@ -168,8 +171,11 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self) GLOBAL_FREEMEM(self->dataSetRef); if (self->dataSet != NULL) - if (self->isDynamicDataSet) + if (self->isDynamicDataSet) { MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); + self->isDynamicDataSet = false; + self->dataSet = NULL; + } if (self->dataSetValues != NULL) { LinkedList_destroyStatic(self->dataSetValues); diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index aa18d62f..c36974ff 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2440,8 +2440,8 @@ MmsMapping_stopEventWorkerThread(MmsMapping* self) } #endif /* (CONFIG_MMS_THREADLESS_STACK != 1) */ -static DataSet* -createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableList variableList) +DataSet* +MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableList variableList) { DataSet* dataSet = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet)); @@ -2520,7 +2520,7 @@ MmsMapping_getDomainSpecificDataSet(MmsMapping* self, char* dataSetName) if (variableList == NULL) return NULL; - return createDataSetByNamedVariableList(self, variableList); + return MmsMapping_createDataSetByNamedVariableList(self, variableList); } void diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index 0c415839..3a994aab 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -141,10 +141,12 @@ deleteDataSetValuesShadowBuffer(ReportControl* self) } GLOBAL_FREEMEM(self->bufferedDataSetValues); - } - if (self->valueReferences != NULL) - GLOBAL_FREEMEM(self->valueReferences); + if (self->valueReferences != NULL) + GLOBAL_FREEMEM(self->valueReferences); + + self->bufferedDataSetValues = NULL; + } } void @@ -165,8 +167,11 @@ ReportControl_destroy(ReportControl* self) deleteDataSetValuesShadowBuffer(self); if (self->isDynamicDataSet) { - if (self->dataSet != NULL) + if (self->dataSet != NULL) { MmsMapping_freeDynamicallyCreatedDataSet(self->dataSet); + self->isDynamicDataSet = false; + self->dataSet = NULL; + } } if (self->buffered) @@ -453,8 +458,10 @@ createDataSetValuesShadowBuffer(ReportControl* rc) } static bool -updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet) +updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, MmsServerConnection* connection) { + bool success = false; + MmsValue* dataSetValue; if (newDatSet != NULL) @@ -465,8 +472,12 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet) char* dataSetName = MmsValue_toString(dataSetValue); if (rc->isDynamicDataSet) { - if (rc->dataSet != NULL) + if (rc->dataSet != NULL) { + deleteDataSetValuesShadowBuffer(rc); MmsMapping_freeDynamicallyCreatedDataSet(rc->dataSet); + rc->isDynamicDataSet = false; + rc->dataSet = NULL; + } } if (dataSetValue != NULL) { @@ -475,8 +486,22 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet) if (dataSet == NULL) { dataSet = MmsMapping_getDomainSpecificDataSet(mapping, dataSetName); + if (dataSet == NULL) { + + /* check if association specific data set is requested */ + if (dataSetName[0] == '@') { + if (connection != NULL) { + MmsNamedVariableList mmsVariableList + = MmsServerConnection_getNamedVariableList(connection, dataSetName + 1); + + if (mmsVariableList != NULL) + dataSet = MmsMapping_createDataSetByNamedVariableList(mapping, mmsVariableList); + } + } + } + if (dataSet == NULL) - return false; + goto exit_function; rc->isDynamicDataSet = true; @@ -500,10 +525,12 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet) rc->inclusionFlags = (ReportInclusionFlag*) GLOBAL_CALLOC(dataSet->elementCount, sizeof(ReportInclusionFlag)); - return true; + success = true; + goto exit_function; } - return false; +exit_function: + return success; } static char* @@ -1156,7 +1183,7 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme printf("Activate report for client %s\n", MmsServerConnection_getClientAddress(connection)); - if (updateReportDataset(self, rc, NULL)) { + if (updateReportDataset(self, rc, NULL, connection)) { updateOwner(rc, connection); @@ -1254,7 +1281,7 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme if (!MmsValue_equals(datSet, value)) { - if (updateReportDataset(self, rc, value)) { + if (updateReportDataset(self, rc, value, connection)) { if (rc->buffered) purgeBuf(rc); @@ -2126,7 +2153,7 @@ Reporting_activateBufferedReports(MmsMapping* self) ReportControl* rc = (ReportControl*) element->data; if (rc->buffered) { - if (updateReportDataset(self, rc, NULL)) + if (updateReportDataset(self, rc, NULL, NULL)) rc->isBuffering = true; else rc->isBuffering = false;