(LIB61850-513)

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

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

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

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

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

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

@ -1,7 +1,7 @@
/* /*
* GooseSubscriber.cs * GooseSubscriber.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,10 +21,10 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
@ -37,12 +37,12 @@ namespace IEC61850
/// <summary> /// <summary>
/// GOOSE listener. /// GOOSE listener.
/// </summary> /// </summary>
public delegate void GooseListener (GooseSubscriber report, object parameter); public delegate void GooseListener(GooseSubscriber report, object parameter);
public class GooseReceiver : IDisposable public class GooseReceiver : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseReceiver_create (); private static extern IntPtr GooseReceiver_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_addSubscriber(IntPtr self, IntPtr subscriber); private static extern void GooseReceiver_addSubscriber(IntPtr self, IntPtr subscriber);
@ -58,7 +58,7 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseReceiver_isRunning (IntPtr self); private static extern bool GooseReceiver_isRunning(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseReceiver_destroy(IntPtr self); private static extern void GooseReceiver_destroy(IntPtr self);
@ -74,12 +74,12 @@ namespace IEC61850
public GooseReceiver() public GooseReceiver()
{ {
self = GooseReceiver_create (); self = GooseReceiver_create();
} }
public void SetInterfaceId(string interfaceId) public void SetInterfaceId(string interfaceId)
{ {
GooseReceiver_setInterfaceId (self, interfaceId); GooseReceiver_setInterfaceId(self, interfaceId);
} }
/// <summary> /// <summary>
@ -109,31 +109,32 @@ namespace IEC61850
public void Start() public void Start()
{ {
GooseReceiver_start (self); GooseReceiver_start(self);
} }
public void Stop() public void Stop()
{ {
GooseReceiver_stop (self); GooseReceiver_stop(self);
} }
public bool IsRunning() public bool IsRunning()
{ {
return GooseReceiver_isRunning (self); return GooseReceiver_isRunning(self);
} }
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
{
isDisposed = true; isDisposed = true;
GooseReceiver_destroy (self); GooseReceiver_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
} }
} }
~GooseReceiver() ~GooseReceiver()
{ {
Dispose (); Dispose();
} }
} }
@ -149,40 +150,40 @@ namespace IEC61850
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalGooseListener (IntPtr subscriber, IntPtr parameter); private delegate void InternalGooseListener(IntPtr subscriber, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_create (string goCbRef, IntPtr dataSetValue); private static extern IntPtr GooseSubscriber_create(string goCbRef, IntPtr dataSetValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setAppId(IntPtr self, UInt16 appId); private static extern void GooseSubscriber_setAppId(IntPtr self, UInt16 appId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isValid (IntPtr self); private static extern bool GooseSubscriber_isValid(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getStNum (IntPtr self); private static extern UInt32 GooseSubscriber_getStNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getSqNum (IntPtr self); private static extern UInt32 GooseSubscriber_getSqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_isTest (IntPtr self); private static extern bool GooseSubscriber_isTest(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getConfRev (IntPtr self); private static extern UInt32 GooseSubscriber_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool GooseSubscriber_needsCommission (IntPtr self); private static extern bool GooseSubscriber_needsCommission(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 GooseSubscriber_getTimeAllowedToLive (IntPtr self); private static extern UInt32 GooseSubscriber_getTimeAllowedToLive(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern UInt64 GooseSubscriber_getTimestamp (IntPtr self); private static extern UInt64 GooseSubscriber_getTimestamp(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getDataSetValues(IntPtr self); private static extern IntPtr GooseSubscriber_getDataSetValues(IntPtr self);
@ -191,7 +192,7 @@ namespace IEC61850
private static extern void GooseSubscriber_destroy(IntPtr self); private static extern void GooseSubscriber_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void GooseSubscriber_setListener (IntPtr self, InternalGooseListener listener, IntPtr parameter); private static extern void GooseSubscriber_setListener(IntPtr self, InternalGooseListener listener, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GooseSubscriber_getGoId(IntPtr self); private static extern IntPtr GooseSubscriber_getGoId(IntPtr self);
@ -214,15 +215,18 @@ namespace IEC61850
private event InternalGooseListener internalListener = null; private event InternalGooseListener internalListener = null;
private void internalGooseListener (IntPtr subscriber, IntPtr parameter) private void internalGooseListener(IntPtr subscriber, IntPtr parameter)
{
try
{ {
try {
if (listener != null) { if (listener != null)
{
listener(this, listenerParameter); listener(this, listenerParameter);
} }
} catch (Exception e) }
catch (Exception e)
{ {
// older versions of mono 2.10 (for linux?) cause this exception // older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
@ -231,28 +235,29 @@ namespace IEC61850
public GooseSubscriber(string goCbRef) public GooseSubscriber(string goCbRef)
{ {
self = GooseSubscriber_create (goCbRef, IntPtr.Zero); self = GooseSubscriber_create(goCbRef, IntPtr.Zero);
} }
public void SetAppId(UInt16 appId) public void SetAppId(UInt16 appId)
{ {
GooseSubscriber_setAppId (self, appId); GooseSubscriber_setAppId(self, appId);
} }
public bool IsValid () public bool IsValid()
{ {
return GooseSubscriber_isValid (self); return GooseSubscriber_isValid(self);
} }
public void SetListener(GooseListener listener, object parameter) public void SetListener(GooseListener listener, object parameter)
{ {
this.listener = listener; this.listener = listener;
this.listenerParameter = parameter; listenerParameter = parameter;
if (internalListener == null) { if (internalListener == null)
internalListener = new InternalGooseListener (internalGooseListener); {
internalListener = new InternalGooseListener(internalGooseListener);
GooseSubscriber_setListener (self, internalListener, IntPtr.Zero); GooseSubscriber_setListener(self, internalListener, IntPtr.Zero);
} }
} }
@ -273,46 +278,46 @@ namespace IEC61850
public UInt32 GetStNum() public UInt32 GetStNum()
{ {
return GooseSubscriber_getStNum (self); return GooseSubscriber_getStNum(self);
} }
public UInt32 GetSqNum() public UInt32 GetSqNum()
{ {
return GooseSubscriber_getSqNum (self); return GooseSubscriber_getSqNum(self);
} }
public bool IsTest() public bool IsTest()
{ {
return GooseSubscriber_isTest (self); return GooseSubscriber_isTest(self);
} }
public UInt32 GetConfRev() public UInt32 GetConfRev()
{ {
return GooseSubscriber_getConfRev (self); return GooseSubscriber_getConfRev(self);
} }
public bool NeedsCommission() public bool NeedsCommission()
{ {
return GooseSubscriber_needsCommission (self); return GooseSubscriber_needsCommission(self);
} }
public UInt32 GetTimeAllowedToLive() public UInt32 GetTimeAllowedToLive()
{ {
return GooseSubscriber_getTimeAllowedToLive (self); return GooseSubscriber_getTimeAllowedToLive(self);
} }
public UInt64 GetTimestamp () public UInt64 GetTimestamp()
{ {
return GooseSubscriber_getTimestamp (self); return GooseSubscriber_getTimestamp(self);
} }
public DateTimeOffset GetTimestampsDateTimeOffset () public DateTimeOffset GetTimestampsDateTimeOffset()
{ {
UInt64 entryTime = GetTimestamp (); UInt64 entryTime = GetTimestamp();
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero); DateTimeOffset retVal = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (entryTime); return retVal.AddMilliseconds(entryTime);
} }
/// <summary> /// <summary>
@ -325,9 +330,9 @@ namespace IEC61850
/// <returns>The data set values.</returns> /// <returns>The data set values.</returns>
public MmsValue GetDataSetValues() public MmsValue GetDataSetValues()
{ {
IntPtr mmsValueRef = GooseSubscriber_getDataSetValues (self); IntPtr mmsValueRef = GooseSubscriber_getDataSetValues(self);
return (new MmsValue (mmsValueRef)); return (new MmsValue(mmsValueRef));
} }
/// <summary> /// <summary>
@ -342,11 +347,12 @@ namespace IEC61850
/// </remarks> /// </remarks>
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
{
isDisposed = true; isDisposed = true;
if (attachedToReceiver == false) if (attachedToReceiver == false)
GooseSubscriber_destroy (self); GooseSubscriber_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
} }

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

@ -1,7 +1,7 @@
/* /*
* IEC61850CommonAPI.cs * IEC61850CommonAPI.cs
* *
* Copyright 2014-2024 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -47,7 +47,7 @@ namespace IEC61850
/// <returns>The version string in format MAJOR.MINOR.PATCH</returns> /// <returns>The version string in format MAJOR.MINOR.PATCH</returns>
public static string GetVersionString() public static string GetVersionString()
{ {
return Marshal.PtrToStringAnsi (LibIEC61850_getVersionString ()); return Marshal.PtrToStringAnsi(LibIEC61850_getVersionString());
} }
/// <summary> /// <summary>
@ -62,8 +62,8 @@ namespace IEC61850
ulong seconds = msTime / 1000; ulong seconds = msTime / 1000;
ulong millies = msTime % 1000; ulong millies = msTime % 1000;
dateTime.AddSeconds ((double) seconds); dateTime.AddSeconds(seconds);
dateTime.AddMilliseconds((double) millies); dateTime.AddMilliseconds(millies);
return dateTime; return dateTime;
} }
@ -75,7 +75,7 @@ namespace IEC61850
/// <param name="msTime">The DateTime object to convert</param> /// <param name="msTime">The DateTime object to convert</param>
public static ulong DateTimeToMsTimestamp(DateTime dateTime) public static ulong DateTimeToMsTimestamp(DateTime dateTime)
{ {
return (ulong) (dateTime.ToUniversalTime ().Subtract (new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds); return (ulong)(dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds);
} }
} }
@ -86,14 +86,15 @@ namespace IEC61850
public UInt16 vlanId; public UInt16 vlanId;
public UInt16 appId; public UInt16 appId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] dstAddress = new byte[6]; public byte[] dstAddress = new byte[6];
} }
/// <summary> /// <summary>
/// MMS data access error for MmsValue type MMS_DATA_ACCESS_ERROR /// MMS data access error for MmsValue type MMS_DATA_ACCESS_ERROR
/// </summary> /// </summary>
public enum MmsDataAccessError { public enum MmsDataAccessError
{
NO_RESPONSE = -2, /* for server internal purposes only! */ NO_RESPONSE = -2, /* for server internal purposes only! */
SUCCESS = -1, SUCCESS = -1,
OBJECT_INVALIDATED = 0, OBJECT_INVALIDATED = 0,
@ -112,7 +113,8 @@ namespace IEC61850
} }
[Flags] [Flags]
public enum TriggerOptions { public enum TriggerOptions
{
NONE = 0, NONE = 0,
/** send report when value of data changed */ /** send report when value of data changed */
DATA_CHANGED = 1, DATA_CHANGED = 1,
@ -131,7 +133,8 @@ namespace IEC61850
/// <summary> /// <summary>
/// SmpMod values /// SmpMod values
/// </summary> /// </summary>
public enum SmpMod { public enum SmpMod
{
SAMPLES_PER_PERIOD = 0, SAMPLES_PER_PERIOD = 0,
SAMPLES_PER_SECOND = 1, SAMPLES_PER_SECOND = 1,
SECONDS_PER_SAMPLE = 2 SECONDS_PER_SAMPLE = 2
@ -141,7 +144,8 @@ namespace IEC61850
/// Values for Sampled Values (SV) OptFlds /// Values for Sampled Values (SV) OptFlds
/// </summary> /// </summary>
[Flags] [Flags]
public enum SVOptions { public enum SVOptions
{
NONE = 0, NONE = 0,
REFRESH_TIME = 1, REFRESH_TIME = 1,
SAMPLE_SYNC = 2, SAMPLE_SYNC = 2,
@ -152,7 +156,8 @@ namespace IEC61850
} }
[Flags] [Flags]
public enum ReportOptions { public enum ReportOptions
{
NONE = 0, NONE = 0,
SEQ_NUM = 1, SEQ_NUM = 1,
TIME_STAMP = 2, TIME_STAMP = 2,
@ -197,30 +202,30 @@ namespace IEC61850
public ushort Value => value; public ushort Value => value;
public override string ToString () public override string ToString()
{ {
return GetValidity ().ToString (); return GetValidity().ToString();
} }
public Quality (int bitStringValue) public Quality(int bitStringValue)
{ {
value = (UInt16)bitStringValue; value = (UInt16)bitStringValue;
} }
public Quality () public Quality()
{ {
value = 0; value = 0;
} }
public Validity GetValidity () public Validity GetValidity()
{ {
int qualityVal = value & 0x3; int qualityVal = value & 0x3;
return (Validity)qualityVal; return (Validity)qualityVal;
} }
public void SetValidity (Validity validity) public void SetValidity(Validity validity)
{ {
value = (UInt16)(value & 0xfffc); value = (UInt16)(value & 0xfffc);
@ -229,139 +234,151 @@ namespace IEC61850
public Validity Validity public Validity Validity
{ {
get {return GetValidity ();} get { return GetValidity(); }
set { SetValidity (value); } set { SetValidity(value); }
} }
public bool Overflow public bool Overflow
{ {
get { return ((this.value & QUALITY_DETAIL_OVERFLOW) != 0);} get { return ((value & QUALITY_DETAIL_OVERFLOW) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_OVERFLOW; this.value |= QUALITY_DETAIL_OVERFLOW;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_OVERFLOW)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_OVERFLOW));
} }
} }
public bool OutOfRange public bool OutOfRange
{ {
get { return ((this.value & QUALITY_DETAIL_OUT_OF_RANGE) != 0);} get { return ((value & QUALITY_DETAIL_OUT_OF_RANGE) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_OUT_OF_RANGE; this.value |= QUALITY_DETAIL_OUT_OF_RANGE;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_OUT_OF_RANGE)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_OUT_OF_RANGE));
} }
} }
public bool BadReference public bool BadReference
{ {
get { return ((this.value & QUALITY_DETAIL_BAD_REFERENCE) != 0);} get { return ((value & QUALITY_DETAIL_BAD_REFERENCE) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_BAD_REFERENCE; this.value |= QUALITY_DETAIL_BAD_REFERENCE;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_BAD_REFERENCE)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_BAD_REFERENCE));
} }
} }
public bool Oscillatory public bool Oscillatory
{ {
get { return ((this.value & QUALITY_DETAIL_OSCILLATORY) != 0);} get { return ((value & QUALITY_DETAIL_OSCILLATORY) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_OSCILLATORY; this.value |= QUALITY_DETAIL_OSCILLATORY;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_OSCILLATORY)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_OSCILLATORY));
} }
} }
public bool Failure public bool Failure
{ {
get { return ((this.value & QUALITY_DETAIL_FAILURE) != 0);} get { return ((value & QUALITY_DETAIL_FAILURE) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_FAILURE; this.value |= QUALITY_DETAIL_FAILURE;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_FAILURE)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_FAILURE));
} }
} }
public bool OldData public bool OldData
{ {
get { return ((this.value & QUALITY_DETAIL_OLD_DATA) != 0);} get { return ((value & QUALITY_DETAIL_OLD_DATA) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_OLD_DATA; this.value |= QUALITY_DETAIL_OLD_DATA;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_OLD_DATA)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_OLD_DATA));
} }
} }
public bool Inconsistent public bool Inconsistent
{ {
get { return ((this.value & QUALITY_DETAIL_INCONSISTENT) != 0);} get { return ((value & QUALITY_DETAIL_INCONSISTENT) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_INCONSISTENT; this.value |= QUALITY_DETAIL_INCONSISTENT;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_INCONSISTENT)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_INCONSISTENT));
} }
} }
public bool Inaccurate public bool Inaccurate
{ {
get { return ((this.value & QUALITY_DETAIL_INACCURATE) != 0);} get { return ((value & QUALITY_DETAIL_INACCURATE) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DETAIL_INACCURATE; this.value |= QUALITY_DETAIL_INACCURATE;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DETAIL_INACCURATE)); this.value = (ushort)(this.value & (~QUALITY_DETAIL_INACCURATE));
} }
} }
public bool Substituted public bool Substituted
{ {
get { return ((this.value & QUALITY_SOURCE_SUBSTITUTED) != 0);} get { return ((value & QUALITY_SOURCE_SUBSTITUTED) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_SOURCE_SUBSTITUTED; this.value |= QUALITY_SOURCE_SUBSTITUTED;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_SOURCE_SUBSTITUTED)); this.value = (ushort)(this.value & (~QUALITY_SOURCE_SUBSTITUTED));
} }
} }
public bool Test public bool Test
{ {
get { return ((this.value & QUALITY_TEST) != 0);} get { return ((value & QUALITY_TEST) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_TEST; this.value |= QUALITY_TEST;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_TEST)); this.value = (ushort)(this.value & (~QUALITY_TEST));
} }
} }
public bool OperatorBlocked public bool OperatorBlocked
{ {
get { return ((this.value & QUALITY_OPERATOR_BLOCKED) != 0);} get { return ((value & QUALITY_OPERATOR_BLOCKED) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_OPERATOR_BLOCKED; this.value |= QUALITY_OPERATOR_BLOCKED;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_OPERATOR_BLOCKED)); this.value = (ushort)(this.value & (~QUALITY_OPERATOR_BLOCKED));
} }
} }
public bool Derived public bool Derived
{ {
get { return ((this.value & QUALITY_DERIVED) != 0); } get { return ((value & QUALITY_DERIVED) != 0); }
set { set
{
if (value) if (value)
this.value |= QUALITY_DERIVED; this.value |= QUALITY_DERIVED;
else else
this.value = (ushort) ((int) this.value & (~QUALITY_DERIVED)); this.value = (ushort)(this.value & (~QUALITY_DERIVED));
} }
} }
} }
@ -372,59 +389,59 @@ namespace IEC61850
public class Timestamp public class Timestamp
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr Timestamp_create (); static extern IntPtr Timestamp_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr Timestamp_createFromByteArray(byte[] byteArry); static extern IntPtr Timestamp_createFromByteArray(byte[] byteArry);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_destroy (IntPtr self); static extern void Timestamp_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_clearFlags (IntPtr self); static extern void Timestamp_clearFlags(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool Timestamp_isLeapSecondKnown (IntPtr self); static extern bool Timestamp_isLeapSecondKnown(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setLeapSecondKnown (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern void Timestamp_setLeapSecondKnown(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool Timestamp_hasClockFailure (IntPtr self); static extern bool Timestamp_hasClockFailure(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setClockFailure (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern void Timestamp_setClockFailure(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool Timestamp_isClockNotSynchronized (IntPtr self); static extern bool Timestamp_isClockNotSynchronized(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setClockNotSynchronized (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern void Timestamp_setClockNotSynchronized(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int Timestamp_getSubsecondPrecision (IntPtr self); static extern int Timestamp_getSubsecondPrecision(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setSubsecondPrecision(IntPtr self, int subsecondPrecision); static extern void Timestamp_setSubsecondPrecision(IntPtr self, int subsecondPrecision);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setTimeInSeconds (IntPtr self, UInt32 secondsSinceEpoch); static extern void Timestamp_setTimeInSeconds(IntPtr self, UInt32 secondsSinceEpoch);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setTimeInMilliseconds (IntPtr self, UInt64 millisSinceEpoch); static extern void Timestamp_setTimeInMilliseconds(IntPtr self, UInt64 millisSinceEpoch);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 Timestamp_getTimeInSeconds (IntPtr self); static extern UInt32 Timestamp_getTimeInSeconds(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 Timestamp_getTimeInMs (IntPtr self); static extern UInt64 Timestamp_getTimeInMs(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void Timestamp_setByMmsUtcTime (IntPtr self, IntPtr mmsValue); static extern void Timestamp_setByMmsUtcTime(IntPtr self, IntPtr mmsValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 Timestamp_getFractionOfSecondPart(IntPtr self); static extern UInt32 Timestamp_getFractionOfSecondPart(IntPtr self);
@ -440,18 +457,18 @@ namespace IEC61850
internal Timestamp(IntPtr timestampRef, bool selfAllocated) internal Timestamp(IntPtr timestampRef, bool selfAllocated)
{ {
this.self = timestampRef; self = timestampRef;
this.responsibleForDeletion = selfAllocated; responsibleForDeletion = selfAllocated;
} }
public Timestamp (DateTime timestamp) : this () public Timestamp(DateTime timestamp) : this()
{ {
SetDateTime (timestamp); SetDateTime(timestamp);
} }
public Timestamp (MmsValue mmsUtcTime) : this() public Timestamp(MmsValue mmsUtcTime) : this()
{ {
SetByMmsUtcTime (mmsUtcTime); SetByMmsUtcTime(mmsUtcTime);
} }
/// <summary> /// <summary>
@ -459,7 +476,7 @@ namespace IEC61850
/// </summary> /// </summary>
public Timestamp() public Timestamp()
{ {
self = Timestamp_create (); self = Timestamp_create();
LeapSecondKnown = true; LeapSecondKnown = true;
responsibleForDeletion = true; responsibleForDeletion = true;
} }
@ -469,9 +486,9 @@ namespace IEC61850
/// </summary> /// </summary>
public Timestamp(Timestamp other) : this() public Timestamp(Timestamp other) : this()
{ {
SetTimeInSeconds (other.GetTimeInSeconds ()); SetTimeInSeconds(other.GetTimeInSeconds());
SetSubsecondPrecision (other.GetSubsecondPrecision ()); SetSubsecondPrecision(other.GetSubsecondPrecision());
SetFractionOfSecondPart (other.GetFractionOfSecondPart ()); SetFractionOfSecondPart(other.GetFractionOfSecondPart());
SetLeapSecondKnow(other.IsLeapSecondKnown()); SetLeapSecondKnow(other.IsLeapSecondKnown());
SetClockFailure(other.HasClockFailure()); SetClockFailure(other.HasClockFailure());
SetClockNotSynchronized(other.IsClockNotSynchronized()); SetClockNotSynchronized(other.IsClockNotSynchronized());
@ -479,19 +496,19 @@ namespace IEC61850
public Timestamp(byte[] value) public Timestamp(byte[] value)
{ {
self = Timestamp_createFromByteArray (value); self = Timestamp_createFromByteArray(value);
responsibleForDeletion = true; responsibleForDeletion = true;
} }
~Timestamp () ~Timestamp()
{ {
if (responsibleForDeletion) if (responsibleForDeletion)
Timestamp_destroy (self); Timestamp_destroy(self);
} }
public void ClearFlags() public void ClearFlags()
{ {
Timestamp_clearFlags (self); Timestamp_clearFlags(self);
} }
public void SetDateTime(DateTime timestamp) public void SetDateTime(DateTime timestamp)
@ -502,104 +519,115 @@ namespace IEC61850
TimeSpan timeDiff = timestampUTC - epoch; TimeSpan timeDiff = timestampUTC - epoch;
ulong timeVal = Convert.ToUInt64(timeDiff.TotalMilliseconds); ulong timeVal = Convert.ToUInt64(timeDiff.TotalMilliseconds);
SetTimeInMilliseconds (timeVal); SetTimeInMilliseconds(timeVal);
} }
public bool LeapSecondKnown { public bool LeapSecondKnown
get { return IsLeapSecondKnown ();} {
set { SetLeapSecondKnow (value);} get { return IsLeapSecondKnown(); }
set { SetLeapSecondKnow(value); }
} }
public bool IsLeapSecondKnown() public bool IsLeapSecondKnown()
{ {
return Timestamp_isLeapSecondKnown (self); return Timestamp_isLeapSecondKnown(self);
} }
public void SetLeapSecondKnow(bool value) public void SetLeapSecondKnow(bool value)
{ {
Timestamp_setLeapSecondKnown (self, value); Timestamp_setLeapSecondKnown(self, value);
} }
public bool ClockFailure { public bool ClockFailure
get { return HasClockFailure ();} {
set { SetClockFailure (value);} get { return HasClockFailure(); }
set { SetClockFailure(value); }
} }
public bool HasClockFailure() public bool HasClockFailure()
{ {
return Timestamp_hasClockFailure (self); return Timestamp_hasClockFailure(self);
} }
public void SetClockFailure(bool value) public void SetClockFailure(bool value)
{ {
Timestamp_setClockFailure (self, value); Timestamp_setClockFailure(self, value);
} }
public bool ClockNotSynchronized { public bool ClockNotSynchronized
get { return IsClockNotSynchronized (); } {
set { SetClockNotSynchronized (value); } get { return IsClockNotSynchronized(); }
set { SetClockNotSynchronized(value); }
} }
public bool IsClockNotSynchronized() { public bool IsClockNotSynchronized()
{
return Timestamp_isClockNotSynchronized(self); return Timestamp_isClockNotSynchronized(self);
} }
public void SetClockNotSynchronized(bool value) { public void SetClockNotSynchronized(bool value)
Timestamp_setClockNotSynchronized (self, value); {
Timestamp_setClockNotSynchronized(self, value);
} }
public int SubsecondPrecision { public int SubsecondPrecision
get { return GetSubsecondPrecision (); } {
set { SetSubsecondPrecision (value); } get { return GetSubsecondPrecision(); }
set { SetSubsecondPrecision(value); }
} }
public int GetSubsecondPrecision() { public int GetSubsecondPrecision()
return Timestamp_getSubsecondPrecision (self); {
return Timestamp_getSubsecondPrecision(self);
} }
public void SetSubsecondPrecision(int subsecondPrecision) { public void SetSubsecondPrecision(int subsecondPrecision)
Timestamp_setSubsecondPrecision (self, subsecondPrecision); {
Timestamp_setSubsecondPrecision(self, subsecondPrecision);
} }
public UInt32 TimeInSeconds { public UInt32 TimeInSeconds
get { return GetTimeInSeconds (); } {
set { SetTimeInSeconds (value); } get { return GetTimeInSeconds(); }
set { SetTimeInSeconds(value); }
} }
public UInt32 GetTimeInSeconds() public UInt32 GetTimeInSeconds()
{ {
return Timestamp_getTimeInSeconds (self); return Timestamp_getTimeInSeconds(self);
} }
public void SetTimeInSeconds(UInt32 secondsSinceEpoch) public void SetTimeInSeconds(UInt32 secondsSinceEpoch)
{ {
Timestamp_setTimeInSeconds (self, secondsSinceEpoch); Timestamp_setTimeInSeconds(self, secondsSinceEpoch);
} }
public UInt64 TimeInMilliseconds { public UInt64 TimeInMilliseconds
get { return GetTimeInMilliseconds (); } {
set { SetTimeInMilliseconds (value); } get { return GetTimeInMilliseconds(); }
set { SetTimeInMilliseconds(value); }
} }
public UInt64 GetTimeInMilliseconds() public UInt64 GetTimeInMilliseconds()
{ {
return Timestamp_getTimeInMs (self); return Timestamp_getTimeInMs(self);
} }
public void SetTimeInMilliseconds(UInt64 millisSinceEpoch) { public void SetTimeInMilliseconds(UInt64 millisSinceEpoch)
Timestamp_setTimeInMilliseconds (self, millisSinceEpoch); {
Timestamp_setTimeInMilliseconds(self, millisSinceEpoch);
} }
public void SetByMmsUtcTime(MmsValue mmsValue) public void SetByMmsUtcTime(MmsValue mmsValue)
{ {
Timestamp_setByMmsUtcTime (self, mmsValue.valueReference); Timestamp_setByMmsUtcTime(self, mmsValue.valueReference);
} }
public DateTime AsDateTime() public DateTime AsDateTime()
{ {
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime retVal = epoch.AddMilliseconds ((double) GetTimeInMilliseconds ()); DateTime retVal = epoch.AddMilliseconds(GetTimeInMilliseconds());
return retVal; return retVal;
} }
@ -695,7 +723,8 @@ namespace IEC61850
/// Definition for LastAppError error type for control models /// Definition for LastAppError error type for control models
/// Used in LastApplError and CommandTermination messages. /// Used in LastApplError and CommandTermination messages.
/// </summary> /// </summary>
public enum ControlLastApplError { public enum ControlLastApplError
{
NO_ERROR = 0, NO_ERROR = 0,
UNKNOWN = 1, UNKNOWN = 1,
TIMEOUT_TEST = 2, TIMEOUT_TEST = 2,
@ -706,7 +735,8 @@ namespace IEC61850
/// AddCause - additional cause information for control model errors /// AddCause - additional cause information for control model errors
/// Used in LastApplError and CommandTermination messages. /// Used in LastApplError and CommandTermination messages.
/// </summary> /// </summary>
public enum ControlAddCause { public enum ControlAddCause
{
ADD_CAUSE_UNKNOWN = 0, ADD_CAUSE_UNKNOWN = 0,
ADD_CAUSE_NOT_SUPPORTED = 1, ADD_CAUSE_NOT_SUPPORTED = 1,
ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY = 2, ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY = 2,
@ -740,7 +770,8 @@ namespace IEC61850
/// <summary> /// <summary>
/// Object reference. Helper function to handle object reference strings. /// Object reference. Helper function to handle object reference strings.
/// </summary> /// </summary>
public static class ObjectReference { public static class ObjectReference
{
/// <summary> /// <summary>
/// Get the name part of an object reference with appended FC /// Get the name part of an object reference with appended FC
@ -751,7 +782,7 @@ namespace IEC61850
/// <param name='objectReferenceWithFc'> /// <param name='objectReferenceWithFc'>
/// Object reference with appended fc. /// Object reference with appended fc.
/// </param> /// </param>
public static string getElementName (string objectReferenceWithFc) public static string getElementName(string objectReferenceWithFc)
{ {
int fcPartStartIndex = objectReferenceWithFc.IndexOf('['); int fcPartStartIndex = objectReferenceWithFc.IndexOf('[');
@ -770,20 +801,20 @@ namespace IEC61850
/// <param name='objectReferenceWithFc'> /// <param name='objectReferenceWithFc'>
/// Object reference with FC. /// Object reference with FC.
/// </param> /// </param>
public static FunctionalConstraint getFC (string objectReferenceWithFc) public static FunctionalConstraint getFC(string objectReferenceWithFc)
{ {
int fcPartStartIndex = objectReferenceWithFc.IndexOf('['); int fcPartStartIndex = objectReferenceWithFc.IndexOf('[');
if (fcPartStartIndex == -1) if (fcPartStartIndex == -1)
return FunctionalConstraint.NONE; return FunctionalConstraint.NONE;
string fcString = objectReferenceWithFc.Substring(fcPartStartIndex + 1 , 2); string fcString = objectReferenceWithFc.Substring(fcPartStartIndex + 1, 2);
try try
{ {
return (FunctionalConstraint) Enum.Parse(typeof(FunctionalConstraint), fcString); return (FunctionalConstraint)Enum.Parse(typeof(FunctionalConstraint), fcString);
} }
catch(ArgumentException) catch (ArgumentException)
{ {
return FunctionalConstraint.NONE; return FunctionalConstraint.NONE;
} }

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

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

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

@ -1,7 +1,7 @@
/* /*
* IsoConnectionParameters.cs * IsoConnectionParameters.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -29,7 +29,8 @@ namespace IEC61850
namespace Client namespace Client
{ {
public enum AcseAuthenticationMechanism { public enum AcseAuthenticationMechanism
{
/** don't use authentication */ /** don't use authentication */
ACSE_AUTH_NONE = 0, ACSE_AUTH_NONE = 0,
/** use password authentication */ /** use password authentication */
@ -47,7 +48,7 @@ namespace IEC61850
{ {
public byte size; public byte size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] public byte[] value; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] value;
} }
@ -56,7 +57,7 @@ namespace IEC61850
{ {
public byte size; public byte size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public byte[] value; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] value;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@ -101,12 +102,12 @@ namespace IEC61850
private IntPtr authParameter = IntPtr.Zero; private IntPtr authParameter = IntPtr.Zero;
internal IsoConnectionParameters (IntPtr self) internal IsoConnectionParameters(IntPtr self)
{ {
this.self = self; this.self = self;
} }
~IsoConnectionParameters () ~IsoConnectionParameters()
{ {
if (authParameter != IntPtr.Zero) if (authParameter != IntPtr.Zero)
AcseAuthenticationParameter_destroy(authParameter); AcseAuthenticationParameter_destroy(authParameter);
@ -138,13 +139,13 @@ namespace IEC61850
/// <param name='tSelector'> /// <param name='tSelector'>
/// ISO COTP transport layer address /// ISO COTP transport layer address
/// </param> /// </param>
public void SetRemoteAddresses (byte[] pSelector, byte[] sSelector, byte[] tSelector) public void SetRemoteAddresses(byte[] pSelector, byte[] sSelector, byte[] tSelector)
{ {
if (tSelector.Length > 4) if (tSelector.Length > 4)
throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded"); throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded");
NativeTSelector nativeTSelector; NativeTSelector nativeTSelector;
nativeTSelector.size = (byte) tSelector.Length; nativeTSelector.size = (byte)tSelector.Length;
nativeTSelector.value = new byte[4]; nativeTSelector.value = new byte[4];
for (int i = 0; i < tSelector.Length; i++) for (int i = 0; i < tSelector.Length; i++)
@ -154,11 +155,11 @@ namespace IEC61850
throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded");
NativeSSelector nativeSSelector; NativeSSelector nativeSSelector;
nativeSSelector.size = (byte) sSelector.Length; nativeSSelector.size = (byte)sSelector.Length;
nativeSSelector.value = new byte[16]; nativeSSelector.value = new byte[16];
for (int i = 0; i < sSelector.Length; i++) for (int i = 0; i < sSelector.Length; i++)
nativeSSelector.value [i] = sSelector [i]; nativeSSelector.value[i] = sSelector[i];
if (pSelector.Length > 16) if (pSelector.Length > 16)
throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded");
@ -182,7 +183,7 @@ namespace IEC61850
/// <param name='aeQualifier'> /// <param name='aeQualifier'>
/// local AE qualifier. /// local AE qualifier.
/// </param> /// </param>
public void SetLocalApTitle (string apTitle, int aeQualifier) public void SetLocalApTitle(string apTitle, int aeQualifier)
{ {
IsoConnectionParameters_setLocalApTitle(self, apTitle, aeQualifier); IsoConnectionParameters_setLocalApTitle(self, apTitle, aeQualifier);
} }
@ -199,13 +200,13 @@ namespace IEC61850
/// <param name='tSelector'> /// <param name='tSelector'>
/// ISO COTP transport layer address /// ISO COTP transport layer address
/// </param> /// </param>
public void SetLocalAddresses (byte[] pSelector, byte[] sSelector, byte[] tSelector) public void SetLocalAddresses(byte[] pSelector, byte[] sSelector, byte[] tSelector)
{ {
if (tSelector.Length > 4) if (tSelector.Length > 4)
throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded"); throw new ArgumentOutOfRangeException("tSelector", "maximum size (4) exceeded");
NativeTSelector nativeTSelector; NativeTSelector nativeTSelector;
nativeTSelector.size = (byte) tSelector.Length; nativeTSelector.size = (byte)tSelector.Length;
nativeTSelector.value = new byte[4]; nativeTSelector.value = new byte[4];
for (int i = 0; i < tSelector.Length; i++) for (int i = 0; i < tSelector.Length; i++)
@ -215,11 +216,11 @@ namespace IEC61850
throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("sSelector", "maximum size (16) exceeded");
NativeSSelector nativeSSelector; NativeSSelector nativeSSelector;
nativeSSelector.size = (byte) sSelector.Length; nativeSSelector.size = (byte)sSelector.Length;
nativeSSelector.value = new byte[16]; nativeSSelector.value = new byte[16];
for (int i = 0; i < sSelector.Length; i++) for (int i = 0; i < sSelector.Length; i++)
nativeSSelector.value [i] = sSelector [i]; nativeSSelector.value[i] = sSelector[i];
if (pSelector.Length > 16) if (pSelector.Length > 16)
throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded"); throw new ArgumentOutOfRangeException("pSelector", "maximum size (16) exceeded");
@ -240,12 +241,13 @@ namespace IEC61850
/// <param name='password'> /// <param name='password'>
/// Password that will be used to authenticate the client /// Password that will be used to authenticate the client
/// </param> /// </param>
public void UsePasswordAuthentication (string password) public void UsePasswordAuthentication(string password)
{
if (authParameter == IntPtr.Zero)
{ {
if (authParameter == IntPtr.Zero) { authParameter = AcseAuthenticationParameter_create();
authParameter = AcseAuthenticationParameter_create (); AcseAuthenticationParameter_setAuthMechanism(authParameter, (int)AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD);
AcseAuthenticationParameter_setAuthMechanism (authParameter, (int)AcseAuthenticationMechanism.ACSE_AUTH_PASSWORD); AcseAuthenticationParameter_setPassword(authParameter, password);
AcseAuthenticationParameter_setPassword (authParameter, password);
IsoConnectionParameters_setAcseAuthenticationParameter(self, authParameter); IsoConnectionParameters_setAcseAuthenticationParameter(self, authParameter);
} }
else else

@ -1,7 +1,7 @@
/* /*
* MmsValue.cs * MmsValue.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,11 +21,8 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using System; using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections; using System.Collections;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace IEC61850 namespace IEC61850
@ -38,29 +35,29 @@ namespace IEC61850
public class MmsValue : IEnumerable, IDisposable public class MmsValue : IEnumerable, IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_toString (IntPtr self); static extern IntPtr MmsValue_toString(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern float MmsValue_toFloat (IntPtr self); static extern float MmsValue_toFloat(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setFloat (IntPtr self, float value); static extern void MmsValue_setFloat(IntPtr self, float value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern double MmsValue_toDouble (IntPtr self); static extern double MmsValue_toDouble(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setDouble (IntPtr self, double newFloatValue); static extern void MmsValue_setDouble(IntPtr self, double newFloatValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBoolean (IntPtr self); static extern bool MmsValue_getBoolean(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setBoolean(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value); static extern void MmsValue_setBoolean(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_getBitStringAsInteger (IntPtr self); static extern UInt32 MmsValue_getBitStringAsInteger(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setBitStringFromInteger(IntPtr self, UInt32 intValue); static extern void MmsValue_setBitStringFromInteger(IntPtr self, UInt32 intValue);
@ -82,64 +79,64 @@ namespace IEC61850
static extern bool MmsValue_getBitStringBit(IntPtr self, int bitPos); static extern bool MmsValue_getBitStringBit(IntPtr self, int bitPos);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int32 MmsValue_toInt32 (IntPtr self); static extern Int32 MmsValue_toInt32(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setInt32(IntPtr self, int value); static extern void MmsValue_setInt32(IntPtr self, int value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int64 MmsValue_toInt64 (IntPtr self); static extern Int64 MmsValue_toInt64(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_toUint32 (IntPtr self); static extern UInt32 MmsValue_toUint32(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int MmsValue_getType (IntPtr self); static extern int MmsValue_getType(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_delete (IntPtr self); static extern void MmsValue_delete(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_getElement (IntPtr complexValue, int index); static extern IntPtr MmsValue_getElement(IntPtr complexValue, int index);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int MmsValue_getArraySize (IntPtr self); static extern int MmsValue_getArraySize(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern ulong MmsValue_getUtcTimeInMs (IntPtr self); static extern ulong MmsValue_getUtcTimeInMs(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setUtcTimeMs (IntPtr self, ulong timeval); static extern void MmsValue_setUtcTimeMs(IntPtr self, ulong timeval);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern ulong MmsValue_getUtcTimeInMsWithUs(IntPtr self, [Out] uint usec); static extern ulong MmsValue_getUtcTimeInMsWithUs(IntPtr self, [Out] uint usec);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern byte MmsValue_getUtcTimeQuality (IntPtr self); static extern byte MmsValue_getUtcTimeQuality(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setUtcTimeQuality (IntPtr self, byte timeQuality); static extern void MmsValue_setUtcTimeQuality(IntPtr self, byte timeQuality);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MmsValue_toUnixTimestamp (IntPtr self); static extern UInt32 MmsValue_toUnixTimestamp(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newBoolean ([MarshalAs(UnmanagedType.I1)] bool value); static extern IntPtr MmsValue_newBoolean([MarshalAs(UnmanagedType.I1)] bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newFloat (float value); static extern IntPtr MmsValue_newFloat(float value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newDouble (double value); static extern IntPtr MmsValue_newDouble(double value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newIntegerFromInt32 (Int32 integer); static extern IntPtr MmsValue_newIntegerFromInt32(Int32 integer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newUnsignedFromUint32(UInt32 integer); static extern IntPtr MmsValue_newUnsignedFromUint32(UInt32 integer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newIntegerFromInt64 (Int64 integer); static extern IntPtr MmsValue_newIntegerFromInt64(Int64 integer);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newBitString(int bitSize); static extern IntPtr MmsValue_newBitString(int bitSize);
@ -188,18 +185,18 @@ namespace IEC61850
static extern bool MmsValue_equals(IntPtr self, IntPtr otherValue); static extern bool MmsValue_equals(IntPtr self, IntPtr otherValue);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newBinaryTime ([MarshalAs(UnmanagedType.I1)] bool timeOfDay); static extern IntPtr MmsValue_newBinaryTime([MarshalAs(UnmanagedType.I1)] bool timeOfDay);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setBinaryTime (IntPtr self, UInt64 timestamp); static extern void MmsValue_setBinaryTime(IntPtr self, UInt64 timestamp);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern ulong MmsValue_getBinaryTimeAsUtcMs (IntPtr self); static extern ulong MmsValue_getBinaryTimeAsUtcMs(IntPtr self);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_newUtcTimeByMsTime (UInt64 timestamp); static extern IntPtr MmsValue_newUtcTimeByMsTime(UInt64 timestamp);
[DllImport("iec61850", CallingConvention=CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int MmsValue_getDataAccessError(IntPtr self); static extern int MmsValue_getDataAccessError(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -221,82 +218,84 @@ namespace IEC61850
private bool responsableForDeletion = false; /* if .NET wrapper is responsable for the deletion of the native MmsValue instance */ private bool responsableForDeletion = false; /* if .NET wrapper is responsable for the deletion of the native MmsValue instance */
internal MmsValue (IntPtr value) internal MmsValue(IntPtr value)
{ {
valueReference = value; valueReference = value;
this.responsableForDeletion = false; responsableForDeletion = false;
} }
public int EncodeMmsData(byte[] buffer, int bufPos, bool encode) public int EncodeMmsData(byte[] buffer, int bufPos, bool encode)
{ {
return MmsValue_encodeMmsData(this.valueReference, buffer, bufPos, encode); return MmsValue_encodeMmsData(valueReference, buffer, bufPos, encode);
} }
public int DecodeMmsData(int bufPos, int bufferLength, IntPtr endBufPo) public int DecodeMmsData(int bufPos, int bufferLength, IntPtr endBufPo)
{ {
return MmsValue_decodeMmsData(this.valueReference, bufPos, bufferLength, endBufPo); return MmsValue_decodeMmsData(valueReference, bufPos, bufferLength, endBufPo);
} }
internal MmsValue (IntPtr value, bool responsableForDeletion) internal MmsValue(IntPtr value, bool responsableForDeletion)
{ {
valueReference = value; valueReference = value;
this.responsableForDeletion = responsableForDeletion; this.responsableForDeletion = responsableForDeletion;
} }
public MmsValue (bool value) public MmsValue(bool value)
{ {
valueReference = MmsValue_newBoolean (value); valueReference = MmsValue_newBoolean(value);
} }
public MmsValue (float value) public MmsValue(float value)
{ {
valueReference = MmsValue_newFloat (value); valueReference = MmsValue_newFloat(value);
} }
public MmsValue (double value) public MmsValue(double value)
{ {
valueReference = MmsValue_newDouble (value); valueReference = MmsValue_newDouble(value);
} }
public MmsValue (int value) public MmsValue(int value)
{ {
valueReference = MmsValue_newIntegerFromInt32 (value); valueReference = MmsValue_newIntegerFromInt32(value);
} }
public MmsValue (UInt32 value) public MmsValue(UInt32 value)
{ {
valueReference = MmsValue_newUnsignedFromUint32(value); valueReference = MmsValue_newUnsignedFromUint32(value);
} }
public MmsValue (long value) public MmsValue(long value)
{ {
valueReference = MmsValue_newIntegerFromInt64 (value); valueReference = MmsValue_newIntegerFromInt64(value);
} }
/// <summary> /// <summary>
/// Create a new <see cref="IEC61850.Common.MmsValue"/> instance of type MMS_VISIBLE_STRING. /// Create a new <see cref="IEC61850.Common.MmsValue"/> instance of type MMS_VISIBLE_STRING.
/// </summary> /// </summary>
/// <param name="value">Value.</param> /// <param name="value">Value.</param>
public MmsValue (string value) public MmsValue(string value)
{ {
valueReference = MmsValue_newVisibleString(value); valueReference = MmsValue_newVisibleString(value);
} }
public void Dispose() public void Dispose()
{ {
lock (this) { lock (this)
if (valueReference != IntPtr.Zero) { {
if (valueReference != IntPtr.Zero)
{
if (responsableForDeletion) if (responsableForDeletion)
MmsValue_delete (valueReference); MmsValue_delete(valueReference);
valueReference = IntPtr.Zero; valueReference = IntPtr.Zero;
} }
} }
} }
~MmsValue () ~MmsValue()
{ {
Dispose(); Dispose();
} }
@ -329,7 +328,7 @@ namespace IEC61850
/// <param name='size'> /// <param name='size'>
/// the current size of the octet string in bytes (defaults to 0) /// the current size of the octet string in bytes (defaults to 0)
/// </param> /// </param>
public static MmsValue NewOctetString (int maxSize, int size = 0) public static MmsValue NewOctetString(int maxSize, int size = 0)
{ {
IntPtr newValue = MmsValue_newOctetString(size, maxSize); IntPtr newValue = MmsValue_newOctetString(size, maxSize);
@ -339,11 +338,11 @@ namespace IEC61850
public MmsValue(byte[] octetString) public MmsValue(byte[] octetString)
{ {
if (octetString.Length > 255) if (octetString.Length > 255)
throw new MmsValueException ("octet string too long"); throw new MmsValueException("octet string too long");
valueReference = MmsValue_newOctetString(octetString.Length, octetString.Length); valueReference = MmsValue_newOctetString(octetString.Length, octetString.Length);
this.setOctetString (octetString); setOctetString(octetString);
} }
/// <summary> /// <summary>
@ -355,11 +354,11 @@ namespace IEC61850
public static MmsValue NewArray(MmsVariableSpecification elementType, int size) public static MmsValue NewArray(MmsVariableSpecification elementType, int size)
{ {
if (size < 1) if (size < 1)
throw new MmsValueException ("array requires at least one element"); throw new MmsValueException("array requires at least one element");
IntPtr newValue = MmsValue_createArray (elementType.self, size); IntPtr newValue = MmsValue_createArray(elementType.self, size);
return new MmsValue (newValue, true); return new MmsValue(newValue, true);
} }
/// <summary> /// <summary>
@ -370,11 +369,11 @@ namespace IEC61850
public static MmsValue NewEmptyArray(int size) public static MmsValue NewEmptyArray(int size)
{ {
if (size < 1) if (size < 1)
throw new MmsValueException ("array requires at least one element"); throw new MmsValueException("array requires at least one element");
IntPtr newValue = MmsValue_createEmptyArray (size); IntPtr newValue = MmsValue_createEmptyArray(size);
return new MmsValue (newValue, true); return new MmsValue(newValue, true);
} }
/// <summary> /// <summary>
@ -385,11 +384,11 @@ namespace IEC61850
public static MmsValue NewEmptyStructure(int size) public static MmsValue NewEmptyStructure(int size)
{ {
if (size < 1) if (size < 1)
throw new MmsValueException ("structure requires at least one element"); throw new MmsValueException("structure requires at least one element");
IntPtr newValue = MmsValue_createEmptyStructure (size); IntPtr newValue = MmsValue_createEmptyStructure(size);
return new MmsValue (newValue, true); return new MmsValue(newValue, true);
} }
@ -400,17 +399,18 @@ namespace IEC61850
/// <param name="largeFormat">If set to <c>true</c> large 6 byte format.</param> /// <param name="largeFormat">If set to <c>true</c> large 6 byte format.</param>
public static MmsValue NewBinaryTime(bool largeFormat) public static MmsValue NewBinaryTime(bool largeFormat)
{ {
IntPtr newValue = MmsValue_newBinaryTime (largeFormat); IntPtr newValue = MmsValue_newBinaryTime(largeFormat);
return new MmsValue (newValue, true); return new MmsValue(newValue, true);
} }
/// <summary> /// <summary>
/// Sets the binary time. /// Sets the binary time.
/// </summary> /// </summary>
/// <param name="timestamp">Timestamp.</param> /// <param name="timestamp">Timestamp.</param>
public void SetBinaryTime(UInt64 timestamp) { public void SetBinaryTime(UInt64 timestamp)
MmsValue_setBinaryTime (this.valueReference, timestamp); {
MmsValue_setBinaryTime(valueReference, timestamp);
} }
/// <summary> /// <summary>
@ -424,12 +424,14 @@ namespace IEC61850
/// The UTC time in ms. /// The UTC time in ms.
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public ulong GetBinaryTimeAsUtcMs () public ulong GetBinaryTimeAsUtcMs()
{
if (GetType() == MmsType.MMS_BINARY_TIME)
{ {
if (GetType () == MmsType.MMS_BINARY_TIME) { return MmsValue_getBinaryTimeAsUtcMs(valueReference);
return MmsValue_getBinaryTimeAsUtcMs (valueReference); }
} else else
throw new MmsValueException ("Value is not a time type"); throw new MmsValueException("Value is not a time type");
} }
/// <summary> /// <summary>
@ -437,11 +439,11 @@ namespace IEC61850
/// </summary> /// </summary>
/// <returns>the new MmsValue instance.</returns> /// <returns>the new MmsValue instance.</returns>
/// <param name="timestamp">the time value as milliseconds since epoch (1.1.1970 UTC).</param> /// <param name="timestamp">the time value as milliseconds since epoch (1.1.1970 UTC).</param>
public static MmsValue NewUtcTime (UInt64 timestamp) public static MmsValue NewUtcTime(UInt64 timestamp)
{ {
IntPtr newValue = MmsValue_newUtcTimeByMsTime (timestamp); IntPtr newValue = MmsValue_newUtcTimeByMsTime(timestamp);
return new MmsValue (newValue, true); return new MmsValue(newValue, true);
} }
/// <summary> /// <summary>
@ -471,9 +473,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// The type. /// The type.
/// </returns> /// </returns>
public new MmsType GetType () public new MmsType GetType()
{ {
return (MmsType)MmsValue_getType (valueReference); return (MmsType)MmsValue_getType(valueReference);
} }
/// <summary> /// <summary>
@ -487,18 +489,22 @@ namespace IEC61850
/// the number of elements (array/structure elements, octets, bits depending on type) /// the number of elements (array/structure elements, octets, bits depending on type)
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public int Size () public int Size()
{
if ((GetType() == MmsType.MMS_ARRAY) || (GetType() == MmsType.MMS_STRUCTURE))
{
return MmsValue_getArraySize(valueReference);
}
else if (GetType() == MmsType.MMS_BIT_STRING)
{ {
if ((GetType () == MmsType.MMS_ARRAY) || (GetType () == MmsType.MMS_STRUCTURE)) {
return MmsValue_getArraySize (valueReference);
} else if (GetType () == MmsType.MMS_BIT_STRING) {
return MmsValue_getBitStringSize(valueReference); return MmsValue_getBitStringSize(valueReference);
} }
else if (GetType () == MmsType.MMS_OCTET_STRING) { else if (GetType() == MmsType.MMS_OCTET_STRING)
{
return MmsValue_getOctetStringSize(valueReference); return MmsValue_getOctetStringSize(valueReference);
} }
else else
throw new MmsValueException ("Operation not supported for this type"); throw new MmsValueException("Operation not supported for this type");
} }
/// <summary> /// <summary>
@ -507,13 +513,14 @@ namespace IEC61850
/// <returns> /// <returns>
/// The maximum size (in bytes) of the octet string /// The maximum size (in bytes) of the octet string
/// </returns> /// </returns>
public int MaxSize () public int MaxSize()
{
if (GetType() == MmsType.MMS_OCTET_STRING)
{ {
if (GetType () == MmsType.MMS_OCTET_STRING) {
return MmsValue_getOctetStringMaxSize(valueReference); return MmsValue_getOctetStringMaxSize(valueReference);
} }
else else
throw new MmsValueException ("Operation not supported for this type"); throw new MmsValueException("Operation not supported for this type");
} }
/// <summary> /// <summary>
@ -525,11 +532,12 @@ namespace IEC61850
/// Byte array containing the bytes of the octet string. /// Byte array containing the bytes of the octet string.
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public byte[] getOctetString () public byte[] getOctetString()
{
if (GetType() == MmsType.MMS_OCTET_STRING)
{ {
if (GetType () == MmsType.MMS_OCTET_STRING) {
IntPtr buffer = MmsValue_getOctetStringBuffer(valueReference); IntPtr buffer = MmsValue_getOctetStringBuffer(valueReference);
int bufferSize = this.Size(); int bufferSize = Size();
byte[] octetString = new byte[bufferSize]; byte[] octetString = new byte[bufferSize];
@ -538,7 +546,7 @@ namespace IEC61850
return octetString; return octetString;
} }
else else
throw new MmsValueException ("Operation not supported for this type"); throw new MmsValueException("Operation not supported for this type");
} }
/// <summary> /// <summary>
@ -546,17 +554,18 @@ namespace IEC61850
/// </summary> /// </summary>
/// <param name="octetString">Byte array containing the bytes of the octet string.</param> /// <param name="octetString">Byte array containing the bytes of the octet string.</param>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type or the byte array is too large.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type or the byte array is too large.</exception>
public void setOctetString (byte[] octetString) public void setOctetString(byte[] octetString)
{
if (GetType() == MmsType.MMS_OCTET_STRING)
{ {
if (GetType () == MmsType.MMS_OCTET_STRING) {
if (this.MaxSize() < octetString.Length) if (MaxSize() < octetString.Length)
throw new MmsValueException("octet string is to large"); throw new MmsValueException("octet string is to large");
MmsValue_setOctetString(valueReference, octetString, octetString.Length); MmsValue_setOctetString(valueReference, octetString, octetString.Length);
} }
else else
throw new MmsValueException ("Operation not supported for this type"); throw new MmsValueException("Operation not supported for this type");
} }
/// <summary> /// <summary>
@ -590,22 +599,26 @@ namespace IEC61850
/// </param> /// </param>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
/// <exception cref="MmsValueException">This exception is thrown if the index is out of range.</exception> /// <exception cref="MmsValueException">This exception is thrown if the index is out of range.</exception>
public MmsValue GetElement (int index) public MmsValue GetElement(int index)
{ {
MmsType type = GetType (); MmsType type = GetType();
if ((type == MmsType.MMS_ARRAY) || (type == MmsType.MMS_STRUCTURE)) { if ((type == MmsType.MMS_ARRAY) || (type == MmsType.MMS_STRUCTURE))
if ((index >= 0) && (index < Size ())) { {
IntPtr value = MmsValue_getElement (valueReference, index); if ((index >= 0) && (index < Size()))
{
IntPtr value = MmsValue_getElement(valueReference, index);
if (value == IntPtr.Zero) if (value == IntPtr.Zero)
return null; return null;
else else
return new MmsValue (value); return new MmsValue(value);
} else }
throw new MmsValueException ("Index out of bounds"); else
} else throw new MmsValueException("Index out of bounds");
throw new MmsValueException ("Value is of wrong type"); }
else
throw new MmsValueException("Value is of wrong type");
} }
/// <summary> /// <summary>
@ -674,12 +687,12 @@ namespace IEC61850
/// The UTC time in seconds (UNIX time stamp). /// The UTC time in seconds (UNIX time stamp).
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public UInt32 ToUnixTimestamp () public UInt32 ToUnixTimestamp()
{ {
if (GetType () == MmsType.MMS_UTC_TIME) if (GetType() == MmsType.MMS_UTC_TIME)
return MmsValue_toUnixTimestamp (valueReference); return MmsValue_toUnixTimestamp(valueReference);
else else
throw new MmsValueException ("Value is not a time type"); throw new MmsValueException("Value is not a time type");
} }
/// <summary> /// <summary>
@ -692,10 +705,12 @@ namespace IEC61850
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public void SetUtcTimeMs(ulong timeval) public void SetUtcTimeMs(ulong timeval)
{ {
if (GetType () == MmsType.MMS_UTC_TIME) { if (GetType() == MmsType.MMS_UTC_TIME)
{
MmsValue_setUtcTimeMs(valueReference, timeval); MmsValue_setUtcTimeMs(valueReference, timeval);
} else }
throw new MmsValueException ("Value is not a time type"); else
throw new MmsValueException("Value is not a time type");
} }
/// <summary> /// <summary>
@ -709,12 +724,14 @@ namespace IEC61850
/// The UTC time in ms. /// The UTC time in ms.
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public ulong GetUtcTimeInMs () public ulong GetUtcTimeInMs()
{
if (GetType() == MmsType.MMS_UTC_TIME)
{ {
if (GetType () == MmsType.MMS_UTC_TIME) { return MmsValue_getUtcTimeInMs(valueReference);
return MmsValue_getUtcTimeInMs (valueReference); }
} else else
throw new MmsValueException ("Value is not a time type"); throw new MmsValueException("Value is not a time type");
} }
/// <summary> /// <summary>
@ -776,8 +793,8 @@ namespace IEC61850
/// <param name="timeQuality">Time quality.</param> /// <param name="timeQuality">Time quality.</param>
public void SetUtcTimeQuality(byte timeQuality) public void SetUtcTimeQuality(byte timeQuality)
{ {
if (GetType () == MmsType.MMS_UTC_TIME) if (GetType() == MmsType.MMS_UTC_TIME)
MmsValue_setUtcTimeQuality (valueReference, timeQuality); MmsValue_setUtcTimeQuality(valueReference, timeQuality);
else else
throw new MmsValueException("Value is not a time type"); throw new MmsValueException("Value is not a time type");
} }
@ -791,11 +808,11 @@ namespace IEC61850
/// <param name='msTime'> /// <param name='msTime'>
/// the millisecond time /// the millisecond time
/// </param> /// </param>
public static DateTimeOffset MsTimeToDateTimeOffset (UInt64 msTime) public static DateTimeOffset MsTimeToDateTimeOffset(UInt64 msTime)
{ {
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 ((double) msTime); return retVal.AddMilliseconds(msTime);
} }
/// <summary> /// <summary>
@ -809,12 +826,12 @@ namespace IEC61850
/// the value as DataTimeOffset instance /// the value as DataTimeOffset instance
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public DateTimeOffset GetUtcTimeAsDateTimeOffset () public DateTimeOffset GetUtcTimeAsDateTimeOffset()
{ {
if (GetType () == MmsType.MMS_UTC_TIME) if (GetType() == MmsType.MMS_UTC_TIME)
return MsTimeToDateTimeOffset (GetUtcTimeInMs ()); return MsTimeToDateTimeOffset(GetUtcTimeInMs());
else else
throw new MmsValueException ("Value is not a time type"); throw new MmsValueException("Value is not a time type");
} }
@ -829,12 +846,12 @@ namespace IEC61850
/// the value if the object as 32 bit signed integer /// the value if the object as 32 bit signed integer
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public Int32 ToInt32 () public Int32 ToInt32()
{ {
if (GetType () != MmsType.MMS_INTEGER) if (GetType() != MmsType.MMS_INTEGER)
throw new MmsValueException ("Value type is not integer"); throw new MmsValueException("Value type is not integer");
return MmsValue_toInt32 (valueReference); return MmsValue_toInt32(valueReference);
} }
/// <summary> /// <summary>
@ -863,12 +880,12 @@ namespace IEC61850
/// the value if the object as 64 bit signed integer /// the value if the object as 64 bit signed integer
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public Int64 ToInt64 () public Int64 ToInt64()
{ {
if (GetType () != MmsType.MMS_INTEGER) if (GetType() != MmsType.MMS_INTEGER)
throw new MmsValueException ("Value type is not integer"); throw new MmsValueException("Value type is not integer");
return MmsValue_toInt64 (valueReference); return MmsValue_toInt64(valueReference);
} }
/// <summary> /// <summary>
@ -882,25 +899,25 @@ namespace IEC61850
/// the value if the object as 32 bit unsigned integer /// the value if the object as 32 bit unsigned integer
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public UInt32 ToUint32 () public UInt32 ToUint32()
{ {
if (GetType () != MmsType.MMS_UNSIGNED) if (GetType() != MmsType.MMS_UNSIGNED)
throw new MmsValueException ("Value type is not unsigned"); throw new MmsValueException("Value type is not unsigned");
return MmsValue_toUint32 (valueReference); return MmsValue_toUint32(valueReference);
} }
public UInt32 BitStringToUInt32 () public UInt32 BitStringToUInt32()
{ {
if (GetType () != MmsType.MMS_BIT_STRING) if (GetType() != MmsType.MMS_BIT_STRING)
throw new MmsValueException("Value type is not bit string"); throw new MmsValueException("Value type is not bit string");
return MmsValue_getBitStringAsInteger(valueReference); return MmsValue_getBitStringAsInteger(valueReference);
} }
public void BitStringFromUInt32 (UInt32 intValue) public void BitStringFromUInt32(UInt32 intValue)
{ {
if (GetType () != MmsType.MMS_BIT_STRING) if (GetType() != MmsType.MMS_BIT_STRING)
throw new MmsValueException("Value type is not bit string"); throw new MmsValueException("Value type is not bit string");
MmsValue_setBitStringFromInteger(valueReference, intValue); MmsValue_setBitStringFromInteger(valueReference, intValue);
@ -922,17 +939,17 @@ namespace IEC61850
MmsValue_setBitStringFromIntegerBigEndian(valueReference, intValue); MmsValue_setBitStringFromIntegerBigEndian(valueReference, intValue);
} }
public void SetBit (int bitPos, bool bitValue) public void SetBit(int bitPos, bool bitValue)
{ {
if (GetType () != MmsType.MMS_BIT_STRING) if (GetType() != MmsType.MMS_BIT_STRING)
throw new MmsValueException("Value type is not bit string"); throw new MmsValueException("Value type is not bit string");
MmsValue_setBitStringBit(valueReference, bitPos, bitValue); MmsValue_setBitStringBit(valueReference, bitPos, bitValue);
} }
public bool GetBit (int bitPos) public bool GetBit(int bitPos)
{ {
if (GetType () != MmsType.MMS_BIT_STRING) if (GetType() != MmsType.MMS_BIT_STRING)
throw new MmsValueException("Value type is not bit string"); throw new MmsValueException("Value type is not bit string");
return MmsValue_getBitStringBit(valueReference, bitPos); return MmsValue_getBitStringBit(valueReference, bitPos);
@ -965,12 +982,12 @@ namespace IEC61850
/// The boolean value /// The boolean value
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public bool GetBoolean () public bool GetBoolean()
{ {
if (GetType () == MmsType.MMS_BOOLEAN) if (GetType() == MmsType.MMS_BOOLEAN)
return MmsValue_getBoolean (valueReference); return MmsValue_getBoolean(valueReference);
else else
throw new MmsValueException ("Value type is not boolean"); throw new MmsValueException("Value type is not boolean");
} }
/// <summary> /// <summary>
@ -995,12 +1012,12 @@ namespace IEC61850
/// The float value /// The float value
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public float ToFloat () public float ToFloat()
{ {
if (GetType () == MmsType.MMS_FLOAT) if (GetType() == MmsType.MMS_FLOAT)
return MmsValue_toFloat (valueReference); return MmsValue_toFloat(valueReference);
else else
throw new MmsValueException ("Value type is not float"); throw new MmsValueException("Value type is not float");
} }
/// <summary> /// <summary>
@ -1010,12 +1027,12 @@ namespace IEC61850
/// the new value to set /// the new value to set
/// </param> /// </param>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public void SetFloat (float value) public void SetFloat(float value)
{ {
if (GetType () == MmsType.MMS_FLOAT) if (GetType() == MmsType.MMS_FLOAT)
MmsValue_setFloat (valueReference, value); MmsValue_setFloat(valueReference, value);
else else
throw new MmsValueException ("Value type is not float"); throw new MmsValueException("Value type is not float");
} }
/// <summary> /// <summary>
@ -1025,12 +1042,12 @@ namespace IEC61850
/// The float value /// The float value
/// </returns> /// </returns>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public double ToDouble () public double ToDouble()
{ {
if (GetType () == MmsType.MMS_FLOAT) if (GetType() == MmsType.MMS_FLOAT)
return MmsValue_toDouble (valueReference); return MmsValue_toDouble(valueReference);
else else
throw new MmsValueException ("Value type is not float"); throw new MmsValueException("Value type is not float");
} }
/// <summary> /// <summary>
@ -1040,12 +1057,12 @@ namespace IEC61850
/// the new value to set /// the new value to set
/// </param> /// </param>
/// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception> /// <exception cref="MmsValueException">This exception is thrown if the value has the wrong type.</exception>
public void SetDouble (double value) public void SetDouble(double value)
{ {
if (GetType () == MmsType.MMS_FLOAT) if (GetType() == MmsType.MMS_FLOAT)
MmsValue_setDouble (valueReference, value); MmsValue_setDouble(valueReference, value);
else else
throw new MmsValueException ("Value type is not float"); throw new MmsValueException("Value type is not float");
} }
/// <summary> /// <summary>
@ -1083,34 +1100,35 @@ namespace IEC61850
return new MmsValue(clonePtr, true); return new MmsValue(clonePtr, true);
} }
public override bool Equals (object obj) public override bool Equals(object obj)
{ {
MmsValue otherValue = (MmsValue) obj; MmsValue otherValue = (MmsValue)obj;
return MmsValue_equals(this.valueReference, otherValue.valueReference); return MmsValue_equals(valueReference, otherValue.valueReference);
} }
// override standard ToString() method // override standard ToString() method
public override string ToString () public override string ToString()
{
switch (GetType())
{ {
switch (GetType ()) {
case MmsType.MMS_VISIBLE_STRING: case MmsType.MMS_VISIBLE_STRING:
case MmsType.MMS_STRING: case MmsType.MMS_STRING:
return Marshal.PtrToStringAnsi (MmsValue_toString (valueReference)); return Marshal.PtrToStringAnsi(MmsValue_toString(valueReference));
case MmsType.MMS_BOOLEAN: case MmsType.MMS_BOOLEAN:
return GetBoolean ().ToString (); return GetBoolean().ToString();
case MmsType.MMS_INTEGER: case MmsType.MMS_INTEGER:
return ToInt64 ().ToString (); return ToInt64().ToString();
case MmsType.MMS_UNSIGNED: case MmsType.MMS_UNSIGNED:
return ToUint32 ().ToString (); return ToUint32().ToString();
case MmsType.MMS_FLOAT: case MmsType.MMS_FLOAT:
return ToDouble ().ToString (); return ToDouble().ToString();
case MmsType.MMS_UTC_TIME: case MmsType.MMS_UTC_TIME:
return GetUtcTimeAsDateTimeOffset ().ToString (); return GetUtcTimeAsDateTimeOffset().ToString();
case MmsType.MMS_BINARY_TIME: case MmsType.MMS_BINARY_TIME:
return (MsTimeToDateTimeOffset (GetBinaryTimeAsUtcMs ()).ToString ()); return (MsTimeToDateTimeOffset(GetBinaryTimeAsUtcMs()).ToString());
case MmsType.MMS_OCTET_STRING: case MmsType.MMS_OCTET_STRING:
return BitConverter.ToString (getOctetString ()); return BitConverter.ToString(getOctetString());
case MmsType.MMS_BIT_STRING: case MmsType.MMS_BIT_STRING:
return GetBitStringAsString(); return GetBitStringAsString();
case MmsType.MMS_STRUCTURE: case MmsType.MMS_STRUCTURE:
@ -1119,13 +1137,17 @@ namespace IEC61850
bool first = true; bool first = true;
foreach (MmsValue element in this) { foreach (MmsValue element in this)
if (first) { {
retString += element.ToString (); if (first)
{
retString += element.ToString();
first = false; first = false;
} else { }
retString += ", " + element.ToString (); else
{
retString += ", " + element.ToString();
} }
} }
@ -1139,13 +1161,17 @@ namespace IEC61850
bool first = true; bool first = true;
foreach (MmsValue element in this) { foreach (MmsValue element in this)
if (first) { {
retString += element.ToString (); if (first)
{
retString += element.ToString();
first = false; first = false;
} else { }
retString += ", " + element.ToString (); else
{
retString += ", " + element.ToString();
} }
} }
@ -1161,9 +1187,9 @@ namespace IEC61850
} }
} }
IEnumerator IEnumerable.GetEnumerator () IEnumerator IEnumerable.GetEnumerator()
{ {
return new MmsValueEnumerator (this); return new MmsValueEnumerator(this);
} }
private class MmsValueEnumerator : IEnumerator private class MmsValueEnumerator : IEnumerator
@ -1171,27 +1197,28 @@ namespace IEC61850
private MmsValue value; private MmsValue value;
private int index = -1; private int index = -1;
public MmsValueEnumerator (MmsValue value) public MmsValueEnumerator(MmsValue value)
{ {
this.value = value; this.value = value;
} }
#region IEnumerator Members #region IEnumerator Members
public void Reset () public void Reset()
{ {
index = -1; index = -1;
} }
public object Current { public object Current
{
get { return value.GetElement (index);} get { return value.GetElement(index); }
} }
public bool MoveNext () public bool MoveNext()
{ {
index++; index++;
if (index >= value.Size ()) if (index >= value.Size())
return false; return false;
else else
return true; return true;
@ -1204,7 +1231,7 @@ namespace IEC61850
public class MmsValueException : Exception public class MmsValueException : Exception
{ {
public MmsValueException (string message) public MmsValueException(string message)
: base(message) : base(message)
{ {
} }

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

@ -1,7 +1,7 @@
/* /*
* ReportControlBlock.cs * ReportControlBlock.cs
* *
* Copyright 2014-2018 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -20,11 +20,9 @@
* *
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
@ -36,10 +34,10 @@ namespace IEC61850
/// </summary> /// </summary>
/// <param name="report">represents the received report. DON'T use this object /// <param name="report">represents the received report. DON'T use this object
/// outside the scope of the report handler!</param> /// outside the scope of the report handler!</param>
public delegate void ReportHandler (Report report, object parameter); public delegate void ReportHandler(Report report, object parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void InternalReportHandler (IntPtr parameter, IntPtr report); internal delegate void InternalReportHandler(IntPtr parameter, IntPtr report);
/// <summary> /// <summary>
/// Report control block (RCB) representation. /// Report control block (RCB) representation.
@ -52,106 +50,106 @@ namespace IEC61850
public class ReportControlBlock : IDisposable public class ReportControlBlock : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_create (string dataAttributeReference); static extern IntPtr ClientReportControlBlock_create(string dataAttributeReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_destroy (IntPtr self); static extern void ClientReportControlBlock_destroy(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self); static extern bool ClientReportControlBlock_isBuffered(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getRptId (IntPtr self); static extern IntPtr ClientReportControlBlock_getRptId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId); static extern void ClientReportControlBlock_setRptId(IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self); static extern bool ClientReportControlBlock_getRptEna(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna); static extern void ClientReportControlBlock_setRptEna(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getResv (IntPtr self); static extern bool ClientReportControlBlock_getResv(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResv (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool resv); static extern void ClientReportControlBlock_setResv(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool resv);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getDataSetReference (IntPtr self); static extern IntPtr ClientReportControlBlock_getDataSetReference(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setDataSetReference (IntPtr self, string dataSetReference); static extern void ClientReportControlBlock_setDataSetReference(IntPtr self, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getConfRev (IntPtr self); static extern UInt32 ClientReportControlBlock_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getOptFlds (IntPtr self); static extern int ClientReportControlBlock_getOptFlds(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setOptFlds (IntPtr self, int optFlds); static extern void ClientReportControlBlock_setOptFlds(IntPtr self, int optFlds);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getBufTm (IntPtr self); static extern UInt32 ClientReportControlBlock_getBufTm(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setBufTm (IntPtr self, UInt32 bufTm); static extern void ClientReportControlBlock_setBufTm(IntPtr self, UInt32 bufTm);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReportControlBlock_getSqNum (IntPtr self); static extern UInt16 ClientReportControlBlock_getSqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReportControlBlock_getTrgOps (IntPtr self); static extern int ClientReportControlBlock_getTrgOps(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setTrgOps (IntPtr self, int trgOps); static extern void ClientReportControlBlock_setTrgOps(IntPtr self, int trgOps);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReportControlBlock_getIntgPd (IntPtr self); static extern UInt32 ClientReportControlBlock_getIntgPd(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd); static extern void ClientReportControlBlock_setIntgPd(IntPtr self, UInt32 intgPd);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getGI (IntPtr self); static extern bool ClientReportControlBlock_getGI(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool gi); static extern void ClientReportControlBlock_setGI(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool gi);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self); static extern bool ClientReportControlBlock_getPurgeBuf(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setPurgeBuf (IntPtr self, [MarshalAs(UnmanagedType.I1)] bool purgeBuf); static extern void ClientReportControlBlock_setPurgeBuf(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool purgeBuf);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_hasResvTms(IntPtr self); static extern bool ClientReportControlBlock_hasResvTms(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern Int16 ClientReportControlBlock_getResvTms (IntPtr self); static extern Int16 ClientReportControlBlock_getResvTms(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setResvTms (IntPtr self, Int16 resvTms); static extern void ClientReportControlBlock_setResvTms(IntPtr self, Int16 resvTms);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getEntryId (IntPtr self); static extern IntPtr ClientReportControlBlock_getEntryId(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setEntryId (IntPtr self, IntPtr entryId); static extern void ClientReportControlBlock_setEntryId(IntPtr self, IntPtr entryId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt64 ClientReportControlBlock_getEntryTime (IntPtr self); static extern UInt64 ClientReportControlBlock_getEntryTime(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientReportControlBlock_getOwner (IntPtr self); static extern IntPtr ClientReportControlBlock_getOwner(IntPtr self);
internal IntPtr self; internal IntPtr self;
@ -177,7 +175,7 @@ namespace IEC61850
private bool reportHandlerInstalled = false; private bool reportHandlerInstalled = false;
private event InternalReportHandler internalHandler = null; private event InternalReportHandler internalHandler = null;
private void resetSendFlags () private void resetSendFlags()
{ {
flagRptId = false; flagRptId = false;
flagRptEna = false; flagRptEna = false;
@ -197,28 +195,31 @@ namespace IEC61850
private Report report = null; private Report report = null;
private void internalReportHandler (IntPtr parameter, IntPtr report) private void internalReportHandler(IntPtr parameter, IntPtr report)
{
try
{ {
try {
if (this.report == null) if (this.report == null)
this.report = new Report (report); this.report = new Report(report);
if (reportHandler != null) if (reportHandler != null)
reportHandler(this.report, reportHandlerParameter); reportHandler(this.report, reportHandlerParameter);
} catch (Exception e) }
catch (Exception e)
{ {
// older versions of mono 2.10 (for linux?) cause this exception // older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
} }
} }
internal ReportControlBlock (string objectReference, IedConnection iedConnection, IntPtr connection) internal ReportControlBlock(string objectReference, IedConnection iedConnection, IntPtr connection)
{ {
self = ClientReportControlBlock_create (objectReference); self = ClientReportControlBlock_create(objectReference);
if (self != IntPtr.Zero) { if (self != IntPtr.Zero)
{
this.iedConnection = iedConnection; this.iedConnection = iedConnection;
this.objectReference = objectReference; this.objectReference = objectReference;
} }
@ -234,14 +235,16 @@ namespace IEC61850
/// <see cref="IEC61850.Client.ReportControlBlock"/> was occupying.</remarks> /// <see cref="IEC61850.Client.ReportControlBlock"/> was occupying.</remarks>
public void Dispose() public void Dispose()
{ {
lock (this) { lock (this)
if (self != IntPtr.Zero) { {
if (self != IntPtr.Zero)
{
iedConnection.UninstallReportHandler (objectReference); iedConnection.UninstallReportHandler(objectReference);
iedConnection.RemoveRCB (this); iedConnection.RemoveRCB(this);
ClientReportControlBlock_destroy (self); ClientReportControlBlock_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
} }
@ -250,12 +253,12 @@ namespace IEC61850
~ReportControlBlock() ~ReportControlBlock()
{ {
Dispose (); Dispose();
} }
public string GetObjectReference () public string GetObjectReference()
{ {
return this.objectReference; return objectReference;
} }
/// <summary> /// <summary>
@ -272,22 +275,23 @@ namespace IEC61850
/// <param name='parameter'> /// <param name='parameter'>
/// parameter is passed to the handler when the handler is invoked. /// parameter is passed to the handler when the handler is invoked.
/// </param> /// </param>
public void InstallReportHandler (ReportHandler reportHandler, object parameter) public void InstallReportHandler(ReportHandler reportHandler, object parameter)
{ {
this.reportHandler = new ReportHandler(reportHandler); this.reportHandler = new ReportHandler(reportHandler);
this.reportHandlerParameter = parameter; reportHandlerParameter = parameter;
if (reportHandlerInstalled == false) { if (reportHandlerInstalled == false)
{
string reportId = this.GetRptId (); string reportId = GetRptId();
if (internalHandler == null) if (internalHandler == null)
{ {
internalHandler = new InternalReportHandler(internalReportHandler); internalHandler = new InternalReportHandler(internalReportHandler);
} }
iedConnection.InstallReportHandler (objectReference, reportId, internalHandler); iedConnection.InstallReportHandler(objectReference, reportId, internalHandler);
reportHandlerInstalled = true; reportHandlerInstalled = true;
} }
@ -297,14 +301,14 @@ namespace IEC61850
/// Read all RCB values from the server /// Read all RCB values from the server
/// </summary> /// </summary>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void GetRCBValues () public void GetRCBValues()
{ {
int error; int error;
iedConnection.GetRCBValues (out error, objectReference, self); iedConnection.GetRCBValues(out error, objectReference, self);
if (error != 0) if (error != 0)
throw new IedConnectionException ("getRCBValues service failed", error); throw new IedConnectionException("getRCBValues service failed", error);
} }
/// <summary> /// <summary>
@ -327,9 +331,9 @@ namespace IEC61850
/// The RCB values are sent by a single MMS write request. /// The RCB values are sent by a single MMS write request.
/// </description> /// </description>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception> /// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void SetRCBValues () public void SetRCBValues()
{ {
SetRCBValues (true); SetRCBValues(true);
} }
private UInt32 CreateParametersMask() private UInt32 CreateParametersMask()
@ -403,7 +407,7 @@ namespace IEC61850
/// <param name='singleRequest'> /// <param name='singleRequest'>
/// If true the values are sent by single MMS write request. Otherwise the values are all sent by their own MMS write requests. /// If true the values are sent by single MMS write request. Otherwise the values are all sent by their own MMS write requests.
/// </param> /// </param>
public void SetRCBValues (bool singleRequest) public void SetRCBValues(bool singleRequest)
{ {
UInt32 parametersMask = CreateParametersMask(); UInt32 parametersMask = CreateParametersMask();
@ -411,18 +415,20 @@ namespace IEC61850
int error; int error;
iedConnection.SetRCBValues (out error, self, parametersMask, singleRequest); iedConnection.SetRCBValues(out error, self, parametersMask, singleRequest);
resetSendFlags(); resetSendFlags();
if (error != 0) if (error != 0)
throw new IedConnectionException ("setRCBValues service failed", error); throw new IedConnectionException("setRCBValues service failed", error);
if (flagRptId) { if (flagRptId)
{
if (reportHandlerInstalled) { if (reportHandlerInstalled)
{
reportHandlerInstalled = false; reportHandlerInstalled = false;
InstallReportHandler(this.reportHandler, this.reportHandlerParameter); InstallReportHandler(reportHandler, reportHandlerParameter);
} }
} }
} }
@ -433,9 +439,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// <c>true</c> if this instance is a buffered RCB; otherwise, <c>false</c>. /// <c>true</c> if this instance is a buffered RCB; otherwise, <c>false</c>.
/// </returns> /// </returns>
public bool IsBuffered () public bool IsBuffered()
{ {
return ClientReportControlBlock_isBuffered (self); return ClientReportControlBlock_isBuffered(self);
} }
/// <summary> /// <summary>
@ -447,9 +453,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// The entry time as ms timestamp /// The entry time as ms timestamp
/// </returns> /// </returns>
public UInt64 GetEntryTime () public UInt64 GetEntryTime()
{ {
return ClientReportControlBlock_getEntryTime (self); return ClientReportControlBlock_getEntryTime(self);
} }
/// <summary> /// <summary>
@ -461,13 +467,13 @@ namespace IEC61850
/// <returns> /// <returns>
/// The entry time as DataTimeOffset /// The entry time as DataTimeOffset
/// </returns> /// </returns>
public DateTimeOffset GetEntryTimeAsDateTimeOffset () public DateTimeOffset GetEntryTimeAsDateTimeOffset()
{ {
UInt64 entryTime = GetEntryTime (); UInt64 entryTime = GetEntryTime();
DateTimeOffset retVal = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero); DateTimeOffset retVal = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
return retVal.AddMilliseconds (entryTime); return retVal.AddMilliseconds(entryTime);
} }
/// <summary> /// <summary>
@ -479,14 +485,15 @@ namespace IEC61850
/// <returns>The entry ID</returns> /// <returns>The entry ID</returns>
public byte[] GetEntryID() public byte[] GetEntryID()
{ {
IntPtr entryIdRef = ClientReportControlBlock_getEntryId (self); IntPtr entryIdRef = ClientReportControlBlock_getEntryId(self);
if (entryIdRef == IntPtr.Zero) if (entryIdRef == IntPtr.Zero)
return null; return null;
else { else
MmsValue entryId = new MmsValue (entryIdRef); {
MmsValue entryId = new MmsValue(entryIdRef);
return entryId.getOctetString (); return entryId.getOctetString();
} }
} }
@ -496,11 +503,11 @@ namespace IEC61850
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);
} }
@ -512,11 +519,11 @@ namespace IEC61850
/// <returns> /// <returns>
/// The data set reference. /// The data set reference.
/// </returns> /// </returns>
public string GetDataSetReference () public string GetDataSetReference()
{ {
IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference (self); IntPtr dataSetRefPtr = ClientReportControlBlock_getDataSetReference(self);
return Marshal.PtrToStringAnsi (dataSetRefPtr); return Marshal.PtrToStringAnsi(dataSetRefPtr);
} }
/// <summary> /// <summary>
@ -525,9 +532,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// The data set reference. /// The data set reference.
/// </returns> /// </returns>
public void SetDataSetReference (string dataSetReference) public void SetDataSetReference(string dataSetReference)
{ {
ClientReportControlBlock_setDataSetReference (self, dataSetReference); ClientReportControlBlock_setDataSetReference(self, dataSetReference);
flagDataSetReference = true; flagDataSetReference = true;
} }
@ -538,11 +545,11 @@ namespace IEC61850
/// <returns> /// <returns>
/// The report identifier. /// The report identifier.
/// </returns> /// </returns>
public string GetRptId () public string GetRptId()
{ {
IntPtr rptIdPtr = ClientReportControlBlock_getRptId (self); IntPtr rptIdPtr = ClientReportControlBlock_getRptId(self);
return Marshal.PtrToStringAnsi (rptIdPtr); return Marshal.PtrToStringAnsi(rptIdPtr);
} }
/// <summary> /// <summary>
@ -551,7 +558,7 @@ namespace IEC61850
/// <param name='rptId'> /// <param name='rptId'>
/// The new RptId /// The new RptId
/// </param> /// </param>
public void SetRptId (string rptId) public void SetRptId(string rptId)
{ {
ClientReportControlBlock_setRptId(self, rptId); ClientReportControlBlock_setRptId(self, rptId);
flagRptId = true; flagRptId = true;
@ -563,9 +570,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, if reporting is enabled, false otherwise /// true, if reporting is enabled, false otherwise
/// </returns> /// </returns>
public bool GetRptEna () public bool GetRptEna()
{ {
return ClientReportControlBlock_getRptEna (self); return ClientReportControlBlock_getRptEna(self);
} }
/// <summary> /// <summary>
@ -574,9 +581,9 @@ namespace IEC61850
/// <param name='rptEna'> /// <param name='rptEna'>
/// true to enable reporting, false to disable /// true to enable reporting, false to disable
/// </param> /// </param>
public void SetRptEna (bool rptEna) public void SetRptEna(bool rptEna)
{ {
ClientReportControlBlock_setRptEna (self, rptEna); ClientReportControlBlock_setRptEna(self, rptEna);
flagRptEna = true; flagRptEna = true;
} }
@ -584,7 +591,7 @@ namespace IEC61850
/// Get the purgeBuf flag of the report control block /// Get the purgeBuf flag of the report control block
/// </summary> /// </summary>
/// <returns>the prugeBuf value</returns> /// <returns>the prugeBuf value</returns>
public bool GetPurgeBuf () public bool GetPurgeBuf()
{ {
return ClientReportControlBlock_getPurgeBuf(self); return ClientReportControlBlock_getPurgeBuf(self);
} }
@ -594,7 +601,7 @@ namespace IEC61850
/// </summary> /// </summary>
/// <description>This is only for buffered RCBs. If set to true the report buffer of a buffered RCB will be cleaned.</description> /// <description>This is only for buffered RCBs. If set to true the report buffer of a buffered RCB will be cleaned.</description>
/// <param name="purgeBuf">set to true to flush report buffer</param> /// <param name="purgeBuf">set to true to flush report buffer</param>
public void SetPurgeBuf (bool purgeBuf) public void SetPurgeBuf(bool purgeBuf)
{ {
ClientReportControlBlock_setPurgeBuf(self, purgeBuf); ClientReportControlBlock_setPurgeBuf(self, purgeBuf);
flagPurgeBuf = true; flagPurgeBuf = true;
@ -608,7 +615,7 @@ namespace IEC61850
/// </returns> /// </returns>
public UInt32 GetBufTm() public UInt32 GetBufTm()
{ {
return ClientReportControlBlock_getBufTm (self); return ClientReportControlBlock_getBufTm(self);
} }
/// <summary> /// <summary>
@ -617,9 +624,9 @@ namespace IEC61850
/// <param name='bufTm'> /// <param name='bufTm'>
/// Buffer time is ms. /// Buffer time is ms.
/// </param> /// </param>
public void SetBufTm (UInt32 bufTm) public void SetBufTm(UInt32 bufTm)
{ {
ClientReportControlBlock_setBufTm (self, bufTm); ClientReportControlBlock_setBufTm(self, bufTm);
flagBufTm = true; flagBufTm = true;
} }
@ -630,9 +637,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, if GI flag is set /// true, if GI flag is set
/// </returns> /// </returns>
public bool GetGI () public bool GetGI()
{ {
return ClientReportControlBlock_getGI (self); return ClientReportControlBlock_getGI(self);
} }
/// <summary> /// <summary>
@ -641,9 +648,9 @@ namespace IEC61850
/// <param name='GI'> /// <param name='GI'>
/// request general interrogation of true /// request general interrogation of true
/// </param> /// </param>
public void SetGI (bool GI) public void SetGI(bool GI)
{ {
ClientReportControlBlock_setGI (self, GI); ClientReportControlBlock_setGI(self, GI);
flagGI = true; flagGI = true;
} }
@ -653,9 +660,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// true, the RCB is reserver by a client /// true, the RCB is reserver by a client
/// </returns> /// </returns>
public bool GetResv () public bool GetResv()
{ {
return ClientReportControlBlock_getResv (self); return ClientReportControlBlock_getResv(self);
} }
/// <summary> /// <summary>
@ -664,9 +671,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// The conf rev. /// The conf rev.
/// </returns> /// </returns>
public UInt32 GetConfRev () public UInt32 GetConfRev()
{ {
return ClientReportControlBlock_getConfRev (self); return ClientReportControlBlock_getConfRev(self);
} }
/// <summary> /// <summary>
@ -675,9 +682,9 @@ namespace IEC61850
/// <param name='resv'> /// <param name='resv'>
/// true: reserver this RCB for exclusive use /// true: reserver this RCB for exclusive use
/// </param> /// </param>
public void SetResv (bool resv) public void SetResv(bool resv)
{ {
ClientReportControlBlock_setResv (self, resv); ClientReportControlBlock_setResv(self, resv);
flagResv = true; flagResv = true;
} }
@ -689,7 +696,7 @@ namespace IEC61850
/// </returns> /// </returns>
public TriggerOptions GetTrgOps() public TriggerOptions GetTrgOps()
{ {
return (TriggerOptions) ClientReportControlBlock_getTrgOps (self); return (TriggerOptions)ClientReportControlBlock_getTrgOps(self);
} }
/// <summary> /// <summary>
@ -700,7 +707,7 @@ namespace IEC61850
/// </param> /// </param>
public void SetTrgOps(TriggerOptions trgOps) public void SetTrgOps(TriggerOptions trgOps)
{ {
ClientReportControlBlock_setTrgOps (self, (int) trgOps); ClientReportControlBlock_setTrgOps(self, (int)trgOps);
flagTrgOps = true; flagTrgOps = true;
} }
@ -711,9 +718,9 @@ namespace IEC61850
/// <returns> /// <returns>
/// integrity period in ms /// integrity period in ms
/// </returns> /// </returns>
public UInt32 GetIntgPd () public UInt32 GetIntgPd()
{ {
return ClientReportControlBlock_getIntgPd (self); return ClientReportControlBlock_getIntgPd(self);
} }
/// <summary> /// <summary>
@ -722,9 +729,9 @@ namespace IEC61850
/// <param name='intgPd'> /// <param name='intgPd'>
/// integrity period in ms /// integrity period in ms
/// </param> /// </param>
public void SetIntgPd (UInt32 intgPd) public void SetIntgPd(UInt32 intgPd)
{ {
ClientReportControlBlock_setIntgPd (self, intgPd); ClientReportControlBlock_setIntgPd(self, intgPd);
flagIntgPd = true; flagIntgPd = true;
} }
@ -736,7 +743,7 @@ namespace IEC61850
/// </returns> /// </returns>
public ReportOptions GetOptFlds() public ReportOptions GetOptFlds()
{ {
return (ReportOptions) ClientReportControlBlock_getOptFlds (self); return (ReportOptions)ClientReportControlBlock_getOptFlds(self);
} }
/// <summary> /// <summary>
@ -747,7 +754,7 @@ namespace IEC61850
/// </param> /// </param>
public void SetOptFlds(ReportOptions optFlds) public void SetOptFlds(ReportOptions optFlds)
{ {
ClientReportControlBlock_setOptFlds (self, (int)optFlds); ClientReportControlBlock_setOptFlds(self, (int)optFlds);
flagOptFlds = true; flagOptFlds = true;
} }

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

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

@ -1,7 +1,7 @@
/* /*
* SampledValuedSubscriber.cs * SampledValuedSubscriber.cs
* *
* Copyright 2017 Michael Zillgith * Copyright 2017-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,9 +21,9 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
@ -41,7 +41,7 @@ namespace IEC61850
public class SVReceiver : IDisposable public class SVReceiver : IDisposable
{ {
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVReceiver_create (); private static extern IntPtr SVReceiver_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_disableDestAddrCheck(IntPtr self); private static extern void SVReceiver_disableDestAddrCheck(IntPtr self);
@ -63,7 +63,7 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private static extern bool SVReceiver_isRunning (IntPtr self); private static extern bool SVReceiver_isRunning(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern void SVReceiver_destroy(IntPtr self); private static extern void SVReceiver_destroy(IntPtr self);
@ -81,22 +81,22 @@ namespace IEC61850
public SVReceiver() public SVReceiver()
{ {
self = SVReceiver_create (); self = SVReceiver_create();
} }
public void SetInterfaceId(string interfaceId) public void SetInterfaceId(string interfaceId)
{ {
SVReceiver_setInterfaceId (self, interfaceId); SVReceiver_setInterfaceId(self, interfaceId);
} }
public void DisableDestAddrCheck() public void DisableDestAddrCheck()
{ {
SVReceiver_disableDestAddrCheck (self); SVReceiver_disableDestAddrCheck(self);
} }
public void EnableDestAddrCheck() public void EnableDestAddrCheck()
{ {
SVReceiver_enableDestAddrCheck (self); SVReceiver_enableDestAddrCheck(self);
} }
/// <summary> /// <summary>
@ -105,13 +105,13 @@ namespace IEC61850
/// <param name="subscriber">Subscriber.</param> /// <param name="subscriber">Subscriber.</param>
public void AddSubscriber(SVSubscriber subscriber) public void AddSubscriber(SVSubscriber subscriber)
{ {
SVReceiver_addSubscriber (self, subscriber.self); SVReceiver_addSubscriber(self, subscriber.self);
} }
public void RemoveSubscriber(SVSubscriber subscriber) public void RemoveSubscriber(SVSubscriber subscriber)
{ {
SVReceiver_removeSubscriber (self, subscriber.self); SVReceiver_removeSubscriber(self, subscriber.self);
} }
/// <summary> /// <summary>
@ -119,7 +119,7 @@ namespace IEC61850
/// </summary> /// </summary>
public void Start() public void Start()
{ {
SVReceiver_start (self); SVReceiver_start(self);
} }
/// <summary> /// <summary>
@ -127,12 +127,12 @@ namespace IEC61850
/// </summary> /// </summary>
public void Stop() public void Stop()
{ {
SVReceiver_stop (self); SVReceiver_stop(self);
} }
public bool IsRunning() public bool IsRunning()
{ {
return SVReceiver_isRunning (self); return SVReceiver_isRunning(self);
} }
/// <summary> /// <summary>
@ -145,16 +145,17 @@ namespace IEC61850
/// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> was occupying.</remarks> /// <see cref="IEC61850.SV.Subscriber.SVReceiver"/> was occupying.</remarks>
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
{
isDisposed = true; isDisposed = true;
SVReceiver_destroy (self); SVReceiver_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
} }
} }
~SVReceiver() ~SVReceiver()
{ {
Dispose (); Dispose();
} }
} }
@ -162,7 +163,7 @@ namespace IEC61850
/// <summary> /// <summary>
/// SV listener. /// SV listener.
/// </summary> /// </summary>
public delegate void SVUpdateListener (SVSubscriber report, object parameter, SVSubscriberASDU asdu); public delegate void SVUpdateListener(SVSubscriber report, object parameter, SVSubscriberASDU asdu);
/// <summary> /// <summary>
/// Sampled Values (SV) Subscriber /// Sampled Values (SV) Subscriber
@ -174,7 +175,7 @@ namespace IEC61850
public class SVSubscriber : IDisposable public class SVSubscriber : IDisposable
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalSVUpdateListener (IntPtr subscriber, IntPtr parameter, IntPtr asdu); private delegate void InternalSVUpdateListener(IntPtr subscriber, IntPtr parameter, IntPtr asdu);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SVSubscriber_create([Out] byte[] ethAddr, UInt16 appID); private static extern IntPtr SVSubscriber_create([Out] byte[] ethAddr, UInt16 appID);
@ -197,16 +198,19 @@ namespace IEC61850
private event InternalSVUpdateListener internalListener = null; private event InternalSVUpdateListener internalListener = null;
private void internalSVUpdateListener (IntPtr subscriber, IntPtr parameter, IntPtr asdu) private void internalSVUpdateListener(IntPtr subscriber, IntPtr parameter, IntPtr asdu)
{
try
{ {
try {
if (listener != null) { if (listener != null)
{
listener(this, listenerParameter, new SVSubscriberASDU(asdu)); listener(this, listenerParameter, new SVSubscriberASDU(asdu));
} }
} }
catch (Exception e) { catch (Exception e)
{
// older versions of mono 2.10 (for linux?) cause this exception // older versions of mono 2.10 (for linux?) cause this exception
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
} }
@ -214,34 +218,39 @@ namespace IEC61850
public SVSubscriber(byte[] ethAddr, UInt16 appID) public SVSubscriber(byte[] ethAddr, UInt16 appID)
{ {
if (ethAddr == null) { if (ethAddr == null)
self = SVSubscriber_create (IntPtr.Zero, appID); {
} else { self = SVSubscriber_create(IntPtr.Zero, appID);
}
else
{
if (ethAddr.Length != 6) if (ethAddr.Length != 6)
throw new ArgumentException ("ethAddr argument has to be of 6 byte size"); throw new ArgumentException("ethAddr argument has to be of 6 byte size");
self = SVSubscriber_create (ethAddr, appID); self = SVSubscriber_create(ethAddr, appID);
} }
} }
public void SetListener(SVUpdateListener listener, object parameter) public void SetListener(SVUpdateListener listener, object parameter)
{ {
this.listener = listener; this.listener = listener;
this.listenerParameter = parameter; listenerParameter = parameter;
if (internalListener == null) { if (internalListener == null)
internalListener = new InternalSVUpdateListener (internalSVUpdateListener); {
internalListener = new InternalSVUpdateListener(internalSVUpdateListener);
SVSubscriber_setListener (self, internalListener, IntPtr.Zero); SVSubscriber_setListener(self, internalListener, IntPtr.Zero);
} }
} }
public void Dispose() public void Dispose()
{ {
if (isDisposed == false) { if (isDisposed == false)
{
isDisposed = true; isDisposed = true;
SVSubscriber_destroy (self); SVSubscriber_destroy(self);
self = IntPtr.Zero; self = IntPtr.Zero;
} }
} }
@ -325,114 +334,114 @@ namespace IEC61850
private IntPtr self; private IntPtr self;
internal SVSubscriberASDU (IntPtr self) internal SVSubscriberASDU(IntPtr self)
{ {
this.self = self; this.self = self;
} }
public UInt16 GetSmpCnt() public UInt16 GetSmpCnt()
{ {
return SVSubscriber_ASDU_getSmpCnt (self); return SVSubscriber_ASDU_getSmpCnt(self);
} }
public string GetSvId() public string GetSvId()
{ {
return Marshal.PtrToStringAnsi (SVSubscriber_ASDU_getSvId(self)); return Marshal.PtrToStringAnsi(SVSubscriber_ASDU_getSvId(self));
} }
public string GetDatSet() public string GetDatSet()
{ {
return Marshal.PtrToStringAnsi (SVSubscriber_ASDU_getDatSet(self)); return Marshal.PtrToStringAnsi(SVSubscriber_ASDU_getDatSet(self));
} }
public UInt32 GetConfRev() public UInt32 GetConfRev()
{ {
return SVSubscriber_ASDU_getConfRev (self); return SVSubscriber_ASDU_getConfRev(self);
} }
public SmpMod GetSmpMod() public SmpMod GetSmpMod()
{ {
return (SmpMod) SVSubscriber_ASDU_getSmpMod (self); return (SmpMod)SVSubscriber_ASDU_getSmpMod(self);
} }
public UInt16 GetSmpRate() public UInt16 GetSmpRate()
{ {
return (UInt16)SVSubscriber_ASDU_getSmpRate (self); return SVSubscriber_ASDU_getSmpRate(self);
} }
public bool HasDatSet() public bool HasDatSet()
{ {
return SVSubscriber_ASDU_hasDatSet (self); return SVSubscriber_ASDU_hasDatSet(self);
} }
public bool HasRefrRm() public bool HasRefrRm()
{ {
return SVSubscriber_ASDU_hasRefrTm (self); return SVSubscriber_ASDU_hasRefrTm(self);
} }
public bool HasSmpMod() public bool HasSmpMod()
{ {
return SVSubscriber_ASDU_hasSmpMod (self); return SVSubscriber_ASDU_hasSmpMod(self);
} }
public bool HasSmpRate() public bool HasSmpRate()
{ {
return SVSubscriber_ASDU_hasSmpRate (self); return SVSubscriber_ASDU_hasSmpRate(self);
} }
public UInt64 GetRefrTmAsMs() public UInt64 GetRefrTmAsMs()
{ {
return SVSubscriber_ASDU_getRefrTmAsMs (self); return SVSubscriber_ASDU_getRefrTmAsMs(self);
} }
public sbyte GetINT8(int index) public sbyte GetINT8(int index)
{ {
return SVSubscriber_ASDU_getINT8 (self, index); return SVSubscriber_ASDU_getINT8(self, index);
} }
public Int16 GetINT16(int index) public Int16 GetINT16(int index)
{ {
return SVSubscriber_ASDU_getINT16 (self, index); return SVSubscriber_ASDU_getINT16(self, index);
} }
public Int32 GetINT32(int index) public Int32 GetINT32(int index)
{ {
return SVSubscriber_ASDU_getINT32 (self, index); return SVSubscriber_ASDU_getINT32(self, index);
} }
public Int64 GetINT64(int index) public Int64 GetINT64(int index)
{ {
return SVSubscriber_ASDU_getINT64 (self, index); return SVSubscriber_ASDU_getINT64(self, index);
} }
public byte GetINT8U(int index) public byte GetINT8U(int index)
{ {
return SVSubscriber_ASDU_getINT8U (self, index); return SVSubscriber_ASDU_getINT8U(self, index);
} }
public UInt16 GetINT16U(int index) public UInt16 GetINT16U(int index)
{ {
return SVSubscriber_ASDU_getINT16U (self, index); return SVSubscriber_ASDU_getINT16U(self, index);
} }
public UInt32 GetINT32U(int index) public UInt32 GetINT32U(int index)
{ {
return SVSubscriber_ASDU_getINT32U (self, index); return SVSubscriber_ASDU_getINT32U(self, index);
} }
public UInt64 GetINT64U(int index) public UInt64 GetINT64U(int index)
{ {
return SVSubscriber_ASDU_getINT64U (self, index); return SVSubscriber_ASDU_getINT64U(self, index);
} }
public float GetFLOAT32(int index) public float GetFLOAT32(int index)
{ {
return SVSubscriber_ASDU_getFLOAT32 (self, index); return SVSubscriber_ASDU_getFLOAT32(self, index);
} }
public double GetFLOAT64(int index) public double GetFLOAT64(int index)
{ {
return SVSubscriber_ASDU_getFLOAT64 (self, index); return SVSubscriber_ASDU_getFLOAT64(self, index);
} }
private struct PTimestamp private struct PTimestamp
@ -446,16 +455,16 @@ namespace IEC61850
public Timestamp GetTimestamp(int index) public Timestamp GetTimestamp(int index)
{ {
PTimestamp retVal = SVSubscriber_ASDU_getTimestamp (self, index); PTimestamp retVal = SVSubscriber_ASDU_getTimestamp(self, index);
return new Timestamp (retVal.val); return new Timestamp(retVal.val);
} }
public Quality GetQuality(int index) public Quality GetQuality(int index)
{ {
UInt16 qValue = SVSubscriber_ASDU_getQuality (self, index); UInt16 qValue = SVSubscriber_ASDU_getQuality(self, index);
return new Quality (qValue); return new Quality(qValue);
} }
/// <summary> /// <summary>
@ -464,7 +473,7 @@ namespace IEC61850
/// <returns>The payload data size in byte</returns> /// <returns>The payload data size in byte</returns>
public int GetDataSize() public int GetDataSize()
{ {
return SVSubscriber_ASDU_getDataSize (self); return SVSubscriber_ASDU_getDataSize(self);
} }
} }
} }

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

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

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

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

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

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

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

Loading…
Cancel
Save