diff --git a/slsSupportLib/include/UdpRxSocket.h b/slsSupportLib/include/UdpRxSocket.h index c22ee01c0..5a730e855 100644 --- a/slsSupportLib/include/UdpRxSocket.h +++ b/slsSupportLib/include/UdpRxSocket.h @@ -5,8 +5,7 @@ data on a udp socket. It provides a drop in replacement for genericSocket. But please be careful since -this might be deprecated in the future. - +this might be deprecated in the future */ @@ -108,15 +107,18 @@ class UdpRxSocket { // refactoring of the receiver ssize_t ReceiveDataOnly(char *dst) { auto r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr); - // if we read an eiger header pkg read again, with new firmware - // this check can be removed - if (r == 40) { + constexpr ssize_t eiger_header_packet = 40; //only detector that has this + if (r == eiger_header_packet) { FILE_LOG(logWARNING) << "Got header pkg"; r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr); } return r; } + ssize_t getPacketSize() const{ + return packet_size; + } + ssize_t getBufferSize() const { uint64_t ret_size = 0; socklen_t optlen = sizeof(uint64_t); diff --git a/slsSupportLib/src/network_utils.cpp b/slsSupportLib/src/network_utils.cpp index 5be89bb2a..b53cd7aaa 100755 --- a/slsSupportLib/src/network_utils.cpp +++ b/slsSupportLib/src/network_utils.cpp @@ -121,7 +121,7 @@ std::string IpToInterfaceName(const std::string &ip) { IpAddr InterfaceNameToIp(const std::string &ifn) { struct ifaddrs *ifaddr, *ifa; - int family, s; + // int family, s; char host[NI_MAXHOST]; if (getifaddrs(&ifaddr) == -1) { @@ -132,7 +132,7 @@ IpAddr InterfaceNameToIp(const std::string &ifn) { if (ifa->ifa_addr == NULL) continue; - s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, + auto s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if ((strcmp(ifa->ifa_name, ifn.c_str()) == 0) && diff --git a/slsSupportLib/tests/CMakeLists.txt b/slsSupportLib/tests/CMakeLists.txt index 6a7315042..bb84225d5 100755 --- a/slsSupportLib/tests/CMakeLists.txt +++ b/slsSupportLib/tests/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-FixedCapacityContainer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-ToString.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-TypeTraits.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp ) \ No newline at end of file diff --git a/slsSupportLib/tests/test-UdpRxSocket.cpp b/slsSupportLib/tests/test-UdpRxSocket.cpp new file mode 100644 index 000000000..4b970fd07 --- /dev/null +++ b/slsSupportLib/tests/test-UdpRxSocket.cpp @@ -0,0 +1,67 @@ +#include "UdpRxSocket.h" +#include "catch.hpp" +#include "sls_detector_exceptions.h" +#include +#include +#include + +TEST_CASE("Receive a packet on localhost") { + constexpr int port = 50001; + const char *host = nullptr; // localhost + + // Create a socket for sending + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = 0; + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + struct addrinfo *res = 0; + + const std::string portname = std::to_string(port); + if (getaddrinfo(host, portname.c_str(), &hints, &res)) { + throw sls::RuntimeError("Failed at getaddrinfo with " + + std::string(host)); + } + int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd == -1) { + throw sls::RuntimeError("Failed to create UDP RX socket"); + } + + std::vector data_to_send{4, 5, 3, 2, 5, 7, 2, 3}; + ssize_t packet_size = + sizeof(decltype(data_to_send)::value_type) * data_to_send.size(); + sls::UdpRxSocket udpsock{port, packet_size, host}; + + int n = sendto(fd, data_to_send.data(), packet_size, 0, res->ai_addr, + res->ai_addrlen); + + CHECK(n == packet_size); + CHECK(udpsock.ReceivePacket()); + + // Copy data from buffer and compare values + std::vector data_received(data_to_send.size()); + memcpy(data_received.data(), udpsock.LastPacket(), udpsock.getPacketSize()); + CHECK(data_received.size() == data_to_send.size()); // sanity check + for (size_t i = 0; i != data_to_send.size(); ++i) { + CHECK(data_to_send[i] == data_received[i]); + } +} + +TEST_CASE("Shutdown socket without hanging") { + constexpr int port = 50001; + constexpr ssize_t packet_size = 8000; + sls::UdpRxSocket s{port, packet_size}; + + // Start a thread and wait for package + // if the socket is left open we would block + std::future ret = + std::async(static_cast( + &sls::UdpRxSocket::ReceivePacket), + &s); + + s.Shutdown(); + auto r = ret.get(); + + CHECK(r == false); // since we didn't get the packet +} \ No newline at end of file