- .NET API: added more async functions

- .NET API: added GetFileDirectoryEx function
. file-tool: add "s" option to send only a single get file directory request
pull/93/head
Michael Zillgith 7 years ago
parent e252715aa9
commit b6c9a56d4a

@ -439,7 +439,12 @@ namespace IEC61850
static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection); static extern IntPtr MmsConnection_getIsoConnectionParameters(IntPtr mmsConnection);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [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)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteFile(IntPtr self, out int error, string fileName); static extern void IedConnection_deleteFile(IntPtr self, out int error, string fileName);
@ -484,6 +489,15 @@ namespace IEC61850
* Async functions * 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)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_ReadObjectHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr value); 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_getLogicalDeviceVariablesAsync(IntPtr self, out int error, string ldName, string continueAfter, IntPtr result,
IedConnection_GetNameListHandler handler, IntPtr parameter); 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)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void IedConnection_QueryLogHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr journalEntries, [MarshalAs(UnmanagedType.I1)] bool moreFollows); 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); 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);
}
/// <summary> /// <summary>
/// Gets the current state of the connection /// Gets the current state of the connection
/// </summary> /// </summary>
@ -1294,6 +1326,41 @@ namespace IEC61850
LinkedList_destroyStatic(fileEntryList); LinkedList_destroyStatic(fileEntryList);
return fileDirectory; return fileDirectory;
}
/// <summary>Read the content of a file directory. - single request version</summary>
/// <param name="directoryName">The name of the directory.</param>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
/// <param name="directoryName">The name of the directory.</param>
public List<FileDirectoryEntry> 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<FileDirectoryEntry> fileDirectory = new List<FileDirectoryEntry>();
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)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -1376,6 +1443,22 @@ namespace IEC61850
throw new IedConnectionException ("Abort failed", error); throw new IedConnectionException ("Abort failed", error);
} }
/// <summary>
/// Abort (close) the connection - asynchronous version
/// </summary>
/// <description>This function will send an abort request to the server. This will immediately interrupt the
/// connection.</description>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void AbortAsync ()
{
int error;
IedConnection_abortAsync (connection, out error);
if (error != 0)
throw new IedConnectionException ("Abort failed", error);
}
/// <summary> /// <summary>
/// Release (close) the connection. /// Release (close) the connection.
/// </summary> /// </summary>
@ -1392,6 +1475,22 @@ namespace IEC61850
throw new IedConnectionException ("Release failed", error); throw new IedConnectionException ("Release failed", error);
} }
/// <summary>
/// Release (close) the connection - asynchronous version
/// </summary>
/// <description>This function will send an release request to the server. The function will block until the
/// connection is released or an error occured.</description>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public void ReleaseAsync ()
{
int error;
IedConnection_releaseAsync(connection, out error);
if (error != 0)
throw new IedConnectionException ("Release failed", error);
}
/// <summary> /// <summary>
/// Immediately close the connection. /// Immediately close the connection.
/// </summary> /// </summary>
@ -1850,6 +1949,30 @@ namespace IEC61850
return invokeId; return invokeId;
} }
public UInt32 GetLogicalDeviceDataSetsAsync(string ldName, string continueAfter, GetNameListHandler handler, object parameter)
{
return GetLogicalDeviceDataSetsAsync(null, ldName, continueAfter, handler, parameter);
}
public UInt32 GetLogicalDeviceDataSetsAsync(List<string> result, string ldName, string continueAfter, GetNameListHandler handler, object parameter)
{
int error;
Tuple<GetNameListHandler, object, List<string>> 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<MmsJournalEntry> journalEntries, bool moreFollows); public delegate void QueryLogHandler(UInt32 invokeId, object parameter, IedClientError err, List<MmsJournalEntry> journalEntries, bool moreFollows);

@ -15,7 +15,9 @@ namespace files
{ {
public static void printFiles (IedConnection con, string prefix, string parent) public static void printFiles (IedConnection con, string prefix, string parent)
{ {
List<FileDirectoryEntry> files = con.GetFileDirectory (parent); bool moreFollows = false;
List<FileDirectoryEntry> files = con.GetFileDirectoryEx (parent, null, out moreFollows);
foreach (FileDirectoryEntry file in files) { foreach (FileDirectoryEntry file in files) {
Console.WriteLine (prefix + file.GetFileName () + "\t" + file.GetFileSize () + "\t" + 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) static bool getFileHandler (object parameter, byte[] data)
@ -48,7 +52,7 @@ namespace files
if (args.Length > 0) if (args.Length > 0)
hostname = args [0]; hostname = args [0];
else else
hostname = "10.0.2.2"; hostname = "127.0.0.1";
Console.WriteLine ("Connect to " + hostname); Console.WriteLine ("Connect to " + hostname);

@ -79,6 +79,7 @@ basename(char* path)
static char* hostname = "localhost"; static char* hostname = "localhost";
static int tcpPort = 102; static int tcpPort = 102;
static char* filename = NULL; static char* filename = NULL;
static bool singleRequest = false;
typedef enum { typedef enum {
FileOperationType_None = 0, FileOperationType_None = 0,
@ -116,6 +117,7 @@ printHelp()
printf(" Options:\n"); printf(" Options:\n");
printf(" -h <hostname/IP>\n"); printf(" -h <hostname/IP>\n");
printf(" -p portnumber\n"); printf(" -p portnumber\n");
printf(" -s single request for show (sub) directory (ignore morefollows");
printf(" Operations\n"); printf(" Operations\n");
printf(" dir - show directory\n"); printf(" dir - show directory\n");
printf(" subdir <dirname> - show sub directory\n"); printf(" subdir <dirname> - show sub directory\n");
@ -140,6 +142,9 @@ parseOptions(int argc, char** argv)
else if (strcmp(argv[currentArgc], "-p") == 0) { else if (strcmp(argv[currentArgc], "-p") == 0) {
tcpPort = atoi(argv[++currentArgc]); tcpPort = atoi(argv[++currentArgc]);
} }
else if (strcmp(argv[currentArgc], "-s") == 0) {
singleRequest = true;
}
else if (strcmp(argv[currentArgc], "del") == 0) { else if (strcmp(argv[currentArgc], "del") == 0) {
operation = FileOperationType_Del; operation = FileOperationType_Del;
filename = argv[++currentArgc]; filename = argv[++currentArgc];
@ -179,9 +184,15 @@ showDirectory(IedConnection con)
{ {
IedClientError error; IedClientError error;
bool moreFollows = false;
/* Get the root directory */ /* Get the root directory */
LinkedList rootDirectory = LinkedList rootDirectory;
IedConnection_getFileDirectory(con, &error, filename);
if (singleRequest)
rootDirectory = IedConnection_getFileDirectoryEx(con, &error, filename, NULL, &moreFollows);
else
rootDirectory = IedConnection_getFileDirectory(con, &error, filename);
if (error != IED_ERROR_OK) { if (error != IED_ERROR_OK) {
printf("Error retrieving file directory\n"); printf("Error retrieving file directory\n");
@ -200,6 +211,9 @@ showDirectory(IedConnection con)
LinkedList_destroyDeep(rootDirectory, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy); LinkedList_destroyDeep(rootDirectory, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy);
} }
if (moreFollows)
printf("\n- MORE FILES AVAILABLE -\n");
} }
void void

@ -208,6 +208,8 @@ IedConnection_createEx(TLSConfiguration tlsConfig, bool useThreads);
* the \ref IedConnection_connect or \ref IedConnection_connectAsync method has to be called. * 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. * 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 * \param tlsConfig the TLS configuration to be used
* *
* \return the new IedConnection instance * \return the new IedConnection instance
@ -287,6 +289,11 @@ IedConnection_connect(IedConnection self, IedClientError* error, const char* hos
/** /**
* \brief Asynchronously connect to a server * \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 self the connection object
* \param error the error code if an error occurs * \param error the error code if an error occurs
* \param hostname the host name or IP address of the server to connect to * \param hostname the host name or IP address of the server to connect to

Loading…
Cancel
Save