- .NET API: Fixed bug in IedConnection.GetFileAsync

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

@ -1682,7 +1682,7 @@ namespace IEC61850
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
private delegate bool IedConnection_GetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId, private delegate bool IedConnection_GetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
IntPtr buffer,UInt32 bytesRead,bool moreFollows); IntPtr buffer, UInt32 bytesRead, [MarshalAs(UnmanagedType.I1)] bool moreFollows);
/// <summary> /// <summary>
/// Callback handler for the asynchronous get file service. Will be invoked for each chunk of received data /// Callback handler for the asynchronous get file service. Will be invoked for each chunk of received data
@ -1693,6 +1693,7 @@ namespace IEC61850
/// <param name="originalInvokeId">the invokeId of the first (file open) request</param> /// <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="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> /// <param name="moreFollows">indicates that more file data follows</param>
/// <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); public delegate bool GetFileAsyncHandler(UInt32 invokeId, object parameter, IedClientError err, UInt32 originalInvokeId, byte[] buffer, bool moreFollows);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -1703,7 +1704,6 @@ namespace IEC61850
private bool nativeGetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId, private bool nativeGetFileAsyncHandler(UInt32 invokeId, IntPtr parameter, int err, UInt32 originalInvokeId,
IntPtr buffer, UInt32 bytesRead, bool moreFollows) IntPtr buffer, UInt32 bytesRead, bool moreFollows)
{ {
GCHandle handle = GCHandle.FromIntPtr(parameter); GCHandle handle = GCHandle.FromIntPtr(parameter);
Tuple<GetFileAsyncHandler, object> callbackInfo = handle.Target as Tuple<GetFileAsyncHandler, object>; Tuple<GetFileAsyncHandler, object> callbackInfo = handle.Target as Tuple<GetFileAsyncHandler, object>;
@ -1711,8 +1711,6 @@ namespace IEC61850
GetFileAsyncHandler handler = callbackInfo.Item1; GetFileAsyncHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2; object handlerParameter = callbackInfo.Item2;
handle.Free();
IedClientError clientError = (IedClientError)err; IedClientError clientError = (IedClientError)err;
byte[] bytes = null; byte[] bytes = null;
@ -1724,7 +1722,28 @@ namespace IEC61850
Marshal.Copy(buffer, bytes, 0, (int)bytesRead); 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> /// <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"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -7,7 +7,8 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>client_example_async</RootNamespace> <RootNamespace>client_example_async</RootNamespace>
<AssemblyName>client_example_async</AssemblyName> <AssemblyName>client_example_async</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -18,6 +19,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole> <Externalconsole>true</Externalconsole>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType> <DebugType>full</DebugType>
@ -41,4 +43,7 @@
<Name>IEC61850.NET</Name> <Name>IEC61850.NET</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
</Project> </Project>

@ -4,6 +4,7 @@ using System.Collections.Generic;
using IEC61850.Client; using IEC61850.Client;
using IEC61850.Common; using IEC61850.Common;
using System.IO; using System.IO;
using System.Threading;
namespace files namespace files
{ {
@ -19,11 +20,13 @@ namespace files
List<FileDirectoryEntry> files = con.GetFileDirectoryEx(parent, null, out moreFollows); 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" +
MmsValue.MsTimeToDateTimeOffset(file.GetLastModified())); MmsValue.MsTimeToDateTimeOffset(file.GetLastModified()));
if (file.GetFileName ().EndsWith ("/")) { if (file.GetFileName().EndsWith("/"))
{
printFiles(con, prefix + " ", parent + file.GetFileName()); printFiles(con, prefix + " ", parent + file.GetFileName());
} }
} }
@ -56,13 +59,15 @@ namespace files
Console.WriteLine("Connect to " + hostname); Console.WriteLine("Connect to " + hostname);
try { try
{
con.Connect(hostname, 102); con.Connect(hostname, 102);
Console.WriteLine("Files in server root directory:"); Console.WriteLine("Files in server root directory:");
List<string> serverDirectory = con.GetServerDirectory(true); List<string> serverDirectory = con.GetServerDirectory(true);
foreach (string entry in serverDirectory) { foreach (string entry in serverDirectory)
{
Console.WriteLine(entry); Console.WriteLine(entry);
} }
@ -80,12 +85,45 @@ namespace files
FileStream fs = new FileStream(filename, FileMode.Create); FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter w = new BinaryWriter(fs); BinaryWriter w = new BinaryWriter(fs);
con.GetFile (filename, new IedConnection.GetFileHandler (getFileHandler), w); bool fileDownloadFinished = false;
//con.GetFile (filename, new IedConnection.GetFileHandler (getFileHandler), w);
/// COMMENT SECTION WHEN USING SYNC VERSION -->
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(); fs.Close();
con.Abort(); con.Abort();
} catch (IedConnectionException e) { }
catch (IedConnectionException e)
{
Console.WriteLine(e.Message); Console.WriteLine(e.Message);
} }

@ -2969,6 +2969,8 @@ IedConnection_getFile(IedConnection self, IedClientError* error, const char* fil
* \param buffer the buffer that contains the received file data * \param buffer the buffer that contains the received file data
* \param bytesRead the number of bytes read into the buffer * \param bytesRead the number of bytes read into the buffer
* \param moreFollows indicates that more file data is following * \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 typedef bool
(*IedConnection_GetFileAsyncHandler) (uint32_t invokeId, void* parameter, IedClientError err, uint32_t originalInvokeId, (*IedConnection_GetFileAsyncHandler) (uint32_t invokeId, void* parameter, IedClientError err, uint32_t originalInvokeId,

Loading…
Cancel
Save