From cf63ab12693ffc2da69aeea7133abfae35c21569 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sat, 27 Oct 2018 14:50:25 +0200 Subject: [PATCH] - .NET API: IedConnection - add async QueryLog functions --- dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs index e354aa2d..771c1274 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs @@ -419,6 +419,18 @@ namespace IEC61850 IedConnection_getLogicalDeviceVariablesAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result, IedConnection_GetNameListHandler handler, IntPtr parameter); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void IedConnection_QueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, [MarshalAs(UnmanagedType.I1)] bool moreFollows); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 + IedConnection_queryLogByTimeAsync(IntPtr self, out int error, string logReference, + UInt64 startTime, UInt64 endTime, IedConnection_QueryLogHandler handler, IntPtr parameter); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 + IedConnection_queryLogAfterAsync(IntPtr self, out int error, string logReference, + IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter); /******************** * FileDirectoryEntry @@ -1690,6 +1702,105 @@ namespace IEC61850 throw new IedConnectionException("Get logical device variables failed", error); } + return invokeId; + } + + + public delegate void QueryLogHandler(UInt32 invokeId, object parameter, IedClientError err, List journalEntries, bool moreFollows); + + private void nativeQueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, + [MarshalAs(UnmanagedType.I1)] bool moreFollows) + { + GCHandle handle = GCHandle.FromIntPtr(parameter); + + Tuple callbackInfo = handle.Target as Tuple; + + QueryLogHandler handler = callbackInfo.Item1; + object handlerParameter = callbackInfo.Item2; + + handle.Free(); + + IedClientError clientError = (IedClientError)err; + + var logResult = WrapNativeLogQueryResult(journalEntries); + + handler(invokeId, handlerParameter, clientError, logResult, moreFollows); + } + + /// + /// Queries all log entries of the given time range (asynchronous version) + /// + /// The list of log entries contained in the response + /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog") + /// Start time of the time range + /// End time of the time range + /// user provided callback function + /// user provided callback parameter + /// This exception is thrown if there is a connection or service error + public UInt32 QueryLogByTimeAsync(string logRef, ulong startTime, ulong stopTime, QueryLogHandler handler, object parameter) + { + int error; + + Tuple callbackInfo = Tuple.Create(handler, parameter); + + GCHandle handle = GCHandle.Alloc(callbackInfo); + + UInt32 invokeId = IedConnection_queryLogByTimeAsync(connection, out error, logRef, startTime, stopTime, nativeQueryLogHandler, GCHandle.ToIntPtr(handle)); + + if (error != 0) + { + handle.Free(); + throw new IedConnectionException("QueryLogByTime failed", error); + } + + return invokeId; + } + + /// + /// Queries all log entries of the given time range (asynchronous version) + /// + /// The list of log entries contained in the response + /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog") + /// Start time of the time range + /// End time of the time range + /// user provided callback function + /// user provided callback parameter + /// This exception is thrown if there is a connection or service error + public UInt32 QueryLogByTimeAsync(string logRef, DateTime startTime, DateTime stopTime, QueryLogHandler handler, object parameter) + { + ulong startTimeMs = LibIEC61850.DateTimeToMsTimestamp (startTime); + ulong stopTimeMs = LibIEC61850.DateTimeToMsTimestamp (stopTime); + + return QueryLogByTimeAsync (logRef, startTimeMs, stopTimeMs, handler, parameter); + } + + /// + /// Queries all log entries after the entry with the given entryID and timestamp (asynchronous version) + /// + /// The list of log entries contained in the response + /// The object reference of the log (e.g. "simpleIOGenericIO/LLN0$EventLog") + /// EntryID of the last received MmsJournalEntry + /// user provided callback function + /// user provided callback parameter + /// This exception is thrown if there is a connection or service error + public UInt32 QueryLogAfterAsync(string logRef, byte[] entryID, ulong timestamp, QueryLogHandler handler, object parameter) + { + int error; + + Tuple callbackInfo = Tuple.Create(handler, parameter); + + GCHandle handle = GCHandle.Alloc(callbackInfo); + + MmsValue entryIdValue = new MmsValue (entryID); + + UInt32 invokeId = IedConnection_queryLogAfterAsync(connection, out error, logRef, entryIdValue.valueReference, timestamp, nativeQueryLogHandler, GCHandle.ToIntPtr(handle)); + + if (error != 0) + { + handle.Free(); + throw new IedConnectionException("QueryLogAfter failed", error); + } + return invokeId; }