From 9ef65946f68025e8166e070b4c0f78206a2db25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Esmery?= Date: Tue, 16 Dec 2025 07:44:23 +0100 Subject: [PATCH 1/2] Fix #147 --- BACnetClient.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/BACnetClient.cs b/BACnetClient.cs index 65eeb45..872f1fc 100644 --- a/BACnetClient.cs +++ b/BACnetClient.cs @@ -1545,10 +1545,7 @@ public IAsyncResult BeginSubscribeCOVRequest(BacnetAddress adr, BacnetObjectId o public void EndSubscribeCOVRequest(IAsyncResult result, out Exception ex) { var res = (BacnetAsyncResult)result; - ex = res.Error; - if (ex == null && !res.WaitForDone(Timeout)) - ex = new Exception("Wait Timeout"); - + ex = res.WaitForDone(Timeout) ? res.Error : new Exception("Wait Timeout"); res.Dispose(); } From 758c051ed5158d7df27426fc06e9767eeda29f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Esmery?= Date: Wed, 11 Feb 2026 14:34:13 +0100 Subject: [PATCH 2/2] Fix stack overflow --- Transport/BacnetIpUdpProtocolTransport.cs | 96 ++++++++++++----------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/Transport/BacnetIpUdpProtocolTransport.cs b/Transport/BacnetIpUdpProtocolTransport.cs index a3fd84f..938bf1a 100644 --- a/Transport/BacnetIpUdpProtocolTransport.cs +++ b/Transport/BacnetIpUdpProtocolTransport.cs @@ -1,34 +1,34 @@ -/************************************************************************** -* MIT License -* -* Copyright (C) 2014 Morten Kvistgaard -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - +/************************************************************************** +* MIT License +* +* Copyright (C) 2014 Morten Kvistgaard +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + namespace System.IO.BACnet; -/// -/// This is the standard BACNet udp transport -/// +/// +/// This is the standard BACNet udp transport +/// public class BacnetIpUdpProtocolTransport : BacnetTransportBase { private UdpClient _sharedConn; @@ -215,15 +215,21 @@ private void OnReceiveData(IAsyncResult asyncResult) { if (connection.Client != null && !_disposing) { - try - { - // BeginReceive ASAP to enable parallel processing (e.g. query additional data while processing a notification) - connection.BeginReceive(OnReceiveData, connection); - } - catch (Exception ex) - { - Log.Error($"Failed to restart data receive. {ex}"); - } + // BeginReceive ASAP to enable parallel processing (e.g. query additional data while processing a notification) + ThreadPool.UnsafeQueueUserWorkItem(static state => + { + var (transport, udp) = ((BacnetIpUdpProtocolTransport transport, UdpClient udp)) state!; + if (udp.Client == null || transport._disposing) return; + + try + { + udp.BeginReceive(transport.OnReceiveData, udp); + } + catch (Exception ex) + { + transport.Log.Error($"Failed to restart data receive. {ex}"); + } + }, (this, connection)); } } @@ -415,12 +421,12 @@ protected virtual BacnetAddress _GetBroadcastAddress() else { // restricted local broadcast (directed ... routable) - foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) - foreach (var ip in adapter.GetIPProperties().UnicastAddresses) - if (LocalEndPoint.Address.Equals(ip.Address)) - { - ipAddr = ip; - break; + foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) + foreach (var ip in adapter.GetIPProperties().UnicastAddresses) + if (LocalEndPoint.Address.Equals(ip.Address)) + { + ipAddr = ip; + break; } } @@ -462,4 +468,4 @@ public override void Dispose() _sharedConn?.Close(); _sharedConn = null; } -} +}