diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs index e166c09f..e354aa2d 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs @@ -413,6 +413,12 @@ namespace IEC61850 static extern UInt32 IedConnection_getServerDirectoryAsync(IntPtr self, out int error, string continueAfter, IntPtr result, IedConnection_GetNameListHandler handler, IntPtr parameter); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 + IedConnection_getLogicalDeviceVariablesAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result, + IedConnection_GetNameListHandler handler, IntPtr parameter); + /******************** * FileDirectoryEntry @@ -518,18 +524,33 @@ namespace IEC61850 private UInt32 connectTimeout = 10000; - /// - /// Gets or sets the timeout used for connection attempts. - /// - /// The connect timeout in milliseconds - public UInt32 ConnectTimeout { - get { - return connectTimeout; - } - set { - connectTimeout = value; - } - } + /// + /// Gets or sets the timeout used for connection attempts. + /// + /// The connect timeout in milliseconds + public UInt32 ConnectTimeout + { + get { + return connectTimeout; + } + set { + connectTimeout = value; + } + } + + /// + /// Gets or sets the maximum size if a PDU (has to be set before calling connect!). + /// + /// The maximum allowed size of an MMS PDU. + public int MaxPduSize + { + get { + return GetMmsConnection().GetLocalDetail(); + } + set { + GetMmsConnection().SetLocalDetail(value); + } + } public MmsConnection GetMmsConnection () @@ -1645,6 +1666,30 @@ namespace IEC61850 throw new IedConnectionException("Get server directory failed", error); } + return invokeId; + } + + public UInt32 GetLogicalDeviceVariablesAsync(string ldName, string continueAfter, GetNameListHandler handler, object parameter) + { + return GetLogicalDeviceVariablesAsync(null, ldName, continueAfter, handler, parameter); + } + + public UInt32 GetLogicalDeviceVariablesAsync(List result, string ldName, string continueAfter, GetNameListHandler handler, object parameter) + { + int error; + + Tuple> callbackInfo = Tuple.Create(handler, parameter, result); + + GCHandle handle = GCHandle.Alloc(callbackInfo); + + UInt32 invokeId = IedConnection_getLogicalDeviceVariablesAsync(connection, out error, ldName, continueAfter, IntPtr.Zero, nativeGetNameListHandler, GCHandle.ToIntPtr(handle)); + + if (error != 0) + { + handle.Free(); + throw new IedConnectionException("Get logical device variables failed", error); + } + return invokeId; } diff --git a/dotnet/client_example_async/Program.cs b/dotnet/client_example_async/Program.cs index 1bedc751..22b2eb44 100644 --- a/dotnet/client_example_async/Program.cs +++ b/dotnet/client_example_async/Program.cs @@ -2,6 +2,7 @@ using IEC61850.Client; using IEC61850.Common; using System.Threading; +using System.Collections.Generic; namespace client_example_async { @@ -28,8 +29,84 @@ namespace client_example_async try { + con.MaxPduSize = 1000; + con.Connect(hostname, port); + AutoResetEvent waitForCallback = new AutoResetEvent(false); + + List ldList = null; + + con.GetServerDirectoryAsync(ldList, null, delegate(uint invokeId, object parameter, IedClientError err, System.Collections.Generic.List nameList, bool moreFollows) { + + if (nameList != null) { + ldList = nameList; + } + else + { + Console.WriteLine("Get server directory error: " + err.ToString()); + } + + waitForCallback.Set(); + + }, null); + + waitForCallback.WaitOne(); + + if (ldList != null) { + + string firstLdName = null; + + Console.WriteLine("Server directory:"); + + foreach (string ldName in ldList) { + Console.WriteLine(" LD: " + ldName); + if (firstLdName == null) + firstLdName = ldName; + } + + bool moreVariabesFollows = true; + string lastVariableName = null; + + List variablesList = new List(); + + while (moreVariabesFollows) { + + waitForCallback.Reset(); + + con.GetLogicalDeviceVariablesAsync(variablesList, firstLdName, lastVariableName, delegate(uint invokeId, object parameter, IedClientError err, List nameList, bool moreFollows) { + + if (nameList != null) { + + if (moreFollows) + Console.WriteLine("More variables available..."); + + lastVariableName = nameList[nameList.Count - 1]; + } + else + { + Console.WriteLine("Get logical device variables error: " + err.ToString()); + } + + + moreVariabesFollows = moreFollows; + + waitForCallback.Set(); + }, null); + + waitForCallback.WaitOne(); + } + + Console.WriteLine("Variables in logical device {0}:", firstLdName); + + foreach (string variableName in variablesList) { + Console.WriteLine(" {0}", variableName); + } + + } + + Console.WriteLine("Now read variables..."); + /* read FCDO */ con.ReadValueAsync("simpleIOGenericIO/GGIO1.AnIn1", FunctionalConstraint.MX, delegate(uint invokeId, object parameter, IedClientError err, MmsValue value) { @@ -81,8 +158,7 @@ namespace client_example_async }, null); - - // Thread.Sleep(5000); + Thread.Sleep(5000); con.Abort(); } diff --git a/dotnet/example3/Main.cs b/dotnet/example3/Main.cs index 86fe0644..f742a31a 100644 --- a/dotnet/example3/Main.cs +++ b/dotnet/example3/Main.cs @@ -28,7 +28,7 @@ namespace example3 con.ConnectTimeout = 10000; - con.GetMmsConnection().SetLocalDetail(1200); + con.MaxPduSize = 1200; con.Connect(hostname, 102);