(LIB61850-513)

->API AcseAuthenticationParameter GetPasswordString
v1.6
Maxson Ramon dos Anjos Medeiros 4 weeks ago
parent edbf23870a
commit 749e603b94

@ -1,7 +1,7 @@
/* /*
* AcseAuthenticationParameter.cs * AcseAuthenticationParameter.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2025-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,7 +21,6 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System; using System;
using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -81,7 +80,7 @@ namespace IEC61850
public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism) public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism)
{ {
AcseAuthenticationParameter_setAuthMechanism(self,(int)acseAuthenticationMechanism); AcseAuthenticationParameter_setAuthMechanism(self, (int)acseAuthenticationMechanism);
} }
public void SetPassword(string password) public void SetPassword(string password)
@ -94,16 +93,39 @@ namespace IEC61850
return (AcseAuthenticationMechanism)AcseAuthenticationParameter_getAuthMechanism(self); return (AcseAuthenticationMechanism)AcseAuthenticationParameter_getAuthMechanism(self);
} }
public string GetPassword() public string GetPasswordString()
{
try
{
byte[] password = GetPasswordByteArray();
return Encoding.UTF8.GetString(password);
}
catch (Exception)
{
return null;
}
}
public byte[] GetPasswordByteArray()
{ {
IntPtr password = AcseAuthenticationParameter_getPassword(self); IntPtr password = AcseAuthenticationParameter_getPassword(self);
if (password != IntPtr.Zero) if (password != IntPtr.Zero)
return Marshal.PtrToStringAnsi(password); {
int lenght = GetPasswordLenght();
byte[] result = new byte[lenght];
Marshal.Copy(password, result, 0, lenght);
return result;
}
else else
return null; return null;
} }
public int GetPasswordLenght() public int GetPasswordLenght()
{ {
return AcseAuthenticationParameter_getPasswordLength(self); return AcseAuthenticationParameter_getPasswordLength(self);
@ -122,7 +144,7 @@ namespace IEC61850
public IsoApplicationReference(IntPtr self) public IsoApplicationReference(IntPtr self)
{ {
this.self= self; this.self = self;
} }
public int GetAeQualifier() public int GetAeQualifier()

@ -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;
} }

@ -1,7 +1,7 @@
/* /*
* IEC61850ServerAPI.cs * IEC61850ServerAPI.cs
* *
* Copyright 2016-2024 Michael Zillgith * Copyright 2016-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -25,10 +25,7 @@ using IEC61850.Model;
using IEC61850.TLS; using IEC61850.TLS;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal;
// IEC 61850 API for the libiec61850 .NET wrapper library // IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850 namespace IEC61850
@ -46,12 +43,13 @@ namespace IEC61850
public static IedModel CreateModelFromConfigFile(string filePath) public static IedModel CreateModelFromConfigFile(string filePath)
{ {
IntPtr retVal = ConfigFileParser_createModelFromConfigFileEx (filePath); IntPtr retVal = ConfigFileParser_createModelFromConfigFileEx(filePath);
if (retVal == IntPtr.Zero) { if (retVal == IntPtr.Zero)
{
return null; return null;
} }
return new IedModel (retVal); return new IedModel(retVal);
} }
} }
@ -286,7 +284,7 @@ namespace IEC61850
if (nodeRef == IntPtr.Zero) if (nodeRef == IntPtr.Zero)
return null; return null;
return GetModelNodeFromNodeRef (nodeRef); return GetModelNodeFromNodeRef(nodeRef);
} }
/// <summary> /// <summary>
@ -301,7 +299,7 @@ namespace IEC61850
if (nodeRef == IntPtr.Zero) if (nodeRef == IntPtr.Zero)
return null; return null;
return GetModelNodeFromNodeRef (nodeRef); return GetModelNodeFromNodeRef(nodeRef);
} }
public SVControlBlock GetSVControlBlock(LogicalNode logicalNode, string svcbName) public SVControlBlock GetSVControlBlock(LogicalNode logicalNode, string svcbName)
@ -332,9 +330,9 @@ namespace IEC61850
public IedModel IedModel { get; } public IedModel IedModel { get; }
public LogicalDevice (IntPtr self, IedModel iedModel) : base (self) public LogicalDevice(IntPtr self, IedModel iedModel) : base(self)
{ {
this.IedModel = iedModel; IedModel = iedModel;
} }
/// <summary> /// <summary>
@ -344,7 +342,7 @@ namespace IEC61850
/// <param name="parent">Model containing this logical device</param> /// <param name="parent">Model containing this logical device</param>
public LogicalDevice(string inst, IedModel parent) public LogicalDevice(string inst, IedModel parent)
{ {
this.IedModel = parent; IedModel = parent;
self = LogicalDevice_create(inst, parent.self); self = LogicalDevice_create(inst, parent.self);
} }
@ -357,7 +355,7 @@ namespace IEC61850
/// <param name="ldName">LD name (for functional naming). When set, the exernally visible domain name for this LD</param> /// <param name="ldName">LD name (for functional naming). When set, the exernally visible domain name for this LD</param>
public LogicalDevice(string inst, IedModel parent, string ldName) public LogicalDevice(string inst, IedModel parent, string ldName)
{ {
this.IedModel = parent; IedModel = parent;
self = LogicalDevice_createEx(inst, parent.self, ldName); self = LogicalDevice_createEx(inst, parent.self, ldName);
} }
@ -368,9 +366,9 @@ namespace IEC61850
/// <returns>the SGCB instance or NULL if no SGCB is available</returns> /// <returns>the SGCB instance or NULL if no SGCB is available</returns>
public SettingGroupControlBlock GetSettingGroupControlBlock() public SettingGroupControlBlock GetSettingGroupControlBlock()
{ {
IntPtr sgcb = LogicalDevice_getSettingGroupControlBlock(this.self); IntPtr sgcb = LogicalDevice_getSettingGroupControlBlock(self);
if(sgcb == IntPtr.Zero) if (sgcb == IntPtr.Zero)
return null; return null;
return new SettingGroupControlBlock(sgcb); return new SettingGroupControlBlock(sgcb);
@ -387,7 +385,7 @@ namespace IEC61850
internal Dictionary<IntPtr, ReportControlBlock> rcbs = new Dictionary<IntPtr, ReportControlBlock>(); internal Dictionary<IntPtr, ReportControlBlock> rcbs = new Dictionary<IntPtr, ReportControlBlock>();
public LogicalNode (IntPtr self, ModelNode parent) : base(self) public LogicalNode(IntPtr self, ModelNode parent) : base(self)
{ {
this.parent = parent; this.parent = parent;
} }
@ -410,12 +408,14 @@ namespace IEC61850
} }
} }
public enum AccessPolicy { public enum AccessPolicy
{
ACCESS_POLICY_ALLOW = 0, ACCESS_POLICY_ALLOW = 0,
ACCESS_POLICY_DENY = 1 ACCESS_POLICY_DENY = 1
} }
public enum DataAttributeType { public enum DataAttributeType
{
BOOLEAN = 0, BOOLEAN = 0,
INT8 = 1, INT8 = 1,
INT16 = 2, INT16 = 2,
@ -596,7 +596,7 @@ namespace IEC61850
IntPtr self = CDC_SPS_create(name, parent.self, options); IntPtr self = CDC_SPS_create(name, parent.self, options);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -756,7 +756,7 @@ namespace IEC61850
IntPtr self = CDC_INS_create(name, parent.self, options); IntPtr self = CDC_INS_create(name, parent.self, options);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -766,7 +766,7 @@ namespace IEC61850
IntPtr self = CDC_MV_create(name, parent.self, options, isIntegerNotFloat); IntPtr self = CDC_MV_create(name, parent.self, options, isIntegerNotFloat);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -776,7 +776,7 @@ namespace IEC61850
IntPtr self = CDC_INC_create(name, parent.self, options, controlOptions); IntPtr self = CDC_INC_create(name, parent.self, options, controlOptions);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -786,7 +786,7 @@ namespace IEC61850
IntPtr self = CDC_LPL_create(name, parent.self, options); IntPtr self = CDC_LPL_create(name, parent.self, options);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -796,7 +796,7 @@ namespace IEC61850
IntPtr self = CDC_DPL_create(name, parent.self, options); IntPtr self = CDC_DPL_create(name, parent.self, options);
if (self != IntPtr.Zero) if (self != IntPtr.Zero)
return new DataObject (self, parent); return new DataObject(self, parent);
else else
return null; return null;
} }
@ -953,7 +953,7 @@ namespace IEC61850
{ {
this.parent = parent; this.parent = parent;
self = DataObject_create (name, parent.self, arrayElements); self = DataObject_create(name, parent.self, arrayElements);
} }
/// <summary> /// <summary>
@ -968,7 +968,7 @@ namespace IEC61850
public DataAttribute GetChildWithFc(string objRef, FunctionalConstraint fc) public DataAttribute GetChildWithFc(string objRef, FunctionalConstraint fc)
{ {
DataAttribute dataAttribute = null; DataAttribute dataAttribute = null;
IntPtr da = ModelNode_getChildWithFc(this.self, objRef, (int)fc); IntPtr da = ModelNode_getChildWithFc(self, objRef, (int)fc);
if (da != IntPtr.Zero) if (da != IntPtr.Zero)
{ {
@ -1014,12 +1014,12 @@ namespace IEC61850
/// <param name="trgOps">the trigger options (dupd, dchg, qchg) that cause an event notification</param> /// <param name="trgOps">the trigger options (dupd, dchg, qchg) that cause an event notification</param>
/// <param name="arrayElements">the number of array elements if the data attribute is an array or 0</param> /// <param name="arrayElements">the number of array elements if the data attribute is an array or 0</param>
/// <param name="sAddr">an optional short address (deprecated)</param> /// <param name="sAddr">an optional short address (deprecated)</param>
public DataAttribute (string name, ModelNode parent, DataAttributeType type, FunctionalConstraint fc, TriggerOptions trgOps, public DataAttribute(string name, ModelNode parent, DataAttributeType type, FunctionalConstraint fc, TriggerOptions trgOps,
int arrayElements, UInt32 sAddr) int arrayElements, UInt32 sAddr)
{ {
this.parent = parent; this.parent = parent;
self = DataAttribute_create (name, parent.self, (int)type, (int)fc, (byte)trgOps, arrayElements, sAddr); self = DataAttribute_create(name, parent.self, (int)type, (int)fc, (byte)trgOps, arrayElements, sAddr);
} }
/// <summary> /// <summary>
@ -1155,7 +1155,7 @@ namespace IEC61850
} }
else else
{ {
if (this.parent != null) if (parent != null)
return parent.GetIedModel(); return parent.GetIedModel();
else else
return null; return null;
@ -1295,7 +1295,7 @@ namespace IEC61850
if (childNode == null) if (childNode == null)
{ {
childNode = ModelNode.CreateInstance(modelNodePtr, this); childNode = ModelNode.CreateInstance(modelNodePtr, this);
if ((childNode != null) && (iedModel != null)) if ((childNode != null) && (iedModel != null))
{ {
@ -1327,14 +1327,16 @@ namespace IEC61850
IntPtr objRefPtr = ModelNode_getObjectReferenceEx(self, nativeMemory, withoutIedName); IntPtr objRefPtr = ModelNode_getObjectReferenceEx(self, nativeMemory, withoutIedName);
if (objRefPtr != IntPtr.Zero) { if (objRefPtr != IntPtr.Zero)
{
string objRef = Marshal.PtrToStringAnsi(objRefPtr); string objRef = Marshal.PtrToStringAnsi(objRefPtr);
Marshal.FreeHGlobal(nativeMemory); Marshal.FreeHGlobal(nativeMemory);
return objRef; return objRef;
} }
else { else
{
Marshal.FreeHGlobal(nativeMemory); Marshal.FreeHGlobal(nativeMemory);
return null; return null;
@ -1741,12 +1743,12 @@ namespace IEC61850
public SettingGroupControlBlock(LogicalNode parent, UInt32 actSG, UInt32 numOfSGs) public SettingGroupControlBlock(LogicalNode parent, UInt32 actSG, UInt32 numOfSGs)
{ {
self = SettingGroupControlBlock_create(parent.self, (byte) actSG, (byte) numOfSGs); self = SettingGroupControlBlock_create(parent.self, (byte)actSG, (byte)numOfSGs);
} }
public SettingGroupControlBlock(IntPtr self) public SettingGroupControlBlock(IntPtr self)
{ {
this.self = self ; this.self = self;
} }
} }
@ -1795,7 +1797,7 @@ namespace IEC61850
if (token != IntPtr.Zero) if (token != IntPtr.Zero)
{ {
GCHandle handle = GCHandle.FromIntPtr(token); GCHandle handle = GCHandle.FromIntPtr(token);
return handle as object; return handle;
} }
} }
} }
@ -1865,7 +1867,7 @@ namespace IEC61850
} }
} }
~ClientConnection () ~ClientConnection()
{ {
Dispose(); Dispose();
} }
@ -1915,7 +1917,7 @@ namespace IEC61850
if (lnModelNode != null && lnModelNode is LogicalNode) if (lnModelNode != null && lnModelNode is LogicalNode)
{ {
this.ln = lnModelNode as LogicalNode; ln = lnModelNode as LogicalNode;
} }
} }
@ -1992,17 +1994,17 @@ namespace IEC61850
/// </summary> /// </summary>
public class ControlAction public class ControlAction
{ {
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setAddCause (IntPtr self, int addCause); static extern void ControlAction_setAddCause(IntPtr self, int addCause);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setError(IntPtr self, int error); static extern void ControlAction_setError(IntPtr self, int error);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ControlAction_getOrCat (IntPtr self); static extern int ControlAction_getOrCat(IntPtr self);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getOrIdent (IntPtr self, ref int size); static extern IntPtr ControlAction_getOrIdent(IntPtr self, ref int size);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getClientConnection(IntPtr self); static extern IntPtr ControlAction_getClientConnection(IntPtr self);
@ -2032,7 +2034,7 @@ namespace IEC61850
private IedServer.ControlHandlerInfo info; private IedServer.ControlHandlerInfo info;
private IedServer iedServer; private IedServer iedServer;
internal ControlAction (IntPtr self, IedServer.ControlHandlerInfo info, IedServer iedServer) internal ControlAction(IntPtr self, IedServer.ControlHandlerInfo info, IedServer iedServer)
{ {
this.self = self; this.self = self;
this.info = info; this.info = info;
@ -2052,36 +2054,36 @@ namespace IEC61850
/// Sets the add cause for the next command termination or application error message /// Sets the add cause for the next command termination or application error message
/// </summary> /// </summary>
/// <param name="addCause">the additional cause code</param> /// <param name="addCause">the additional cause code</param>
public void SetAddCause (ControlAddCause addCause) public void SetAddCause(ControlAddCause addCause)
{ {
ControlAction_setAddCause (self, (int)addCause); ControlAction_setAddCause(self, (int)addCause);
} }
/// <summary> /// <summary>
/// Gets the originator category provided by the client /// Gets the originator category provided by the client
/// </summary> /// </summary>
/// <returns>The or cat.</returns> /// <returns>The or cat.</returns>
public OrCat GetOrCat () public OrCat GetOrCat()
{ {
return (OrCat)ControlAction_getOrCat (self); return (OrCat)ControlAction_getOrCat(self);
} }
/// <summary> /// <summary>
/// Get the originator identifier provided by the client /// Get the originator identifier provided by the client
/// </summary> /// </summary>
/// <returns>The or ident.</returns> /// <returns>The or ident.</returns>
public byte [] GetOrIdent () public byte[] GetOrIdent()
{ {
int size = 0; int size = 0;
IntPtr orIdentPtr = ControlAction_getOrIdent (self, ref size); IntPtr orIdentPtr = ControlAction_getOrIdent(self, ref size);
if (orIdentPtr == IntPtr.Zero) if (orIdentPtr == IntPtr.Zero)
return null; return null;
byte [] orIdent = new byte [size]; byte[] orIdent = new byte[size];
Marshal.Copy (orIdentPtr, orIdent, 0, size); Marshal.Copy(orIdentPtr, orIdent, 0, size);
return orIdent; return orIdent;
} }
@ -2099,7 +2101,7 @@ namespace IEC61850
/// Gets the control object that is subject to this action /// Gets the control object that is subject to this action
/// </summary> /// </summary>
/// <returns>the controllable data object instance</returns> /// <returns>the controllable data object instance</returns>
public DataObject GetControlObject () public DataObject GetControlObject()
{ {
return info.controlObject; return info.controlObject;
} }
@ -2126,14 +2128,15 @@ namespace IEC61850
/// Gets the client object associated with the client that caused the control action /// Gets the client object associated with the client that caused the control action
/// </summary> /// </summary>
/// <returns>The client connection.</returns> /// <returns>The client connection.</returns>
public ClientConnection GetClientConnection () public ClientConnection GetClientConnection()
{ {
ClientConnection con = null; ClientConnection con = null;
IntPtr conPtr = ControlAction_getClientConnection (self); IntPtr conPtr = ControlAction_getClientConnection(self);
if (conPtr != IntPtr.Zero) { if (conPtr != IntPtr.Zero)
iedServer.clientConnections.TryGetValue (conPtr, out con); {
iedServer.clientConnections.TryGetValue(conPtr, out con);
} }
return con; return con;
@ -2222,7 +2225,7 @@ namespace IEC61850
public delegate void RCBEventHandler(object parameter, ReportControlBlock rcb, ClientConnection con, RCBEventType eventType, string parameterName, MmsDataAccessError serviceError); public delegate void RCBEventHandler(object parameter, ReportControlBlock rcb, ClientConnection con, RCBEventType eventType, string parameterName, MmsDataAccessError serviceError);
public delegate MmsDataAccessError WriteAccessHandler (DataAttribute dataAttr, MmsValue value, public delegate MmsDataAccessError WriteAccessHandler(DataAttribute dataAttr, MmsValue value,
ClientConnection connection, object parameter); ClientConnection connection, object parameter);
/// <summary> /// <summary>
@ -2261,7 +2264,8 @@ namespace IEC61850
/// <summary> /// <summary>
/// Return type of ControlHandler and ControlWaitForExecutionHandler /// Return type of ControlHandler and ControlWaitForExecutionHandler
/// </summary> /// </summary>
public enum ControlHandlerResult { public enum ControlHandlerResult
{
/// <summary> /// <summary>
/// check or operation failed /// check or operation failed
/// </summary> /// </summary>
@ -2276,11 +2280,12 @@ namespace IEC61850
WAITING = 2 WAITING = 2
} }
public delegate ControlHandlerResult ControlWaitForExecutionHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test, bool synchroCheck); public delegate ControlHandlerResult ControlWaitForExecutionHandler(ControlAction action, object parameter, MmsValue ctlVal, bool test, bool synchroCheck);
public delegate ControlHandlerResult ControlHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test); public delegate ControlHandlerResult ControlHandler(ControlAction action, object parameter, MmsValue ctlVal, bool test);
public enum CheckHandlerResult { public enum CheckHandlerResult
{
/// <summary> /// <summary>
/// check passed /// check passed
/// </summary> /// </summary>
@ -2318,7 +2323,7 @@ namespace IEC61850
DATASET_GET_DIRECTORY DATASET_GET_DIRECTORY
} }
public delegate CheckHandlerResult CheckHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test, bool interlockCheck); public delegate CheckHandlerResult CheckHandler(ControlAction action, object parameter, MmsValue ctlVal, bool test, bool interlockCheck);
public static class SqliteLogStorage public static class SqliteLogStorage
{ {
@ -2486,13 +2491,13 @@ namespace IEC61850
/// </summary> /// </summary>
public class IedServer : IDisposable public class IedServer : IDisposable
{ {
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedServer_createWithConfig(IntPtr modelRef, IntPtr tlsConfiguration, IntPtr serverConfiguratio); static extern IntPtr IedServer_createWithConfig(IntPtr modelRef, IntPtr tlsConfiguration, IntPtr serverConfiguratio);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setLocalIpAddress(IntPtr self, string localIpAddress); static extern void IedServer_setLocalIpAddress(IntPtr self, string localIpAddress);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_start(IntPtr self, int tcpPort); static extern void IedServer_start(IntPtr self, int tcpPort);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -2751,13 +2756,13 @@ namespace IEC61850
public delegate bool IedServer_ListObjectsAccessHandler(IntPtr parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, FunctionalConstraint fc); public delegate bool IedServer_ListObjectsAccessHandler(IntPtr parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice ld, LogicalNode ln, string objectName, string subObjectName, FunctionalConstraint fc);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlPerformCheckHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool interlockCheck); private delegate int InternalControlPerformCheckHandler(IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool interlockCheck);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlWaitForExecutionHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool synchoCheck); private delegate int InternalControlWaitForExecutionHandler(IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool synchoCheck);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test); private delegate int InternalControlHandler(IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalSelectStateChangedHandler(IntPtr action, IntPtr parameter, [MarshalAs(UnmanagedType.I1)] bool isSelected, int reason); private delegate void InternalSelectStateChangedHandler(IntPtr action, IntPtr parameter, [MarshalAs(UnmanagedType.I1)] bool isSelected, int reason);
@ -2769,7 +2774,7 @@ namespace IEC61850
static extern void IedServer_setPerformCheckHandler(IntPtr self, IntPtr node, InternalControlPerformCheckHandler handler, IntPtr parameter); static extern void IedServer_setPerformCheckHandler(IntPtr self, IntPtr node, InternalControlPerformCheckHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setControlHandler (IntPtr self, IntPtr node, InternalControlHandler handler, IntPtr parameter); static extern void IedServer_setControlHandler(IntPtr self, IntPtr node, InternalControlHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setSelectStateChangedHandler(IntPtr self, IntPtr node, InternalSelectStateChangedHandler handler, IntPtr parameter); static extern void IedServer_setSelectStateChangedHandler(IntPtr self, IntPtr node, InternalSelectStateChangedHandler handler, IntPtr parameter);
@ -2778,7 +2783,7 @@ namespace IEC61850
static extern void IedServer_setWriteAccessPolicy(IntPtr self, FunctionalConstraint fc, AccessPolicy policy); static extern void IedServer_setWriteAccessPolicy(IntPtr self, FunctionalConstraint fc, AccessPolicy policy);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalWriteAccessHandler (IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter); private delegate int InternalWriteAccessHandler(IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_handleWriteAccess(IntPtr self, IntPtr dataAttribute, static extern void IedServer_handleWriteAccess(IntPtr self, IntPtr dataAttribute,
@ -2804,7 +2809,7 @@ namespace IEC61850
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalConnectionHandler (IntPtr iedServer, IntPtr clientConnection, [MarshalAs(UnmanagedType.I1)] bool connected, IntPtr parameter); private delegate void InternalConnectionHandler(IntPtr iedServer, IntPtr clientConnection, [MarshalAs(UnmanagedType.I1)] bool connected, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setConnectionIndicationHandler(IntPtr self, InternalConnectionHandler handler, IntPtr parameter); static extern void IedServer_setConnectionIndicationHandler(IntPtr self, InternalConnectionHandler handler, IntPtr parameter);
@ -2849,7 +2854,8 @@ namespace IEC61850
// hold references to managed LogStorage instances to avoid problems with GC // hold references to managed LogStorage instances to avoid problems with GC
private Dictionary<string, LogStorage> logStorages = new Dictionary<string, LogStorage>(); private Dictionary<string, LogStorage> logStorages = new Dictionary<string, LogStorage>();
internal class ControlHandlerInfo { internal class ControlHandlerInfo
{
public DataObject controlObject = null; public DataObject controlObject = null;
public GCHandle handle; public GCHandle handle;
@ -2868,57 +2874,58 @@ namespace IEC61850
public ControlHandlerInfo(DataObject controlObject) public ControlHandlerInfo(DataObject controlObject)
{ {
this.controlObject = controlObject; this.controlObject = controlObject;
this.handle = GCHandle.Alloc(this); handle = GCHandle.Alloc(this);
} }
~ControlHandlerInfo() ~ControlHandlerInfo()
{ {
this.handle.Free(); handle.Free();
} }
} }
private Dictionary<DataObject, ControlHandlerInfo> controlHandlers = new Dictionary<DataObject, ControlHandlerInfo> (); private Dictionary<DataObject, ControlHandlerInfo> controlHandlers = new Dictionary<DataObject, ControlHandlerInfo>();
int InternalControlHandlerImpl (IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test) int InternalControlHandlerImpl(IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test)
{ {
GCHandle handle = GCHandle.FromIntPtr (parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
ControlAction controlAction = new ControlAction (action, info, this); ControlAction controlAction = new ControlAction(action, info, this);
if (info != null && info.controlHandler != null) if (info != null && info.controlHandler != null)
return (int)info.controlHandler (controlAction, info.controlHandlerParameter, new MmsValue (ctlVal), test); return (int)info.controlHandler(controlAction, info.controlHandlerParameter, new MmsValue(ctlVal), test);
else else
return (int)ControlHandlerResult.FAILED; return (int)ControlHandlerResult.FAILED;
} }
int InternalCheckHandlerImpl(IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool interlockCheck) int InternalCheckHandlerImpl(IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool interlockCheck)
{ {
GCHandle handle = GCHandle.FromIntPtr (parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
if (info != null && info.checkHandler != null) if (info != null && info.checkHandler != null)
{ {
ControlAction controlAction = new ControlAction (action, info, this); ControlAction controlAction = new ControlAction(action, info, this);
return (int)info.checkHandler (controlAction, info.checkHandlerParameter, new MmsValue (ctlVal), test, interlockCheck); return (int)info.checkHandler(controlAction, info.checkHandlerParameter, new MmsValue(ctlVal), test, interlockCheck);
} else }
else
return (int)CheckHandlerResult.OBJECT_UNDEFINED; return (int)CheckHandlerResult.OBJECT_UNDEFINED;
} }
int InternalControlWaitForExecutionHandlerImpl (IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool synchoCheck) int InternalControlWaitForExecutionHandlerImpl(IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool synchoCheck)
{ {
GCHandle handle = GCHandle.FromIntPtr (parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
if (info != null && info.waitForExecHandler != null) if (info != null && info.waitForExecHandler != null)
{ {
ControlAction controlAction = new ControlAction (action, info, this); ControlAction controlAction = new ControlAction(action, info, this);
return (int)info.waitForExecHandler (controlAction, info.waitForExecHandlerParameter, new MmsValue (ctlVal), test, synchoCheck); return (int)info.waitForExecHandler(controlAction, info.waitForExecHandlerParameter, new MmsValue(ctlVal), test, synchoCheck);
} }
else else
return (int)ControlHandlerResult.FAILED; return (int)ControlHandlerResult.FAILED;
@ -2938,13 +2945,14 @@ namespace IEC61850
} }
} }
private struct WriteAccessHandlerInfo { private struct WriteAccessHandlerInfo
{
public WriteAccessHandler handler; public WriteAccessHandler handler;
public InternalWriteAccessHandler internalHandler; public InternalWriteAccessHandler internalHandler;
public object parameter; public object parameter;
public DataAttribute dataAttribute; public DataAttribute dataAttribute;
public WriteAccessHandlerInfo (WriteAccessHandler h, object p, DataAttribute da, InternalWriteAccessHandler internalHandler) public WriteAccessHandlerInfo(WriteAccessHandler h, object p, DataAttribute da, InternalWriteAccessHandler internalHandler)
{ {
handler = h; handler = h;
parameter = p; parameter = p;
@ -2953,7 +2961,7 @@ namespace IEC61850
} }
} }
int WriteAccessHandlerImpl (IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter) int WriteAccessHandlerImpl(IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter)
{ {
WriteAccessHandlerInfo info; WriteAccessHandlerInfo info;
@ -2969,7 +2977,7 @@ namespace IEC61850
} }
else else
{ {
return (int) MmsDataAccessError.OBJECT_ACCESS_DENIED; return (int)MmsDataAccessError.OBJECT_ACCESS_DENIED;
} }
} }
@ -2992,7 +3000,7 @@ namespace IEC61850
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld); ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld);
ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(ln); ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(ln);
@ -3048,13 +3056,13 @@ namespace IEC61850
} }
} }
private bool InternalDataSetlHandlerImplementation (IntPtr parameter, IntPtr connection, int operation, string datasetRef) private bool InternalDataSetlHandlerImplementation(IntPtr parameter, IntPtr connection, int operation, string datasetRef)
{ {
if (dataSetAccessHandler != null && connection != IntPtr.Zero) if (dataSetAccessHandler != null && connection != IntPtr.Zero)
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
return dataSetAccessHandler(dataSetAccessHandlerParameter, con, (DataSetOperation)operation, datasetRef); return dataSetAccessHandler(dataSetAccessHandlerParameter, con, (DataSetOperation)operation, datasetRef);
} }
@ -3070,7 +3078,7 @@ namespace IEC61850
private IedServer_ActiveSettingGroupChangedHandler internalActiveSettingGroupChangedHandler = null; private IedServer_ActiveSettingGroupChangedHandler internalActiveSettingGroupChangedHandler = null;
public void SetActiveSettingGroupChangedHandler(ActiveSettingGroupChangedHandler handler,SettingGroupControlBlock settingGroupControlBlock, object parameter) public void SetActiveSettingGroupChangedHandler(ActiveSettingGroupChangedHandler handler, SettingGroupControlBlock settingGroupControlBlock, object parameter)
{ {
activeSettingGroupChangedHandler = handler; activeSettingGroupChangedHandler = handler;
activeSettingGroupChangedHandlerParameter = parameter; activeSettingGroupChangedHandlerParameter = parameter;
@ -3094,7 +3102,7 @@ namespace IEC61850
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
return activeSettingGroupChangedHandler(activeSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newActSg, con); return activeSettingGroupChangedHandler(activeSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newActSg, con);
} }
@ -3129,7 +3137,7 @@ namespace IEC61850
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
return editSettingGroupChangedHandler(editSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newEditSg, con); return editSettingGroupChangedHandler(editSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newEditSg, con);
} }
@ -3154,7 +3162,7 @@ namespace IEC61850
{ {
internalEditSettingGroupConfirmationHandler = new IedServer_EditSettingGroupConfirmationHandler(InternalEditSettingGroupConfirmationImplementation); internalEditSettingGroupConfirmationHandler = new IedServer_EditSettingGroupConfirmationHandler(InternalEditSettingGroupConfirmationImplementation);
IedServer_setEditSettingGroupConfirmationHandler(self, settingGroupControlBlock.self, internalEditSettingGroupConfirmationHandler, IntPtr.Zero); IedServer_setEditSettingGroupConfirmationHandler(self, settingGroupControlBlock.self, internalEditSettingGroupConfirmationHandler, IntPtr.Zero);
} }
} }
@ -3181,12 +3189,12 @@ namespace IEC61850
public SVCHandlerInfo(SVControlBlock sampledValuesControlBlock) public SVCHandlerInfo(SVControlBlock sampledValuesControlBlock)
{ {
this.sampledValuesControlBlock = sampledValuesControlBlock; this.sampledValuesControlBlock = sampledValuesControlBlock;
this.handle = GCHandle.Alloc(this); handle = GCHandle.Alloc(this);
} }
~SVCHandlerInfo() ~SVCHandlerInfo()
{ {
this.handle.Free(); handle.Free();
} }
} }
@ -3240,9 +3248,9 @@ namespace IEC61850
public void SetAuthenticator(AcseAuthenticatorHandler acseAuthenticatorHandler, object acseAuthenticatorHandlerParameter) public void SetAuthenticator(AcseAuthenticatorHandler acseAuthenticatorHandler, object acseAuthenticatorHandlerParameter)
{ {
this.acseAuthenticatorHandler = acseAuthenticatorHandler; this.acseAuthenticatorHandler = acseAuthenticatorHandler;
this.acseAuthenticatorHandlerParameter= acseAuthenticatorHandlerParameter; this.acseAuthenticatorHandlerParameter = acseAuthenticatorHandlerParameter;
if(iedServer_AcseAuthenticator == null) if (iedServer_AcseAuthenticator == null)
{ {
iedServer_AcseAuthenticator = new IedServer_AcseAuthenticator(InternalAcseAuthenticator); iedServer_AcseAuthenticator = new IedServer_AcseAuthenticator(InternalAcseAuthenticator);
IedServer_setAuthenticator(self, iedServer_AcseAuthenticator, IntPtr.Zero); IedServer_setAuthenticator(self, iedServer_AcseAuthenticator, IntPtr.Zero);
@ -3251,12 +3259,12 @@ namespace IEC61850
private bool InternalAcseAuthenticator(IntPtr parameter, IntPtr authParameter, IntPtr securityToken, IntPtr appReference) private bool InternalAcseAuthenticator(IntPtr parameter, IntPtr authParameter, IntPtr securityToken, IntPtr appReference)
{ {
if(acseAuthenticatorHandler != null && authParameter != IntPtr.Zero && appReference != IntPtr.Zero) if (acseAuthenticatorHandler != null && authParameter != IntPtr.Zero && appReference != IntPtr.Zero)
{ {
AcseAuthenticationParameter acseAuthenticationParameter = new AcseAuthenticationParameter(authParameter); AcseAuthenticationParameter acseAuthenticationParameter = new AcseAuthenticationParameter(authParameter);
IsoApplicationReference isoApplicationReference = new IsoApplicationReference(appReference); IsoApplicationReference isoApplicationReference = new IsoApplicationReference(appReference);
GCHandle token = GCHandle.FromIntPtr(securityToken); GCHandle token = GCHandle.FromIntPtr(securityToken);
return acseAuthenticatorHandler(acseAuthenticatorHandlerParameter, acseAuthenticationParameter, token as object, isoApplicationReference); return acseAuthenticatorHandler(acseAuthenticatorHandlerParameter, acseAuthenticationParameter, token, isoApplicationReference);
} }
return false; return false;
@ -3277,7 +3285,7 @@ namespace IEC61850
if (internalReadAccessHandler == null) if (internalReadAccessHandler == null)
{ {
internalReadAccessHandler = new IedServer_ReadAccessHandler (InternalReadHandlerImplementation); internalReadAccessHandler = new IedServer_ReadAccessHandler(InternalReadHandlerImplementation);
IedServer_setReadAccessHandler(self, internalReadAccessHandler, IntPtr.Zero); IedServer_setReadAccessHandler(self, internalReadAccessHandler, IntPtr.Zero);
} }
@ -3289,14 +3297,14 @@ namespace IEC61850
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld); ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld);
ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(ln); ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(ln);
ModelNode doModelNode = null; ModelNode doModelNode = null;
if(dataObject != IntPtr.Zero) if (dataObject != IntPtr.Zero)
doModelNode = iedModel.GetModelNodeFromNodeRef(dataObject); doModelNode = iedModel.GetModelNodeFromNodeRef(dataObject);
return readAccessHandler(ldModelNode as LogicalDevice, lnModelNode as LogicalNode, doModelNode as DataObject, (FunctionalConstraint)fc, con, readAccessHandlerParameter); return readAccessHandler(ldModelNode as LogicalDevice, lnModelNode as LogicalNode, doModelNode as DataObject, (FunctionalConstraint)fc, con, readAccessHandlerParameter);
} }
@ -3312,7 +3320,7 @@ namespace IEC61850
DIRECTORY_CAT_LOG_LIST DIRECTORY_CAT_LOG_LIST
} }
public delegate bool DirectoryAccessHandler(object parameter, ClientConnection connection, IedServer_DirectoryCategory category,LogicalDevice ld); public delegate bool DirectoryAccessHandler(object parameter, ClientConnection connection, IedServer_DirectoryCategory category, LogicalDevice ld);
private DirectoryAccessHandler directoryAccessHandler = null; private DirectoryAccessHandler directoryAccessHandler = null;
@ -3339,11 +3347,11 @@ namespace IEC61850
{ {
ClientConnection con = null; ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = null; ModelNode ldModelNode = null;
if(logicalDevice != IntPtr.Zero) if (logicalDevice != IntPtr.Zero)
ldModelNode = iedModel.GetModelNodeFromNodeRef(logicalDevice); ldModelNode = iedModel.GetModelNodeFromNodeRef(logicalDevice);
return directoryAccessHandler(directoryAccessHandlerParameter, con, (IedServer_DirectoryCategory)category, ldModelNode as LogicalDevice); return directoryAccessHandler(directoryAccessHandlerParameter, con, (IedServer_DirectoryCategory)category, ldModelNode as LogicalDevice);
@ -3353,33 +3361,37 @@ namespace IEC61850
} }
private Dictionary<IntPtr, WriteAccessHandlerInfo> writeAccessHandlers = new Dictionary<IntPtr, WriteAccessHandlerInfo> (); private Dictionary<IntPtr, WriteAccessHandlerInfo> writeAccessHandlers = new Dictionary<IntPtr, WriteAccessHandlerInfo>();
private void ConnectionIndicationHandlerImpl (IntPtr iedServer, IntPtr clientConnection, bool connected, IntPtr parameter) private void ConnectionIndicationHandlerImpl(IntPtr iedServer, IntPtr clientConnection, bool connected, IntPtr parameter)
{ {
if (connected == false) { if (connected == false)
{
ClientConnection con = null; ClientConnection con = null;
clientConnections.TryGetValue (clientConnection, out con); clientConnections.TryGetValue(clientConnection, out con);
if (con != null) { if (con != null)
{
if (connectionHandler != null) if (connectionHandler != null)
connectionHandler (this, con, false, connectionHandlerParameter); connectionHandler(this, con, false, connectionHandlerParameter);
clientConnections.Remove (clientConnection); clientConnections.Remove(clientConnection);
} }
} else { }
ClientConnection con = new ClientConnection (clientConnection); else
{
ClientConnection con = new ClientConnection(clientConnection);
clientConnections.Add (clientConnection, con); clientConnections.Add(clientConnection, con);
if (connectionHandler != null) if (connectionHandler != null)
connectionHandler (this, con, true, connectionHandlerParameter); connectionHandler(this, con, true, connectionHandlerParameter);
} }
} }
internal Dictionary<IntPtr, ClientConnection> clientConnections = new Dictionary<IntPtr, ClientConnection> (); internal Dictionary<IntPtr, ClientConnection> clientConnections = new Dictionary<IntPtr, ClientConnection>();
/* store IedModel instance to prevent garbage collector */ /* store IedModel instance to prevent garbage collector */
private IedModel iedModel = null; private IedModel iedModel = null;
@ -3396,13 +3408,13 @@ namespace IEC61850
if (config != null) if (config != null)
nativeConfig = config.self; nativeConfig = config.self;
self = IedServer_createWithConfig (iedModel.self, IntPtr.Zero, nativeConfig); self = IedServer_createWithConfig(iedModel.self, IntPtr.Zero, nativeConfig);
} }
public IedServer(IedModel iedModel, TLSConfiguration tlsConfig, IedServerConfig config = null) public IedServer(IedModel iedModel, TLSConfiguration tlsConfig, IedServerConfig config = null)
{ {
this.iedModel = iedModel; this.iedModel = iedModel;
this.tlsConfiguration = tlsConfig; tlsConfiguration = tlsConfig;
IntPtr nativeConfig = IntPtr.Zero; IntPtr nativeConfig = IntPtr.Zero;
IntPtr nativeTLSConfig = IntPtr.Zero; IntPtr nativeTLSConfig = IntPtr.Zero;
@ -3411,9 +3423,9 @@ namespace IEC61850
nativeConfig = config.self; nativeConfig = config.self;
if (tlsConfig != null) if (tlsConfig != null)
nativeTLSConfig = tlsConfig.GetNativeInstance (); nativeTLSConfig = tlsConfig.GetNativeInstance();
self = IedServer_createWithConfig (iedModel.self, nativeTLSConfig, nativeConfig); self = IedServer_createWithConfig(iedModel.self, nativeTLSConfig, nativeConfig);
} }
private InternalConnectionHandler internalConnectionHandler = null; private InternalConnectionHandler internalConnectionHandler = null;
@ -3424,7 +3436,7 @@ namespace IEC61850
/// <param name="localIpAddress">Local IP address.</param> /// <param name="localIpAddress">Local IP address.</param>
public void SetLocalIpAddress(string localIpAddress) public void SetLocalIpAddress(string localIpAddress)
{ {
IedServer_setLocalIpAddress (self, localIpAddress); IedServer_setLocalIpAddress(self, localIpAddress);
} }
/// <summary> /// <summary>
@ -3434,8 +3446,8 @@ namespace IEC61850
/// <param name="tcpPort">TCP port to use</param> /// <param name="tcpPort">TCP port to use</param>
public void Start(string localIpAddress, int tcpPort) public void Start(string localIpAddress, int tcpPort)
{ {
SetLocalIpAddress (localIpAddress); SetLocalIpAddress(localIpAddress);
Start (tcpPort); Start(tcpPort);
} }
/// <summary>Start MMS server</summary> /// <summary>Start MMS server</summary>
@ -3443,15 +3455,15 @@ namespace IEC61850
public void Start(int tcpPort) public void Start(int tcpPort)
{ {
if (internalConnectionHandler == null) if (internalConnectionHandler == null)
internalConnectionHandler = new InternalConnectionHandler (ConnectionIndicationHandlerImpl); internalConnectionHandler = new InternalConnectionHandler(ConnectionIndicationHandlerImpl);
IedServer_setConnectionIndicationHandler (self, internalConnectionHandler, IntPtr.Zero); IedServer_setConnectionIndicationHandler(self, internalConnectionHandler, IntPtr.Zero);
IedServer_start(self, tcpPort); IedServer_start(self, tcpPort);
} }
/// <summary>Start MMS server</summary> /// <summary>Start MMS server</summary>
public void Start () public void Start()
{ {
Start(-1); Start(-1);
} }
@ -3491,8 +3503,8 @@ namespace IEC61850
IedServer_destroy(self); IedServer_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
internalConnectionHandler = null; internalConnectionHandler = null;
this.iedModel = null; iedModel = null;
this.tlsConfiguration = null; tlsConfiguration = null;
} }
} }
} }
@ -3535,51 +3547,52 @@ namespace IEC61850
{ {
ControlHandlerInfo info; ControlHandlerInfo info;
controlHandlers.TryGetValue (controlObject, out info); controlHandlers.TryGetValue(controlObject, out info);
if (info == null) { if (info == null)
info = new ControlHandlerInfo (controlObject); {
controlHandlers.Add (controlObject, info); info = new ControlHandlerInfo(controlObject);
controlHandlers.Add(controlObject, info);
} }
return info; return info;
} }
public void SetControlHandler (DataObject controlObject, ControlHandler handler, object parameter) public void SetControlHandler(DataObject controlObject, ControlHandler handler, object parameter)
{ {
ControlHandlerInfo info = GetControlHandlerInfo (controlObject); ControlHandlerInfo info = GetControlHandlerInfo(controlObject);
info.controlHandler = handler; info.controlHandler = handler;
info.controlHandlerParameter = parameter; info.controlHandlerParameter = parameter;
if (internalControlHandlerRef == null) if (internalControlHandlerRef == null)
internalControlHandlerRef = new InternalControlHandler (InternalControlHandlerImpl); internalControlHandlerRef = new InternalControlHandler(InternalControlHandlerImpl);
IedServer_setControlHandler(self, controlObject.self, internalControlHandlerRef, GCHandle.ToIntPtr(info.handle)); IedServer_setControlHandler(self, controlObject.self, internalControlHandlerRef, GCHandle.ToIntPtr(info.handle));
} }
public void SetCheckHandler (DataObject controlObject, CheckHandler handler, object parameter) public void SetCheckHandler(DataObject controlObject, CheckHandler handler, object parameter)
{ {
ControlHandlerInfo info = GetControlHandlerInfo (controlObject); ControlHandlerInfo info = GetControlHandlerInfo(controlObject);
info.checkHandler = handler; info.checkHandler = handler;
info.checkHandlerParameter = parameter; info.checkHandlerParameter = parameter;
if (internalControlPerformCheckHandlerRef == null) if (internalControlPerformCheckHandlerRef == null)
internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler (InternalCheckHandlerImpl); internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler(InternalCheckHandlerImpl);
IedServer_setPerformCheckHandler(self, controlObject.self, internalControlPerformCheckHandlerRef, GCHandle.ToIntPtr(info.handle)); IedServer_setPerformCheckHandler(self, controlObject.self, internalControlPerformCheckHandlerRef, GCHandle.ToIntPtr(info.handle));
} }
public void SetWaitForExecutionHandler (DataObject controlObject, ControlWaitForExecutionHandler handler, object parameter) public void SetWaitForExecutionHandler(DataObject controlObject, ControlWaitForExecutionHandler handler, object parameter)
{ {
ControlHandlerInfo info = GetControlHandlerInfo (controlObject); ControlHandlerInfo info = GetControlHandlerInfo(controlObject);
info.waitForExecHandler = handler; info.waitForExecHandler = handler;
info.waitForExecHandlerParameter = parameter; info.waitForExecHandlerParameter = parameter;
if (internalControlWaitForExecutionHandlerRef == null) if (internalControlWaitForExecutionHandlerRef == null)
internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler (InternalControlWaitForExecutionHandlerImpl); internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler(InternalControlWaitForExecutionHandlerImpl);
IedServer_setWaitForExecutionHandler(self, controlObject.self, internalControlWaitForExecutionHandlerRef, GCHandle.ToIntPtr(info.handle)); IedServer_setWaitForExecutionHandler(self, controlObject.self, internalControlWaitForExecutionHandlerRef, GCHandle.ToIntPtr(info.handle));
} }
@ -3619,13 +3632,13 @@ namespace IEC61850
/// <param name="dataAttr">the data attribute to monitor</param> /// <param name="dataAttr">the data attribute to monitor</param>
/// <param name="handler">the callback function that is invoked if a client tries to write to the monitored data attribute.</param> /// <param name="handler">the callback function that is invoked if a client tries to write to the monitored data attribute.</param>
/// <param name="parameter">a user provided parameter that is passed to the WriteAccessHandler when called.</param> /// <param name="parameter">a user provided parameter that is passed to the WriteAccessHandler when called.</param>
public void HandleWriteAccess (DataAttribute dataAttr, WriteAccessHandler handler, object parameter) public void HandleWriteAccess(DataAttribute dataAttr, WriteAccessHandler handler, object parameter)
{ {
InternalWriteAccessHandler internalHandler = new InternalWriteAccessHandler(WriteAccessHandlerImpl); InternalWriteAccessHandler internalHandler = new InternalWriteAccessHandler(WriteAccessHandlerImpl);
writeAccessHandlers.Add (dataAttr.self, new WriteAccessHandlerInfo(handler, parameter, dataAttr, internalHandler)); writeAccessHandlers.Add(dataAttr.self, new WriteAccessHandlerInfo(handler, parameter, dataAttr, internalHandler));
IedServer_handleWriteAccess (self, dataAttr.self, internalHandler, IntPtr.Zero); IedServer_handleWriteAccess(self, dataAttr.self, internalHandler, IntPtr.Zero);
} }
private void AddHandlerInfoForDataAttributeRecursive(DataAttribute da, WriteAccessHandler handler, object parameter, InternalWriteAccessHandler internalHandler) private void AddHandlerInfoForDataAttributeRecursive(DataAttribute da, WriteAccessHandler handler, object parameter, InternalWriteAccessHandler internalHandler)
@ -3709,7 +3722,7 @@ namespace IEC61850
/// <param name="policy">The new default access policy</param> /// <param name="policy">The new default access policy</param>
public void SetWriteAccessPolicy(FunctionalConstraint fc, AccessPolicy policy) public void SetWriteAccessPolicy(FunctionalConstraint fc, AccessPolicy policy)
{ {
IedServer_setWriteAccessPolicy (self, fc, policy); IedServer_setWriteAccessPolicy(self, fc, policy);
} }
/// <summary> /// <summary>
@ -3743,7 +3756,7 @@ namespace IEC61850
public void UpdateAttributeValue(DataAttribute dataAttr, MmsValue value) public void UpdateAttributeValue(DataAttribute dataAttr, MmsValue value)
{ {
IedServer_updateAttributeValue (self, dataAttr.self, value.valueReference); IedServer_updateAttributeValue(self, dataAttr.self, value.valueReference);
} }
public void UpdateBooleanAttributeValue(DataAttribute dataAttr, bool value) public void UpdateBooleanAttributeValue(DataAttribute dataAttr, bool value)
@ -3763,7 +3776,7 @@ namespace IEC61850
public void UpdateInt64AttributeValue(DataAttribute dataAttr, Int64 value) public void UpdateInt64AttributeValue(DataAttribute dataAttr, Int64 value)
{ {
IedServer_updateInt64AttributeValue (self, dataAttr.self, value); IedServer_updateInt64AttributeValue(self, dataAttr.self, value);
} }
public void UpdateVisibleStringAttributeValue(DataAttribute dataAttr, string value) public void UpdateVisibleStringAttributeValue(DataAttribute dataAttr, string value)
@ -3784,7 +3797,7 @@ namespace IEC61850
public void UpdateTimestampAttributeValue(DataAttribute dataAttr, Timestamp timestamp) public void UpdateTimestampAttributeValue(DataAttribute dataAttr, Timestamp timestamp)
{ {
IedServer_updateTimestampAttributeValue (self, dataAttr.self, timestamp.self); IedServer_updateTimestampAttributeValue(self, dataAttr.self, timestamp.self);
} }
public void UpdateQuality(DataAttribute dataAttr, ushort value) public void UpdateQuality(DataAttribute dataAttr, ushort value)
@ -3794,10 +3807,10 @@ namespace IEC61850
public MmsValue GetAttributeValue(DataAttribute dataAttr) public MmsValue GetAttributeValue(DataAttribute dataAttr)
{ {
IntPtr mmsValuePtr = IedServer_getAttributeValue (self, dataAttr.self); IntPtr mmsValuePtr = IedServer_getAttributeValue(self, dataAttr.self);
if (mmsValuePtr != IntPtr.Zero) if (mmsValuePtr != IntPtr.Zero)
return new MmsValue (mmsValuePtr); return new MmsValue(mmsValuePtr);
else else
return null; return null;
} }
@ -3939,7 +3952,7 @@ namespace IEC61850
if (connection != IntPtr.Zero) if (connection != IntPtr.Zero)
{ {
this.clientConnections.TryGetValue(connection, out con); clientConnections.TryGetValue(connection, out con);
} }
ReportControlBlock reportControlBlock = null; ReportControlBlock reportControlBlock = null;

@ -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)
{ {

@ -374,8 +374,11 @@ namespace server_access_control
if (acseAuthenticationMechanism == IEC61850.AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD) if (acseAuthenticationMechanism == IEC61850.AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD)
{ {
int passwordLenght = authParameter.GetPasswordLenght(); byte[] passArray = authParameter.GetPasswordByteArray();
string password = authParameter.GetPassword(); int passwordLenght = passArray.Length;
string password = authParameter.GetPasswordString();
if (passwordLenght == passwords.First().Length) if (passwordLenght == passwords.First().Length)
{ {
if (password == passwords.First()) if (password == passwords.First())

@ -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();

@ -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.
* *

@ -57,6 +57,8 @@ 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* const char*
AcseAuthenticationParameter_getPassword(AcseAuthenticationParameter self) AcseAuthenticationParameter_getPassword(AcseAuthenticationParameter self)
{ {

@ -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