- added .NET wrapper for RCBEventHandler

pull/374/head
Michael Zillgith 4 years ago
parent 94563cb9f6
commit d036b09712

@ -1,7 +1,7 @@
/*
* IEC61850ServerAPI.cs
*
* Copyright 2016 Michael Zillgith
* Copyright 2016-2022 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -331,12 +331,19 @@ namespace IEC61850
this.parent = parent;
}
internal Dictionary<IntPtr, ReportControlBlock> rcbs = new Dictionary<IntPtr, ReportControlBlock>();
public LogicalNode(string name, LogicalDevice parent)
{
this.parent = parent;
base.self = LogicalNode_create(name, parent.self);
}
internal void AddRcb(ReportControlBlock rcb)
{
rcbs.Add(rcb.self, rcb);
}
}
public enum AccessPolicy {
@ -1301,12 +1308,27 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ReportControlBlock_setPreconfiguredClient(IntPtr self, byte type, [Out] byte[] buf);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern string ReportControlBlock_getName(IntPtr self);
public IntPtr self = IntPtr.Zero;
private string name = null;
private LogicalNode parent = null;
public ReportControlBlock(string name, LogicalNode parent, string rptId, bool isBuffered,
string dataSetName, uint confRev, byte trgOps, byte options, uint bufTm, uint intgPd)
{
self = ReportControlBlock_create(name, parent.self, rptId, isBuffered, dataSetName, confRev, trgOps, options, bufTm, intgPd);
parent.AddRcb(this);
this.parent = parent;
}
internal ReportControlBlock(IntPtr self, LogicalNode parent)
{
this.parent = parent;
this.self = self;
parent.AddRcb(this);
}
public void SetPreconfiguredClient(byte[] clientAddress)
@ -1316,6 +1338,28 @@ namespace IEC61850
else if (clientAddress.Length == 6)
ReportControlBlock_setPreconfiguredClient(self, 6, clientAddress);
}
public string Name
{
get
{
if (name == null)
{
name = ReportControlBlock_getName(self);
}
return name;
}
}
public LogicalNode Parent
{
get
{
return parent;
}
}
}
/// <summary>
@ -1691,6 +1735,47 @@ namespace IEC61850
public delegate void GoCBEventHandler(MmsGooseControlBlock goCB, int cbEvent, object parameter);
/// <summary>
/// Report control block event types
/// </summary>
public enum RCBEventType
{
/// <summary>
/// parameter read by client (not implemented).
/// </summary>
GET_PARAMETER = 0,
/// <summary>
/// parameter set by client.
/// </summary>
SET_PARAMETER = 1,
/// <summary>
/// reservation canceled.
/// </summary>
UNRESERVED = 2,
/// <summary>
/// reservation
/// </summary>
RESERVED = 3,
/// <summary>
/// RCB enabled
/// </summary>
ENABLED = 4,
/// <summary>
/// RCB disabled
/// </summary>
DISABLED = 5,
/// <summary>
/// GI report triggered
/// </summary>
GI = 6,
/// <summary>
/// Purge buffer procedure executed
/// </summary>
PURGEBUF = 7
}
public delegate void RCBEventHandler(object parameter, ReportControlBlock rcb, ClientConnection con, RCBEventType eventType, string parameterName, MmsDataAccessError serviceError);
public delegate MmsDataAccessError WriteAccessHandler (DataAttribute dataAttr, MmsValue value,
ClientConnection connection, object parameter);
@ -1917,6 +2002,12 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setGoCBHandler(IntPtr self, InternalGoCBEventHandler handler, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void InternalRCBEventHandler(IntPtr paramter, IntPtr rcb, IntPtr connection, int eventType, string parameterName, int serviceError);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setRCBEventHandler(IntPtr self, InternalRCBEventHandler handler, IntPtr parameter);
private IntPtr self = IntPtr.Zero;
private InternalControlHandler internalControlHandlerRef = null;
@ -2561,6 +2652,70 @@ namespace IEC61850
}
}
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ReportControlBlock_getParent(IntPtr self);
private RCBEventHandler rcbEventHandler = null;
private object rcbEventHandlerParameter = null;
private InternalRCBEventHandler internalRCBEventHandler = null;
private void InternalRCBEventHandlerImplementation(IntPtr parameter, IntPtr rcb, IntPtr connection, int eventType, string parameterName, int serviceError)
{
if (rcbEventHandler != null)
{
ClientConnection con = null;
if (connection != IntPtr.Zero)
{
this.clientConnections.TryGetValue(connection, out con);
}
ReportControlBlock reportControlBlock = null;
if (rcb != IntPtr.Zero)
{
IntPtr lnPtr = ReportControlBlock_getParent(rcb);
if (lnPtr != IntPtr.Zero)
{
ModelNode lnModelNode = iedModel.GetModelNodeFromNodeRef(lnPtr);
if (lnModelNode != null)
{
LogicalNode ln = lnModelNode as LogicalNode;
if (ln.rcbs.TryGetValue(rcb, out reportControlBlock) == false)
{
reportControlBlock = new ReportControlBlock(rcb, ln);
}
}
}
}
rcbEventHandler.Invoke(rcbEventHandlerParameter, reportControlBlock, con, (RCBEventType)eventType, parameterName, (MmsDataAccessError)serviceError);
}
}
/// <summary>
/// Set a callback handler for RCB events
/// </summary>
/// <param name="handler">the callback handler</param>
/// <param name="parameter">user provided parameter that is passed to the callback handler</param>
public void SetRCBEventHandler(RCBEventHandler handler, object parameter)
{
rcbEventHandler = handler;
rcbEventHandlerParameter = parameter;
if (internalRCBEventHandler == null)
{
internalRCBEventHandler = new InternalRCBEventHandler(InternalRCBEventHandlerImplementation);
IedServer_setRCBEventHandler(self, internalRCBEventHandler, IntPtr.Zero);
}
}
}
}

@ -67,6 +67,18 @@ namespace server1
}, null);
iedServer.SetRCBEventHandler(delegate (object parameter, ReportControlBlock rcb, ClientConnection con, RCBEventType eventType, string parameterName, MmsDataAccessError serviceError)
{
Console.WriteLine("RCB: " + rcb.Parent.GetObjectReference() + "." + rcb.Name + " event: " + eventType.ToString());
if (eventType == RCBEventType.SET_PARAMETER)
{
Console.WriteLine(" param: " + parameterName);
Console.WriteLine(" result: " + serviceError.ToString());
}
}, null);
iedServer.Start(102);
if (iedServer.IsRunning())

Loading…
Cancel
Save