Merge branch 'v1.6_develop' of bitbucket.com:mz-automation/libiec61850 into v1.6_develop

v1.6
Michael Zillgith 4 weeks ago
commit 3da8aa5222

@ -0,0 +1,205 @@
/*
* AcseAuthenticationParameter.cs
*
* Copyright 2025-2025 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 <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
/// <summary>
/// Authentication mechanism used by AcseAuthenticator
/// </summary>
public enum AcseAuthenticationMechanism
{
/** Neither ACSE nor TLS authentication used */
ACSE_AUTH_NONE = 0,
/** Use ACSE password for client authentication */
ACSE_AUTH_PASSWORD = 1,
/** Use ACSE certificate for client authentication */
ACSE_AUTH_CERTIFICATE = 2,
/** Use TLS certificate for client authentication */
ACSE_AUTH_TLS = 3
}
public class AcseAuthenticationParameter
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr AcseAuthenticationParameter_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int AcseAuthenticationParameter_getAuthMechanism(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr AcseAuthenticationParameter_getPassword(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int AcseAuthenticationParameter_getPasswordLength(IntPtr self);
private IntPtr self = IntPtr.Zero;
public AcseAuthenticationParameter()
{
self = AcseAuthenticationParameter_create();
}
public AcseAuthenticationParameter(IntPtr self)
{
this.self = self;
}
public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism)
{
AcseAuthenticationParameter_setAuthMechanism(self, (int)acseAuthenticationMechanism);
}
public void SetPassword(string password)
{
AcseAuthenticationParameter_setPassword(self, password);
}
public AcseAuthenticationMechanism GetAuthMechanism()
{
return (AcseAuthenticationMechanism)AcseAuthenticationParameter_getAuthMechanism(self);
}
public string GetPasswordString()
{
try
{
byte[] password = GetPasswordByteArray();
return Encoding.UTF8.GetString(password);
}
catch (Exception)
{
return null;
}
}
public byte[] GetPasswordByteArray()
{
IntPtr password = AcseAuthenticationParameter_getPassword(self);
if (password != IntPtr.Zero)
{
int lenght = GetPasswordLenght();
byte[] result = new byte[lenght];
Marshal.Copy(password, result, 0, lenght);
return result;
}
else
return null;
}
public int GetPasswordLenght()
{
return AcseAuthenticationParameter_getPasswordLength(self);
}
}
public class IsoApplicationReference
{
private IntPtr self = IntPtr.Zero;
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int IsoApplicationReference_getAeQualifier(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IsoApplicationReference_getApTitle(IntPtr self);
public IsoApplicationReference(IntPtr self)
{
this.self = self;
}
public int GetAeQualifier()
{
return IsoApplicationReference_getAeQualifier(self);
}
public ItuObjectIdentifier GetApTitle()
{
IntPtr identfier = IsoApplicationReference_getApTitle(self);
if (identfier == IntPtr.Zero)
return null;
return new ItuObjectIdentifier(identfier);
}
}
public class ItuObjectIdentifier
{
private IntPtr self = IntPtr.Zero;
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ItuObjectIdentifier_getArcCount(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ItuObjectIdentifier_getArc(IntPtr self);
public ItuObjectIdentifier(IntPtr self)
{
this.self = self;
}
public int GetArcCount()
{
return ItuObjectIdentifier_getArcCount(self);
}
public ushort[] GetArcs()
{
int count = ItuObjectIdentifier_getArcCount(self);
if (count <= 0 || count > 10) return Array.Empty<ushort>();
IntPtr arcPtr = ItuObjectIdentifier_getArc(self);
ushort[] arcs = new ushort[count];
short[] temp = new short[count];
Marshal.Copy(arcPtr, temp, 0, count);
for (int i = 0; i < count; i++)
arcs[i] = (ushort)temp[i];
return arcs;
}
}
}

@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

@ -1,7 +1,7 @@
/* /*
* Control.cs * Control.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,15 +21,15 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
// IEC 61850 common API parts (used by client and server API) // IEC 61850 common API parts (used by client and server API)
namespace Common { namespace Common
{
/// <summary> /// <summary>
/// Control model /// Control model
@ -39,7 +39,7 @@ namespace IEC61850
/** status only */ /** status only */
STATUS_ONLY = 0, STATUS_ONLY = 0,
/** direct with normal security */ /** direct with normal security */
DIRECT_NORMAL= 1, DIRECT_NORMAL = 1,
/** select before operate (SBO) with normal security */ /** select before operate (SBO) with normal security */
SBO_NORMAL = 2, SBO_NORMAL = 2,
/** direct with enhanced security */ /** direct with enhanced security */
@ -51,7 +51,8 @@ namespace IEC61850
/// <summary> /// <summary>
/// Originator category /// Originator category
/// </summary> /// </summary>
public enum OrCat { public enum OrCat
{
/** Not supported - should not be used */ /** Not supported - should not be used */
NOT_SUPPORTED = 0, NOT_SUPPORTED = 0,
/** Control operation issued from an operator using a client located at bay level */ /** Control operation issued from an operator using a client located at bay level */
@ -71,32 +72,32 @@ namespace IEC61850
/** Status change occurred without control action (for example external trip of a circuit breaker or failure inside the breaker) */ /** Status change occurred without control action (for example external trip of a circuit breaker or failure inside the breaker) */
PROCESS = 8 PROCESS = 8
} }
} }
namespace Client namespace Client
{ {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct LastApplErrorInternal internal struct LastApplErrorInternal
{ {
public int ctlNum; public int ctlNum;
public int error; public int error;
public int addCause; public int addCause;
} }
public class LastApplError public class LastApplError
{ {
public int ctlNum; public int ctlNum;
public int error; public int error;
public ControlAddCause addCause; public ControlAddCause addCause;
internal LastApplError (LastApplErrorInternal lastApplError) internal LastApplError(LastApplErrorInternal lastApplError)
{ {
this.addCause = (ControlAddCause) lastApplError.addCause; addCause = (ControlAddCause)lastApplError.addCause;
this.error = lastApplError.error; error = lastApplError.error;
this.ctlNum = lastApplError.ctlNum; ctlNum = lastApplError.ctlNum;
} }
} }
public enum ControlActionType public enum ControlActionType
{ {
@ -109,36 +110,36 @@ namespace IEC61850
/// Control object. /// Control object.
/// </summary> /// </summary>
public class ControlObject : IDisposable public class ControlObject : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern LastApplErrorInternal ControlObjectClient_getLastApplError(IntPtr self); private static extern LastApplErrorInternal ControlObjectClient_getLastApplError(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ControlObjectClient_create(string objectReference, IntPtr connection); private static extern IntPtr ControlObjectClient_create(string objectReference, IntPtr connection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_destroy(IntPtr self); private static extern void ControlObjectClient_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int ControlObjectClient_getControlModel(IntPtr self); private static extern int ControlObjectClient_getControlModel(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int ControlObjectClient_getCtlValType(IntPtr self); private static extern int ControlObjectClient_getCtlValType(IntPtr self);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int ControlObjectClient_getLastError (IntPtr self); private static extern int ControlObjectClient_getLastError(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime); private static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime);
/// <summary> /// <summary>
/// Handler for asynchronous control actions (select, operate, cancel) /// Handler for asynchronous control actions (select, operate, cancel)
/// </summary> /// </summary>
public delegate void ControlActionHandler (UInt32 invokeId, Object parameter, IedClientError error, ControlActionType type, bool success); public delegate void ControlActionHandler(UInt32 invokeId, Object parameter, IedClientError error, ControlActionType type, bool success);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void ControlObjectClient_ControlActionHandler (UInt32 invokeId, IntPtr parameter, int err, int type, [MarshalAs(UnmanagedType.I1)] bool success); private delegate void ControlObjectClient_ControlActionHandler(UInt32 invokeId, IntPtr parameter, int err, int type, [MarshalAs(UnmanagedType.I1)] bool success);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 ControlObjectClient_operateAsync(IntPtr self, out int err, IntPtr ctlVal, UInt64 operTime, private static extern UInt32 ControlObjectClient_operateAsync(IntPtr self, out int err, IntPtr ctlVal, UInt64 operTime,
@ -171,51 +172,51 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setOrigin(IntPtr self, string orIdent, int orCat); private static extern void ControlObjectClient_setOrigin(IntPtr self, string orIdent, int orCat);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setInterlockCheck(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); private static extern void ControlObjectClient_setInterlockCheck(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setSynchroCheck(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); private static extern void ControlObjectClient_setSynchroCheck(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setTestMode(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); private static extern void ControlObjectClient_setTestMode(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalCommandTerminationHandler(IntPtr parameter,IntPtr controlClient); private delegate void InternalCommandTerminationHandler(IntPtr parameter, IntPtr controlClient);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void ControlObjectClient_setCommandTerminationHandler(IntPtr self, private static extern void ControlObjectClient_setCommandTerminationHandler(IntPtr self,
InternalCommandTerminationHandler handler, IntPtr handlerParameter); InternalCommandTerminationHandler handler, IntPtr handlerParameter);
public delegate void CommandTerminationHandler (Object parameter, ControlObject controlObject); public delegate void CommandTerminationHandler(Object parameter, ControlObject controlObject);
private IedConnection iedConnection; private IedConnection iedConnection;
private IntPtr self; private IntPtr self;
private CommandTerminationHandler commandTerminationHandler = null; private CommandTerminationHandler commandTerminationHandler = null;
private Object commandTerminationHandlerParameter = null; private Object commandTerminationHandlerParameter = null;
private void MyCommandTerminationHandler (IntPtr paramter, IntPtr controlClient) private void MyCommandTerminationHandler(IntPtr paramter, IntPtr controlClient)
{ {
if (commandTerminationHandler != null) if (commandTerminationHandler != null)
commandTerminationHandler(commandTerminationHandlerParameter, this); commandTerminationHandler(commandTerminationHandlerParameter, this);
} }
private InternalCommandTerminationHandler intCommandTerminationHandler; private InternalCommandTerminationHandler intCommandTerminationHandler;
internal ControlObject (string objectReference, IntPtr connection, IedConnection iedConnection) internal ControlObject(string objectReference, IntPtr connection, IedConnection iedConnection)
{ {
this.iedConnection = iedConnection; this.iedConnection = iedConnection;
this.self = ControlObjectClient_create(objectReference, connection); self = ControlObjectClient_create(objectReference, connection);
if (this.self == System.IntPtr.Zero) if (self == System.IntPtr.Zero)
throw new IedConnectionException("Control object not found", 0); throw new IedConnectionException("Control object not found", 0);
intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler); intCommandTerminationHandler = new InternalCommandTerminationHandler(MyCommandTerminationHandler);
ControlObjectClient_setCommandTerminationHandler(self, intCommandTerminationHandler, self); ControlObjectClient_setCommandTerminationHandler(self, intCommandTerminationHandler, self);
} }
/// <summary> /// <summary>
/// Gets the control model. /// Gets the control model.
@ -223,23 +224,23 @@ namespace IEC61850
/// <returns> /// <returns>
/// The control model. /// The control model.
/// </returns> /// </returns>
public ControlModel GetControlModel () public ControlModel GetControlModel()
{ {
ControlModel controlModel = (ControlModel) ControlObjectClient_getControlModel(self); ControlModel controlModel = (ControlModel)ControlObjectClient_getControlModel(self);
return controlModel; return controlModel;
} }
/// <summary> /// <summary>
/// Get the type of ctlVal. /// Get the type of ctlVal.
/// </summary> /// </summary>
/// <returns>MmsType required for the ctlVal value.</returns> /// <returns>MmsType required for the ctlVal value.</returns>
public MmsType GetCtlValType () public MmsType GetCtlValType()
{ {
MmsType ctlValType = (MmsType) ControlObjectClient_getCtlValType (self); MmsType ctlValType = (MmsType)ControlObjectClient_getCtlValType(self);
return ctlValType; return ctlValType;
} }
/// <summary> /// <summary>
/// Sets the origin parameter used by control commands. /// Sets the origin parameter used by control commands.
@ -250,18 +251,20 @@ namespace IEC61850
/// <param name='originatorCategory'> /// <param name='originatorCategory'>
/// Originator category. /// Originator category.
/// </param> /// </param>
public void SetOrigin (string originator, OrCat originatorCategory) public void SetOrigin(string originator, OrCat originatorCategory)
{ {
ControlObjectClient_setOrigin(self, originator, (int) originatorCategory); ControlObjectClient_setOrigin(self, originator, (int)originatorCategory);
} }
/// <summary> /// <summary>
/// Gets the error code of the last synchronous control action (operate, select, select-with-value, cancel) /// Gets the error code of the last synchronous control action (operate, select, select-with-value, cancel)
/// </summary> /// </summary>
/// <value>error code.</value> /// <value>error code.</value>
public IedClientError LastError { public IedClientError LastError
get { {
return (IedClientError)ControlObjectClient_getLastError (self); get
{
return (IedClientError)ControlObjectClient_getLastError(self);
} }
} }
@ -270,10 +273,10 @@ namespace IEC61850
/// </summary> /// </summary>
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (bool ctlVal) public bool Operate(bool ctlVal)
{ {
return Operate (ctlVal, 0); return Operate(ctlVal, 0);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value (time activated control). /// Operate the control with the specified control value (time activated control).
@ -281,22 +284,22 @@ namespace IEC61850
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <param name='operTime'>the time when the operation will be executed</param> /// <param name='operTime'>the time when the operation will be executed</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (bool ctlVal, UInt64 operTime) public bool Operate(bool ctlVal, UInt64 operTime)
{ {
MmsValue value = new MmsValue(ctlVal); MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime); return Operate(value, operTime);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value. /// Operate the control with the specified control value.
/// </summary> /// </summary>
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (float ctlVal) public bool Operate(float ctlVal)
{ {
return Operate (ctlVal, 0); return Operate(ctlVal, 0);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value (time activated control). /// Operate the control with the specified control value (time activated control).
@ -304,22 +307,22 @@ namespace IEC61850
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <param name='operTime'>the time when the operation will be executed</param> /// <param name='operTime'>the time when the operation will be executed</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (float ctlVal, UInt64 operTime) public bool Operate(float ctlVal, UInt64 operTime)
{ {
MmsValue value = new MmsValue(ctlVal); MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime); return Operate(value, operTime);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value. /// Operate the control with the specified control value.
/// </summary> /// </summary>
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (int ctlVal) public bool Operate(int ctlVal)
{ {
return Operate (ctlVal, 0); return Operate(ctlVal, 0);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value (time activated control). /// Operate the control with the specified control value (time activated control).
@ -327,22 +330,22 @@ namespace IEC61850
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <param name='operTime'>the time when the operation will be executed</param> /// <param name='operTime'>the time when the operation will be executed</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (int ctlVal, UInt64 operTime) public bool Operate(int ctlVal, UInt64 operTime)
{ {
MmsValue value = new MmsValue(ctlVal); MmsValue value = new MmsValue(ctlVal);
return Operate (value, operTime); return Operate(value, operTime);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value. /// Operate the control with the specified control value.
/// </summary> /// </summary>
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (MmsValue ctlVal) public bool Operate(MmsValue ctlVal)
{ {
return Operate (ctlVal, 0); return Operate(ctlVal, 0);
} }
/// <summary> /// <summary>
/// Operate the control with the specified control value (time activated control). /// Operate the control with the specified control value (time activated control).
@ -350,18 +353,18 @@ namespace IEC61850
/// <param name='ctlVal'>the new value of the control</param> /// <param name='ctlVal'>the new value of the control</param>
/// <param name='operTime'>the time when the operation will be executed</param> /// <param name='operTime'>the time when the operation will be executed</param>
/// <returns>true when the operation has been successful, false otherwise</returns> /// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (MmsValue ctlVal, UInt64 operTime) public bool Operate(MmsValue ctlVal, UInt64 operTime)
{ {
return ControlObjectClient_operate(self, ctlVal.valueReference, operTime); return ControlObjectClient_operate(self, ctlVal.valueReference, operTime);
} }
private ControlObjectClient_ControlActionHandler internalOperateHandler = null; private ControlObjectClient_ControlActionHandler internalOperateHandler = null;
private void nativeOperateHandler (UInt32 invokeId, IntPtr parameter, int err, int type, bool success) private void nativeOperateHandler(UInt32 invokeId, IntPtr parameter, int err, int type, bool success)
{ {
GCHandle handle = GCHandle.FromIntPtr(parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
Tuple<ControlActionHandler, object> callbackInfo = handle.Target as Tuple<ControlActionHandler, object>; Tuple<ControlActionHandler, object> callbackInfo = handle.Target as Tuple<ControlActionHandler, object>;
ControlActionHandler handler = callbackInfo.Item1; ControlActionHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2; object handlerParameter = callbackInfo.Item2;
@ -370,7 +373,7 @@ namespace IEC61850
IedClientError clientError = (IedClientError)err; IedClientError clientError = (IedClientError)err;
handler(invokeId, handlerParameter, clientError, (ControlActionType) type, success); handler(invokeId, handlerParameter, clientError, (ControlActionType)type, success);
} }
@ -382,9 +385,9 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (bool ctlVal, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(bool ctlVal, ControlActionHandler handler, object parameter)
{ {
return OperateAsync (ctlVal, 0, handler, parameter); return OperateAsync(ctlVal, 0, handler, parameter);
} }
/// <summary> /// <summary>
@ -396,11 +399,11 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (bool ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(bool ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter)
{ {
MmsValue value = new MmsValue(ctlVal); MmsValue value = new MmsValue(ctlVal);
return OperateAsync (value, operTime, handler, parameter); return OperateAsync(value, operTime, handler, parameter);
} }
/// <summary> /// <summary>
@ -411,9 +414,9 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (float ctlVal, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(float ctlVal, ControlActionHandler handler, object parameter)
{ {
return OperateAsync (ctlVal, 0, handler, parameter); return OperateAsync(ctlVal, 0, handler, parameter);
} }
/// <summary> /// <summary>
@ -425,11 +428,11 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (float ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(float ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter)
{ {
MmsValue value = new MmsValue(ctlVal); MmsValue value = new MmsValue(ctlVal);
return OperateAsync (value, operTime, handler, parameter); return OperateAsync(value, operTime, handler, parameter);
} }
/// <summary> /// <summary>
@ -440,9 +443,9 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (int ctlVal, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(int ctlVal, ControlActionHandler handler, object parameter)
{ {
return OperateAsync (ctlVal, 0, handler, parameter); return OperateAsync(ctlVal, 0, handler, parameter);
} }
/// <summary> /// <summary>
@ -454,9 +457,9 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (int ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(int ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter)
{ {
return OperateAsync (ctlVal, operTime, handler, parameter); return OperateAsync(ctlVal, operTime, handler, parameter);
} }
/// <summary> /// <summary>
@ -467,9 +470,9 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (MmsValue ctlVal, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(MmsValue ctlVal, ControlActionHandler handler, object parameter)
{ {
return OperateAsync (ctlVal, 0, handler, parameter); return OperateAsync(ctlVal, 0, handler, parameter);
} }
/// <summary> /// <summary>
@ -481,7 +484,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 OperateAsync (MmsValue ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter) public UInt32 OperateAsync(MmsValue ctlVal, UInt64 operTime, ControlActionHandler handler, object parameter)
{ {
int error; int error;
@ -507,7 +510,7 @@ namespace IEC61850
/// Select the control object. /// Select the control object.
/// </summary> /// </summary>
/// <returns>true when the selection has been successful, false otherwise</returns> /// <returns>true when the selection has been successful, false otherwise</returns>
public bool Select () public bool Select()
{ {
return ControlObjectClient_select(self); return ControlObjectClient_select(self);
} }
@ -546,7 +549,7 @@ namespace IEC61850
/// </summary> /// </summary>
/// <param name='ctlVal'>the value to be checked.</param> /// <param name='ctlVal'>the value to be checked.</param>
/// <returns>true when the selection has been successful, false otherwise</returns> /// <returns>true when the selection has been successful, false otherwise</returns>
public bool SelectWithValue (MmsValue ctlVal) public bool SelectWithValue(MmsValue ctlVal)
{ {
return ControlObjectClient_selectWithValue(self, ctlVal.valueReference); return ControlObjectClient_selectWithValue(self, ctlVal.valueReference);
} }
@ -558,7 +561,7 @@ namespace IEC61850
/// the value to be checked. /// the value to be checked.
/// </param> /// </param>
/// <returns>true when the selection has been successful, false otherwise</returns> /// <returns>true when the selection has been successful, false otherwise</returns>
public bool SelectWithValue (bool ctlVal) public bool SelectWithValue(bool ctlVal)
{ {
return SelectWithValue(new MmsValue(ctlVal)); return SelectWithValue(new MmsValue(ctlVal));
} }
@ -570,7 +573,7 @@ namespace IEC61850
/// the value to be checked. /// the value to be checked.
/// </param> /// </param>
/// <returns>true when the selection has been successful, false otherwise</returns> /// <returns>true when the selection has been successful, false otherwise</returns>
public bool SelectWithValue (int ctlVal) public bool SelectWithValue(int ctlVal)
{ {
return SelectWithValue(new MmsValue(ctlVal)); return SelectWithValue(new MmsValue(ctlVal));
} }
@ -582,7 +585,7 @@ namespace IEC61850
/// the value to be checked. /// the value to be checked.
/// </param> /// </param>
/// <returns>true when the selection has been successful, false otherwise</returns> /// <returns>true when the selection has been successful, false otherwise</returns>
public bool SelectWithValue (float ctlVal) public bool SelectWithValue(float ctlVal)
{ {
return SelectWithValue(new MmsValue(ctlVal)); return SelectWithValue(new MmsValue(ctlVal));
} }
@ -595,7 +598,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 SelectWithValueAsync (bool ctlVal, ControlActionHandler handler, object parameter) public UInt32 SelectWithValueAsync(bool ctlVal, ControlActionHandler handler, object parameter)
{ {
return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter); return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter);
} }
@ -608,7 +611,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 SelectWithValueAsync (int ctlVal, ControlActionHandler handler, object parameter) public UInt32 SelectWithValueAsync(int ctlVal, ControlActionHandler handler, object parameter)
{ {
return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter); return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter);
} }
@ -621,7 +624,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 SelectWithValueAsync (float ctlVal, ControlActionHandler handler, object parameter) public UInt32 SelectWithValueAsync(float ctlVal, ControlActionHandler handler, object parameter)
{ {
return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter); return SelectWithValueAsync(new MmsValue(ctlVal), handler, parameter);
} }
@ -634,7 +637,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public UInt32 SelectWithValueAsync (MmsValue ctlVal, ControlActionHandler handler, object parameter) public UInt32 SelectWithValueAsync(MmsValue ctlVal, ControlActionHandler handler, object parameter)
{ {
int error; int error;
@ -664,7 +667,7 @@ namespace IEC61850
/// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param> /// <param name="parameter">User provided callback parameter. Will be passed to the callback function</param>
/// <returns>the invoke ID of the sent request</returns> /// <returns>the invoke ID of the sent request</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public bool Cancel () public bool Cancel()
{ {
return ControlObjectClient_cancel(self); return ControlObjectClient_cancel(self);
} }
@ -698,90 +701,93 @@ namespace IEC61850
/// Enables the synchro check for operate commands /// Enables the synchro check for operate commands
/// </summary> /// </summary>
[Obsolete("use SetSynchroCheck instead")] [Obsolete("use SetSynchroCheck instead")]
public void EnableSynchroCheck () public void EnableSynchroCheck()
{ {
ControlObjectClient_setSynchroCheck (self, true); ControlObjectClient_setSynchroCheck(self, true);
} }
/// <summary> /// <summary>
/// Enables the interlock check for operate and select commands /// Enables the interlock check for operate and select commands
/// </summary> /// </summary>
[Obsolete("use SetInterlockCheck instead")] [Obsolete("use SetInterlockCheck instead")]
public void EnableInterlockCheck () public void EnableInterlockCheck()
{ {
ControlObjectClient_setInterlockCheck (self, true); ControlObjectClient_setInterlockCheck(self, true);
} }
/// <summary> /// <summary>
/// Sets the value of the interlock check flag for operate and select commands /// Sets the value of the interlock check flag for operate and select commands
/// </summary> /// </summary>
public void SetInterlockCheck (bool value) public void SetInterlockCheck(bool value)
{ {
ControlObjectClient_setInterlockCheck (self, value); ControlObjectClient_setInterlockCheck(self, value);
} }
/// <summary> /// <summary>
/// Sets the value of the synchro check flag for operate command /// Sets the value of the synchro check flag for operate command
/// </summary> /// </summary>
public void SetSynchroCheck (bool value) public void SetSynchroCheck(bool value)
{ {
ControlObjectClient_setSynchroCheck (self, value); ControlObjectClient_setSynchroCheck(self, value);
} }
/// <summary> /// <summary>
/// Sets the value of the test flag for the operate command /// Sets the value of the test flag for the operate command
/// </summary> /// </summary>
public void SetTestMode (bool value) public void SetTestMode(bool value)
{ {
ControlObjectClient_setTestMode (self, value); ControlObjectClient_setTestMode(self, value);
} }
/// <summary> /// <summary>
/// Gets the last received LastApplError (Additional Cause Diagnostics) value. /// Gets the last received LastApplError (Additional Cause Diagnostics) value.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// The last appl error. /// The last appl error.
/// </returns> /// </returns>
public LastApplError GetLastApplError () public LastApplError GetLastApplError()
{ {
LastApplErrorInternal lastApplError = ControlObjectClient_getLastApplError(self); LastApplErrorInternal lastApplError = ControlObjectClient_getLastApplError(self);
return new LastApplError(lastApplError); return new LastApplError(lastApplError);
} }
/// <summary> /// <summary>
/// Sets the command termination handler. /// Sets the command termination handler.
/// </summary> /// </summary>
/// <param name='handler'> /// <param name='handler'>
/// the handler (delegate) that is invoked when a CommandTerminationMessage is received. /// the handler (delegate) that is invoked when a CommandTerminationMessage is received.
/// </param> /// </param>
/// <param name='parameter'> /// <param name='parameter'>
/// Parameter. /// Parameter.
/// </param> /// </param>
public void SetCommandTerminationHandler (CommandTerminationHandler handler, Object parameter) public void SetCommandTerminationHandler(CommandTerminationHandler handler, Object parameter)
{ {
this.commandTerminationHandler = handler; commandTerminationHandler = handler;
this.commandTerminationHandlerParameter = parameter; commandTerminationHandlerParameter = parameter;
} }
protected virtual void Dispose(bool disposing) { protected virtual void Dispose(bool disposing)
if (this.self != System.IntPtr.Zero) { {
ControlObjectClient_destroy (self); if (self != System.IntPtr.Zero)
this.self = System.IntPtr.Zero; {
} ControlObjectClient_destroy(self);
} self = System.IntPtr.Zero;
}
public void Dispose() { }
Dispose (true);
} public void Dispose()
{
~ControlObject() Dispose(true);
{ }
Dispose (false);
} ~ControlObject()
} {
Dispose(false);
} }
}
}
} }

@ -1,7 +1,7 @@
/* /*
* DataSet.cs * DataSet.cs
* *
* Copyright 2014-2018 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,12 +20,10 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace Client namespace Client

@ -1,7 +1,7 @@
/* /*
* GooseControlBlock.cs * GooseControlBlock.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,270 +20,270 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace Client namespace Client
{ {
public class GooseControlBlock : IDisposable { public class GooseControlBlock : IDisposable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientGooseControlBlock_create (string dataAttributeReference); static extern IntPtr ClientGooseControlBlock_create(string dataAttributeReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientGooseControlBlock_destroy(IntPtr self); static extern void ClientGooseControlBlock_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getGoCBValues (IntPtr connection, out int error, string rcbReference, IntPtr updateRcb); static extern IntPtr IedConnection_getGoCBValues(IntPtr connection, out int error, string rcbReference, IntPtr updateRcb);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setGoCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, [MarshalAs(UnmanagedType.I1)] bool singleRequest); static extern void IedConnection_setGoCBValues(IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, [MarshalAs(UnmanagedType.I1)] bool singleRequest);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientGooseControlBlock_getGoEna (IntPtr self); static extern bool ClientGooseControlBlock_getGoEna(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientGooseControlBlock_setGoEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna); static extern void ClientGooseControlBlock_setGoEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientGooseControlBlock_getGoID (IntPtr self); static extern IntPtr ClientGooseControlBlock_getGoID(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientGooseControlBlock_setGoID (IntPtr self, string goId); static extern void ClientGooseControlBlock_setGoID(IntPtr self, string goId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientGooseControlBlock_getDatSet (IntPtr self); static extern IntPtr ClientGooseControlBlock_getDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientGooseControlBlock_setDatSet (IntPtr self, string datSet); static extern void ClientGooseControlBlock_setDatSet(IntPtr self, string datSet);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientGooseControlBlock_getConfRev (IntPtr self); static extern UInt32 ClientGooseControlBlock_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientGooseControlBlock_getNdsComm (IntPtr self); static extern bool ClientGooseControlBlock_getNdsComm(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientGooseControlBlock_getMinTime (IntPtr self); static extern UInt32 ClientGooseControlBlock_getMinTime(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientGooseControlBlock_getMaxTime (IntPtr self); static extern UInt32 ClientGooseControlBlock_getMaxTime(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientGooseControlBlock_getFixedOffs (IntPtr self); static extern bool ClientGooseControlBlock_getFixedOffs(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern PhyComAddress ClientGooseControlBlock_getDstAddress (IntPtr self); static extern PhyComAddress ClientGooseControlBlock_getDstAddress(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientGooseControlBlock_getDstAddress_addr(IntPtr self); static extern IntPtr ClientGooseControlBlock_getDstAddress_addr(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern byte ClientGooseControlBlock_getDstAddress_priority(IntPtr self); static extern byte ClientGooseControlBlock_getDstAddress_priority(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientGooseControlBlock_getDstAddress_vid(IntPtr self); static extern UInt16 ClientGooseControlBlock_getDstAddress_vid(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientGooseControlBlock_getDstAddress_appid(IntPtr self); static extern UInt16 ClientGooseControlBlock_getDstAddress_appid(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientGooseControlBlock_setDstAddress (IntPtr self, PhyComAddress value); static extern void ClientGooseControlBlock_setDstAddress(IntPtr self, PhyComAddress value);
private IntPtr self; private IntPtr self;
private IntPtr connection; private IntPtr connection;
private string objectReference; private string objectReference;
private bool isDisposed = false; private bool isDisposed = false;
private bool flagGoEna = false; private bool flagGoEna = false;
private bool flagGoID = false; private bool flagGoID = false;
private bool flagDatSet = false; private bool flagDatSet = false;
private bool flagDstAddress = false; private bool flagDstAddress = false;
internal GooseControlBlock(string objectReference, IntPtr connection) internal GooseControlBlock(string objectReference, IntPtr connection)
{ {
self = ClientGooseControlBlock_create (objectReference); self = ClientGooseControlBlock_create(objectReference);
this.connection = connection; this.connection = connection;
this.objectReference = objectReference; this.objectReference = objectReference;
} }
public string GetObjectReference () public string GetObjectReference()
{ {
return this.objectReference; return objectReference;
} }
/// <summary> /// <summary>
/// Read all GoCB values from the server /// Read all GoCB values from the server
/// </summary> /// </summary>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void GetCBValues () public void GetCBValues()
{ {
int error; int error;
IedConnection_getGoCBValues (connection, out error, objectReference, self); IedConnection_getGoCBValues(connection, out error, objectReference, self);
if (error != 0) if (error != 0)
throw new IedConnectionException ("getGoCBValues service failed", error); throw new IedConnectionException("getGoCBValues service failed", error);
} }
private void private void
resetSendFlags() resetSendFlags()
{ {
flagGoEna = false; flagGoEna = false;
flagGoID = false; flagGoID = false;
flagDatSet = false; flagDatSet = false;
flagDstAddress = false; flagDstAddress = false;
} }
public void SetCBValues (bool singleRequest) public void SetCBValues(bool singleRequest)
{ {
UInt32 parametersMask = 0; UInt32 parametersMask = 0;
if (flagGoEna) if (flagGoEna)
parametersMask += 1; parametersMask += 1;
if (flagGoID) if (flagGoID)
parametersMask += 2; parametersMask += 2;
if (flagDatSet) if (flagDatSet)
parametersMask += 4; parametersMask += 4;
if (flagDstAddress) if (flagDstAddress)
parametersMask += 32; parametersMask += 32;
int error; int error;
IedConnection_setGoCBValues (connection, out error, self, parametersMask, singleRequest); IedConnection_setGoCBValues(connection, out error, self, parametersMask, singleRequest);
resetSendFlags (); resetSendFlags();
if (error != 0) if (error != 0)
throw new IedConnectionException ("setGoCBValues service failed", error); throw new IedConnectionException("setGoCBValues service failed", error);
} }
public void SetCBValues () public void SetCBValues()
{ {
SetCBValues (true); SetCBValues(true);
} }
public bool GetGoEna() public bool GetGoEna()
{ {
return ClientGooseControlBlock_getGoEna (self); return ClientGooseControlBlock_getGoEna(self);
} }
public void SetGoEna(bool value) public void SetGoEna(bool value)
{ {
ClientGooseControlBlock_setGoEna (self, value); ClientGooseControlBlock_setGoEna(self, value);
flagGoEna = true; flagGoEna = true;
} }
public string GetGoID() public string GetGoID()
{ {
IntPtr goIdRef = ClientGooseControlBlock_getGoID (self); IntPtr goIdRef = ClientGooseControlBlock_getGoID(self);
return Marshal.PtrToStringAnsi (goIdRef); return Marshal.PtrToStringAnsi(goIdRef);
} }
public void SetGoID (string goID) public void SetGoID(string goID)
{ {
ClientGooseControlBlock_setGoID (self, goID); ClientGooseControlBlock_setGoID(self, goID);
flagGoID = true; flagGoID = true;
} }
public string GetDatSet() public string GetDatSet()
{ {
IntPtr datSetRef = ClientGooseControlBlock_getDatSet (self); IntPtr datSetRef = ClientGooseControlBlock_getDatSet(self);
return Marshal.PtrToStringAnsi (datSetRef); return Marshal.PtrToStringAnsi(datSetRef);
} }
public void SetDataSet(string datSet) public void SetDataSet(string datSet)
{ {
ClientGooseControlBlock_setDatSet (self, datSet); ClientGooseControlBlock_setDatSet(self, datSet);
flagDatSet = true; flagDatSet = true;
} }
public UInt32 GetConfRev() public UInt32 GetConfRev()
{ {
return ClientGooseControlBlock_getConfRev (self); return ClientGooseControlBlock_getConfRev(self);
} }
public bool GetNdsComm() public bool GetNdsComm()
{ {
return ClientGooseControlBlock_getNdsComm (self); return ClientGooseControlBlock_getNdsComm(self);
} }
public UInt32 GetMinTime() public UInt32 GetMinTime()
{ {
return ClientGooseControlBlock_getMinTime (self); return ClientGooseControlBlock_getMinTime(self);
} }
public UInt32 GetMaxTime() public UInt32 GetMaxTime()
{ {
return ClientGooseControlBlock_getMaxTime (self); return ClientGooseControlBlock_getMaxTime(self);
} }
public bool GetFixedOffs() public bool GetFixedOffs()
{ {
return ClientGooseControlBlock_getFixedOffs (self); return ClientGooseControlBlock_getFixedOffs(self);
} }
public PhyComAddress GetDstAddress() public PhyComAddress GetDstAddress()
{ {
PhyComAddress addr = new PhyComAddress(); PhyComAddress addr = new PhyComAddress();
IntPtr value = ClientGooseControlBlock_getDstAddress_addr(self); IntPtr value = ClientGooseControlBlock_getDstAddress_addr(self);
MmsValue mmsValue = new MmsValue(value); MmsValue mmsValue = new MmsValue(value);
byte[] dstMacAddr = mmsValue.getOctetString(); byte[] dstMacAddr = mmsValue.getOctetString();
dstMacAddr.CopyTo(addr.dstAddress, 0); dstMacAddr.CopyTo(addr.dstAddress, 0);
addr.dstAddress = dstMacAddr; addr.dstAddress = dstMacAddr;
addr.appId = ClientGooseControlBlock_getDstAddress_appid(self); addr.appId = ClientGooseControlBlock_getDstAddress_appid(self);
addr.vlanId = ClientGooseControlBlock_getDstAddress_vid(self); addr.vlanId = ClientGooseControlBlock_getDstAddress_vid(self);
addr.vlanPriority = ClientGooseControlBlock_getDstAddress_priority(self); addr.vlanPriority = ClientGooseControlBlock_getDstAddress_priority(self);
return addr; return addr;
} }
public void SetDstAddress(PhyComAddress value) public void SetDstAddress(PhyComAddress value)
{ {
ClientGooseControlBlock_setDstAddress (self, value); ClientGooseControlBlock_setDstAddress(self, value);
flagDstAddress = true; flagDstAddress = true;
} }
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
isDisposed = true; {
ClientGooseControlBlock_destroy (self); isDisposed = true;
self = IntPtr.Zero; ClientGooseControlBlock_destroy(self);
} self = IntPtr.Zero;
} }
}
~GooseControlBlock() ~GooseControlBlock()
{ {
Dispose (); Dispose();
} }
} }
} }
} }

@ -1,7 +1,7 @@
/* /*
* GooseSubscriber.cs * GooseSubscriber.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,345 +21,351 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace GOOSE namespace GOOSE
{ {
namespace Subscriber namespace Subscriber
{ {
/// <summary> /// <summary>
/// GOOSE listener. /// GOOSE listener.
/// </summary> /// </summary>
public delegate void GooseListener (GooseSubscriber report, object parameter); public delegate void GooseListener(GooseSubscriber report, object parameter);
public class GooseReceiver : IDisposable public class GooseReceiver : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseReceiver_create (); private static extern IntPtr GooseReceiver_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_addSubscriber(IntPtr self, IntPtr subscriber); private static extern void GooseReceiver_addSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_removeSubscriber(IntPtr self, IntPtr subscriber); private static extern void GooseReceiver_removeSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_start(IntPtr self); private static extern void GooseReceiver_start(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_stop(IntPtr self); private static extern void GooseReceiver_stop(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseReceiver_isRunning (IntPtr self); private static extern bool GooseReceiver_isRunning(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_destroy(IntPtr self); private static extern void GooseReceiver_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_setInterfaceId(IntPtr self, string interfaceId); private static extern void GooseReceiver_setInterfaceId(IntPtr self, string interfaceId);
private IntPtr self; private IntPtr self;
private bool isDisposed = false; private bool isDisposed = false;
private List<GooseSubscriber> subscribers = new List<GooseSubscriber>(); private List<GooseSubscriber> subscribers = new List<GooseSubscriber>();
public GooseReceiver() public GooseReceiver()
{ {
self = GooseReceiver_create (); self = GooseReceiver_create();
} }
public void SetInterfaceId(string interfaceId) public void SetInterfaceId(string interfaceId)
{ {
GooseReceiver_setInterfaceId (self, interfaceId); GooseReceiver_setInterfaceId(self, interfaceId);
} }
/// <summary> /// <summary>
/// Add the subscriber to be handled by this receiver instance /// Add the subscriber to be handled by this receiver instance
/// </summary> /// </summary>
/// <remarks>A GooseSubscriber can only be added to one GooseReceiver!</remarks> /// <remarks>A GooseSubscriber can only be added to one GooseReceiver!</remarks>
/// <param name="subscriber"></param> /// <param name="subscriber"></param>
public void AddSubscriber(GooseSubscriber subscriber) public void AddSubscriber(GooseSubscriber subscriber)
{ {
if (subscriber.attachedToReceiver == false) if (subscriber.attachedToReceiver == false)
{ {
subscriber.attachedToReceiver = true; subscriber.attachedToReceiver = true;
GooseReceiver_addSubscriber(self, subscriber.self); GooseReceiver_addSubscriber(self, subscriber.self);
subscribers.Add(subscriber); subscribers.Add(subscriber);
} }
} }
public void RemoveSubscriber(GooseSubscriber subscriber) public void RemoveSubscriber(GooseSubscriber subscriber)
{ {
if (subscriber.attachedToReceiver) if (subscriber.attachedToReceiver)
{ {
GooseReceiver_removeSubscriber(self, subscriber.self); GooseReceiver_removeSubscriber(self, subscriber.self);
subscribers.Remove(subscriber); subscribers.Remove(subscriber);
subscriber.attachedToReceiver = false; subscriber.attachedToReceiver = false;
} }
} }
public void Start()
{
GooseReceiver_start(self);
}
public void Stop()
{
GooseReceiver_stop(self);
}
public bool IsRunning()
{
return GooseReceiver_isRunning(self);
}
public void Dispose()
{
if (isDisposed == false)
{
isDisposed = true;
GooseReceiver_destroy(self);
self = IntPtr.Zero;
}
}
~GooseReceiver()
{
Dispose();
}
}
/// <summary>
/// Representing a GOOSE subscriber
/// </summary>
/// <description>
/// NOTE: After SetListener is called, do not call any function outside of
/// the callback handler!
/// </description>
public class GooseSubscriber : IDisposable
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalGooseListener(IntPtr subscriber, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_create(string goCbRef, IntPtr dataSetValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setAppId(IntPtr self, UInt16 appId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isValid(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getStNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getSqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isTest(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_needsCommission(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getTimeAllowedToLive(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 GooseSubscriber_getTimestamp(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSetValues(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setListener(IntPtr self, InternalGooseListener listener, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoCbRef(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSet(IntPtr self);
internal IntPtr self;
private bool isDisposed = false;
public void Start() // don't call native destructor when attached to a receiver
{ internal bool attachedToReceiver = false;
GooseReceiver_start (self);
}
public void Stop() private GooseListener listener = null;
{ private object listenerParameter = null;
GooseReceiver_stop (self);
}
public bool IsRunning() private event InternalGooseListener internalListener = null;
{
return GooseReceiver_isRunning (self);
}
public void Dispose() private void internalGooseListener(IntPtr subscriber, IntPtr parameter)
{ {
if (isDisposed == false) { try
isDisposed = true; {
GooseReceiver_destroy (self);
self = IntPtr.Zero;
}
}
~GooseReceiver() if (listener != null)
{ {
Dispose (); listener(this, listenerParameter);
} }
}
/// <summary>
/// Representing a GOOSE subscriber
/// </summary>
/// <description>
/// NOTE: After SetListener is called, do not call any function outside of
/// the callback handler!
/// </description>
public class GooseSubscriber : IDisposable
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalGooseListener (IntPtr subscriber, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_create (string goCbRef, IntPtr dataSetValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setAppId(IntPtr self, UInt16 appId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isValid (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getStNum (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getSqNum (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isTest (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getConfRev (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_needsCommission (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getTimeAllowedToLive (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 GooseSubscriber_getTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSetValues(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setListener (IntPtr self, InternalGooseListener listener, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoCbRef(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSet(IntPtr self);
internal IntPtr self;
private bool isDisposed = false;
// don't call native destructor when attached to a receiver
internal bool attachedToReceiver = false;
private GooseListener listener = null;
private object listenerParameter = null;
private event InternalGooseListener internalListener = null; }
catch (Exception e)
private void internalGooseListener (IntPtr subscriber, IntPtr parameter) {
{ // older versions of mono 2.10 (for linux?) cause this exception
try { Console.WriteLine(e.Message);
}
if (listener != null) { }
listener(this, listenerParameter);
} public GooseSubscriber(string goCbRef)
{
} catch (Exception e) self = GooseSubscriber_create(goCbRef, IntPtr.Zero);
{ }
// older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message); public void SetAppId(UInt16 appId)
} {
} GooseSubscriber_setAppId(self, appId);
}
public GooseSubscriber(string goCbRef)
{ public bool IsValid()
self = GooseSubscriber_create (goCbRef, IntPtr.Zero); {
} return GooseSubscriber_isValid(self);
}
public void SetAppId(UInt16 appId)
{ public void SetListener(GooseListener listener, object parameter)
GooseSubscriber_setAppId (self, appId); {
} this.listener = listener;
listenerParameter = parameter;
public bool IsValid ()
{ if (internalListener == null)
return GooseSubscriber_isValid (self); {
} internalListener = new InternalGooseListener(internalGooseListener);
public void SetListener(GooseListener listener, object parameter) GooseSubscriber_setListener(self, internalListener, IntPtr.Zero);
{ }
this.listener = listener; }
this.listenerParameter = parameter;
public string GetGoId()
if (internalListener == null) { {
internalListener = new InternalGooseListener (internalGooseListener); return Marshal.PtrToStringAnsi(GooseSubscriber_getGoId(self));
}
GooseSubscriber_setListener (self, internalListener, IntPtr.Zero);
} public string GetGoCbRef()
} {
return Marshal.PtrToStringAnsi(GooseSubscriber_getGoCbRef(self));
public string GetGoId() }
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getGoId(self)); public string GetDataSet()
} {
return Marshal.PtrToStringAnsi(GooseSubscriber_getDataSet(self));
public string GetGoCbRef() }
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getGoCbRef(self)); public UInt32 GetStNum()
} {
return GooseSubscriber_getStNum(self);
public string GetDataSet() }
{
return Marshal.PtrToStringAnsi(GooseSubscriber_getDataSet(self)); public UInt32 GetSqNum()
} {
return GooseSubscriber_getSqNum(self);
public UInt32 GetStNum() }
{
return GooseSubscriber_getStNum (self); public bool IsTest()
} {
return GooseSubscriber_isTest(self);
public UInt32 GetSqNum() }
{
return GooseSubscriber_getSqNum (self); public UInt32 GetConfRev()
} {
return GooseSubscriber_getConfRev(self);
public bool IsTest() }
{
return GooseSubscriber_isTest (self); public bool NeedsCommission()
} {
return GooseSubscriber_needsCommission(self);
public UInt32 GetConfRev() }
{
return GooseSubscriber_getConfRev (self); public UInt32 GetTimeAllowedToLive()
} {
return GooseSubscriber_getTimeAllowedToLive(self);
public bool NeedsCommission() }
{
return GooseSubscriber_needsCommission (self); public UInt64 GetTimestamp()
} {
return GooseSubscriber_getTimestamp(self);
public UInt32 GetTimeAllowedToLive() }
{
return GooseSubscriber_getTimeAllowedToLive (self); public DateTimeOffset GetTimestampsDateTimeOffset()
} {
UInt64 entryTime = GetTimestamp();
public UInt64 GetTimestamp ()
{ DateTimeOffset retVal = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return GooseSubscriber_getTimestamp (self);
} return retVal.AddMilliseconds(entryTime);
}
public DateTimeOffset GetTimestampsDateTimeOffset ()
{ /// <summary>
UInt64 entryTime = GetTimestamp (); /// Get the values of the GOOSE data set from the last received GOOSE message
/// </summary>
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero); /// <remarks>
/// The MmsValue instance is only valid in the context of the GooseLister callback.
return retVal.AddMilliseconds (entryTime); /// Do not store for outside use!
} /// </remarks>
/// <returns>The data set values.</returns>
/// <summary> public MmsValue GetDataSetValues()
/// Get the values of the GOOSE data set from the last received GOOSE message {
/// </summary> IntPtr mmsValueRef = GooseSubscriber_getDataSetValues(self);
/// <remarks>
/// The MmsValue instance is only valid in the context of the GooseLister callback. return (new MmsValue(mmsValueRef));
/// Do not store for outside use! }
/// </remarks>
/// <returns>The data set values.</returns> /// <summary>
public MmsValue GetDataSetValues() /// Releases all resource used by the <see cref="IEC61850.GOOSE.Subscriber.GooseSubscriber"/> object.
{ /// </summary>
IntPtr mmsValueRef = GooseSubscriber_getDataSetValues (self); /// <remarks>>
/// This function has only to be called when the <see cref="IEC61850.GOOSE.Subscriber.GooseSubscriber"/>
return (new MmsValue (mmsValueRef)); /// has not been added to the GooseReceiver or has been removed from the GooseReceiver.
} /// When the GooseReceiver holds a reference it will take care for releasing the resources.
/// In this case Dispose MUST not be called! Otherwise the natice resources will be
/// <summary> /// released twice.
/// Releases all resource used by the <see cref="IEC61850.GOOSE.Subscriber.GooseSubscriber"/> object. /// </remarks>
/// </summary> public void Dispose()
/// <remarks>> {
/// This function has only to be called when the <see cref="IEC61850.GOOSE.Subscriber.GooseSubscriber"/> if (isDisposed == false)
/// has not been added to the GooseReceiver or has been removed from the GooseReceiver. {
/// When the GooseReceiver holds a reference it will take care for releasing the resources. isDisposed = true;
/// In this case Dispose MUST not be called! Otherwise the natice resources will be
/// released twice. if (attachedToReceiver == false)
/// </remarks> GooseSubscriber_destroy(self);
public void Dispose()
{ self = IntPtr.Zero;
if (isDisposed == false) { }
isDisposed = true; }
if (attachedToReceiver == false) ~GooseSubscriber()
GooseSubscriber_destroy (self); {
Dispose();
self = IntPtr.Zero; }
}
}
~GooseSubscriber()
{
Dispose();
}
} }
} }
} }
} }

@ -1,7 +1,7 @@
/* /*
* IEC61850ClientAPI.cs * IEC61850ClientAPI.cs
* *
* Copyright 2014-2023 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,14 +20,11 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections;
using IEC61850.Common; using IEC61850.Common;
using IEC61850.TLS; using IEC61850.TLS;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
// IEC 61850 API for the libiec61850 .NET wrapper library // IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850 namespace IEC61850
@ -62,11 +59,11 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void MmsServerIdentity_destroy(IntPtr self); private static extern void MmsServerIdentity_destroy(IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void MmsConnection_setLocalDetail (IntPtr self, Int32 localDetail); private static extern void MmsConnection_setLocalDetail(IntPtr self, Int32 localDetail);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 MmsConnection_getLocalDetail (IntPtr self); private static extern Int32 MmsConnection_getLocalDetail(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 MmsConnection_setRequestTimeout(IntPtr self, UInt32 timeoutInMs); private static extern Int32 MmsConnection_setRequestTimeout(IntPtr self, UInt32 timeoutInMs);
@ -106,11 +103,11 @@ namespace IEC61850
self = mmsConnection; self = mmsConnection;
} }
~MmsConnection () ~MmsConnection()
{ {
if (selfDestroy) if (selfDestroy)
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
MmsConnection_destroy(self); MmsConnection_destroy(self);
} }
private void FreeHGlobaleDeleteFunction(IntPtr pointer) private void FreeHGlobaleDeleteFunction(IntPtr pointer)
@ -140,7 +137,7 @@ namespace IEC61850
throw new IedConnectionException("Failed to read server identity"); throw new IedConnectionException("Failed to read server identity");
MmsServerIdentity serverIdentity = (MmsServerIdentity) MmsServerIdentity serverIdentity = (MmsServerIdentity)
Marshal.PtrToStructure(identity, typeof(MmsServerIdentity)); Marshal.PtrToStructure(identity, typeof(MmsServerIdentity));
MmsServerIdentity_destroy(identity); MmsServerIdentity_destroy(identity);
@ -343,7 +340,7 @@ namespace IEC61850
} }
} }
~MmsJournalEntry () ~MmsJournalEntry()
{ {
Dispose(); Dispose();
} }
@ -356,7 +353,7 @@ namespace IEC61850
/// <param name="parameter">user provided callback parameter</param> /// <param name="parameter">user provided callback parameter</param>
/// <param name="err">Error code of response or timeout error in case of a response timeout</param> /// <param name="err">Error code of response or timeout error in case of a response timeout</param>
/// <param name="rcb">the report control block instance</param> /// <param name="rcb">the report control block instance</param>
public delegate void GetRCBValuesHandler(UInt32 invokeId,object parameter,IedClientError err,ReportControlBlock rcb); public delegate void GetRCBValuesHandler(UInt32 invokeId, object parameter, IedClientError err, ReportControlBlock rcb);
/// <summary> /// <summary>
/// Asynchonous service handler for the set RCB values service /// Asynchonous service handler for the set RCB values service
@ -365,7 +362,7 @@ namespace IEC61850
/// <param name="parameter">user provided callback parameter</param> /// <param name="parameter">user provided callback parameter</param>
/// <param name="err">Error code of response or timeout error in case of a response timeout</param> /// <param name="err">Error code of response or timeout error in case of a response timeout</param>
/// <param name="rcb">the report control block instance</param> /// <param name="rcb">the report control block instance</param>
public delegate void SetRCBValuesHandler(UInt32 invokeId,object parameter,IedClientError err,ReportControlBlock rcb); public delegate void SetRCBValuesHandler(UInt32 invokeId, object parameter, IedClientError err, ReportControlBlock rcb);
/// <summary> /// <summary>
/// Generic asynchonous service handler - used by simple services that have only success or error result /// Generic asynchonous service handler - used by simple services that have only success or error result
@ -373,7 +370,7 @@ namespace IEC61850
/// <param name="invokeId">The invoke ID of the request triggering this callback</param> /// <param name="invokeId">The invoke ID of the request triggering this callback</param>
/// <param name="parameter">user provided callback parameter</param> /// <param name="parameter">user provided callback parameter</param>
/// <param name="err">Error code of response or timeout error in case of a response timeout</param> /// <param name="err">Error code of response or timeout error in case of a response timeout</param>
public delegate void GenericServiceHandler(UInt32 invokeId,object parameter,IedClientError err); public delegate void GenericServiceHandler(UInt32 invokeId, object parameter, IedClientError err);
/// <summary> /// <summary>
/// This class acts as the entry point for the IEC 61850 client API. It represents a single /// This class acts as the entry point for the IEC 61850 client API. It represents a single
@ -483,7 +480,7 @@ namespace IEC61850
static extern IntPtr IedConnection_getVariableSpecification(IntPtr self, out int error, string objectReference, int fc); static extern IntPtr IedConnection_getVariableSpecification(IntPtr self, out int error, string objectReference, int fc);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalConnectionClosedHandler(IntPtr parameter,IntPtr Iedconnection); private delegate void InternalConnectionClosedHandler(IntPtr parameter, IntPtr Iedconnection);
/// <summary> /// <summary>
/// Called when the connection is closed /// Called when the connection is closed
@ -552,7 +549,7 @@ namespace IEC61850
static extern int IedConnection_getState(IntPtr connection); static extern int IedConnection_getState(IntPtr connection);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalStateChangedHandler(IntPtr parameter,IntPtr iedConnection,int newState); private delegate void InternalStateChangedHandler(IntPtr parameter, IntPtr iedConnection, int newState);
/// <summary> /// <summary>
/// Called when there is a change in the connection state /// Called when there is a change in the connection state
@ -582,7 +579,7 @@ namespace IEC61850
private static extern void IedConnection_releaseAsync(IntPtr self, out int error); private static extern void IedConnection_releaseAsync(IntPtr self, out int error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_ReadObjectHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr value); private delegate void IedConnection_ReadObjectHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -590,7 +587,7 @@ namespace IEC61850
IedConnection_ReadObjectHandler handler, IntPtr parameter); IedConnection_ReadObjectHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_WriteObjectHandler(UInt32 invokeId,IntPtr parameter,int err); private delegate void IedConnection_WriteObjectHandler(UInt32 invokeId, IntPtr parameter, int err);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -598,7 +595,7 @@ namespace IEC61850
IntPtr value, IedConnection_WriteObjectHandler handler, IntPtr parameter); IntPtr value, IedConnection_WriteObjectHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_GetNameListHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr nameList,[MarshalAs(UnmanagedType.I1)] bool moreFollows); private delegate void IedConnection_GetNameListHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -616,7 +613,7 @@ namespace IEC61850
IedConnection_GetNameListHandler handler, IntPtr parameter); IedConnection_GetNameListHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_QueryLogHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr journalEntries,[MarshalAs(UnmanagedType.I1)] bool moreFollows); private delegate void IedConnection_QueryLogHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -629,7 +626,7 @@ namespace IEC61850
IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter); IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_GetVariableSpecificationHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr spec); private delegate void IedConnection_GetVariableSpecificationHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr spec);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -663,7 +660,7 @@ namespace IEC61850
IedConnection_GetDataSetDirectoryHandler handler, IntPtr parameter); IedConnection_GetDataSetDirectoryHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_GetRCBValuesHandler(UInt32 invokeId,IntPtr parameter,int err,IntPtr rcb); private delegate void IedConnection_GetRCBValuesHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr rcb);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -671,7 +668,7 @@ namespace IEC61850
IedConnection_GetRCBValuesHandler handler, IntPtr parameter); IedConnection_GetRCBValuesHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_GenericServiceHandler(UInt32 invokeId,IntPtr parameter,int err); private delegate void IedConnection_GenericServiceHandler(UInt32 invokeId, IntPtr parameter, int err);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
@ -680,7 +677,7 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 static extern UInt32
IedConnection_deleteFileAsync(IntPtr self, out int error, string fileName, IedConnection_deleteFileAsync(IntPtr self, out int error, string fileName,
IedConnection_GenericServiceHandler handler, IntPtr parameter); IedConnection_GenericServiceHandler handler, IntPtr parameter);
@ -706,7 +703,7 @@ namespace IEC61850
static extern void LinkedList_destroyStatic(IntPtr self); static extern void LinkedList_destroyStatic(IntPtr self);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void LinkedListValueDeleteFunction(IntPtr pointer); private delegate void LinkedListValueDeleteFunction(IntPtr pointer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction); static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction);
@ -759,7 +756,7 @@ namespace IEC61850
} }
} }
~IedConnection () ~IedConnection()
{ {
Dispose(); Dispose();
} }
@ -1632,7 +1629,7 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private delegate bool InternalIedClientGetFileHandler(IntPtr parameter,IntPtr buffer,UInt32 bytesRead); private delegate bool InternalIedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead);
private bool iedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead) private bool iedClientGetFileHandler(IntPtr parameter, IntPtr buffer, UInt32 bytesRead)
{ {
@ -1658,7 +1655,7 @@ namespace IEC61850
static extern void IedConnection_setFilestoreBasepath(IntPtr self, string fileName); static extern void IedConnection_setFilestoreBasepath(IntPtr self, string fileName);
public delegate bool GetFileHandler(object parameter,byte[] data); public delegate bool GetFileHandler(object parameter, byte[] data);
private class GetFileCallback private class GetFileCallback
{ {
@ -1720,7 +1717,7 @@ namespace IEC61850
{ {
int error; int error;
IedConnection_setFile(connection, out error, sourceFilename, destinationFilename); IedConnection_setFile(connection, out error, sourceFilename, destinationFilename);
if (error != 0) if (error != 0)
throw new IedConnectionException("Error uploading file", error); throw new IedConnectionException("Error uploading file", error);
@ -1771,7 +1768,7 @@ namespace IEC61850
Marshal.Copy(buffer, bytes, 0, (int)bytesRead); Marshal.Copy(buffer, bytes, 0, (int)bytesRead);
} }
bool retVal = handler(invokeId, handlerParameter, clientError, originalInvokeId, bytes, moreFollows); bool retVal = handler(invokeId, handlerParameter, clientError, originalInvokeId, bytes, moreFollows);
if (clientError != IedClientError.IED_ERROR_OK) if (clientError != IedClientError.IED_ERROR_OK)
{ {
@ -2338,7 +2335,7 @@ namespace IEC61850
/// <param name="parameter">user provided callback parameter</param> /// <param name="parameter">user provided callback parameter</param>
/// <param name="err">Error code of response or timeout error in case of a response timeout</param> /// <param name="err">Error code of response or timeout error in case of a response timeout</param>
/// <param name="value">The read result value or null in case of an error</param> /// <param name="value">The read result value or null in case of an error</param>
public delegate void ReadValueHandler(UInt32 invokeId,object parameter,IedClientError err,MmsValue value); public delegate void ReadValueHandler(UInt32 invokeId, object parameter, IedClientError err, MmsValue value);
private IedConnection_ReadObjectHandler internalReadObjectHandler = null; private IedConnection_ReadObjectHandler internalReadObjectHandler = null;
@ -2417,7 +2414,7 @@ namespace IEC61850
handler(invokeId, handlerParameter, clientError, varSpec); handler(invokeId, handlerParameter, clientError, varSpec);
} }
public delegate void GetVariableSpecifcationHandler(UInt32 invokeId,object parameter,IedClientError err,MmsVariableSpecification spec); public delegate void GetVariableSpecifcationHandler(UInt32 invokeId, object parameter, IedClientError err, MmsVariableSpecification spec);
/// <summary>Read the variable specification (type description of a DA or FCDO</summary> /// <summary>Read the variable specification (type description of a DA or FCDO</summary>
/// <param name="objectReference">The object reference of a DA or FCDO.</param> /// <param name="objectReference">The object reference of a DA or FCDO.</param>
@ -2473,7 +2470,7 @@ namespace IEC61850
handler(invokeId, handlerParameter, clientError, dataSet); handler(invokeId, handlerParameter, clientError, dataSet);
} }
public delegate void ReadDataSetHandler(UInt32 invokeId,object parameter,IedClientError err,DataSet dataSet); public delegate void ReadDataSetHandler(UInt32 invokeId, object parameter, IedClientError err, DataSet dataSet);
/// <summary> /// <summary>
/// Read the values of a data set (GetDataSetValues service) - asynchronous version /// Read the values of a data set (GetDataSetValues service) - asynchronous version
@ -2521,7 +2518,7 @@ namespace IEC61850
/// <param name="invokeId">The invoke ID of the reqeust triggering this callback</param> /// <param name="invokeId">The invoke ID of the reqeust triggering this callback</param>
/// <param name="parameter">user provided callback parameter</param> /// <param name="parameter">user provided callback parameter</param>
/// <param name="err">Error code of response or timeout error in case of a response timeout</param> /// <param name="err">Error code of response or timeout error in case of a response timeout</param>
public delegate void WriteValueHandler(UInt32 invokeId,object parameter,IedClientError err); public delegate void WriteValueHandler(UInt32 invokeId, object parameter, IedClientError err);
private IedConnection_WriteObjectHandler internalWriteObjectHandler = null; private IedConnection_WriteObjectHandler internalWriteObjectHandler = null;
@ -2563,11 +2560,11 @@ namespace IEC61850
return invokeId; return invokeId;
} }
public delegate void GetNameListHandler(UInt32 invokeId,object parameter,IedClientError err,List<string> nameList,bool moreFollows); public delegate void GetNameListHandler(UInt32 invokeId, object parameter, IedClientError err, List<string> nameList, bool moreFollows);
private IedConnection_GetNameListHandler internalGetNameListHandler = null; private IedConnection_GetNameListHandler internalGetNameListHandler = null;
private void nativeGetNameListHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows) private void nativeGetNameListHandler(UInt32 invokeId, IntPtr parameter, int err, IntPtr nameList, [MarshalAs(UnmanagedType.I1)] bool moreFollows)
{ {
GCHandle handle = GCHandle.FromIntPtr(parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
@ -2692,7 +2689,7 @@ namespace IEC61850
return invokeId; return invokeId;
} }
public delegate void QueryLogHandler(UInt32 invokeId,object parameter,IedClientError err,List<MmsJournalEntry> journalEntries,bool moreFollows); public delegate void QueryLogHandler(UInt32 invokeId, object parameter, IedClientError err, List<MmsJournalEntry> journalEntries, bool moreFollows);
private IedConnection_QueryLogHandler internalQueryLogHandler = null; private IedConnection_QueryLogHandler internalQueryLogHandler = null;
@ -2936,17 +2933,17 @@ namespace IEC61850
public IedConnectionException(string message) public IedConnectionException(string message)
: base(message) : base(message)
{ {
this.errorCode = 0; errorCode = 0;
} }
public int GetErrorCode() public int GetErrorCode()
{ {
return this.errorCode; return errorCode;
} }
public IedClientError GetIedClientError() public IedClientError GetIedClientError()
{ {
return (IedClientError)this.errorCode; return (IedClientError)errorCode;
} }
} }

File diff suppressed because it is too large Load Diff

@ -22,9 +22,7 @@
*/ */
using IEC61850.Server; using IEC61850.Server;
using System; using System;
using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library // IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850 namespace IEC61850
@ -45,7 +43,7 @@ namespace IEC61850
internal IntPtr Self { get => self; } internal IntPtr Self { get => self; }
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr SVControlBlock_create(string name, IntPtr parent, string svID,string dataSet, UInt32 confRev, uint smpMod, static extern IntPtr SVControlBlock_create(string name, IntPtr parent, string svID, string dataSet, UInt32 confRev, uint smpMod,
UInt16 smpRate, uint optFlds, bool isUnicast); UInt16 smpRate, uint optFlds, bool isUnicast);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -67,7 +65,7 @@ namespace IEC61850
public SVControlBlock(string name, IedModel parent, string svID, string dataSet, UInt32 confRev, uint smpMod, public SVControlBlock(string name, IedModel parent, string svID, string dataSet, UInt32 confRev, uint smpMod,
UInt16 smpRate, uint optFlds, bool isUnicast) UInt16 smpRate, uint optFlds, bool isUnicast)
{ {
this.self = SVControlBlock_create(name, parent.self, svID, dataSet, confRev, smpMod, smpRate, optFlds, isUnicast); self = SVControlBlock_create(name, parent.self, svID, dataSet, confRev, smpMod, smpRate, optFlds, isUnicast);
this.parent = parent; this.parent = parent;
} }

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
/* /*
* IedServerConfig.cs * IedServerConfig.cs
* *
* Copyright 2018 Michael Zillgith * Copyright 2018-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,9 +21,9 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850.Server namespace IEC61850.Server
{ {

@ -1,7 +1,7 @@
/* /*
* IsoConnectionParameters.cs * IsoConnectionParameters.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -26,38 +26,39 @@ using System.Runtime.InteropServices;
namespace IEC61850 namespace IEC61850
{ {
namespace Client namespace Client
{ {
public enum AcseAuthenticationMechanism { public enum AcseAuthenticationMechanism
{
/** don't use authentication */ /** don't use authentication */
ACSE_AUTH_NONE = 0, ACSE_AUTH_NONE = 0,
/** use password authentication */ /** use password authentication */
ACSE_AUTH_PASSWORD = 1 ACSE_AUTH_PASSWORD = 1
} }
/// <summary> /// <summary>
/// Connection parameters associated with the ISO protocol layers (transport, session, presentation, ACSE) /// Connection parameters associated with the ISO protocol layers (transport, session, presentation, ACSE)
/// </summary> /// </summary>
public class IsoConnectionParameters public class IsoConnectionParameters
{ {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct NativeTSelector private struct NativeTSelector
{ {
public byte size; public byte size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] public byte[] value; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] value;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct NativeSSelector private struct NativeSSelector
{ {
public byte size; public byte size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public byte[] value; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] value;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct NativePSelector private struct NativePSelector
@ -68,49 +69,49 @@ namespace IEC61850
} }
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_destroy(IntPtr self); private static extern void IsoConnectionParameters_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setRemoteApTitle(IntPtr self, string apTitle, int aeQualifier); private static extern void IsoConnectionParameters_setRemoteApTitle(IntPtr self, string apTitle, int aeQualifier);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setRemoteAddresses(IntPtr self, NativePSelector pSelector, NativeSSelector sSelector, NativeTSelector tSelector); private static extern void IsoConnectionParameters_setRemoteAddresses(IntPtr self, NativePSelector pSelector, NativeSSelector sSelector, NativeTSelector tSelector);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setLocalApTitle(IntPtr self, string apTitle, int aeQualifier); private static extern void IsoConnectionParameters_setLocalApTitle(IntPtr self, string apTitle, int aeQualifier);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setLocalAddresses(IntPtr self, NativePSelector pSelector, NativeSSelector sSelector, NativeTSelector tSelector); private static extern void IsoConnectionParameters_setLocalAddresses(IntPtr self, NativePSelector pSelector, NativeSSelector sSelector, NativeTSelector tSelector);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void IsoConnectionParameters_setAcseAuthenticationParameter(IntPtr self, IntPtr acseAuthParameter); private static extern void IsoConnectionParameters_setAcseAuthenticationParameter(IntPtr self, IntPtr acseAuthParameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr AcseAuthenticationParameter_create(); private static extern IntPtr AcseAuthenticationParameter_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_destroy(IntPtr self); private static extern void AcseAuthenticationParameter_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism); private static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password); private static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password);
private IntPtr self; private IntPtr self;
private IntPtr authParameter = IntPtr.Zero; private IntPtr authParameter = IntPtr.Zero;
internal IsoConnectionParameters (IntPtr self) internal IsoConnectionParameters(IntPtr self)
{ {
this.self = self; this.self = self;
} }
~IsoConnectionParameters () ~IsoConnectionParameters()
{ {
if (authParameter != IntPtr.Zero) if (authParameter != IntPtr.Zero)
AcseAuthenticationParameter_destroy(authParameter); AcseAuthenticationParameter_destroy(authParameter);
} }
/// <summary> /// <summary>
/// Sets the remote ap title related parameters /// Sets the remote ap title related parameters
@ -122,9 +123,9 @@ namespace IEC61850
/// remote AE qualifier. /// remote AE qualifier.
/// </param> /// </param>
public void SetRemoteApTitle(string apTitle, int aeQualifier) public void SetRemoteApTitle(string apTitle, int aeQualifier)
{ {
IsoConnectionParameters_setRemoteApTitle(self, apTitle, aeQualifier); IsoConnectionParameters_setRemoteApTitle(self, apTitle, aeQualifier);
} }
/// <summary> /// <summary>
/// Sets the remote addresses for ISO layers (transport, session, presentation) /// Sets the remote addresses for ISO layers (transport, session, presentation)
@ -138,27 +139,27 @@ namespace IEC61850
/// <param name='tSelector'> /// <param name='tSelector'>
/// ISO COTP transport layer address /// ISO COTP transport layer address
/// </param> /// </param>
public void SetRemoteAddresses (byte[] pSelector, byte[] sSelector, byte[] tSelector) public void SetRemoteAddresses(byte[] pSelector, byte[] sSelector, byte[] tSelector)
{ {
if (tSelector.Length > 4) if (tSelector.Length > 4)
throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded"); throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded");
NativeTSelector nativeTSelector; NativeTSelector nativeTSelector;
nativeTSelector.size = (byte) tSelector.Length; nativeTSelector.size = (byte)tSelector.Length;
nativeTSelector.value = new byte[4]; nativeTSelector.value = new byte[4];
for (int i = 0; i < tSelector.Length; i++) for (int i = 0; i < tSelector.Length; i++)
nativeTSelector.value[i] = tSelector[i]; nativeTSelector.value[i] = tSelector[i];
if (sSelector.Length > 16) if (sSelector.Length > 16)
throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded");
NativeSSelector nativeSSelector; NativeSSelector nativeSSelector;
nativeSSelector.size = (byte) sSelector.Length; nativeSSelector.size = (byte)sSelector.Length;
nativeSSelector.value = new byte[16]; nativeSSelector.value = new byte[16];
for (int i = 0; i < sSelector.Length; i++) for (int i = 0; i < sSelector.Length; i++)
nativeSSelector.value [i] = sSelector [i]; nativeSSelector.value[i] = sSelector[i];
if (pSelector.Length > 16) if (pSelector.Length > 16)
throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded");
@ -171,7 +172,7 @@ namespace IEC61850
nativePSelector.value[i] = pSelector[i]; nativePSelector.value[i] = pSelector[i];
IsoConnectionParameters_setRemoteAddresses(self, nativePSelector, nativeSSelector, nativeTSelector); IsoConnectionParameters_setRemoteAddresses(self, nativePSelector, nativeSSelector, nativeTSelector);
} }
/// <summary> /// <summary>
/// Sets the local ap title related parameters /// Sets the local ap title related parameters
@ -182,10 +183,10 @@ namespace IEC61850
/// <param name='aeQualifier'> /// <param name='aeQualifier'>
/// local AE qualifier. /// local AE qualifier.
/// </param> /// </param>
public void SetLocalApTitle (string apTitle, int aeQualifier) public void SetLocalApTitle(string apTitle, int aeQualifier)
{ {
IsoConnectionParameters_setLocalApTitle(self, apTitle, aeQualifier); IsoConnectionParameters_setLocalApTitle(self, apTitle, aeQualifier);
} }
/// <summary> /// <summary>
/// Sets the local addresses for ISO layers (transport, session, presentation) /// Sets the local addresses for ISO layers (transport, session, presentation)
@ -199,27 +200,27 @@ namespace IEC61850
/// <param name='tSelector'> /// <param name='tSelector'>
/// ISO COTP transport layer address /// ISO COTP transport layer address
/// </param> /// </param>
public void SetLocalAddresses (byte[] pSelector, byte[] sSelector, byte[] tSelector) public void SetLocalAddresses(byte[] pSelector, byte[] sSelector, byte[] tSelector)
{ {
if (tSelector.Length > 4) if (tSelector.Length > 4)
throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded"); throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded");
NativeTSelector nativeTSelector; NativeTSelector nativeTSelector;
nativeTSelector.size = (byte) tSelector.Length; nativeTSelector.size = (byte)tSelector.Length;
nativeTSelector.value = new byte[4]; nativeTSelector.value = new byte[4];
for (int i = 0; i < tSelector.Length; i++) for (int i = 0; i < tSelector.Length; i++)
nativeTSelector.value[i] = tSelector[i]; nativeTSelector.value[i] = tSelector[i];
if (sSelector.Length > 16) if (sSelector.Length > 16)
throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded");
NativeSSelector nativeSSelector; NativeSSelector nativeSSelector;
nativeSSelector.size = (byte) sSelector.Length; nativeSSelector.size = (byte)sSelector.Length;
nativeSSelector.value = new byte[16]; nativeSSelector.value = new byte[16];
for (int i = 0; i < sSelector.Length; i++) for (int i = 0; i < sSelector.Length; i++)
nativeSSelector.value [i] = sSelector [i]; nativeSSelector.value[i] = sSelector[i];
if (pSelector.Length > 16) if (pSelector.Length > 16)
throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded");
@ -232,7 +233,7 @@ namespace IEC61850
nativePSelector.value[i] = pSelector[i]; nativePSelector.value[i] = pSelector[i];
IsoConnectionParameters_setLocalAddresses(self, nativePSelector, nativeSSelector, nativeTSelector); IsoConnectionParameters_setLocalAddresses(self, nativePSelector, nativeSSelector, nativeTSelector);
} }
/// <summary> /// <summary>
/// Instruct ACSE layer to use password authentication. /// Instruct ACSE layer to use password authentication.
@ -240,19 +241,20 @@ namespace IEC61850
/// <param name='password'> /// <param name='password'>
/// Password that will be used to authenticate the client /// Password that will be used to authenticate the client
/// </param> /// </param>
public void UsePasswordAuthentication (string password) public void UsePasswordAuthentication(string password)
{ {
if (authParameter == IntPtr.Zero) { if (authParameter == IntPtr.Zero)
authParameter = AcseAuthenticationParameter_create (); {
AcseAuthenticationParameter_setAuthMechanism (authParameter, (int)AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD); authParameter = AcseAuthenticationParameter_create();
AcseAuthenticationParameter_setPassword (authParameter, password); AcseAuthenticationParameter_setAuthMechanism(authParameter, (int)AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD);
IsoConnectionParameters_setAcseAuthenticationParameter(self, authParameter); AcseAuthenticationParameter_setPassword(authParameter, password);
} IsoConnectionParameters_setAcseAuthenticationParameter(self, authParameter);
else }
throw new IedConnectionException("Authentication parameter already set"); else
} throw new IedConnectionException("Authentication parameter already set");
} }
}
}
}
} }

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
/* /*
* MmsVariableSpecification.cs * MmsVariableSpecification.cs
* *
* Copyright 2014-2024 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,11 +21,9 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System; using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace IEC61850 namespace IEC61850
@ -73,7 +71,7 @@ namespace IEC61850
internal MmsVariableSpecification(IntPtr self, MmsVariableSpecification parent) internal MmsVariableSpecification(IntPtr self, MmsVariableSpecification parent)
{ {
this.self = self; this.self = self;
this.responsableForDeletion = false; responsableForDeletion = false;
this.parent = parent; this.parent = parent;
} }

@ -1,7 +1,7 @@
/* /*
* ReportControlBlock.cs * ReportControlBlock.cs
* *
* Copyright 2014-2018 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,26 +20,24 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace Client namespace Client
{ {
/// <summary> /// <summary>
/// Report handler. /// Report handler.
/// </summary> /// </summary>
/// <param name="report">represents the received report. DON'T use this object /// <param name="report">represents the received report. DON'T use this object
/// outside the scope of the report handler!</param> /// outside the scope of the report handler!</param>
public delegate void ReportHandler (Report report, object parameter); public delegate void ReportHandler(Report report, object parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void InternalReportHandler (IntPtr parameter, IntPtr report); internal delegate void InternalReportHandler(IntPtr parameter, IntPtr report);
/// <summary> /// <summary>
/// Report control block (RCB) representation. /// Report control block (RCB) representation.
@ -50,213 +48,218 @@ namespace IEC61850
/// Values at the server are only affected when the SetRCBValues method is called. /// Values at the server are only affected when the SetRCBValues method is called.
/// </description> /// </description>
public class ReportControlBlock : IDisposable public class ReportControlBlock : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_create (string dataAttributeReference); static extern IntPtr ClientReportControlBlock_create(string dataAttributeReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_destroy (IntPtr self); static extern void ClientReportControlBlock_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self); static extern bool ClientReportControlBlock_isBuffered(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getRptId (IntPtr self); static extern IntPtr ClientReportControlBlock_getRptId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId); static extern void ClientReportControlBlock_setRptId(IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self); static extern bool ClientReportControlBlock_getRptEna(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna); static extern void ClientReportControlBlock_setRptEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getResv (IntPtr self); static extern bool ClientReportControlBlock_getResv(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResv (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool resv); static extern void ClientReportControlBlock_setResv(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool resv);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getDataSetReference (IntPtr self); static extern IntPtr ClientReportControlBlock_getDataSetReference(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setDataSetReference (IntPtr self, string dataSetReference); static extern void ClientReportControlBlock_setDataSetReference(IntPtr self, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getConfRev (IntPtr self); static extern UInt32 ClientReportControlBlock_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getOptFlds (IntPtr self); static extern int ClientReportControlBlock_getOptFlds(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setOptFlds (IntPtr self, int optFlds); static extern void ClientReportControlBlock_setOptFlds(IntPtr self, int optFlds);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getBufTm (IntPtr self); static extern UInt32 ClientReportControlBlock_getBufTm(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setBufTm (IntPtr self, UInt32 bufTm); static extern void ClientReportControlBlock_setBufTm(IntPtr self, UInt32 bufTm);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReportControlBlock_getSqNum (IntPtr self); static extern UInt16 ClientReportControlBlock_getSqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getTrgOps (IntPtr self); static extern int ClientReportControlBlock_getTrgOps(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setTrgOps (IntPtr self, int trgOps); static extern void ClientReportControlBlock_setTrgOps(IntPtr self, int trgOps);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getIntgPd (IntPtr self); static extern UInt32 ClientReportControlBlock_getIntgPd(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd); static extern void ClientReportControlBlock_setIntgPd(IntPtr self, UInt32 intgPd);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getGI (IntPtr self); static extern bool ClientReportControlBlock_getGI(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool gi); static extern void ClientReportControlBlock_setGI(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool gi);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self); static extern bool ClientReportControlBlock_getPurgeBuf(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setPurgeBuf (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool purgeBuf); static extern void ClientReportControlBlock_setPurgeBuf(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool purgeBuf);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_hasResvTms(IntPtr self); static extern bool ClientReportControlBlock_hasResvTms(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int16 ClientReportControlBlock_getResvTms (IntPtr self); static extern Int16 ClientReportControlBlock_getResvTms(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResvTms (IntPtr self, Int16 resvTms); static extern void ClientReportControlBlock_setResvTms(IntPtr self, Int16 resvTms);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getEntryId (IntPtr self); static extern IntPtr ClientReportControlBlock_getEntryId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setEntryId (IntPtr self, IntPtr entryId); static extern void ClientReportControlBlock_setEntryId(IntPtr self, IntPtr entryId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 ClientReportControlBlock_getEntryTime (IntPtr self); static extern UInt64 ClientReportControlBlock_getEntryTime(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getOwner (IntPtr self); static extern IntPtr ClientReportControlBlock_getOwner(IntPtr self);
internal IntPtr self; internal IntPtr self;
private IedConnection iedConnection = null; private IedConnection iedConnection = null;
private string objectReference; private string objectReference;
private bool flagRptId = false; private bool flagRptId = false;
private bool flagRptEna = false; private bool flagRptEna = false;
private bool flagResv = false; private bool flagResv = false;
private bool flagDataSetReference = false; private bool flagDataSetReference = false;
private bool flagConfRev = false; private bool flagConfRev = false;
private bool flagOptFlds = false; private bool flagOptFlds = false;
private bool flagBufTm = false; private bool flagBufTm = false;
private bool flagSqNum = false; private bool flagSqNum = false;
private bool flagTrgOps = false; private bool flagTrgOps = false;
private bool flagIntgPd = false; private bool flagIntgPd = false;
private bool flagGI = false; private bool flagGI = false;
private bool flagPurgeBuf = false; private bool flagPurgeBuf = false;
private bool flagResvTms = false; private bool flagResvTms = false;
private bool flagEntryId = false; private bool flagEntryId = false;
private event ReportHandler reportHandler = null; private event ReportHandler reportHandler = null;
private object reportHandlerParameter; private object reportHandlerParameter;
private bool reportHandlerInstalled = false; private bool reportHandlerInstalled = false;
private event InternalReportHandler internalHandler = null; private event InternalReportHandler internalHandler = null;
private void resetSendFlags () private void resetSendFlags()
{ {
flagRptId = false; flagRptId = false;
flagRptEna = false; flagRptEna = false;
flagResv = false; flagResv = false;
flagDataSetReference = false; flagDataSetReference = false;
flagConfRev = false; flagConfRev = false;
flagOptFlds = false; flagOptFlds = false;
flagBufTm = false; flagBufTm = false;
flagSqNum = false; flagSqNum = false;
flagTrgOps = false; flagTrgOps = false;
flagIntgPd = false; flagIntgPd = false;
flagGI = false; flagGI = false;
flagPurgeBuf = false; flagPurgeBuf = false;
flagResvTms = false; flagResvTms = false;
flagEntryId = false; flagEntryId = false;
} }
private Report report = null; private Report report = null;
private void internalReportHandler (IntPtr parameter, IntPtr report) private void internalReportHandler(IntPtr parameter, IntPtr report)
{ {
try { try
{
if (this.report == null)
this.report = new Report (report); if (this.report == null)
this.report = new Report(report);
if (reportHandler != null)
reportHandler(this.report, reportHandlerParameter); if (reportHandler != null)
reportHandler(this.report, reportHandlerParameter);
} catch (Exception e)
{ }
// older versions of mono 2.10 (for linux?) cause this exception catch (Exception e)
Console.WriteLine(e.Message); {
} // older versions of mono 2.10 (for linux?) cause this exception
} Console.WriteLine(e.Message);
}
internal ReportControlBlock (string objectReference, IedConnection iedConnection, IntPtr connection) }
{
self = ClientReportControlBlock_create (objectReference); internal ReportControlBlock(string objectReference, IedConnection iedConnection, IntPtr connection)
{
if (self != IntPtr.Zero) { self = ClientReportControlBlock_create(objectReference);
this.iedConnection = iedConnection;
this.objectReference = objectReference; if (self != IntPtr.Zero)
} {
} this.iedConnection = iedConnection;
this.objectReference = objectReference;
/// <summary> }
/// Releases all resource used by the <see cref="IEC61850.Client.ReportControlBlock"/> object. }
/// </summary>
/// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="IEC61850.Client.ReportControlBlock"/>. The /// <summary>
/// <see cref="Dispose"/> method leaves the <see cref="IEC61850.Client.ReportControlBlock"/> in an unusable state. /// Releases all resource used by the <see cref="IEC61850.Client.ReportControlBlock"/> object.
/// After calling <see cref="Dispose"/>, you must release all references to the /// </summary>
/// <see cref="IEC61850.Client.ReportControlBlock"/> so the garbage collector can reclaim the memory that the /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="IEC61850.Client.ReportControlBlock"/>. The
/// <see cref="IEC61850.Client.ReportControlBlock"/> was occupying.</remarks> /// <see cref="Dispose"/> method leaves the <see cref="IEC61850.Client.ReportControlBlock"/> in an unusable state.
public void Dispose() /// After calling <see cref="Dispose"/>, you must release all references to the
{ /// <see cref="IEC61850.Client.ReportControlBlock"/> so the garbage collector can reclaim the memory that the
lock (this) { /// <see cref="IEC61850.Client.ReportControlBlock"/> was occupying.</remarks>
if (self != IntPtr.Zero) { public void Dispose()
{
iedConnection.UninstallReportHandler (objectReference); lock (this)
{
iedConnection.RemoveRCB (this); if (self != IntPtr.Zero)
{
ClientReportControlBlock_destroy (self);
iedConnection.UninstallReportHandler(objectReference);
self = IntPtr.Zero;
} iedConnection.RemoveRCB(this);
}
} ClientReportControlBlock_destroy(self);
~ReportControlBlock() self = IntPtr.Zero;
{ }
Dispose (); }
} }
public string GetObjectReference () ~ReportControlBlock()
{ {
return this.objectReference; Dispose();
} }
public string GetObjectReference()
{
return objectReference;
}
/// <summary> /// <summary>
/// Installs the report handler. /// Installs the report handler.
@ -272,40 +275,41 @@ namespace IEC61850
/// <param name='parameter'> /// <param name='parameter'>
/// parameter is passed to the handler when the handler is invoked. /// parameter is passed to the handler when the handler is invoked.
/// </param> /// </param>
public void InstallReportHandler (ReportHandler reportHandler, object parameter) public void InstallReportHandler(ReportHandler reportHandler, object parameter)
{ {
this.reportHandler = new ReportHandler(reportHandler); this.reportHandler = new ReportHandler(reportHandler);
this.reportHandlerParameter = parameter; reportHandlerParameter = parameter;
if (reportHandlerInstalled == false) { if (reportHandlerInstalled == false)
{
string reportId = this.GetRptId (); string reportId = GetRptId();
if (internalHandler == null) if (internalHandler == null)
{ {
internalHandler = new InternalReportHandler(internalReportHandler); internalHandler = new InternalReportHandler(internalReportHandler);
} }
iedConnection.InstallReportHandler (objectReference, reportId, internalHandler); iedConnection.InstallReportHandler(objectReference, reportId, internalHandler);
reportHandlerInstalled = true; reportHandlerInstalled = true;
} }
} }
/// <summary> /// <summary>
/// Read all RCB values from the server /// Read all RCB values from the server
/// </summary> /// </summary>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void GetRCBValues () public void GetRCBValues()
{ {
int error; int error;
iedConnection.GetRCBValues (out error, objectReference, self); iedConnection.GetRCBValues(out error, objectReference, self);
if (error != 0) if (error != 0)
throw new IedConnectionException ("getRCBValues service failed", error); throw new IedConnectionException("getRCBValues service failed", error);
} }
/// <summary> /// <summary>
/// Read all RCB values from the server - asynchronous version /// Read all RCB values from the server - asynchronous version
@ -327,10 +331,10 @@ namespace IEC61850
/// The RCB values are sent by a single MMS write request. /// The RCB values are sent by a single MMS write request.
/// </description> /// </description>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void SetRCBValues () public void SetRCBValues()
{ {
SetRCBValues (true); SetRCBValues(true);
} }
private UInt32 CreateParametersMask() private UInt32 CreateParametersMask()
{ {
@ -403,7 +407,7 @@ namespace IEC61850
/// <param name='singleRequest'> /// <param name='singleRequest'>
/// If true the values are sent by single MMS write request. Otherwise the values are all sent by their own MMS write requests. /// If true the values are sent by single MMS write request. Otherwise the values are all sent by their own MMS write requests.
/// </param> /// </param>
public void SetRCBValues (bool singleRequest) public void SetRCBValues(bool singleRequest)
{ {
UInt32 parametersMask = CreateParametersMask(); UInt32 parametersMask = CreateParametersMask();
@ -411,21 +415,23 @@ namespace IEC61850
int error; int error;
iedConnection.SetRCBValues (out error, self, parametersMask, singleRequest); iedConnection.SetRCBValues(out error, self, parametersMask, singleRequest);
resetSendFlags(); resetSendFlags();
if (error != 0) if (error != 0)
throw new IedConnectionException ("setRCBValues service failed", error); throw new IedConnectionException("setRCBValues service failed", error);
if (flagRptId) { if (flagRptId)
{
if (reportHandlerInstalled) { if (reportHandlerInstalled)
{
reportHandlerInstalled = false; reportHandlerInstalled = false;
InstallReportHandler(this.reportHandler, this.reportHandlerParameter); InstallReportHandler(reportHandler, reportHandlerParameter);
} }
} }
} }
/// <summary> /// <summary>
/// Determines whether this instance is a buffered or unbuffered RCB. /// Determines whether this instance is a buffered or unbuffered RCB.
@ -433,10 +439,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// <c>true</c> if this instance is a buffered RCB; otherwise, <c>false</c>. /// <c>true</c> if this instance is a buffered RCB; otherwise, <c>false</c>.
/// </returns> /// </returns>
public bool IsBuffered () public bool IsBuffered()
{ {
return ClientReportControlBlock_isBuffered (self); return ClientReportControlBlock_isBuffered(self);
} }
/// <summary> /// <summary>
/// Gets the entry time of the RCB as ms time /// Gets the entry time of the RCB as ms time
@ -447,10 +453,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// The entry time as ms timestamp /// The entry time as ms timestamp
/// </returns> /// </returns>
public UInt64 GetEntryTime () public UInt64 GetEntryTime()
{ {
return ClientReportControlBlock_getEntryTime (self); return ClientReportControlBlock_getEntryTime(self);
} }
/// <summary> /// <summary>
/// Gets the entry time of the RCB as DateTimeOffset /// Gets the entry time of the RCB as DateTimeOffset
@ -461,49 +467,50 @@ namespace IEC61850
/// <returns> /// <returns>
/// The entry time as DataTimeOffset /// The entry time as DataTimeOffset
/// </returns> /// </returns>
public DateTimeOffset GetEntryTimeAsDateTimeOffset () public DateTimeOffset GetEntryTimeAsDateTimeOffset()
{ {
UInt64 entryTime = GetEntryTime (); UInt64 entryTime = GetEntryTime();
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero); DateTimeOffset retVal = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (entryTime); return retVal.AddMilliseconds(entryTime);
} }
/// <summary> /// <summary>
/// Gets the entryID of RCB /// Gets the entryID of RCB
/// </summary> /// </summary>
/// Returns the EntryID of the last received GetRCBValues service response. /// Returns the EntryID of the last received GetRCBValues service response.
/// The EntryID is only present in buffered RCBs (BRCBs). /// The EntryID is only present in buffered RCBs (BRCBs).
/// ///
/// <returns>The entry ID</returns> /// <returns>The entry ID</returns>
public byte[] GetEntryID() public byte[] GetEntryID()
{ {
IntPtr entryIdRef = ClientReportControlBlock_getEntryId (self); IntPtr entryIdRef = ClientReportControlBlock_getEntryId(self);
if (entryIdRef == IntPtr.Zero) if (entryIdRef == IntPtr.Zero)
return null; return null;
else { else
MmsValue entryId = new MmsValue (entryIdRef); {
MmsValue entryId = new MmsValue(entryIdRef);
return entryId.getOctetString (); return entryId.getOctetString();
} }
} }
public void SetEntryID(byte[] entryId) public void SetEntryID(byte[] entryId)
{ {
flagEntryId = true; flagEntryId = true;
MmsValue entryID = MmsValue.NewOctetString (entryId.Length); MmsValue entryID = MmsValue.NewOctetString(entryId.Length);
entryID.setOctetString (entryId); entryID.setOctetString(entryId);
ClientReportControlBlock_setEntryId (self, entryID.valueReference); ClientReportControlBlock_setEntryId(self, entryID.valueReference);
} }
/// <summary> /// <summary>
@ -512,12 +519,12 @@ namespace IEC61850
/// <returns> /// <returns>
/// The data set reference. /// The data set reference.
/// </returns> /// </returns>
public string GetDataSetReference () public string GetDataSetReference()
{ {
IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference (self); IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference(self);
return Marshal.PtrToStringAnsi (dataSetRefPtr); return Marshal.PtrToStringAnsi(dataSetRefPtr);
} }
/// <summary> /// <summary>
/// Sets the data set reference. Use this method to select the associated data set for the RCB /// Sets the data set reference. Use this method to select the associated data set for the RCB
@ -525,12 +532,12 @@ namespace IEC61850
/// <returns> /// <returns>
/// The data set reference. /// The data set reference.
/// </returns> /// </returns>
public void SetDataSetReference (string dataSetReference) public void SetDataSetReference(string dataSetReference)
{ {
ClientReportControlBlock_setDataSetReference (self, dataSetReference); ClientReportControlBlock_setDataSetReference(self, dataSetReference);
flagDataSetReference = true; flagDataSetReference = true;
} }
/// <summary> /// <summary>
/// Gets the report identifier. /// Gets the report identifier.
@ -538,12 +545,12 @@ namespace IEC61850
/// <returns> /// <returns>
/// The report identifier. /// The report identifier.
/// </returns> /// </returns>
public string GetRptId () public string GetRptId()
{ {
IntPtr rptIdPtr = ClientReportControlBlock_getRptId (self); IntPtr rptIdPtr = ClientReportControlBlock_getRptId(self);
return Marshal.PtrToStringAnsi (rptIdPtr); return Marshal.PtrToStringAnsi(rptIdPtr);
} }
/// <summary> /// <summary>
/// Sets the RptId (report ID) of the RCB /// Sets the RptId (report ID) of the RCB
@ -551,7 +558,7 @@ namespace IEC61850
/// <param name='rptId'> /// <param name='rptId'>
/// The new RptId /// The new RptId
/// </param> /// </param>
public void SetRptId (string rptId) public void SetRptId(string rptId)
{ {
ClientReportControlBlock_setRptId(self, rptId); ClientReportControlBlock_setRptId(self, rptId);
flagRptId = true; flagRptId = true;
@ -563,10 +570,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, if reporting is enabled, false otherwise /// true, if reporting is enabled, false otherwise
/// </returns> /// </returns>
public bool GetRptEna () public bool GetRptEna()
{ {
return ClientReportControlBlock_getRptEna (self); return ClientReportControlBlock_getRptEna(self);
} }
/// <summary> /// <summary>
/// Sets report enable flag. Use this to enable reporting /// Sets report enable flag. Use this to enable reporting
@ -574,17 +581,17 @@ namespace IEC61850
/// <param name='rptEna'> /// <param name='rptEna'>
/// true to enable reporting, false to disable /// true to enable reporting, false to disable
/// </param> /// </param>
public void SetRptEna (bool rptEna) public void SetRptEna(bool rptEna)
{ {
ClientReportControlBlock_setRptEna (self, rptEna); ClientReportControlBlock_setRptEna(self, rptEna);
flagRptEna = true; flagRptEna = true;
} }
/// <summary> /// <summary>
/// Get the purgeBuf flag of the report control block /// Get the purgeBuf flag of the report control block
/// </summary> /// </summary>
/// <returns>the prugeBuf value</returns> /// <returns>the prugeBuf value</returns>
public bool GetPurgeBuf () public bool GetPurgeBuf()
{ {
return ClientReportControlBlock_getPurgeBuf(self); return ClientReportControlBlock_getPurgeBuf(self);
} }
@ -594,7 +601,7 @@ namespace IEC61850
/// </summary> /// </summary>
/// <description>This is only for buffered RCBs. If set to true the report buffer of a buffered RCB will be cleaned.</description> /// <description>This is only for buffered RCBs. If set to true the report buffer of a buffered RCB will be cleaned.</description>
/// <param name="purgeBuf">set to true to flush report buffer</param> /// <param name="purgeBuf">set to true to flush report buffer</param>
public void SetPurgeBuf (bool purgeBuf) public void SetPurgeBuf(bool purgeBuf)
{ {
ClientReportControlBlock_setPurgeBuf(self, purgeBuf); ClientReportControlBlock_setPurgeBuf(self, purgeBuf);
flagPurgeBuf = true; flagPurgeBuf = true;
@ -607,9 +614,9 @@ namespace IEC61850
/// The buffer time in ms. /// The buffer time in ms.
/// </returns> /// </returns>
public UInt32 GetBufTm() public UInt32 GetBufTm()
{ {
return ClientReportControlBlock_getBufTm (self); return ClientReportControlBlock_getBufTm(self);
} }
/// <summary> /// <summary>
/// Sets the buffer time. /// Sets the buffer time.
@ -617,12 +624,12 @@ namespace IEC61850
/// <param name='bufTm'> /// <param name='bufTm'>
/// Buffer time is ms. /// Buffer time is ms.
/// </param> /// </param>
public void SetBufTm (UInt32 bufTm) public void SetBufTm(UInt32 bufTm)
{ {
ClientReportControlBlock_setBufTm (self, bufTm); ClientReportControlBlock_setBufTm(self, bufTm);
flagBufTm = true; flagBufTm = true;
} }
/// <summary> /// <summary>
/// Gets the GI flag /// Gets the GI flag
@ -630,10 +637,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, if GI flag is set /// true, if GI flag is set
/// </returns> /// </returns>
public bool GetGI () public bool GetGI()
{ {
return ClientReportControlBlock_getGI (self); return ClientReportControlBlock_getGI(self);
} }
/// <summary> /// <summary>
/// Sets the GI flag. Use this to trigger a GI (general interrogation) command. /// Sets the GI flag. Use this to trigger a GI (general interrogation) command.
@ -641,11 +648,11 @@ namespace IEC61850
/// <param name='GI'> /// <param name='GI'>
/// request general interrogation of true /// request general interrogation of true
/// </param> /// </param>
public void SetGI (bool GI) public void SetGI(bool GI)
{ {
ClientReportControlBlock_setGI (self, GI); ClientReportControlBlock_setGI(self, GI);
flagGI = true; flagGI = true;
} }
/// <summary> /// <summary>
/// Check if RCB is reserved by a client /// Check if RCB is reserved by a client
@ -653,10 +660,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, the RCB is reserver by a client /// true, the RCB is reserver by a client
/// </returns> /// </returns>
public bool GetResv () public bool GetResv()
{ {
return ClientReportControlBlock_getResv (self); return ClientReportControlBlock_getResv(self);
} }
/// <summary> /// <summary>
/// Gets the configuration revision of the RCB /// Gets the configuration revision of the RCB
@ -664,9 +671,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// The conf rev. /// The conf rev.
/// </returns> /// </returns>
public UInt32 GetConfRev () public UInt32 GetConfRev()
{ {
return ClientReportControlBlock_getConfRev (self); return ClientReportControlBlock_getConfRev(self);
} }
/// <summary> /// <summary>
@ -675,11 +682,11 @@ namespace IEC61850
/// <param name='resv'> /// <param name='resv'>
/// true: reserver this RCB for exclusive use /// true: reserver this RCB for exclusive use
/// </param> /// </param>
public void SetResv (bool resv) public void SetResv(bool resv)
{ {
ClientReportControlBlock_setResv (self, resv); ClientReportControlBlock_setResv(self, resv);
flagResv = true; flagResv = true;
} }
/// <summary> /// <summary>
/// Gets the trigger options of the RCB /// Gets the trigger options of the RCB
@ -688,9 +695,9 @@ namespace IEC61850
/// trigger options /// trigger options
/// </returns> /// </returns>
public TriggerOptions GetTrgOps() public TriggerOptions GetTrgOps()
{ {
return (TriggerOptions) ClientReportControlBlock_getTrgOps (self); return (TriggerOptions)ClientReportControlBlock_getTrgOps(self);
} }
/// <summary> /// <summary>
/// Sets the trigger options of the RCB. /// Sets the trigger options of the RCB.
@ -699,11 +706,11 @@ namespace IEC61850
/// trigger options /// trigger options
/// </param> /// </param>
public void SetTrgOps(TriggerOptions trgOps) public void SetTrgOps(TriggerOptions trgOps)
{ {
ClientReportControlBlock_setTrgOps (self, (int) trgOps); ClientReportControlBlock_setTrgOps(self, (int)trgOps);
flagTrgOps = true; flagTrgOps = true;
} }
/// <summary> /// <summary>
/// Gets the integrity period /// Gets the integrity period
@ -711,10 +718,10 @@ namespace IEC61850
/// <returns> /// <returns>
/// integrity period in ms /// integrity period in ms
/// </returns> /// </returns>
public UInt32 GetIntgPd () public UInt32 GetIntgPd()
{ {
return ClientReportControlBlock_getIntgPd (self); return ClientReportControlBlock_getIntgPd(self);
} }
/// <summary> /// <summary>
/// Sets the integrity period /// Sets the integrity period
@ -722,11 +729,11 @@ namespace IEC61850
/// <param name='intgPd'> /// <param name='intgPd'>
/// integrity period in ms /// integrity period in ms
/// </param> /// </param>
public void SetIntgPd (UInt32 intgPd) public void SetIntgPd(UInt32 intgPd)
{ {
ClientReportControlBlock_setIntgPd (self, intgPd); ClientReportControlBlock_setIntgPd(self, intgPd);
flagIntgPd = true; flagIntgPd = true;
} }
/// <summary> /// <summary>
/// Gets the option fields. /// Gets the option fields.
@ -735,9 +742,9 @@ namespace IEC61850
/// The option fields /// The option fields
/// </returns> /// </returns>
public ReportOptions GetOptFlds() public ReportOptions GetOptFlds()
{ {
return (ReportOptions) ClientReportControlBlock_getOptFlds (self); return (ReportOptions)ClientReportControlBlock_getOptFlds(self);
} }
/// <summary> /// <summary>
/// Sets the option field. Used to enable or disable optional report elements /// Sets the option field. Used to enable or disable optional report elements
@ -746,11 +753,11 @@ namespace IEC61850
/// Option field. /// Option field.
/// </param> /// </param>
public void SetOptFlds(ReportOptions optFlds) public void SetOptFlds(ReportOptions optFlds)
{ {
ClientReportControlBlock_setOptFlds (self, (int)optFlds); ClientReportControlBlock_setOptFlds(self, (int)optFlds);
flagOptFlds = true; flagOptFlds = true;
} }
/// <summary> /// <summary>
/// Check if the report control block has the "ResvTms" attribute. /// Check if the report control block has the "ResvTms" attribute.
@ -805,7 +812,7 @@ namespace IEC61850
else else
return null; return null;
} }
} }
} }
} }

@ -1,7 +1,7 @@
/* /*
* Reporting.cs * Reporting.cs
* *
* Copyright 2014-2018 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,11 +20,10 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System;
using System.Runtime.InteropServices;
using IEC61850.Common; using IEC61850.Common;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace IEC61850 namespace IEC61850
{ {

@ -1,7 +1,7 @@
/* /*
* SampledValuesControlBlock.cs * SampledValuesControlBlock.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,185 +20,184 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace Client namespace Client
{ {
/// <summary> /// <summary>
/// Sampled values control bloc (SvCB) representation. /// Sampled values control bloc (SvCB) representation.
/// </summary> /// </summary>
/// <description> /// <description>
/// This class is used as a client side representation (copy) of a sampled values control block (SvCB). /// This class is used as a client side representation (copy) of a sampled values control block (SvCB).
/// </description> /// </description>
public class SampledValuesControlBlock : IDisposable public class SampledValuesControlBlock : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientSVControlBlock_create (IntPtr iedConnection, string reference); static extern IntPtr ClientSVControlBlock_create(IntPtr iedConnection, string reference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientSVControlBlock_destroy(IntPtr self); static extern void ClientSVControlBlock_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientSVControlBlock_getLastComError (IntPtr self); static extern int ClientSVControlBlock_getLastComError(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientSVControlBlock_isMulticast (IntPtr self); static extern bool ClientSVControlBlock_isMulticast(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientSVControlBlock_setSvEna (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern bool ClientSVControlBlock_setSvEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientSVControlBlock_setResv (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern bool ClientSVControlBlock_setResv(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientSVControlBlock_getSvEna (IntPtr self); static extern bool ClientSVControlBlock_getSvEna(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientSVControlBlock_getResv (IntPtr self); static extern bool ClientSVControlBlock_getResv(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientSVControlBlock_getMsvID (IntPtr self); static extern IntPtr ClientSVControlBlock_getMsvID(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientSVControlBlock_getDatSet (IntPtr self); static extern IntPtr ClientSVControlBlock_getDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientSVControlBlock_getConfRev (IntPtr self); static extern UInt32 ClientSVControlBlock_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientSVControlBlock_getSmpRate (IntPtr self); static extern UInt16 ClientSVControlBlock_getSmpRate(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientSVControlBlock_getOptFlds (IntPtr self); static extern int ClientSVControlBlock_getOptFlds(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern byte ClientSVControlBlock_getSmpMod(IntPtr self); static extern byte ClientSVControlBlock_getSmpMod(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientSVControlBlock_getNoASDU (IntPtr self); static extern int ClientSVControlBlock_getNoASDU(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern PhyComAddress ClientSVControlBlock_getDstAddress (IntPtr self); static extern PhyComAddress ClientSVControlBlock_getDstAddress(IntPtr self);
private IntPtr self; private IntPtr self;
private string objectReference; private string objectReference;
private bool isDisposed = false; private bool isDisposed = false;
public IntPtr Self { get => self;} public IntPtr Self { get => self; }
internal SampledValuesControlBlock(IntPtr iedConnection, string objectReference) internal SampledValuesControlBlock(IntPtr iedConnection, string objectReference)
{ {
self = ClientSVControlBlock_create (iedConnection, objectReference); self = ClientSVControlBlock_create(iedConnection, objectReference);
this.objectReference = objectReference; this.objectReference = objectReference;
} }
public string GetObjectReference () public string GetObjectReference()
{ {
return this.objectReference; return objectReference;
} }
public IedClientError GetLastComError() public IedClientError GetLastComError()
{ {
return (IedClientError)ClientSVControlBlock_getLastComError (self); return (IedClientError)ClientSVControlBlock_getLastComError(self);
} }
public bool IsMulticast() public bool IsMulticast()
{ {
return ClientSVControlBlock_isMulticast (self); return ClientSVControlBlock_isMulticast(self);
} }
public bool GetResv() public bool GetResv()
{ {
return ClientSVControlBlock_getResv (self); return ClientSVControlBlock_getResv(self);
} }
public bool SetResv(bool value) public bool SetResv(bool value)
{ {
return ClientSVControlBlock_setResv (self, value); return ClientSVControlBlock_setResv(self, value);
} }
public bool GetSvEna() public bool GetSvEna()
{ {
return ClientSVControlBlock_getSvEna (self); return ClientSVControlBlock_getSvEna(self);
} }
public bool SetSvEna(bool value) public bool SetSvEna(bool value)
{ {
return ClientSVControlBlock_setSvEna (self, value); return ClientSVControlBlock_setSvEna(self, value);
} }
public string GetMsvID () public string GetMsvID()
{ {
IntPtr msvIdPtr = ClientSVControlBlock_getMsvID (self); IntPtr msvIdPtr = ClientSVControlBlock_getMsvID(self);
return Marshal.PtrToStringAnsi (msvIdPtr); return Marshal.PtrToStringAnsi(msvIdPtr);
} }
public string GetDatSet () public string GetDatSet()
{ {
IntPtr datSetPtr = ClientSVControlBlock_getDatSet (self); IntPtr datSetPtr = ClientSVControlBlock_getDatSet(self);
return Marshal.PtrToStringAnsi (datSetPtr); return Marshal.PtrToStringAnsi(datSetPtr);
} }
public UInt32 GetConfRev () public UInt32 GetConfRev()
{ {
return ClientSVControlBlock_getConfRev (self); return ClientSVControlBlock_getConfRev(self);
} }
public UInt16 GetSmpRate () public UInt16 GetSmpRate()
{ {
return ClientSVControlBlock_getSmpRate (self); return ClientSVControlBlock_getSmpRate(self);
} }
public SVOptions GetOptFlds () public SVOptions GetOptFlds()
{ {
return (SVOptions)ClientSVControlBlock_getOptFlds (self); return (SVOptions)ClientSVControlBlock_getOptFlds(self);
} }
public SmpMod GetSmpMod () public SmpMod GetSmpMod()
{ {
return (SmpMod)ClientSVControlBlock_getSmpMod (self); return (SmpMod)ClientSVControlBlock_getSmpMod(self);
} }
public int GetNoASDU () public int GetNoASDU()
{ {
return ClientSVControlBlock_getNoASDU (self); return ClientSVControlBlock_getNoASDU(self);
} }
public PhyComAddress GetDstAddress() public PhyComAddress GetDstAddress()
{ {
return ClientSVControlBlock_getDstAddress (self); return ClientSVControlBlock_getDstAddress(self);
} }
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
isDisposed = true; {
ClientSVControlBlock_destroy (self); isDisposed = true;
self = IntPtr.Zero; ClientSVControlBlock_destroy(self);
} self = IntPtr.Zero;
} }
}
~SampledValuesControlBlock()
{ ~SampledValuesControlBlock()
Dispose (); {
} Dispose();
}
}
}
}
}
} }

@ -1,7 +1,7 @@
/* /*
* SampledValuedSubscriber.cs * SampledValuedSubscriber.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,454 +21,463 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
namespace SV namespace SV
{ {
namespace Subscriber namespace Subscriber
{ {
/// <summary> /// <summary>
/// SV receiver. /// SV receiver.
/// </summary> /// </summary>
/// A receiver is responsible for processing all SV message for a single Ethernet interface. /// A receiver is responsible for processing all SV message for a single Ethernet interface.
/// In order to process messages from multiple Ethernet interfaces you have to create multiple /// In order to process messages from multiple Ethernet interfaces you have to create multiple
/// instances. /// instances.
public class SVReceiver : IDisposable public class SVReceiver : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVReceiver_create (); private static extern IntPtr SVReceiver_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_disableDestAddrCheck(IntPtr self); private static extern void SVReceiver_disableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_enableDestAddrCheck(IntPtr self); private static extern void SVReceiver_enableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_addSubscriber(IntPtr self, IntPtr subscriber); private static extern void SVReceiver_addSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_removeSubscriber(IntPtr self, IntPtr subscriber); private static extern void SVReceiver_removeSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_start(IntPtr self); private static extern void SVReceiver_start(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_stop(IntPtr self); private static extern void SVReceiver_stop(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVReceiver_isRunning (IntPtr self); private static extern bool SVReceiver_isRunning(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_destroy(IntPtr self); private static extern void SVReceiver_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_setInterfaceId(IntPtr self, string interfaceId); private static extern void SVReceiver_setInterfaceId(IntPtr self, string interfaceId);
private IntPtr self; private IntPtr self;
private bool isDisposed = false; private bool isDisposed = false;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> class. /// Initializes a new instance of the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> class.
/// </summary> /// </summary>
public SVReceiver() public SVReceiver()
{ {
self = SVReceiver_create (); self = SVReceiver_create();
} }
public void SetInterfaceId(string interfaceId) public void SetInterfaceId(string interfaceId)
{ {
SVReceiver_setInterfaceId (self, interfaceId); SVReceiver_setInterfaceId(self, interfaceId);
} }
public void DisableDestAddrCheck() public void DisableDestAddrCheck()
{ {
SVReceiver_disableDestAddrCheck (self); SVReceiver_disableDestAddrCheck(self);
} }
public void EnableDestAddrCheck() public void EnableDestAddrCheck()
{ {
SVReceiver_enableDestAddrCheck (self); SVReceiver_enableDestAddrCheck(self);
} }
/// <summary> /// <summary>
/// Add a subscriber to handle /// Add a subscriber to handle
/// </summary> /// </summary>
/// <param name="subscriber">Subscriber.</param> /// <param name="subscriber">Subscriber.</param>
public void AddSubscriber(SVSubscriber subscriber) public void AddSubscriber(SVSubscriber subscriber)
{ {
SVReceiver_addSubscriber (self, subscriber.self); SVReceiver_addSubscriber(self, subscriber.self);
} }
public void RemoveSubscriber(SVSubscriber subscriber) public void RemoveSubscriber(SVSubscriber subscriber)
{ {
SVReceiver_removeSubscriber (self, subscriber.self); SVReceiver_removeSubscriber(self, subscriber.self);
} }
/// <summary> /// <summary>
/// Start handling SV messages /// Start handling SV messages
/// </summary> /// </summary>
public void Start() public void Start()
{ {
SVReceiver_start (self); SVReceiver_start(self);
} }
/// <summary> /// <summary>
/// Stop handling SV messges /// Stop handling SV messges
/// </summary> /// </summary>
public void Stop() public void Stop()
{ {
SVReceiver_stop (self); SVReceiver_stop(self);
} }
public bool IsRunning() public bool IsRunning()
{ {
return SVReceiver_isRunning (self); return SVReceiver_isRunning(self);
} }
/// <summary> /// <summary>
/// Releases all resource used by the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> object. /// Releases all resource used by the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> object.
/// </summary> /// </summary>
/// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="IEC61850.SV.Subscriber.SVReceiver"/>. The /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="IEC61850.SV.Subscriber.SVReceiver"/>. The
/// <see cref="Dispose"/> method leaves the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> in an unusable state. /// <see cref="Dispose"/> method leaves the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> in an unusable state.
/// After calling <see cref="Dispose"/>, you must release all references to the /// After calling <see cref="Dispose"/>, you must release all references to the
/// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> so the garbage collector can reclaim the memory that the /// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> so the garbage collector can reclaim the memory that the
/// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> was occupying.</remarks> /// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> was occupying.</remarks>
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
isDisposed = true; {
SVReceiver_destroy (self); isDisposed = true;
self = IntPtr.Zero; SVReceiver_destroy(self);
} self = IntPtr.Zero;
} }
}
~SVReceiver()
{ ~SVReceiver()
Dispose (); {
} Dispose();
} }
}
/// <summary>
/// SV listener. /// <summary>
/// </summary> /// SV listener.
public delegate void SVUpdateListener (SVSubscriber report, object parameter, SVSubscriberASDU asdu); /// </summary>
public delegate void SVUpdateListener(SVSubscriber report, object parameter, SVSubscriberASDU asdu);
/// <summary>
/// Sampled Values (SV) Subscriber /// <summary>
/// /// Sampled Values (SV) Subscriber
/// A subscriber is an instance associated with a single stream of measurement data. It is identified ///
/// by the Ethernet destination address, the appID value (both are on SV message level) and the svID value /// A subscriber is an instance associated with a single stream of measurement data. It is identified
/// that is part of each ASDU. /// by the Ethernet destination address, the appID value (both are on SV message level) and the svID value
/// </summary> /// that is part of each ASDU.
public class SVSubscriber : IDisposable /// </summary>
{ public class SVSubscriber : IDisposable
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] {
private delegate void InternalSVUpdateListener (IntPtr subscriber, IntPtr parameter, IntPtr asdu); [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalSVUpdateListener(IntPtr subscriber, IntPtr parameter, IntPtr asdu);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_create([Out] byte[] ethAddr, UInt16 appID); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_create([Out] byte[] ethAddr, UInt16 appID);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_create(IntPtr ethAddr, UInt16 appID); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_create(IntPtr ethAddr, UInt16 appID);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVSubscriber_setListener(IntPtr self, InternalSVUpdateListener listener, IntPtr parameter); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVSubscriber_setListener(IntPtr self, InternalSVUpdateListener listener, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVSubscriber_destroy(IntPtr self); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVSubscriber_destroy(IntPtr self);
internal IntPtr self;
internal IntPtr self;
private bool isDisposed = false;
private bool isDisposed = false;
private SVUpdateListener listener;
private object listenerParameter = null; private SVUpdateListener listener;
private object listenerParameter = null;
private event InternalSVUpdateListener internalListener = null;
private event InternalSVUpdateListener internalListener = null;
private void internalSVUpdateListener (IntPtr subscriber, IntPtr parameter, IntPtr asdu)
{ private void internalSVUpdateListener(IntPtr subscriber, IntPtr parameter, IntPtr asdu)
try { {
try
if (listener != null) { {
listener(this, listenerParameter, new SVSubscriberASDU(asdu));
} if (listener != null)
{
} listener(this, listenerParameter, new SVSubscriberASDU(asdu));
catch (Exception e) { }
// older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message); }
} catch (Exception e)
} {
// older versions of mono 2.10 (for linux?) cause this exception
public SVSubscriber(byte[] ethAddr, UInt16 appID) Console.WriteLine(e.Message);
{ }
if (ethAddr == null) { }
self = SVSubscriber_create (IntPtr.Zero, appID);
} else { public SVSubscriber(byte[] ethAddr, UInt16 appID)
{
if (ethAddr.Length != 6) if (ethAddr == null)
throw new ArgumentException ("ethAddr argument has to be of 6 byte size"); {
self = SVSubscriber_create(IntPtr.Zero, appID);
self = SVSubscriber_create (ethAddr, appID); }
} else
} {
public void SetListener(SVUpdateListener listener, object parameter) if (ethAddr.Length != 6)
{ throw new ArgumentException("ethAddr argument has to be of 6 byte size");
this.listener = listener;
this.listenerParameter = parameter; self = SVSubscriber_create(ethAddr, appID);
}
if (internalListener == null) { }
internalListener = new InternalSVUpdateListener (internalSVUpdateListener);
public void SetListener(SVUpdateListener listener, object parameter)
SVSubscriber_setListener (self, internalListener, IntPtr.Zero); {
} this.listener = listener;
} listenerParameter = parameter;
public void Dispose() if (internalListener == null)
{ {
if (isDisposed == false) { internalListener = new InternalSVUpdateListener(internalSVUpdateListener);
isDisposed = true;
SVSubscriber_destroy (self); SVSubscriber_setListener(self, internalListener, IntPtr.Zero);
self = IntPtr.Zero; }
} }
}
}
public class SVSubscriberASDU
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getSmpCnt(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_ASDU_getSvId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_ASDU_getDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 SVSubscriber_ASDU_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern byte SVSubscriber_ASDU_getSmpMod(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getSmpRate(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasRefrTm(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasSmpMod(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] public void Dispose()
[return: MarshalAs(UnmanagedType.I1)] {
private static extern bool SVSubscriber_ASDU_hasSmpRate(IntPtr self); if (isDisposed == false)
{
isDisposed = true;
SVSubscriber_destroy(self);
self = IntPtr.Zero;
}
}
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 SVSubscriber_ASDU_getRefrTmAsMs(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] public class SVSubscriberASDU
private static extern sbyte SVSubscriber_ASDU_getINT8(IntPtr self, int index); {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getSmpCnt(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int16 SVSubscriber_ASDU_getINT16(IntPtr self, int index); private static extern IntPtr SVSubscriber_ASDU_getSvId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 SVSubscriber_ASDU_getINT32(IntPtr self, int index); private static extern IntPtr SVSubscriber_ASDU_getDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int64 SVSubscriber_ASDU_getINT64(IntPtr self, int index); private static extern UInt32 SVSubscriber_ASDU_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern byte SVSubscriber_ASDU_getINT8U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getINT16U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 SVSubscriber_ASDU_getINT32U(IntPtr self, int index); private static extern byte SVSubscriber_ASDU_getSmpMod(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 SVSubscriber_ASDU_getINT64U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern float SVSubscriber_ASDU_getFLOAT32(IntPtr self, int index); private static extern UInt16 SVSubscriber_ASDU_getSmpRate(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern double SVSubscriber_ASDU_getFLOAT64(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getQuality(IntPtr self, int index); [return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int SVSubscriber_ASDU_getDataSize(IntPtr self); [return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasRefrTm(IntPtr self);
private IntPtr self;
internal SVSubscriberASDU (IntPtr self) [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
{ [return: MarshalAs(UnmanagedType.I1)]
this.self = self; private static extern bool SVSubscriber_ASDU_hasSmpMod(IntPtr self);
}
public UInt16 GetSmpCnt() [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
{ [return: MarshalAs(UnmanagedType.I1)]
return SVSubscriber_ASDU_getSmpCnt (self); private static extern bool SVSubscriber_ASDU_hasSmpRate(IntPtr self);
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
public string GetSvId() private static extern UInt64 SVSubscriber_ASDU_getRefrTmAsMs(IntPtr self);
{
return Marshal.PtrToStringAnsi (SVSubscriber_ASDU_getSvId(self)); [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
} private static extern sbyte SVSubscriber_ASDU_getINT8(IntPtr self, int index);
public string GetDatSet() [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
{ private static extern Int16 SVSubscriber_ASDU_getINT16(IntPtr self, int index);
return Marshal.PtrToStringAnsi (SVSubscriber_ASDU_getDatSet(self));
} [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 SVSubscriber_ASDU_getINT32(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int64 SVSubscriber_ASDU_getINT64(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern byte SVSubscriber_ASDU_getINT8U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getINT16U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 SVSubscriber_ASDU_getINT32U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 SVSubscriber_ASDU_getINT64U(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern float SVSubscriber_ASDU_getFLOAT32(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern double SVSubscriber_ASDU_getFLOAT64(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getQuality(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int SVSubscriber_ASDU_getDataSize(IntPtr self);
private IntPtr self;
internal SVSubscriberASDU(IntPtr self)
{
this.self = self;
}
public UInt16 GetSmpCnt()
{
return SVSubscriber_ASDU_getSmpCnt(self);
}
public string GetSvId()
{
return Marshal.PtrToStringAnsi(SVSubscriber_ASDU_getSvId(self));
}
public string GetDatSet()
{
return Marshal.PtrToStringAnsi(SVSubscriber_ASDU_getDatSet(self));
}
public UInt32 GetConfRev() public UInt32 GetConfRev()
{ {
return SVSubscriber_ASDU_getConfRev (self); return SVSubscriber_ASDU_getConfRev(self);
} }
public SmpMod GetSmpMod() public SmpMod GetSmpMod()
{ {
return (SmpMod) SVSubscriber_ASDU_getSmpMod (self); return (SmpMod)SVSubscriber_ASDU_getSmpMod(self);
} }
public UInt16 GetSmpRate() public UInt16 GetSmpRate()
{ {
return (UInt16)SVSubscriber_ASDU_getSmpRate (self); return SVSubscriber_ASDU_getSmpRate(self);
} }
public bool HasDatSet() public bool HasDatSet()
{ {
return SVSubscriber_ASDU_hasDatSet (self); return SVSubscriber_ASDU_hasDatSet(self);
} }
public bool HasRefrRm() public bool HasRefrRm()
{ {
return SVSubscriber_ASDU_hasRefrTm (self); return SVSubscriber_ASDU_hasRefrTm(self);
} }
public bool HasSmpMod() public bool HasSmpMod()
{ {
return SVSubscriber_ASDU_hasSmpMod (self); return SVSubscriber_ASDU_hasSmpMod(self);
} }
public bool HasSmpRate() public bool HasSmpRate()
{ {
return SVSubscriber_ASDU_hasSmpRate (self); return SVSubscriber_ASDU_hasSmpRate(self);
} }
public UInt64 GetRefrTmAsMs() public UInt64 GetRefrTmAsMs()
{ {
return SVSubscriber_ASDU_getRefrTmAsMs (self); return SVSubscriber_ASDU_getRefrTmAsMs(self);
} }
public sbyte GetINT8(int index) public sbyte GetINT8(int index)
{ {
return SVSubscriber_ASDU_getINT8 (self, index); return SVSubscriber_ASDU_getINT8(self, index);
} }
public Int16 GetINT16(int index) public Int16 GetINT16(int index)
{ {
return SVSubscriber_ASDU_getINT16 (self, index); return SVSubscriber_ASDU_getINT16(self, index);
} }
public Int32 GetINT32(int index) public Int32 GetINT32(int index)
{ {
return SVSubscriber_ASDU_getINT32 (self, index); return SVSubscriber_ASDU_getINT32(self, index);
} }
public Int64 GetINT64(int index) public Int64 GetINT64(int index)
{ {
return SVSubscriber_ASDU_getINT64 (self, index); return SVSubscriber_ASDU_getINT64(self, index);
} }
public byte GetINT8U(int index) public byte GetINT8U(int index)
{ {
return SVSubscriber_ASDU_getINT8U (self, index); return SVSubscriber_ASDU_getINT8U(self, index);
} }
public UInt16 GetINT16U(int index) public UInt16 GetINT16U(int index)
{ {
return SVSubscriber_ASDU_getINT16U (self, index); return SVSubscriber_ASDU_getINT16U(self, index);
} }
public UInt32 GetINT32U(int index) public UInt32 GetINT32U(int index)
{ {
return SVSubscriber_ASDU_getINT32U (self, index); return SVSubscriber_ASDU_getINT32U(self, index);
} }
public UInt64 GetINT64U(int index) public UInt64 GetINT64U(int index)
{ {
return SVSubscriber_ASDU_getINT64U (self, index); return SVSubscriber_ASDU_getINT64U(self, index);
} }
public float GetFLOAT32(int index) public float GetFLOAT32(int index)
{ {
return SVSubscriber_ASDU_getFLOAT32 (self, index); return SVSubscriber_ASDU_getFLOAT32(self, index);
} }
public double GetFLOAT64(int index) public double GetFLOAT64(int index)
{ {
return SVSubscriber_ASDU_getFLOAT64 (self, index); return SVSubscriber_ASDU_getFLOAT64(self, index);
} }
private struct PTimestamp private struct PTimestamp
{ {
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)] [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)]
public byte[] val; public byte[] val;
} }
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern PTimestamp SVSubscriber_ASDU_getTimestamp(IntPtr self, int index); private static extern PTimestamp SVSubscriber_ASDU_getTimestamp(IntPtr self, int index);
public Timestamp GetTimestamp(int index) public Timestamp GetTimestamp(int index)
{ {
PTimestamp retVal = SVSubscriber_ASDU_getTimestamp (self, index); PTimestamp retVal = SVSubscriber_ASDU_getTimestamp(self, index);
return new Timestamp (retVal.val); return new Timestamp(retVal.val);
} }
public Quality GetQuality(int index) public Quality GetQuality(int index)
{ {
UInt16 qValue = SVSubscriber_ASDU_getQuality (self, index); UInt16 qValue = SVSubscriber_ASDU_getQuality(self, index);
return new Quality (qValue); return new Quality(qValue);
} }
/// <summary> /// <summary>
/// Gets the size of the payload data in bytes. The payload comprises the data set data. /// Gets the size of the payload data in bytes. The payload comprises the data set data.
/// </summary> /// </summary>
/// <returns>The payload data size in byte</returns> /// <returns>The payload data size in byte</returns>
public int GetDataSize() public int GetDataSize()
{ {
return SVSubscriber_ASDU_getDataSize (self); return SVSubscriber_ASDU_getDataSize(self);
} }
} }
} }
} }
} }

@ -21,14 +21,9 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System; using System;
using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using IEC61850.Common;
/// <summary> /// <summary>
/// IEC 61850 API for the libiec61850 .NET wrapper library /// IEC 61850 API for the libiec61850 .NET wrapper library
@ -114,7 +109,7 @@ namespace IEC61850
{ {
if (isValid) if (isValid)
{ {
return (TLSConfigVersion)TLSConnection_getTLSVersion((IntPtr)self); return (TLSConfigVersion)TLSConnection_getTLSVersion(self);
} }
else else
{ {
@ -136,7 +131,7 @@ namespace IEC61850
if (isValid) if (isValid)
{ {
IntPtr peerAddrBuf = Marshal.AllocHGlobal(130); IntPtr peerAddrBuf = Marshal.AllocHGlobal(130);
IntPtr peerAddrStr = TLSConnection_getPeerAddress(this.self, peerAddrBuf); IntPtr peerAddrStr = TLSConnection_getPeerAddress(self, peerAddrBuf);
string peerAddr = null; string peerAddr = null;
@ -331,8 +326,8 @@ namespace IEC61850
public void SetEventHandler(TLSEventHandler handler, object parameter) public void SetEventHandler(TLSEventHandler handler, object parameter)
{ {
this.eventHandler = handler; eventHandler = handler;
this.eventHandlerParameter = parameter; eventHandlerParameter = parameter;
if (internalTLSEventHandlerRef == null) if (internalTLSEventHandlerRef == null)
{ {

@ -8,6 +8,7 @@
using System; using System;
using IEC61850.Server; using IEC61850.Server;
using IEC61850.Common; using IEC61850.Common;
using IEC61850;
using System.Threading; using System.Threading;
using System.Net; using System.Net;
using static IEC61850.Server.IedServer; using static IEC61850.Server.IedServer;
@ -17,6 +18,7 @@ using IEC61850.Client;
using ReportControlBlock = IEC61850.Server.ReportControlBlock; using ReportControlBlock = IEC61850.Server.ReportControlBlock;
using IEC61850.Model; using IEC61850.Model;
using System.Data.Common; using System.Data.Common;
using System.Security.Cryptography;
namespace server_access_control namespace server_access_control
{ {
@ -142,12 +144,23 @@ namespace server_access_control
/* Install handler to control access to control blocks (RCBs, LCBs, GoCBs, SVCBs, SGCBs)*/ /* Install handler to control access to control blocks (RCBs, LCBs, GoCBs, SVCBs, SGCBs)*/
bool ControlBlockAccessCallBack(object parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, ControlBlockAccessType accessType) bool ControlBlockAccessCallBack(object parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, ControlBlockAccessType accessType)
{ {
string password = parameter as string;
object securityToken = connection.GetSecurityToken();
if(securityToken != null)
{
if ((securityToken as string == password))
Console.WriteLine("Correct securityToken");
else
Console.WriteLine("Incorrect securityToken");
}
Console.WriteLine(acsiClass.ToString() + " "+ accessType.ToString() + " access " + ld.GetName() + ln.GetName() +"/"+ objectName + "." + subObjectName + "\n"); Console.WriteLine(acsiClass.ToString() + " "+ accessType.ToString() + " access " + ld.GetName() + ln.GetName() +"/"+ objectName + "." + subObjectName + "\n");
return true; return true;
} }
iedServer.SetControlBlockAccessHandler(ControlBlockAccessCallBack, iedServer); iedServer.SetControlBlockAccessHandler(ControlBlockAccessCallBack, "securityToken_password");
/* By default access to variables with FC=DC and FC=CF is not allowed. /* By default access to variables with FC=DC and FC=CF is not allowed.
* This allow to write to simpleIOGenericIO/GGIO1.NamPlt.vendor variable used * This allow to write to simpleIOGenericIO/GGIO1.NamPlt.vendor variable used
@ -332,6 +345,67 @@ namespace server_access_control
iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_1, null); iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_1, null);
iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_2, null); iedServer.SetSVCBHandler(sVCBEventHandler, sampledValuesControlBlock_2, null);
bool clientAuthenticator (object parameter, AcseAuthenticationParameter authParameter, object securityToken, IsoApplicationReference isoApplicationReference)
{
List<string> passwords = parameter as List<string>;
int aeQualifier = isoApplicationReference.GetAeQualifier();
ItuObjectIdentifier ituObjectIdentifier = isoApplicationReference.GetApTitle();
int arcCount = ituObjectIdentifier.GetArcCount();
ushort[] arc = ituObjectIdentifier.GetArcs();
Console.WriteLine("ACSE Authenticator:\n");
string appTitle = "";
for (int i = 0; i < arcCount; i++)
{
appTitle += arc[i];
if (i != (arcCount - 1))
appTitle += ".";
}
Console.WriteLine(" client ap-title: " + appTitle);
Console.WriteLine("\n client ae-qualifier: "+ aeQualifier + " \n");
IEC61850.AcseAuthenticationMechanism acseAuthenticationMechanism = authParameter.GetAuthMechanism();
if (acseAuthenticationMechanism == IEC61850.AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD)
{
byte[] passArray = authParameter.GetPasswordByteArray();
int passwordLenght = passArray.Length;
string password = authParameter.GetPasswordString();
if (passwordLenght == passwords.First().Length)
{
if (password == passwords.First())
{
securityToken = passwords.First();
return true;
}
}
else if (passwordLenght == passwords[1].Length)
{
if (password == passwords[1])
{
securityToken = passwords[1];
return true;
}
}
}
return false;
}
List<string> passwords = new List<string>();
passwords.Add("user1@testpw");
passwords.Add("user2@testpw");
iedServer.SetAuthenticator(clientAuthenticator, passwords);
iedServer.Start(102); iedServer.Start(102);
if (iedServer.IsRunning()) if (iedServer.IsRunning())

@ -60,7 +60,7 @@ main(int argc, char** argv)
IsoConnectionParameters_setRemoteAddresses(parameters, remotePSelector, remoteSSelector, localTSelector); IsoConnectionParameters_setRemoteAddresses(parameters, remotePSelector, remoteSSelector, localTSelector);
IsoConnectionParameters_setLocalAddresses(parameters, localPSelector, localSSelector, remoteTSelector); IsoConnectionParameters_setLocalAddresses(parameters, localPSelector, localSSelector, remoteTSelector);
char* password = "top secret"; char* password = "user1@testpw";
/* use authentication */ /* use authentication */
AcseAuthenticationParameter auth = AcseAuthenticationParameter_create(); AcseAuthenticationParameter auth = AcseAuthenticationParameter_create();
@ -84,6 +84,8 @@ main(int argc, char** argv)
printf("Failed to connect to %s:%i\n", hostname, tcpPort); printf("Failed to connect to %s:%i\n", hostname, tcpPort);
} }
while (true);
IedConnection_destroy(con); IedConnection_destroy(con);
AcseAuthenticationParameter_destroy(auth); AcseAuthenticationParameter_destroy(auth);

@ -1,7 +1,7 @@
/* /*
* reporting.c * reporting.c
* *
* Copyright 2013-2024 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *

@ -1,7 +1,7 @@
/* /*
* config_file_parser.c * config_file_parser.c
* *
* Copyright 2014-2024 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *

@ -1,7 +1,7 @@
/* /*
* asn1_ber_primitive_value.c * asn1_ber_primitive_value.c
* *
* Copyright 2013-2022 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -28,51 +28,56 @@
Asn1PrimitiveValue* Asn1PrimitiveValue*
Asn1PrimitiveValue_create(int size) Asn1PrimitiveValue_create(int size)
{ {
Asn1PrimitiveValue* self = (Asn1PrimitiveValue*) GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue)); Asn1PrimitiveValue* self = (Asn1PrimitiveValue*)GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue));
if (self) { if (self)
self->size = 1; {
self->maxSize = size; self->size = 1;
self->maxSize = size;
self->octets = (uint8_t*) GLOBAL_CALLOC(1, size); self->octets = (uint8_t*)GLOBAL_CALLOC(1, size);
if (self->octets == NULL) { if (self->octets == NULL)
GLOBAL_FREEMEM(self); {
self = NULL; GLOBAL_FREEMEM(self);
} self = NULL;
} }
}
return self; return self;
} }
Asn1PrimitiveValue* Asn1PrimitiveValue*
Asn1PrimitiveValue_clone(Asn1PrimitiveValue* self) Asn1PrimitiveValue_clone(Asn1PrimitiveValue* self)
{ {
Asn1PrimitiveValue* clone = (Asn1PrimitiveValue*) GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue)); Asn1PrimitiveValue* clone = (Asn1PrimitiveValue*)GLOBAL_MALLOC(sizeof(Asn1PrimitiveValue));
if (clone) {
clone->size = self->size;
clone->maxSize = self->maxSize;
clone->octets = (uint8_t*) GLOBAL_MALLOC(self->maxSize); if (clone)
{
clone->size = self->size;
clone->maxSize = self->maxSize;
if (clone->octets) { clone->octets = (uint8_t*)GLOBAL_MALLOC(self->maxSize);
memcpy(clone->octets, self->octets, clone->maxSize);
}
else {
GLOBAL_FREEMEM(clone);
clone = NULL;
}
} if (clone->octets)
{
memcpy(clone->octets, self->octets, clone->maxSize);
}
else
{
GLOBAL_FREEMEM(clone);
clone = NULL;
}
}
return clone; return clone;
} }
bool bool
Asn1PrimitivaValue_compare(Asn1PrimitiveValue* self, Asn1PrimitiveValue* otherValue) Asn1PrimitivaValue_compare(Asn1PrimitiveValue* self, Asn1PrimitiveValue* otherValue)
{ {
if (self->size == otherValue->size) { if (self->size == otherValue->size)
{
if (memcmp(self->octets, otherValue->octets, self->size) == 0) if (memcmp(self->octets, otherValue->octets, self->size) == 0)
return true; return true;
else else
@ -97,7 +102,8 @@ Asn1PrimitiveValue_getMaxSize(Asn1PrimitiveValue* self)
void void
Asn1PrimitiveValue_destroy(Asn1PrimitiveValue* self) Asn1PrimitiveValue_destroy(Asn1PrimitiveValue* self)
{ {
if (self) { if (self)
{
GLOBAL_FREEMEM(self->octets); GLOBAL_FREEMEM(self->octets);
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
} }

@ -1,7 +1,7 @@
/* /*
* ber_decoder.c * ber_decoder.c
* *
* Copyright 2013-2022 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -37,14 +37,18 @@ getIndefiniteLength(uint8_t* buffer, int bufPos, int maxBufPos, int depth, int m
int length = 0; int length = 0;
while (bufPos < maxBufPos) { while (bufPos < maxBufPos)
if ((buffer[bufPos] == 0) && ((bufPos + 1) < maxBufPos) && (buffer[bufPos+1] == 0)) { {
if ((buffer[bufPos] == 0) && ((bufPos + 1) < maxBufPos) && (buffer[bufPos + 1] == 0))
{
return length + 2; return length + 2;
} }
else { else
{
length++; length++;
if ((buffer[bufPos++] & 0x1f) == 0x1f) { if ((buffer[bufPos++] & 0x1f) == 0x1f)
{
/* handle extended tags */ /* handle extended tags */
bufPos++; bufPos++;
length++; length++;
@ -74,17 +78,21 @@ BerDecoder_decodeLengthRecursive(uint8_t* buffer, int* length, int bufPos, int m
uint8_t len1 = buffer[bufPos++]; uint8_t len1 = buffer[bufPos++];
if (len1 & 0x80) { if (len1 & 0x80)
{
int lenLength = len1 & 0x7f; int lenLength = len1 & 0x7f;
if (lenLength == 0) { /* indefinite length form */ if (lenLength == 0)
{ /* indefinite length form */
*length = getIndefiniteLength(buffer, bufPos, maxBufPos, depth, maxDepth); *length = getIndefiniteLength(buffer, bufPos, maxBufPos, depth, maxDepth);
} }
else { else
{
*length = 0; *length = 0;
int i; int i;
for (i = 0; i < lenLength; i++) { for (i = 0; i < lenLength; i++)
{
if (bufPos >= maxBufPos) if (bufPos >= maxBufPos)
return -1; return -1;
@ -95,18 +103,15 @@ BerDecoder_decodeLengthRecursive(uint8_t* buffer, int* length, int bufPos, int m
*length += buffer[bufPos++]; *length += buffer[bufPos++];
} }
} }
} }
else { else
{
*length = len1; *length = len1;
} }
if (*length < 0) if (*length < 0)
return -1; return -1;
if (*length > maxBufPos)
return -1;
if (bufPos + (*length) > maxBufPos) if (bufPos + (*length) > maxBufPos)
return -1; return -1;
@ -126,8 +131,12 @@ BerDecoder_decodeString(uint8_t* buffer, int strlen, int bufPos, int maxBufPos)
return NULL; return NULL;
char* string = (char*) GLOBAL_MALLOC(strlen + 1); char* string = (char*) GLOBAL_MALLOC(strlen + 1);
memcpy(string, buffer + bufPos, strlen);
string[strlen] = 0; if (string)
{
memcpy(string, buffer + bufPos, strlen);
string[strlen] = 0;
}
return string; return string;
} }
@ -138,7 +147,8 @@ BerDecoder_decodeUint32(uint8_t* buffer, int intLen, int bufPos)
uint32_t value = 0; uint32_t value = 0;
int i; int i;
for (i = 0; i < intLen; i++) { for (i = 0; i < intLen; i++)
{
value <<= 8; value <<= 8;
value += buffer[bufPos + i]; value += buffer[bufPos + i];
} }
@ -159,7 +169,8 @@ BerDecoder_decodeInt32(uint8_t* buffer, int intlen, int bufPos)
else else
value = 0; value = 0;
for (i = 0; i < intlen; i++) { for (i = 0; i < intlen; i++)
{
value <<= 8; value <<= 8;
value += buffer[bufPos + i]; value += buffer[bufPos + i];
} }
@ -171,18 +182,20 @@ float
BerDecoder_decodeFloat(uint8_t* buffer, int bufPos) BerDecoder_decodeFloat(uint8_t* buffer, int bufPos)
{ {
float value; float value;
uint8_t* valueBuf = (uint8_t*) &value; uint8_t* valueBuf = (uint8_t*)&value;
int i; int i;
bufPos += 1; /* skip exponentWidth field */ bufPos += 1; /* skip exponentWidth field */
#if (ORDER_LITTLE_ENDIAN == 1) #if (ORDER_LITTLE_ENDIAN == 1)
for (i = 3; i >= 0; i--) { for (i = 3; i >= 0; i--)
{
valueBuf[i] = buffer[bufPos++]; valueBuf[i] = buffer[bufPos++];
} }
#else #else
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++)
{
valueBuf[i] = buffer[bufPos++]; valueBuf[i] = buffer[bufPos++];
} }
#endif #endif
@ -194,18 +207,20 @@ double
BerDecoder_decodeDouble(uint8_t* buffer, int bufPos) BerDecoder_decodeDouble(uint8_t* buffer, int bufPos)
{ {
double value; double value;
uint8_t* valueBuf = (uint8_t*) &value; uint8_t* valueBuf = (uint8_t*)&value;
int i; int i;
bufPos += 1; /* skip exponentWidth field */ bufPos += 1; /* skip exponentWidth field */
#if (ORDER_LITTLE_ENDIAN == 1) #if (ORDER_LITTLE_ENDIAN == 1)
for (i = 7; i >= 0; i--) { for (i = 7; i >= 0; i--)
{
valueBuf[i] = buffer[bufPos++]; valueBuf[i] = buffer[bufPos++];
} }
#else #else
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++)
{
valueBuf[i] = buffer[bufPos++]; valueBuf[i] = buffer[bufPos++];
} }
#endif #endif
@ -214,7 +229,8 @@ BerDecoder_decodeDouble(uint8_t* buffer, int bufPos)
} }
bool bool
BerDecoder_decodeBoolean(uint8_t* buffer, int bufPos) { BerDecoder_decodeBoolean(uint8_t* buffer, int bufPos)
{
if (buffer[bufPos] != 0) if (buffer[bufPos] != 0)
return true; return true;
else else
@ -233,7 +249,8 @@ BerDecoder_decodeOID(uint8_t* buffer, int bufPos, int length, ItuObjectIdentifie
oid->arc[i] = 0; oid->arc[i] = 0;
/* parse first two arcs */ /* parse first two arcs */
if (length > 0) { if (length > 0)
{
oid->arc[0] = buffer[bufPos] / 40; oid->arc[0] = buffer[bufPos] / 40;
oid->arc[1] = buffer[bufPos] % 40; oid->arc[1] = buffer[bufPos] % 40;
@ -242,8 +259,9 @@ BerDecoder_decodeOID(uint8_t* buffer, int bufPos, int length, ItuObjectIdentifie
} }
/* parse remaining arcs */ /* parse remaining arcs */
while ((bufPos - startPos < length) && (currentArc < 10)) { while ((bufPos - startPos < length) && (currentArc < 10))
oid->arc[currentArc] = oid->arc[currentArc]<<7; {
oid->arc[currentArc] = oid->arc[currentArc] << 7;
if (buffer[bufPos] < 0x80) if (buffer[bufPos] < 0x80)
oid->arc[currentArc++] += buffer[bufPos]; oid->arc[currentArc++] += buffer[bufPos];

@ -1,7 +1,7 @@
/* /*
* ber_integer.c * ber_integer.c
* *
* Copyright 2013-2022 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -25,7 +25,7 @@
#include "ber_integer.h" #include "ber_integer.h"
#include "ber_encoder.h" #include "ber_encoder.h"
static int static bool
setIntegerValue(Asn1PrimitiveValue* self, uint8_t* valueBuffer, int bufferSize) setIntegerValue(Asn1PrimitiveValue* self, uint8_t* valueBuffer, int bufferSize)
{ {
#if (ORDER_LITTLE_ENDIAN == 1) #if (ORDER_LITTLE_ENDIAN == 1)
@ -34,13 +34,15 @@ setIntegerValue(Asn1PrimitiveValue* self, uint8_t* valueBuffer, int bufferSize)
int size = BerEncoder_compressInteger(valueBuffer, bufferSize); int size = BerEncoder_compressInteger(valueBuffer, bufferSize);
if (size <= self->maxSize) { if (size <= self->maxSize)
{
self->size = size; self->size = size;
memcpy(self->octets, valueBuffer, size); memcpy(self->octets, valueBuffer, size);
return 1;
return true;
} }
else else
return 0; return false;
} }
Asn1PrimitiveValue* Asn1PrimitiveValue*
@ -61,7 +63,8 @@ BerInteger_createFromBuffer(uint8_t* buf, int size)
Asn1PrimitiveValue* self = Asn1PrimitiveValue_create(maxSize); Asn1PrimitiveValue* self = Asn1PrimitiveValue_create(maxSize);
if (self) { if (self)
{
memcpy(self->octets, buf, size); memcpy(self->octets, buf, size);
self->size = size; self->size = size;
@ -70,21 +73,22 @@ BerInteger_createFromBuffer(uint8_t* buf, int size)
return self; return self;
} }
int bool
BerInteger_setFromBerInteger(Asn1PrimitiveValue* self, Asn1PrimitiveValue* value) BerInteger_setFromBerInteger(Asn1PrimitiveValue* self, Asn1PrimitiveValue* value)
{ {
if (self->maxSize >= value->size) { if (self->maxSize >= value->size)
{
self->size = value->size; self->size = value->size;
memcpy(self->octets, value->octets, value->size); memcpy(self->octets, value->octets, value->size);
return 1; return true;
} }
else else
return 0; return false;
} }
int bool
BerInteger_setInt32(Asn1PrimitiveValue* self, int32_t value) BerInteger_setInt32(Asn1PrimitiveValue* self, int32_t value)
{ {
int32_t valueCopy = value; int32_t valueCopy = value;
@ -98,14 +102,15 @@ BerInteger_createFromInt32(int32_t value)
{ {
Asn1PrimitiveValue* asn1Value = BerInteger_createInt32(); Asn1PrimitiveValue* asn1Value = BerInteger_createInt32();
if (asn1Value) { if (asn1Value)
{
BerInteger_setInt32(asn1Value, value); BerInteger_setInt32(asn1Value, value);
} }
return asn1Value; return asn1Value;
} }
int bool
BerInteger_setUint16(Asn1PrimitiveValue* self, uint16_t value) BerInteger_setUint16(Asn1PrimitiveValue* self, uint16_t value)
{ {
uint16_t valueCopy = value; uint16_t valueCopy = value;
@ -130,7 +135,7 @@ BerInteger_setUint16(Asn1PrimitiveValue* self, uint16_t value)
return setIntegerValue(self, byteBuffer, sizeof(byteBuffer)); return setIntegerValue(self, byteBuffer, sizeof(byteBuffer));
} }
int bool
BerInteger_setUint8(Asn1PrimitiveValue* self, uint8_t value) BerInteger_setUint8(Asn1PrimitiveValue* self, uint8_t value)
{ {
uint8_t valueCopy = value; uint8_t valueCopy = value;
@ -139,7 +144,7 @@ BerInteger_setUint8(Asn1PrimitiveValue* self, uint8_t value)
return setIntegerValue(self, valueBuffer, sizeof(value)); return setIntegerValue(self, valueBuffer, sizeof(value));
} }
int bool
BerInteger_setUint32(Asn1PrimitiveValue* self, uint32_t value) BerInteger_setUint32(Asn1PrimitiveValue* self, uint32_t value)
{ {
uint32_t valueCopy = value; uint32_t valueCopy = value;
@ -169,7 +174,8 @@ BerInteger_createFromUint32(uint32_t value)
{ {
Asn1PrimitiveValue* asn1Value = BerInteger_createInt32(); Asn1PrimitiveValue* asn1Value = BerInteger_createInt32();
if (asn1Value) { if (asn1Value)
{
BerInteger_setUint32(asn1Value, value); BerInteger_setUint32(asn1Value, value);
} }
@ -182,7 +188,7 @@ BerInteger_createInt64()
return Asn1PrimitiveValue_create(9); return Asn1PrimitiveValue_create(9);
} }
int bool
BerInteger_setInt64(Asn1PrimitiveValue* self, int64_t value) BerInteger_setInt64(Asn1PrimitiveValue* self, int64_t value)
{ {
int64_t valueCopy = value; int64_t valueCopy = value;
@ -196,7 +202,8 @@ BerInteger_createFromInt64(int64_t value)
{ {
Asn1PrimitiveValue* asn1Value = BerInteger_createInt64(); Asn1PrimitiveValue* asn1Value = BerInteger_createInt64();
if (asn1Value) { if (asn1Value)
{
BerInteger_setInt64(asn1Value, value); BerInteger_setInt64(asn1Value, value);
} }
@ -244,4 +251,3 @@ BerInteger_toInt64(Asn1PrimitiveValue* self, int64_t* nativeValue)
for (i = 0; i < self->size; i++) for (i = 0; i < self->size; i++)
*nativeValue = (*nativeValue << 8) | buf[i]; *nativeValue = (*nativeValue << 8) | buf[i];
} }

@ -91,11 +91,31 @@ AcseAuthenticationParameter_destroy(AcseAuthenticationParameter self);
LIB61850_API void LIB61850_API void
AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism); AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism);
LIB61850_API AcseAuthenticationMechanism
AcseAuthenticationParameter_getAuthMechanism(AcseAuthenticationParameter self);
LIB61850_API void LIB61850_API void
AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char* password); AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char* password);
LIB61850_API const char*
AcseAuthenticationParameter_getPassword(AcseAuthenticationParameter self);
/** LIB61850_API int
AcseAuthenticationParameter_getPasswordLength(AcseAuthenticationParameter self);
LIB61850_API int
IsoApplicationReference_getAeQualifier(IsoApplicationReference self);
LIB61850_API const ItuObjectIdentifier*
IsoApplicationReference_getApTitle(const IsoApplicationReference* self);
LIB61850_API int
ItuObjectIdentifier_getArcCount(ItuObjectIdentifier* self);
LIB61850_API const uint16_t*
ItuObjectIdentifier_getArc(ItuObjectIdentifier* self);
/**
* \brief Callback function to authenticate a client * \brief Callback function to authenticate a client
* *
* \param parameter user provided parameter - set when user registers the authenticator * \param parameter user provided parameter - set when user registers the authenticator

@ -1,7 +1,7 @@
/* /*
* ber_integer.h * ber_integer.h
* *
* Copyright 2013-2018 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -36,22 +36,22 @@ BerInteger_createFromBuffer(uint8_t* buf, int size);
LIB61850_INTERNAL Asn1PrimitiveValue* LIB61850_INTERNAL Asn1PrimitiveValue*
BerInteger_createInt32(void); BerInteger_createInt32(void);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setFromBerInteger(Asn1PrimitiveValue* self, Asn1PrimitiveValue* value); BerInteger_setFromBerInteger(Asn1PrimitiveValue* self, Asn1PrimitiveValue* value);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setInt32(Asn1PrimitiveValue* self, int32_t value); BerInteger_setInt32(Asn1PrimitiveValue* self, int32_t value);
LIB61850_INTERNAL Asn1PrimitiveValue* LIB61850_INTERNAL Asn1PrimitiveValue*
BerInteger_createFromInt32(int32_t value); BerInteger_createFromInt32(int32_t value);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setUint8(Asn1PrimitiveValue* self, uint8_t value); BerInteger_setUint8(Asn1PrimitiveValue* self, uint8_t value);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setUint16(Asn1PrimitiveValue* self, uint16_t value); BerInteger_setUint16(Asn1PrimitiveValue* self, uint16_t value);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setUint32(Asn1PrimitiveValue* self, uint32_t value); BerInteger_setUint32(Asn1PrimitiveValue* self, uint32_t value);
LIB61850_INTERNAL Asn1PrimitiveValue* LIB61850_INTERNAL Asn1PrimitiveValue*
@ -63,7 +63,7 @@ BerInteger_createFromInt64(int64_t value);
LIB61850_INTERNAL Asn1PrimitiveValue* LIB61850_INTERNAL Asn1PrimitiveValue*
BerInteger_createInt64(void); BerInteger_createInt64(void);
LIB61850_INTERNAL int LIB61850_INTERNAL bool
BerInteger_setInt64(Asn1PrimitiveValue* self, int64_t value); BerInteger_setInt64(Asn1PrimitiveValue* self, int64_t value);
LIB61850_INTERNAL void LIB61850_INTERNAL void

@ -57,12 +57,76 @@ AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char*
self->value.password.passwordLength = strlen(password); self->value.password.passwordLength = strlen(password);
} }
/* TODO
->One function returning as string and another as by array*/
const char*
AcseAuthenticationParameter_getPassword(AcseAuthenticationParameter self)
{
if (self == NULL)
return NULL;
if (self->mechanism != ACSE_AUTH_PASSWORD)
return NULL;
return (char*)self->value.password.octetString;
}
int
AcseAuthenticationParameter_getPasswordLength(AcseAuthenticationParameter self)
{
if (self == NULL)
return 0;
if (self->mechanism != ACSE_AUTH_PASSWORD)
return 0;
return self->value.password.passwordLength;
}
void void
AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism) AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism)
{ {
self->mechanism = mechanism; self->mechanism = mechanism;
} }
AcseAuthenticationMechanism
AcseAuthenticationParameter_getAuthMechanism(AcseAuthenticationParameter self)
{
return self->mechanism;
}
LIB61850_API int
IsoApplicationReference_getAeQualifier(IsoApplicationReference self)
{
return self.aeQualifier;
}
LIB61850_API const ItuObjectIdentifier*
IsoApplicationReference_getApTitle(const IsoApplicationReference* self)
{
if (self == NULL)
return NULL;
return &(self->apTitle);
}
LIB61850_API int
ItuObjectIdentifier_getArcCount(ItuObjectIdentifier* self)
{
if (self == NULL)
return NULL;
return self->arcCount;
}
LIB61850_API const uint16_t*
ItuObjectIdentifier_getArc(ItuObjectIdentifier* self)
{
if (self == NULL)
return NULL;
return self->arc;
}
IsoConnectionParameters IsoConnectionParameters
IsoConnectionParameters_create() IsoConnectionParameters_create()
{ {

@ -1,7 +1,7 @@
/* /*
* mms_server.c * mms_server.c
* *
* Copyright 2013-2024 Michael Zillgith * Copyright 2013-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *

Loading…
Cancel
Save