From a940b0a9eef35fbfa05ca9e07350896694c7f15e Mon Sep 17 00:00:00 2001 From: Mario Dominguez Date: Thu, 5 Dec 2024 08:45:39 +0100 Subject: [PATCH] Refs #22427: Feature Impl Signed-off-by: Mario Dominguez --- src/cpp/rtps/RTPSDomain.cpp | 138 ++++++++++++------ src/cpp/rtps/attributes/ServerAttributes.cpp | 6 +- src/cpp/rtps/attributes/ServerAttributes.hpp | 16 +- .../discovery/participant/PDPServer.cpp | 16 +- 4 files changed, 113 insertions(+), 63 deletions(-) diff --git a/src/cpp/rtps/RTPSDomain.cpp b/src/cpp/rtps/RTPSDomain.cpp index 843dd0d01fd..988eb1eb7c5 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,104 @@ 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; - } + const std::string& ros_discovery_server_env_value = ros_discovery_server_env(); - // 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)) + if (ros_discovery_server_env_value != "AUTO") { - // 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)); + } - client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT; - // RemoteServerAttributes already fill in above + 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 the client must become a super client - if (ros_super_client_env()) + 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()) + { + client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT; + } + } + else { + // SUPER_CLIENT client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT; + + // DS_AUTO transport. Similar to LARGE_DATA, but without UDPv4 + client_att.useBuiltinTransports = false; + client_att.setup_transports(BuiltinTransports::DS_AUTO); + + // Ignore initialpeers + client_att.builtin.initialPeersList = LocatorList(); + + // Add remote DS based on port + eprosima::fastdds::rtps::Locator_t locator; + locator.kind = LOCATOR_KIND_TCPv4; + + eprosima::fastdds::rtps::PortParameters port_params; + + auto ds_auto_port = port_params.getDiscoveryServerPort(domain_id); + + IPLocator::setPhysicalPort(locator, ds_auto_port); + IPLocator::setLogicalPort(locator, ds_auto_port); + IPLocator::setIPv4(locator, 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); + + 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)) + .build_and_call(); + if (res != 0) + { + 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/ServerAttributes.cpp b/src/cpp/rtps/attributes/ServerAttributes.cpp index 88386358eb5..e83226dad43 100644 --- a/src/cpp/rtps/attributes/ServerAttributes.cpp +++ b/src/cpp/rtps/attributes/ServerAttributes.cpp @@ -64,9 +64,9 @@ bool ros_super_client_env() const std::string& ros_discovery_server_env() { - static std::string servers; - SystemInfo::get_env(DEFAULT_ROS2_MASTER_URI, servers); - return servers; + static std::string value; + SystemInfo::get_env(DEFAULT_ROS2_MASTER_URI, value); + return value; } bool load_environment_server_info( diff --git a/src/cpp/rtps/attributes/ServerAttributes.hpp b/src/cpp/rtps/attributes/ServerAttributes.hpp index bb4b20c4a8a..6c7a52e1054 100644 --- a/src/cpp/rtps/attributes/ServerAttributes.hpp +++ b/src/cpp/rtps/attributes/ServerAttributes.hpp @@ -136,13 +136,15 @@ 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"; diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp index 1cf9622ce34..2e52938ba12 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp @@ -67,17 +67,19 @@ PDPServer::PDPServer( // Add remote servers from environment variable LocatorList_t env_servers; { - std::lock_guard lock(*getMutex()); - - if (load_environment_server_info(env_servers)) + if (ros_discovery_server_env() != "AUTO") { - for (auto server : env_servers) + std::lock_guard lock(*getMutex()); + if (load_environment_server_info(env_servers)) { + for (auto server : env_servers) { - std::unique_lock disc_lock(mp_builtin->getDiscoveryMutex()); - mp_builtin->m_DiscoveryServers.push_back(server); + { + std::unique_lock disc_lock(mp_builtin->getDiscoveryMutex()); + mp_builtin->m_DiscoveryServers.push_back(server); + } + m_discovery.discovery_config.m_DiscoveryServers.push_back(server); } - m_discovery.discovery_config.m_DiscoveryServers.push_back(server); } } }