diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index a02a7374..e166c09f 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -398,6 +398,21 @@ namespace IEC61850
IedConnection_readObjectAsync(IntPtr self, out int error, string objRef, int fc,
IedConnection_ReadObjectHandler handler, IntPtr parameter);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate void IedConnection_WriteObjectHandler (UInt32 invokeId, IntPtr parameter, int err);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_writeObjectAsync(IntPtr self, out int error, string objRef, int fc,
+ IntPtr value, IedConnection_WriteObjectHandler handler, IntPtr parameter);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate void IedConnection_GetNameListHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_getServerDirectoryAsync(IntPtr self, out int error, string continueAfter, IntPtr result,
+ IedConnection_GetNameListHandler handler, IntPtr parameter);
/********************
* FileDirectoryEntry
@@ -1492,7 +1507,7 @@ namespace IEC61850
handler(invokeId, handlerParameter, clientError, mmsValue);
}
- /// Asynchronously read the value of a data attribute (DA) or functional constraint data object (FCDO).
+ /// Asynchronously read the value of a data attribute (DA) or functional constraint data object (FCDO) - GetData service
/// The object reference of a DA or FCDO.
/// The functional constraint (FC) of the object
/// Callback function to handle the received response or service timeout
@@ -1515,6 +1530,121 @@ namespace IEC61850
throw new IedConnectionException("Reading value failed", error);
}
+ return invokeId;
+ }
+
+ ///
+ /// Write value 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
+ public delegate void WriteValueHandler(UInt32 invokeId, object parameter, IedClientError err);
+
+ private void nativeWriteObjectHandler (UInt32 invokeId, IntPtr parameter, int err)
+ {
+ GCHandle handle = GCHandle.FromIntPtr(parameter);
+
+ Tuple callbackInfo = handle.Target as Tuple;
+
+ WriteValueHandler handler = callbackInfo.Item1;
+ object handlerParameter = callbackInfo.Item2;
+
+ handle.Free();
+
+ IedClientError clientError = (IedClientError)err;
+
+ handler(invokeId, handlerParameter, clientError);
+ }
+
+
+ public UInt32 WriteValueAsync(string objectReference, FunctionalConstraint fc, MmsValue value, WriteValueHandler handler, object parameter)
+ {
+ int error;
+
+ Tuple callbackInfo = Tuple.Create(handler, parameter);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_writeObjectAsync(connection, out error, objectReference, (int)fc, value.valueReference, nativeWriteObjectHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Writing value failed", error);
+ }
+
+ return invokeId;
+ }
+
+ public delegate void GetNameListHandler(UInt32 invokeId, object parameter, IedClientError err, List nameList, bool moreFollows);
+
+ private void nativeGetNameListHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows)
+ {
+ GCHandle handle = GCHandle.FromIntPtr(parameter);
+
+ Tuple> callbackInfo = handle.Target as Tuple>;
+
+ GetNameListHandler handler = callbackInfo.Item1;
+ object handlerParameter = callbackInfo.Item2;
+ List resultList = callbackInfo.Item3;
+
+ handle.Free();
+
+ IedClientError clientError = (IedClientError)err;
+
+ if (nameList != IntPtr.Zero)
+ {
+ IntPtr element = LinkedList_getNext(nameList);
+
+ if (resultList == null)
+ resultList = new List();
+
+ while (element != IntPtr.Zero)
+ {
+ string ld = Marshal.PtrToStringAnsi(LinkedList_getData(element));
+
+ resultList.Add(ld);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroy(nameList);
+
+ handler(invokeId, handlerParameter, clientError, resultList, moreFollows);
+ }
+ else
+ {
+ handler(invokeId, handlerParameter, clientError, null, moreFollows);
+ }
+
+ }
+
+ ///
+ /// Gets the server directory (Logical devices or file objects)
+ ///
+ /// list where to store the result or null to create a new list for the result
+ /// continuation value (last received name)
+ /// user provided callback function
+ /// user provided callback parameter
+ /// the invoke ID of the sent request
+ /// This exception is thrown if there is a connection or service error
+ public UInt32 GetServerDirectoryAsync(List result, string continueAfter, GetNameListHandler handler, object parameter)
+ {
+ int error;
+
+ Tuple> callbackInfo = Tuple.Create(handler, parameter, result);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_getServerDirectoryAsync(connection, out error, continueAfter, IntPtr.Zero, nativeGetNameListHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Get server directory failed", error);
+ }
+
return invokeId;
}