diff --git a/include/fastdds/rtps/attributes/BuiltinTransports.hpp b/include/fastdds/rtps/attributes/BuiltinTransports.hpp index cc5addafc3c..b99141066bd 100644 --- a/include/fastdds/rtps/attributes/BuiltinTransports.hpp +++ b/include/fastdds/rtps/attributes/BuiltinTransports.hpp @@ -104,14 +104,15 @@ inline bool operator ==( */ enum class BuiltinTransports : uint16_t { - NONE = 0, //< No transport will be instantiated - DEFAULT = 1, //< Default value that will instantiate UDPv4 and SHM transports + NONE = 0, //< No transport will be instantiated + DEFAULT = 1, //< Default value that will instantiate UDPv4 and SHM transports DEFAULTv6 = 2, //< Instantiate UDPv6 and SHM transports SHM = 3, //< Instantiate SHM transport only UDPv4 = 4, //< Instantiate UDPv4 transport only UDPv6 = 5, //< Instantiate UDPv6 transport only LARGE_DATA = 6, //< Instantiate SHM, UDPv4 and TCPv4 transports, but UDPv4 is only used for bootstrapping discovery - LARGE_DATAv6 = 7 //< Instantiate SHM, UDPv6 and TCPv6 transports, but UDPv6 is only used for bootstrapping discovery + LARGE_DATAv6 = 7, //< Instantiate SHM, UDPv6 and TCPv6 transports, but UDPv6 is only used for bootstrapping discovery + P2P = 8 //< Instantiate SHM and TCPv4 transports, shall only be used along with EASY_MODE= }; inline std::ostream& operator <<( @@ -144,6 +145,9 @@ inline std::ostream& operator <<( case BuiltinTransports::LARGE_DATAv6: output << "LARGE_DATAv6"; break; + case BuiltinTransports::P2P: + output << "P2P"; + break; default: output << "UNKNOWN"; break; diff --git a/resources/images/fastdds_github_banner.png b/resources/images/fastdds_github_banner.png index 284e377e2d6..5eb782133e4 100644 Binary files a/resources/images/fastdds_github_banner.png and b/resources/images/fastdds_github_banner.png differ diff --git a/resources/xsd/fastdds_profiles.xsd b/resources/xsd/fastdds_profiles.xsd index ed487dec017..56395e79518 100644 --- a/resources/xsd/fastdds_profiles.xsd +++ b/resources/xsd/fastdds_profiles.xsd @@ -1963,6 +1963,7 @@ + diff --git a/src/cpp/rtps/RTPSDomain.cpp b/src/cpp/rtps/RTPSDomain.cpp index 843dd0d01fd..df45a8fe52d 100644 --- a/src/cpp/rtps/RTPSDomain.cpp +++ b/src/cpp/rtps/RTPSDomain.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -518,59 +519,128 @@ RTPSParticipant* RTPSDomainImpl::clientServerEnvironmentCreationOverride( // Is up to the caller guarantee the att argument is not modified during the call RTPSParticipantAttributes client_att(att); - // Retrieve the info from the environment variable - LocatorList_t& server_list = client_att.builtin.discovery_config.m_DiscoveryServers; - if (load_environment_server_info(server_list) && server_list.empty()) - { - // It's not an error, the environment variable may not be set. Any issue with environment - // variable syntax is EPROSIMA_LOG_ERROR already - return nullptr; - } + // Check whether we need to initialize in easy mode + const std::string& easy_mode_env_value = easy_mode_env(); - // Check if some address requires the UDPv6, TCPv4 or TCPv6 transport - if (server_list.has_kind() && - !has_user_transport(client_att)) + if (easy_mode_env_value.empty()) { - // Extend builtin transports with the UDPv6 transport - auto descriptor = std::make_shared(); - descriptor->sendBufferSize = client_att.sendSocketBufferSize; - descriptor->receiveBufferSize = client_att.listenSocketBufferSize; - client_att.userTransports.push_back(std::move(descriptor)); - } - if (server_list.has_kind() && - !has_user_transport(client_att)) - { - // Extend builtin transports with the TCPv4 transport - auto descriptor = std::make_shared(); - // Add automatic port - descriptor->add_listener_port(0); - descriptor->sendBufferSize = client_att.sendSocketBufferSize; - descriptor->receiveBufferSize = client_att.listenSocketBufferSize; - client_att.userTransports.push_back(std::move(descriptor)); - } - if (server_list.has_kind() && - !has_user_transport(client_att)) - { - // Extend builtin transports with the TCPv6 transport - auto descriptor = std::make_shared(); - // Add automatic port - descriptor->add_listener_port(0); - descriptor->sendBufferSize = client_att.sendSocketBufferSize; - descriptor->receiveBufferSize = client_att.listenSocketBufferSize; - client_att.userTransports.push_back(std::move(descriptor)); - } + // Retrieve the info from the environment variable + LocatorList_t& server_list = client_att.builtin.discovery_config.m_DiscoveryServers; + if (load_environment_server_info(server_list) && server_list.empty()) + { + // It's not an error, the environment variable may not be set. Any issue with environment + // variable syntax is EPROSIMA_LOG_ERROR already + return nullptr; + } - EPROSIMA_LOG_INFO(DOMAIN, "Detected auto client-server environment variable." - << "Trying to create client with the default server setup: " - << client_att.builtin.discovery_config.m_DiscoveryServers); + // Check if some address requires the UDPv6, TCPv4 or TCPv6 transport + if (server_list.has_kind() && + !has_user_transport(client_att)) + { + // Extend builtin transports with the UDPv6 transport + auto descriptor = std::make_shared(); + descriptor->sendBufferSize = client_att.sendSocketBufferSize; + descriptor->receiveBufferSize = client_att.listenSocketBufferSize; + client_att.userTransports.push_back(std::move(descriptor)); + } + if (server_list.has_kind() && + !has_user_transport(client_att)) + { + // Extend builtin transports with the TCPv4 transport + auto descriptor = std::make_shared(); + // Add automatic port + descriptor->add_listener_port(0); + descriptor->sendBufferSize = client_att.sendSocketBufferSize; + descriptor->receiveBufferSize = client_att.listenSocketBufferSize; + client_att.userTransports.push_back(std::move(descriptor)); + } + if (server_list.has_kind() && + !has_user_transport(client_att)) + { + // Extend builtin transports with the TCPv6 transport + auto descriptor = std::make_shared(); + // Add automatic port + descriptor->add_listener_port(0); + descriptor->sendBufferSize = client_att.sendSocketBufferSize; + descriptor->receiveBufferSize = client_att.listenSocketBufferSize; + client_att.userTransports.push_back(std::move(descriptor)); + } + + EPROSIMA_LOG_INFO(DOMAIN, "Detected auto client-server environment variable." + << "Trying to create client with the default server setup: " + << client_att.builtin.discovery_config.m_DiscoveryServers); - client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT; - // RemoteServerAttributes already fill in above + client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT; + // RemoteServerAttributes already fill in above - // Check if the client must become a super client - if (ros_super_client_env()) + // Check if the client must become a super client + if (ros_super_client_env()) + { + client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT; + } + } + else { + // SUPER_CLIENT client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT; + + // P2P transport. Similar to LARGE_DATA, but with UDPv4 unicast + client_att.useBuiltinTransports = false; + client_att.setup_transports(BuiltinTransports::P2P); + + // Ignore initialpeers + client_att.builtin.initialPeersList = LocatorList(); + + eprosima::fastdds::rtps::PortParameters port_params; + + auto domain_port = port_params.get_discovery_server_port(domain_id); + + // Add user traffic TCP + eprosima::fastdds::rtps::Locator_t locator_tcp; + locator_tcp.kind = LOCATOR_KIND_TCPv4; + + IPLocator::setPhysicalPort(locator_tcp, 0); + IPLocator::setLogicalPort(locator_tcp, 0); + // Initialize to the wan interface + IPLocator::setIPv4(locator_tcp, "0.0.0.0"); + + client_att.defaultUnicastLocatorList.push_back(locator_tcp); + + // Add remote DS based on port + eprosima::fastdds::rtps::Locator_t locator_udp; + locator_udp.kind = LOCATOR_KIND_UDPv4; + + locator_udp.port = domain_port; + IPLocator::setIPv4(locator_udp, 127, 0, 0, 1); + + // Point to the well known DS port in the corresponding domain + client_att.builtin.discovery_config.m_DiscoveryServers.push_back(locator_udp); + + SystemCommandBuilder sys_command; + int res = sys_command.executable(FAST_DDS_DEFAULT_CLI_SCRIPT_NAME) + .verb(FAST_DDS_DEFAULT_CLI_DISCOVERY_VERB) + .verb(FAST_DDS_DEFAULT_CLI_AUTO_VERB) + .arg("-d") + .value(std::to_string(domain_id)) + .value(easy_mode_env_value + ":" + std::to_string(domain_id)) + .build_and_call(); +#ifndef _WIN32 + // Adecuate Python subprocess return + res = WEXITSTATUS(res); +#endif // _WIN32 + + if (res != SystemCommandBuilder::SystemCommandResult::SUCCESS) + { + if (res == SystemCommandBuilder::SystemCommandResult::BAD_PARAM) + { + EPROSIMA_LOG_ERROR("DOMAIN", "EASY_MODE IP connection conflicts with a previous one."); + } + else + { + EPROSIMA_LOG_ERROR(DOMAIN, "Auto discovery server client setup. Unable to spawn daemon."); + } + return nullptr; + } } RTPSParticipant* part = createParticipant(domain_id, enabled, client_att, listen); diff --git a/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp b/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp index 74140cf2896..1d30d88305f 100644 --- a/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp +++ b/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp @@ -301,6 +301,38 @@ static void setup_transports_large_datav6( } } +static void setup_transports_p2p( + RTPSParticipantAttributes& att, + bool intraprocess_only, + const fastdds::rtps::BuiltinTransportsOptions& options) +{ + if (!intraprocess_only) + { + setup_large_data_shm_transport(att, options); + + auto tcp_transport = create_tcpv4_transport(att, options); + att.userTransports.push_back(tcp_transport); + + Locator_t tcp_loc; + tcp_loc.kind = LOCATOR_KIND_TCPv4; + IPLocator::setIPv4(tcp_loc, "0.0.0.0"); + IPLocator::setPhysicalPort(tcp_loc, 0); + IPLocator::setLogicalPort(tcp_loc, 0); + att.defaultUnicastLocatorList.push_back(tcp_loc); + } + + auto udp_descriptor = create_udpv4_transport(att, intraprocess_only, options); + att.userTransports.push_back(udp_descriptor); + + if (!intraprocess_only) + { + Locator_t udp_locator; + udp_locator.kind = LOCATOR_KIND_UDPv4; + IPLocator::setIPv4(udp_locator, "127.0.0.1"); + att.builtin.metatrafficUnicastLocatorList.push_back(udp_locator); + } +} + void RTPSParticipantAttributes::setup_transports( fastdds::rtps::BuiltinTransports transports, const fastdds::rtps::BuiltinTransportsOptions& options) @@ -309,7 +341,8 @@ void RTPSParticipantAttributes::setup_transports( (transports != fastdds::rtps::BuiltinTransports::NONE && transports != fastdds::rtps::BuiltinTransports::SHM && transports != fastdds::rtps::BuiltinTransports::LARGE_DATA && - transports != fastdds::rtps::BuiltinTransports::LARGE_DATAv6)) + transports != fastdds::rtps::BuiltinTransports::LARGE_DATAv6 && + transports != fastdds::rtps::BuiltinTransports::P2P)) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Max message size of UDP cannot be greater than " << std::to_string( @@ -358,6 +391,12 @@ void RTPSParticipantAttributes::setup_transports( setup_transports_large_datav6(*this, intraprocess_only, options); break; + case fastdds::rtps::BuiltinTransports::P2P: + // This parameter will allow allow the initialization of UDP transports with maxMessageSize > 65500 KB (s_maximumMessageSize) + max_msg_size_no_frag = options.maxMessageSize; + setup_transports_p2p(*this, intraprocess_only, options); + break; + default: EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Setup for '" << transports << "' transport configuration not yet supported."); diff --git a/src/cpp/rtps/attributes/ServerAttributes.cpp b/src/cpp/rtps/attributes/ServerAttributes.cpp index eb117590469..9caf73fceef 100644 --- a/src/cpp/rtps/attributes/ServerAttributes.cpp +++ b/src/cpp/rtps/attributes/ServerAttributes.cpp @@ -69,6 +69,13 @@ const std::string& ros_discovery_server_env() return servers; } +const std::string& easy_mode_env() +{ + static std::string ip_value; + SystemInfo::get_env(EASY_MODE_URI, ip_value); + return ip_value; +} + bool load_environment_server_info( LocatorList_t& servers_list) { diff --git a/src/cpp/rtps/attributes/ServerAttributes.hpp b/src/cpp/rtps/attributes/ServerAttributes.hpp index bb4b20c4a8a..53e0454b2aa 100644 --- a/src/cpp/rtps/attributes/ServerAttributes.hpp +++ b/src/cpp/rtps/attributes/ServerAttributes.hpp @@ -136,16 +136,26 @@ std::basic_ostream& operator <<( // Default server base guidPrefix const char* const DEFAULT_ROS2_SERVER_GUIDPREFIX = "44.53.00.5f.45.50.52.4f.53.49.4d.41"; -/* Environment variable to specify a semicolon-separated list of locators ([transport]ip:port) that define remote server - * locators. The [transport] specification is optional. The default transport is UDPv4. - * For the variable to take any effect, the following pre-condition must be met: - * - The discovery protocol must be either SIMPLE or SERVER. - * a. In the case of SIMPLE, the participant is created as a CLIENT instead. - * b. In the case of SERVER, the participant is created as a SERVER, using the DEFAULT_ROS2_MASTER_URI list to - * expand the list of remote servers. +/* Environment variable that can either serve to: + * - Specify the Discovery Server auto mode by setting its value to AUTO. + * - Specify a semicolon-separated list of locators ([transport]ip:port) that define remote server + * locators. The [transport] specification is optional. The default transport is UDPv4. + * For the variable to take any effect, the following pre-condition must be met: + * - The discovery protocol must be either SIMPLE or SERVER. + * a. In the case of SIMPLE, the participant is created as a CLIENT instead. + * b. In the case of SERVER, the participant is created as a SERVER, using the DEFAULT_ROS2_MASTER_URI list to + * expand the list of remote servers. */ const char* const DEFAULT_ROS2_MASTER_URI = "ROS_DISCOVERY_SERVER"; +/* Environment variable that: + * - Will spawn a background Discovery Server in the current domain (if there were not). + * - Specify an external ip address to connect the background Discovery Server (the port is deduced from the domain). + * - Set the transports to TCP and SHM. + * - Make the participant a SUPER_CLIENT. + */ +const char* const EASY_MODE_URI = "EASY_MODE"; + /* Environment variable to transform a SIMPLE participant in a SUPER CLIENT. * If the participant is not SIMPLE, the variable doesn't have any effects. * The variable can assume the following values: @@ -186,6 +196,12 @@ bool load_environment_server_info( */ const std::string& ros_discovery_server_env(); +/** + * Get the value of environment variable EASY_MODE_URI + * @return The value of environment variable EASY_MODE_URI. Empty string if the variable is not defined. + */ +const std::string& easy_mode_env(); + /** * Get the value of environment variable ROS_SUPER_CLIENT * @return The value of environment variable ROS_SUPER_CLIENT. False if the variable is not defined. diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp index 1cf9622ce34..ea0981ceecb 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp @@ -68,7 +68,6 @@ PDPServer::PDPServer( LocatorList_t env_servers; { std::lock_guard lock(*getMutex()); - if (load_environment_server_info(env_servers)) { for (auto server : env_servers) diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 179dc1d2e67..9bdc3175d90 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -115,7 +115,8 @@ static void set_builtin_transports_from_env_var( "UDPv4", BuiltinTransports::UDPv4, "UDPv6", BuiltinTransports::UDPv6, "LARGE_DATA", BuiltinTransports::LARGE_DATA, - "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6)) + "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6, + "P2P", BuiltinTransports::P2P)) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" << env_var_name << "'. Leaving as DEFAULT"); @@ -141,7 +142,8 @@ static void set_builtin_transports_from_env_var( "UDPv4", BuiltinTransports::UDPv4, "UDPv6", BuiltinTransports::UDPv6, "LARGE_DATA", BuiltinTransports::LARGE_DATA, - "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6)) + "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6, + "P2P", BuiltinTransports::P2P)) { EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" << env_var_name << "'. Leaving as DEFAULT"); diff --git a/src/cpp/utils/SystemCommandBuilder.hpp b/src/cpp/utils/SystemCommandBuilder.hpp new file mode 100644 index 00000000000..982ab5b5656 --- /dev/null +++ b/src/cpp/utils/SystemCommandBuilder.hpp @@ -0,0 +1,87 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef UTILS__SYSTEMCOMMANDBUILDER_HPP_ +#define UTILS__SYSTEMCOMMANDBUILDER_HPP_ + +#include +#include + +namespace eprosima { + +namespace fastdds { + +static constexpr const char* FAST_DDS_DEFAULT_CLI_SCRIPT_NAME = "fastdds"; +static constexpr const char* FAST_DDS_DEFAULT_CLI_DISCOVERY_VERB = "discovery"; +static constexpr const char* FAST_DDS_DEFAULT_CLI_AUTO_VERB = "auto"; + +/** + * @brief Class to build and execute system commands. + */ +class SystemCommandBuilder +{ +public: + + enum SystemCommandResult + { + SUCCESS = 0, + FAILURE, + BAD_PARAM, + INVALID + }; + + SystemCommandBuilder() = default; + + SystemCommandBuilder& executable( + const std::string& executable) + { + command_ << executable; + return *this; + } + + SystemCommandBuilder& verb( + const std::string& verb) + { + command_ << " " << verb; + return *this; + } + + SystemCommandBuilder& arg( + const std::string& arg) + { + command_ << " " << arg; + return *this; + } + + SystemCommandBuilder& value( + const std::string& value) + { + command_ << " " << value; + return *this; + } + + int build_and_call() + { + return std::system(command_.str().c_str()); + } + +private: + + std::stringstream command_; +}; + +} // namespace fastdds +} // namespace eprosima + +#endif // UTILS__SYSTEMCOMMANDBUILDER_HPP_ diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index 36ca76c7adf..b1ecf8ffc82 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -4673,6 +4673,7 @@ XMLP_ret XMLParser::getXMLBuiltinTransports( + @@ -4834,7 +4835,8 @@ XMLP_ret XMLParser::getXMLBuiltinTransports( UDPv4, eprosima::fastdds::rtps::BuiltinTransports::UDPv4, UDPv6, eprosima::fastdds::rtps::BuiltinTransports::UDPv6, LARGE_DATA, eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA, - LARGE_DATAv6, eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATAv6)) + LARGE_DATAv6, eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATAv6, + P2P, eprosima::fastdds::rtps::BuiltinTransports::P2P)) { EPROSIMA_LOG_ERROR(XMLPARSER, "Node '" << KIND << "' bad content"); ret = XMLP_ret::XML_ERROR; diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index 7d679553a61..237e774b24d 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -199,6 +199,7 @@ const char* DEFAULT_C = "DEFAULT"; const char* DEFAULTv6 = "DEFAULTv6"; const char* LARGE_DATA = "LARGE_DATA"; const char* LARGE_DATAv6 = "LARGE_DATAv6"; +const char* P2P = "P2P"; const char* INIT_ACKNACK_DELAY = "initial_acknack_delay"; const char* HEARTB_RESP_DELAY = "heartbeat_response_delay"; const char* INIT_HEARTB_DELAY = "initial_heartbeat_delay"; diff --git a/src/cpp/xmlparser/XMLParserCommon.h b/src/cpp/xmlparser/XMLParserCommon.h index 1bf1811273b..1d33dc58299 100644 --- a/src/cpp/xmlparser/XMLParserCommon.h +++ b/src/cpp/xmlparser/XMLParserCommon.h @@ -215,6 +215,7 @@ extern const char* DEFAULT_C; extern const char* DEFAULTv6; extern const char* LARGE_DATA; extern const char* LARGE_DATAv6; +extern const char* P2P; extern const char* INIT_ACKNACK_DELAY; extern const char* HEARTB_RESP_DELAY; extern const char* INIT_HEARTB_DELAY; diff --git a/test/blackbox/api/dds-pim/PubSubReader.hpp b/test/blackbox/api/dds-pim/PubSubReader.hpp index d3069adce6c..32a121b888e 100644 --- a/test/blackbox/api/dds-pim/PubSubReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubReader.hpp @@ -336,6 +336,8 @@ class PubSubReader , message_receive_count_(0) , filter_expression_("") , expression_parameters_({}) + , use_preferred_domain_id_(false) + , preferred_domain_id_(0) { // Load default QoS to permit testing with external XML profile files. DomainParticipantFactory::get_instance()->load_profiles(); @@ -427,10 +429,11 @@ class PubSubReader ASSERT_TRUE(participant_->is_enabled()); } } + if (participant_ == nullptr) { participant_ = DomainParticipantFactory::get_instance()->create_participant( - (uint32_t)GET_PID() % 230, + (use_preferred_domain_id_ ? preferred_domain_id_ : (uint32_t)GET_PID() % 230), participant_qos_, &participant_listener_, eprosima::fastdds::dds::StatusMask::none()); @@ -952,6 +955,14 @@ class PubSubReader return *this; } + PubSubReader& set_domain_id( + const uint32_t& domain_id) + { + use_preferred_domain_id_ = true; + preferred_domain_id_ = domain_id; + return *this; + } + /*** Function to change QoS ***/ PubSubReader& reliability( const eprosima::fastdds::dds::ReliabilityQosPolicyKind kind) @@ -1725,7 +1736,7 @@ class PubSubReader std::cout << "Reader gets discovery result..." << std::endl; } - void setOnDiscoveryFunction( + void set_on_discovery_function( std::function f) { @@ -1861,6 +1872,11 @@ class PubSubReader return matched_; } + unsigned int get_participants_matched() const + { + return participant_matched_; + } + void set_xml_filename( const std::string& name) { @@ -2223,6 +2239,10 @@ class PubSubReader std::string filter_expression_; //! Parameters for CFT expression std::vector expression_parameters_; + + //! Preferred domain ID + bool use_preferred_domain_id_; + uint32_t preferred_domain_id_; }; template diff --git a/test/blackbox/api/dds-pim/PubSubWriter.hpp b/test/blackbox/api/dds-pim/PubSubWriter.hpp index 2ea4a818b66..469c494691d 100644 --- a/test/blackbox/api/dds-pim/PubSubWriter.hpp +++ b/test/blackbox/api/dds-pim/PubSubWriter.hpp @@ -88,7 +88,7 @@ class PubSubWriter static_cast(should_be_ignored); if (writer_.onDiscovery_ != nullptr) { - writer_.discovery_result_ = writer_.onDiscovery_(info); + writer_.discovery_result_ = writer_.onDiscovery_(info, status); } if (status == eprosima::fastdds::rtps::ParticipantDiscoveryStatus::DISCOVERED_PARTICIPANT) @@ -303,7 +303,8 @@ class PubSubWriter , times_liveliness_lost_(0) , times_incompatible_qos_(0) , last_incompatible_qos_(eprosima::fastdds::dds::INVALID_QOS_POLICY_ID) - + , use_preferred_domain_id_(false) + , preferred_domain_id_(0) #if HAVE_SECURITY , authorized_(0) , unauthorized_(0) @@ -392,7 +393,7 @@ class PubSubWriter if (participant_ == nullptr) { participant_ = DomainParticipantFactory::get_instance()->create_participant( - (uint32_t)GET_PID() % 230, + (use_preferred_domain_id_ ? preferred_domain_id_ : (uint32_t)GET_PID() % 230), participant_qos_, &participant_listener_, eprosima::fastdds::dds::StatusMask::none()); @@ -868,6 +869,21 @@ class PubSubWriter return *this; } + PubSubWriter& set_domain_id( + const uint32_t& domain_id) + { + use_preferred_domain_id_ = true; + preferred_domain_id_ = domain_id; + return *this; + } + + void set_on_discovery_function( + std::function f) + { + onDiscovery_ = f; + } + /*** Function to change QoS ***/ PubSubWriter& reliability( const eprosima::fastdds::dds::ReliabilityQosPolicyKind kind) @@ -1078,6 +1094,12 @@ class PubSubWriter return *this; } + PubSubWriter& setup_p2p_transports() + { + participant_qos_.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::P2P); + return *this; + } + PubSubWriter& disable_builtin_transport() { participant_qos_.transport().use_builtin_transports = false; @@ -1653,6 +1675,11 @@ class PubSubWriter return matched_; } + unsigned int get_participants_matched() const + { + return participant_matched_; + } + unsigned int missed_deadlines() const { return listener_.missed_deadlines(); @@ -2056,7 +2083,8 @@ class PubSubWriter std::string participant_profile_ = ""; std::string datawriter_profile_ = ""; - std::function onDiscovery_; + std::function onDiscovery_; //! A mutex for liveliness std::mutex liveliness_mutex_; @@ -2073,6 +2101,9 @@ class PubSubWriter unsigned int times_incompatible_qos_; //! Latest conflicting PolicyId eprosima::fastdds::dds::QosPolicyId_t last_incompatible_qos_; + //! Preferred domain ID + bool use_preferred_domain_id_; + uint32_t preferred_domain_id_; #if HAVE_SECURITY std::mutex mutexAuthentication_; diff --git a/test/blackbox/builtin_transports_profile.xml b/test/blackbox/builtin_transports_profile.xml index 6ee611b4b9f..767b5dfe814 100644 --- a/test/blackbox/builtin_transports_profile.xml +++ b/test/blackbox/builtin_transports_profile.xml @@ -111,5 +111,13 @@ + + 0 + + Participant.builtin_transports_p2p + P2P + + + diff --git a/test/blackbox/common/BlackboxTestsDiscovery.cpp b/test/blackbox/common/BlackboxTestsDiscovery.cpp index 1123d338a9d..16c1f724e29 100644 --- a/test/blackbox/common/BlackboxTestsDiscovery.cpp +++ b/test/blackbox/common/BlackboxTestsDiscovery.cpp @@ -891,7 +891,7 @@ TEST_P(Discovery, PubSubAsReliableHelloworldParticipantDiscovery) ASSERT_TRUE(writer.isInitialized()); int count = 0; - reader.setOnDiscoveryFunction([&writer, &count](const ParticipantBuiltinTopicData& info, + reader.set_on_discovery_function([&writer, &count](const ParticipantBuiltinTopicData& info, ParticipantDiscoveryStatus status) -> bool { if (info.guid == writer.participant_guid()) @@ -937,7 +937,7 @@ TEST_P(Discovery, PubSubAsReliableHelloworldUserData) ASSERT_TRUE(writer.isInitialized()); - reader.setOnDiscoveryFunction([&writer](const ParticipantBuiltinTopicData& info, + reader.set_on_discovery_function([&writer](const ParticipantBuiltinTopicData& info, ParticipantDiscoveryStatus /*status*/) -> bool { if (info.guid == writer.participant_guid()) diff --git a/test/blackbox/common/BlackboxTestsSecurity.cpp b/test/blackbox/common/BlackboxTestsSecurity.cpp index 4b582667a03..e97eacac854 100644 --- a/test/blackbox/common/BlackboxTestsSecurity.cpp +++ b/test/blackbox/common/BlackboxTestsSecurity.cpp @@ -2250,7 +2250,7 @@ TEST_P(Security, BuiltinAuthenticationAndCryptoPlugin_user_data) sub_property_policy.properties().emplace_back("rtps.endpoint.submessage_protection_kind", "ENCRYPT"); sub_property_policy.properties().emplace_back("rtps.endpoint.payload_protection_kind", "ENCRYPT"); - reader.setOnDiscoveryFunction([&writer](const ParticipantBuiltinTopicData& info, + reader.set_on_discovery_function([&writer](const ParticipantBuiltinTopicData& info, ParticipantDiscoveryStatus /*status*/) -> bool { if (info.guid == writer.participant_guid()) diff --git a/test/blackbox/common/BlackboxTestsTransportCustom.cpp b/test/blackbox/common/BlackboxTestsTransportCustom.cpp index 020f11ace1b..5c6b373a52d 100644 --- a/test/blackbox/common/BlackboxTestsTransportCustom.cpp +++ b/test/blackbox/common/BlackboxTestsTransportCustom.cpp @@ -612,6 +612,20 @@ TEST(ChainingTransportTests, builtin_transports_env_large_data) BuiltinTransportsTest::test_env("LARGE_DATA"); } +/** + * DS Auto transport shall always be used along with ROS_DISCOVERY_SERVER=AUTO. + * This is due to the working principle of the mode. If it is not specified, + * the background discovery server will not be launched and the test will never + * finish since both clients will keep waiting for it. + */ +TEST(ChainingTransportTests, builtin_transports_env_p2p) +{ +#ifndef _WIN32 // EASY_MODE not available on Windows yet + setenv("EASY_MODE", "127.0.0.1", 1); + BuiltinTransportsTest::test_env("P2P"); +#endif // _WIN32 +} + TEST(ChainingTransportTests, builtin_transports_env_large_data_with_max_msg_size) { BuiltinTransportsTest::test_env("LARGE_DATA?max_msg_size=70KB&sockets_size=70KB"); @@ -675,6 +689,22 @@ TEST(ChainingTransportTests, builtin_transports_xml_large_data) BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_largedata"); } +/** + * DS Auto transport shall always be used along with EASY_MODE=. + * This is due to the working principle of the mode. If it is not specified, + * the background discovery server will not be launched and the test will never + * finish since both clients will keep waiting for it. + * On the other hand, defining the environment variable somehow shadows the + * xml parsing, but it is assumed in this case. + */ +TEST(ChainingTransportTests, builtin_transports_xml_p2p) +{ +#ifndef _WIN32 // EASY_MODE not available on Windows yet + setenv("EASY_MODE", "127.0.0.1", 1); + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_p2p"); +#endif // _WIN32 +} + TEST(ChainingTransportTests, builtin_transports_xml_large_data_with_max_msg_size) { BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_largedata_max_msg_size"); diff --git a/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp b/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp new file mode 100644 index 00000000000..efa0ec475ca --- /dev/null +++ b/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp @@ -0,0 +1,364 @@ +// Copyright 2024 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include +#include +#include +#include +#include + +#include "BlackboxTests.hpp" +#include "PubSubReader.hpp" +#include "PubSubWriter.hpp" + + +void set_easy_discovery_mode_env( + const std::string& ip = "127.0.0.1") +{ + /* Set environment variable which will contain the ip of an external point of discovery*/ +#ifdef _WIN32 + _putenv_s("EASY_MODE", ip.c_str()); +#else + setenv("EASY_MODE", ip.c_str(), 1); +#endif // _WIN32 + +} + +void stop_background_servers() +{ + // Stop server(s) + int res = std::system("fastdds discovery stop"); + ASSERT_EQ(res, 0); +} + +/** + * Refers to FASTDDS-EASYMODE-TEST:01 from the test plan. + * + * Launching a participant client with the environment variable EASY_MODE + * correctly spawns and discovers a Discovery Server in the expected + * domain. + * + */ +TEST(DSEasyMode, easy_discovery_mode_env_correctly_launches) +{ +#ifndef _WIN32 // The feature is not supported on Windows yet + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader(TEST_TOPIC_NAME); + + // Setting ROS_DISCOVERY_SERVER to AUTO + // Configures as SUPER_CLIENT SHM and TCP + set_easy_discovery_mode_env(); + + std::atomic writer_background_ds_discovered(false); + std::atomic reader_background_ds_discovered(false); + + writer.set_on_discovery_function( + [&writer_background_ds_discovered]( + const eprosima::fastdds::rtps::ParticipantBuiltinTopicData& data, + eprosima::fastdds::rtps::ParticipantDiscoveryStatus) + { + if (data.participant_name == "DiscoveryServerAuto") + { + writer_background_ds_discovered.store(true); + } + return true; + }); + writer.init(); + + reader.set_on_discovery_function( + [&reader_background_ds_discovered](const eprosima::fastdds::rtps::ParticipantBuiltinTopicData& data, + eprosima::fastdds::rtps::ParticipantDiscoveryStatus) + { + if (data.participant_name == "DiscoveryServerAuto") + { + reader_background_ds_discovered.store(true); + } + return true; + }); + reader.init(); + + ASSERT_TRUE(writer.isInitialized()); + ASSERT_TRUE(reader.isInitialized()); + + // Wait for endpoint discovery first + writer.wait_discovery(); + reader.wait_discovery(); + + // Two participants are expected to have been discovered: + // Backgroud DS and the other reader/writer + ASSERT_GE(writer.get_participants_matched(), 2u); + ASSERT_GE(reader.get_participants_matched(), 2u); + ASSERT_TRUE(writer_background_ds_discovered.load()); + ASSERT_TRUE(reader_background_ds_discovered.load()); + + auto data = default_helloworld_data_generator(); + + reader.startReception(data); + writer.send(data); + ASSERT_TRUE(data.empty()); + + reader.block_for_all(); + + // Stop server + stop_background_servers(); +#endif // _WIN32 +} + +/** + * Refers to FASTDDS-EASYMODE-TEST:02 from the test plan. + * + * TCP and SHM are the transports used in EASY_MODE. + */ +TEST(DSEasyMode, easy_discovery_mode_env_correct_transports_are_used) +{ +#ifndef _WIN32 // The feature is not supported on Windows yet + PubSubWriter writer_udp(TEST_TOPIC_NAME), writer_auto(TEST_TOPIC_NAME); + PubSubReader reader_auto(TEST_TOPIC_NAME); + + auto udpv4_transport = std::make_shared(); + + writer_udp.disable_builtin_transport() + .add_user_transport_to_pparams(udpv4_transport) + .init(); + + ASSERT_TRUE(writer_udp.isInitialized()); + + // Setting ROS_DISCOVERY_SERVER to AUTO + // Configures as SUPER_CLIENT SHM and TCP + set_easy_discovery_mode_env(); + + std::atomic locators_match_p2p_transport(true); + + reader_auto.set_on_discovery_function( + [&locators_match_p2p_transport](const eprosima::fastdds::rtps::ParticipantBuiltinTopicData& data, + eprosima::fastdds::rtps::ParticipantDiscoveryStatus) + { + for (auto locator : data.metatraffic_locators.unicast) + { + locators_match_p2p_transport.store( locators_match_p2p_transport && + (locator.kind == LOCATOR_KIND_UDPv4 || locator.kind == LOCATOR_KIND_SHM)); + } + + if (!data.metatraffic_locators.multicast.empty()) + { + locators_match_p2p_transport.store(false); + } + + return true; + }); + reader_auto.init(); + + ASSERT_TRUE(reader_auto.isInitialized()); + + // Discovery shall not happen + writer_udp.wait_discovery(std::chrono::seconds(1)); + reader_auto.wait_discovery(std::chrono::seconds(1)); + + ASSERT_FALSE(writer_udp.is_matched()); + ASSERT_FALSE(reader_auto.is_matched()); + + // Now launch another DS AUTO participant writer + writer_auto.init(); + + writer_auto.wait_discovery(); + reader_auto.wait_discovery(); + + ASSERT_TRUE(locators_match_p2p_transport.load()); + + // Stop server + stop_background_servers(); +#endif // _WIN32 +} + +/** + * Refers to FASTDDS-EASYMODE-TEST:03 from the test plan. + * + * Client participants are aware of the discovery + * information of the rest of participants in the same domain. + */ +TEST(DSEasyMode, easy_discovery_mode_env_discovery_info) +{ +#ifndef _WIN32 // The feature is not supported on Windows yet + unsigned int num_writers = 3; + std::vector>> writers; + writers.reserve(num_writers); + PubSubReader reader_auto(TEST_TOPIC_NAME + "_auto"); + + for (std::size_t i = 0; i < num_writers; ++i) + { + writers.emplace_back(std::make_shared>(TEST_TOPIC_NAME + std::to_string(i))); + + eprosima::fastdds::dds::WireProtocolConfigQos wire_protocol_qos; + + wire_protocol_qos.builtin.discovery_config.discoveryProtocol = + eprosima::fastdds::rtps::DiscoveryProtocol::CLIENT; + + eprosima::fastdds::rtps::Locator_t locator; + locator.kind = LOCATOR_KIND_UDPv4; + + eprosima::fastdds::rtps::PortParameters port_params; + + auto domain_port = port_params.get_discovery_server_port((uint32_t)GET_PID() % 230); + + locator.port = domain_port; + IPLocator::setIPv4(locator, "127.0.0.1"); + + // Point to the well known DS port in the corresponding domain + wire_protocol_qos.builtin.discovery_config.m_DiscoveryServers.push_back(locator); + + writers.back()->set_wire_protocol_qos(wire_protocol_qos) + .setup_p2p_transports() + .init(); + + ASSERT_TRUE(writers.back()->isInitialized()); + } + + // Setting ROS_DISCOVERY_SERVER to AUTO + // Configures as SUPER_CLIENT SHM and TCP + set_easy_discovery_mode_env(); + + reader_auto.init(); + ASSERT_TRUE(reader_auto.isInitialized()); + + // Discovery DS in Domain 0 + num_writers + reader_auto.wait_participant_discovery(num_writers + 1); + + // This participant shall discover all the other participants + // Despite not sharing a common topic with them (SUPER_CLIENT) + ASSERT_EQ(reader_auto.get_participants_matched(), num_writers + 1u); + + for (auto& writer : writers) + { + // Writers shall discover SERVER participant only + ASSERT_LE(writer->get_participants_matched(), 1u); + } + + // Stop server + stop_background_servers(); +#endif // _WIN32 +} + +/** + * Refers to FASTDDS-EASYMODE-TEST:04 from the test plan. + * + * Launching participant clients in different domains with + * ROS_DISCOVERY_SERVER set to AUTO correctly + * launch and discover the Discovery Server in its domain. + */ +TEST(DSEasyMode, easy_discovery_mode_env_multiple_clients_multiple_domains) +{ +#ifndef _WIN32 // The feature is not supported on Windows yet + unsigned int num_writer_reader_pairs = 5; + + std::vector>> writers; + std::vector>> readers; + + // Setting ROS_DISCOVERY_SERVER to AUTO + // Configures as SUPER_CLIENT SHM and TCP + set_easy_discovery_mode_env(); + + for (std::size_t i = 10; i < 10 + num_writer_reader_pairs; ++i) + { + writers.emplace_back(std::make_shared>(TEST_TOPIC_NAME + "_domain_" + + std::to_string(i))); + readers.emplace_back(std::make_shared>(TEST_TOPIC_NAME + "_domain_" + + std::to_string(i))); + + writers.back()->set_domain_id((uint32_t)i) + .init(); + readers.back()->set_domain_id((uint32_t)i) + .init(); + } + + for (std::size_t i = 0; i < num_writer_reader_pairs; ++i) + { + writers[i]->wait_discovery(); + readers[i]->wait_discovery(); + + ASSERT_EQ(writers[i]->get_matched(), 1u); + ASSERT_EQ(readers[i]->get_matched(), 1u); + + auto data = default_helloworld_data_generator(); + + readers[i]->startReception(data); + writers[i]->send(data); + ASSERT_TRUE(data.empty()); + + readers[i]->block_for_all(); + } + + // Stop servers + stop_background_servers(); +#endif // _WIN32 +} + +/** + * Launching a second participant in the same domain with different + * EASY_MODE ip value shall log an error. + */ +TEST(DSEasyMode, easy_discovery_mode_env_inconsistent_ip) +{ +#ifndef _WIN32 // The feature is not supported on Windows yet + + using Log = eprosima::fastdds::dds::Log; + using LogConsumer = eprosima::fastdds::dds::LogConsumer; + + // A LogConsumer accounting for any log errors + struct TestConsumer : public LogConsumer + { + TestConsumer( + std::atomic_size_t& n_logs_ref) + : n_logs_(n_logs_ref) + { + } + + void Consume( + const Log::Entry&) override + { + ++n_logs_; + } + + private: + + std::atomic_size_t& n_logs_; + }; + + // Counter for log entries + std::atomicn_logs{}; + + // Prepare Log module to check that at least one DOMAIN error is produced + Log::SetCategoryFilter(std::regex("DOMAIN")); + Log::SetVerbosity(Log::Kind::Error); + Log::RegisterConsumer(std::unique_ptr(new TestConsumer(n_logs))); + + // Set EASY_MODE to localhost + set_easy_discovery_mode_env(); + PubSubWriter writer(TEST_TOPIC_NAME); + + writer.init(); + ASSERT_TRUE(writer.isInitialized()); + + // Set EASY_MODE to another address in the same domain + set_easy_discovery_mode_env("192.168.1.100"); + PubSubWriter reader(TEST_TOPIC_NAME); + + reader.init(); + ASSERT_TRUE(n_logs.load() > 0); + + // Stop servers + stop_background_servers(); +#endif // _WIN32 +} diff --git a/test/blackbox/common/DDSBlackboxTestsTransportSHMUDP.cpp b/test/blackbox/common/DDSBlackboxTestsTransportSHMUDP.cpp index 1f004f0f673..ba009a8a280 100644 --- a/test/blackbox/common/DDSBlackboxTestsTransportSHMUDP.cpp +++ b/test/blackbox/common/DDSBlackboxTestsTransportSHMUDP.cpp @@ -214,7 +214,7 @@ static void shm_metatraffic_test( check_shm_locators(info, unicast, multicast); return true; }; - reader.setOnDiscoveryFunction(discovery_checker); + reader.set_on_discovery_function(discovery_checker); reader.max_multicast_locators_number(2); reader.init(); ASSERT_TRUE(reader.isInitialized()); diff --git a/test/system/tools/fds/CliDiscoveryManagerTests.cpp b/test/system/tools/fds/CliDiscoveryManagerTests.cpp index 13533a8734e..c922df98179 100644 --- a/test/system/tools/fds/CliDiscoveryManagerTests.cpp +++ b/test/system/tools/fds/CliDiscoveryManagerTests.cpp @@ -226,9 +226,9 @@ class CliDiscoveryManagerTest : public ::testing::Test { "udp_1_ip_1_port", { - {"-l", "127.0.0.1", "-p", "8500"}, + {"-l", "127.0.0.1", "-p", "7402"}, {"127.0.0.1"}, - {8500}, + {7402}, {}, {}, } @@ -535,12 +535,12 @@ TEST_F(CliDiscoveryManagerTest, SetServerQos) EXPECT_EQ(qos.wire_protocol().builtin.metatrafficUnicastLocatorList.size(), 1); for (const Locator_t& locator : qos.wire_protocol().builtin.metatrafficUnicastLocatorList) { - compareLocator(locator, "0.0.0.0", 7402, true, false); + compareLocator(locator, "0.0.0.0", 7402, false, false); } EXPECT_FALSE(qos.transport().use_builtin_transports); EXPECT_EQ(qos.wire_protocol().builtin.discovery_config.discoveryProtocol, DiscoveryProtocol::SERVER); ASSERT_EQ(qos.transport().user_transports.size(), 1); - EXPECT_TRUE(nullptr != dynamic_cast(qos.transport().user_transports[0].get())); + EXPECT_TRUE(nullptr != dynamic_cast(qos.transport().user_transports[0].get())); } TEST_F(CliDiscoveryManagerTest, GetCliPortsAndIps) @@ -728,7 +728,7 @@ TEST_F(CliDiscoveryManagerTest, GetListeningPorts) } ASSERT_FALSE(port_7402_7652); - addServers(test_case_map.at("tcp_2_ip_2_port")); + addServers(test_case_map.at("udp_2_ip_2_port")); manager.configure_transports(); DomainParticipant* server = DomainParticipantFactory::get_instance()->create_participant(0, manager.getServerQos()); diff --git a/test/unittest/xmlparser/XMLElementParserTests.cpp b/test/unittest/xmlparser/XMLElementParserTests.cpp index 5f5da4c41dc..32cd651cf44 100644 --- a/test/unittest/xmlparser/XMLElementParserTests.cpp +++ b/test/unittest/xmlparser/XMLElementParserTests.cpp @@ -930,6 +930,7 @@ TEST_F(XMLParserTests, getXMLbuiltinTransports) bt_list.push_back("UDPv6"); bt_list.push_back("LARGE_DATA"); bt_list.push_back("LARGE_DATAv6"); + bt_list.push_back("P2P"); for (auto test_transport : bt_list) { diff --git a/tools/fds/CliDiscoveryManager.cpp b/tools/fds/CliDiscoveryManager.cpp index 6266e702f60..eebf03eca09 100644 --- a/tools/fds/CliDiscoveryManager.cpp +++ b/tools/fds/CliDiscoveryManager.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -247,10 +248,10 @@ std::vector CliDiscoveryManager::get_listening_ports() std::vector ports; std::string command; #ifdef __APPLE__ - command = "netstat -an | grep LISTEN"; + command = "netstat -an | grep udp4"; std::regex port_regex(R"(\*.([\d+]+))"); #else - command = "ss -ltn"; + command = "ss -lun"; std::regex port_regex(R"(0\.0\.0\.0:(\d+))"); #endif // ifdef __APPLE__ std::string result = exec_command(command); @@ -310,7 +311,7 @@ pid_t CliDiscoveryManager::get_pid_of_server( { std::string command = "lsof -i :"; command += std::to_string(port); - command += " | grep LISTEN | awk '{print $2}'"; + command += " | grep UDP | awk '{print $2}'"; std::string result = exec_command(command); if (result.empty()) { @@ -372,7 +373,7 @@ void CliDiscoveryManager::start_server_auto_mode( load_environment_server_info(read_servers_from_file(file_name.str()), serverList); for (rtps::Locator_t& locator : serverList) { - locator.kind = LOCATOR_KIND_TCPv4; + locator.kind = LOCATOR_KIND_UDPv4; } pServer->get_qos(serverQos); serverQos.wire_protocol().builtin.discovery_config.m_DiscoveryServers = serverList; @@ -388,7 +389,7 @@ void CliDiscoveryManager::start_server_auto_mode( load_environment_server_info(read_servers_from_file(file_name.str()), serverList); for (rtps::Locator_t& locator : serverList) { - locator.kind = LOCATOR_KIND_TCPv4; + locator.kind = LOCATOR_KIND_UDPv4; } serverQos.wire_protocol().builtin.discovery_config.m_DiscoveryServers = serverList; pServer = DomainParticipantFactory::get_instance()->create_participant(0, serverQos); @@ -409,16 +410,14 @@ void CliDiscoveryManager::start_server_auto_mode( void CliDiscoveryManager::set_server_qos( const uint16_t port) { - rtps::Locator_t locator; - locator.kind = LOCATOR_KIND_TCPv4; - rtps::IPLocator::setPhysicalPort(locator, port); - rtps::IPLocator::setLogicalPort(locator, port); - rtps::IPLocator::setIPv4(locator, "0.0.0.0"); - serverQos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator); - auto tcp_descriptor = std::make_shared(); - tcp_descriptor->add_listener_port(port); - tcp_descriptor->non_blocking_send = true; - serverQos.transport().user_transports.push_back(tcp_descriptor); + rtps::Locator_t udp_locator; + udp_locator.kind = LOCATOR_KIND_UDPv4; + udp_locator.port = port; + // Initialize to the wan interface + IPLocator::setIPv4(udp_locator, "0.0.0.0"); + serverQos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(udp_locator); + auto udp_descriptor = std::make_shared(); + serverQos.transport().user_transports.push_back(udp_descriptor); serverQos.transport().use_builtin_transports = false; serverQos.wire_protocol().builtin.discovery_config.discoveryProtocol = rtps::DiscoveryProtocol::SERVER; serverQos.name("DiscoveryServerAuto"); @@ -958,7 +957,7 @@ int CliDiscoveryManager::fastdds_discovery_auto_start( load_environment_server_info(servers, serverList); for (rtps::Locator_t& locator : serverList) { - locator.kind = LOCATOR_KIND_TCPv4; + locator.kind = LOCATOR_KIND_UDPv4; } serverQos.wire_protocol().builtin.discovery_config.m_DiscoveryServers = serverList; start_server_auto_mode(port, id);