diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs index 0b7413e1..8a0914a2 100644 --- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs +++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs @@ -749,6 +749,9 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern int ModelNode_getType(IntPtr self); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ModelNode_getObjectReference(IntPtr self, IntPtr objectReference); + public IntPtr self; internal ModelNode() @@ -787,9 +790,24 @@ namespace IEC61850 } } - } + public string GetObjectReference() + { + IntPtr objRefPtr = ModelNode_getObjectReference(self, IntPtr.Zero); + + if (objRefPtr != IntPtr.Zero) { + string objRef = Marshal.PtrToStringAnsi(objRefPtr); + Marshal.FreeHGlobal(objRefPtr); + + return objRef; + } + else { + return null; + } + } + + } public class DataSet { @@ -1021,6 +1039,42 @@ namespace IEC61850 public delegate MmsDataAccessError WriteAccessHandler (DataAttribute dataAttr, MmsValue value, ClientConnection connection, object parameter); + /// + /// Reason for the select state change + /// + public enum SelectStateChangedReason + { + /// + /// Control has been selected + /// + SELECT_STATE_REASON_SELECTED = 0, + /// + /// Cancel received for the control + /// + SELECT_STATE_REASON_CANCELED = 1, + /// + /// Unselected due to timeout (sboTimeout) + /// + SELECT_STATE_REASON_TIMEOUT = 2, + /// + /// Unselected due to successful operate + /// + SELECT_STATE_REASON_OPERATED = 3, + /// + /// Unselected due to failed operate + /// + SELECT_STATE_REASON_OPERATE_FAILED = 4, + /// + /// Unselected due to disconnection of selecting client + /// + SELECT_STATE_REASON_DISCONNECTED = 5 + } + + public delegate void ControlSelectStateChangedHandler(ControlAction action, object parameter, bool isSelected, SelectStateChangedReason reason); + + /// + /// Return type of ControlHandler and ControlWaitForExecutionHandler + /// public enum ControlHandlerResult { /// /// check or operation failed @@ -1141,6 +1195,9 @@ namespace IEC61850 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate int InternalControlHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void InternalSelectStateChangedHandler(IntPtr action, IntPtr parameter, [MarshalAs(UnmanagedType.I1)] bool isSelected, int reason); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern void IedServer_setWaitForExecutionHandler(IntPtr self, IntPtr node, InternalControlWaitForExecutionHandler handler, IntPtr parameter); @@ -1150,6 +1207,9 @@ namespace IEC61850 [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern void IedServer_setControlHandler (IntPtr self, IntPtr node, InternalControlHandler handler, IntPtr parameter); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] + static extern void IedServer_setSelectStateChangedHandler(IntPtr self, IntPtr node, InternalSelectStateChangedHandler handler, IntPtr parameter); + [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] static extern void IedServer_setWriteAccessPolicy(IntPtr self, FunctionalConstraint fc, AccessPolicy policy); @@ -1182,6 +1242,7 @@ namespace IEC61850 private InternalControlHandler internalControlHandlerRef = null; private InternalControlPerformCheckHandler internalControlPerformCheckHandlerRef = null; private InternalControlWaitForExecutionHandler internalControlWaitForExecutionHandlerRef = null; + private InternalSelectStateChangedHandler internalSelectedStateChangedHandlerRef = null; internal class ControlHandlerInfo { public DataObject controlObject = null; @@ -1196,15 +1257,19 @@ namespace IEC61850 public ControlWaitForExecutionHandler waitForExecHandler = null; public object waitForExecHandlerParameter = null; + public ControlSelectStateChangedHandler selectStateChangedHandler = null; + public object selectStateChangedHandlerParameter = null; + public ControlHandlerInfo(DataObject controlObject) { this.controlObject = controlObject; this.handle = GCHandle.Alloc(this); } - ~ControlHandlerInfo() { + + ~ControlHandlerInfo() + { this.handle.Free(); } - } private Dictionary controlHandlers = new Dictionary (); @@ -1217,7 +1282,7 @@ namespace IEC61850 ControlAction controlAction = new ControlAction (action, info, this); - if (info != null & info.controlHandler != null) + if (info != null && info.controlHandler != null) return (int)info.controlHandler (controlAction, info.controlHandlerParameter, new MmsValue (ctlVal), test); else return (int)ControlHandlerResult.FAILED; @@ -1229,8 +1294,8 @@ namespace IEC61850 ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; - if (info != null & info.checkHandler != null) { - + if (info != null && info.checkHandler != null) + { ControlAction controlAction = new ControlAction (action, info, this); return (int)info.checkHandler (controlAction, info.checkHandlerParameter, new MmsValue (ctlVal), test, interlockCheck); @@ -1244,8 +1309,8 @@ namespace IEC61850 ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; - if (info != null & info.waitForExecHandler != null) { - + if (info != null && info.waitForExecHandler != null) + { ControlAction controlAction = new ControlAction (action, info, this); return (int)info.waitForExecHandler (controlAction, info.waitForExecHandlerParameter, new MmsValue (ctlVal), test, synchoCheck); @@ -1254,6 +1319,20 @@ namespace IEC61850 return (int)ControlHandlerResult.FAILED; } + void InternalSelectStateChangedHandlerImpl(IntPtr action, IntPtr parameter, bool isSelected, int reason) + { + GCHandle handle = GCHandle.FromIntPtr(parameter); + + ControlHandlerInfo info = (ControlHandlerInfo)handle.Target; + + if (info != null && info.selectStateChangedHandler != null) + { + ControlAction controlAction = new ControlAction(action, info, this); + + info.selectStateChangedHandler(controlAction, info.selectStateChangedHandlerParameter, isSelected, (SelectStateChangedReason)reason); + } + } + private struct WriteAccessHandlerInfo { public WriteAccessHandler handler; public object parameter; @@ -1269,7 +1348,6 @@ namespace IEC61850 int WriteAccessHandlerImpl (IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter) { - //object info = writeAccessHandlers.Item [dataAttribute]; WriteAccessHandlerInfo info; writeAccessHandlers.TryGetValue (dataAttribute, out info); @@ -1333,15 +1411,6 @@ namespace IEC61850 self = IedServer_createWithConfig (iedModel.self, nativeTLSConfig, nativeConfig); } - // causes undefined behavior - //~IedServer() - //{ - // if (self != IntPtr.Zero) - // { - // IedServer_destroy(self); - // } - //} - private InternalConnectionHandler internalConnectionHandler = null; /// @@ -1484,11 +1553,29 @@ namespace IEC61850 IedServer_setWaitForExecutionHandler(self, controlObject.self, internalControlWaitForExecutionHandlerRef, GCHandle.ToIntPtr(info.handle)); } - + + /// + /// Set a callback handler for a controllable data object to track select state changes + /// + /// Control object. + /// Handler. + /// A user provided parameter that is passed to the callback handler. + public void SetSelectStateChangedHandler(DataObject controlObject, ControlSelectStateChangedHandler handler, object parameter) + { + ControlHandlerInfo info = GetControlHandlerInfo(controlObject); + + info.selectStateChangedHandler = handler; + info.selectStateChangedHandlerParameter = parameter; + + if (internalSelectedStateChangedHandlerRef == null) + internalSelectedStateChangedHandlerRef = new InternalSelectStateChangedHandler(InternalSelectStateChangedHandlerImpl); + + IedServer_setSelectStateChangedHandler(self, controlObject.self, internalSelectedStateChangedHandlerRef, GCHandle.ToIntPtr(info.handle)); + } + public void HandleWriteAccess (DataAttribute dataAttr, WriteAccessHandler handler, object parameter) { writeAccessHandlers.Add (dataAttr.self, new WriteAccessHandlerInfo(handler, parameter, dataAttr)); - //writeAccessHandlers.Item [dataAttr.self] = handler; IedServer_handleWriteAccess (self, dataAttr.self, WriteAccessHandlerImpl, IntPtr.Zero); } diff --git a/dotnet/server1/Program.cs b/dotnet/server1/Program.cs index 8853382b..bef0da90 100644 --- a/dotnet/server1/Program.cs +++ b/dotnet/server1/Program.cs @@ -51,27 +51,45 @@ namespace server1 return ControlHandlerResult.OK; }, null); + DataObject spcso2 = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/GGIO1.SPCSO2"); + + iedServer.SetSelectStateChangedHandler (spcso2, delegate (ControlAction action, object parameter, bool isSelected, SelectStateChangedReason reason) { + DataObject cObj = action.GetControlObject(); + + Console.WriteLine("Control object " + cObj.GetObjectReference() + (isSelected ? " selected" : " unselected") + " reason: " + reason.ToString()); + + }, null); + iedServer.Start (102); - Console.WriteLine ("Server started"); - GC.Collect (); + if (iedServer.IsRunning()) + { + Console.WriteLine("Server started"); - DataObject ggio1AnIn1 = (DataObject)iedModel.GetModelNodeByShortObjectReference ("GenericIO/GGIO1.AnIn1"); + GC.Collect(); - DataAttribute ggio1AnIn1magF = (DataAttribute)ggio1AnIn1.GetChild ("mag.f"); - DataAttribute ggio1AnIn1T = (DataAttribute)ggio1AnIn1.GetChild ("t"); + DataObject ggio1AnIn1 = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/GGIO1.AnIn1"); - float floatVal = 1.0f; + DataAttribute ggio1AnIn1magF = (DataAttribute)ggio1AnIn1.GetChild("mag.f"); + DataAttribute ggio1AnIn1T = (DataAttribute)ggio1AnIn1.GetChild("t"); - while (running) { - floatVal += 1f; - iedServer.UpdateTimestampAttributeValue (ggio1AnIn1T, new Timestamp (DateTime.Now)); - iedServer.UpdateFloatAttributeValue (ggio1AnIn1magF, floatVal); - Thread.Sleep (100); - } + float floatVal = 1.0f; + + while (running) + { + floatVal += 1f; + iedServer.UpdateTimestampAttributeValue(ggio1AnIn1T, new Timestamp(DateTime.Now)); + iedServer.UpdateFloatAttributeValue(ggio1AnIn1magF, floatVal); + Thread.Sleep(100); + } - iedServer.Stop (); - Console.WriteLine ("Server stopped"); + iedServer.Stop(); + Console.WriteLine("Server stopped"); + } + else + { + Console.WriteLine("Failed to start server"); + } iedServer.Destroy (); } diff --git a/dotnet/server1/model.cfg b/dotnet/server1/model.cfg index 6f332425..1136df8d 100644 --- a/dotnet/server1/model.cfg +++ b/dotnet/server1/model.cfg @@ -2,13 +2,12 @@ MODEL(simpleIO){ LD(GenericIO){ LN(LLN0){ DO(Mod 0){ -DA(stVal 0 12 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); DA(ctlModel 0 12 4 0 0)=0; } DO(Beh 0){ -DA(stVal 0 12 0 1 0); +DA(stVal 0 3 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); } @@ -24,30 +23,22 @@ DA(d 0 20 5 0 0); DA(configRev 0 20 5 0 0); DA(ldNs 0 20 11 0 0); } -DS(Events){ +DS(ControlEvents){ DE(GGIO1$ST$SPCSO1$stVal); DE(GGIO1$ST$SPCSO2$stVal); DE(GGIO1$ST$SPCSO3$stVal); DE(GGIO1$ST$SPCSO4$stVal); -} -DS(AnalogValues){ -DE(GGIO1$MX$AnIn1); -DE(GGIO1$MX$AnIn2); -DE(GGIO1$MX$AnIn3); -DE(GGIO1$MX$AnIn4); -} -RC(EventsRCB01 Events 0 Events 1 24 111 50 1000); -RC(AnalogValuesRCB01 AnalogValues 0 AnalogValues 1 24 111 50 1000); -LC(EventLog Events GenericIO/LLN0$EventLog 19 0 0 1); -LC(GeneralLog - - 19 0 0 1); -LOG(GeneralLog); -LOG(EventLog); -GC(gcbEvents events Events 2 0 -1 -1 ){ -PA(4 273 4096 010ccd010001); -} -GC(gcbAnalogValues analog AnalogValues 2 0 -1 -1 ){ -PA(4 273 4096 010ccd010001); -} +DE(GGIO1$ST$SPCSO5$stVal); +DE(GGIO1$ST$SPCSO6$stVal); +DE(GGIO1$ST$SPCSO7$stVal); +DE(GGIO1$ST$SPCSO8$stVal); +DE(GGIO1$ST$SPCSO9$stVal); +DE(GGIO1$ST$SPCSO2$stSeld); +DE(GGIO1$OR$SPCSO2$opRcvd); +DE(GGIO1$OR$SPCSO2$opOk); +} +RC(ControlEventsRCB01 ControlEvents 0 ControlEvents 1 17 239 0 1000); +RC(ControlEventsRCB02 ControlEvents 0 ControlEvents 1 17 239 0 1000); } LN(LPHD1){ DO(PhyNam 0){ @@ -66,13 +57,12 @@ DA(t 0 22 0 0 0); } LN(GGIO1){ DO(Mod 0){ -DA(stVal 0 12 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); DA(ctlModel 0 12 4 0 0)=0; } DO(Beh 0){ -DA(stVal 0 12 0 1 0); +DA(stVal 0 3 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); } @@ -94,11 +84,11 @@ DA(q 0 23 1 2 0); DA(t 0 22 1 0 0); } DO(AnIn2 0){ -DA(mag 0 27 1 1 101){ +DA(mag 0 27 1 1 0){ DA(f 0 10 1 1 0); } DA(q 0 23 1 2 0); -DA(t 0 22 1 0 102); +DA(t 0 22 1 0 0); } DO(AnIn3 0){ DA(mag 0 27 1 1 0){ @@ -115,8 +105,6 @@ DA(q 0 23 1 2 0); DA(t 0 22 1 0 0); } DO(SPCSO1 0){ -DA(stVal 0 0 0 1 0); -DA(q 0 23 0 2 0); DA(Oper 0 27 12 0 0){ DA(ctlVal 0 0 12 0 0); DA(origin 0 27 12 0 0){ @@ -128,12 +116,13 @@ DA(T 0 22 12 0 0); DA(Test 0 0 12 0 0); DA(Check 0 24 12 0 0); } -DA(ctlModel 0 12 4 0 0)=1; +DA(stVal 0 0 0 1 0); +DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=1; } DO(SPCSO2 0){ -DA(stVal 0 0 0 1 0); -DA(q 0 23 0 2 0); +DA(SBO 0 17 12 0 0); DA(Oper 0 27 12 0 0){ DA(ctlVal 0 0 12 0 0); DA(origin 0 27 12 0 0){ @@ -145,12 +134,28 @@ DA(T 0 22 12 0 0); DA(Test 0 0 12 0 0); DA(Check 0 24 12 0 0); } -DA(ctlModel 0 12 4 0 0)=1; -DA(t 0 22 0 0 0); +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); } -DO(SPCSO3 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); +DA(t 0 22 0 0 0); +DA(stSeld 0 0 0 1 0); +DA(opRcvd 0 0 9 1 0); +DA(opOk 0 0 9 1 0); +DA(tOpOk 0 22 9 0 0); +DA(ctlModel 0 12 4 0 0)=2; +DA(sboTimeout 0 9 4 1 0)=2000; +DA(sboClass 0 12 4 0 0); +} +DO(SPCSO3 0){ DA(Oper 0 27 12 0 0){ DA(ctlVal 0 0 12 0 0); DA(origin 0 27 12 0 0){ @@ -162,12 +167,33 @@ DA(T 0 22 12 0 0); DA(Test 0 0 12 0 0); DA(Check 0 24 12 0 0); } -DA(ctlModel 0 12 4 0 0)=1; -DA(t 0 22 0 0 0); +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); } -DO(SPCSO4 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); +DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=3; +} +DO(SPCSO4 0){ +DA(SBOw 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} DA(Oper 0 27 12 0 0){ DA(ctlVal 0 0 12 0 0); DA(origin 0 27 12 0 0){ @@ -179,58 +205,200 @@ DA(T 0 22 12 0 0); DA(Test 0 0 12 0 0); DA(Check 0 24 12 0 0); } -DA(ctlModel 0 12 4 0 0)=1; -DA(t 0 22 0 0 0); +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); } -DO(Ind1 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=4; +} +DO(SPCSO5 0){ +DA(Oper 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); } -DO(Ind2 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=1; +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +} +} +DO(SPCSO6 0){ +DA(SBO 0 17 12 0 0); +DA(Oper 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); } -DO(Ind3 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=2; +} +DO(SPCSO7 0){ +DA(Oper 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); } -DO(Ind4 0){ DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=3; } +DO(SPCSO8 0){ +DA(SBOw 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); } -LN(PDUP1){ -DO(Beh 0){ -DA(stVal 0 12 0 1 0); +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} +DA(Oper 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(operTm 0 22 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +} +DA(origin 0 27 0 0 0){ +DA(orCat 0 12 0 0 0); +DA(orIdent 0 13 0 0 0); +} +DA(ctlNum 0 6 0 0 0); +DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); +DA(ctlModel 0 12 4 0 0)=4; } -DO(Mod 0){ -DA(stVal 0 12 0 1 0); +DO(SPCSO9 0){ +DA(Oper 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +DA(Check 0 24 12 0 0); +} +DA(Cancel 0 27 12 0 0){ +DA(ctlVal 0 0 12 0 0); +DA(origin 0 27 12 0 0){ +DA(orCat 0 12 12 0 0); +DA(orIdent 0 13 12 0 0); +} +DA(ctlNum 0 6 12 0 0); +DA(T 0 22 12 0 0); +DA(Test 0 0 12 0 0); +} +DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); -DA(ctlModel 0 12 4 0 0)=0; +DA(ctlModel 0 12 4 0 0)=3; } -DO(Str 0){ -DA(general 0 0 0 1 0); -DA(dirGeneral 0 12 0 1 0); +DO(Ind1 0){ +DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); } -DO(Op 0){ -DA(general 0 0 0 1 0); +DO(Ind2 0){ +DA(stVal 0 0 0 1 0); DA(q 0 23 0 2 0); DA(t 0 22 0 0 0); } -DO(OpDlTmms 0){ -DA(setVal 0 3 2 1 0); +DO(Ind3 0){ +DA(stVal 0 0 0 1 0); +DA(q 0 23 0 2 0); +DA(t 0 22 0 0 0); } -DO(RsDlTmms 0){ -DA(setVal 0 3 2 1 0); +DO(Ind4 0){ +DA(stVal 0 0 0 1 0); +DA(q 0 23 0 2 0); +DA(t 0 22 0 0 0); } } } diff --git a/src/iec61850/inc/iec61850_server.h b/src/iec61850/inc/iec61850_server.h index 77cc75ca..4e5bee3a 100644 --- a/src/iec61850/inc/iec61850_server.h +++ b/src/iec61850/inc/iec61850_server.h @@ -1475,7 +1475,7 @@ IedServer_setWaitForExecutionHandler(IedServer self, DataObject* node, ControlWa * \param self the instance of IedServer to operate on. * \param node the controllable data object handle * \param handler a callback function of type ControlHandler - * \param parameter a user provided parameter that is passed to the control handler. + * \param parameter a user provided parameter that is passed to the callback handler. */ LIB61850_API void IedServer_setSelectStateChangedHandler(IedServer self, DataObject* node, ControlSelectStateChangedHandler handler, void* parameter);