- .NET API: adopted to new server side control API

pull/179/head
Michael Zillgith 6 years ago
parent 6c14425ca8
commit 8099734f11

@ -28,10 +28,7 @@ using IEC61850.Common;
namespace IEC61850
{
/// <summary>
/// IEC 61850 common API parts (used by client and server API)
/// </summary>
// IEC 61850 common API parts (used by client and server API)
namespace Common {
/// <summary>
@ -76,8 +73,8 @@ namespace IEC61850
}
}
namespace Client {
namespace Client
{
[StructLayout(LayoutKind.Sequential)]
internal struct LastApplErrorInternal
{
@ -128,7 +125,10 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
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);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime);
@ -190,7 +190,7 @@ namespace IEC61850
public delegate void CommandTerminationHandler (Object parameter, ControlObject controlObject);
private IedConnection iedConnection;
private IntPtr controlObject;
private IntPtr self;
private CommandTerminationHandler commandTerminationHandler = null;
private Object commandTerminationHandlerParameter = null;
@ -207,14 +207,14 @@ namespace IEC61850
{
this.iedConnection = iedConnection;
this.controlObject = ControlObjectClient_create(objectReference, connection);
this.self = ControlObjectClient_create(objectReference, connection);
if (this.controlObject == System.IntPtr.Zero)
if (this.self == System.IntPtr.Zero)
throw new IedConnectionException("Control object not found", 0);
intCommandTerminationHandler = new InternalCommandTerminationHandler (MyCommandTerminationHandler);
ControlObjectClient_setCommandTerminationHandler(controlObject, intCommandTerminationHandler, controlObject);
ControlObjectClient_setCommandTerminationHandler(self, intCommandTerminationHandler, self);
}
/// <summary>
@ -225,7 +225,7 @@ namespace IEC61850
/// </returns>
public ControlModel GetControlModel ()
{
ControlModel controlModel = (ControlModel) ControlObjectClient_getControlModel(controlObject);
ControlModel controlModel = (ControlModel) ControlObjectClient_getControlModel(self);
return controlModel;
}
@ -236,7 +236,7 @@ namespace IEC61850
/// <returns>MmsType required for the ctlVal value.</returns>
public MmsType GetCtlValType ()
{
MmsType ctlValType = (MmsType) ControlObjectClient_getCtlValType (controlObject);
MmsType ctlValType = (MmsType) ControlObjectClient_getCtlValType (self);
return ctlValType;
}
@ -252,7 +252,17 @@ namespace IEC61850
/// </param>
public void SetOrigin (string originator, OrCat originatorCategory)
{
ControlObjectClient_setOrigin(controlObject, originator, (int) originatorCategory);
ControlObjectClient_setOrigin(self, originator, (int) originatorCategory);
}
/// <summary>
/// Gets the error code of the last synchronous control action (operate, select, select-with-value, cancel)
/// </summary>
/// <value>error code.</value>
public IedClientError LastError {
get {
return (IedClientError)ControlObjectClient_getLastError (self);
}
}
/// <summary>
@ -342,7 +352,7 @@ namespace IEC61850
/// <returns>true when the operation has been successful, false otherwise</returns>
public bool Operate (MmsValue ctlVal, UInt64 operTime)
{
return ControlObjectClient_operate(controlObject, ctlVal.valueReference, operTime);
return ControlObjectClient_operate(self, ctlVal.valueReference, operTime);
}
private void nativeOperateHandler (UInt32 invokeId, IntPtr parameter, int err, int type, bool success)
@ -477,7 +487,7 @@ namespace IEC61850
GCHandle handle = GCHandle.Alloc(callbackInfo);
UInt32 invokeId = ControlObjectClient_operateAsync(controlObject, out error, ctlVal.valueReference, operTime, nativeOperateHandler, GCHandle.ToIntPtr(handle));
UInt32 invokeId = ControlObjectClient_operateAsync(self, out error, ctlVal.valueReference, operTime, nativeOperateHandler, GCHandle.ToIntPtr(handle));
if (error != 0)
{
@ -494,7 +504,7 @@ namespace IEC61850
/// <returns>true when the selection has been successful, false otherwise</returns>
public bool Select ()
{
return ControlObjectClient_select(controlObject);
return ControlObjectClient_select(self);
}
/// <summary>
@ -512,7 +522,7 @@ namespace IEC61850
GCHandle handle = GCHandle.Alloc(callbackInfo);
UInt32 invokeId = ControlObjectClient_selectAsync(controlObject, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle));
UInt32 invokeId = ControlObjectClient_selectAsync(self, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle));
if (error != 0)
{
@ -530,7 +540,7 @@ namespace IEC61850
/// <returns>true when the selection has been successful, false otherwise</returns>
public bool SelectWithValue (MmsValue ctlVal)
{
return ControlObjectClient_selectWithValue(controlObject, ctlVal.valueReference);
return ControlObjectClient_selectWithValue(self, ctlVal.valueReference);
}
/// <summary>
@ -624,7 +634,7 @@ namespace IEC61850
GCHandle handle = GCHandle.Alloc(callbackInfo);
UInt32 invokeId = ControlObjectClient_selectWithValueAsync(controlObject, out error, ctlVal.valueReference, nativeOperateHandler, GCHandle.ToIntPtr(handle));
UInt32 invokeId = ControlObjectClient_selectWithValueAsync(self, out error, ctlVal.valueReference, nativeOperateHandler, GCHandle.ToIntPtr(handle));
if (error != 0)
{
@ -645,7 +655,7 @@ namespace IEC61850
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public bool Cancel ()
{
return ControlObjectClient_cancel(controlObject);
return ControlObjectClient_cancel(self);
}
/// <summary>
@ -659,7 +669,7 @@ namespace IEC61850
GCHandle handle = GCHandle.Alloc(callbackInfo);
UInt32 invokeId = ControlObjectClient_cancelAsync(controlObject, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle));
UInt32 invokeId = ControlObjectClient_cancelAsync(self, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle));
if (error != 0)
{
@ -676,7 +686,7 @@ namespace IEC61850
[Obsolete("use SetSynchroCheck instead")]
public void EnableSynchroCheck ()
{
ControlObjectClient_setSynchroCheck (controlObject, true);
ControlObjectClient_setSynchroCheck (self, true);
}
/// <summary>
@ -685,7 +695,7 @@ namespace IEC61850
[Obsolete("use SetInterlockCheck instead")]
public void EnableInterlockCheck ()
{
ControlObjectClient_setInterlockCheck (controlObject, true);
ControlObjectClient_setInterlockCheck (self, true);
}
/// <summary>
@ -693,7 +703,7 @@ namespace IEC61850
/// </summary>
public void SetInterlockCheck (bool value)
{
ControlObjectClient_setInterlockCheck (controlObject, value);
ControlObjectClient_setInterlockCheck (self, value);
}
/// <summary>
@ -701,7 +711,7 @@ namespace IEC61850
/// </summary>
public void SetSynchroCheck (bool value)
{
ControlObjectClient_setSynchroCheck (controlObject, value);
ControlObjectClient_setSynchroCheck (self, value);
}
/// <summary>
@ -709,7 +719,7 @@ namespace IEC61850
/// </summary>
public void SetTestMode (bool value)
{
ControlObjectClient_setTestMode (controlObject, value);
ControlObjectClient_setTestMode (self, value);
}
/// <summary>
@ -720,7 +730,7 @@ namespace IEC61850
/// </returns>
public LastApplError GetLastApplError ()
{
LastApplErrorInternal lastApplError = ControlObjectClient_getLastApplError(controlObject);
LastApplErrorInternal lastApplError = ControlObjectClient_getLastApplError(self);
return new LastApplError(lastApplError);
}
@ -741,9 +751,9 @@ namespace IEC61850
}
protected virtual void Dispose(bool disposing) {
if (this.controlObject != System.IntPtr.Zero) {
ControlObjectClient_destroy (controlObject);
this.controlObject = System.IntPtr.Zero;
if (this.self != System.IntPtr.Zero) {
ControlObjectClient_destroy (self);
this.self = System.IntPtr.Zero;
}
}

@ -1,7 +1,7 @@
/*
* IEC61850ClientAPI.cs
*
* Copyright 2014-2016 Michael Zillgith
* Copyright 2014-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -29,14 +29,10 @@ using System.Collections;
using IEC61850.Common;
using IEC61850.TLS;
/// <summary>
/// IEC 61850 API for the libiec61850 .NET wrapper library
/// </summary>
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
/// <summary>
/// IEC 61850 client API.
/// </summary>
// IEC 61850 client API.
namespace Client
{
@ -201,7 +197,9 @@ namespace IEC61850
}
}
/// <summary>
/// Represents a variable in a log entry
/// </summary>
public class MmsJournalVariable
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -265,6 +263,10 @@ namespace IEC61850
this.self = self;
}
/// <summary>
/// Gets the journal variables.
/// </summary>
/// <returns>The journal variables.</returns>
public List<MmsJournalVariable> GetJournalVariables()
{
if (variables == null)
@ -289,7 +291,10 @@ namespace IEC61850
return variables;
}
/// <summary>
/// Gets the entry identifier of the log entry
/// </summary>
/// <returns>The entry identifier.</returns>
public byte[] GetEntryID()
{
IntPtr mmsValuePtr = MmsJournalEntry_getEntryID(self);
@ -301,6 +306,10 @@ namespace IEC61850
return octetString;
}
/// <summary>
/// Gets the occurence time of the log entry
/// </summary>
/// <returns>The occurence time.</returns>
public ulong GetOccurenceTime()
{
IntPtr mmsValuePtr = MmsJournalEntry_getOccurenceTime(self);
@ -310,6 +319,9 @@ namespace IEC61850
return mmsValue.GetBinaryTimeAsUtcMs();
}
/// <summary>
/// Releases all resource used by the <see cref="T:IEC61850.Client.MmsJournalEntry"/> object.
/// </summary>
public void Dispose()
{
if (self != IntPtr.Zero)

@ -21,26 +21,21 @@
* 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 System.Runtime.InteropServices;
using IEC61850.Common;
using IEC61850.TLS;
/// <summary>
/// IEC 61850 API for the libiec61850 .NET wrapper library
/// </summary>
// IEC 61850 API for the libiec61850 .NET wrapper library
namespace IEC61850
{
/// <summary>
/// IEC 61850 server API.
/// </summary>
namespace Server
{
public class ConfigFileParser
// IEC 61850 server API.
namespace Server
{
/// <summary>
/// Config file parser.
/// </summary>
public class ConfigFileParser
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -69,6 +64,9 @@ namespace IEC61850
}
}
/// <summary>
/// Representation of the IED server data model
/// </summary>
public class IedModel
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -93,6 +91,10 @@ namespace IEC61850
this.self = self;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:IEC61850.Server.IedModel"/> class.
/// </summary>
/// <param name="name">IED name</param>
public IedModel(string name)
{
self = IedModel_create(name);
@ -159,8 +161,6 @@ namespace IEC61850
return getModelNodeFromNodeRef (nodeRef);
}
}
public class LogicalDevice : ModelNode
@ -483,8 +483,6 @@ namespace IEC61850
public class ClientConnection
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ClientConnection_getPeerAddress(IntPtr self);
@ -505,6 +503,99 @@ namespace IEC61850
}
}
/// <summary>
/// Represents additional context information of the control action that caused the callback invokation
/// </summary>
public class ControlAction
{
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ControlAction_setAddCause (IntPtr self, int addCause);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ControlAction_getOrCat (IntPtr self);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getOrIdent (IntPtr self, ref int size);
[DllImport ("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ControlAction_getClientConnection (IntPtr self);
private IntPtr self;
private IedServer.ControlHandlerInfo info;
private IedServer iedServer;
internal ControlAction (IntPtr self, IedServer.ControlHandlerInfo info, IedServer iedServer)
{
this.self = self;
this.info = info;
this.iedServer = iedServer;
}
/// <summary>
/// Sets the add cause for the next command termination or application error message
/// </summary>
/// <param name="addCause">the additional cause code</param>
public void SetAddCause (ControlAddCause addCause)
{
ControlAction_setAddCause (self, (int)addCause);
}
/// <summary>
/// Gets the originator category provided by the client
/// </summary>
/// <returns>The or cat.</returns>
public OrCat GetOrCat ()
{
return (OrCat)ControlAction_getOrCat (self);
}
/// <summary>
/// Get the originator identifier provided by the client
/// </summary>
/// <returns>The or ident.</returns>
public byte [] GetOrIdent ()
{
int size = 0;
IntPtr orIdentPtr = ControlAction_getOrIdent (self, ref size);
if (orIdentPtr == IntPtr.Zero)
return null;
byte [] orIdent = new byte [size];
Marshal.Copy (orIdentPtr, orIdent, 0, size);
return orIdent;
}
/// <summary>
/// Gets the control object that is subject to this action
/// </summary>
/// <returns>the controllable data object instance</returns>
public DataObject GetControlObject ()
{
return info.controlObject;
}
/// <summary>
/// Gets the client object associated with the client that caused the control action
/// </summary>
/// <returns>The client connection.</returns>
public ClientConnection GetClientConnection ()
{
ClientConnection con = null;
IntPtr conPtr = ControlAction_getClientConnection (self);
if (conPtr != IntPtr.Zero) {
iedServer.clientConnections.TryGetValue (conPtr, out con);
}
return con;
}
}
public delegate MmsDataAccessError WriteAccessHandler (DataAttribute dataAttr, MmsValue value,
ClientConnection connection, object parameter);
@ -523,9 +614,9 @@ namespace IEC61850
WAITING = 2
}
public delegate ControlHandlerResult ControlWaitForExecutionHandler (DataObject controlObject, object parameter, MmsValue ctlVal, bool test, bool synchroCheck);
public delegate ControlHandlerResult ControlWaitForExecutionHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test, bool synchroCheck);
public delegate ControlHandlerResult ControlHandler (DataObject controlObject, object parameter, MmsValue ctlVal, bool test);
public delegate ControlHandlerResult ControlHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test);
public enum CheckHandlerResult {
/// <summary>
@ -550,8 +641,7 @@ namespace IEC61850
OBJECT_UNDEFINED = 4
}
public delegate CheckHandlerResult CheckHandler (DataObject controlObject, object parameter, MmsValue ctlVal, bool test, bool interlockCheck,
ClientConnection connection);
public delegate CheckHandlerResult CheckHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test, bool interlockCheck);
/// <summary>
/// This class acts as the entry point for the IEC 61850 client API. It represents a single
@ -615,13 +705,13 @@ namespace IEC61850
static extern IntPtr IedServer_getAttributeValue(IntPtr self, IntPtr dataAttribute);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlPerformCheckHandler (IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool interlockCheck, IntPtr connection);
private delegate int InternalControlPerformCheckHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool interlockCheck);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlWaitForExecutionHandler (IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool synchoCheck);
private delegate int InternalControlWaitForExecutionHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test, [MarshalAs(UnmanagedType.I1)] bool synchoCheck);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int InternalControlHandler (IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test);
private delegate int InternalControlHandler (IntPtr action, IntPtr parameter, IntPtr ctlVal, [MarshalAs(UnmanagedType.I1)] bool test);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedServer_setWaitForExecutionHandler(IntPtr self, IntPtr node, InternalControlWaitForExecutionHandler handler, IntPtr parameter);
@ -665,7 +755,7 @@ namespace IEC61850
private InternalControlPerformCheckHandler internalControlPerformCheckHandlerRef = null;
private InternalControlWaitForExecutionHandler internalControlWaitForExecutionHandlerRef = null;
private class ControlHandlerInfo {
internal class ControlHandlerInfo {
public DataObject controlObject = null;
public GCHandle handle;
@ -691,42 +781,46 @@ namespace IEC61850
private Dictionary<DataObject, ControlHandlerInfo> controlHandlers = new Dictionary<DataObject, ControlHandlerInfo> ();
int internalControlHandler (IntPtr parameter, IntPtr ctlVal, bool test)
int InternalControlHandlerImpl (IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test)
{
GCHandle handle = GCHandle.FromIntPtr (parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
ControlAction controlAction = new ControlAction (action, info, this);
if (info != null & info.controlHandler != null)
return (int)info.controlHandler (info.controlObject, info.controlHandlerParameter, new MmsValue (ctlVal), test);
return (int)info.controlHandler (controlAction, info.controlHandlerParameter, new MmsValue (ctlVal), test);
else
return (int)ControlHandlerResult.FAILED;
}
int internalCheckHandler(IntPtr parameter, IntPtr ctlVal, bool test, bool interlockCheck, IntPtr connection)
int InternalCheckHandlerImpl(IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool interlockCheck)
{
GCHandle handle = GCHandle.FromIntPtr (parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
if (info != null & info.checkHandler != null) {
ClientConnection con = null;
clientConnections.TryGetValue (connection, out con);
ControlAction controlAction = new ControlAction (action, info, this);
return (int)info.checkHandler (info.controlObject, info.checkHandlerParameter, new MmsValue (ctlVal), test, interlockCheck, con);
return (int)info.checkHandler (controlAction, info.checkHandlerParameter, new MmsValue (ctlVal), test, interlockCheck);
} else
return (int)CheckHandlerResult.OBJECT_UNDEFINED;
}
int internalControlWaitForExecutionHandler (IntPtr parameter, IntPtr ctlVal, bool test, bool synchoCheck)
int InternalControlWaitForExecutionHandlerImpl (IntPtr action, IntPtr parameter, IntPtr ctlVal, bool test, bool synchoCheck)
{
GCHandle handle = GCHandle.FromIntPtr (parameter);
ControlHandlerInfo info = (ControlHandlerInfo)handle.Target;
if (info != null & info.waitForExecHandler != null) {
return (int)info.waitForExecHandler (info.controlObject, info.waitForExecHandlerParameter, new MmsValue (ctlVal), test, synchoCheck);
ControlAction controlAction = new ControlAction (action, info, this);
return (int)info.waitForExecHandler (controlAction, info.waitForExecHandlerParameter, new MmsValue (ctlVal), test, synchoCheck);
}
else
return (int)ControlHandlerResult.FAILED;
@ -745,7 +839,7 @@ namespace IEC61850
}
}
int writeAccessHandler (IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter)
int WriteAccessHandlerImpl (IntPtr dataAttribute, IntPtr value, IntPtr connection, IntPtr parameter)
{
//object info = writeAccessHandlers.Item [dataAttribute];
WriteAccessHandlerInfo info;
@ -761,7 +855,7 @@ namespace IEC61850
private Dictionary<IntPtr, WriteAccessHandlerInfo> writeAccessHandlers = new Dictionary<IntPtr, WriteAccessHandlerInfo> ();
private void connectionIndicationHandler (IntPtr iedServer, IntPtr clientConnection, bool connected, IntPtr parameter)
private void ConnectionIndicationHandlerImpl (IntPtr iedServer, IntPtr clientConnection, bool connected, IntPtr parameter)
{
if (connected == false) {
ClientConnection con = null;
@ -785,9 +879,7 @@ namespace IEC61850
}
}
private Dictionary<IntPtr, ClientConnection> clientConnections = new Dictionary<IntPtr, ClientConnection> ();
internal Dictionary<IntPtr, ClientConnection> clientConnections = new Dictionary<IntPtr, ClientConnection> ();
public IedServer(IedModel iedModel, IedServerConfig config = null)
{
@ -849,7 +941,7 @@ namespace IEC61850
public void Start(int tcpPort)
{
if (internalConnectionHandler == null)
internalConnectionHandler = new InternalConnectionHandler (connectionIndicationHandler);
internalConnectionHandler = new InternalConnectionHandler (ConnectionIndicationHandlerImpl);
IedServer_setConnectionIndicationHandler (self, internalConnectionHandler, IntPtr.Zero);
@ -910,7 +1002,7 @@ namespace IEC61850
info.controlHandlerParameter = parameter;
if (internalControlHandlerRef == null)
internalControlHandlerRef = new InternalControlHandler (internalControlHandler);
internalControlHandlerRef = new InternalControlHandler (InternalControlHandlerImpl);
IedServer_setControlHandler(self, controlObject.self, internalControlHandlerRef, GCHandle.ToIntPtr(info.handle));
}
@ -923,7 +1015,7 @@ namespace IEC61850
info.checkHandlerParameter = parameter;
if (internalControlPerformCheckHandlerRef == null)
internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler (internalCheckHandler);
internalControlPerformCheckHandlerRef = new InternalControlPerformCheckHandler (InternalCheckHandlerImpl);
IedServer_setPerformCheckHandler(self, controlObject.self, internalControlPerformCheckHandlerRef, GCHandle.ToIntPtr(info.handle));
}
@ -936,7 +1028,7 @@ namespace IEC61850
info.waitForExecHandlerParameter = parameter;
if (internalControlWaitForExecutionHandlerRef == null)
internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler (internalControlWaitForExecutionHandler);
internalControlWaitForExecutionHandlerRef = new InternalControlWaitForExecutionHandler (InternalControlWaitForExecutionHandlerImpl);
IedServer_setWaitForExecutionHandler(self, controlObject.self, internalControlWaitForExecutionHandlerRef, GCHandle.ToIntPtr(info.handle));
}
@ -946,7 +1038,7 @@ namespace IEC61850
writeAccessHandlers.Add (dataAttr.self, new WriteAccessHandlerInfo(handler, parameter, dataAttr));
//writeAccessHandlers.Item [dataAttr.self] = handler;
IedServer_handleWriteAccess (self, dataAttr.self, writeAccessHandler, IntPtr.Zero);
IedServer_handleWriteAccess (self, dataAttr.self, WriteAccessHandlerImpl, IntPtr.Zero);
}
public void SetWriteAccessPolicy(FunctionalConstraint fc, AccessPolicy policy)

@ -521,9 +521,12 @@ namespace IEC61850
if ((elementType == MmsType.MMS_ARRAY) || (elementType == MmsType.MMS_STRUCTURE)) {
if ((index >= 0) && (index < Size ())) {
MmsValue_setElement (valueReference, index, elementValue.valueReference);
} else
if (elementValue != null)
MmsValue_setElement (valueReference, index, elementValue.valueReference);
else
MmsValue_setElement (valueReference, index, IntPtr.Zero);
} else
throw new MmsValueException ("Index out of bounds");
} else

@ -31,7 +31,7 @@ namespace server1
IedServer iedServer = new IedServer (iedModel, config);
iedServer.SetControlHandler (spcso1, delegate(DataObject controlObject, object parameter, MmsValue ctlVal, bool test) {
iedServer.SetControlHandler (spcso1, delegate(ControlAction action, object parameter, MmsValue ctlVal, bool test) {
bool val = ctlVal.GetBoolean();
if (val)

@ -126,7 +126,11 @@ namespace tests
Assert.AreEqual (elem2.GetType (), MmsType.MMS_INTEGER);
Assert.AreEqual (elem2.ToInt32 (), 3);
}
val.SetElement (0, null);
val.SetElement (1, null);
val.SetElement (2, null);
}
[Test()]
public void MmsValueStructure()
@ -147,6 +151,9 @@ namespace tests
MmsValue elem1 = val.GetElement (1);
Assert.AreEqual (elem1.GetType (), MmsType.MMS_BIT_STRING);
val.SetElement (0, null);
val.SetElement (1, null);
}
[Test ()]
@ -428,7 +435,17 @@ namespace tests
IedServer iedServer = new IedServer (iedModel);
iedServer.SetControlHandler (spcso1, delegate(DataObject controlObject, object parameter, MmsValue ctlVal, bool test) {
iedServer.SetControlHandler (spcso1, delegate(ControlAction action, object parameter, MmsValue ctlVal, bool test) {
byte [] orIdent = action.GetOrIdent ();
string orIdentStr = System.Text.Encoding.UTF8.GetString (orIdent, 0, orIdent.Length);
Assert.AreEqual ("TEST1234", orIdentStr);
Assert.AreEqual (OrCat.MAINTENANCE, action.GetOrCat ());
Assert.AreSame (spcso1, action.GetControlObject ());
handlerCalled++;
return ControlHandlerResult.OK;
}, null);
@ -440,6 +457,7 @@ namespace tests
connection.Connect ("localhost", 10002);
ControlObject controlClient = connection.CreateControlObject ("simpleIOGenericIO/GGIO1.SPCSO1");
controlClient.SetOrigin ("TEST1234", OrCat.MAINTENANCE);
Assert.IsNotNull (controlClient);

@ -46,7 +46,7 @@ namespace tls_server_example
IedServer iedServer = new IedServer (iedModel, tlsConfig);
iedServer.SetControlHandler (spcso1, delegate(DataObject controlObject, object parameter, MmsValue ctlVal, bool test) {
iedServer.SetControlHandler (spcso1, delegate(ControlAction action, object parameter, MmsValue ctlVal, bool test) {
bool val = ctlVal.GetBoolean();
if (val)

@ -1086,7 +1086,7 @@ typedef enum {
typedef void* ControlAction;
/**
* \brief Set the add cause for the next command termination or application error message
* \brief Sets the add cause for the next command termination or application error message
*
* \param self the control action instance
* \param addCause the additional cause
@ -1095,7 +1095,7 @@ LIB61850_API void
ControlAction_setAddCause(ControlAction self, ControlAddCause addCause);
/**
* \brief Get the originator category provided by the client
* \brief Gets the originator category provided by the client
*
* \param self the control action instance
*
@ -1105,7 +1105,7 @@ LIB61850_API int
ControlAction_getOrCat(ControlAction self);
/**
* \brief Get the originator identifier provided by the client
* \brief Gets the originator identifier provided by the client
*
* \param self the control action instance
*
@ -1115,7 +1115,7 @@ LIB61850_API uint8_t*
ControlAction_getOrIdent(ControlAction self, int* orIdentSize);
/**
* \brief Get the client object associated with the client that caused the control action
* \brief Gets the client object associated with the client that caused the control action
*
* \param self the control action instance
*
@ -1125,7 +1125,7 @@ LIB61850_API ClientConnection
ControlAction_getClientConnection(ControlAction self);
/**
* \brief Get the control object that is subject to this action
* \brief Gets the control object that is subject to this action
*
* \param self the control action instance
*

Loading…
Cancel
Save