diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs index d6852a10..a714c55b 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs @@ -2404,6 +2404,33 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern void IedServer_setTimeQuality(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool leapSecondKnown, [MarshalAs(UnmanagedType.I1)] bool clockFailure, [MarshalAs(UnmanagedType.I1)] bool clockNotSynchronized, int subsecondPrecision); + [StructLayout(LayoutKind.Sequential)] + private struct NativeTSelector + { + public byte size; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] value; + } + + [StructLayout(LayoutKind.Sequential)] + private struct NativeSSelector + { + public byte size; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] value; + } + + [StructLayout(LayoutKind.Sequential)] + private struct NativePSelector + { + public byte size; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] value; + } + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedServer_setLocalAddresses(IntPtr self, IntPtr pSel, IntPtr sSel, IntPtr tSel); + private IntPtr self = IntPtr.Zero; private InternalControlHandler internalControlHandlerRef = null; @@ -2612,6 +2639,82 @@ namespace IEC61850 IedServer_setLocalIpAddress (self, localIpAddress); } + /// + /// Set the called (local) addresses that should be checked by the server + /// + /// P-selector (max. 16 bytes), or null when the P-selecter should not be checked + /// S-selector (max. 16 bytes), or null when the S-selecter should not be checked + /// T-selector (max. 4 bytes), or null when the T-selecter should not be checked + /// when a selector is given that exceeds the maximum size + public void SetLocalAddresses(byte[] pSelector, byte[] sSelector, byte[] tSelector) + { + IntPtr nPSel = IntPtr.Zero; + IntPtr nSSel = IntPtr.Zero; + IntPtr nTSel = IntPtr.Zero; + + if (pSelector != null) + { + if (pSelector.Length > 16) + throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded"); + + NativePSelector nativePSelector; + nativePSelector.size = (byte)pSelector.Length; + nativePSelector.value = new byte[16]; + + for (int i = 0; i < pSelector.Length; i++) + nativePSelector.value[i] = pSelector[i]; + + nPSel = Marshal.AllocHGlobal(Marshal.SizeOf(nativePSelector)); + + Marshal.StructureToPtr(nativePSelector, nPSel, false); + } + + if (sSelector != null) + { + if (sSelector.Length > 16) + throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded"); + + NativeSSelector nativeSSelector; + nativeSSelector.size = (byte)sSelector.Length; + nativeSSelector.value = new byte[16]; + + for (int i = 0; i < sSelector.Length; i++) + nativeSSelector.value[i] = sSelector[i]; + + nSSel = Marshal.AllocHGlobal(Marshal.SizeOf(nativeSSelector)); + + Marshal.StructureToPtr(nativeSSelector, nSSel, false); + } + + if (tSelector != null) + { + if (tSelector.Length > 4) + throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded"); + + NativeTSelector nativeTSelector; + nativeTSelector.size = (byte)tSelector.Length; + nativeTSelector.value = new byte[16]; + + for (int i = 0; i < tSelector.Length; i++) + nativeTSelector.value[i] = tSelector[i]; + + nTSel = Marshal.AllocHGlobal(Marshal.SizeOf(nativeTSelector)); + + Marshal.StructureToPtr(nativeTSelector, nTSel, false); + } + + IedServer_setLocalAddresses(self, nPSel, nSSel, nTSel); + + if (nPSel != IntPtr.Zero) + Marshal.FreeHGlobal(nPSel); + + if (nSSel != IntPtr.Zero) + Marshal.FreeHGlobal(nSSel); + + if (nTSel != IntPtr.Zero) + Marshal.FreeHGlobal(nTSel); + } + /// /// Start MMS server ///