BACnet
BACnet copied to clipboard
Raspberry Pi Example Has Exception - Platform not supported
I tried to run the RP example with Mono, and with .Net Core 2.2 Both trials return similar message at this line
bacnet_client.Start();
platform not supported exception socket.iocontrol, handles Windows-specific control codes and is not supported on this platform.
for my case, it works just fine, when you create bacnet client do not enter ip address in there
var bacnetClient = new BacnetClient(new BacnetIpUdpProtocolTransport(0xBAC0, false));
bacnetClient.start();
I don't use mono, just publish as "linux-arm" and it will work well for rp3, e.g.
dotnet publish -c Release -r linux-arm -o outputFolder
I'm getting the same exception with the same calls as hoangdungt2 on a OSX and Linux Debian. I'm using an ARM processor. The error seems to stem from the following line in the BACnet.dll
client?.Client.IOControl(unchecked((int)SIO_UDP_CONNRESET),
new[] { System.Convert.ToByte(false) }, null);
I fixed this in my fork awhile ago, sorry for being vague since i dont completely remember, but the best i could gather when i looked into it was that the conn reset was a windows only thing. Hope it helps.
/// <summary>
/// Done to prevent exceptions in Socket.BeginReceive()
/// May only be an issue on windows.
/// </summary>
/// <remarks>
/// http://microsoft.public.win32.programmer.networks.narkive.com/RlxW2V6m/udp-comms-and-connection-reset-problem
/// https://stackoverflow.com/questions/34242622/windows-udp-sockets-recvfrom-fails-with-error-10054
/// https://stackoverflow.com/questions/38790802/determine-operating-system-in-net-core
/// </remarks>
private static void DisableConnReset(UdpClient client)
{
if (EnvironmentHelper.IsWindowsEnvironment())
{
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
client?.Client.IOControl(unchecked((int)SIO_UDP_CONNRESET),
new[] { System.Convert.ToByte(false) }, null);
}
}
I made the following change to BacnetIpUdpProtocolTransport.cs file of the v2-netstandard branch
line 85
if (_dontFragment) _sharedConn.DontFragment = _dontFragment;
removed line 105
added line 107
if (_dontFragment) _exclusiveConn.DontFragment = _dontFragment;
changed line 139 to
try
{
client?.Client.IOControl(unchecked((int)SIO_UDP_CONNRESET),
new[] { System.Convert.ToByte(false) }, null);
}
catch (PlatformNotSupportedException ex)
{
var socket = new Socket(client.Client.AddressFamily, client.Client.SocketType, client.Client.ProtocolType);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
}
Note: This will only work if you call BacnetIpUdpProtocolTransport() with dontFragment=false. I don't know much about socket programming but I assume that disabling connection reset is the same as keeping the connection alive.
The solution provided by @mykah89 and @pnguyen-ecs worked for me and no errors appeared. Many thanks everybody.🙏
Hi BACnet libary team Please reopen issue and integrate fix for DisableConnReset to v2-netstandard branch. I'm using .net core 3.1. Library working fine on windows 10 + wsl2 + docker and on raspberry pi 4 + ubuntu + docker. IsOSPlatform is supported by .net core, .net framework, .net standard https://docs.microsoft.com/en-US/dotnet/api/system.runtime.interopservices.runtimeinformation.isosplatform?view=netcore-3.1
private static void DisableConnReset(UdpClient client)
{
bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
const uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
client?.Client.IOControl(unchecked((int)SIO_UDP_CONNRESET),
new[] { System.Convert.ToByte(false) }, null);
}
}
Hi @minzdrav, you are right this should be integrated with that branch. I will let you know when this is available.
Any idea when this change will be available?