diff --git a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp index 0f040b583d7..7457d8c21b7 100644 --- a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp +++ b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -321,6 +322,14 @@ class DomainParticipantQos return flow_controllers_; } + /** + * Provides a way of easily configuring transport related configuration on certain pre-defined scenarios. + * + * @param transports Defines the transport configuration scenario to setup. + */ + RTPS_DllAPI void setup_transports( + rtps::BuiltinTransports transports); + private: //!UserData Qos, implemented in the library. diff --git a/include/fastdds/rtps/attributes/BuiltinTransports.hpp b/include/fastdds/rtps/attributes/BuiltinTransports.hpp new file mode 100644 index 00000000000..6f297d77567 --- /dev/null +++ b/include/fastdds/rtps/attributes/BuiltinTransports.hpp @@ -0,0 +1,85 @@ +// Copyright 2023 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. + +/** + * @file BuiltinTransports.hpp + */ + +#ifndef _FASTDDS_RTPS_ATTRIBUTES__BUILTINTRANSPORTS_HPP_ +#define _FASTDDS_RTPS_ATTRIBUTES__BUILTINTRANSPORTS_HPP_ + +#include +#include + +namespace eprosima { +namespace fastdds { +namespace rtps { + +/** + * Defines the kind of transports automatically instantiated upon the creation of a participant + */ +enum class BuiltinTransports : uint16_t +{ + 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 +}; + +inline std::ostream& operator <<( + std::ostream& output, + BuiltinTransports transports) +{ + switch (transports) + { + case BuiltinTransports::NONE: + output << "NONE"; + break; + case BuiltinTransports::DEFAULT: + output << "DEFAULT"; + break; + case BuiltinTransports::DEFAULTv6: + output << "DEFAULTv6"; + break; + case BuiltinTransports::SHM: + output << "SHM"; + break; + case BuiltinTransports::UDPv4: + output << "UDPv4"; + break; + case BuiltinTransports::UDPv6: + output << "UDPv6"; + break; + case BuiltinTransports::LARGE_DATA: + output << "LARGE_DATA"; + break; + case BuiltinTransports::LARGE_DATAv6: + output << "LARGE_DATAv6"; + break; + default: + output << "UNKNOWN"; + break; + } + return output; +} + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima + +#endif // _FASTDDS_RTPS_ATTRIBUTES__BUILTINTRANSPORTS_HPP_ diff --git a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h index f6d4ec94e75..7251a8f74b1 100644 --- a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h +++ b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -20,6 +20,7 @@ #define _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ #include +#include #include #include #include @@ -35,14 +36,12 @@ #include namespace eprosima { - namespace fastdds { - namespace rtps { /** * Struct to define participant types to set participant type parameter property - *@ingroup DISCOVERY_MODULE + * @ingroup DISCOVERY_MODULE */ struct ParticipantType { @@ -56,14 +55,13 @@ struct ParticipantType static constexpr const char* UNKNOWN = "UNKNOWN"; }; -} /* namespace rtps */ -} /* namespace fastdds */ +} // namespace rtps +} // namespace fastdds namespace fastrtps { namespace rtps { - -//!PDP subclass choice +//! PDP subclass choice typedef enum DiscoveryProtocol { NONE, @@ -126,7 +124,7 @@ inline std::ostream& operator <<( return output; } -//!Filtering flags when discovering participants +//! Filtering flags when discovering participants typedef enum ParticipantFilteringFlags : uint32_t { NO_FILTER = 0, @@ -435,7 +433,7 @@ class BuiltinAttributes /** * Class RTPSParticipantAttributes used to define different aspects of a RTPSParticipant. - *@ingroup RTPS_ATTRIBUTES_MODULE + * @ingroup RTPS_ATTRIBUTES_MODULE */ class RTPSParticipantAttributes { @@ -443,18 +441,9 @@ class RTPSParticipantAttributes public: - RTPSParticipantAttributes() - { - setName("RTPSParticipant"); - sendSocketBufferSize = 0; - listenSocketBufferSize = 0; - participantID = -1; - useBuiltinTransports = true; - } + RTPSParticipantAttributes() = default; - virtual ~RTPSParticipantAttributes() - { - } + virtual ~RTPSParticipantAttributes() = default; bool operator ==( const RTPSParticipantAttributes& b) const @@ -475,6 +464,14 @@ class RTPSParticipantAttributes (this->flow_controllers == b.flow_controllers); } + /** + * Provides a way of easily configuring transport related configuration on certain pre-defined scenarios. + * + * @param transports Defines the transport configuration scenario to setup. + */ + RTPS_DllAPI void setup_transports( + fastdds::rtps::BuiltinTransports transports); + /** * Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case * that it was defined with NO UnicastLocators. At least ONE locator should be included in this list. @@ -491,12 +488,12 @@ class RTPSParticipantAttributes * @brief Send socket buffer size for the send resource. Zero value indicates to use default system buffer size. * Default value: 0. */ - uint32_t sendSocketBufferSize; + uint32_t sendSocketBufferSize = 0; /*! Listen socket buffer for all listen resources. Zero value indicates to use default system buffer size. * Default value: 0. */ - uint32_t listenSocketBufferSize; + uint32_t listenSocketBufferSize = 0; //! Optionally allows user to define the GuidPrefix_t GuidPrefix_t prefix; @@ -516,8 +513,8 @@ class RTPSParticipantAttributes //!User Data of the participant std::vector userData; - //!Participant ID - int32_t participantID; + //! Participant ID + int32_t participantID = -1; /** * @brief Throughput controller parameters. Leave default for uncontrolled flow. @@ -529,9 +526,10 @@ class RTPSParticipantAttributes //!User defined transports to use alongside or in place of builtins. std::vector> userTransports; - //!Set as false to disable the default UDPv4 implementation. - bool useBuiltinTransports; - //!Holds allocation limits affecting collections managed by a participant. + //! Set as false to disable the creation of the default transports. + bool useBuiltinTransports = true; + + //! Holds allocation limits affecting collections managed by a participant. RTPSParticipantAllocationAttributes allocation; //! Property policies @@ -555,12 +553,12 @@ class RTPSParticipantAttributes private: - //!Name of the participant. - string_255 name; + //! Name of the participant. + string_255 name{"RTPSParticipant"}; }; -} /* namespace rtps */ -} /* namespace fastrtps */ -} /* namespace eprosima */ +} // namespace rtps +} // namespace fastrtps +} // namespace eprosima -#endif /* _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ */ +#endif // _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ diff --git a/include/fastrtps/xmlparser/XMLParser.h b/include/fastrtps/xmlparser/XMLParser.h index 2ef8ea39bba..b57a33dd457 100644 --- a/include/fastrtps/xmlparser/XMLParser.h +++ b/include/fastrtps/xmlparser/XMLParser.h @@ -598,6 +598,11 @@ class XMLParser tinyxml2::XMLElement* elem, SubscriberAttributes& subscriber, uint8_t ident); + + RTPS_DllAPI static XMLP_ret getXMLBuiltinTransports( + tinyxml2::XMLElement* elem, + eprosima::fastdds::rtps::BuiltinTransports* bt, + uint8_t ident); }; } // namespace xmlparser diff --git a/include/fastrtps/xmlparser/XMLParserCommon.h b/include/fastrtps/xmlparser/XMLParserCommon.h index 759aa009930..07e8b0747de 100644 --- a/include/fastrtps/xmlparser/XMLParserCommon.h +++ b/include/fastrtps/xmlparser/XMLParserCommon.h @@ -115,6 +115,7 @@ extern const char* IP6_TO_SEND; extern const char* THROUGHPUT_CONT; extern const char* USER_TRANS; extern const char* USE_BUILTIN_TRANS; +extern const char* BUILTIN_TRANS; extern const char* PROPERTIES_POLICY; extern const char* NAME; extern const char* REMOTE_LOCATORS; @@ -171,6 +172,10 @@ extern const char* UDPv6; extern const char* TCPv4; extern const char* TCPv6; extern const char* SHM; +extern const char* DEFAULT_C; +extern const char* DEFAULTv6; +extern const char* LARGE_DATA; +extern const char* LARGE_DATAv6; extern const char* INIT_ACKNACK_DELAY; extern const char* HEARTB_RESP_DELAY; extern const char* INIT_HEARTB_DELAY; diff --git a/resources/xsd/fastRTPS_profiles.xsd b/resources/xsd/fastRTPS_profiles.xsd index 7672e3b6233..3ebb04c95aa 100644 --- a/resources/xsd/fastRTPS_profiles.xsd +++ b/resources/xsd/fastRTPS_profiles.xsd @@ -720,6 +720,20 @@ + + + + + + + + + + + + + + diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index a5213c25954..db7ec1c2dd8 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -77,6 +77,7 @@ set(${PROJECT_NAME}_source_files rtps/messages/submessages/HeartbeatMsg.hpp rtps/network/NetworkFactory.cpp rtps/network/ReceiverResource.cpp + rtps/attributes/RTPSParticipantAttributes.cpp rtps/participant/RTPSParticipant.cpp rtps/participant/RTPSParticipantImpl.cpp rtps/RTPSDomain.cpp @@ -174,6 +175,7 @@ set(${PROJECT_NAME}_source_files fastdds/core/policy/QosPolicyUtils.cpp fastdds/publisher/qos/WriterQos.cpp fastdds/subscriber/qos/ReaderQos.cpp + fastdds/utils/QosConverters.cpp rtps/builtin/BuiltinProtocols.cpp rtps/builtin/discovery/participant/DirectMessageSender.cpp rtps/builtin/discovery/participant/PDP.cpp @@ -383,7 +385,7 @@ find_package(Atomic MODULE) # prioritizes writes # try_run cannot manage targets yet -get_target_property(CMAKE_ATOMIC_LIB eProsima_atomic INTERFACE_LINK_LIBRARIES) +get_target_property(CMAKE_ATOMIC_LIB eProsima_atomic INTERFACE_LINK_LIBRARIES) if(NOT CMAKE_ATOMIC_LIB) set(CMAKE_ATOMIC_LIB) endif() @@ -501,7 +503,7 @@ if(MSVC OR MSVC_IDE) endif() # Get OpenSSL version suitable manifest format - execute_process( COMMAND PowerShell -NoLogo -Command "&{ param([string]$original) + execute_process( COMMAND PowerShell -NoLogo -Command "&{ param([string]$original) if ($original -notmatch '\\d+$') { $res = $original.Substring(0,$original.length-1) + '.' + ([int]$original[$original.length-1]-[int][char]'a'+1); } diff --git a/src/cpp/fastdds/domain/qos/DomainParticipantQos.cpp b/src/cpp/fastdds/domain/qos/DomainParticipantQos.cpp index b38ed9fd319..296182cb360 100644 --- a/src/cpp/fastdds/domain/qos/DomainParticipantQos.cpp +++ b/src/cpp/fastdds/domain/qos/DomainParticipantQos.cpp @@ -19,12 +19,27 @@ #include +#include +#include +#include + namespace eprosima { namespace fastdds { namespace dds { const DomainParticipantQos PARTICIPANT_QOS_DEFAULT; +void DomainParticipantQos::setup_transports( + rtps::BuiltinTransports transports) +{ + fastrtps::rtps::RTPSParticipantAttributes attr; + utils::set_attributes_from_qos(attr, *this); + + attr.setup_transports(transports); + + utils::set_qos_from_attributes(*this, attr); +} + } /* namespace dds */ } /* namespace fastdds */ } /* namespace eprosima */ diff --git a/src/cpp/fastdds/utils/QosConverters.cpp b/src/cpp/fastdds/utils/QosConverters.cpp new file mode 100644 index 00000000000..df6b3c7035f --- /dev/null +++ b/src/cpp/fastdds/utils/QosConverters.cpp @@ -0,0 +1,222 @@ +// Copyright 2022 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. + +/* + * QosConverters.cpp + * + */ + +#include + +#include +#include + +namespace eprosima { +namespace fastdds { +namespace dds { +namespace utils { + +using fastrtps::rtps::Property; +using std::string; + +void set_qos_from_attributes( + DataWriterQos& qos, + const PublisherAttributes& attr) +{ + qos.writer_resource_limits().matched_subscriber_allocation = attr.matched_subscriber_allocation; + qos.properties() = attr.properties; + qos.throughput_controller() = attr.throughputController; + qos.endpoint().unicast_locator_list = attr.unicastLocatorList; + qos.endpoint().multicast_locator_list = attr.multicastLocatorList; + qos.endpoint().remote_locator_list = attr.remoteLocatorList; + qos.endpoint().history_memory_policy = attr.historyMemoryPolicy; + qos.endpoint().user_defined_id = attr.getUserDefinedID(); + qos.endpoint().entity_id = attr.getEntityID(); + qos.reliable_writer_qos().times = attr.times; + qos.reliable_writer_qos().disable_positive_acks = attr.qos.m_disablePositiveACKs; + qos.durability() = attr.qos.m_durability; + qos.durability_service() = attr.qos.m_durabilityService; + qos.deadline() = attr.qos.m_deadline; + qos.latency_budget() = attr.qos.m_latencyBudget; + qos.liveliness() = attr.qos.m_liveliness; + qos.reliability() = attr.qos.m_reliability; + qos.lifespan() = attr.qos.m_lifespan; + qos.user_data().setValue(attr.qos.m_userData); + qos.ownership() = attr.qos.m_ownership; + qos.ownership_strength() = attr.qos.m_ownershipStrength; + qos.destination_order() = attr.qos.m_destinationOrder; + qos.representation() = attr.qos.representation; + qos.publish_mode() = attr.qos.m_publishMode; + qos.history() = attr.topic.historyQos; + qos.resource_limits() = attr.topic.resourceLimitsQos; + qos.data_sharing() = attr.qos.data_sharing; + qos.reliable_writer_qos().disable_heartbeat_piggyback = attr.qos.disable_heartbeat_piggyback; + + if (attr.qos.m_partition.size() > 0 ) + { + Property property; + property.name("partitions"); + string partitions; + bool is_first_partition = true; + + for (auto partition : attr.qos.m_partition.names()) + { + partitions += (is_first_partition ? "" : ";") + partition; + is_first_partition = false; + } + + property.value(std::move(partitions)); + qos.properties().properties().push_back(std::move(property)); + } +} + +void set_qos_from_attributes( + DataReaderQos& qos, + const SubscriberAttributes& attr) +{ + qos.reader_resource_limits().matched_publisher_allocation = attr.matched_publisher_allocation; + qos.properties() = attr.properties; + qos.expects_inline_qos(attr.expectsInlineQos); + qos.endpoint().unicast_locator_list = attr.unicastLocatorList; + qos.endpoint().multicast_locator_list = attr.multicastLocatorList; + qos.endpoint().remote_locator_list = attr.remoteLocatorList; + qos.endpoint().history_memory_policy = attr.historyMemoryPolicy; + qos.endpoint().user_defined_id = attr.getUserDefinedID(); + qos.endpoint().entity_id = attr.getEntityID(); + qos.reliable_reader_qos().times = attr.times; + qos.reliable_reader_qos().disable_positive_ACKs = attr.qos.m_disablePositiveACKs; + qos.durability() = attr.qos.m_durability; + qos.durability_service() = attr.qos.m_durabilityService; + qos.deadline() = attr.qos.m_deadline; + qos.latency_budget() = attr.qos.m_latencyBudget; + qos.liveliness() = attr.qos.m_liveliness; + qos.reliability() = attr.qos.m_reliability; + qos.lifespan() = attr.qos.m_lifespan; + qos.user_data().setValue(attr.qos.m_userData); + qos.ownership() = attr.qos.m_ownership; + qos.destination_order() = attr.qos.m_destinationOrder; + qos.type_consistency().type_consistency = attr.qos.type_consistency; + qos.type_consistency().representation = attr.qos.representation; + qos.time_based_filter() = attr.qos.m_timeBasedFilter; + qos.history() = attr.topic.historyQos; + qos.resource_limits() = attr.topic.resourceLimitsQos; + qos.data_sharing() = attr.qos.data_sharing; + + if (attr.qos.m_partition.size() > 0 ) + { + Property property; + property.name("partitions"); + string partitions; + bool is_first_partition = true; + + for (auto partition : attr.qos.m_partition.names()) + { + partitions += (is_first_partition ? "" : ";") + partition; + is_first_partition = false; + } + + property.value(std::move(partitions)); + qos.properties().properties().push_back(std::move(property)); + } +} + +void set_qos_from_attributes( + DomainParticipantQos& qos, + const eprosima::fastrtps::rtps::RTPSParticipantAttributes& attr) +{ + qos.user_data().setValue(attr.userData); + qos.allocation() = attr.allocation; + qos.wire_protocol().prefix = attr.prefix; + qos.wire_protocol().participant_id = attr.participantID; + qos.wire_protocol().builtin = attr.builtin; + qos.wire_protocol().port = attr.port; + qos.wire_protocol().throughput_controller = attr.throughputController; + qos.wire_protocol().default_unicast_locator_list = attr.defaultUnicastLocatorList; + qos.wire_protocol().default_multicast_locator_list = attr.defaultMulticastLocatorList; + qos.transport().user_transports = attr.userTransports; + qos.transport().use_builtin_transports = attr.useBuiltinTransports; + qos.transport().send_socket_buffer_size = attr.sendSocketBufferSize; + qos.transport().listen_socket_buffer_size = attr.listenSocketBufferSize; + qos.name() = attr.getName(); + qos.flow_controllers() = attr.flow_controllers; + + // Merge attributes and qos properties + for (auto property : attr.properties.properties()) + { + string* property_value = fastrtps::rtps::PropertyPolicyHelper::find_property( + qos.properties(), property.name()); + if (nullptr == property_value) + { + qos.properties().properties().emplace_back(property); + } + else + { + *property_value = property.value(); + } + } + qos.properties().binary_properties() = attr.properties.binary_properties(); +} + +void set_attributes_from_qos( + fastrtps::rtps::RTPSParticipantAttributes& attr, + const DomainParticipantQos& qos) +{ + attr.allocation = qos.allocation(); + attr.properties = qos.properties(); + attr.setName(qos.name()); + attr.prefix = qos.wire_protocol().prefix; + attr.participantID = qos.wire_protocol().participant_id; + attr.builtin = qos.wire_protocol().builtin; + attr.port = qos.wire_protocol().port; + attr.throughputController = qos.wire_protocol().throughput_controller; + attr.defaultUnicastLocatorList = qos.wire_protocol().default_unicast_locator_list; + attr.defaultMulticastLocatorList = qos.wire_protocol().default_multicast_locator_list; + attr.userTransports = qos.transport().user_transports; + attr.useBuiltinTransports = qos.transport().use_builtin_transports; + attr.sendSocketBufferSize = qos.transport().send_socket_buffer_size; + attr.listenSocketBufferSize = qos.transport().listen_socket_buffer_size; + attr.userData = qos.user_data().data_vec(); + attr.flow_controllers = qos.flow_controllers(); +} + +void set_qos_from_attributes( + TopicQos& qos, + const TopicAttributes& attr) +{ + qos.history() = attr.historyQos; + qos.resource_limits() = attr.resourceLimitsQos; +} + +void set_qos_from_attributes( + SubscriberQos& qos, + const SubscriberAttributes& attr) +{ + qos.group_data().setValue(attr.qos.m_groupData); + qos.partition() = attr.qos.m_partition; + qos.presentation() = attr.qos.m_presentation; +} + +void set_qos_from_attributes( + PublisherQos& qos, + const PublisherAttributes& attr) +{ + qos.group_data().setValue(attr.qos.m_groupData); + qos.partition() = attr.qos.m_partition; + qos.presentation() = attr.qos.m_presentation; +} + +} /* namespace utils */ +} /* namespace dds */ +} /* namespace fastdds */ +} /* namespace eprosima */ diff --git a/src/cpp/fastdds/utils/QosConverters.hpp b/src/cpp/fastdds/utils/QosConverters.hpp new file mode 100644 index 00000000000..7b89defa50a --- /dev/null +++ b/src/cpp/fastdds/utils/QosConverters.hpp @@ -0,0 +1,123 @@ +// Copyright 2022 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. + +/** + * @file QosConverters.h + */ + +#ifndef _FASTDDS_UTILS_QOS_CONVERTERS_HPP_ +#define _FASTDDS_UTILS_QOS_CONVERTERS_HPP_ +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#include +#include +#include +#include +#include +#include +#include + +namespace eprosima { +namespace fastdds { +namespace dds { +namespace utils { + +using fastrtps::PublisherAttributes; +using fastrtps::SubscriberAttributes; +using fastrtps::TopicAttributes; + +/** + * Obtains the DataWriterQos from the PublisherAttributes provided. + * + * @param[out] qos Pointer to the QoS to write on + * @param[in] attr Pointer to the attributes from which to obtain data + */ +void set_qos_from_attributes( + DataWriterQos& qos, + const PublisherAttributes& attr); + +/** + * Obtains the DataReaderQos from the SubscriberAttributes provided. + * + * @param[out] qos Pointer to the QoS to write on + * @param[in] attr Pointer to the attributes from which to obtain data + */ +void set_qos_from_attributes( + DataReaderQos& qos, + const SubscriberAttributes& attr); + +/** + * @brief Fill DomainParticipantQos from a given attributes RTPSParticipantAttributes object + * + * For the case of the non-binary properties, instead of the RTPSParticipantAttributes overriding the + * property list in the DomainParticipantQos, a merge is performed in the following manner: + * + * - If any property from the RTPSParticipantAttributes is not in the DomainParticipantQos, then it is appended + * to the DomainParticipantQos. + * - If any property from the RTPSParticipantAttributes property is also in the DomainParticipantQos, then the + * value in the DomainParticipantQos is overridden with that of the RTPSParticipantAttributes. + * + * @param[in, out] qos The DomainParticipantQos to set + * @param[in] attr The RTPSParticipantAttributes from which the @c qos is set. + */ +void set_qos_from_attributes( + DomainParticipantQos& qos, + const eprosima::fastrtps::rtps::RTPSParticipantAttributes& attr); + +/** + * Obtains the RTPSParticipantAttributes from the DomainParticipantQos provided. + * + * @param[out] attr Pointer to the attributes from which to obtain data + * @param[in] qos Pointer to the QoS to write on + */ +void set_attributes_from_qos( + fastrtps::rtps::RTPSParticipantAttributes& attr, + const DomainParticipantQos& qos); + +/** + * Obtains the TopicQos from the TopicAttributes provided. + * + * @param[out] qos Pointer to the QoS to write on + * @param[in] attr Pointer to the attributes from which to obtain data + */ +void set_qos_from_attributes( + TopicQos& qos, + const TopicAttributes& attr); + +/** + * Obtains the SubscriberQos from the SubscriberAttributes provided. + * + * @param[out] qos Pointer to the QoS to write on + * @param[in] attr Pointer to the attributes from which to obtain data + */ +void set_qos_from_attributes( + SubscriberQos& qos, + const SubscriberAttributes& attr); + +/** + * Obtains the PublisherQos from the PublisherAttributes provided. + * + * @param[out] qos Pointer to the QoS to write on + * @param[in] attr Pointer to the attributes from which to obtain data + */ +void set_qos_from_attributes( + PublisherQos& qos, + const PublisherAttributes& attr); + +} /* namespace utils */ +} /* namespace dds */ +} /* namespace fastdds */ +} /* namespace eprosima */ +#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC +#endif /* _FASTDDS_UTILS_QOS_CONVERTERS_HPP_ */ diff --git a/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp b/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp new file mode 100644 index 00000000000..efa3395c3f3 --- /dev/null +++ b/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp @@ -0,0 +1,307 @@ +// Copyright 2023 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 +#include +#include +#include +#include +#include +#include + +#include + +namespace eprosima { +namespace fastrtps { +namespace rtps { + +static bool is_intraprocess_only( + const RTPSParticipantAttributes& att) +{ + return + xmlparser::XMLProfileManager::library_settings().intraprocess_delivery == INTRAPROCESS_FULL && + att.builtin.discovery_config.ignoreParticipantFlags == + (ParticipantFilteringFlags::FILTER_DIFFERENT_HOST | ParticipantFilteringFlags::FILTER_DIFFERENT_PROCESS); +} + +static std::shared_ptr create_shm_transport( + const RTPSParticipantAttributes& att) +{ + auto descriptor = std::make_shared(); + + // We assume (Linux) UDP doubles the user socket buffer size in kernel, so + // the equivalent segment size in SHM would be socket buffer size x 2 + auto segment_size_udp_equivalent = + std::max(att.sendSocketBufferSize, att.listenSocketBufferSize) * 2; + descriptor->segment_size(segment_size_udp_equivalent); + return descriptor; +} + +static std::shared_ptr create_udpv4_transport( + const RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = std::make_shared(); + descriptor->sendBufferSize = att.sendSocketBufferSize; + descriptor->receiveBufferSize = att.listenSocketBufferSize; + if (intraprocess_only) + { + // Avoid multicast leaving the host for intraprocess-only participants + descriptor->TTL = 0; + } + return descriptor; +} + +static std::shared_ptr create_udpv6_transport( + const RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = std::make_shared(); + descriptor->sendBufferSize = att.sendSocketBufferSize; + descriptor->receiveBufferSize = att.listenSocketBufferSize; + if (intraprocess_only) + { + // Avoid multicast leaving the host for intraprocess-only participants + descriptor->TTL = 0; + } + return descriptor; +} + +static std::shared_ptr create_tcpv4_transport( + const RTPSParticipantAttributes& att) +{ + auto descriptor = std::make_shared(); + descriptor->add_listener_port(0); + descriptor->sendBufferSize = att.sendSocketBufferSize; + descriptor->receiveBufferSize = att.listenSocketBufferSize; + + descriptor->calculate_crc = false; + descriptor->check_crc = false; + descriptor->apply_security = false; + descriptor->enable_tcp_nodelay = true; + + return descriptor; +} + +static std::shared_ptr create_tcpv6_transport( + const RTPSParticipantAttributes& att) +{ + auto descriptor = std::make_shared(); + descriptor->add_listener_port(0); + descriptor->sendBufferSize = att.sendSocketBufferSize; + descriptor->receiveBufferSize = att.listenSocketBufferSize; + + descriptor->calculate_crc = false; + descriptor->check_crc = false; + descriptor->apply_security = false; + descriptor->enable_tcp_nodelay = true; + + return descriptor; +} + +static void setup_transports_default( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = create_udpv4_transport(att, intraprocess_only); + +#ifdef SHM_TRANSPORT_BUILTIN + if (!intraprocess_only) + { + auto shm_transport = create_shm_transport(att); + // Use same default max_message_size on both UDP and SHM + shm_transport->max_message_size(descriptor->max_message_size()); + att.userTransports.push_back(shm_transport); + } +#endif // ifdef SHM_TRANSPORT_BUILTIN + + att.userTransports.push_back(descriptor); +} + +static void setup_transports_defaultv6( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = create_udpv6_transport(att, intraprocess_only); + +#ifdef SHM_TRANSPORT_BUILTIN + if (!intraprocess_only) + { + auto shm_transport = create_shm_transport(att); + // Use same default max_message_size on both UDP and SHM + shm_transport->max_message_size(descriptor->max_message_size()); + att.userTransports.push_back(shm_transport); + } +#endif // ifdef SHM_TRANSPORT_BUILTIN + + att.userTransports.push_back(descriptor); +} + +static void setup_transports_shm( + RTPSParticipantAttributes& att) +{ +#ifdef FASTDDS_SHM_TRANSPORT_DISABLED + logError(RTPS_PARTICIPANT, "Trying to configure SHM transport only, " << + "but Fast DDS was built without SHM transport support."); +#else + auto descriptor = create_shm_transport(att); + att.userTransports.push_back(descriptor); +#endif // FASTDDS_SHM_TRANSPORT_DISABLED +} + +static void setup_transports_udpv4( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = create_udpv4_transport(att, intraprocess_only); + att.userTransports.push_back(descriptor); +} + +static void setup_transports_udpv6( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + auto descriptor = create_udpv6_transport(att, intraprocess_only); + att.userTransports.push_back(descriptor); +} + +static void setup_transports_large_data( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + if (!intraprocess_only) + { + auto shm_transport = create_shm_transport(att); + att.userTransports.push_back(shm_transport); + + auto shm_loc = fastdds::rtps::SHMLocator::create_locator(0, fastdds::rtps::SHMLocator::Type::UNICAST); + att.defaultUnicastLocatorList.push_back(shm_loc); + + auto tcp_transport = create_tcpv4_transport(att); + 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.builtin.metatrafficUnicastLocatorList.push_back(tcp_loc); + att.defaultUnicastLocatorList.push_back(tcp_loc); + } + + auto udp_descriptor = create_udpv4_transport(att, intraprocess_only); + att.userTransports.push_back(udp_descriptor); + + if (!intraprocess_only) + { + Locator_t pdp_locator; + pdp_locator.kind = LOCATOR_KIND_UDPv4; + IPLocator::setIPv4(pdp_locator, "239.255.0.1"); + att.builtin.metatrafficMulticastLocatorList.push_back(pdp_locator); + } +} + +static void setup_transports_large_datav6( + RTPSParticipantAttributes& att, + bool intraprocess_only) +{ + if (!intraprocess_only) + { + auto shm_transport = create_shm_transport(att); + att.userTransports.push_back(shm_transport); + + auto shm_loc = fastdds::rtps::SHMLocator::create_locator(0, fastdds::rtps::SHMLocator::Type::UNICAST); + att.defaultUnicastLocatorList.push_back(shm_loc); + + auto tcp_transport = create_tcpv6_transport(att); + att.userTransports.push_back(tcp_transport); + + Locator_t tcp_loc; + tcp_loc.kind = LOCATOR_KIND_TCPv6; + IPLocator::setIPv6(tcp_loc, "::"); + IPLocator::setPhysicalPort(tcp_loc, 0); + IPLocator::setLogicalPort(tcp_loc, 0); + att.builtin.metatrafficUnicastLocatorList.push_back(tcp_loc); + att.defaultUnicastLocatorList.push_back(tcp_loc); + } + + auto udp_descriptor = create_udpv6_transport(att, intraprocess_only); + att.userTransports.push_back(udp_descriptor); + + if (!intraprocess_only) + { + Locator_t pdp_locator; + pdp_locator.kind = LOCATOR_KIND_UDPv6; + att.builtin.metatrafficMulticastLocatorList.push_back(pdp_locator); + } +} + +void RTPSParticipantAttributes::setup_transports( + fastdds::rtps::BuiltinTransports transports) +{ + bool intraprocess_only = is_intraprocess_only(*this); + + switch (transports) + { + case fastdds::rtps::BuiltinTransports::NONE: + break; + + case fastdds::rtps::BuiltinTransports::DEFAULT: + setup_transports_default(*this, intraprocess_only); + break; + + case fastdds::rtps::BuiltinTransports::DEFAULTv6: + setup_transports_defaultv6(*this, intraprocess_only); + break; + + case fastdds::rtps::BuiltinTransports::SHM: + setup_transports_shm(*this); + break; + + case fastdds::rtps::BuiltinTransports::UDPv4: + setup_transports_udpv4(*this, intraprocess_only); + break; + + case fastdds::rtps::BuiltinTransports::UDPv6: + setup_transports_udpv6(*this, intraprocess_only); + break; + + case fastdds::rtps::BuiltinTransports::LARGE_DATA: + setup_transports_large_data(*this, intraprocess_only); + break; + + case fastdds::rtps::BuiltinTransports::LARGE_DATAv6: + setup_transports_large_datav6(*this, intraprocess_only); + break; + + default: + logError(RTPS_PARTICIPANT, + "Setup for '" << transports << "' transport configuration not yet supported."); + return; + } + + useBuiltinTransports = false; +} + +} // namespace rtps +} // namespace fastdds +} // namespace eprosima diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index d4c5038e57d..d968aad6711 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,8 @@ #include #include #include +#include +#include namespace eprosima { namespace fastrtps { @@ -66,6 +69,35 @@ namespace rtps { using UDPv4TransportDescriptor = fastdds::rtps::UDPv4TransportDescriptor; using TCPTransportDescriptor = fastdds::rtps::TCPTransportDescriptor; using SharedMemTransportDescriptor = fastdds::rtps::SharedMemTransportDescriptor; +using BuiltinTransports = fastdds::rtps::BuiltinTransports; + +/** + * Parse the environment variable specifying the transports to instantiate + */ +static BuiltinTransports get_builtin_transports_from_env_var() +{ + static constexpr const char* env_var_name = "FASTDDS_BUILTIN_TRANSPORTS"; + + BuiltinTransports ret_val = BuiltinTransports::DEFAULT; + std::string env_value; + if (SystemInfo::get_env(env_var_name, env_value) == ReturnCode_t::RETCODE_OK) + { + if (!get_element_enum_value(env_value.c_str(), ret_val, + "NONE", BuiltinTransports::NONE, + "DEFAULT", BuiltinTransports::DEFAULT, + "DEFAULTv6", BuiltinTransports::DEFAULTv6, + "SHM", BuiltinTransports::SHM, + "UDPv4", BuiltinTransports::UDPv4, + "UDPv6", BuiltinTransports::UDPv6, + "LARGE_DATA", BuiltinTransports::LARGE_DATA, + "LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6)) + { + logError(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" << + env_var_name << "'. Leaving as DEFAULT"); + } + } + return ret_val; +} static EntityId_t TrustedWriter( const EntityId_t& reader) @@ -146,37 +178,15 @@ RTPSParticipantImpl::RTPSParticipantImpl( { m_persistence_guid = GUID_t(persistence_guid, c_EntityId_RTPSParticipant); } - // Builtin transports by default - if (PParam.useBuiltinTransports) - { - UDPv4TransportDescriptor descriptor; - descriptor.sendBufferSize = m_att.sendSocketBufferSize; - descriptor.receiveBufferSize = m_att.listenSocketBufferSize; - if (is_intraprocess_only()) - { - // Avoid multicast leaving the host for intraprocess-only participants - descriptor.TTL = 0; - } - m_network_Factory.RegisterTransport(&descriptor, &m_att.properties); -#ifdef SHM_TRANSPORT_BUILTIN - if (!is_intraprocess_only()) - { - SharedMemTransportDescriptor shm_transport; - // We assume (Linux) UDP doubles the user socket buffer size in kernel, so - // the equivalent segment size in SHM would be socket buffer size x 2 - auto segment_size_udp_equivalent = - std::max(m_att.sendSocketBufferSize, m_att.listenSocketBufferSize) * 2; - shm_transport.segment_size(segment_size_udp_equivalent); - // Use same default max_message_size on both UDP and SHM - shm_transport.max_message_size(descriptor.max_message_size()); - has_shm_transport_ |= m_network_Factory.RegisterTransport(&shm_transport); - } -#endif // ifdef SHM_TRANSPORT_BUILTIN + // Setup builtin transports + if (m_att.useBuiltinTransports) + { + m_att.setup_transports(get_builtin_transports_from_env_var()); } // BACKUP servers guid is its persistence one - if (PParam.builtin.discovery_config.discoveryProtocol == DiscoveryProtocol::BACKUP) + if (m_att.builtin.discovery_config.discoveryProtocol == DiscoveryProtocol::BACKUP) { m_persistence_guid = m_guid; } @@ -187,14 +197,14 @@ RTPSParticipantImpl::RTPSParticipantImpl( guid_str_ = guid_sstr.str(); // Client-server discovery protocol requires that every TCP transport has a listening port - switch (PParam.builtin.discovery_config.discoveryProtocol) + switch (m_att.builtin.discovery_config.discoveryProtocol) { case DiscoveryProtocol::BACKUP: case DiscoveryProtocol::CLIENT: case DiscoveryProtocol::SERVER: case DiscoveryProtocol::SUPER_CLIENT: // Verify if listening ports are provided - for (auto& transportDescriptor : PParam.userTransports) + for (auto& transportDescriptor : m_att.userTransports) { TCPTransportDescriptor* pT = dynamic_cast(transportDescriptor.get()); if (pT && pT->listening_ports.empty()) @@ -210,7 +220,7 @@ RTPSParticipantImpl::RTPSParticipantImpl( // User defined transports - for (const auto& transportDescriptor : PParam.userTransports) + for (const auto& transportDescriptor : m_att.userTransports) { if (m_network_Factory.RegisterTransport(transportDescriptor.get(), &m_att.properties)) { @@ -335,7 +345,7 @@ RTPSParticipantImpl::RTPSParticipantImpl( // Start security if (!m_security_manager.init( security_attributes_, - PParam.properties)) + m_att.properties)) { // Participant will be deleted, no need to allocate buffers or create builtin endpoints return; @@ -382,12 +392,12 @@ RTPSParticipantImpl::RTPSParticipantImpl( flow_controller_factory_.init(this); // Support old API - if (PParam.throughputController.bytesPerPeriod != UINT32_MAX && PParam.throughputController.periodMillisecs != 0) + if (m_att.throughputController.bytesPerPeriod != UINT32_MAX && m_att.throughputController.periodMillisecs != 0) { fastdds::rtps::FlowControllerDescriptor old_descriptor; old_descriptor.name = guid_str_.c_str(); - old_descriptor.max_bytes_per_period = PParam.throughputController.bytesPerPeriod; - old_descriptor.period_ms = PParam.throughputController.periodMillisecs; + old_descriptor.max_bytes_per_period = m_att.throughputController.bytesPerPeriod; + old_descriptor.period_ms = m_att.throughputController.periodMillisecs; flow_controller_factory_.register_flow_controller(old_descriptor); } diff --git a/src/cpp/rtps/xmlparser/XMLElementParser.cpp b/src/cpp/rtps/xmlparser/XMLElementParser.cpp index 3f0a7c8e41c..e58b99ec8c0 100644 --- a/src/cpp/rtps/xmlparser/XMLElementParser.cpp +++ b/src/cpp/rtps/xmlparser/XMLElementParser.cpp @@ -20,6 +20,7 @@ #include #include #include +#include using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; @@ -4029,3 +4030,46 @@ XMLP_ret XMLParser::getXMLSubscriberAttributes( return XMLP_ret::XML_OK; } + +XMLP_ret XMLParser::getXMLBuiltinTransports( + tinyxml2::XMLElement* elem, + eprosima::fastdds::rtps::BuiltinTransports* bt, + uint8_t /*ident*/) +{ + /* + + + + + + + + + + + + + */ + const char* text = elem->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + + if (!get_element_enum_value(text, *bt, + NONE, eprosima::fastdds::rtps::BuiltinTransports::NONE, + DEFAULT_C, eprosima::fastdds::rtps::BuiltinTransports::DEFAULT, + DEFAULTv6, eprosima::fastdds::rtps::BuiltinTransports::DEFAULTv6, + SHM, eprosima::fastdds::rtps::BuiltinTransports::SHM, + 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)) + { + logError(XMLPARSER, "Node '" << KIND << "' bad content"); + return XMLP_ret::XML_ERROR; + } + + return XMLP_ret::XML_OK; +} diff --git a/src/cpp/rtps/xmlparser/XMLParser.cpp b/src/cpp/rtps/xmlparser/XMLParser.cpp index 67137d5f3b3..8735d56895a 100644 --- a/src/cpp/rtps/xmlparser/XMLParser.cpp +++ b/src/cpp/rtps/xmlparser/XMLParser.cpp @@ -1924,6 +1924,16 @@ XMLP_ret XMLParser::fillDataNode( return XMLP_ret::XML_ERROR; } } + else if (strcmp(name, BUILTIN_TRANS) == 0) + { + // builtinTransports + eprosima::fastdds::rtps::BuiltinTransports bt; + if (XMLP_ret::XML_OK != getXMLBuiltinTransports(p_aux0, &bt, ident)) + { + return XMLP_ret::XML_ERROR; + } + participant_node.get()->rtps.setup_transports(bt); + } else if (strcmp(name, PROPERTIES_POLICY) == 0) { // propertiesPolicy diff --git a/src/cpp/rtps/xmlparser/XMLParserCommon.cpp b/src/cpp/rtps/xmlparser/XMLParserCommon.cpp index 23bca36f4da..dd23443a1c0 100644 --- a/src/cpp/rtps/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/rtps/xmlparser/XMLParserCommon.cpp @@ -99,6 +99,7 @@ const char* PART_ID = "participantID"; const char* THROUGHPUT_CONT = "throughputController"; const char* USER_TRANS = "userTransports"; const char* USE_BUILTIN_TRANS = "useBuiltinTransports"; +const char* BUILTIN_TRANS = "builtinTransports"; const char* PROPERTIES_POLICY = "propertiesPolicy"; const char* NAME = "name"; const char* REMOTE_LOCATORS = "remote_locators"; @@ -155,6 +156,10 @@ const char* UDPv6 = "UDPv6"; const char* TCPv4 = "TCPv4"; const char* TCPv6 = "TCPv6"; const char* SHM = "SHM"; +const char* DEFAULT_C = "DEFAULT"; +const char* DEFAULTv6 = "DEFAULTv6"; +const char* LARGE_DATA = "LARGE_DATA"; +const char* LARGE_DATAv6 = "LARGE_DATAv6"; const char* INIT_ACKNACK_DELAY = "initialAcknackDelay"; const char* HEARTB_RESP_DELAY = "heartbeatResponseDelay"; const char* INIT_HEARTB_DELAY = "initialHeartbeatDelay"; diff --git a/src/cpp/utils/string_utilities.hpp b/src/cpp/utils/string_utilities.hpp new file mode 100644 index 00000000000..ae5b4772f00 --- /dev/null +++ b/src/cpp/utils/string_utilities.hpp @@ -0,0 +1,51 @@ +// Copyright 2023 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__STRING_UTILITIES_HPP_ +#define UTILS__STRING_UTILITIES_HPP_ + +template +static bool get_element_enum_value( + const char* input, + _Enum& output, + const char* name, + _Enum value) +{ + if (0 == strcmp(input, name)) + { + output = value; + return true; + } + + return false; +} + +template +static bool get_element_enum_value( + const char* input, + _Enum& output, + const char* name, + _Enum value, + Targs... args) +{ + if (0 == strcmp(input, name)) + { + output = value; + return true; + } + + return get_element_enum_value(input, output, args ...); +} + +#endif // UTILS__STRING_UTILITIES_HPP_ diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index 0475b6fabf2..ec6e8725c91 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -335,6 +335,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/check_guid.py ${CMAKE_CURRENT_BINARY_DIR}/check_guid.py) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/partitions.xml ${CMAKE_CURRENT_BINARY_DIR}/partitions.xml) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/builtin_transports_profile.xml + ${CMAKE_CURRENT_BINARY_DIR}/builtin_transports_profile.xml) file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/datagrams" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") if(FASTRTPS_API_TESTS) diff --git a/test/blackbox/XFAIL_DDS_PIM.list b/test/blackbox/XFAIL_DDS_PIM.list index 60b6da03c3d..5472f92ec26 100644 --- a/test/blackbox/XFAIL_DDS_PIM.list +++ b/test/blackbox/XFAIL_DDS_PIM.list @@ -8,3 +8,9 @@ BlackboxTests_DDS_PIM.LivelinessQos.ThreeWriters_ThreeReaders.Intraprocess BlackboxTests_DDS_PIM.LivelinessQos.ThreeWriters_ThreeReaders.Transport BlackboxTests_DDS_PIM.LivelinessQos.TwoWriters_OneReader_ManualByParticipant.Intraprocess BlackboxTests_DDS_PIM.PersistenceLargeData.PubSubAsReliablePubPersistentWithFrag.Transport +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_api_large_data +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_api_large_datav6 +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_env_large_data +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_env_large_datav6 +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_xml_large_data +BlackboxTests_DDS_PIM.ChainingTransportTests.builtin_transports_xml_large_datav6 diff --git a/test/blackbox/api/dds-pim/PubSubReader.hpp b/test/blackbox/api/dds-pim/PubSubReader.hpp index 1f53974d3bc..2f94b832992 100644 --- a/test/blackbox/api/dds-pim/PubSubReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubReader.hpp @@ -928,6 +928,13 @@ class PubSubReader return *this; } + PubSubReader& setup_transports( + eprosima::fastdds::rtps::BuiltinTransports transports) + { + participant_qos_.setup_transports(transports); + return *this; + } + PubSubReader& disable_builtin_transport() { participant_qos_.transport().use_builtin_transports = false; diff --git a/test/blackbox/api/dds-pim/PubSubWriter.hpp b/test/blackbox/api/dds-pim/PubSubWriter.hpp index 819b2418d6a..26fa690b6ef 100644 --- a/test/blackbox/api/dds-pim/PubSubWriter.hpp +++ b/test/blackbox/api/dds-pim/PubSubWriter.hpp @@ -891,6 +891,13 @@ class PubSubWriter return *this; } + PubSubWriter& setup_transports( + eprosima::fastdds::rtps::BuiltinTransports transports) + { + participant_qos_.setup_transports(transports); + return *this; + } + PubSubWriter& disable_builtin_transport() { participant_qos_.transport().use_builtin_transports = false; diff --git a/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp b/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp index 9b18e661c63..54ad64aaa1d 100644 --- a/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp +++ b/test/blackbox/api/fastrtps_deprecated/PubSubReader.hpp @@ -291,15 +291,33 @@ class PubSubReader void init() { - participant_attr_.domainId = (uint32_t)GET_PID() % 230; - + //Create participant // Use local copies of attributes to catch #6507 issues with valgrind eprosima::fastrtps::ParticipantAttributes participant_attr; eprosima::fastrtps::SubscriberAttributes subscriber_attr; - participant_attr = participant_attr_; - subscriber_attr = subscriber_attr_; - participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr, &participant_listener_); + if (!xml_file_.empty()) + { + eprosima::fastrtps::Domain::loadXMLProfilesFile(xml_file_); + if (!participant_profile_.empty()) + { + // Need to specify ID in XML + participant_ = eprosima::fastrtps::Domain::createParticipant(participant_profile_, + &participant_listener_); + ASSERT_NE(participant_, nullptr); + participant_attr = participant_->getAttributes(); + subscriber_attr = subscriber_attr_; + } + } + if (participant_ == nullptr) + { + participant_attr_.domainId = (uint32_t)GET_PID() % 230; + + participant_attr = participant_attr_; + subscriber_attr = subscriber_attr_; + + participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr, &participant_listener_); + } if (participant_ != nullptr) { @@ -712,6 +730,13 @@ class PubSubReader return *this; } + PubSubReader& setup_transports( + eprosima::fastdds::rtps::BuiltinTransports transports) + { + participant_attr_.rtps.setup_transports(transports); + return *this; + } + PubSubReader& disable_builtin_transport() { participant_attr_.rtps.useBuiltinTransports = false; @@ -1291,6 +1316,18 @@ class PubSubReader return matched_; } + void set_xml_filename( + const std::string& name) + { + xml_file_ = name; + } + + void set_participant_profile( + const std::string& profile) + { + participant_profile_ = profile; + } + const eprosima::fastrtps::rtps::GUID_t& participant_guid() const { return participant_guid_; @@ -1402,6 +1439,9 @@ class PubSubReader size_t number_samples_expected_; bool discovery_result_; + std::string xml_file_ = ""; + std::string participant_profile_ = ""; + std::function onDiscovery_; std::function onEndpointDiscovery_; diff --git a/test/blackbox/api/fastrtps_deprecated/PubSubWriter.hpp b/test/blackbox/api/fastrtps_deprecated/PubSubWriter.hpp index 90279329cb5..ae612bc3e10 100644 --- a/test/blackbox/api/fastrtps_deprecated/PubSubWriter.hpp +++ b/test/blackbox/api/fastrtps_deprecated/PubSubWriter.hpp @@ -289,15 +289,32 @@ class PubSubWriter void init() { //Create participant - participant_attr_.domainId = (uint32_t)GET_PID() % 230; - // Use local copies of attributes to catch #6507 issues with valgrind eprosima::fastrtps::ParticipantAttributes participant_attr; eprosima::fastrtps::PublisherAttributes publisher_attr; - participant_attr = participant_attr_; - publisher_attr = publisher_attr_; - participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr, &participant_listener_); + if (!xml_file_.empty()) + { + eprosima::fastrtps::Domain::loadXMLProfilesFile(xml_file_); + if (!participant_profile_.empty()) + { + // Need to specify ID in XML + participant_ = eprosima::fastrtps::Domain::createParticipant(participant_profile_, + &participant_listener_); + ASSERT_NE(participant_, nullptr); + participant_attr = participant_->getAttributes(); + publisher_attr = publisher_attr_; + } + } + if (participant_ == nullptr) + { + participant_attr_.domainId = (uint32_t)GET_PID() % 230; + + participant_attr = participant_attr_; + publisher_attr = publisher_attr_; + + participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr, &participant_listener_); + } if (participant_ != nullptr) { @@ -726,6 +743,13 @@ class PubSubWriter return *this; } + PubSubWriter& setup_transports( + eprosima::fastdds::rtps::BuiltinTransports transports) + { + participant_attr_.rtps.setup_transports(transports); + return *this; + } + PubSubWriter& disable_builtin_transport() { participant_attr_.rtps.useBuiltinTransports = false; @@ -1195,6 +1219,18 @@ class PubSubWriter return matched_; } + void set_xml_filename( + const std::string& name) + { + xml_file_ = name; + } + + void set_participant_profile( + const std::string& profile) + { + participant_profile_ = profile; + } + unsigned int missed_deadlines() const { return listener_.missed_deadlines(); @@ -1475,6 +1511,9 @@ class PubSubWriter std::map mapPartitionCountList_; bool discovery_result_; + std::string xml_file_ = ""; + std::string participant_profile_ = ""; + std::function onDiscovery_; //! A mutex for liveliness diff --git a/test/blackbox/builtin_transports_profile.xml b/test/blackbox/builtin_transports_profile.xml new file mode 100644 index 00000000000..0163b1674ec --- /dev/null +++ b/test/blackbox/builtin_transports_profile.xml @@ -0,0 +1,83 @@ + + + + + + transport + UDPv4 + + + + + 0 + + Participant.builtin_transports_none + NONE + + + transport + + + + + + 0 + + Participant.builtin_transports_default + DEFAULT + + + + + 0 + + Participant.builtin_transports_defaultv6 + DEFAULTv6 + + + + + 0 + + Participant.builtin_transports_shm + SHM + + + + + 0 + + Participant.builtin_transports_udp + UDPv4 + + + + + 0 + + Participant.builtin_transports_udpv6 + UDPv6 + + + + + 0 + + Participant.builtin_transports_largedata + LARGE_DATA + + + + + 0 + + Participant.builtin_transports_largedatav6 + LARGE_DATAv6 + + + + + diff --git a/test/blackbox/common/BlackboxTestsTransportCustom.cpp b/test/blackbox/common/BlackboxTestsTransportCustom.cpp index 8b879bd7249..5944d53d702 100644 --- a/test/blackbox/common/BlackboxTestsTransportCustom.cpp +++ b/test/blackbox/common/BlackboxTestsTransportCustom.cpp @@ -14,15 +14,19 @@ #include "BlackboxTests.hpp" -#include "PubSubReader.hpp" -#include "PubSubWriter.hpp" +#include + +#include #include #include #include #include -#include +#include "PubSubReader.hpp" +#include "PubSubWriter.hpp" + +using BuiltinTransports = eprosima::fastdds::rtps::BuiltinTransports; class TestChainingTransportDescriptor : public eprosima::fastdds::rtps::ChainingTransportDescriptor { @@ -112,6 +116,181 @@ eprosima::fastdds::rtps::TransportInterface* TestChainingTransportDescriptor::cr return new TestChainingTransport(*this); } +class BuiltinTransportsTest +{ +public: + + static void test_xml( + const std::string& profiles_file, + const std::string& participant_profile) + { + run_test(profiles_file, participant_profile, "", BuiltinTransports::NONE); + } + + static void test_env( + const std::string& env_var_value) + { + if (env_var_value == "NONE") + { +#ifdef _WIN32 + _putenv_s(env_var_name_.c_str(), env_var_value.c_str()); +#else + setenv(env_var_name_.c_str(), env_var_value.c_str(), 1); +#endif // _WIN32 + + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader(TEST_TOPIC_NAME); + + writer.init(); + ASSERT_FALSE(writer.isInitialized()); + + reader.init(); + ASSERT_FALSE(reader.isInitialized()); + + } + else + { + run_test("", "", env_var_value, BuiltinTransports::NONE); + } + } + + static void test_api( + const BuiltinTransports& builtin_transports) + { + if (builtin_transports == BuiltinTransports::NONE) + { + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader(TEST_TOPIC_NAME); + + writer.setup_transports(builtin_transports).init(); + ASSERT_FALSE(writer.isInitialized()); + + reader.setup_transports(builtin_transports).init(); + ASSERT_FALSE(reader.isInitialized()); + } + else + { + run_test("", "", "", builtin_transports); + } + } + +private: + + static void run_test( + const std::string& profiles_file, + const std::string& participant_profile, + const std::string& env_var_value, + const BuiltinTransports& builtin_transports) + { + enum class BuiltinTransportsTestCase : uint8_t + { + NONE, + XML, + ENV, + API + }; + + BuiltinTransportsTestCase test_case = BuiltinTransportsTestCase::NONE; + + /* Validate input */ + if (profiles_file != "") + { + ASSERT_NE(participant_profile, ""); + ASSERT_EQ(builtin_transports, BuiltinTransports::NONE); + ASSERT_EQ(env_var_value, ""); + test_case = BuiltinTransportsTestCase::XML; + } + else if (env_var_value != "") + { + ASSERT_EQ(profiles_file, ""); + ASSERT_EQ(participant_profile, ""); + ASSERT_EQ(builtin_transports, BuiltinTransports::NONE); + test_case = BuiltinTransportsTestCase::ENV; + } + else if (builtin_transports != BuiltinTransports::NONE) + { + ASSERT_EQ(profiles_file, ""); + ASSERT_EQ(participant_profile, ""); + ASSERT_EQ(env_var_value, ""); + test_case = BuiltinTransportsTestCase::API; + } + + ASSERT_NE(test_case, BuiltinTransportsTestCase::NONE); + + /* Test configuration */ + PubSubWriter writer(TEST_TOPIC_NAME); + PubSubReader reader(TEST_TOPIC_NAME); + + // Reliable keep all to wait of all acked as end condition + writer.reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS) + .history_kind(eprosima::fastrtps::KEEP_ALL_HISTORY_QOS); + + reader.reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS) + .history_kind(eprosima::fastrtps::KEEP_ALL_HISTORY_QOS); + + // Builtin transport configuration according to test_case + switch (test_case) + { + case BuiltinTransportsTestCase::XML: + { + writer.set_xml_filename(profiles_file); + writer.set_participant_profile(participant_profile); + + reader.set_xml_filename(profiles_file); + reader.set_participant_profile(participant_profile); + break; + } + case BuiltinTransportsTestCase::ENV: + { +#ifdef _WIN32 + _putenv_s(env_var_name_.c_str(), env_var_name_.c_str()); +#else + setenv(env_var_name_.c_str(), env_var_name_.c_str(), 1); +#endif // _WIN32 + break; + } + case BuiltinTransportsTestCase::API: + { + writer.setup_transports(builtin_transports); + reader.setup_transports(builtin_transports); + break; + } + default: + { + FAIL(); + } + } + + /* Run test */ + // Init writer + writer.init(); + ASSERT_TRUE(writer.isInitialized()); + + // Init reader + reader.init(); + ASSERT_TRUE(reader.isInitialized()); + + // Wait for discovery + writer.wait_discovery(); + reader.wait_discovery(); + + // Send data + auto data = default_helloworld_data_generator(); + reader.startReception(data); + writer.send(data); + ASSERT_TRUE(data.empty()); + + // Wait for reception acknowledgement + reader.block_for_all(); + EXPECT_TRUE(writer.waitForAllAcked(std::chrono::seconds(3))); + } + + static const std::string env_var_name_; +}; + +// Static const member of non-integral types cannot be in-class initialized +const std::string BuiltinTransportsTest::env_var_name_ = "FASTDDS_BUILTIN_TRANSPORTS"; + TEST(ChainingTransportTests, basic_test) { bool writer_init_function_called = false; @@ -305,4 +484,130 @@ TEST(ChainingTransportTests, tcp_client_server_with_wan_correct_sender_resources //! is being created ASSERT_LE(times_writer_send_function_called.load(), 30); ASSERT_LE(times_reader_receive_function_called.load(), 30); -} \ No newline at end of file +} + +TEST(ChainingTransportTests, builtin_transports_api_none) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::NONE); +} + +TEST(ChainingTransportTests, builtin_transports_api_default) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::DEFAULT); +} + +TEST(ChainingTransportTests, builtin_transports_api_defaultv6) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::DEFAULTv6); +} + +TEST(ChainingTransportTests, builtin_transports_api_shm) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::SHM); +} + +TEST(ChainingTransportTests, builtin_transports_api_udpv4) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::UDPv4); +} + +TEST(ChainingTransportTests, builtin_transports_api_udpv6) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::UDPv6); +} + +TEST(ChainingTransportTests, builtin_transports_api_large_data) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::LARGE_DATA); +} + +#ifndef __APPLE__ +TEST(ChainingTransportTests, builtin_transports_api_large_datav6) +{ + BuiltinTransportsTest::test_api(BuiltinTransports::LARGE_DATAv6); +} +#endif // __APPLE__ + +TEST(ChainingTransportTests, builtin_transports_env_none) +{ + BuiltinTransportsTest::test_env("NONE"); +} + +TEST(ChainingTransportTests, builtin_transports_env_default) +{ + BuiltinTransportsTest::test_env("DEFAULT"); +} + +TEST(ChainingTransportTests, builtin_transports_env_defaultv6) +{ + BuiltinTransportsTest::test_env("DEFAULTv6"); +} + +TEST(ChainingTransportTests, builtin_transports_env_shm) +{ + BuiltinTransportsTest::test_env("SHM"); +} + +TEST(ChainingTransportTests, builtin_transports_env_udpv4) +{ + BuiltinTransportsTest::test_env("UDPv4"); +} + +TEST(ChainingTransportTests, builtin_transports_env_udpv6) +{ + BuiltinTransportsTest::test_env("UDPv6"); +} + +TEST(ChainingTransportTests, builtin_transports_env_large_data) +{ + BuiltinTransportsTest::test_env("LARGE_DATA"); +} + +#ifndef __APPLE__ +TEST(ChainingTransportTests, builtin_transports_env_large_datav6) +{ + BuiltinTransportsTest::test_env("LARGE_DATAv6"); +} +#endif // __APPLE__ + +TEST(ChainingTransportTests, builtin_transports_xml_none) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_none"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_default) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_default"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_defaultv6) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_defaultv6"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_shm) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_shm"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_udpv4) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_udp"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_udpv6) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_udpv6"); +} + +TEST(ChainingTransportTests, builtin_transports_xml_large_data) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_largedata"); +} + +#ifndef __APPLE__ +TEST(ChainingTransportTests, builtin_transports_xml_large_datav6) +{ + BuiltinTransportsTest::test_xml("builtin_transports_profile.xml", "participant_largedatav6"); +} +#endif // __APPLE__ diff --git a/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h new file mode 100644 index 00000000000..4f7b88551c1 --- /dev/null +++ b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -0,0 +1,597 @@ +// Copyright 2023 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. + +/** + * @file RTPSParticipantAttributes.h + */ + +#ifndef _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ +#define _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace eprosima { +namespace fastdds { +namespace rtps { + +/** + * Struct to define participant types to set participant type parameter property + * @ingroup DISCOVERY_MODULE + */ +struct ParticipantType +{ + static constexpr const char* SIMPLE = "SIMPLE"; + static constexpr const char* SERVER = "SERVER"; + static constexpr const char* CLIENT = "CLIENT"; + static constexpr const char* SUPER_CLIENT = "SUPER_CLIENT"; + static constexpr const char* BACKUP = "BACKUP"; + static constexpr const char* NONE = "NONE"; + static constexpr const char* EXTERNAL = "EXTERNAL"; + static constexpr const char* UNKNOWN = "UNKNOWN"; +}; + +} // namespace rtps +} // namespace fastdds + +namespace fastrtps { +namespace rtps { + +//! PDP subclass choice +typedef enum DiscoveryProtocol +{ + NONE, + /*!< + NO discovery whatsoever would be used. + Publisher and Subscriber defined with the same topic name would NOT be linked. + All matching must be done manually through the addReaderLocator, addReaderProxy, addWriterProxy methods. + */ + SIMPLE, + /*!< + Discovery works according to 'The Real-time Publish-Subscribe Protocol(RTPS) DDS + Interoperability Wire Protocol Specification' + */ + EXTERNAL, + /*!< + A user defined PDP subclass object must be provided in the attributes that deals with the discovery. + Framework is not responsible of this object lifetime. + */ + CLIENT, /*!< The participant will behave as a client concerning discovery operation. + Server locators should be specified as attributes. */ + SERVER, /*!< The participant will behave as a server concerning discovery operation. + Discovery operation is volatile (discovery handshake must take place if shutdown). */ + BACKUP, /*!< The participant will behave as a server concerning discovery operation. + Discovery operation persist on a file (discovery handshake wouldn't repeat if shutdown). */ + SUPER_CLIENT /*!< The participant will behave as a client concerning all internal behaviour. + Remote servers will treat it as a server and will share every discovery information. */ + +} DiscoveryProtocol_t; + +inline std::ostream& operator <<( + std::ostream& output, + const DiscoveryProtocol& discovery_protocol) +{ + switch (discovery_protocol) + { + case DiscoveryProtocol::NONE: + output << fastdds::rtps::ParticipantType::NONE; + break; + case DiscoveryProtocol::SIMPLE: + output << fastdds::rtps::ParticipantType::SIMPLE; + break; + case DiscoveryProtocol::EXTERNAL: + output << fastdds::rtps::ParticipantType::EXTERNAL; + break; + case DiscoveryProtocol::CLIENT: + output << fastdds::rtps::ParticipantType::CLIENT; + break; + case DiscoveryProtocol::SUPER_CLIENT: + output << fastdds::rtps::ParticipantType::SUPER_CLIENT; + break; + case DiscoveryProtocol::SERVER: + output << fastdds::rtps::ParticipantType::SERVER; + break; + case DiscoveryProtocol::BACKUP: + output << fastdds::rtps::ParticipantType::BACKUP; + break; + default: + output << fastdds::rtps::ParticipantType::UNKNOWN; + } + return output; +} + +//! Filtering flags when discovering participants +typedef enum ParticipantFilteringFlags : uint32_t +{ + NO_FILTER = 0, + FILTER_DIFFERENT_HOST = 0x1, + FILTER_DIFFERENT_PROCESS = 0x2, + FILTER_SAME_PROCESS = 0x4 +} ParticipantFilteringFlags_t; + +#define BUILTIN_DATA_MAX_SIZE 512 + +//! PDP factory for EXTERNAL type +class PDP; +class BuiltinProtocols; + +typedef struct _PDPFactory +{ + // Pointer to the PDP creator + PDP* (*CreatePDPInstance)(BuiltinProtocols*); + // Pointer to the PDP destructor + void (* ReleasePDPInstance)( + PDP*); + + bool operator ==( + const struct _PDPFactory& e) const + { + return (CreatePDPInstance == e.CreatePDPInstance) + && (ReleasePDPInstance == e.ReleasePDPInstance); + } + +} PDPFactory; + +/** + * Class SimpleEDPAttributes, to define the attributes of the Simple Endpoint Discovery Protocol. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class SimpleEDPAttributes +{ +public: + + //!Default value true. + bool use_PublicationWriterANDSubscriptionReader; + + //!Default value true. + bool use_PublicationReaderANDSubscriptionWriter; + +#if HAVE_SECURITY + bool enable_builtin_secure_publications_writer_and_subscriptions_reader; + + bool enable_builtin_secure_subscriptions_writer_and_publications_reader; +#endif // if HAVE_SECURITY + + SimpleEDPAttributes() + : use_PublicationWriterANDSubscriptionReader(true) + , use_PublicationReaderANDSubscriptionWriter(true) +#if HAVE_SECURITY + , enable_builtin_secure_publications_writer_and_subscriptions_reader(true) + , enable_builtin_secure_subscriptions_writer_and_publications_reader(true) +#endif // if HAVE_SECURITY + { + } + + bool operator ==( + const SimpleEDPAttributes& b) const + { + return (this->use_PublicationWriterANDSubscriptionReader == b.use_PublicationWriterANDSubscriptionReader) && +#if HAVE_SECURITY + (this->enable_builtin_secure_publications_writer_and_subscriptions_reader == + b.enable_builtin_secure_publications_writer_and_subscriptions_reader) && + (this->enable_builtin_secure_subscriptions_writer_and_publications_reader == + b.enable_builtin_secure_subscriptions_writer_and_publications_reader) && +#endif // if HAVE_SECURITY + (this->use_PublicationReaderANDSubscriptionWriter == b.use_PublicationReaderANDSubscriptionWriter); + } + +}; + +/** + * Struct InitialAnnouncementConfig defines the behavior of the RTPSParticipant initial announcements. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +struct InitialAnnouncementConfig +{ + /// Number of initial announcements with specific period (default 5) + uint32_t count = 5u; + + /// Specific period for initial announcements (default 100ms) + Duration_t period = { 0, 100000000u }; + + bool operator ==( + const InitialAnnouncementConfig& b) const + { + return (count == b.count) && (period == b.period); + } + +}; + +/** + * Class DiscoverySettings, to define the attributes of the several discovery protocols available + * @ingroup RTPS_ATTRIBUTES_MODULE + */ + +class DiscoverySettings +{ +public: + + //! Chosen discovery protocol + DiscoveryProtocol_t discoveryProtocol = DiscoveryProtocol_t::SIMPLE; + + /** + * If set to true, SimpleEDP would be used. + */ + bool use_SIMPLE_EndpointDiscoveryProtocol = true; + + /** + * If set to true, StaticEDP based on an XML file would be implemented. + * The XML filename must be provided. + */ + bool use_STATIC_EndpointDiscoveryProtocol = false; + + /** + * Lease Duration of the RTPSParticipant, + * indicating how much time remote RTPSParticipants should consider this RTPSParticipant alive. + */ + Duration_t leaseDuration = { 20, 0 }; + + /** + * The period for the RTPSParticipant to send its Discovery Message to all other discovered RTPSParticipants + * as well as to all Multicast ports. + */ + Duration_t leaseDuration_announcementperiod = { 3, 0 }; + + //!Initial announcements configuration + InitialAnnouncementConfig initial_announcements; + + //!Attributes of the SimpleEDP protocol + SimpleEDPAttributes m_simpleEDP; + + //! function that returns a PDP object (only if EXTERNAL selected) + PDPFactory m_PDPfactory{}; + /** + * The period for the RTPSParticipant to: + * send its Discovery Message to its servers + * check for EDP endpoints matching + */ + Duration_t discoveryServer_client_syncperiod = { 0, 450 * 1000000}; // 450 milliseconds + + //! Discovery Server settings, only needed if use_CLIENT_DiscoveryProtocol=true + eprosima::fastdds::rtps::RemoteServerList_t m_DiscoveryServers; + + //! Filtering participants out depending on location + ParticipantFilteringFlags_t ignoreParticipantFlags = ParticipantFilteringFlags::NO_FILTER; + + DiscoverySettings() = default; + + bool operator ==( + const DiscoverySettings& b) const + { + return (this->discoveryProtocol == b.discoveryProtocol) && + (this->use_SIMPLE_EndpointDiscoveryProtocol == b.use_SIMPLE_EndpointDiscoveryProtocol) && + (this->use_STATIC_EndpointDiscoveryProtocol == b.use_STATIC_EndpointDiscoveryProtocol) && + (this->discoveryServer_client_syncperiod == b.discoveryServer_client_syncperiod) && + (this->m_PDPfactory == b.m_PDPfactory) && + (this->leaseDuration == b.leaseDuration) && + (this->leaseDuration_announcementperiod == b.leaseDuration_announcementperiod) && + (this->initial_announcements == b.initial_announcements) && + (this->m_simpleEDP == b.m_simpleEDP) && + (this->static_edp_xml_config_ == b.static_edp_xml_config_) && + (this->m_DiscoveryServers == b.m_DiscoveryServers) && + (this->ignoreParticipantFlags == b.ignoreParticipantFlags); + } + + /** + * Get the static endpoint XML filename + * @return Static endpoint XML filename + */ + FASTRTPS_DEPRECATED("Use static_edp_xml_config()") + const char* getStaticEndpointXMLFilename() const + { + return static_edp_xml_config(); + } + + /** + * Set the static endpoint XML filename + * @param str Static endpoint XML filename + * @deprecated + */ + FASTRTPS_DEPRECATED("Use static_edp_xml_config()") + void setStaticEndpointXMLFilename( + const char* str) + { + static_edp_xml_config_ = "file://" + std::string(str); + } + + /** + * Set the static endpoint XML configuration. + * @param str URI specifying the static endpoint XML configuration. + * The string could contain a filename (file://) or the XML content directly (data://). + */ + void static_edp_xml_config( + const char* str) + { + static_edp_xml_config_ = str; + } + + /** + * Get the static endpoint XML configuration. + * @return URI specifying the static endpoint XML configuration. + * The string could contain a filename (file://) or the XML content directly (data://). + */ + const char* static_edp_xml_config() const + { + return static_edp_xml_config_.c_str(); + } + +private: + + //! URI specifying the static EDP XML configuration, only necessary if use_STATIC_EndpointDiscoveryProtocol=true + //! This string could contain a filename or the XML content directly. + std::string static_edp_xml_config_ = ""; +}; + +/** + * TypeLookupService settings. + */ +class TypeLookupSettings +{ +public: + + //!Indicates to use the TypeLookup Service client endpoints + bool use_client = false; + + //!Indicates to use the TypeLookup Service server endpoints + bool use_server = false; + +}; + +/** + * Class BuiltinAttributes, to define the behavior of the RTPSParticipant builtin protocols. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class BuiltinAttributes +{ +public: + + //! Discovery protocol related attributes + DiscoverySettings discovery_config; + + //! Indicates to use the WriterLiveliness protocol. + bool use_WriterLivelinessProtocol = true; + + //! TypeLookup Service settings + TypeLookupSettings typelookup_config; + + //! Metatraffic Unicast Locator List + LocatorList_t metatrafficUnicastLocatorList; + + //! Metatraffic Multicast Locator List. + LocatorList_t metatrafficMulticastLocatorList; + + //! Initial peers. + LocatorList_t initialPeersList; + + //! Memory policy for builtin readers + MemoryManagementPolicy_t readerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin readers + uint32_t readerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Memory policy for builtin writers + MemoryManagementPolicy_t writerHistoryMemoryPolicy = + MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; + + //! Maximum payload size for builtin writers + uint32_t writerPayloadSize = BUILTIN_DATA_MAX_SIZE; + + //! Mutation tries if the port is being used. + uint32_t mutation_tries = 100u; + + //! Set to true to avoid multicast traffic on builtin endpoints + bool avoid_builtin_multicast = true; + + BuiltinAttributes() = default; + + virtual ~BuiltinAttributes() = default; + + bool operator ==( + const BuiltinAttributes& b) const + { + return (this->discovery_config == b.discovery_config) && + (this->use_WriterLivelinessProtocol == b.use_WriterLivelinessProtocol) && + (typelookup_config.use_client == b.typelookup_config.use_client) && + (typelookup_config.use_server == b.typelookup_config.use_server) && + (this->metatrafficUnicastLocatorList == b.metatrafficUnicastLocatorList) && + (this->metatrafficMulticastLocatorList == b.metatrafficMulticastLocatorList) && + (this->initialPeersList == b.initialPeersList) && + (this->readerHistoryMemoryPolicy == b.readerHistoryMemoryPolicy) && + (this->readerPayloadSize == b.readerPayloadSize) && + (this->writerHistoryMemoryPolicy == b.writerHistoryMemoryPolicy) && + (this->writerPayloadSize == b.writerPayloadSize) && + (this->mutation_tries == b.mutation_tries) && + (this->avoid_builtin_multicast == b.avoid_builtin_multicast); + } + +}; + +/** + * Class RTPSParticipantAttributes used to define different aspects of a RTPSParticipant. + * @ingroup RTPS_ATTRIBUTES_MODULE + */ +class RTPSParticipantAttributes +{ + using FlowControllerDescriptorList = std::vector>; + +public: + + RTPSParticipantAttributes() = default; + + virtual ~RTPSParticipantAttributes() = default; + + bool operator ==( + const RTPSParticipantAttributes& b) const + { + return (this->name == b.name) && + (this->defaultUnicastLocatorList == b.defaultUnicastLocatorList) && + (this->defaultMulticastLocatorList == b.defaultMulticastLocatorList) && + (this->ignore_non_matching_locators == b.ignore_non_matching_locators) && + (this->sendSocketBufferSize == b.sendSocketBufferSize) && + (this->listenSocketBufferSize == b.listenSocketBufferSize) && + (this->builtin == b.builtin) && + (this->port == b.port) && + (this->userData == b.userData) && + (this->participantID == b.participantID) && + (this->throughputController == b.throughputController) && + (this->useBuiltinTransports == b.useBuiltinTransports) && + (this->properties == b.properties) && + (this->prefix == b.prefix) && + (this->flow_controllers == b.flow_controllers); + + } + + /** + * Provides a way of easily configuring transport related configuration on certain pre-defined scenarios. + * + * @param transports Defines the transport configuration scenario to setup. + */ + void setup_transports( + fastdds::rtps::BuiltinTransports /*transports*/) + { + // Only include UDPv4 behavior for mock tests + setup_transports_default(*this); + useBuiltinTransports = false; + } + + static void setup_transports_default( + RTPSParticipantAttributes& att) + { + auto descriptor = create_udpv4_transport(att); + + att.userTransports.push_back(descriptor); + } + + static std::shared_ptr create_udpv4_transport( + const RTPSParticipantAttributes& att) + { + auto descriptor = std::make_shared(); + descriptor->sendBufferSize = att.sendSocketBufferSize; + descriptor->receiveBufferSize = att.listenSocketBufferSize; + + return descriptor; + } + + /** + * Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case + * that it was defined with NO UnicastLocators. At least ONE locator should be included in this list. + */ + LocatorList_t defaultUnicastLocatorList; + + /** + * Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the + * case that it was defined with NO MulticastLocators. This is usually left empty. + */ + LocatorList_t defaultMulticastLocatorList; + + /** + * Whether locators that don't match with the announced locators should be kept. + */ + bool ignore_non_matching_locators = false; + + /*! + * @brief Send socket buffer size for the send resource. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t sendSocketBufferSize = 0; + + /*! Listen socket buffer for all listen resources. Zero value indicates to use default system buffer size. + * Default value: 0. + */ + uint32_t listenSocketBufferSize = 0; + + //! Optionally allows user to define the GuidPrefix_t + GuidPrefix_t prefix; + + RTPS_DllAPI inline bool ReadguidPrefix( + const char* pfx) + { + return bool(std::istringstream(pfx) >> prefix); + } + + //! Builtin parameters. + BuiltinAttributes builtin; + + //! Port Parameters + PortParameters port; + + //! User Data of the participant + std::vector userData; + + //! Participant ID + int32_t participantID = -1; + + /** + * @brief Throughput controller parameters. Leave default for uncontrolled flow. + * + * @deprecated Use flow_controllers on RTPSParticipantAttributes + */ + ThroughputControllerDescriptor throughputController; + + //! User defined transports to use alongside or in place of builtins. + std::vector> userTransports; + + //! Set as false to disable the creation of the default transports. + bool useBuiltinTransports = true; + + //! Holds allocation limits affecting collections managed by a participant. + RTPSParticipantAllocationAttributes allocation; + + //! Property policies + PropertyPolicy properties; + + //! Set the name of the participant. + inline void setName( + const char* nam) + { + name = nam; + } + + //! Get the name of the participant. + inline const char* getName() const + { + return name.c_str(); + } + + //! Flow controllers. + FlowControllerDescriptorList flow_controllers; + +private: + + //! Name of the participant. + string_255 name{"RTPSParticipant"}; +}; + +} // namespace rtps +} // namespace fastrtps +} // namespace eprosima + +#endif // _FASTDDS_RTPSPARTICIPANTPARAMETERS_H_ diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index 4948b39e542..e887e30b159 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -47,6 +47,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -63,6 +68,13 @@ #include "../../common/GTestPrinters.hpp" #include "../../logging/mock/MockConsumer.h" +#if defined(_WIN32) +#define GET_PID _getpid +#else +#define GET_PID getpid +#include +#endif // if defined(_WIN32) + namespace eprosima { namespace fastdds { namespace dds { @@ -79,7 +91,6 @@ using fastrtps::types::TypeDescriptor; using fastrtps::xmlparser::XMLP_ret; using fastrtps::xmlparser::XMLProfileManager; - // Mocked TopicDataType for Topic creation tests class TopicDataTypeMock : public TopicDataType { @@ -3551,6 +3562,227 @@ TEST(ParticipantTests, UnsupportedMethods) ASSERT_EQ(DomainParticipantFactory::get_instance()->delete_participant(participant), ReturnCode_t::RETCODE_OK); } +TEST(ParticipantTests, ParticipantCreationWithBuiltinTransport) +{ + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::DEFAULT); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + return true; + } + } + return false; + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::DEFAULTv6); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + return true; + } + } + return false; + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::SHM); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + return true; + } + } + return false; + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::UDPv4); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + return true; + } + } + return false; + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::UDPv6); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + return true; + } + } + return false; + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::LARGE_DATA); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + bool hasSHM = false; + bool hasUDP = false; + bool hasTCP = false; + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasSHM = true; + } + else if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasUDP = true; + } + else if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasTCP = true; + } + } + + return (hasSHM && hasUDP && hasTCP); + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } + + { + DomainParticipantQos qos; + fastrtps::rtps::RTPSParticipantAttributes attributes_; + qos.setup_transports(rtps::BuiltinTransports::LARGE_DATAv6); + + DomainParticipant* participant_ = DomainParticipantFactory::get_instance()->create_participant( + (uint32_t)GET_PID() % 230, qos); + ASSERT_NE(nullptr, participant_); + + get_rtps_attributes(participant_, attributes_); + + auto transport_check = [](fastrtps::rtps::RTPSParticipantAttributes& attributes_) -> bool + { + bool hasSHM = false; + bool hasUDP = false; + bool hasTCP = false; + for (auto& transportDescriptor : attributes_.userTransports) + { + if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasSHM = true; + } + else if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasUDP = true; + } + else if ( nullptr != + dynamic_cast(transportDescriptor.get())) + { + hasTCP = true; + } + } + + return (hasSHM && hasUDP && hasTCP); + }; + EXPECT_TRUE(transport_check(attributes_)); + EXPECT_FALSE(attributes_.useBuiltinTransports); + } +} + } // namespace dds } // namespace fastdds } // namespace eprosima diff --git a/test/unittest/dds/publisher/CMakeLists.txt b/test/unittest/dds/publisher/CMakeLists.txt index 953469ae0a7..a554cc8063d 100644 --- a/test/unittest/dds/publisher/CMakeLists.txt +++ b/test/unittest/dds/publisher/CMakeLists.txt @@ -92,6 +92,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/TopicImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/TypeSupport.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/qos/TopicQos.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/utils/QosConverters.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastrtps_deprecated/subscriber/SubscriberHistory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/PropertyPolicy.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/builtin/BuiltinProtocols.cpp @@ -141,6 +142,7 @@ set(DATAWRITERTESTS_SOURCE DataWriterTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/participant/RTPSParticipant.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/participant/RTPSParticipantImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/persistence/PersistenceFactory.cpp diff --git a/test/unittest/dds/status/CMakeLists.txt b/test/unittest/dds/status/CMakeLists.txt index 7afa0ccdc09..2c848d3a802 100644 --- a/test/unittest/dds/status/CMakeLists.txt +++ b/test/unittest/dds/status/CMakeLists.txt @@ -59,6 +59,7 @@ set(LISTENERTESTS_SOURCE ListenerTests.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/log/FileConsumer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/PropertyPolicy.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/common/Time_t.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/utils/QosConverters.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/ThroughputControllerDescriptor.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/FlowControllerConsts.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/history/CacheChangePool.cpp @@ -149,6 +150,7 @@ target_include_directories(ListenerTests PRIVATE ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSWriter ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSDomain ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSDomainImpl + ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantAttributes ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipant ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantImpl ${PROJECT_SOURCE_DIR}/test/mock/rtps/Endpoint diff --git a/test/unittest/dynamic_types/CMakeLists.txt b/test/unittest/dynamic_types/CMakeLists.txt index ebe7cce3ec9..ad9ce52a5c3 100644 --- a/test/unittest/dynamic_types/CMakeLists.txt +++ b/test/unittest/dynamic_types/CMakeLists.txt @@ -106,15 +106,17 @@ target_compile_definitions(DynamicTypesTests PRIVATE ) target_include_directories(DynamicTypesTests PRIVATE ${Asio_INCLUDE_DIR} + ${PROJECT_SOURCE_DIR}/test/mock/rtps/SharedMemTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv6TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv6TransportDescriptor - ${PROJECT_SOURCE_DIR}/test/mock/rtps/SharedMemTransportDescriptor + ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantAttributes $<$:${TINYXML2_INCLUDE_DIR}> ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/src/cpp ) target_link_libraries(DynamicTypesTests GTest::gtest $<$:iphlpapi$Shlwapi> diff --git a/test/unittest/statistics/dds/CMakeLists.txt b/test/unittest/statistics/dds/CMakeLists.txt index e251ac72421..ba02a7e07df 100644 --- a/test/unittest/statistics/dds/CMakeLists.txt +++ b/test/unittest/statistics/dds/CMakeLists.txt @@ -142,6 +142,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS) ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/TopicImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/TypeSupport.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/topic/qos/TopicQos.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/utils/QosConverters.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/PropertyPolicy.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/builtin/BuiltinProtocols.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/builtin/data/ParticipantProxyData.cpp @@ -190,6 +191,7 @@ if (SQLITE3_SUPPORT AND FASTDDS_STATISTICS) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/messages/SendBuffersManager.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/NetworkFactory.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/network/ReceiverResource.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/participant/RTPSParticipant.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/participant/RTPSParticipantImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/persistence/PersistenceFactory.cpp diff --git a/test/unittest/xmlparser/CMakeLists.txt b/test/unittest/xmlparser/CMakeLists.txt index ab05dab43e5..0676b3a2d04 100644 --- a/test/unittest/xmlparser/CMakeLists.txt +++ b/test/unittest/xmlparser/CMakeLists.txt @@ -135,7 +135,9 @@ target_include_directories(XMLProfileParserTests PRIVATE ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv6TransportDescriptor + ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantAttributes ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/src/cpp ${Asio_INCLUDE_DIR} ) @@ -213,15 +215,17 @@ target_compile_definitions(XMLParserTests PRIVATE $<$:__INTERNALDEBUG> # Internal debug activated. ) target_include_directories(XMLParserTests PRIVATE + ${PROJECT_SOURCE_DIR}/test/mock/rtps/SharedMemTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv6TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv6TransportDescriptor - ${PROJECT_SOURCE_DIR}/test/mock/rtps/SharedMemTransportDescriptor + ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantAttributes ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/src/cpp ${Asio_INCLUDE_DIR} ) @@ -333,6 +337,7 @@ target_include_directories(XMLEndpointParserTests PRIVATE ${PROJECT_SOURCE_DIR}/test/mock/rtps/WriterProxyData ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include + ${PROJECT_SOURCE_DIR}/src/cpp ${Asio_INCLUDE_DIR} ) diff --git a/test/unittest/xmlparser/XMLElementParserTests.cpp b/test/unittest/xmlparser/XMLElementParserTests.cpp index 098aaa1c6e1..7c3cf6ffd49 100644 --- a/test/unittest/xmlparser/XMLElementParserTests.cpp +++ b/test/unittest/xmlparser/XMLElementParserTests.cpp @@ -467,8 +467,8 @@ TEST_F(XMLParserTests, getXMLLocatorTCPv4) * 1. Correct parsing of a valid element. * 2. Check an empty definition of . * 3. Check an empty definition of . - * 5. Check an empty definition of
. - * 6. Check an bad element as a child xml element. + * 4. Check an empty definition of
. + * 5. Check an bad element as a child xml element. */ TEST_F(XMLParserTests, getXMLLocatorTCPv6) { @@ -537,8 +537,8 @@ TEST_F(XMLParserTests, getXMLLocatorTCPv6) * 1. Correct parsing of a valid descriptor present in the XmlProfileManager. * 2. Check a reference to a non existentTransportDescriptorInterface. * 3. Check an empty definition of . - * 5. Check an empty definition of . - * 6. Check an empty list of transports. + * 4. Check an empty definition of . + * 5. Check an empty list of transports. */ TEST_F(XMLParserTests, getXMLTransports) { @@ -602,14 +602,70 @@ TEST_F(XMLParserTests, getXMLTransports) xmlparser::XMLProfileManager::DeleteInstance(); } +/* + * This test checks the proper parsing of the xml elements and negative cases. + * 1. Correct parsing of all valid values of BuiltinTransport. + * 2. Check a wrong definition of . + * 3. Check an empty definition of . + */ +TEST_F(XMLParserTests, getXMLbuiltinTransports) +{ + uint8_t ident = 1; + eprosima::fastdds::rtps::BuiltinTransports bt; + tinyxml2::XMLDocument xml_doc; + tinyxml2::XMLElement* titleElement; + + // Parametrized XML + const char* xml_p = + "\ + %s\ + "; + constexpr size_t xml_len {500}; + char xml[xml_len]; + + // Valid XML + std::vector bt_list; + bt_list.push_back("NONE"); + bt_list.push_back("DEFAULT"); + bt_list.push_back("DEFAULTv6"); + bt_list.push_back("SHM"); + bt_list.push_back("UDPv4"); + bt_list.push_back("UDPv6"); + bt_list.push_back("LARGE_DATA"); + bt_list.push_back("LARGE_DATAv6"); + + for (auto test_transport : bt_list) + { + snprintf(xml, xml_len, xml_p, test_transport.c_str()); + ASSERT_EQ(tinyxml2::XMLError::XML_SUCCESS, xml_doc.Parse(xml)); + titleElement = xml_doc.RootElement(); + ASSERT_EQ(XMLP_ret::XML_OK, XMLParserTest::getXMLBuiltinTransports_wrapper(titleElement, &bt, ident)); + } + + // Wrong ID + snprintf(xml, xml_len, xml_p, "WrongBuiltinTransport"); + ASSERT_EQ(tinyxml2::XMLError::XML_SUCCESS, xml_doc.Parse(xml)); + titleElement = xml_doc.RootElement(); + ASSERT_EQ(XMLP_ret::XML_ERROR, XMLParserTest::getXMLBuiltinTransports_wrapper(titleElement, &bt, ident)); + + // Missing data + snprintf(xml, xml_len, xml_p, ""); + ASSERT_EQ(tinyxml2::XMLError::XML_SUCCESS, xml_doc.Parse(xml)); + titleElement = xml_doc.RootElement(); + ASSERT_EQ(XMLP_ret::XML_ERROR, XMLParserTest::getXMLBuiltinTransports_wrapper(titleElement, &bt, ident)); + + // Clean up + xmlparser::XMLProfileManager::DeleteInstance(); +} + /* * This test checks the proper parsing of the xml elements to a PropertyPolicy object, and negative * cases. * 1. Correct parsing of a valid . * 2. Check missing values for the possible elemnts of the properties. * 3. Check an empty list of . - * 5. Check an empty list of . - * 6. Check an wrong descriptor for properties. + * 4. Check an empty list of . + * 5. Check an wrong descriptor for properties. */ TEST_F(XMLParserTests, getXMLPropertiesPolicy) { diff --git a/test/unittest/xmlparser/wrapper/XMLParserTest.hpp b/test/unittest/xmlparser/wrapper/XMLParserTest.hpp index ba7525e9047..2e783109b3c 100644 --- a/test/unittest/xmlparser/wrapper/XMLParserTest.hpp +++ b/test/unittest/xmlparser/wrapper/XMLParserTest.hpp @@ -134,6 +134,14 @@ class XMLParserTest : public XMLParser return getXMLTransports(elem, transports, ident); } + static XMLP_ret getXMLBuiltinTransports_wrapper( + tinyxml2::XMLElement* elem, + eprosima::fastdds::rtps::BuiltinTransports* bt, + uint8_t ident) + { + return getXMLBuiltinTransports(elem, bt, ident); + } + static XMLP_ret getXMLguidPrefix_wrapper( tinyxml2::XMLElement* elem, GuidPrefix_t& prefix, diff --git a/versions.md b/versions.md index 886b1fec140..53d1aa4efdf 100644 --- a/versions.md +++ b/versions.md @@ -1,6 +1,11 @@ Forthcoming ----------- +* Added the possibility to define a listening port equal to 0 in TCP Transport +* Added support for TCP to Fast DDS CLI and environment variable +* Added configuration of builtin transports through DomainParticipantQos, environment + variable and XML. + Version 2.6.6 -------------