From 12df1da9e23bbd0b3dbcb7e2251863eadccf18f4 Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:19:50 +1100 Subject: [PATCH 1/9] Add a network hash type for QNX --- src/dsl/word/Network.hpp | 3 +- src/extension/NetworkController.hpp | 9 +++--- src/extension/network/NUClearNetwork.cpp | 6 ++-- src/extension/network/NUClearNetwork.hpp | 15 ++++++--- src/util/network/network_hash_t.hpp | 40 ++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 src/util/network/network_hash_t.hpp diff --git a/src/dsl/word/Network.hpp b/src/dsl/word/Network.hpp index e1377b015..760af8266 100644 --- a/src/dsl/word/Network.hpp +++ b/src/dsl/word/Network.hpp @@ -24,6 +24,7 @@ #define NUCLEAR_DSL_WORD_NETWORK_HPP #include "../../threading/Reaction.hpp" +#include "../../util/network/network_hash_t.hpp" #include "../../util/network/sock_t.hpp" #include "../../util/serialise/Serialise.hpp" #include "../store/ThreadStore.hpp" @@ -47,7 +48,7 @@ namespace dsl { }; struct NetworkListen { - uint64_t hash{0}; + util::network::network_hash_t hash{0}; std::shared_ptr reaction{nullptr}; }; diff --git a/src/extension/NetworkController.hpp b/src/extension/NetworkController.hpp index 30fff7baa..268afaaa8 100644 --- a/src/extension/NetworkController.hpp +++ b/src/extension/NetworkController.hpp @@ -30,6 +30,7 @@ #include "../PowerPlant.hpp" #include "../Reactor.hpp" #include "../util/get_hostname.hpp" +#include "../util/network/network_hash_t.hpp" #include "network/NUClearNetwork.hpp" namespace NUClear { @@ -49,7 +50,7 @@ namespace extension { // Set our function callback network.set_packet_callback([this](const network::NUClearNetwork::NetworkTarget& remote, - const uint64_t& hash, + const util::network::network_hash_t& hash, const bool& reliable, std::vector&& payload) { // Construct our NetworkSource information @@ -59,7 +60,7 @@ namespace extension { std::vector p(std::move(payload)); // Store in our thread local cache - dsl::store::ThreadStore>::value = &p; + dsl::store::ThreadStore>::value = &p; dsl::store::ThreadStore::value = &src; /* Mutex Scope */ { @@ -76,7 +77,7 @@ namespace extension { } // Clear our cache - dsl::store::ThreadStore>::value = nullptr; + dsl::store::ThreadStore>::value = nullptr; dsl::store::ThreadStore::value = nullptr; }); @@ -175,7 +176,7 @@ namespace extension { /// Mutex to guard the list of reactions std::mutex reaction_mutex; /// Map of type hashes to reactions that are interested in them - std::multimap> reactions{}; + std::multimap> reactions{}; }; } // namespace extension diff --git a/src/extension/network/NUClearNetwork.cpp b/src/extension/network/NUClearNetwork.cpp index 4a49886a1..51af03475 100644 --- a/src/extension/network/NUClearNetwork.cpp +++ b/src/extension/network/NUClearNetwork.cpp @@ -82,7 +82,9 @@ namespace extension { } void NUClearNetwork::set_packet_callback( - std::function&&)> f) { + std::function< + void(const NetworkTarget&, const util::network::network_hash_t&, const bool&, std::vector&&)> + f) { packet_callback = std::move(f); } @@ -1028,7 +1030,7 @@ namespace extension { } - void NUClearNetwork::send(const uint64_t& hash, + void NUClearNetwork::send(const util::network::network_hash_t& hash, const std::vector& payload, const std::string& target, bool reliable) { diff --git a/src/extension/network/NUClearNetwork.hpp b/src/extension/network/NUClearNetwork.hpp index fc3d93656..ba3ee7fd6 100644 --- a/src/extension/network/NUClearNetwork.hpp +++ b/src/extension/network/NUClearNetwork.hpp @@ -36,6 +36,7 @@ #include #include +#include "../../util/network/network_hash_t.hpp" #include "../../util/network/sock_t.hpp" #include "../../util/platform.hpp" #include "wire_protocol.hpp" @@ -130,15 +131,20 @@ namespace extension { * @param target who we are sending to (blank means everyone) * @param reliable if the delivery of the data should be ensured */ - void send(const uint64_t& hash, const std::vector& payload, const std::string& target, bool reliable); + void send(const util::network::network_hash_t& hash, + const std::vector& payload, + const std::string& target, + bool reliable); /** * @brief Set the callback to use when a data packet is completed * * @param f the callback function */ - void set_packet_callback( - std::function&&)> f); + void set_packet_callback(std::function&&)> f); /** * @brief Set the callback to use when a node joins the network @@ -313,7 +319,8 @@ namespace extension { std::atomic packet_id_source{0}; /// The callback to execute when a data packet is completed - std::function&&)> + std::function< + void(const NetworkTarget&, const util::network::network_hash_t&, const bool&, std::vector&&)> packet_callback; /// The callback to execute when a node joins the network std::function join_callback; diff --git a/src/util/network/network_hash_t.hpp b/src/util/network/network_hash_t.hpp new file mode 100644 index 000000000..2f6589dde --- /dev/null +++ b/src/util/network/network_hash_t.hpp @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2017 NUClear Contributors + * + * This file is part of the NUClear codebase. + * See https://github.com/Fastcode/NUClear for further info. + * + * 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. + */ + +#ifndef NUCLEAR_UTIL_NETWORK_NETWORK_HASH_T_HPP +#define NUCLEAR_UTIL_NETWORK_NETWORK_HASH_T_HPP + +namespace NUClear { +namespace util { + namespace network { + +#ifdef __QNX__ + using network_hash_t = unsigned long long; +#else + using network_hash_t = uint64_t; +#endif + + } // namespace network +} // namespace util +} // namespace NUClear + +#endif // NUCLEAR_UTIL_NETWORK_NETWORK_HASH_T_HPP From 1ce5a4643c0e79614814d519364d94b591b24d4c Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:20:10 +1100 Subject: [PATCH 2/9] AI_ALL is undefined on QNX --- src/util/network/resolve.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/util/network/resolve.cpp b/src/util/network/resolve.cpp index 73435b41b..322d4cffb 100644 --- a/src/util/network/resolve.cpp +++ b/src/util/network/resolve.cpp @@ -37,7 +37,9 @@ namespace util { addrinfo hints{}; hints.ai_family = AF_UNSPEC; // don't care about IPv4 or IPv6 hints.ai_socktype = AF_UNSPEC; // don't care about TCP or UDP - hints.ai_flags = AI_ALL; // Get all addresses even if we don't have an interface for them +#ifndef __QNX__ + hints.ai_flags = AI_ALL; // Get all addresses even if we don't have an interface for them +#endif // Get our info on this address addrinfo* servinfo_ptr = nullptr; From 04459472433bbf5fb7e1b2d73dcced3c5757b57f Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:20:35 +1100 Subject: [PATCH 3/9] Fix constructor inheritance in QNX --- src/message/CommandLineArguments.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/message/CommandLineArguments.hpp b/src/message/CommandLineArguments.hpp index 3341a9d9d..6206b6f5f 100644 --- a/src/message/CommandLineArguments.hpp +++ b/src/message/CommandLineArguments.hpp @@ -30,8 +30,14 @@ namespace message { * @brief This type is a NUClear message type that holds command line arguments */ struct CommandLineArguments : public std::vector { +#ifdef __QNX__ + public: + template + CommandLineArguments(Args... args) : std::vector::vector(std::forward(args)...) {} +#else // Inherit constructors using std::vector::vector; +#endif }; } // namespace message From 9429ae89480ae5f6df582b11d3f0e80aa82995bc Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:21:00 +1100 Subject: [PATCH 4/9] Link against `socket` library for QNX --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 911a429bd..b2ba0af9b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,10 @@ target_link_libraries(nuclear ${CMAKE_THREAD_LIBS_INIT}) set_target_properties(nuclear PROPERTIES POSITION_INDEPENDENT_CODE ON) target_compile_features(nuclear PUBLIC cxx_std_14) +if(QNX) + target_link_libraries(nuclear socket) +endif(QNX) + # Enable warnings, and all warnings are errors if(MSVC) target_compile_options(nuclear PRIVATE /W4 /WX) From 93b1c7962f39767de7f846ff70fe55122d99807b Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:21:24 +1100 Subject: [PATCH 5/9] Don't use `int64_t` in template for QNX --- tests/dsl/emit/Delay.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/dsl/emit/Delay.cpp b/tests/dsl/emit/Delay.cpp index 8e5fb5c1a..535dca33a 100644 --- a/tests/dsl/emit/Delay.cpp +++ b/tests/dsl/emit/Delay.cpp @@ -32,7 +32,11 @@ namespace { std::vector events; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) /// @brief Test units are the time units the test is performed in +#ifdef __QNX__ +using TestUnits = std::chrono::duration>; +#else using TestUnits = std::chrono::duration>; +#endif /// @brief Perform this many different time points for the test constexpr int test_loops = 5; From 16960504b235601e930f80305c9e60a1556d20d0 Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:44:53 +1100 Subject: [PATCH 6/9] Remove fanciness from `CommandLineArguments` --- src/message/CommandLineArguments.hpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/message/CommandLineArguments.hpp b/src/message/CommandLineArguments.hpp index 6206b6f5f..faeb116ba 100644 --- a/src/message/CommandLineArguments.hpp +++ b/src/message/CommandLineArguments.hpp @@ -23,22 +23,14 @@ #ifndef NUCLEAR_MESSAGE_COMMANDLINEARGUMENTS_HPP #define NUCLEAR_MESSAGE_COMMANDLINEARGUMENTS_HPP -namespace NUClear { -namespace message { +#include +#include + /** * @brief This type is a NUClear message type that holds command line arguments */ - struct CommandLineArguments : public std::vector { -#ifdef __QNX__ - public: - template - CommandLineArguments(Args... args) : std::vector::vector(std::forward(args)...) {} -#else - // Inherit constructors - using std::vector::vector; -#endif - }; + struct CommandLineArguments : public std::vector {}; } // namespace message } // namespace NUClear From 8425292b802f603e22124136609af353a9b050a0 Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:45:25 +1100 Subject: [PATCH 7/9] Condition on the existence of `AI_ALL` --- src/util/network/resolve.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/network/resolve.cpp b/src/util/network/resolve.cpp index 322d4cffb..3ab545cee 100644 --- a/src/util/network/resolve.cpp +++ b/src/util/network/resolve.cpp @@ -37,7 +37,7 @@ namespace util { addrinfo hints{}; hints.ai_family = AF_UNSPEC; // don't care about IPv4 or IPv6 hints.ai_socktype = AF_UNSPEC; // don't care about TCP or UDP -#ifndef __QNX__ +#ifdef AI_ALL hints.ai_flags = AI_ALL; // Get all addresses even if we don't have an interface for them #endif From 44bf4053314cf5aa974d8635ac403ed33a82c87e Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:45:44 +1100 Subject: [PATCH 8/9] Use `int` rather than `int64_t` --- tests/dsl/emit/Delay.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/dsl/emit/Delay.cpp b/tests/dsl/emit/Delay.cpp index 535dca33a..4ef44e0b8 100644 --- a/tests/dsl/emit/Delay.cpp +++ b/tests/dsl/emit/Delay.cpp @@ -32,11 +32,7 @@ namespace { std::vector events; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) /// @brief Test units are the time units the test is performed in -#ifdef __QNX__ -using TestUnits = std::chrono::duration>; -#else -using TestUnits = std::chrono::duration>; -#endif +using TestUnits = std::chrono::duration>; /// @brief Perform this many different time points for the test constexpr int test_loops = 5; From 4bdebee3c36e9a49f265752ff0f32f60b76001f2 Mon Sep 17 00:00:00 2001 From: Alex Biddulph Date: Fri, 3 Nov 2023 14:52:19 +1100 Subject: [PATCH 9/9] Fix bizarre commit in `CommandLineArguments` --- src/message/CommandLineArguments.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/message/CommandLineArguments.hpp b/src/message/CommandLineArguments.hpp index faeb116ba..1117d27aa 100644 --- a/src/message/CommandLineArguments.hpp +++ b/src/message/CommandLineArguments.hpp @@ -26,6 +26,8 @@ #include #include +namespace NUClear { +namespace message { /** * @brief This type is a NUClear message type that holds command line arguments