diff --git a/src/mms/inc/mms_type_spec.h b/src/mms/inc/mms_type_spec.h index d9db23f..2069358 100644 --- a/src/mms/inc/mms_type_spec.h +++ b/src/mms/inc/mms_type_spec.h @@ -91,6 +91,17 @@ MmsVariableSpecification_getNamedVariableRecursive(MmsVariableSpecification* sel MmsType MmsVariableSpecification_getType(MmsVariableSpecification* self); +/** + * \brief Check if the value has exactly the same type as this variable specfication + * + * \param self the MmsVariableSpecification instance + * \param value the value to check + * + * \return true if type is matching, false otherwise + */ +bool +MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, MmsValue* value); + /** * \brief get the name of the variable * diff --git a/src/mms/iso_mms/common/mms_type_spec.c b/src/mms/iso_mms/common/mms_type_spec.c index 3d3ea1f..95f17ba 100644 --- a/src/mms/iso_mms/common/mms_type_spec.c +++ b/src/mms/iso_mms/common/mms_type_spec.c @@ -95,6 +95,64 @@ MmsVariableSpecification_getType(MmsVariableSpecification* self) return self->type; } +bool +MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, MmsValue* value) +{ + 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) { + + int 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 { + int i; + for (i = 0; i < componentCount; i++) { + + if (MmsVariableSpecification_isValueOfType(self->typeSpec.array.elementTypeSpec, MmsValue_getElement(value, i)) == false) + return false; + } + } + } + else if (self->type == MMS_BIT_STRING) { + if (self->typeSpec.bitString == value->value.bitString.size) + return true; + + if (self->typeSpec.bitString < 0) { + if (value->value.bitString.size <= (-self->typeSpec.bitString)) + return true; + } + } + else if (self->type == MMS_FLOAT) { + if ((self->typeSpec.floatingpoint.exponentWidth == value->value.floatingPoint.exponentWidth) && + (self->typeSpec.floatingpoint.formatWidth == value->value.floatingPoint.formatWidth)) + return true; + } + else if (self->type == MMS_BINARY_TIME) { + if (self->typeSpec.binaryTime == value->value.binaryTime.size) + return true; + } + else + return true; + + } + + return false; +} + const char* MmsVariableSpecification_getName(MmsVariableSpecification* self) { diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index 41c0a70..13eaec6 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -657,7 +657,7 @@ mmsServer_handleWriteRequest( } /* Check for correct type */ - if (MmsValue_getType(value) != MmsVariableSpecification_getType(variable)) { + if (MmsVariableSpecification_isValueOfType(variable, value) == false) { accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT; goto end_of_main_loop; } diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 228dab8..29379a0 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -570,4 +570,5 @@ EXPORTS IedServer_setFilestoreBasepath IedModel_getDeviceByInst MmsConnection_writeNamedVariableList - IedConnection_writeDataSetValues \ No newline at end of file + IedConnection_writeDataSetValues + MmsVariableSpecification_isValueOfType diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 87146bd..d4589e1 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -652,3 +652,4 @@ EXPORTS SVClientASDU_hasRefrTm SVClientASDU_getRefrTmAsMs IedConnection_writeDataSetValues + MmsVariableSpecification_isValueOfType