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

v1.6
Michael Zillgith 4 weeks ago
commit 3da8aa5222

@ -0,0 +1,205 @@
/*
* AcseAuthenticationParameter.cs
*
* Copyright 2025-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
using System;
using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
/// <summary>
/// Authentication mechanism used by AcseAuthenticator
/// </summary>
public enum AcseAuthenticationMechanism
{
/** Neither ACSE nor TLS authentication used */
ACSE_AUTH_NONE = 0,
/** Use ACSE password for client authentication */
ACSE_AUTH_PASSWORD = 1,
/** Use ACSE certificate for client authentication */
ACSE_AUTH_CERTIFICATE = 2,
/** Use TLS certificate for client authentication */
ACSE_AUTH_TLS = 3
}
public class AcseAuthenticationParameter
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr AcseAuthenticationParameter_create();
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setAuthMechanism(IntPtr self, int mechanism);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void AcseAuthenticationParameter_setPassword(IntPtr self, string password);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int AcseAuthenticationParameter_getAuthMechanism(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr AcseAuthenticationParameter_getPassword(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int AcseAuthenticationParameter_getPasswordLength(IntPtr self);
private IntPtr self = IntPtr.Zero;
public AcseAuthenticationParameter()
{
self = AcseAuthenticationParameter_create();
}
public AcseAuthenticationParameter(IntPtr self)
{
this.self = self;
}
public void SetAuthMechanism(AcseAuthenticationMechanism acseAuthenticationMechanism)
{
AcseAuthenticationParameter_setAuthMechanism(self, (int)acseAuthenticationMechanism);
}
public void SetPassword(string password)
{
AcseAuthenticationParameter_setPassword(self, password);
}
public AcseAuthenticationMechanism GetAuthMechanism()
{
return (AcseAuthenticationMechanism)AcseAuthenticationParameter_getAuthMechanism(self);
}
public string GetPasswordString()
{
try
{
byte[] password = GetPasswordByteArray();
return Encoding.UTF8.GetString(password);
}
catch (Exception)
{
return null;
}
}
public byte[] GetPasswordByteArray()
{
IntPtr password = AcseAuthenticationParameter_getPassword(self);
if (password != IntPtr.Zero)
{
int lenght = GetPasswordLenght();
byte[] result = new byte[lenght];
Marshal.Copy(password, result, 0, lenght);
return result;
}
else
return null;
}
public int GetPasswordLenght()
{
return AcseAuthenticationParameter_getPasswordLength(self);
}
}
public class IsoApplicationReference
{
private IntPtr self = IntPtr.Zero;
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int IsoApplicationReference_getAeQualifier(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IsoApplicationReference_getApTitle(IntPtr self);
public IsoApplicationReference(IntPtr self)
{
this.self = self;
}
public int GetAeQualifier()
{
return IsoApplicationReference_getAeQualifier(self);
}
public ItuObjectIdentifier GetApTitle()
{
IntPtr identfier = IsoApplicationReference_getApTitle(self);
if (identfier == IntPtr.Zero)
return null;
return new ItuObjectIdentifier(identfier);
}
}
public class ItuObjectIdentifier
{
private IntPtr self = IntPtr.Zero;
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ItuObjectIdentifier_getArcCount(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ItuObjectIdentifier_getArc(IntPtr self);
public ItuObjectIdentifier(IntPtr self)
{
this.self = self;
}
public int GetArcCount()
{
return ItuObjectIdentifier_getArcCount(self);
}
public ushort[] GetArcs()
{
int count = ItuObjectIdentifier_getArcCount(self);
if (count <= 0 || count > 10) return Array.Empty<ushort>();
IntPtr arcPtr = ItuObjectIdentifier_getArc(self);
ushort[] arcs = new ushort[count];
short[] temp = new short[count];
Marshal.Copy(arcPtr, temp, 0, count);
for (int i = 0; i < count; i++)
arcs[i] = (ushort)temp[i];
return arcs;
}
}
}

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

@ -1,7 +1,7 @@
/* /*
* Control.cs * Control.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -21,15 +21,15 @@
* See COPYING file for the complete license text. * See COPYING file for the complete license text.
*/ */
using IEC61850.Common;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using IEC61850.Common;
namespace IEC61850 namespace IEC61850
{ {
// IEC 61850 common API parts (used by client and server API) // IEC 61850 common API parts (used by client and server API)
namespace Common { namespace Common
{
/// <summary> /// <summary>
/// Control model /// Control model
@ -39,7 +39,7 @@ namespace IEC61850
/** status only */ /** status only */
STATUS_ONLY = 0, STATUS_ONLY = 0,
/** direct with normal security */ /** direct with normal security */
DIRECT_NORMAL= 1, DIRECT_NORMAL = 1,
/** select before operate (SBO) with normal security */ /** select before operate (SBO) with normal security */
SBO_NORMAL = 2, SBO_NORMAL = 2,
/** direct with enhanced security */ /** direct with enhanced security */
@ -51,7 +51,8 @@ namespace IEC61850
/// <summary> /// <summary>
/// Originator category /// Originator category
/// </summary> /// </summary>
public enum OrCat { public enum OrCat
{
/** Not supported - should not be used */ /** Not supported - should not be used */
NOT_SUPPORTED = 0, NOT_SUPPORTED = 0,
/** Control operation issued from an operator using a client located at bay level */ /** Control operation issued from an operator using a client located at bay level */
@ -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;
} }

File diff suppressed because it is too large Load Diff

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

@ -1,7 +1,7 @@
/* /*
* IsoConnectionParameters.cs * IsoConnectionParameters.cs
* *
* Copyright 2014 Michael Zillgith * Copyright 2014-2025 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -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)
{ {

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save