- .NET API: Fixed bug in IedConnection.GetFileAsync

pull/374/head
Michael Zillgith 4 years ago
parent 824c9ad5dd
commit 5d1f66d7e6

@ -1681,8 +1681,8 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private delegate bool IedConnection_GetFileAsyncHandler(UInt32 invokeId,IntPtr parameter,int err,UInt32 originalInvokeId,
IntPtr buffer,UInt32 bytesRead,bool moreFollows);
private delegate bool IedConnection_GetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
IntPtr buffer, UInt32 bytesRead, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
/// <summary>
/// Callback handler for the asynchronous get file service. Will be invoked for each chunk of received data
@ -1693,7 +1693,8 @@ namespace IEC61850
/// <param name="originalInvokeId">the invokeId of the first (file open) request</param>
/// <param name="buffer">the file data received with the last response, or null if no file data available</param>
/// <param name="moreFollows">indicates that more file data follows</param>
public delegate bool GetFileAsyncHandler(UInt32 invokeId,object parameter,IedClientError err,UInt32 originalInvokeId,byte[] buffer,bool moreFollows);
/// <returns>true, continue the file download when moreFollows is true, false, stop file download</returns>
public delegate bool GetFileAsyncHandler(UInt32 invokeId, object parameter, IedClientError err, UInt32 originalInvokeId, byte[] buffer, bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32
@ -1703,7 +1704,6 @@ namespace IEC61850
private bool nativeGetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
IntPtr buffer, UInt32 bytesRead, bool moreFollows)
{
GCHandle handle = GCHandle.FromIntPtr(parameter);
Tuple<GetFileAsyncHandler, object> callbackInfo = handle.Target as Tuple<GetFileAsyncHandler, object>;
@ -1711,8 +1711,6 @@ namespace IEC61850
GetFileAsyncHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
handle.Free();
IedClientError clientError = (IedClientError)err;
byte[] bytes = null;
@ -1724,7 +1722,28 @@ namespace IEC61850
Marshal.Copy(buffer, bytes, 0, (int)bytesRead);
}
return handler(invokeId, handlerParameter, clientError, originalInvokeId, bytes, moreFollows);
bool retVal = handler(invokeId, handlerParameter, clientError, originalInvokeId, bytes, moreFollows);
if (clientError != IedClientError.IED_ERROR_OK)
{
handle.Free();
}
else
{
if (moreFollows == false)
{
handle.Free();
}
else
{
if (retVal == false)
{
handle.Free();
}
}
}
return retVal;
}
/// <summary>

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -7,7 +7,8 @@
<OutputType>Exe</OutputType>
<RootNamespace>client_example_async</RootNamespace>
<AssemblyName>client_example_async</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -18,6 +19,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
@ -41,4 +43,7 @@
<Name>IEC61850.NET</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
</Project>

@ -4,93 +4,131 @@ using System.Collections.Generic;
using IEC61850.Client;
using IEC61850.Common;
using System.IO;
using System.Threading;
namespace files
{
/// <summary>
/// This example connects to an IEC 61850 device, list the available files, and then
/// tries to read the file "IEDSERVER.BIN" from the server.
/// </summary>
class MainClass
{
public static void printFiles (IedConnection con, string prefix, string parent)
{
/// <summary>
/// This example connects to an IEC 61850 device, list the available files, and then
/// tries to read the file "IEDSERVER.BIN" from the server.
/// </summary>
class MainClass
{
public static void printFiles(IedConnection con, string prefix, string parent)
{
bool moreFollows = false;
List<FileDirectoryEntry> files = con.GetFileDirectoryEx (parent, null, out moreFollows);
List<FileDirectoryEntry> files = con.GetFileDirectoryEx(parent, null, out moreFollows);
foreach (FileDirectoryEntry file in files) {
Console.WriteLine (prefix + file.GetFileName () + "\t" + file.GetFileSize () + "\t" +
MmsValue.MsTimeToDateTimeOffset (file.GetLastModified ()));
foreach (FileDirectoryEntry file in files)
{
Console.WriteLine(prefix + file.GetFileName() + "\t" + file.GetFileSize() + "\t" +
MmsValue.MsTimeToDateTimeOffset(file.GetLastModified()));
if (file.GetFileName ().EndsWith ("/")) {
printFiles (con, prefix + " ", parent + file.GetFileName ());
}
}
if (file.GetFileName().EndsWith("/"))
{
printFiles(con, prefix + " ", parent + file.GetFileName());
}
}
if (moreFollows)
Console.WriteLine("-- MORE FILES AVAILABLE --");
}
}
static bool getFileHandler (object parameter, byte[] data)
{
Console.WriteLine ("received " + data.Length + " bytes");
static bool getFileHandler(object parameter, byte[] data)
{
Console.WriteLine("received " + data.Length + " bytes");
BinaryWriter binWriter = (BinaryWriter)parameter;
BinaryWriter binWriter = (BinaryWriter)parameter;
binWriter.Write (data);
binWriter.Write(data);
return true;
}
return true;
}
public static void Main (string[] args)
{
IedConnection con = new IedConnection ();
public static void Main(string[] args)
{
IedConnection con = new IedConnection();
string hostname;
string hostname;
if (args.Length > 0)
hostname = args [0];
else
hostname = "127.0.0.1";
if (args.Length > 0)
hostname = args[0];
else
hostname = "127.0.0.1";
Console.WriteLine ("Connect to " + hostname);
Console.WriteLine("Connect to " + hostname);
try {
con.Connect (hostname, 102);
try
{
con.Connect(hostname, 102);
Console.WriteLine ("Files in server root directory:");
List<string> serverDirectory = con.GetServerDirectory (true);
Console.WriteLine("Files in server root directory:");
List<string> serverDirectory = con.GetServerDirectory(true);
foreach (string entry in serverDirectory) {
Console.WriteLine (entry);
}
foreach (string entry in serverDirectory)
{
Console.WriteLine(entry);
}
Console.WriteLine ();
Console.WriteLine();
Console.WriteLine ("File directory tree at server:");
printFiles (con, "", "");
Console.WriteLine ();
Console.WriteLine("File directory tree at server:");
printFiles(con, "", "");
Console.WriteLine();
string filename = "IEDSERVER.BIN";
string filename = "IEDSERVER.BIN";
Console.WriteLine ("Download file " + filename);
Console.WriteLine("Download file " + filename);
/* Download file from server and write it to a new local file */
FileStream fs = new FileStream (filename, FileMode.Create);
BinaryWriter w = new BinaryWriter (fs);
/* Download file from server and write it to a new local file */
FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter w = new BinaryWriter(fs);
con.GetFile (filename, new IedConnection.GetFileHandler (getFileHandler), w);
bool fileDownloadFinished = false;
fs.Close ();
//con.GetFile (filename, new IedConnection.GetFileHandler (getFileHandler), w);
con.Abort ();
} catch (IedConnectionException e) {
Console.WriteLine (e.Message);
}
/// COMMENT SECTION WHEN USING SYNC VERSION -->
// release all resources - do NOT use the object after this call!!
con.Dispose ();
}
}
con.GetFileAsync(filename, delegate (UInt32 invokeId, object parameter, IedClientError err, UInt32 originalInvokeId, byte[] buffer, bool moreFollows)
{
if (err == IedClientError.IED_ERROR_OK)
{
Console.WriteLine("Received new file segment with " + buffer.Length.ToString() + " bytes, more-follows: " + moreFollows.ToString());
w.Write(buffer);
if (moreFollows == false)
fileDownloadFinished = true;
}
else
{
Console.WriteLine("File download error: " + err.ToString());
fileDownloadFinished = true;
}
return true;
}, w);
while (fileDownloadFinished == false)
{
Thread.Sleep(500);
}
/// <-- COMMENT SECTION WHEN USING SYNC VERSION
fs.Close();
con.Abort();
}
catch (IedConnectionException e)
{
Console.WriteLine(e.Message);
}
// release all resources - do NOT use the object after this call!!
con.Dispose();
}
}
}

@ -2969,6 +2969,8 @@ IedConnection_getFile(IedConnection self, IedClientError* error, const char* fil
* \param buffer the buffer that contains the received file data
* \param bytesRead the number of bytes read into the buffer
* \param moreFollows indicates that more file data is following
*
* \return true, continue the file download when moreFollows is true, false, stop file download
*/
typedef bool
(*IedConnection_GetFileAsyncHandler) (uint32_t invokeId, void* parameter, IedClientError err, uint32_t originalInvokeId,

Loading…
Cancel
Save