diff --git a/dotnet/IEC61850forCSharp/Control.cs b/dotnet/IEC61850forCSharp/Control.cs
index d064334b..bb4f876c 100644
--- a/dotnet/IEC61850forCSharp/Control.cs
+++ b/dotnet/IEC61850forCSharp/Control.cs
@@ -100,8 +100,6 @@ namespace IEC61850
///
public class ControlObject
{
-
-
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern LastApplErrorInternal ControlObjectClient_getLastApplError(IntPtr self);
@@ -114,16 +112,20 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int ControlObjectClient_getControlModel(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_select(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_selectWithValue(IntPtr self, IntPtr ctlVal);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_cancel(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 6056fcaa..992623da 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -54,7 +54,8 @@ namespace IEC61850
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern float MmsValue_toFloat (IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
@@ -135,8 +136,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteDataSet (IntPtr self, out int error, string dataSetReference);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getDataSetDirectory (IntPtr self, out int error, string dataSetReference, out bool isDeletable);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr IedConnection_getDataSetDirectory(IntPtr self, out int error, string dataSetReference, [MarshalAs(UnmanagedType.I1)] out bool isDeletable);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getMmsConnection (IntPtr self);
@@ -892,13 +893,33 @@ namespace IEC61850
if (error != 0)
throw new IedConnectionException ("Failed to delete data set", error);
- }
-
+ }
+
+ ///
+ /// Get the directory of the data set.
+ ///
+ /// This function returns a list of object references with appended functional constraints (FC) of the data set elemenents.
+ /// The object reference of the data set
+ /// the list of object references
+ /// This exception is thrown if there is a connection or service error
+ public List GetDataSetDirectory(string dataSetReference)
+ {
+ bool isDeletable;
+
+ return GetDataSetDirectory(dataSetReference, out isDeletable);
+ }
+
+ ///
+ /// Get the directory of the data set.
+ ///
+ /// This function returns a list of object references with appended functional constraints (FC) of the data set elemenents.
+ /// The object reference of the data set
+ /// Indication if this data set is permanent or deletable.
+ /// the list of object references
/// This exception is thrown if there is a connection or service error
- public List GetDataSetDirectory (string dataSetReference)
+ public List GetDataSetDirectory (string dataSetReference, out bool isDeletable)
{
int error;
- bool isDeletable;
IntPtr linkedList = IedConnection_getDataSetDirectory (connection, out error, dataSetReference, out isDeletable);
diff --git a/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj b/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj
index 535e22ab..be311af9 100644
--- a/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj
+++ b/dotnet/IEC61850forCSharp/IEC61850forCSharp.csproj
@@ -1,46 +1,46 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {C35D624E-5506-4560-8074-1728F1FA1A4D}
- Library
- iec61850dotnet
- iec61850dotnet
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- none
- true
- bin\Release
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {C35D624E-5506-4560-8074-1728F1FA1A4D}
+ Library
+ iec61850dotnet
+ iec61850dotnet
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+
+
+ none
+ true
+ bin\Release
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dotnet/IEC61850forCSharp/MmsValue.cs b/dotnet/IEC61850forCSharp/MmsValue.cs
index 0ab8c06b..cb85814e 100644
--- a/dotnet/IEC61850forCSharp/MmsValue.cs
+++ b/dotnet/IEC61850forCSharp/MmsValue.cs
@@ -46,7 +46,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern double MmsValue_toDouble (IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@@ -61,7 +62,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setBitStringBit(IntPtr self, int bitPos, bool value);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBitStringBit(IntPtr self, int bitPos);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@@ -130,7 +132,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_getOctetStringBuffer(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_equals(IntPtr self, IntPtr otherValue);
diff --git a/dotnet/IEC61850forCSharp/ReportControlBlock.cs b/dotnet/IEC61850forCSharp/ReportControlBlock.cs
index 60f7a5fc..c1ddedb8 100644
--- a/dotnet/IEC61850forCSharp/ReportControlBlock.cs
+++ b/dotnet/IEC61850forCSharp/ReportControlBlock.cs
@@ -55,7 +55,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setRCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@@ -65,12 +66,14 @@ namespace IEC61850
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern void ClientReportControlBlock_setRptEna (IntPtr self, bool rptEna);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern void ClientReportControlBlock_setRptEna(IntPtr self, bool rptEna);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getResv (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@@ -112,13 +115,15 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getGI (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, bool gi);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
diff --git a/dotnet/IEC61850forCSharp/Reporting.cs b/dotnet/IEC61850forCSharp/Reporting.cs
index 4bade8e5..68e7e7aa 100644
--- a/dotnet/IEC61850forCSharp/Reporting.cs
+++ b/dotnet/IEC61850forCSharp/Reporting.cs
@@ -67,7 +67,8 @@ namespace IEC61850
public class Report
{
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@@ -79,28 +80,34 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReport_getReasonForInclusion(IntPtr self, int elementIndex);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasSeqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReport_getSeqNum(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasDataSetName(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasReasonForInclusion(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReport_getConfRev(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasBufOvfl(IntPtr self);
- [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasDataReference(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c
index 490f3cf9..846d8071 100644
--- a/src/iec61850/client/ied_connection.c
+++ b/src/iec61850/client/ied_connection.c
@@ -34,6 +34,7 @@
#include "mms_value_internal.h"
#define DEFAULT_CONNECTION_TIMEOUT 10000
+#define DATA_SET_MAX_NAME_LENGTH 64 /* is 32 according to standard! */
typedef struct sICLogicalDevice
{
@@ -1827,7 +1828,7 @@ IedConnection_createDataSet(IedConnection self, IedClientError* error, const cha
{
char domainIdBuffer[65];
- char itemIdBuffer[33]; /* maximum data set name = 32 chars */
+ char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId;
const char* itemId;
@@ -1899,7 +1900,7 @@ void
IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const char* dataSetReference)
{
char domainId[65];
- char itemId[33];
+ char itemId[DATA_SET_MAX_NAME_LENGTH + 1];
bool isAssociationSpecific = false;
int dataSetReferenceLength = strlen(dataSetReference);
@@ -1912,7 +1913,7 @@ IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const cha
const char* itemIdString = dataSetReference + strlen(domainId) + 1;
- if (strlen(itemIdString) > 32) {
+ if (strlen(itemIdString) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
@@ -1953,7 +1954,7 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
LinkedList dataSetMembers = NULL;
char domainIdBuffer[65];
- char itemIdBuffer[129];
+ char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId = NULL;
const char* itemId = NULL;
@@ -1962,9 +1963,22 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
if (dataSetReference[0] != '@') {
domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
- char* itemIdRef = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
- StringUtils_replace(itemIdRef, '.', '$');
- itemId = itemIdRef;
+
+ if (domainId == NULL) {
+ *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
+ goto exit_function;
+ }
+
+ const char* itemIdRef = dataSetReference + strlen(domainId) + 1;
+
+ if (strlen(itemIdRef) > DATA_SET_MAX_NAME_LENGTH) {
+ *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
+ goto exit_function;
+ }
+
+ char* itemIdRefInBuffer = copyStringToBuffer(itemIdRef, itemIdBuffer);
+ StringUtils_replace(itemIdRefInBuffer, '.', '$');
+ itemId = itemIdRefInBuffer;
}
else {
itemId = dataSetReference + 1;
@@ -2006,6 +2020,7 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
*error = iedConnection_mapMmsErrorToIedError(mmsError);
+exit_function:
return dataSetMembers;
}
@@ -2014,7 +2029,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
ClientDataSet dataSet)
{
char domainIdBuffer[65];
- char itemIdBuffer[129];
+ char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId = NULL;
const char* itemId = NULL;
@@ -2023,7 +2038,21 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
if (dataSetReference[0] != '@') {
domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
- char* itemIdRef = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
+
+ if (domainId == NULL) {
+ *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
+ goto exit_function;
+ }
+
+ const char* itemIdRefOrig = dataSetReference + strlen(domainId) + 1;
+
+ if (strlen(itemIdRefOrig) > DATA_SET_MAX_NAME_LENGTH) {
+ *error = IED_ERROR_OBJECT_REFERENCE_INVALID;
+ goto exit_function;
+ }
+
+ char* itemIdRef = copyStringToBuffer(itemIdRefOrig, itemIdBuffer);
+
StringUtils_replace(itemIdRef, '.', '$');
itemId = itemIdRef;
}
@@ -2045,7 +2074,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
if (dataSetVal == NULL) {
*error = iedConnection_mapMmsErrorToIedError(mmsError);
- goto cleanup_and_exit;
+ goto exit_function;
}
else
*error = IED_ERROR_OK;
@@ -2059,7 +2088,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
MmsValue_update(dataSetValues, dataSetVal);
}
-cleanup_and_exit:
+exit_function:
return dataSet;
}