diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 68a22ff3..b919cfeb 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -439,7 +439,12 @@ namespace IEC61850
static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
- static extern IntPtr IedConnection_getFileDirectory(IntPtr self, out int error, string directoryName);
+ static extern IntPtr IedConnection_getFileDirectory(IntPtr self, out int error, string directoryName);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr
+ IedConnection_getFileDirectoryEx(IntPtr self, out int error, string directoryName, string continueAfter
+ , [MarshalAs(UnmanagedType.I1)] out bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteFile(IntPtr self, out int error, string fileName);
@@ -484,6 +489,15 @@ namespace IEC61850
* Async functions
*********************/
+ [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ static extern void IedConnection_connectAsync (IntPtr self, out int error, string hostname, int tcpPort);
+
+ [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ static extern void IedConnection_abortAsync (IntPtr self, out int error);
+
+ [DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
+ private static extern void IedConnection_releaseAsync(IntPtr self, out int error);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_ReadObjectHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr value);
@@ -513,6 +527,11 @@ namespace IEC61850
IedConnection_getLogicalDeviceVariablesAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result,
IedConnection_GetNameListHandler handler, IntPtr parameter);
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern UInt32
+ IedConnection_getLogicalDeviceDataSetsAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result,
+ IedConnection_GetNameListHandler handler, IntPtr parameter);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_QueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
@@ -686,6 +705,19 @@ namespace IEC61850
throw new IedConnectionException ("Connect to " + hostname + ":" + tcpPort + " failed", error);
}
+ public void ConnectAsync(string hostname, int tcpPort)
+ {
+ int error;
+
+ IedConnection_setConnectTimeout(connection, connectTimeout);
+
+ IedConnection_connectAsync (connection, out error, hostname, tcpPort);
+
+ if (error != 0)
+ throw new IedConnectionException ("Connect to " + hostname + ":" + tcpPort + " failed", error);
+
+ }
+
///
/// Gets the current state of the connection
///
@@ -1294,6 +1326,41 @@ namespace IEC61850
LinkedList_destroyStatic(fileEntryList);
return fileDirectory;
+ }
+
+ /// Read the content of a file directory. - single request version
+ /// The name of the directory.
+ /// This exception is thrown if there is a connection or service error
+ /// The name of the directory.
+ public List GetFileDirectoryEx(string directoryName, string continueAfter, out bool moreFollows)
+ {
+ int error;
+
+ IntPtr fileEntryList = IedConnection_getFileDirectoryEx(connection, out error, directoryName, continueAfter, out moreFollows);
+
+ if (error != 0)
+ throw new IedConnectionException("Reading file directory failed", error);
+
+ List fileDirectory = new List();
+
+ IntPtr element = LinkedList_getNext(fileEntryList);
+
+ while (element != IntPtr.Zero)
+ {
+ IntPtr elementData = LinkedList_getData(element);
+
+ FileDirectoryEntry entry = new FileDirectoryEntry(elementData);
+
+ fileDirectory.Add(entry);
+
+ FileDirectoryEntry_destroy(elementData);
+
+ element = LinkedList_getNext(element);
+ }
+
+ LinkedList_destroyStatic(fileEntryList);
+
+ return fileDirectory;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@@ -1376,6 +1443,22 @@ namespace IEC61850
throw new IedConnectionException ("Abort failed", error);
}
+ ///
+ /// Abort (close) the connection - asynchronous version
+ ///
+ /// This function will send an abort request to the server. This will immediately interrupt the
+ /// connection.
+ /// This exception is thrown if there is a connection or service error
+ public void AbortAsync ()
+ {
+ int error;
+
+ IedConnection_abortAsync (connection, out error);
+
+ if (error != 0)
+ throw new IedConnectionException ("Abort failed", error);
+ }
+
///
/// Release (close) the connection.
///
@@ -1392,6 +1475,22 @@ namespace IEC61850
throw new IedConnectionException ("Release failed", error);
}
+ ///
+ /// Release (close) the connection - asynchronous version
+ ///
+ /// This function will send an release request to the server. The function will block until the
+ /// connection is released or an error occured.
+ /// This exception is thrown if there is a connection or service error
+ public void ReleaseAsync ()
+ {
+ int error;
+
+ IedConnection_releaseAsync(connection, out error);
+
+ if (error != 0)
+ throw new IedConnectionException ("Release failed", error);
+ }
+
///
/// Immediately close the connection.
///
@@ -1850,6 +1949,30 @@ namespace IEC61850
return invokeId;
}
+ public UInt32 GetLogicalDeviceDataSetsAsync(string ldName, string continueAfter, GetNameListHandler handler, object parameter)
+ {
+ return GetLogicalDeviceDataSetsAsync(null, ldName, continueAfter, handler, parameter);
+ }
+
+
+ public UInt32 GetLogicalDeviceDataSetsAsync(List result, string ldName, string continueAfter, GetNameListHandler handler, object parameter)
+ {
+ int error;
+
+ Tuple> callbackInfo = Tuple.Create(handler, parameter, result);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_getLogicalDeviceDataSetsAsync(connection, out error, ldName, continueAfter, IntPtr.Zero, nativeGetNameListHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Get logical device data sets failed", error);
+ }
+
+ return invokeId;
+ }
public delegate void QueryLogHandler(UInt32 invokeId, object parameter, IedClientError err, List journalEntries, bool moreFollows);
diff --git a/dotnet/files/FileServicesExample.cs b/dotnet/files/FileServicesExample.cs
index f77743fc..bdd02126 100644
--- a/dotnet/files/FileServicesExample.cs
+++ b/dotnet/files/FileServicesExample.cs
@@ -15,7 +15,9 @@ namespace files
{
public static void printFiles (IedConnection con, string prefix, string parent)
{
- List files = con.GetFileDirectory (parent);
+ bool moreFollows = false;
+
+ List files = con.GetFileDirectoryEx (parent, null, out moreFollows);
foreach (FileDirectoryEntry file in files) {
Console.WriteLine (prefix + file.GetFileName () + "\t" + file.GetFileSize () + "\t" +
@@ -26,6 +28,8 @@ namespace files
}
}
+ if (moreFollows)
+ Console.WriteLine("-- MORE FILES AVAILABLE --");
}
static bool getFileHandler (object parameter, byte[] data)
@@ -48,7 +52,7 @@ namespace files
if (args.Length > 0)
hostname = args [0];
else
- hostname = "10.0.2.2";
+ hostname = "127.0.0.1";
Console.WriteLine ("Connect to " + hostname);
diff --git a/examples/iec61850_client_example_files/file-tool.c b/examples/iec61850_client_example_files/file-tool.c
index 52680c44..6a53dd0a 100644
--- a/examples/iec61850_client_example_files/file-tool.c
+++ b/examples/iec61850_client_example_files/file-tool.c
@@ -79,6 +79,7 @@ basename(char* path)
static char* hostname = "localhost";
static int tcpPort = 102;
static char* filename = NULL;
+static bool singleRequest = false;
typedef enum {
FileOperationType_None = 0,
@@ -116,6 +117,7 @@ printHelp()
printf(" Options:\n");
printf(" -h \n");
printf(" -p portnumber\n");
+ printf(" -s single request for show (sub) directory (ignore morefollows");
printf(" Operations\n");
printf(" dir - show directory\n");
printf(" subdir - show sub directory\n");
@@ -140,6 +142,9 @@ parseOptions(int argc, char** argv)
else if (strcmp(argv[currentArgc], "-p") == 0) {
tcpPort = atoi(argv[++currentArgc]);
}
+ else if (strcmp(argv[currentArgc], "-s") == 0) {
+ singleRequest = true;
+ }
else if (strcmp(argv[currentArgc], "del") == 0) {
operation = FileOperationType_Del;
filename = argv[++currentArgc];
@@ -179,9 +184,15 @@ showDirectory(IedConnection con)
{
IedClientError error;
+ bool moreFollows = false;
+
/* Get the root directory */
- LinkedList rootDirectory =
- IedConnection_getFileDirectory(con, &error, filename);
+ LinkedList rootDirectory;
+
+ if (singleRequest)
+ rootDirectory = IedConnection_getFileDirectoryEx(con, &error, filename, NULL, &moreFollows);
+ else
+ rootDirectory = IedConnection_getFileDirectory(con, &error, filename);
if (error != IED_ERROR_OK) {
printf("Error retrieving file directory\n");
@@ -200,6 +211,9 @@ showDirectory(IedConnection con)
LinkedList_destroyDeep(rootDirectory, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy);
}
+
+ if (moreFollows)
+ printf("\n- MORE FILES AVAILABLE -\n");
}
void
diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h
index 0bd6f358..2a673439 100644
--- a/src/iec61850/inc/iec61850_client.h
+++ b/src/iec61850/inc/iec61850_client.h
@@ -208,6 +208,8 @@ IedConnection_createEx(TLSConfiguration tlsConfig, bool useThreads);
* the \ref IedConnection_connect or \ref IedConnection_connectAsync method has to be called.
* The connection will use TLS when a TLSConfiguration object is provided. The connection will be in thread mode.
*
+ * \deprecated Use \ref IedConnection_createEx instead
+ *
* \param tlsConfig the TLS configuration to be used
*
* \return the new IedConnection instance
@@ -287,6 +289,11 @@ IedConnection_connect(IedConnection self, IedClientError* error, const char* hos
/**
* \brief Asynchronously connect to a server
*
+ * The function will return immediately. No error doesn't indicate that the
+ * connection is established. The current connection state has to be tracked
+ * by polling the \ref IedConnection_getState function or by using
+ * \ref IedConnection_StateChangedHandler
+ *
* \param self the connection object
* \param error the error code if an error occurs
* \param hostname the host name or IP address of the server to connect to