From 363d4ef5a75f05b85e967d3d986acd897a9bafae Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 27 Apr 2015 13:55:41 +0200 Subject: [PATCH] - reject CreateDataSet for non-existing LN --- dotnet/datasets/DataSetExample.cs | 12 +++-- dotnet/reporting/ReportingExample.cs | 18 +++++--- src/iec61850/server/mms_mapping/mms_mapping.c | 44 ++++++++++++++++--- src/mms/inc/mms_server.h | 5 +-- src/mms/inc_private/mms_server_internal.h | 2 +- .../server/mms_named_variable_list_service.c | 18 +++++--- 6 files changed, 73 insertions(+), 26 deletions(-) diff --git a/dotnet/datasets/DataSetExample.cs b/dotnet/datasets/DataSetExample.cs index e0da9d10..5d502516 100644 --- a/dotnet/datasets/DataSetExample.cs +++ b/dotnet/datasets/DataSetExample.cs @@ -36,13 +36,17 @@ namespace datasets List dataSetElements = new List(); + string dataSetName = "simpleIOGenericIO/UNKNOWN.ds1"; + + //string dataSetName = "simpleIOGenericIO/LLN0.ds1"; + dataSetElements.Add("simpleIOGenericIO/GGIO1.AnIn1.mag.f[MX]"); dataSetElements.Add("simpleIOGenericIO/GGIO1.AnIn2.mag.f[MX]"); - con.CreateDataSet("simpleIOGenericIO/LLN0.ds1", dataSetElements); + con.CreateDataSet(dataSetName, dataSetElements); // get the directory of the data set - List dataSetDirectory = con.GetDataSetDirectory("simpleIOGenericIO/LLN0.ds1"); + List dataSetDirectory = con.GetDataSetDirectory(dataSetName); foreach (string entry in dataSetDirectory) { @@ -50,7 +54,7 @@ namespace datasets } // read the values of the newly created data set - DataSet dataSet = con.ReadDataSetValues("simpleIOGenericIO/LLN0.ds1", null); + DataSet dataSet = con.ReadDataSetValues(dataSetName, null); MmsValue dataSetValues = dataSet.GetValues(); @@ -61,7 +65,7 @@ namespace datasets } // delete the data set - con.DeleteDataSet("simpleIOGenericIO/LLN0.ds1"); + con.DeleteDataSet(dataSetName); con.Abort(); } diff --git a/dotnet/reporting/ReportingExample.cs b/dotnet/reporting/ReportingExample.cs index 0dde51db..6a1d9538 100644 --- a/dotnet/reporting/ReportingExample.cs +++ b/dotnet/reporting/ReportingExample.cs @@ -27,12 +27,18 @@ namespace reporting if (report.GetReasonForInclusion(i) != ReasonForInclusion.REASON_NOT_INCLUDED) { Console.WriteLine(" element " + i + " included for reason " + report.GetReasonForInclusion(i).ToString() + " " + values.GetElement(i)); } + + if (report.HasDataReference()) { + Console.WriteLine(" data-ref: " + report.GetDataReference(i)); + } + } ReportControlBlock rcb = (ReportControlBlock) parameter; - - Console.WriteLine(" For RCB: " + rcb.GetObjectReference() + " Buffered: " + rcb.IsBuffered()); - + + Console.WriteLine(" For RCB: " + rcb.GetObjectReference() + " Buffered: " + rcb.IsBuffered() + + " data-set: " + rcb.GetDataSetReference ()); + } @@ -78,8 +84,10 @@ namespace reporting rcb2.GetRCBValues(); - rcb2.InstallReportHandler(reportHandler, rcb2); - + rcb2.InstallReportHandler(reportHandler, rcb2); + + rcb2.SetOptFlds(ReportOptions.REASON_FOR_INCLUSION | ReportOptions.SEQ_NUM | ReportOptions.TIME_STAMP | + ReportOptions.CONF_REV | ReportOptions.ENTRY_ID | ReportOptions.DATA_REFERENCE | ReportOptions.DATA_SET); rcb2.SetTrgOps(TriggerOptions.DATA_CHANGED | TriggerOptions.INTEGRITY); rcb2.SetIntgPd(2000); rcb2.SetRptEna(true); diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index ac4bee6d..8ee61286 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -2179,17 +2179,17 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS return DATA_ACCESS_ERROR_SUCCESS; } -static bool +static MmsError variableListChangedHandler (void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection) { - bool allow = true; + MmsError allow = MMS_ERROR_NONE; #if (DEBUG_IED_SERVER == 1) if (create) - printf("create data set "); + printf("IED_SERVER: create data set "); else - printf("delete data set "); + printf("IED_SERVER: delete data set "); switch (listType) { case MMS_VMD_SPECIFIC: @@ -2208,7 +2208,37 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li MmsMapping* self = (MmsMapping*) parameter; - if (create == false) { + if (create) { + if (listType == MMS_DOMAIN_SPECIFIC) { + // check if LN exists - otherwise reject request (to fulfill test case sDsN1c) + + allow = MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT; + + IedModel* model = self->model; + + LogicalDevice* ld = IedModel_getDevice(model, domain->domainName); + + if (ld != NULL) { + + char lnName[129]; + + char* separator = strchr(listName, '$'); + + if (separator != NULL) { + int lnNameLen = separator - listName; + + memcpy(lnName, listName, lnNameLen); + lnName[lnNameLen] = 0; + + if (LogicalDevice_getLogicalNode(ld, lnName) != NULL) + allow = MMS_ERROR_NONE; + } + + } + + } + } + else { /* Check if data set is referenced in a report */ LinkedList element = self->reportControls; @@ -2223,7 +2253,7 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li if (rc->dataSet->logicalDeviceName != NULL) { if (strcmp(rc->dataSet->name, listName) == 0) { if (strcmp(rc->dataSet->logicalDeviceName, MmsDomain_getName(domain)) == 0) { - allow = false; + allow = MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED; break; } } @@ -2232,7 +2262,7 @@ variableListChangedHandler (void* parameter, bool create, MmsVariableListType li else if (listType == MMS_ASSOCIATION_SPECIFIC) { if (rc->dataSet->logicalDeviceName == NULL) { if (strcmp(rc->dataSet->name, listName) == 0) { - allow = false; + allow = MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED; break; } } diff --git a/src/mms/inc/mms_server.h b/src/mms/inc/mms_server.h index e2c4ee71..da2035bb 100644 --- a/src/mms/inc/mms_server.h +++ b/src/mms/inc/mms_server.h @@ -109,10 +109,9 @@ MmsServer_isLocked(MmsServer self); * \param listName the name * \param connection client connection that requests the creation of deletion of the variable list * - * \return true if operation has to be accepted, false if operation has to be rejected. In case of false an error message - * is returned to the client. + * \return MMS_ERROR_NONE if the request is accepted, otherwise the MmsError value that has to be sent back to the client */ -typedef bool (*MmsNamedVariableListChangedHandler)(void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, +typedef MmsError (*MmsNamedVariableListChangedHandler)(void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection); /** diff --git a/src/mms/inc_private/mms_server_internal.h b/src/mms/inc_private/mms_server_internal.h index 000936d4..2e7f5712 100644 --- a/src/mms/inc_private/mms_server_internal.h +++ b/src/mms/inc_private/mms_server_internal.h @@ -289,7 +289,7 @@ mmsServer_createMmsWriteResponse(MmsServerConnection connection, void mmsServer_writeMmsRejectPdu(uint32_t* invokeId, int reason, ByteBuffer* response); -bool +MmsError mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection); diff --git a/src/mms/iso_mms/server/mms_named_variable_list_service.c b/src/mms/iso_mms/server/mms_named_variable_list_service.c index 66d4d4cb..41a91a7e 100644 --- a/src/mms/iso_mms/server/mms_named_variable_list_service.c +++ b/src/mms/iso_mms/server/mms_named_variable_list_service.c @@ -47,17 +47,21 @@ #define CONFIG_MMS_MAX_NUMBER_OF_DATA_SET_MEMBERS 50 #endif -bool +MmsError mmsServer_callVariableListChangedHandler(bool create, MmsVariableListType listType, MmsDomain* domain, char* listName, MmsServerConnection connection) { MmsServer self = connection->server; - if (self->variableListChangedHandler != NULL) + if (self->variableListChangedHandler != NULL) { + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: call MmsNamedVariableListChangedHandler for new list %s\n", listName); + return self->variableListChangedHandler(self->variableListChangedHandlerParameter, create, listType, domain, listName, connection); + } else - return true; + return MMS_ERROR_NONE; } static void @@ -150,7 +154,7 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection, if (MmsNamedVariableList_isDeletable(variableList)) { - if (mmsServer_callVariableListChangedHandler(false, MMS_DOMAIN_SPECIFIC, domain, listName, connection) == true) { + if (mmsServer_callVariableListChangedHandler(false, MMS_DOMAIN_SPECIFIC, domain, listName, connection) == MMS_ERROR_NONE) { MmsDomain_deleteNamedVariableList(domain, listName); numberDeleted++; } @@ -420,13 +424,15 @@ mmsServer_handleDefineNamedVariableListRequest( if (namedVariableList != NULL) { - if (mmsServer_callVariableListChangedHandler(true, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection) == true) { + mmsError = mmsServer_callVariableListChangedHandler(true, MMS_DOMAIN_SPECIFIC, domain, variableListName, connection); + + if (mmsError == MMS_ERROR_NONE) { MmsDomain_addNamedVariableList(domain, namedVariableList); createDefineNamedVariableListResponse(invokeId, response); } else { MmsNamedVariableList_destroy(namedVariableList); - mmsServer_createConfirmedErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED); + mmsServer_createConfirmedErrorPdu(invokeId, response, mmsError); } } else