(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
*
* Copyright 2014 Michael Zillgith
* Copyright 2025-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -21,7 +21,6 @@
* See COPYING file for the complete license text.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
@ -81,7 +80,7 @@ namespace IEC61850
public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism)
{
AcseAuthenticationParameter_setAuthMechanism(self,(int)acseAuthenticationMechanism);
AcseAuthenticationParameter_setAuthMechanism(self, (int)acseAuthenticationMechanism);
}
public void SetPassword(string password)
@ -94,16 +93,39 @@ namespace IEC61850
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);
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
return null;
}
public int GetPasswordLenght()
{
return AcseAuthenticationParameter_getPasswordLength(self);
@ -122,7 +144,7 @@ namespace IEC61850
public IsoApplicationReference(IntPtr self)
{
this.self= self;
this.self = self;
}
public int GetAeQualifier()

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

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

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

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

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

@ -1,7 +1,7 @@
/*
* IEC61850ClientAPI.cs
*
* Copyright 2014-2023 Michael Zillgith
* Copyright 2014-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -20,14 +20,11 @@
*
* 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.TLS;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
@ -62,11 +59,11 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void MmsServerIdentity_destroy(IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
private static extern void MmsConnection_setLocalDetail (IntPtr self, Int32 localDetail);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void MmsConnection_setLocalDetail(IntPtr self, Int32 localDetail);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
private static extern Int32 MmsConnection_getLocalDetail (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 MmsConnection_getLocalDetail(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 MmsConnection_setRequestTimeout(IntPtr self, UInt32 timeoutInMs);
@ -106,11 +103,11 @@ namespace IEC61850
self = mmsConnection;
}
~MmsConnection ()
~MmsConnection()
{
if (selfDestroy)
if (self != IntPtr.Zero)
MmsConnection_destroy(self);
if (self != IntPtr.Zero)
MmsConnection_destroy(self);
}
private void FreeHGlobaleDeleteFunction(IntPtr pointer)
@ -140,7 +137,7 @@ namespace IEC61850
throw new IedConnectionException("Failed to read server identity");
MmsServerIdentity serverIdentity = (MmsServerIdentity)
Marshal.PtrToStructure(identity, typeof(MmsServerIdentity));
Marshal.PtrToStructure(identity, typeof(MmsServerIdentity));
MmsServerIdentity_destroy(identity);
@ -343,7 +340,7 @@ namespace IEC61850
}
}
~MmsJournalEntry ()
~MmsJournalEntry()
{
Dispose();
}
@ -356,7 +353,7 @@ namespace IEC61850
/// <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="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>
/// 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="err">Error code of response or timeout error in case of a response timeout</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>
/// 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="parameter">user provided callback parameter</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>
/// 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);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalConnectionClosedHandler(IntPtr parameter,IntPtr Iedconnection);
private delegate void InternalConnectionClosedHandler(IntPtr parameter, IntPtr Iedconnection);
/// <summary>
/// Called when the connection is closed
@ -552,7 +549,7 @@ namespace IEC61850
static extern int IedConnection_getState(IntPtr connection);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalStateChangedHandler(IntPtr parameter,IntPtr iedConnection,int newState);
private delegate void InternalStateChangedHandler(IntPtr parameter, IntPtr iedConnection, int newState);
/// <summary>
/// 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);
[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)]
static extern UInt32
@ -590,7 +587,7 @@ namespace IEC61850
IedConnection_ReadObjectHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -598,7 +595,7 @@ namespace IEC61850
IntPtr value, IedConnection_WriteObjectHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -616,7 +613,7 @@ namespace IEC61850
IedConnection_GetNameListHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -629,7 +626,7 @@ namespace IEC61850
IntPtr entryID, UInt64 timeStamp, IedConnection_QueryLogHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -663,7 +660,7 @@ namespace IEC61850
IedConnection_GetDataSetDirectoryHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -671,7 +668,7 @@ namespace IEC61850
IedConnection_GetRCBValuesHandler handler, IntPtr parameter);
[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)]
static extern UInt32
@ -680,7 +677,7 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
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);
@ -706,7 +703,7 @@ namespace IEC61850
static extern void LinkedList_destroyStatic(IntPtr self);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void LinkedListValueDeleteFunction(IntPtr pointer);
private delegate void LinkedListValueDeleteFunction(IntPtr pointer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void LinkedList_destroyDeep(IntPtr list, LinkedListValueDeleteFunction valueDeleteFunction);
@ -759,7 +756,7 @@ namespace IEC61850
}
}
~IedConnection ()
~IedConnection()
{
Dispose();
}
@ -1632,7 +1629,7 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[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)
{
@ -1658,7 +1655,7 @@ namespace IEC61850
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
{
@ -1720,7 +1717,7 @@ namespace IEC61850
{
int error;
IedConnection_setFile(connection, out error, sourceFilename, destinationFilename);
IedConnection_setFile(connection, out error, sourceFilename, destinationFilename);
if (error != 0)
throw new IedConnectionException("Error uploading file", error);
@ -1771,7 +1768,7 @@ namespace IEC61850
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)
{
@ -2338,7 +2335,7 @@ namespace IEC61850
/// <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="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;
@ -2417,7 +2414,7 @@ namespace IEC61850
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>
/// <param name="objectReference">The object reference of a DA or FCDO.</param>
@ -2473,7 +2470,7 @@ namespace IEC61850
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>
/// 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="parameter">user provided callback parameter</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;
@ -2563,11 +2560,11 @@ namespace IEC61850
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 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);
@ -2692,7 +2689,7 @@ namespace IEC61850
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;
@ -2936,17 +2933,17 @@ namespace IEC61850
public IedConnectionException(string message)
: base(message)
{
this.errorCode = 0;
errorCode = 0;
}
public int GetErrorCode()
{
return this.errorCode;
return errorCode;
}
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 System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
@ -45,7 +43,7 @@ namespace IEC61850
internal IntPtr Self { get => self; }
[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);
[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,
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;
}

@ -1,7 +1,7 @@
/*
* IEC61850ServerAPI.cs
*
* Copyright 2016-2024 Michael Zillgith
* Copyright 2016-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -25,10 +25,7 @@ using IEC61850.Model;
using IEC61850.TLS;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Runtime.InteropServices;
using System.Security.Principal;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
@ -46,12 +43,13 @@ namespace IEC61850
public static IedModel CreateModelFromConfigFile(string filePath)
{
IntPtr retVal = ConfigFileParser_createModelFromConfigFileEx (filePath);
if (retVal == IntPtr.Zero) {
IntPtr retVal = ConfigFileParser_createModelFromConfigFileEx(filePath);
if (retVal == IntPtr.Zero)
{
return null;
}
return new IedModel (retVal);
return new IedModel(retVal);
}
}
@ -286,7 +284,7 @@ namespace IEC61850
if (nodeRef == IntPtr.Zero)
return null;
return GetModelNodeFromNodeRef (nodeRef);
return GetModelNodeFromNodeRef(nodeRef);
}
/// <summary>
@ -301,7 +299,7 @@ namespace IEC61850
if (nodeRef == IntPtr.Zero)
return null;
return GetModelNodeFromNodeRef (nodeRef);
return GetModelNodeFromNodeRef(nodeRef);
}
public SVControlBlock GetSVControlBlock(LogicalNode logicalNode, string svcbName)
@ -332,9 +330,9 @@ namespace IEC61850
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>
@ -344,7 +342,7 @@ namespace IEC61850
/// <param name="parent">Model containing this logical device</param>
public LogicalDevice(string inst, IedModel parent)
{
this.IedModel = parent;
IedModel = parent;
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>
public LogicalDevice(string inst, IedModel parent, string ldName)
{
this.IedModel = parent;
IedModel = parent;
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>
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 new SettingGroupControlBlock(sgcb);
@ -387,7 +385,7 @@ namespace IEC61850
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;
}
@ -410,12 +408,14 @@ namespace IEC61850
}
}
public enum AccessPolicy {
public enum AccessPolicy
{
ACCESS_POLICY_ALLOW = 0,
ACCESS_POLICY_DENY = 1
}
public enum DataAttributeType {
public enum DataAttributeType
{
BOOLEAN = 0,
INT8 = 1,
INT16 = 2,
@ -596,7 +596,7 @@ namespace IEC61850
IntPtr self = CDC_SPS_create(name, parent.self, options);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -756,7 +756,7 @@ namespace IEC61850
IntPtr self = CDC_INS_create(name, parent.self, options);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -766,7 +766,7 @@ namespace IEC61850
IntPtr self = CDC_MV_create(name, parent.self, options, isIntegerNotFloat);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -776,7 +776,7 @@ namespace IEC61850
IntPtr self = CDC_INC_create(name, parent.self, options, controlOptions);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -786,7 +786,7 @@ namespace IEC61850
IntPtr self = CDC_LPL_create(name, parent.self, options);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -796,7 +796,7 @@ namespace IEC61850
IntPtr self = CDC_DPL_create(name, parent.self, options);
if (self != IntPtr.Zero)
return new DataObject (self, parent);
return new DataObject(self, parent);
else
return null;
}
@ -953,7 +953,7 @@ namespace IEC61850
{
this.parent = parent;
self = DataObject_create (name, parent.self, arrayElements);
self = DataObject_create(name, parent.self, arrayElements);
}
/// <summary>
@ -968,7 +968,7 @@ namespace IEC61850
public DataAttribute GetChildWithFc(string objRef, FunctionalConstraint fc)
{
DataAttribute dataAttribute = null;
IntPtr da = ModelNode_getChildWithFc(this.self, objRef, (int)fc);
IntPtr da = ModelNode_getChildWithFc(self, objRef, (int)fc);
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="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>
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)
{
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>
@ -1155,7 +1155,7 @@ namespace IEC61850
}
else
{
if (this.parent != null)
if (parent != null)
return parent.GetIedModel();
else
return null;
@ -1295,7 +1295,7 @@ namespace IEC61850
if (childNode == null)
{
childNode = ModelNode.CreateInstance(modelNodePtr, this);
childNode = ModelNode.CreateInstance(modelNodePtr, this);
if ((childNode != null) && (iedModel != null))
{
@ -1327,14 +1327,16 @@ namespace IEC61850
IntPtr objRefPtr = ModelNode_getObjectReferenceEx(self, nativeMemory, withoutIedName);
if (objRefPtr != IntPtr.Zero) {
if (objRefPtr != IntPtr.Zero)
{
string objRef = Marshal.PtrToStringAnsi(objRefPtr);
Marshal.FreeHGlobal(nativeMemory);
return objRef;
}
else {
else
{
Marshal.FreeHGlobal(nativeMemory);
return null;
@ -1741,12 +1743,12 @@ namespace IEC61850
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)
{
this.self = self ;
this.self = self;
}
}
@ -1795,7 +1797,7 @@ namespace IEC61850
if (token != IntPtr.Zero)
{
GCHandle handle = GCHandle.FromIntPtr(token);
return handle as object;
return handle;
}
}
}
@ -1865,7 +1867,7 @@ namespace IEC61850
}
}
~ClientConnection ()
~ClientConnection()
{
Dispose();
}
@ -1915,7 +1917,7 @@ namespace IEC61850
if (lnModelNode != null && lnModelNode is LogicalNode)
{
this.ln = lnModelNode as LogicalNode;
ln = lnModelNode as LogicalNode;
}
}
@ -1992,17 +1994,17 @@ namespace IEC61850
/// </summary>
public class ControlAction
{
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setAddCause (IntPtr self, int addCause);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setAddCause(IntPtr self, int addCause);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setError(IntPtr self, int error);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ControlAction_getOrCat (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ControlAction_getOrCat(IntPtr self);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getOrIdent (IntPtr self, ref int size);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getOrIdent(IntPtr self, ref int size);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getClientConnection(IntPtr self);
@ -2032,7 +2034,7 @@ namespace IEC61850
private IedServer.ControlHandlerInfo info;
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.info = info;
@ -2052,36 +2054,36 @@ namespace IEC61850
/// Sets the add cause for the next command termination or application error message
/// </summary>
/// <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>
/// Gets the originator category provided by the client
/// </summary>
/// <returns>The or cat.</returns>
public OrCat GetOrCat ()
public OrCat GetOrCat()
{
return (OrCat)ControlAction_getOrCat (self);
return (OrCat)ControlAction_getOrCat(self);
}
/// <summary>
/// Get the originator identifier provided by the client
/// </summary>
/// <returns>The or ident.</returns>
public byte [] GetOrIdent ()
public byte[] GetOrIdent()
{
int size = 0;
IntPtr orIdentPtr = ControlAction_getOrIdent (self, ref size);
IntPtr orIdentPtr = ControlAction_getOrIdent(self, ref size);
if (orIdentPtr == IntPtr.Zero)
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;
}
@ -2099,7 +2101,7 @@ namespace IEC61850
/// Gets the control object that is subject to this action
/// </summary>
/// <returns>the controllable data object instance</returns>
public DataObject GetControlObject ()
public DataObject GetControlObject()
{
return info.controlObject;
}
@ -2126,14 +2128,15 @@ namespace IEC61850
/// Gets the client object associated with the client that caused the control action
/// </summary>
/// <returns>The client connection.</returns>
public ClientConnection GetClientConnection ()
public ClientConnection GetClientConnection()
{
ClientConnection con = null;
IntPtr conPtr = ControlAction_getClientConnection (self);
IntPtr conPtr = ControlAction_getClientConnection(self);
if (conPtr != IntPtr.Zero) {
iedServer.clientConnections.TryGetValue (conPtr, out con);
if (conPtr != IntPtr.Zero)
{
iedServer.clientConnections.TryGetValue(conPtr, out 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 MmsDataAccessError WriteAccessHandler (DataAttribute dataAttr, MmsValue value,
public delegate MmsDataAccessError WriteAccessHandler(DataAttribute dataAttr, MmsValue value,
ClientConnection connection, object parameter);
/// <summary>
@ -2261,7 +2264,8 @@ namespace IEC61850
/// <summary>
/// Return type of ControlHandler and ControlWaitForExecutionHandler
/// </summary>
public enum ControlHandlerResult {
public enum ControlHandlerResult
{
/// <summary>
/// check or operation failed
/// </summary>
@ -2276,11 +2280,12 @@ namespace IEC61850
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>
/// check passed
/// </summary>
@ -2318,7 +2323,7 @@ namespace IEC61850
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
{
@ -2486,13 +2491,13 @@ namespace IEC61850
/// </summary>
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);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
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);
[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);
[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)]
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)]
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)]
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);
[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)]
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);
[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)]
static extern void IedServer_handleWriteAccess(IntPtr self, IntPtr dataAttribute,
@ -2804,7 +2809,7 @@ namespace IEC61850
}
[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)]
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
private Dictionary<string, LogStorage> logStorages = new Dictionary<string, LogStorage>();
internal class ControlHandlerInfo {
internal class ControlHandlerInfo
{
public DataObject controlObject = null;
public GCHandle handle;
@ -2868,57 +2874,58 @@ namespace IEC61850
public ControlHandlerInfo(DataObject controlObject)
{
this.controlObject = controlObject;
this.handle = GCHandle.Alloc(this);
handle = GCHandle.Alloc(this);
}
~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;
ControlAction controlAction = new ControlAction (action, info, this);
ControlAction controlAction = new ControlAction(action, info, this);
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
return (int)ControlHandlerResult.FAILED;
}
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;
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);
} else
return (int)info.checkHandler(controlAction, info.checkHandlerParameter, new MmsValue(ctlVal), test, interlockCheck);
}
else
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;
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
return (int)ControlHandlerResult.FAILED;
@ -2938,13 +2945,14 @@ namespace IEC61850
}
}
private struct WriteAccessHandlerInfo {
private struct WriteAccessHandlerInfo
{
public WriteAccessHandler handler;
public InternalWriteAccessHandler internalHandler;
public object parameter;
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;
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;
@ -2969,7 +2977,7 @@ namespace IEC61850
}
else
{
return (int) MmsDataAccessError.OBJECT_ACCESS_DENIED;
return (int)MmsDataAccessError.OBJECT_ACCESS_DENIED;
}
}
@ -2992,7 +3000,7 @@ namespace IEC61850
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld);
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)
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
return dataSetAccessHandler(dataSetAccessHandlerParameter, con, (DataSetOperation)operation, datasetRef);
}
@ -3070,7 +3078,7 @@ namespace IEC61850
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;
activeSettingGroupChangedHandlerParameter = parameter;
@ -3094,7 +3102,7 @@ namespace IEC61850
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
return activeSettingGroupChangedHandler(activeSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newActSg, con);
}
@ -3129,7 +3137,7 @@ namespace IEC61850
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
return editSettingGroupChangedHandler(editSettingGroupChangedHandlerParameter, new SettingGroupControlBlock(sgcb), newEditSg, con);
}
@ -3154,7 +3162,7 @@ namespace IEC61850
{
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)
{
this.sampledValuesControlBlock = sampledValuesControlBlock;
this.handle = GCHandle.Alloc(this);
handle = GCHandle.Alloc(this);
}
~SVCHandlerInfo()
{
this.handle.Free();
handle.Free();
}
}
@ -3240,9 +3248,9 @@ namespace IEC61850
public void SetAuthenticator(AcseAuthenticatorHandler acseAuthenticatorHandler, object acseAuthenticatorHandlerParameter)
{
this.acseAuthenticatorHandler = acseAuthenticatorHandler;
this.acseAuthenticatorHandlerParameter= acseAuthenticatorHandlerParameter;
this.acseAuthenticatorHandlerParameter = acseAuthenticatorHandlerParameter;
if(iedServer_AcseAuthenticator == null)
if (iedServer_AcseAuthenticator == null)
{
iedServer_AcseAuthenticator = new IedServer_AcseAuthenticator(InternalAcseAuthenticator);
IedServer_setAuthenticator(self, iedServer_AcseAuthenticator, IntPtr.Zero);
@ -3251,12 +3259,12 @@ namespace IEC61850
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);
IsoApplicationReference isoApplicationReference = new IsoApplicationReference(appReference);
GCHandle token = GCHandle.FromIntPtr(securityToken);
return acseAuthenticatorHandler(acseAuthenticatorHandlerParameter, acseAuthenticationParameter, token as object, isoApplicationReference);
return acseAuthenticatorHandler(acseAuthenticatorHandlerParameter, acseAuthenticationParameter, token, isoApplicationReference);
}
return false;
@ -3277,7 +3285,7 @@ namespace IEC61850
if (internalReadAccessHandler == null)
{
internalReadAccessHandler = new IedServer_ReadAccessHandler (InternalReadHandlerImplementation);
internalReadAccessHandler = new IedServer_ReadAccessHandler(InternalReadHandlerImplementation);
IedServer_setReadAccessHandler(self, internalReadAccessHandler, IntPtr.Zero);
}
@ -3289,14 +3297,14 @@ namespace IEC61850
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = iedModel.GetModelNodeFromNodeRef(ld);
ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(ln);
ModelNode doModelNode = null;
if(dataObject != IntPtr.Zero)
doModelNode = iedModel.GetModelNodeFromNodeRef(dataObject);
if (dataObject != IntPtr.Zero)
doModelNode = iedModel.GetModelNodeFromNodeRef(dataObject);
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
}
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;
@ -3339,11 +3347,11 @@ namespace IEC61850
{
ClientConnection con = null;
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
ModelNode ldModelNode = null;
if(logicalDevice != IntPtr.Zero)
if (logicalDevice != IntPtr.Zero)
ldModelNode = iedModel.GetModelNodeFromNodeRef(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;
clientConnections.TryGetValue (clientConnection, out con);
clientConnections.TryGetValue(clientConnection, out con);
if (con != null) {
if (con != 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)
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 */
private IedModel iedModel = null;
@ -3396,13 +3408,13 @@ namespace IEC61850
if (config != null)
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)
{
this.iedModel = iedModel;
this.tlsConfiguration = tlsConfig;
tlsConfiguration = tlsConfig;
IntPtr nativeConfig = IntPtr.Zero;
IntPtr nativeTLSConfig = IntPtr.Zero;
@ -3411,9 +3423,9 @@ namespace IEC61850
nativeConfig = config.self;
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;
@ -3424,7 +3436,7 @@ namespace IEC61850
/// <param name="localIpAddress">Local IP address.</param>
public void SetLocalIpAddress(string localIpAddress)
{
IedServer_setLocalIpAddress (self, localIpAddress);
IedServer_setLocalIpAddress(self, localIpAddress);
}
/// <summary>
@ -3434,8 +3446,8 @@ namespace IEC61850
/// <param name="tcpPort">TCP port to use</param>
public void Start(string localIpAddress, int tcpPort)
{
SetLocalIpAddress (localIpAddress);
Start (tcpPort);
SetLocalIpAddress(localIpAddress);
Start(tcpPort);
}
/// <summary>Start MMS server</summary>
@ -3443,15 +3455,15 @@ namespace IEC61850
public void Start(int tcpPort)
{
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);
}
/// <summary>Start MMS server</summary>
public void Start ()
public void Start()
{
Start(-1);
}
@ -3491,8 +3503,8 @@ namespace IEC61850
IedServer_destroy(self);
self = IntPtr.Zero;
internalConnectionHandler = null;
this.iedModel = null;
this.tlsConfiguration = null;
iedModel = null;
tlsConfiguration = null;
}
}
}
@ -3535,51 +3547,52 @@ namespace IEC61850
{
ControlHandlerInfo info;
controlHandlers.TryGetValue (controlObject, out info);
controlHandlers.TryGetValue(controlObject, out info);
if (info == null) {
info = new ControlHandlerInfo (controlObject);
controlHandlers.Add (controlObject, info);
if (info == null)
{
info = new ControlHandlerInfo(controlObject);
controlHandlers.Add(controlObject, 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.controlHandlerParameter = parameter;
if (internalControlHandlerRef == null)
internalControlHandlerRef = new InternalControlHandler (InternalControlHandlerImpl);
internalControlHandlerRef = new InternalControlHandler(InternalControlHandlerImpl);
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.checkHandlerParameter = parameter;
if (internalControlPerformCheckHandlerRef == null)
internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler (InternalCheckHandlerImpl);
internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler(InternalCheckHandlerImpl);
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.waitForExecHandlerParameter = parameter;
if (internalControlWaitForExecutionHandlerRef == null)
internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler (InternalControlWaitForExecutionHandlerImpl);
internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler(InternalControlWaitForExecutionHandlerImpl);
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="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>
public void HandleWriteAccess (DataAttribute dataAttr, WriteAccessHandler handler, object parameter)
public void HandleWriteAccess(DataAttribute dataAttr, WriteAccessHandler handler, object parameter)
{
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)
@ -3709,7 +3722,7 @@ namespace IEC61850
/// <param name="policy">The new default access policy</param>
public void SetWriteAccessPolicy(FunctionalConstraint fc, AccessPolicy policy)
{
IedServer_setWriteAccessPolicy (self, fc, policy);
IedServer_setWriteAccessPolicy(self, fc, policy);
}
/// <summary>
@ -3743,7 +3756,7 @@ namespace IEC61850
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)
@ -3763,7 +3776,7 @@ namespace IEC61850
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)
@ -3784,7 +3797,7 @@ namespace IEC61850
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)
@ -3794,10 +3807,10 @@ namespace IEC61850
public MmsValue GetAttributeValue(DataAttribute dataAttr)
{
IntPtr mmsValuePtr = IedServer_getAttributeValue (self, dataAttr.self);
IntPtr mmsValuePtr = IedServer_getAttributeValue(self, dataAttr.self);
if (mmsValuePtr != IntPtr.Zero)
return new MmsValue (mmsValuePtr);
return new MmsValue(mmsValuePtr);
else
return null;
}
@ -3939,7 +3952,7 @@ namespace IEC61850
if (connection != IntPtr.Zero)
{
this.clientConnections.TryGetValue(connection, out con);
clientConnections.TryGetValue(connection, out con);
}
ReportControlBlock reportControlBlock = null;

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

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

File diff suppressed because it is too large Load Diff

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

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

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

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

@ -1,7 +1,7 @@
/*
* SampledValuedSubscriber.cs
*
* Copyright 2017 Michael Zillgith
* Copyright 2017-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -21,454 +21,463 @@
* See COPYING file for the complete license text.
*/
using IEC61850.Common;
using System;
using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850
{
namespace SV
{
namespace Subscriber
{
/// <summary>
/// SV receiver.
/// </summary>
/// 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
/// instances.
public class SVReceiver : IDisposable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVReceiver_create ();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_disableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_enableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_addSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_removeSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_start(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_stop(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVReceiver_isRunning (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_setInterfaceId(IntPtr self, string interfaceId);
private IntPtr self;
private bool isDisposed = false;
/// <summary>
/// Initializes a new instance of the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> class.
/// </summary>
public SVReceiver()
{
self = SVReceiver_create ();
}
public void SetInterfaceId(string interfaceId)
{
SVReceiver_setInterfaceId (self, interfaceId);
}
public void DisableDestAddrCheck()
{
SVReceiver_disableDestAddrCheck (self);
}
public void EnableDestAddrCheck()
{
SVReceiver_enableDestAddrCheck (self);
}
/// <summary>
/// Add a subscriber to handle
/// </summary>
/// <param name="subscriber">Subscriber.</param>
public void AddSubscriber(SVSubscriber subscriber)
{
SVReceiver_addSubscriber (self, subscriber.self);
}
public void RemoveSubscriber(SVSubscriber subscriber)
{
SVReceiver_removeSubscriber (self, subscriber.self);
}
/// <summary>
/// Start handling SV messages
/// </summary>
public void Start()
{
SVReceiver_start (self);
}
/// <summary>
/// Stop handling SV messges
/// </summary>
public void Stop()
{
SVReceiver_stop (self);
}
public bool IsRunning()
{
return SVReceiver_isRunning (self);
}
/// <summary>
/// Releases all resource used by the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> object.
/// </summary>
/// <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.
/// 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"/> was occupying.</remarks>
public void Dispose()
{
if (isDisposed == false) {
isDisposed = true;
SVReceiver_destroy (self);
self = IntPtr.Zero;
}
}
~SVReceiver()
{
Dispose ();
}
}
/// <summary>
/// SV listener.
/// </summary>
public delegate void SVUpdateListener (SVSubscriber report, object parameter, SVSubscriberASDU asdu);
/// <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
/// that is part of each ASDU.
/// </summary>
public class SVSubscriber : IDisposable
{
[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(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_destroy(IntPtr self);
internal IntPtr self;
private bool isDisposed = false;
private SVUpdateListener listener;
private object listenerParameter = null;
private event InternalSVUpdateListener internalListener = null;
private void internalSVUpdateListener (IntPtr subscriber, IntPtr parameter, IntPtr asdu)
{
try {
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);
}
}
public SVSubscriber(byte[] ethAddr, UInt16 appID)
{
if (ethAddr == null) {
self = SVSubscriber_create (IntPtr.Zero, appID);
} else {
if (ethAddr.Length != 6)
throw new ArgumentException ("ethAddr argument has to be of 6 byte size");
self = SVSubscriber_create (ethAddr, appID);
}
}
public void SetListener(SVUpdateListener listener, object parameter)
{
this.listener = listener;
this.listenerParameter = parameter;
if (internalListener == null) {
internalListener = new InternalSVUpdateListener (internalSVUpdateListener);
SVSubscriber_setListener (self, internalListener, IntPtr.Zero);
}
}
public void Dispose()
{
if (isDisposed == false) {
isDisposed = true;
SVSubscriber_destroy (self);
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);
namespace SV
{
namespace Subscriber
{
/// <summary>
/// SV receiver.
/// </summary>
/// 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
/// instances.
public class SVReceiver : IDisposable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVReceiver_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_disableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_enableDestAddrCheck(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_addSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_removeSubscriber(IntPtr self, IntPtr subscriber);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_start(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_stop(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVReceiver_isRunning(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_setInterfaceId(IntPtr self, string interfaceId);
private IntPtr self;
private bool isDisposed = false;
/// <summary>
/// Initializes a new instance of the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> class.
/// </summary>
public SVReceiver()
{
self = SVReceiver_create();
}
public void SetInterfaceId(string interfaceId)
{
SVReceiver_setInterfaceId(self, interfaceId);
}
public void DisableDestAddrCheck()
{
SVReceiver_disableDestAddrCheck(self);
}
public void EnableDestAddrCheck()
{
SVReceiver_enableDestAddrCheck(self);
}
/// <summary>
/// Add a subscriber to handle
/// </summary>
/// <param name="subscriber">Subscriber.</param>
public void AddSubscriber(SVSubscriber subscriber)
{
SVReceiver_addSubscriber(self, subscriber.self);
}
public void RemoveSubscriber(SVSubscriber subscriber)
{
SVReceiver_removeSubscriber(self, subscriber.self);
}
/// <summary>
/// Start handling SV messages
/// </summary>
public void Start()
{
SVReceiver_start(self);
}
/// <summary>
/// Stop handling SV messges
/// </summary>
public void Stop()
{
SVReceiver_stop(self);
}
public bool IsRunning()
{
return SVReceiver_isRunning(self);
}
/// <summary>
/// Releases all resource used by the <see cref="IEC61850.SV.Subscriber.SVReceiver"/> object.
/// </summary>
/// <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.
/// 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"/> was occupying.</remarks>
public void Dispose()
{
if (isDisposed == false)
{
isDisposed = true;
SVReceiver_destroy(self);
self = IntPtr.Zero;
}
}
~SVReceiver()
{
Dispose();
}
}
/// <summary>
/// SV listener.
/// </summary>
public delegate void SVUpdateListener(SVSubscriber report, object parameter, SVSubscriberASDU asdu);
/// <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
/// that is part of each ASDU.
/// </summary>
public class SVSubscriber : IDisposable
{
[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(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_destroy(IntPtr self);
internal IntPtr self;
private bool isDisposed = false;
private SVUpdateListener listener;
private object listenerParameter = null;
private event InternalSVUpdateListener internalListener = null;
private void internalSVUpdateListener(IntPtr subscriber, IntPtr parameter, IntPtr asdu)
{
try
{
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);
}
}
public SVSubscriber(byte[] ethAddr, UInt16 appID)
{
if (ethAddr == null)
{
self = SVSubscriber_create(IntPtr.Zero, appID);
}
else
{
if (ethAddr.Length != 6)
throw new ArgumentException("ethAddr argument has to be of 6 byte size");
self = SVSubscriber_create(ethAddr, appID);
}
}
public void SetListener(SVUpdateListener listener, object parameter)
{
this.listener = listener;
listenerParameter = parameter;
if (internalListener == null)
{
internalListener = new InternalSVUpdateListener(internalSVUpdateListener);
SVSubscriber_setListener(self, internalListener, IntPtr.Zero);
}
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasSmpRate(IntPtr self);
public void Dispose()
{
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)]
private static extern sbyte SVSubscriber_ASDU_getINT8(IntPtr self, int index);
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 Int16 SVSubscriber_ASDU_getINT16(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_ASDU_getSvId(IntPtr 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 IntPtr SVSubscriber_ASDU_getDatSet(IntPtr self);
[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_getConfRev(IntPtr self);
[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 byte SVSubscriber_ASDU_getSmpMod(IntPtr self);
[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_getSmpRate(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt16 SVSubscriber_ASDU_getQuality(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasDatSet(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int SVSubscriber_ASDU_getDataSize(IntPtr self);
private IntPtr self;
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasRefrTm(IntPtr self);
internal SVSubscriberASDU (IntPtr self)
{
this.self = self;
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasSmpMod(IntPtr 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));
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVSubscriber_ASDU_hasSmpRate(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 SVSubscriber_ASDU_getRefrTmAsMs(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern sbyte SVSubscriber_ASDU_getINT8(IntPtr self, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern Int16 SVSubscriber_ASDU_getINT16(IntPtr self, int index);
[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()
{
return SVSubscriber_ASDU_getConfRev (self);
}
public SmpMod GetSmpMod()
{
return (SmpMod) SVSubscriber_ASDU_getSmpMod (self);
}
public UInt32 GetConfRev()
{
return SVSubscriber_ASDU_getConfRev(self);
}
public SmpMod GetSmpMod()
{
return (SmpMod)SVSubscriber_ASDU_getSmpMod(self);
}
public UInt16 GetSmpRate()
{
return (UInt16)SVSubscriber_ASDU_getSmpRate (self);
}
public bool HasDatSet()
{
return SVSubscriber_ASDU_hasDatSet (self);
}
public bool HasRefrRm()
{
return SVSubscriber_ASDU_hasRefrTm (self);
}
public bool HasSmpMod()
{
return SVSubscriber_ASDU_hasSmpMod (self);
}
public bool HasSmpRate()
{
return SVSubscriber_ASDU_hasSmpRate (self);
}
public UInt64 GetRefrTmAsMs()
{
return SVSubscriber_ASDU_getRefrTmAsMs (self);
}
public sbyte GetINT8(int index)
{
return SVSubscriber_ASDU_getINT8 (self, index);
}
public Int16 GetINT16(int index)
{
return SVSubscriber_ASDU_getINT16 (self, index);
}
public Int32 GetINT32(int index)
{
return SVSubscriber_ASDU_getINT32 (self, index);
}
public Int64 GetINT64(int index)
{
return SVSubscriber_ASDU_getINT64 (self, index);
}
public byte GetINT8U(int index)
{
return SVSubscriber_ASDU_getINT8U (self, index);
}
public UInt16 GetINT16U(int index)
{
return SVSubscriber_ASDU_getINT16U (self, index);
}
public UInt32 GetINT32U(int index)
{
return SVSubscriber_ASDU_getINT32U (self, index);
}
public UInt64 GetINT64U(int index)
{
return SVSubscriber_ASDU_getINT64U (self, index);
}
public float GetFLOAT32(int index)
{
return SVSubscriber_ASDU_getFLOAT32 (self, index);
}
public double GetFLOAT64(int index)
{
return SVSubscriber_ASDU_getFLOAT64 (self, index);
}
private struct PTimestamp
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)]
public byte[] val;
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern PTimestamp SVSubscriber_ASDU_getTimestamp(IntPtr self, int index);
public Timestamp GetTimestamp(int index)
{
PTimestamp retVal = SVSubscriber_ASDU_getTimestamp (self, index);
return new Timestamp (retVal.val);
}
public Quality GetQuality(int index)
{
UInt16 qValue = SVSubscriber_ASDU_getQuality (self, index);
return new Quality (qValue);
}
/// <summary>
/// Gets the size of the payload data in bytes. The payload comprises the data set data.
/// </summary>
/// <returns>The payload data size in byte</returns>
public int GetDataSize()
{
return SVSubscriber_ASDU_getDataSize (self);
}
}
}
}
public UInt16 GetSmpRate()
{
return SVSubscriber_ASDU_getSmpRate(self);
}
public bool HasDatSet()
{
return SVSubscriber_ASDU_hasDatSet(self);
}
public bool HasRefrRm()
{
return SVSubscriber_ASDU_hasRefrTm(self);
}
public bool HasSmpMod()
{
return SVSubscriber_ASDU_hasSmpMod(self);
}
public bool HasSmpRate()
{
return SVSubscriber_ASDU_hasSmpRate(self);
}
public UInt64 GetRefrTmAsMs()
{
return SVSubscriber_ASDU_getRefrTmAsMs(self);
}
public sbyte GetINT8(int index)
{
return SVSubscriber_ASDU_getINT8(self, index);
}
public Int16 GetINT16(int index)
{
return SVSubscriber_ASDU_getINT16(self, index);
}
public Int32 GetINT32(int index)
{
return SVSubscriber_ASDU_getINT32(self, index);
}
public Int64 GetINT64(int index)
{
return SVSubscriber_ASDU_getINT64(self, index);
}
public byte GetINT8U(int index)
{
return SVSubscriber_ASDU_getINT8U(self, index);
}
public UInt16 GetINT16U(int index)
{
return SVSubscriber_ASDU_getINT16U(self, index);
}
public UInt32 GetINT32U(int index)
{
return SVSubscriber_ASDU_getINT32U(self, index);
}
public UInt64 GetINT64U(int index)
{
return SVSubscriber_ASDU_getINT64U(self, index);
}
public float GetFLOAT32(int index)
{
return SVSubscriber_ASDU_getFLOAT32(self, index);
}
public double GetFLOAT64(int index)
{
return SVSubscriber_ASDU_getFLOAT64(self, index);
}
private struct PTimestamp
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)]
public byte[] val;
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern PTimestamp SVSubscriber_ASDU_getTimestamp(IntPtr self, int index);
public Timestamp GetTimestamp(int index)
{
PTimestamp retVal = SVSubscriber_ASDU_getTimestamp(self, index);
return new Timestamp(retVal.val);
}
public Quality GetQuality(int index)
{
UInt16 qValue = SVSubscriber_ASDU_getQuality(self, index);
return new Quality(qValue);
}
/// <summary>
/// Gets the size of the payload data in bytes. The payload comprises the data set data.
/// </summary>
/// <returns>The payload data size in byte</returns>
public int GetDataSize()
{
return SVSubscriber_ASDU_getDataSize(self);
}
}
}
}
}

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

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

@ -60,7 +60,7 @@ main(int argc, char** argv)
IsoConnectionParameters_setRemoteAddresses(parameters, remotePSelector, remoteSSelector, localTSelector);
IsoConnectionParameters_setLocalAddresses(parameters, localPSelector, localSSelector, remoteTSelector);
char* password = "top secret";
char* password = "user1@testpw";
/* use authentication */
AcseAuthenticationParameter auth = AcseAuthenticationParameter_create();

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

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

@ -57,6 +57,8 @@ AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char*
self->value.password.passwordLength = strlen(password);
}
/* TODO
->One function returning as string and another as by array*/
const char*
AcseAuthenticationParameter_getPassword(AcseAuthenticationParameter self)
{

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

Loading…
Cancel
Save