->Add ICD test file example to .net Tools;

->Add IEC61850Model/SVControlBlock.cs;
->Add SVCBHandler to .net
v1.6
Maxson Ramon dos Anjos Medeiros 1 month ago
parent cc4f25d122
commit 5c6ef51159

@ -0,0 +1,57 @@
using IEC61850.Server;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
// IEC 61850 server API.
namespace Model
{
public enum SMVEvent
{
IEC61850_SVCB_EVENT_ENABLE = 1,
IEC61850_SVCB_EVENT_DISABLE = 0,
}
public class SVControlBlock : ModelNode
{
private IntPtr self = IntPtr.Zero;
public IedModel parent { get; }
internal IntPtr Self { get => self; }
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr SVControlBlock_create(string name, IntPtr parent, string svID,string dataSet, UInt32 confRev, uint smpMod,
UInt16 smpRate, uint optFlds, bool isUnicast);
/// <summary>
/// create a new Multicast/Unicast Sampled Value (SV) control block (SvCB)
/// Create a new Sampled Value control block(SvCB) and add it to the given logical node(LN)
/// </summary>
/// <param name="name">name of the SvCB relative to the parent LN</param>
/// <param name="parent">the parent LN</param>
/// <param name="svID">the application ID of the SvCB</param>
/// <param name="dataSet">the data set reference to be used by the SVCB</param>
/// <param name="confRev">the configuration revision</param>
/// <param name="smpMod">the sampling mode used</param>
/// <param name="smpRate">the sampling rate used</param>
/// <param name="optFlds"></param>
/// <param name="isUnicast">the optional element configuration</param>
public SVControlBlock(string name, IedModel parent, string svID, string dataSet, UInt32 confRev, uint smpMod,
UInt16 smpRate, uint optFlds, bool isUnicast)
{
this.self = SVControlBlock_create(name, parent.self, svID, dataSet, confRev, smpMod, smpRate, optFlds, isUnicast);
this.parent = parent;
}
public SVControlBlock(IntPtr self)
{
this.self = self;
}
}
}
}

@ -30,6 +30,7 @@ using System.Security.Cryptography;
using System.Xml.Linq;
using IEC61850.Client;
using IEC61850.Common;
using IEC61850.Model;
using IEC61850.TLS;
using static System.Collections.Specialized.BitVector32;
using static System.Net.Mime.MediaTypeNames;
@ -86,6 +87,9 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedModel_getDeviceByInst(IntPtr self, string ldInst);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedModel_getSVControlBlock(IntPtr self, IntPtr parentLN, string svcbName);
internal IntPtr self = IntPtr.Zero;
internal IedModel(IntPtr self)
@ -306,6 +310,16 @@ namespace IEC61850
return GetModelNodeFromNodeRef (nodeRef);
}
public SVControlBlock GetSVControlBlock(LogicalNode logicalNode, string svcbName)
{
IntPtr nodeRef = IedModel_getSVControlBlock(self, logicalNode.self, svcbName);
if (nodeRef == IntPtr.Zero)
return null;
return new SVControlBlock(nodeRef);
}
}
/// <summary>
@ -2497,8 +2511,8 @@ namespace IEC61850
///// <param name="svcb">the SVCB control block instance</param>
///// <param name="handler">the event handler to be used</param>
///// <param name="parameter">user provided parameter that is passed to the handler</param>
//[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
//public static extern void IedServer_setSVCBHandler(IntPtr self, IntPtr svcb, SVCBEventHandler handler, IntPtr parameter);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
public static extern void IedServer_setSVCBHandler(IntPtr self, IntPtr svcb, SVCBEventHandler handler, IntPtr parameter);
///// <summary>
///// callback handler for SVCB events
@ -2506,8 +2520,8 @@ namespace IEC61850
///// <param name="svcb">the related SVCB instance</param>
///// <param name="eventType">event type</param>
///// <param name="parameter">user defined parameter</param>
//[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
//public delegate void SVCBEventHandler(IntPtr svcb, int eventType, IntPtr parameter);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SVCBEventHandler(IntPtr svcb, int eventType, IntPtr parameter);
/// <summary>
/// callback handler to control client read access to data attributes
@ -3015,79 +3029,74 @@ namespace IEC61850
//------------
//public delegate bool InternalSVCBEventHandler(SampledValuesControlBlock sampledValuesControlBlock, SMVEvent sMVEvent, object parameter);
public delegate void InternalSVCBEventHandler(SVControlBlock sampledValuesControlBlock, SMVEvent sMVEvent, object parameter);
//private InternalSVCBEventHandler internalSVCBEventHandler = null;
private InternalSVCBEventHandler internalSVCBEventHandler = null;
//private object sVCBEventHandlerParameter = null;
private object sVCBEventHandlerParameter = null;
//private SVCBEventHandler sVCBEventHandler = null;
private SVCBEventHandler sVCBEventHandler = null;
//internal class SVCHandlerInfo
//{
// public SampledValuesControlBlock sampledValuesControlBlock = null;
// public GCHandle handle;
internal class SVCHandlerInfo
{
public SVControlBlock sampledValuesControlBlock = null;
public GCHandle handle;
// public InternalSVCBEventHandler internalSVCBEventHandler = null;
// public object svcHandlerParameter = null;
public InternalSVCBEventHandler internalSVCBEventHandler = null;
public object svcHandlerParameter = null;
// public SVCHandlerInfo(SampledValuesControlBlock sampledValuesControlBlock)
// {
// this.sampledValuesControlBlock = sampledValuesControlBlock;
// this.handle = GCHandle.Alloc(this);
// }
public SVCHandlerInfo(SVControlBlock sampledValuesControlBlock)
{
this.sampledValuesControlBlock = sampledValuesControlBlock;
this.handle = GCHandle.Alloc(this);
}
// ~SVCHandlerInfo()
// {
// this.handle.Free();
// }
//}
~SVCHandlerInfo()
{
this.handle.Free();
}
}
//private Dictionary<SampledValuesControlBlock, SVCHandlerInfo> svcHandlers = new Dictionary<SampledValuesControlBlock, SVCHandlerInfo>();
private Dictionary<SVControlBlock, SVCHandlerInfo> svcHandlers = new Dictionary<SVControlBlock, SVCHandlerInfo>();
//private SVCHandlerInfo GetSVCHandlerInfo(SampledValuesControlBlock sampledValuesControlBlock)
//{
// SVCHandlerInfo info;
private SVCHandlerInfo GetSVCHandlerInfo(SVControlBlock sampledValuesControlBlock)
{
SVCHandlerInfo info;
// svcHandlers.TryGetValue(sampledValuesControlBlock, out info);
svcHandlers.TryGetValue(sampledValuesControlBlock, out info);
// if (info == null)
// {
// info = new SVCHandlerInfo(sampledValuesControlBlock);
// svcHandlers.Add(sampledValuesControlBlock, info);
// }
if (info == null)
{
info = new SVCHandlerInfo(sampledValuesControlBlock);
svcHandlers.Add(sampledValuesControlBlock, info);
}
// return info;
//}
return info;
}
//public void SetSVCBHandler(InternalSVCBEventHandler handler, SampledValuesControlBlock sampledValuesControlBlock, object parameter)
//{
// SVCHandlerInfo info = GetSVCHandlerInfo(sampledValuesControlBlock);
public void SetSVCBHandler(InternalSVCBEventHandler handler, SVControlBlock sampledValuesControlBlock, object parameter)
{
SVCHandlerInfo info = GetSVCHandlerInfo(sampledValuesControlBlock);
// info.internalSVCBEventHandler = handler;
// info.svcHandlerParameter = parameter;
info.internalSVCBEventHandler = handler;
info.svcHandlerParameter = parameter;
// if (sVCBEventHandler == null)
// sVCBEventHandler = new SVCBEventHandler(InternalSVCBEventHandlerImplementation);
if (sVCBEventHandler == null)
sVCBEventHandler = new SVCBEventHandler(InternalSVCBEventHandlerImplementation);
// IedServer_setSVCBHandler(self, sampledValuesControlBlock.Self, sVCBEventHandler, GCHandle.ToIntPtr(info.handle));
//}
IedServer_setSVCBHandler(self, sampledValuesControlBlock.Self, sVCBEventHandler, GCHandle.ToIntPtr(info.handle));
}
//public enum SMVEvent
//{
// IEC61850_SVCB_EVENT_ENABLE = 1,
// IEC61850_SVCB_EVENT_DISABLE = 0,
//}
//private void InternalSVCBEventHandlerImplementation(IntPtr svcb, int eventType, IntPtr parameter)
//{
// GCHandle handle = GCHandle.FromIntPtr(parameter);
private void InternalSVCBEventHandlerImplementation(IntPtr svcb, int eventType, IntPtr parameter)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
// SVCHandlerInfo info = (SVCHandlerInfo)handle.Target;
SVCHandlerInfo info = (SVCHandlerInfo)handle.Target;
// if (info != null && info.internalSVCBEventHandler != null)
// info.internalSVCBEventHandler(info.sampledValuesControlBlock,(SMVEvent)eventType, info.svcHandlerParameter);
//}
if (info != null && info.internalSVCBEventHandler != null)
info.internalSVCBEventHandler(info.sampledValuesControlBlock, (SMVEvent)eventType, info.svcHandlerParameter);
}
public delegate MmsDataAccessError InternalReadAccessHandler(LogicalDevice ld, LogicalNode ln, DataObject dataObject, FunctionalConstraint fc, ClientConnection connection, object parameter);

@ -15,6 +15,7 @@ using System.Collections.Generic;
using System.Reflection.Metadata;
using IEC61850.Client;
using ReportControlBlock = IEC61850.Server.ReportControlBlock;
using IEC61850.Model;
namespace server_access_control
{
@ -222,18 +223,16 @@ namespace server_access_control
/* Handler for Sampled values control block
*/
//void sVCBEventHandler(SampledValuesControlBlock svcb, SMVEvent smvEvent, object parameter)
//{
// Console.WriteLine(svcb.GetNoASDU() + " event: "+ smvEvent.ToString() );
//}
//implement IedModel_getSVControlBlock && SVControlBlock
//SampledValuesControlBlock sampledValuesControlBlock = (SampledValuesControlBlock)iedModel.GetModelNodeByShortObjectReference("GenericIO/GGIO1.SPCSO1");
void SVCBEventHandler(SVControlBlock svcb, SMVEvent smvEvent, object parameter)
{
Console.WriteLine("SVControlBlock event " + smvEvent.ToString());
}
//iedServer.SetSVCBHandler(sVCBEventHandler,)
//LogicalNode logicalNode = (LogicalNode)iedModel.GetModelNodeByShortObjectReference("GenericIO/GGIO1");
//SVControlBlock sampledValuesControlBlock = iedModel.GetSVControlBlock(logicalNode, "MSVCB01");
//iedServer.SetSVCBHandler(SVCBEventHandler, sampledValuesControlBlock, null);
//SettingGroups
/*SettingGroups*/
LogicalDevice logicalDevice = (LogicalDevice)iedModel.GetModelNodeByShortObjectReference("GenericIO"); ;
SettingGroupControlBlock settingGroupControlBlock = logicalDevice.GetSettingGroupControlBlock();
@ -250,11 +249,11 @@ namespace server_access_control
DataAttribute dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.StrVal.setMag.f");
iedServer.UpdateFloatAttributeValue(dataAttribute, ptoc1Settings[actSG - 1].strVal);
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.opDlTmms.setVal");
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.OpDlTmms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].opDlTmms);
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.rsDlTmms.setVal");
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RsDlTmms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].rsDlTmms);
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.rstTms.setVal");
dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RstTms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].rstTms);
}

@ -1,81 +1,5 @@
MODEL(simpleIO){
LD(GenericIO){
LN(LLN0){
SG(1 5)
DO(Mod 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
DA(ctlModel 0 12 4 16 0)=0;
}
DO(Beh 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
}
DO(Health 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
}
DO(NamPlt 0){
DA(vendor 0 20 5 16 0)="MZ Automation";
DA(swRev 0 20 5 16 0)="1.3.0";
DA(d 0 20 5 16 0)="libiec61850 server example";
DA(configRev 0 20 5 16 0);
DA(ldNs 0 20 11 16 0);
}
DS(Events){
DE(GGIO1$ST$SPCSO1$stVal);
DE(GGIO1$ST$SPCSO2$stVal);
DE(GGIO1$ST$SPCSO3$stVal);
DE(GGIO1$ST$SPCSO4$stVal);
}
DS(Events2){
DE(GGIO1$ST$SPCSO1);
DE(GGIO1$ST$SPCSO2);
DE(GGIO1$ST$SPCSO3);
DE(GGIO1$ST$SPCSO4);
}
DS(Measurements){
DE(GGIO1$MX$AnIn1$mag$f);
DE(GGIO1$MX$AnIn1$q);
DE(GGIO1$MX$AnIn2$mag$f);
DE(GGIO1$MX$AnIn2$q);
DE(GGIO1$MX$AnIn3$mag$f);
DE(GGIO1$MX$AnIn3$q);
DE(GGIO1$MX$AnIn4$mag$f);
DE(GGIO1$MX$AnIn4$q);
}
DS(ServiceTracking){
DE(LTRK1$SR$SpcTrk);
DE(LTRK1$SR$DpcTrk);
DE(LTRK1$SR$IncTrk);
DE(LTRK1$SR$BscTrk);
DE(LTRK1$SR$UrcbTrk);
DE(LTRK1$SR$BrcbTrk);
DE(LTRK1$SR$GocbTrk);
DE(LTRK1$SR$SgcbTrk);
DE(LTRK1$SR$LocbTrk);
}
RC(EventsRCB01 Events1 0 Events2 1 24 175 50 1000);
RC(EventsIndexed01 Events2 0 Events 1 24 175 50 1000);
RC(EventsIndexed02 Events2 0 Events 1 24 175 50 1000);
RC(EventsIndexed03 Events2 0 Events 1 24 175 50 1000);
RC(Measurements01 Measurements 1 Measurements 1 16 239 50 1000);
RC(Measurements02 Measurements 1 Measurements 1 16 239 50 1000);
RC(Measurements03 Measurements 1 Measurements 1 16 239 50 1000);
RC(brcbServiceTracking01 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
RC(brcbServiceTracking02 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
RC(brcbServiceTracking03 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
LC(EventLog Events GenericIO/LLN0$EventLog 19 0 1 0);
LC(GeneralLog - - 19 0 0 0);
LOG();
LOG(EventLog);
GC(gcbEvents events Events 3 0 1000 3000){
PA(4 1 1000 010CCD010001);
}
}
LN(LPHD1){
DO(PhyNam 0){
DA(vendor 0 20 5 16 0);
@ -235,6 +159,85 @@ DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
}
}
LN(LLN0){
SG(1 5)
DO(Mod 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
DA(ctlModel 0 12 4 16 0)=0;
}
DO(Beh 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
}
DO(Health 0){
DA(stVal 0 12 0 17 0)=1;
DA(q 0 23 0 18 0);
DA(t 0 22 0 16 0);
}
DO(NamPlt 0){
DA(vendor 0 20 5 16 0)="MZ Automation";
DA(swRev 0 20 5 16 0)="1.3.0";
DA(d 0 20 5 16 0)="libiec61850 server example";
DA(configRev 0 20 5 16 0);
DA(ldNs 0 20 11 16 0);
}
DS(Events){
DE(GGIO1$ST$SPCSO1$stVal);
DE(GGIO1$ST$SPCSO2$stVal);
DE(GGIO1$ST$SPCSO3$stVal);
DE(GGIO1$ST$SPCSO4$stVal);
}
DS(Events2){
DE(GGIO1$ST$SPCSO1);
DE(GGIO1$ST$SPCSO2);
DE(GGIO1$ST$SPCSO3);
DE(GGIO1$ST$SPCSO4);
}
DS(Measurements){
DE(GGIO1$MX$AnIn1$mag$f);
DE(GGIO1$MX$AnIn1$q);
DE(GGIO1$MX$AnIn2$mag$f);
DE(GGIO1$MX$AnIn2$q);
DE(GGIO1$MX$AnIn3$mag$f);
DE(GGIO1$MX$AnIn3$q);
DE(GGIO1$MX$AnIn4$mag$f);
DE(GGIO1$MX$AnIn4$q);
}
DS(ServiceTracking){
DE(LTRK1$SR$SpcTrk);
DE(LTRK1$SR$DpcTrk);
DE(LTRK1$SR$IncTrk);
DE(LTRK1$SR$BscTrk);
DE(LTRK1$SR$UrcbTrk);
DE(LTRK1$SR$BrcbTrk);
DE(LTRK1$SR$GocbTrk);
DE(LTRK1$SR$SgcbTrk);
DE(LTRK1$SR$LocbTrk);
}
RC(EventsRCB01 Events1 0 Events2 1 24 175 50 1000);
RC(EventsIndexed01 Events2 0 Events 1 24 175 50 1000);
RC(EventsIndexed02 Events2 0 Events 1 24 175 50 1000);
RC(EventsIndexed03 Events2 0 Events 1 24 175 50 1000);
RC(Measurements01 Measurements 1 Measurements 1 16 239 50 1000);
RC(Measurements02 Measurements 1 Measurements 1 16 239 50 1000);
RC(Measurements03 Measurements 1 Measurements 1 16 239 50 1000);
RC(brcbServiceTracking01 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
RC(brcbServiceTracking02 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
RC(brcbServiceTracking03 ServiceTracking 1 ServiceTracking 1 19 228 0 0);
LC(EventLog Events GenericIO/LLN0$EventLog 19 0 1 0);
LC(GeneralLog - - 19 0 0 0);
LOG();
LOG(EventLog);
GC(gcbEvents events Events 3 0 1000 3000){
PA(4 1 1000 010CCD010001);
}
SMVC(MSVCB01 xxxxMUnn01 Events 0 0 0 1 0 ){
PA(4 123 4000 010CCD040001);
}
}
LN(PTOC1){
DO(Mod 0){
DA(stVal 0 12 0 17 0);

@ -8,12 +8,12 @@
</PropertyGroup>
<ItemGroup>
<None Remove="model.cfg" />
<None Remove="model..cfg" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="model.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<EmbeddedResource Include="model..cfg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

@ -16,6 +16,7 @@
<None Remove="ICDFiles\sampleModel.icd" />
<None Remove="ICDFiles\sampleModel_errors.icd" />
<None Remove="ICDFiles\sampleModel_with_dataset.icd" />
<None Remove="ICDFiles\simpleIO_access_control.icd" />
<None Remove="ICDFiles\simpleIO_control_tests.cid" />
<None Remove="ICDFiles\simpleIO_direct_control.cid" />
<None Remove="ICDFiles\simpleIO_direct_control.icd" />
@ -49,6 +50,9 @@
<EmbeddedResource Include="ICDFiles\sampleModel_with_dataset.icd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ICDFiles\simpleIO_access_control.icd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ICDFiles\simpleIO_control_tests.cid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>

Loading…
Cancel
Save