diff --git a/dotnet/IEC61850forCSharp/GooseControlBlock.cs b/dotnet/IEC61850forCSharp/GooseControlBlock.cs new file mode 100644 index 00000000..ec27577e --- /dev/null +++ b/dotnet/IEC61850forCSharp/GooseControlBlock.cs @@ -0,0 +1,240 @@ +/* + * GooseControlBlock.cs + * + * Copyright 2017 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ +using System; +using System.Runtime.InteropServices; +using System.Diagnostics; + +using IEC61850.Common; + +namespace IEC61850 +{ + namespace Client + { + + public class GooseControlBlock { + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ClientGooseControlBlock_create (string dataAttributeReference); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void ClientGooseControlBlock_destroy(IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr IedConnection_getGoCBValues (IntPtr connection, out int error, string rcbReference, IntPtr updateRcb); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedConnection_setGoCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + static extern bool ClientGooseControlBlock_getGoEna (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void ClientGooseControlBlock_setGoEna(IntPtr self, bool rptEna); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ClientGooseControlBlock_getGoID (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void ClientGooseControlBlock_setGoID (IntPtr self, string goId); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ClientGooseControlBlock_getDatSet (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void ClientGooseControlBlock_setDatSet (IntPtr self, string datSet); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 ClientGooseControlBlock_getConfRev (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + static extern bool ClientGooseControlBlock_getNdsComm (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 ClientGooseControlBlock_getMinTime (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern UInt32 ClientGooseControlBlock_getMaxTime (IntPtr self); + + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + static extern bool ClientGooseControlBlock_getFixedOffs (IntPtr self); + + + private IntPtr self; + private IntPtr connection; + private string objectReference; + + private bool isDisposed = false; + + private bool flagGoEna = false; + private bool flagGoID = false; + private bool flagDatSet = false; + private bool flagDstAddress = false; + + internal GooseControlBlock(string objectReference, IntPtr connection) + { + self = ClientGooseControlBlock_create (objectReference); + this.connection = connection; + this.objectReference = objectReference; + } + + public string GetObjectReference () + { + return this.objectReference; + } + + /// + /// Read all GoCB values from the server + /// + /// This exception is thrown if there is a connection or service error + public void GetCBValues () + { + int error; + + IedConnection_getGoCBValues (connection, out error, objectReference, self); + + if (error != 0) + throw new IedConnectionException ("getGoCBValues service failed", error); + } + + private void + resetSendFlags() + { + flagGoEna = false; + flagGoID = false; + flagDatSet = false; + flagDstAddress = false; + } + + public void SetCBValues (bool singleRequest) + { + UInt32 parametersMask = 0; + + if (flagGoEna) + parametersMask += 1; + + if (flagGoID) + parametersMask += 2; + + if (flagDatSet) + parametersMask += 4; + + int error; + + IedConnection_setGoCBValues (connection, out error, self, parametersMask, singleRequest); + + resetSendFlags (); + + if (error != 0) + throw new IedConnectionException ("setGoCBValues service failed", error); + } + + public void SetCBValues () + { + SetCBValues (true); + } + + public bool GetGoEna() + { + return ClientGooseControlBlock_getGoEna (self); + } + + public void SetGoEna(bool value) + { + ClientGooseControlBlock_setGoEna (self, value); + + flagGoEna = true; + } + + public string GetGoID() + { + IntPtr goIdRef = ClientGooseControlBlock_getGoID (self); + + return Marshal.PtrToStringAnsi (goIdRef); + } + + public void SetGoID (string goID) + { + ClientGooseControlBlock_setGoID (self, goID); + + flagGoID = true; + } + + public string GetDatSet() + { + IntPtr datSetRef = ClientGooseControlBlock_getDatSet (self); + + return Marshal.PtrToStringAnsi (datSetRef); + } + + public void SetDataSet(string datSet) + { + ClientGooseControlBlock_setDatSet (self, datSet); + + flagDatSet = true; + } + + public UInt32 GetConfRev() + { + return ClientGooseControlBlock_getConfRev (self); + } + + public bool GetNdsComm() + { + return ClientGooseControlBlock_getNdsComm (self); + } + + public UInt32 GetMinTime() + { + return ClientGooseControlBlock_getMinTime (self); + } + + public UInt32 GetMaxTime() + { + return ClientGooseControlBlock_getMaxTime (self); + } + + public bool GetFixedOffs() + { + return ClientGooseControlBlock_getFixedOffs (self); + } + + public void Dispose() + { + if (isDisposed == false) { + isDisposed = true; + ClientGooseControlBlock_destroy (self); + self = IntPtr.Zero; + } + } + + ~GooseControlBlock() + { + Dispose (); + } + + } + } +} \ No newline at end of file diff --git a/dotnet/IEC61850forCSharp/IEC61850.NET.csproj b/dotnet/IEC61850forCSharp/IEC61850.NET.csproj index 550a89b9..e752d257 100644 --- a/dotnet/IEC61850forCSharp/IEC61850.NET.csproj +++ b/dotnet/IEC61850forCSharp/IEC61850.NET.csproj @@ -47,6 +47,7 @@ + \ No newline at end of file diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs index e51c94c4..b17317c4 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs @@ -531,10 +531,28 @@ namespace IEC61850 return controlObject; } + /// + /// Creates a new SampledValuesControlBlock instance. + /// + /// > + /// This function will also read the SVCB values from the server. + /// + /// The new SVCB instance + /// The object reference of the SVCB + public SampledValuesControlBlock GetSvControlBlock (string svcbObjectReference) + { + return new SampledValuesControlBlock (connection, svcbObjectReference); + } - - - + /// + /// Creates a new SampledValuesControlBlock instance. + /// + /// The new GoCB instance + /// The object reference of the GoCB + public GooseControlBlock GetGooseControlBlock (string gocbObjectReference) + { + return new GooseControlBlock (gocbObjectReference, connection); + } /// /// Updates the device model by quering the server. diff --git a/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs b/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs index 1e1d8617..47205465 100644 --- a/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850CommonAPI.cs @@ -72,6 +72,17 @@ namespace IEC61850 } } + [StructLayout(LayoutKind.Sequential)] + public class PhyComAddress + { + public byte vlanPriority; + public UInt16 vlanId; + public UInt16 appId; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] + public byte[] dstAddress = new byte[6]; + } + /// /// MMS data access error for MmsValue type MMS_DATA_ACCESS_ERROR /// diff --git a/dotnet/IEC61850forCSharp/Reporting.cs b/dotnet/IEC61850forCSharp/Reporting.cs index 85bcd249..dfbf6d6b 100644 --- a/dotnet/IEC61850forCSharp/Reporting.cs +++ b/dotnet/IEC61850forCSharp/Reporting.cs @@ -46,19 +46,6 @@ namespace IEC61850 } - /// - /// Creates a new SampledValuesControlBlock instance. - /// - /// > - /// This function will also read the SVCB values from the server. - /// - /// The new SVCB instamce - /// The object reference of the SVCB - public SampledValuesControlBlock GetSvControlBlock (string svcbObjectReference) - { - return new SampledValuesControlBlock (connection, svcbObjectReference); - } - public ReportControlBlock GetReportControlBlock (string rcbObjectReference) { var newRCB = new ReportControlBlock (rcbObjectReference, this, connection); diff --git a/dotnet/IEC61850forCSharp/SampledValuesControlBlock.cs b/dotnet/IEC61850forCSharp/SampledValuesControlBlock.cs index bf4cd213..e306fcaf 100644 --- a/dotnet/IEC61850forCSharp/SampledValuesControlBlock.cs +++ b/dotnet/IEC61850forCSharp/SampledValuesControlBlock.cs @@ -88,6 +88,9 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern int ClientSVControlBlock_getNoASDU (IntPtr self); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern PhyComAddress ClientSVControlBlock_getDstAddress (IntPtr self); + private IntPtr self; private string objectReference; @@ -174,6 +177,11 @@ namespace IEC61850 return ClientSVControlBlock_getNoASDU (self); } + public PhyComAddress GetDstAddress() + { + return ClientSVControlBlock_getDstAddress (self); + } + public void Dispose() { if (isDisposed == false) {