From e02b85f147127c329f81a22bd6700d659a96015d Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 20 Jun 2022 11:20:15 +0200 Subject: [PATCH] - fixed data set handling problem when using functional naming (ldName) (LIB61850-160) --- src/iec61850/server/mms_mapping/mms_mapping.c | 126 +++++++++++------- src/iec61850/server/mms_mapping/reporting.c | 16 ++- src/mms/iso_mms/server/mms_domain.c | 8 +- src/mms/iso_mms/server/mms_write_service.c | 44 +++--- 4 files changed, 117 insertions(+), 77 deletions(-) diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 7efd80d7..0926987d 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -3978,85 +3978,109 @@ MmsMapping_stopEventWorkerThread(MmsMapping* self) DataSet* MmsMapping_createDataSetByNamedVariableList(MmsMapping* self, MmsNamedVariableList variableList) { - DataSet* dataSet = (DataSet*) GLOBAL_MALLOC(sizeof(DataSet)); + DataSet* dataSet = (DataSet*) GLOBAL_CALLOC(1, sizeof(DataSet)); - if (variableList->domain != NULL) - dataSet->logicalDeviceName = MmsDomain_getName(variableList->domain) + strlen(self->model->name); - else - dataSet->logicalDeviceName = NULL; /* name is not relevant for association specific data sets */ + if (dataSet) { - dataSet->name = variableList->name; - dataSet->elementCount = LinkedList_size(variableList->listOfVariables); + if (variableList->domain != NULL) { + LogicalDevice* ld = IedModel_getDevice(self->model, MmsDomain_getName(variableList->domain)); - LinkedList element = LinkedList_getNext(variableList->listOfVariables); + if (ld) { + dataSet->logicalDeviceName = ld->name; + } + else { + if (DEBUG_IED_SERVER) + printf("IED_SERVER: LD lookup error!"); + } + } + else + dataSet->logicalDeviceName = NULL; /* name is not relevant for association specific data sets */ - DataSetEntry* lastDataSetEntry = NULL; + dataSet->name = variableList->name; + dataSet->elementCount = LinkedList_size(variableList->listOfVariables); - while (element != NULL) { - MmsAccessSpecifier* listEntry = (MmsAccessSpecifier*) element->data; + LinkedList element = LinkedList_getNext(variableList->listOfVariables); - DataSetEntry* dataSetEntry = (DataSetEntry*) GLOBAL_MALLOC(sizeof(DataSetEntry)); + DataSetEntry* lastDataSetEntry = NULL; - /* use variable name part of domain name as logicalDeviceName */ - dataSetEntry->logicalDeviceName = MmsDomain_getName(listEntry->domain) + strlen(self->model->name); - dataSetEntry->variableName = listEntry->variableName; - dataSetEntry->index = listEntry->arrayIndex; - dataSetEntry->componentName = listEntry->componentName; - dataSetEntry->sibling = NULL; - dataSetEntry->value = NULL; + while (element != NULL) { + MmsAccessSpecifier* listEntry = (MmsAccessSpecifier*) element->data; - if (lastDataSetEntry == NULL) - dataSet->fcdas =dataSetEntry; - else - lastDataSetEntry->sibling = dataSetEntry; + LogicalDevice* entryLd = IedModel_getDevice(self->model, MmsDomain_getName(listEntry->domain)); - MmsVariableSpecification* dataSetEntryVarSpec = NULL; + if (entryLd) { - MmsValue* dataSetEntryValue = MmsServer_getValueFromCacheEx(self->mmsServer, listEntry->domain, listEntry->variableName, &dataSetEntryVarSpec); + DataSetEntry* dataSetEntry = (DataSetEntry*) GLOBAL_MALLOC(sizeof(DataSetEntry)); - if (dataSetEntryValue) { - if (dataSetEntry->index != -1) { - if (dataSetEntryVarSpec->type == MMS_ARRAY) { - MmsValue* elementValue = MmsValue_getElement(dataSetEntryValue, dataSetEntry->index); + if (dataSetEntry) { - if (elementValue) { + /* use variable name part of domain name as logicalDeviceName */ + dataSetEntry->logicalDeviceName = entryLd->name; + dataSetEntry->variableName = listEntry->variableName; + dataSetEntry->index = listEntry->arrayIndex; + dataSetEntry->componentName = listEntry->componentName; + dataSetEntry->sibling = NULL; + dataSetEntry->value = NULL; - if (dataSetEntry->componentName) { - MmsVariableSpecification* elementType = dataSetEntryVarSpec->typeSpec.array.elementTypeSpec; + if (lastDataSetEntry == NULL) + dataSet->fcdas =dataSetEntry; + else + lastDataSetEntry->sibling = dataSetEntry; + + MmsVariableSpecification* dataSetEntryVarSpec = NULL; + + MmsValue* dataSetEntryValue = MmsServer_getValueFromCacheEx(self->mmsServer, listEntry->domain, listEntry->variableName, &dataSetEntryVarSpec); + + if (dataSetEntryValue) { + if (dataSetEntry->index != -1) { + if (dataSetEntryVarSpec->type == MMS_ARRAY) { + MmsValue* elementValue = MmsValue_getElement(dataSetEntryValue, dataSetEntry->index); - MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, dataSetEntry->componentName); + if (elementValue) { + + if (dataSetEntry->componentName) { + MmsVariableSpecification* elementType = dataSetEntryVarSpec->typeSpec.array.elementTypeSpec; + + MmsValue* subElementValue = MmsVariableSpecification_getChildValue(elementType, elementValue, dataSetEntry->componentName); + + if (subElementValue) { + dataSetEntry->value = subElementValue; + } + else { + if (DEBUG_IED_SERVER) + printf("IED_SERVER: ERROR - component %s of array element not found\n", dataSetEntry->componentName); + } - if (subElementValue) { - dataSetEntry->value = subElementValue; + } + else { + dataSetEntry->value = elementValue; + } + } + else { + if (DEBUG_IED_SERVER) + printf("IED_SERVER: ERROR - array element %i not found\n", dataSetEntry->index); + } } else { if (DEBUG_IED_SERVER) - printf("IED_SERVER: ERROR - component %s of array element not found\n", dataSetEntry->componentName); + printf("IED_SERVER: ERROR - variable %s/%s is not an array\n", dataSetEntry->logicalDeviceName, dataSetEntry->variableName); } - } else { - dataSetEntry->value = elementValue; + dataSetEntry->value = dataSetEntryValue; } } - else { - if (DEBUG_IED_SERVER) - printf("IED_SERVER: ERROR - array element %i not found\n", dataSetEntry->index); - } - } - else { - if (DEBUG_IED_SERVER) - printf("IED_SERVER: ERROR - variable %s/%s is not an array\n", dataSetEntry->logicalDeviceName, dataSetEntry->variableName); + + lastDataSetEntry = dataSetEntry; } } else { - dataSetEntry->value = dataSetEntryValue; + if (DEBUG_IED_SERVER) + printf("IED_SERVER: LD lookup error!\n"); } - } - - lastDataSetEntry = dataSetEntry; - element = LinkedList_getNext(element); + element = LinkedList_getNext(element); + } } return dataSet; diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index d473391c..d26bff8c 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -721,7 +721,21 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, char externalVisibleName[256]; /* Construct external visible name */ - StringUtils_concatString(externalVisibleName, 256, mapping->model->name, dataSetLdName); + + LogicalDevice* ld = IedModel_getDeviceByInst(mapping->model, dataSetLdName); + + if (ld == NULL) { + success = false; + goto exit_function; + } + + if (ld->ldName) { + StringUtils_copyStringMax(externalVisibleName, 256, ld->ldName); + } + else { + StringUtils_concatString(externalVisibleName, 256, mapping->model->name, dataSetLdName); + } + StringUtils_appendString(externalVisibleName, 256, "/"); StringUtils_appendString(externalVisibleName, 256, dataSetName); diff --git a/src/mms/iso_mms/server/mms_domain.c b/src/mms/iso_mms/server/mms_domain.c index f4bdf519..a53fd5d2 100644 --- a/src/mms/iso_mms/server/mms_domain.c +++ b/src/mms/iso_mms/server/mms_domain.c @@ -39,9 +39,11 @@ MmsDomain_create(char* domainName) { MmsDomain* self = (MmsDomain*) GLOBAL_CALLOC(1, sizeof(MmsDomain)); - self->domainName = StringUtils_copyString(domainName); - self->namedVariableLists = LinkedList_create(); - self->journals = NULL; + if (self) { + self->domainName = StringUtils_copyString(domainName); + self->namedVariableLists = LinkedList_create(); + self->journals = NULL; + } return self; } diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index 1c02a97a..2acbb197 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -481,34 +481,34 @@ handleWriteNamedVariableListRequest( void mmsServer_handleWriteRequest( - MmsServerConnection connection, - uint8_t* buffer, int bufPos, int maxBufPos, - uint32_t invokeId, - ByteBuffer* response) + MmsServerConnection connection, + uint8_t* buffer, int bufPos, int maxBufPos, + uint32_t invokeId, + ByteBuffer* response) { (void)bufPos; (void)maxBufPos; - MmsPdu_t* mmsPdu = 0; + MmsPdu_t* mmsPdu = 0; - asn_dec_rval_t rval; /* Decoder return value */ + asn_dec_rval_t rval; /* Decoder return value */ - rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, CONFIG_MMS_MAXIMUM_PDU_SIZE); + rval = ber_decode(NULL, &asn_DEF_MmsPdu, (void**) &mmsPdu, buffer, CONFIG_MMS_MAXIMUM_PDU_SIZE); - if (rval.code != RC_OK) { - mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); - goto exit_function; - } + if (rval.code != RC_OK) { + mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response); + goto exit_function; + } MmsServer_lockModel(connection->server); - WriteRequest_t* writeRequest = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write); + WriteRequest_t* writeRequest = &(mmsPdu->choice.confirmedRequestPdu.confirmedServiceRequest.choice.write); - if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName) { - handleWriteNamedVariableListRequest(connection, writeRequest, invokeId, response); - goto exit_function; - } - else if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) { + if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName) { + handleWriteNamedVariableListRequest(connection, writeRequest, invokeId, response); + goto exit_function; + } + else if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) { int numberOfWriteItems = writeRequest->variableAccessSpecification.choice.listOfVariable.list.count; @@ -571,7 +571,7 @@ mmsServer_handleWriteRequest( variable = MmsDomain_getNamedVariable(domain, nameIdStr); } - #if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) +#if (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) else if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_vmdspecific) { Identifier_t nameId = varSpec->variableSpecification.choice.name.choice.vmdspecific; @@ -579,7 +579,7 @@ mmsServer_handleWriteRequest( variable = MmsDevice_getNamedVariable(device, nameIdStr); } - #endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ +#endif /* (CONFIG_MMS_SUPPORT_VMD_SCOPE_NAMED_VARIABLES == 1) */ else { accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED; @@ -616,7 +616,7 @@ mmsServer_handleWriteRequest( if (alternateAccess != NULL) { - if (domain == NULL) + if (domain == NULL) domain = (MmsDomain*) device; MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr); @@ -701,7 +701,7 @@ mmsServer_handleWriteRequest( accessResults[i] = valueIndication; -end_of_main_loop: + end_of_main_loop: MmsValue_delete(value); } @@ -714,7 +714,7 @@ end_of_main_loop: goto exit_function; } -exit_function: + exit_function: MmsServer_unlockModel(connection->server);