diff --git a/src/cpp/rtps/RTPSDomain.cpp b/src/cpp/rtps/RTPSDomain.cpp
index 36dd3d8ecb3..4f2deeea066 100644
--- a/src/cpp/rtps/RTPSDomain.cpp
+++ b/src/cpp/rtps/RTPSDomain.cpp
@@ -58,6 +58,23 @@ namespace eprosima {
namespace fastdds {
namespace rtps {
+const char* EASY_MODE_SERVICE_PROFILE =
+ "\n"
+ "\n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " 1\n"
+ " 0\n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ "\n";
+
template
bool has_user_transport(
const RTPSParticipantAttributes& att)
@@ -616,6 +633,22 @@ RTPSParticipant* RTPSDomainImpl::clientServerEnvironmentCreationOverride(
// Point to the well known DS port in the corresponding domain
client_att.builtin.discovery_config.m_DiscoveryServers.push_back(locator_udp);
+ // Load the 'service' profile for ROS2_EASY_MODE services if there is no existing profile yet
+ xmlparser::PublisherAttributes attr;
+ auto ret_if = xmlparser::XMLProfileManager::fillPublisherAttributes("service", attr, false);
+ if (ret_if == xmlparser::XMLP_ret::XML_ERROR)
+ {
+ // An XML_ERROR is returned if there is no existing profile for the given name
+ xmlparser::XMLProfileManager::loadXMLString(EASY_MODE_SERVICE_PROFILE, strlen(EASY_MODE_SERVICE_PROFILE));
+ EPROSIMA_LOG_INFO(RTPS_DOMAIN, "Loaded service profile for ROS2_EASY_MODE servers");
+ }
+ else
+ {
+ // There is already a profile with the given name. Do not overwrite it
+ EPROSIMA_LOG_WARNING(RTPS_DOMAIN, "An XML profile for 'service' was found. When using ROS2_EASY_MODE, please ensure"
+ " the max_blocking_time is configured with a value higher than the default.");
+ }
+
SystemCommandBuilder sys_command;
int res = sys_command.executable(FAST_DDS_DEFAULT_CLI_SCRIPT_NAME)
.verb(FAST_DDS_DEFAULT_CLI_DISCOVERY_VERB)
diff --git a/test/blackbox/common/BlackboxTestsTransportCustom.cpp b/test/blackbox/common/BlackboxTestsTransportCustom.cpp
index 3615ba7b3ac..3e1ca520e01 100644
--- a/test/blackbox/common/BlackboxTestsTransportCustom.cpp
+++ b/test/blackbox/common/BlackboxTestsTransportCustom.cpp
@@ -613,7 +613,7 @@ TEST(ChainingTransportTests, builtin_transports_env_large_data)
}
/**
- * DS Auto transport shall always be used along with ROS_DISCOVERY_SERVER=AUTO.
+ * P2P transport shall always be used along with ROS2_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.
diff --git a/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp b/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp
index 7dd41224ac4..99425024528 100644
--- a/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp
+++ b/test/blackbox/common/DDSBlackboxTestsDSEasyMode.cpp
@@ -58,7 +58,7 @@ TEST(DSEasyMode, easy_discovery_mode_env_correctly_launches)
PubSubWriter writer(TEST_TOPIC_NAME);
PubSubReader reader(TEST_TOPIC_NAME);
- // Setting ROS_DISCOVERY_SERVER to AUTO
+ // Setting ROS2_EASY_MODE
// Configures as SUPER_CLIENT SHM and TCP
set_easy_discovery_mode_env();
@@ -136,8 +136,7 @@ TEST(DSEasyMode, easy_discovery_mode_env_correct_transports_are_used)
ASSERT_TRUE(writer_udp.isInitialized());
- // Setting ROS_DISCOVERY_SERVER to AUTO
- // Configures as SUPER_CLIENT SHM and TCP
+ // Setting ROS2_EASY_MODE configures as SUPER_CLIENT SHM and TCP
set_easy_discovery_mode_env();
std::atomic locators_match_p2p_transport(true);
@@ -226,7 +225,7 @@ TEST(DSEasyMode, easy_discovery_mode_env_discovery_info)
ASSERT_TRUE(writers.back()->isInitialized());
}
- // Setting ROS_DISCOVERY_SERVER to AUTO
+ // Setting ROS2_EASY_MODE
// Configures as SUPER_CLIENT SHM and TCP
set_easy_discovery_mode_env();
@@ -266,7 +265,7 @@ TEST(DSEasyMode, easy_discovery_mode_env_multiple_clients_multiple_domains)
std::vector>> writers;
std::vector>> readers;
- // Setting ROS_DISCOVERY_SERVER to AUTO
+ // Setting ROS2_EASY_MODE
// Configures as SUPER_CLIENT SHM and TCP
set_easy_discovery_mode_env();
diff --git a/test/unittest/dds/participant/CMakeLists.txt b/test/unittest/dds/participant/CMakeLists.txt
index 40952009401..af06d6754df 100644
--- a/test/unittest/dds/participant/CMakeLists.txt
+++ b/test/unittest/dds/participant/CMakeLists.txt
@@ -16,6 +16,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../profiles/test_xml_profile.xml
${CMAKE_CURRENT_BINARY_DIR}/test_xml_profile.xml
COPYONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../profiles/test_xml_service_easy_mode.xml
+ ${CMAKE_CURRENT_BINARY_DIR}/test_xml_service_easy_mode.xml
+ COPYONLY)
+
set(PARTICIPANTTESTS_SOURCE
ParticipantTests.cpp
)
diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp
index bf1347d2f1f..f73f03fcc21 100644
--- a/test/unittest/dds/participant/ParticipantTests.cpp
+++ b/test/unittest/dds/participant/ParticipantTests.cpp
@@ -81,6 +81,14 @@
#define GET_PID getpid
#endif // if defined(_WIN32)
+void stop_background_servers()
+{
+#ifndef _WIN32 // The feature is not supported on Windows yet
+ // Stop server(s)
+ int res = std::system("fastdds discovery stop");
+ ASSERT_EQ(res, 0);
+#endif // _WIN32
+}
namespace eprosima {
namespace fastdds {
@@ -1077,6 +1085,17 @@ void set_environment_variable(
#endif // _WIN32
}
+void set_easy_mode_environment_variable(
+ const std::string ip = "127.0.0.1"
+ )
+{
+#ifdef _WIN32
+ ASSERT_EQ(0, _putenv_s(rtps::EASY_MODE_URI, ip.c_str()));
+#else
+ ASSERT_EQ(0, setenv(rtps::EASY_MODE_URI, ip.c_str(), 1));
+#endif // _WIN32
+}
+
void set_environment_file(
const std::string& filename)
{
@@ -1483,6 +1502,70 @@ TEST(ParticipantTests, ServerParticipantRemoteServerListConfiguration)
EXPECT_EQ(RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant));
}
+TEST(ParticipantTests, EasyModeParticipantLoadsServiceDataWriterQos)
+{
+ // Use get_datawriter_qos_from_profile to check if the profile is correctly loaded.
+ {
+ // Default participant
+ DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(
+ (uint32_t)GET_PID() % 230, PARTICIPANT_QOS_DEFAULT);
+ ASSERT_NE(nullptr, participant);
+ Publisher* default_publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
+ ASSERT_NE(default_publisher, nullptr);
+ DataWriterQos dw_qos;
+ EXPECT_EQ(default_publisher->get_datawriter_qos_from_profile("service", dw_qos), RETCODE_BAD_PARAMETER);
+
+ EXPECT_EQ(RETCODE_OK, participant->delete_publisher(default_publisher));
+ EXPECT_EQ(RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant));
+ }
+
+ {
+ // Easy mode participant
+ set_easy_mode_environment_variable();
+ DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(
+ (uint32_t)GET_PID() % 230, PARTICIPANT_QOS_DEFAULT);
+ ASSERT_NE(nullptr, participant);
+ Publisher* easy_mode_publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
+ ASSERT_NE(easy_mode_publisher, nullptr);
+ DataWriterQos dw_qos;
+ EXPECT_EQ(easy_mode_publisher->get_datawriter_qos_from_profile("service", dw_qos), RETCODE_OK);
+ EXPECT_EQ(dw_qos.reliability().max_blocking_time.seconds, 1); // Easy Mode value
+ EXPECT_EQ(dw_qos.reliability().max_blocking_time.nanosec, 0u); // Easy Mode value
+ EXPECT_EQ(dw_qos.durability().kind, TRANSIENT_LOCAL_DURABILITY_QOS); // Default value
+
+ EXPECT_EQ(RETCODE_OK, participant->delete_publisher(easy_mode_publisher));
+ EXPECT_EQ(RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant));
+ stop_background_servers();
+ }
+}
+
+TEST(ParticipantTests, EasyModeParticipantDoNotOverwriteCustomDataWriterQos)
+{
+ {
+ // Easy mode participant with existing profile
+ // Set XML profile as environment variable: "export FASTDDS_DEFAULT_PROFILES_FILE=test_xml_service_easy_mode.xml"
+ eprosima::testing::set_environment_variable("FASTDDS_DEFAULT_PROFILES_FILE", "test_xml_service_easy_mode.xml");
+ set_easy_mode_environment_variable();
+ DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(
+ (uint32_t)GET_PID() % 230, PARTICIPANT_QOS_DEFAULT);
+ ASSERT_NE(nullptr, participant);
+ Publisher* easy_mode_publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
+ ASSERT_NE(easy_mode_publisher, nullptr);
+ PublisherQos profile_qos;
+ EXPECT_EQ(easy_mode_publisher->get_participant()->get_publisher_qos_from_profile("service", profile_qos),
+ RETCODE_OK);
+ DataWriterQos dw_qos;
+ easy_mode_publisher->get_datawriter_qos_from_profile("service", dw_qos);
+ EXPECT_EQ(dw_qos.reliability().max_blocking_time.seconds, 5); // XML value
+ EXPECT_EQ(dw_qos.reliability().max_blocking_time.nanosec, 0u); // XML value
+ EXPECT_EQ(dw_qos.durability().kind, VOLATILE_DURABILITY_QOS); // XML value
+
+ EXPECT_EQ(RETCODE_OK, participant->delete_publisher(easy_mode_publisher));
+ EXPECT_EQ(RETCODE_OK, DomainParticipantFactory::get_instance()->delete_participant(participant));
+ stop_background_servers();
+ }
+}
+
/**
* Dynamic modification of servers. Replacing previous servers with new ones.
*/
diff --git a/test/unittest/dds/profiles/test_xml_service_easy_mode.xml b/test/unittest/dds/profiles/test_xml_service_easy_mode.xml
new file mode 100644
index 00000000000..9b9da3bfbfa
--- /dev/null
+++ b/test/unittest/dds/profiles/test_xml_service_easy_mode.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+ 5
+ 0
+
+
+
+ VOLATILE
+
+
+
+
+