From 2ffb55f25a118482e1fcf4195fe34b00485e78b9 Mon Sep 17 00:00:00 2001 From: Kevin Jhang Date: Wed, 29 Dec 2021 15:05:41 +0800 Subject: [PATCH] - change array write handle way --- dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs | 28 +++++++++++++++++++ src/iec61850/inc/iec61850_dynamic_model.h | 20 +++++++++++++ src/iec61850/inc/iec61850_model.h | 1 + src/iec61850/server/model/dynamic_model.c | 27 ++++++++++++++++-- src/iec61850/server/model/model.c | 5 ++++ src/mms/iso_mms/common/mms_type_spec.c | 14 +++++++++- src/mms/iso_mms/common/mms_value.c | 2 +- src/mms/iso_mms/server/mms_write_service.c | 2 ++ 8 files changed, 95 insertions(+), 4 deletions(-) diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs index 69beb84c..541ffa2a 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs @@ -908,6 +908,12 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern int DataAttribute_getFC(IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern int DataAttribute_getSize(IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern int DataAttribute_getIndex(IntPtr self); internal DataAttribute(IntPtr self, ModelNode parent) : base(self) { @@ -991,6 +997,28 @@ namespace IEC61850 public void SetValue(MmsValue value) { DataAttribute_setValue(self, value.valueReference); + } + + /// + /// The size of the data attribute + /// + public int Size + { + get + { + return DataAttribute_getSize(self); + } + } + + /// + /// The index of the data attribute + /// + public int Index + { + get + { + return DataAttribute_getIndex(self); + } } } diff --git a/src/iec61850/inc/iec61850_dynamic_model.h b/src/iec61850/inc/iec61850_dynamic_model.h index 59829e64..19cb4215 100644 --- a/src/iec61850/inc/iec61850_dynamic_model.h +++ b/src/iec61850/inc/iec61850_dynamic_model.h @@ -157,6 +157,26 @@ DataAttribute_getType(DataAttribute* self); LIB61850_API FunctionalConstraint DataAttribute_getFC(DataAttribute* self); +/** + * \brief Get the size of the data attribute + * + * \param self the data attribute instance + * + * \return the size of the data attribute + */ +LIB61850_API int +DataAttribute_getSize(DataAttribute* self); + +/** + * \brief Get the index of the data attribute + * + * \param self the data attribute instance + * + * \return the index of the data attribute + */ +LIB61850_API int +DataAttribute_getIndex(DataAttribute* self); + /** * \brief Get the trigger options of the data attribute * diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index 6681f5d5..a53c8c29 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -223,6 +223,7 @@ struct sDataAttribute { ModelNode* firstChild; int elementCount; /* > 0 if this is an array */ + int index; FunctionalConstraint fc; DataAttributeType type; diff --git a/src/iec61850/server/model/dynamic_model.c b/src/iec61850/server/model/dynamic_model.c index 0e4e13d3..f3ee253e 100644 --- a/src/iec61850/server/model/dynamic_model.c +++ b/src/iec61850/server/model/dynamic_model.c @@ -543,12 +543,17 @@ DataObject_getLastChild(DataObject* self) static void DataObject_addChild(DataObject* self, ModelNode* child) { - if (self->firstChild == NULL) + if (self->firstChild == NULL) { self->firstChild = child; + + ((DataAttribute*)child)->index = 0; + } else { ModelNode* lastChild = DataObject_getLastChild(self); lastChild->sibling = child; + + ((DataAttribute*)child)->index = ((DataAttribute*)lastChild)->index + 1; } } @@ -590,12 +595,17 @@ DataAttribute_getLastChild(DataAttribute* self) static void DataAttribute_addChild(DataAttribute* self, ModelNode* child) { - if (self->firstChild == NULL) + if (self->firstChild == NULL) { self->firstChild = child; + + ((DataAttribute*)child)->index = 0; + } else { ModelNode* lastChild = DataAttribute_getLastChild(self); lastChild->sibling = child; + + ((DataAttribute*)child)->index = ((DataAttribute*)lastChild)->index + 1; } } @@ -616,6 +626,7 @@ DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type self->sibling = NULL; self->triggerOptions = triggerOptions; self->sAddr = sAddr; + self->index = -1; if (parent->modelType == DataObjectModelType) DataObject_addChild((DataObject*) parent, (ModelNode*) self); @@ -637,6 +648,18 @@ DataAttribute_getFC(DataAttribute* self) return self->fc; } +int +DataAttribute_getSize(DataAttribute* self) +{ + return self->elementCount; +} + +int +DataAttribute_getIndex(DataAttribute* self) +{ + return self->index; +} + uint8_t DataAttribute_getTrgOps(DataAttribute* self) { diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index 3da07561..ea7610b0 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -607,6 +607,11 @@ ModelNode_getChild(ModelNode* self, const char* name) /* check for separator */ const char* separator = strchr(name, '.'); + /* skip array node */ + if (name[0] == '[') { + return ModelNode_getChild(self, separator + 1); + } + int nameElementLength = 0; if (separator != NULL) diff --git a/src/mms/iso_mms/common/mms_type_spec.c b/src/mms/iso_mms/common/mms_type_spec.c index a59c1e02..8c6df233 100644 --- a/src/mms/iso_mms/common/mms_type_spec.c +++ b/src/mms/iso_mms/common/mms_type_spec.c @@ -102,10 +102,21 @@ MmsVariableSpecification_getType(MmsVariableSpecification* self) return self->type; } +static bool +equalType(const MmsVariableSpecification* self, const MmsValue* otherValue) +{ + if (self->type == otherValue->type || + (self->type == MMS_STRUCTURE && otherValue->type == MMS_ARRAY) || + (self->type == MMS_ARRAY && otherValue->type == MMS_STRUCTURE)) + return true; + + return false; +} + bool MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, const MmsValue* value) { - if ((self->type) == (value->type)) { + if (equalType(self, value)) { if ((self->type == MMS_STRUCTURE) || (self->type == MMS_ARRAY)) { @@ -132,6 +143,7 @@ MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, const Mms if (MmsVariableSpecification_isValueOfType(self->typeSpec.array.elementTypeSpec, MmsValue_getElement(value, i)) == false) return false; } + return true; } } else if (self->type == MMS_BIT_STRING) { diff --git a/src/mms/iso_mms/common/mms_value.c b/src/mms/iso_mms/common/mms_value.c index 3fc5eda2..561a933b 100644 --- a/src/mms/iso_mms/common/mms_value.c +++ b/src/mms/iso_mms/common/mms_value.c @@ -98,7 +98,7 @@ MmsValue_newUnsignedFromBerInteger(Asn1PrimitiveValue* berInteger) return self; } -bool +static bool equalType(const MmsValue* self, const MmsValue* otherValue) { if (self->type == otherValue->type || diff --git a/src/mms/iso_mms/server/mms_write_service.c b/src/mms/iso_mms/server/mms_write_service.c index 31a171e4..beff5926 100644 --- a/src/mms/iso_mms/server/mms_write_service.c +++ b/src/mms/iso_mms/server/mms_write_service.c @@ -615,6 +615,7 @@ mmsServer_handleWriteRequest( continue; } +#if 0 if (alternateAccess != NULL) { if (domain == NULL) @@ -674,6 +675,7 @@ mmsServer_handleWriteRequest( goto end_of_main_loop; } +#endif /* Check for correct type */ if (MmsVariableSpecification_isValueOfType(variable, value) == false) {