Skip to content

Commit

Permalink
Fast DDS EASY_MODE - Feature - XMLRPC Server (#5551)
Browse files Browse the repository at this point in the history
* Refs #22352: Add preferred_domain_id to PubSubAPI

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22352: Refactor set_on_discovery_function in PubSubAPI

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22352: Add get_participants_matched() in PubSubAPI

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22352: Update BB tests with new APIs

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22352: Add Auto Discovery Mode BB tests

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: New DS_AUTO BuiltinTransport option

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: SystemCommandBuilder class

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: Feature Impl

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: Fix tests compilation in all platforms

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: Apply Carlo's review

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: stop background servers with stop instead of shutdown in BB tests

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22427: Update banner

Signed-off-by: cferreiragonz <[email protected]>

* Refs #22627: Rename DS_AUTO transport to P2P

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Refactor BB tests with EASY_MODE

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Refactor feature impl with EASY_MODE

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Distinguish Log error if the EASY_MODE IP conflicts with a previous one

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Review NIT

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Feature use UDP for metatraffic

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: UDP metatraffic Cli

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Feature with UDP BB tests

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Remove unsued line

Signed-off-by: Mario Dominguez <[email protected]>

* Refs #22627: Feature with UDP CLI tests

Signed-off-by: cferreiragonz <[email protected]>

* Refs #22627: Avoid macro collision in MacOS

Signed-off-by: Mario Domínguez López <[email protected]>

---------

Signed-off-by: Mario Dominguez <[email protected]>
Signed-off-by: cferreiragonz <[email protected]>
Signed-off-by: Mario Domínguez López <[email protected]>
Co-authored-by: Mario Dominguez <[email protected]>
  • Loading branch information
cferreiragonz and Mario-DL authored Jan 22, 2025
1 parent 7a14e0f commit d396e9a
Show file tree
Hide file tree
Showing 24 changed files with 774 additions and 92 deletions.
10 changes: 7 additions & 3 deletions include/fastdds/rtps/attributes/BuiltinTransports.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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=<ip>
};

inline std::ostream& operator <<(
Expand Down Expand Up @@ -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;
Expand Down
Binary file modified resources/images/fastdds_github_banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/xsd/fastdds_profiles.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,7 @@
<xs:enumeration value="UDPv6" />
<xs:enumeration value="LARGE_DATA" />
<xs:enumeration value="LARGE_DATAv6" />
<xs:enumeration value="P2P" />
</xs:restriction>
</xs:simpleType>

Expand Down
162 changes: 116 additions & 46 deletions src/cpp/rtps/RTPSDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <rtps/transport/UDPv6Transport.h>
#include <rtps/writer/BaseWriter.hpp>
#include <utils/Host.hpp>
#include <utils/SystemCommandBuilder.hpp>
#include <utils/SystemInfo.hpp>
#include <xmlparser/XMLProfileManager.h>

Expand Down Expand Up @@ -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<LOCATOR_KIND_UDPv6>() &&
!has_user_transport<fastdds::rtps::UDPv6TransportDescriptor>(client_att))
if (easy_mode_env_value.empty())
{
// Extend builtin transports with the UDPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::UDPv6TransportDescriptor>();
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv4>() &&
!has_user_transport<fastdds::rtps::TCPv4TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv4 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv4TransportDescriptor>();
// 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<LOCATOR_KIND_TCPv6>() &&
!has_user_transport<fastdds::rtps::TCPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv6TransportDescriptor>();
// 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<LOCATOR_KIND_UDPv6>() &&
!has_user_transport<fastdds::rtps::UDPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the UDPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::UDPv6TransportDescriptor>();
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv4>() &&
!has_user_transport<fastdds::rtps::TCPv4TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv4 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv4TransportDescriptor>();
// 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<LOCATOR_KIND_TCPv6>() &&
!has_user_transport<fastdds::rtps::TCPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv6TransportDescriptor>();
// 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);
Expand Down
41 changes: 40 additions & 1 deletion src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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(
Expand Down Expand Up @@ -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.");
Expand Down
7 changes: 7 additions & 0 deletions src/cpp/rtps/attributes/ServerAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
30 changes: 23 additions & 7 deletions src/cpp/rtps/attributes/ServerAttributes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,26 @@ std::basic_ostream<charT>& 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:
Expand Down Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ PDPServer::PDPServer(
LocatorList_t env_servers;
{
std::lock_guard<std::recursive_mutex> lock(*getMutex());

if (load_environment_server_info(env_servers))
{
for (auto server : env_servers)
Expand Down
6 changes: 4 additions & 2 deletions src/cpp/rtps/participant/RTPSParticipantImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand Down
Loading

0 comments on commit d396e9a

Please sign in to comment.