diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
index 4113cee3..1980b23b 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
@@ -2160,6 +2160,15 @@ namespace IEC61850
IEC61850_CB_ACCESS_TYPE_WRITE
}
+ public enum DataSetOperation
+ {
+ DATASET_CREATE,
+ DATASET_DELETE,
+ DATASET_READ,
+ DATASET_WRITE,
+ DATASET_GET_DIRECTORY
+ }
+
public delegate CheckHandlerResult CheckHandler (ControlAction action, object parameter, MmsValue ctlVal, bool test, bool interlockCheck);
public static class SqliteLogStorage
@@ -2360,6 +2369,12 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
public static extern void IedServer_setControlBlockAccessHandler(IntPtr self, IedServer_ControlBlockAccessHandler handler, IntPtr parameter);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void IedServer_setDataSetAccessHandler(IntPtr self, IedServer_DataSetAccessHandler handler, IntPtr parameter);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate bool IedServer_DataSetAccessHandler(IntPtr parameter, IntPtr connection, int operation, string datasetRef);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool IedServer_ControlBlockAccessHandler(IntPtr parameter, IntPtr connection, int acsiClass, IntPtr ld, IntPtr ln, string objectName, string subObjectName, int accessType);
@@ -2619,7 +2634,6 @@ namespace IEC61850
}
-
///
/// Set a handler to control read and write access to control blocks and logs
///
@@ -2638,6 +2652,47 @@ namespace IEC61850
}
}
+ public delegate bool DataSetAccessHandler(object parameter, ClientConnection connection, DataSetOperation operation, string datasetRef);
+
+ private DataSetAccessHandler dataSetAccessHandler = null;
+
+ private object dataSetAccessHandlerParameter = null;
+
+ private IedServer_DataSetAccessHandler internalDataSetAccessHandler = null;
+
+ ///
+ /// Callback that is called when the client is calling a dataset operation (create, delete, read, write, list directory)
+ /// note This callback is called before the IedServer_RCBEventHandler and only in case of operations(RCB_EVENT_GET_PARAMETER, RCB_EVENT_SET_PARAMETER, RCB_EVENT_ENABLE
+ ///
+ /// the callback handler to be used
+ /// a user provided parameter that is passed to the handler
+ public void SetDataSetAccessHandler(DataSetAccessHandler handler, object parameter)
+ {
+ dataSetAccessHandler = handler;
+ dataSetAccessHandlerParameter = parameter;
+
+ if (internalDataSetAccessHandler == null)
+ {
+ internalDataSetAccessHandler = new IedServer_DataSetAccessHandler(InternalDataSetlHandlerImplementation);
+
+ IedServer_setDataSetAccessHandler(self, internalDataSetAccessHandler, IntPtr.Zero);
+ }
+ }
+
+ private bool InternalDataSetlHandlerImplementation (IntPtr parameter, IntPtr connection, int operation, string datasetRef)
+ {
+ if (dataSetAccessHandler != null && connection != IntPtr.Zero)
+ {
+ ClientConnection con = null;
+
+ this.clientConnections.TryGetValue(connection, out con);
+
+ return dataSetAccessHandler(dataSetAccessHandlerParameter, con, (DataSetOperation)operation, datasetRef);
+ }
+
+ return false;
+ }
+
private Dictionary writeAccessHandlers = new Dictionary ();
private void ConnectionIndicationHandlerImpl (IntPtr iedServer, IntPtr clientConnection, bool connected, IntPtr parameter)
diff --git a/dotnet/server_example_access_control/Program.cs b/dotnet/server_example_access_control/Program.cs
index b77c0cb2..c6f069d8 100644
--- a/dotnet/server_example_access_control/Program.cs
+++ b/dotnet/server_example_access_control/Program.cs
@@ -12,6 +12,7 @@ using System.Threading;
using System.Net;
using static IEC61850.Server.IedServer;
using System.Collections.Generic;
+using System.Reflection.Metadata;
namespace server_access_control
{
@@ -143,6 +144,23 @@ namespace server_access_control
iedServer.SetControlBlockAccessHandler(ControlBlockAccessCallBack, iedServer);
+ /* 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
+ * by iec61850_client_example1.
+ */
+ iedServer.SetWriteAccessPolicy(FunctionalConstraint.DC, AccessPolicy.ACCESS_POLICY_ALLOW);
+
+ /* Install handler to perform access control on datasets */
+ bool dataSetAccessHandler(object parameter, ClientConnection connection, DataSetOperation operation, string datasetRef)
+ {
+ Console.WriteLine("Data set access: "+ datasetRef+" operation: "+ operation.ToString() + "\n");
+
+ return true;
+ }
+
+ iedServer.SetDataSetAccessHandler(dataSetAccessHandler, iedServer);
+
+
iedServer.Start(102);
if (iedServer.IsRunning())