From 2c765de4bd1140b4f10c5e53be633614e8f59adc Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Mon, 29 Jan 2024 10:03:55 -0300 Subject: [PATCH 1/7] Add a time wait for packets, this reduces CPU usage when idle, but doesn't affect throughput. --- source/src/enet_encap/networkhandler.cc | 4 ++-- source/src/enet_encap/networkhandler.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/src/enet_encap/networkhandler.cc b/source/src/enet_encap/networkhandler.cc index 0e85263..b5c64ed 100644 --- a/source/src/enet_encap/networkhandler.cc +++ b/source/src/enet_encap/networkhandler.cc @@ -776,7 +776,7 @@ EipStatus NetworkHandlerInitialize() } -EipStatus NetworkHandlerProcessOnce() +EipStatus NetworkHandlerProcessOnce(int timeoutInSeconds) { read_set = master_set; @@ -785,7 +785,7 @@ EipStatus NetworkHandlerProcessOnce() // On Linux, select() modifies timeout to reflect the amount of time // not slept; most other implementations do not do this. // Consider timeout to be undefined after select() returns. - tv.tv_sec = 0; + tv.tv_sec = timeoutInSeconds; tv.tv_usec = 0; int ready_count = select( highest_socket_handle + 1, &read_set, 0, 0, &tv ); diff --git a/source/src/enet_encap/networkhandler.h b/source/src/enet_encap/networkhandler.h index 0e17c90..197b26f 100644 --- a/source/src/enet_encap/networkhandler.h +++ b/source/src/enet_encap/networkhandler.h @@ -19,7 +19,7 @@ */ EipStatus NetworkHandlerInitialize(); -EipStatus NetworkHandlerProcessOnce(); +EipStatus NetworkHandlerProcessOnce(int timeoutInSeconds = 0); EipStatus NetworkHandlerFinish(); From b6a5343210b21d5215ccf3a33e2f2437043feab8 Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Tue, 6 Feb 2024 11:32:50 -0300 Subject: [PATCH 2/7] Now builds on Windows under Visual Studio 2022 We still have lots of warnings. --- source/src/byte_bufs.h | 6 +++--- source/src/cip/cipconnection.cc | 4 ++++ source/src/enet_encap/encap.cc | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/src/byte_bufs.h b/source/src/byte_bufs.h index deb1c05..27d6b74 100644 --- a/source/src/byte_bufs.h +++ b/source/src/byte_bufs.h @@ -33,7 +33,7 @@ class ByteBuf uint8_t* data() const { return start; } uint8_t* end() const { return limit; } - ssize_t size() const { return limit - start; } // ssize_t is signed + uint16_t size() const { return limit - start; } // uint16_t is signed protected: uint8_t* start; @@ -72,7 +72,7 @@ class BufWriter /// Return the unused size of the buffer, the remaining capacity which is empty. /// A negative value would indicate an overrun, but that also indicates a bug in /// in this class because protections are everywhere to prevent overruns. - ssize_t capacity() const { return limit - start; } + uint16_t capacity() const { return limit - start; } /// Advance the start of the buffer by the specified number of bytes and trim /// the capacity(). @@ -174,7 +174,7 @@ class BufReader /// in the buffer. /// A negative value would indicate an overrun, but that also indicates a bug in /// in this class because protections are everywhere to prevent overruns. - ssize_t size() const { return limit - start; } + uint16_t size() const { return limit - start; } /// Advance the start of the buffer by the specified number of bytes and trim /// the size(). diff --git a/source/src/cip/cipconnection.cc b/source/src/cip/cipconnection.cc index a814303..d9456c7 100644 --- a/source/src/cip/cipconnection.cc +++ b/source/src/cip/cipconnection.cc @@ -1231,7 +1231,11 @@ void CipConn::GeneralConfiguration( ConnectionData* aConnData, ConnInstanceType // "expected_packet_rate x connection_timeout_multiplier". Initial value // is called a "pre-consumption" timeout value. if( RxTimeoutUSecs() ) +#ifdef _MSC_VER + SetInactivityWatchDogTimerUSecs(max(RxTimeoutUSecs(), 10000000u)); +#else SetInactivityWatchDogTimerUSecs( std::max( RxTimeoutUSecs(), 10000000u ) ); +#endif else { // this is not an erro diff --git a/source/src/enet_encap/encap.cc b/source/src/enet_encap/encap.cc index 59823bd..ec84e62 100644 --- a/source/src/enet_encap/encap.cc +++ b/source/src/enet_encap/encap.cc @@ -416,8 +416,11 @@ static int disposeOfLargePacket( int aSocket, unsigned aCount ) while( aCount ) { // toss in chunks. +#ifdef _MSC_VER + int readz = min(aCount, unsigned(sizeof chunk)); +#else int readz = std::min( aCount, unsigned( sizeof chunk ) ); - +#endif int num_read = Encapsulation::EnsuredTcpRecv( aSocket, chunk, readz ); if( num_read != readz ) From 33f9c2c75b18136b942ce4cdc88e7a1abc21dc2a Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Tue, 6 Feb 2024 12:32:08 -0300 Subject: [PATCH 3/7] Don't warn on scanf when using Visual Studio --- source/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index b0f460f..b82036b 100755 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -112,7 +112,8 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # enable clock_gettime: add_definitions( -D_POSIX_C_SOURCE=199309L ) endif() - +elseif (MSVC) + add_definitions( -D_CRT_SECURE_NO_WARNINGS ) endif() add_subdirectory( src ) From 433919e724a20c95148e87e292f239dd5963e6d8 Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Tue, 20 Feb 2024 12:33:45 -0300 Subject: [PATCH 4/7] Windows doesn't let us bind to INADDR_BROADCAST, so we build the interface specific broadcast address. --- source/src/enet_encap/networkhandler.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/src/enet_encap/networkhandler.cc b/source/src/enet_encap/networkhandler.cc index b5c64ed..67beb46 100644 --- a/source/src/enet_encap/networkhandler.cc +++ b/source/src/enet_encap/networkhandler.cc @@ -660,7 +660,8 @@ EipStatus NetworkHandlerInitialize() } { - SockAddr address( kEIP_Reserved_Port, INADDR_BROADCAST ); + // Windows doesn't let us bind to INADDR_BROADCAST, so we build the broadcast address + SockAddr address( kEIP_Reserved_Port, (c.ip_address & c.network_mask) | ~c.network_mask); if( bind( s_sockets.udp_global_broadcast_listener, address, SADDRZ ) ) { From a086d7f8af98a1b8cde9de0c1138ddc44b3e2205 Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Tue, 20 Feb 2024 15:43:14 -0300 Subject: [PATCH 5/7] Windows doesn't let us bind to the interface specific broadcast address, so bind to INADDR_ANY. --- source/src/enet_encap/networkhandler.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/src/enet_encap/networkhandler.cc b/source/src/enet_encap/networkhandler.cc index 67beb46..1a717a9 100644 --- a/source/src/enet_encap/networkhandler.cc +++ b/source/src/enet_encap/networkhandler.cc @@ -581,6 +581,12 @@ EipStatus NetworkHandlerInitialize() wVersionRequested = MAKEWORD(2, 2); WSAStartup( wVersionRequested, &wsaData ); + + // Windows doesn't seem to like binding broadcast udp sockets to INADDR_BROADCAST, or the broadcast + // address of any interface so we bind to INADDR_ANY. + long udp_broadcast_addr = INADDR_ANY; +#else + long udp_broadcast_addr = INADDR_BROADCAST; #endif static const int one = 1; @@ -660,8 +666,7 @@ EipStatus NetworkHandlerInitialize() } { - // Windows doesn't let us bind to INADDR_BROADCAST, so we build the broadcast address - SockAddr address( kEIP_Reserved_Port, (c.ip_address & c.network_mask) | ~c.network_mask); + SockAddr address( kEIP_Reserved_Port, udp_broadcast_addr); if( bind( s_sockets.udp_global_broadcast_listener, address, SADDRZ ) ) { From 22299b717f8869831c68e24ac921466546cd1ada Mon Sep 17 00:00:00 2001 From: Furry Futtock Date: Wed, 21 Feb 2024 15:14:40 -0300 Subject: [PATCH 6/7] Finally got this to work on Windows under Visual Studio. Winsock2 only seems seem to want bind broadcast UDP sockets to INADDR_ANY, so for _WIN32 builds I bind udp_global_broadcast_listener and disable udp_local_broadcast_listener. --- source/src/enet_encap/networkhandler.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/src/enet_encap/networkhandler.cc b/source/src/enet_encap/networkhandler.cc index 1a717a9..0583e79 100644 --- a/source/src/enet_encap/networkhandler.cc +++ b/source/src/enet_encap/networkhandler.cc @@ -581,12 +581,6 @@ EipStatus NetworkHandlerInitialize() wVersionRequested = MAKEWORD(2, 2); WSAStartup( wVersionRequested, &wsaData ); - - // Windows doesn't seem to like binding broadcast udp sockets to INADDR_BROADCAST, or the broadcast - // address of any interface so we bind to INADDR_ANY. - long udp_broadcast_addr = INADDR_ANY; -#else - long udp_broadcast_addr = INADDR_BROADCAST; #endif static const int one = 1; @@ -666,7 +660,11 @@ EipStatus NetworkHandlerInitialize() } { - SockAddr address( kEIP_Reserved_Port, udp_broadcast_addr); +#if defined(_WIN32) + SockAddr address(kEIP_Reserved_Port, INADDR_ANY); +#else + SockAddr address( kEIP_Reserved_Port, INADDR_BROADCAST); +#endif if( bind( s_sockets.udp_global_broadcast_listener, address, SADDRZ ) ) { @@ -677,6 +675,7 @@ EipStatus NetworkHandlerInitialize() } } +#if !defined(_WIN32) //-------------------------------------------- // create a new UDP socket s_sockets.udp_local_broadcast_listener = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); @@ -709,6 +708,7 @@ EipStatus NetworkHandlerInitialize() goto error; } } +#endif //--------------------------------------------------- // create a new UDP socket @@ -754,7 +754,7 @@ EipStatus NetworkHandlerInitialize() // add the listener socket to the master set master_set_add( "TCP", s_sockets.tcp_listener ); master_set_add( "UDP", s_sockets.udp_unicast_listener ); - master_set_add( "UDP", s_sockets.udp_local_broadcast_listener ); + if (s_sockets.udp_local_broadcast_listener != -1) master_set_add( "UDP", s_sockets.udp_local_broadcast_listener ); master_set_add( "UDP", s_sockets.udp_global_broadcast_listener ); CIPSTER_TRACE_INFO( "%s:\n" From e18cc975c954eaefd4f9eba29d15bb914d6410a9 Mon Sep 17 00:00:00 2001 From: Robin Page Date: Thu, 18 Apr 2024 16:25:06 +0100 Subject: [PATCH 7/7] Now builds under gcc 12 --- source/src/cip/cipepath.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/src/cip/cipepath.h b/source/src/cip/cipepath.h index 0422249..7ab53f0 100644 --- a/source/src/cip/cipepath.h +++ b/source/src/cip/cipepath.h @@ -128,6 +128,11 @@ class CipAppPath : public SegmentGroup tag[0] = 0; } + CipAppPath(const CipAppPath &rhs) + { + *this = rhs; + } + CipAppPath( int aClassId, int aInstanceId, int aAttributeId = 0 ) { tag[0] = 0;