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) {