diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 4c2a53c4..0ccd5b09 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -1,7 +1,7 @@
/*
* IEC61850ClientAPI.cs
*
- * Copyright 2014-2019 Michael Zillgith
+ * Copyright 2014-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
@@ -622,13 +622,31 @@ namespace IEC61850
int fc, IedConnection_GetVariableSpecificationHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate void IedConnection_ReadDataSetHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr dataSet);
+ private delegate void IedConnection_ReadDataSetHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr dataSet);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
IedConnection_readDataSetValuesAsync(IntPtr self, out int error, string dataSetReference, IntPtr dataSet,
IedConnection_ReadDataSetHandler handler, IntPtr parameter);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_createDataSetAsync(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference, IntPtr dataSet,
+ IedConnection_GenericServiceHandler handler, IntPtr parameter);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_deleteDataSetAsync(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference,
+ IedConnection_GenericServiceHandler handler, IntPtr parameter);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate void IedConnection_GetDataSetDirectoryHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr dataSetDirectory, [MarshalAs(UnmanagedType.I1)] bool isDeletable);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_getDataSetDirectoryAsync(IntPtr self, out int error, [MarshalAs(UnmanagedType.LPStr)] string dataSetReference,
+ IedConnection_GetDataSetDirectoryHandler handler, IntPtr parameter);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_GetRCBValuesHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr rcb);
@@ -1727,9 +1745,6 @@ namespace IEC61850
return invokeId;
}
-
-
-
///
/// Abort (close) the connection.
///
@@ -1989,6 +2004,47 @@ namespace IEC61850
}
+ ///
+ /// Create a new data set - asynchronous version.
+ ///
+ /// This function creates a new data set at the server. The data set consists of the members defined
+ /// by the list of object references provided.
+ /// The object reference of the data set
+ /// A list of object references of the data set elements
+ /// Callback function to handle the received response or service timeout
+ /// User provided callback parameter. Will be passed to the callback function
+ /// the invoke ID of the sent request
+ /// This exception is thrown if there is a connection or service error
+ public UInt32 CreateDataSetAsync(string dataSetReference, List dataSetElements, GenericServiceHandler handler, object parameter)
+ {
+ int error = 0;
+
+ IntPtr linkedList = LinkedList_create();
+
+ foreach (string dataSetElement in dataSetElements)
+ {
+ IntPtr dataSetElementHandle = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(dataSetElement);
+
+ LinkedList_add(linkedList, dataSetElementHandle);
+ }
+
+ Tuple callbackInfo = Tuple.Create(handler, parameter);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_createDataSetAsync(connection, out error, dataSetReference, linkedList, nativeGenericServiceHandler, GCHandle.ToIntPtr(handle));
+
+ LinkedList_destroyDeep(linkedList, new LinkedListValueDeleteFunction(FreeHGlobaleDeleteFunction));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Create data set failed", error);
+ }
+
+ return invokeId;
+ }
+
///
/// Delete a data set.
///
@@ -2009,6 +2065,35 @@ namespace IEC61850
return isDeleted;
}
+ ///
+ /// Delete a data set - asynchronous version.
+ ///
+ /// This function will delete a data set at the server. This function may fail if the data set is not
+ /// deletable.
+ /// The object reference of the data set
+ /// Callback function to handle the received response or service timeout
+ /// User provided callback parameter. Will be passed to the callback function
+ /// the invoke ID of the sent request
+ /// This exception is thrown if there is a connection or service error
+ public UInt32 DeleteDataSetAsync(string dataSetReference, GenericServiceHandler handler, object parameter)
+ {
+ int error = 0;
+
+ Tuple callbackInfo = Tuple.Create(handler, parameter);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_deleteDataSetAsync(connection, out error, dataSetReference, nativeGenericServiceHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Delete data set failed", error);
+ }
+
+ return invokeId;
+ }
+
///
/// Get the directory of the data set.
///
@@ -2058,6 +2143,72 @@ namespace IEC61850
return newList;
}
+ ///
+ /// Get data set directory handler.
+ ///
+ /// The invoke ID of the reqeust triggering this callback
+ /// user provided callback parameter
+ /// Error code of response or timeout error in case of a response timeout
+ /// the list of data set entry references
+ /// data set can be deleted by a client (dynamic data set)
+ public delegate void GetDataSetDirectoryHandler(UInt32 invokeId, object parameter, IedClientError err, List dataSetDirectory, bool isDeletable);
+
+ private void nativeGetDataSetDirectoryHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr dataSetDirectory, bool isDeletable)
+ {
+ GCHandle handle = GCHandle.FromIntPtr(parameter);
+
+ Tuple callbackInfo = handle.Target as Tuple;
+
+ GetDataSetDirectoryHandler handler = callbackInfo.Item1;
+ object handlerParameter = callbackInfo.Item2;
+
+ IntPtr element = LinkedList_getNext(dataSetDirectory);
+
+ handle.Free();
+
+ List newList = new List();
+
+ while (element != IntPtr.Zero)
+ {
+ string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
+
+ newList.Add(dataObject);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroy(dataSetDirectory);
+
+ handler.Invoke(invokeId, handlerParameter, (IedClientError)err, newList, isDeletable);
+ }
+
+ ///
+ /// Read the data set directory - asynchronous version
+ ///
+ /// The data set directory async.
+ /// Data set reference.
+ /// Callback function to handle the received response or service timeout
+ /// User provided callback parameter. Will be passed to the callback function
+ /// the invoke ID of the sent request
+ /// This exception is thrown if there is a connection or service error
+ public UInt32 GetDataSetDirectoryAsync(string dataSetReference, GetDataSetDirectoryHandler handler, object parameter)
+ {
+ int error = 0;
+
+ Tuple callbackInfo = Tuple.Create(handler, parameter);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_getDataSetDirectoryAsync(connection, out error, dataSetReference, nativeGetDataSetDirectoryHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Get data set directory failed", error);
+ }
+
+ return invokeId;
+ }
///
/// Read object handler.