From 49c64ebfeb47e49efa79a503f3aa4a57c8421abf Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Thu, 21 Mar 2024 19:55:03 +0000 Subject: [PATCH] - IED server: fixed - write access to whole array doesn't work (LIB61850-436)(#499) --- src/mms/iso_mms/common/mms_type_spec.c | 30 ++++++------ src/mms/iso_mms/server/mms_write_service.c | 53 +++++++++++++--------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/mms/iso_mms/common/mms_type_spec.c b/src/mms/iso_mms/common/mms_type_spec.c index f83b804e4..c1db5d892 100644 --- a/src/mms/iso_mms/common/mms_type_spec.c +++ b/src/mms/iso_mms/common/mms_type_spec.c @@ -1,7 +1,7 @@ /* * mms_type_spec.c * - * Copyright 2013 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of libIEC61850. * @@ -108,36 +108,40 @@ MmsVariableSpecification_getType(MmsVariableSpecification* self) bool MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, const MmsValue* value) { - if ((self->type) == (value->type)) { - - if ((self->type == MMS_STRUCTURE) || (self->type == MMS_ARRAY)) { - + if ((self->type) == (value->type)) + { + if ((self->type == MMS_STRUCTURE) || (self->type == MMS_ARRAY)) + { int componentCount = self->typeSpec.structure.elementCount; if (componentCount != (int) MmsValue_getArraySize(value)) return false; - if (self->type == MMS_STRUCTURE) { - + if (self->type == MMS_STRUCTURE) + { int i; - for (i = 0; i < componentCount; i++) { - + for (i = 0; i < componentCount; i++) + { if (MmsVariableSpecification_isValueOfType(self->typeSpec.structure.elements[i], MmsValue_getElement(value, i)) == false) return false; } return true; } - else { + else + { int i; - for (i = 0; i < componentCount; i++) { - + for (i = 0; i < componentCount; i++) + { if (MmsVariableSpecification_isValueOfType(self->typeSpec.array.elementTypeSpec, MmsValue_getElement(value, i)) == false) return false; } + + return true; } } - else if (self->type == MMS_BIT_STRING) { + else if (self->type == MMS_BIT_STRING) + { if (self->typeSpec.bitString == value->value.bitString.size) return true; diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index 096bc30f1..fdde1f165 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -598,12 +598,13 @@ mmsServer_handleWriteRequest( MmsServer_lockModel(connection->server); - if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName) { + if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName) + { handleWriteNamedVariableListRequest(connection, writeRequest, invokeId, response); goto exit_function; } - else if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) { - + else if (writeRequest->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) + { int numberOfWriteItems = writeRequest->variableAccessSpecification.choice.listOfVariable.list.count; if (numberOfWriteItems < 1) { @@ -627,7 +628,8 @@ mmsServer_handleWriteRequest( int i; - for (i = 0; i < numberOfWriteItems; i++) { + for (i = 0; i < numberOfWriteItems; i++) + { ListOfVariableSeq_t* varSpec = writeRequest->variableAccessSpecification.choice.listOfVariable.list.array[i]; @@ -644,7 +646,8 @@ mmsServer_handleWriteRequest( char nameIdStr[65]; - if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_domainspecific) { + if (varSpec->variableSpecification.choice.name.present == ObjectName_PR_domainspecific) + { Identifier_t domainId = varSpec->variableSpecification.choice.name.choice.domainspecific.domainId; char domainIdStr[65]; @@ -687,8 +690,8 @@ mmsServer_handleWriteRequest( AlternateAccess_t* alternateAccess = varSpec->alternateAccess; - if (alternateAccess != NULL) { - + if (alternateAccess != NULL) + { if ((variable->type == MMS_STRUCTURE) && (mmsServer_isComponentAccess(alternateAccess) == false)) { accessResults[i] = DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT; continue; @@ -714,12 +717,13 @@ mmsServer_handleWriteRequest( continue; } - if (alternateAccess != NULL) { - + if (alternateAccess != NULL) + { if (domain == NULL) domain = (MmsDomain*) device; - if (mmsServer_isIndexAccess(alternateAccess)) { + if (mmsServer_isIndexAccess(alternateAccess)) + { MmsValue* cachedArray = MmsServer_getValueFromCache(connection->server, domain, nameIdStr); if (cachedArray == NULL) { @@ -730,8 +734,8 @@ mmsServer_handleWriteRequest( int index = mmsServer_getLowIndex(alternateAccess); int numberOfElements = mmsServer_getNumberOfElements(alternateAccess); - if (numberOfElements == 0) { /* select single array element with index */ - + if (numberOfElements == 0) /* select single array element with index */ + { MmsValue* elementValue = MmsValue_getElement(cachedArray, index); if (elementValue == NULL) { @@ -739,7 +743,8 @@ mmsServer_handleWriteRequest( goto end_of_main_loop; } - if (mmsServer_isAccessToArrayComponent(alternateAccess)) { + if (mmsServer_isAccessToArrayComponent(alternateAccess)) + { MmsVariableSpecification* namedVariable = MmsDomain_getNamedVariable(domain, nameIdStr); if (namedVariable) { @@ -757,16 +762,18 @@ mmsServer_handleWriteRequest( goto end_of_main_loop; } } - else { /* select sub-array with start-index and number-of-elements */ - - if (MmsValue_getType(value) != MMS_ARRAY) { + else /* select sub-array with start-index and number-of-elements */ + { + if (MmsValue_getType(value) != MMS_ARRAY) + { accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; goto end_of_main_loop; } int elementNo; - for (elementNo = 0; elementNo < numberOfElements; elementNo++) { + for (elementNo = 0; elementNo < numberOfElements; elementNo++) + { MmsValue* newElement = MmsValue_getElement(value, elementNo); MmsValue* elementValue = MmsValue_getElement(cachedArray, index++); @@ -785,22 +792,26 @@ mmsServer_handleWriteRequest( accessResults[i] = DATA_ACCESS_ERROR_SUCCESS; goto end_of_main_loop; } - else if (mmsServer_isComponentAccess(alternateAccess)) { + else if (mmsServer_isComponentAccess(alternateAccess)) + { variable = getComponent(connection, domain, alternateAccess, variable, nameIdStr); - if (variable == NULL) { + if (variable == NULL) + { accessResults[i] = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT; goto end_of_main_loop; } } - else { + else + { accessResults[i] = DATA_ACCESS_ERROR_SUCCESS; goto end_of_main_loop; } } /* Check for correct type */ - if (MmsVariableSpecification_isValueOfType(variable, value) == false) { + if (MmsVariableSpecification_isValueOfType(variable, value) == false) + { accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; goto end_of_main_loop; }