diff --git a/include/fastdds/dds/domain/DomainParticipantListener.hpp b/include/fastdds/dds/domain/DomainParticipantListener.hpp index 0aceab58e1f..9455729d6e5 100644 --- a/include/fastdds/dds/domain/DomainParticipantListener.hpp +++ b/include/fastdds/dds/domain/DomainParticipantListener.hpp @@ -100,26 +100,9 @@ class DomainParticipantListener : * * @param[out] participant Pointer to the Participant which discovered the remote DataReader. * @param[out] info Remote DataReader information. User can take ownership of the object. - */ - virtual void on_subscriber_discovery( - DomainParticipant* participant, - fastrtps::rtps::ReaderDiscoveryInfo&& info) - { - static_cast(participant); - static_cast(info); - } - - /*! - * This method is called when a new DataReader is discovered, or a previously discovered DataReader changes - * its QOS or is removed. - * - * @warning Not Supported. This callback will never be called in the current version. - * - * @param[out] participant Pointer to the Participant which discovered the remote DataReader. - * @param[out] info Remote DataReader information. User can take ownership of the object. * @param[out] should_be_ignored Flag to indicate the library to automatically ignore the discovered DataReader. */ - virtual void on_subscriber_discovery( + virtual void on_data_reader_discovery( DomainParticipant* participant, fastrtps::rtps::ReaderDiscoveryInfo&& info, bool& should_be_ignored) @@ -135,26 +118,9 @@ class DomainParticipantListener : * * @param[out] participant Pointer to the Participant which discovered the remote DataWriter. * @param[out] info Remote DataWriter information. User can take ownership of the object. - */ - virtual void on_publisher_discovery( - DomainParticipant* participant, - fastrtps::rtps::WriterDiscoveryInfo&& info) - { - static_cast(participant); - static_cast(info); - } - - /*! - * This method is called when a new DataWriter is discovered, or a previously discovered DataWriter changes - * its QOS or is removed. - * - * @warning Not Supported. This callback will never be called in the current version. - * - * @param[out] participant Pointer to the Participant which discovered the remote DataWriter. - * @param[out] info Remote DataWriter information. User can take ownership of the object. * @param[out] should_be_ignored Flag to indicate the library to automatically ignore the discovered DataWriter. */ - virtual void on_publisher_discovery( + virtual void on_data_writer_discovery( DomainParticipant* participant, fastrtps::rtps::WriterDiscoveryInfo&& info, bool& should_be_ignored) diff --git a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp index b463aa03e0c..9fdb758501a 100644 --- a/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp +++ b/include/fastdds/dds/domain/qos/DomainParticipantQos.hpp @@ -86,6 +86,7 @@ class DomainParticipantQos (this->builtin_controllers_sender_thread_ == b.builtin_controllers_sender_thread()) && (this->timed_events_thread_ == b.timed_events_thread()) && (this->discovery_server_thread_ == b.discovery_server_thread()) && + (this->typelookup_service_thread_ == b.typelookup_service_thread()) && #if HAVE_SECURITY (this->security_log_thread_ == b.security_log_thread()) && #endif // if HAVE_SECURITY @@ -433,6 +434,37 @@ class DomainParticipantQos discovery_server_thread_ = value; } + /** + * Getter for TypeLookup service ThreadSettings + * + * @return rtps::ThreadSettings reference + */ + rtps::ThreadSettings& typelookup_service_thread() + { + return typelookup_service_thread_; + } + + /** + * Getter for TypeLookup service ThreadSettings + * + * @return rtps::ThreadSettings reference + */ + const rtps::ThreadSettings& typelookup_service_thread() const + { + return typelookup_service_thread_; + } + + /** + * Setter for the TypeLookup service ThreadSettings + * + * @param value New ThreadSettings to be set + */ + void typelookup_service_thread( + const rtps::ThreadSettings& value) + { + typelookup_service_thread_ = value; + } + #if HAVE_SECURITY /** * Getter for security log ThreadSettings @@ -505,6 +537,9 @@ class DomainParticipantQos //! Thread settings for the discovery server thread rtps::ThreadSettings discovery_server_thread_; + //! Thread settings for the builtin TypeLookup service requests and replies threads + rtps::ThreadSettings typelookup_service_thread_; + #if HAVE_SECURITY //! Thread settings for the security log thread rtps::ThreadSettings security_log_thread_; diff --git a/include/fastdds/dds/log/Log.hpp b/include/fastdds/dds/log/Log.hpp index 9f2cc0f819a..51c9bb68b02 100644 --- a/include/fastdds/dds/log/Log.hpp +++ b/include/fastdds/dds/log/Log.hpp @@ -282,17 +282,18 @@ class LogConsumer // Name of variables inside macros must be unique, or it could produce an error with external variables #if !HAVE_LOG_NO_ERROR -#define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \ +#define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \ do { \ - using namespace eprosima::fastdds::dds; \ std::stringstream fastdds_log_ss_tmp__; \ fastdds_log_ss_tmp__ << msg; \ - Log::QueueLog(fastdds_log_ss_tmp__.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Error); \ + eprosima::fastdds::dds::Log::QueueLog( \ + fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \ + eprosima::fastdds::dds::Log::Kind::Error); \ } while (0) #elif (__INTERNALDEBUG || _INTERNALDEBUG) -#define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \ +#define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \ do { \ auto fastdds_log_lambda_tmp__ = [&]() \ { \ @@ -312,21 +313,21 @@ class LogConsumer ***********/ #if !HAVE_LOG_NO_WARNING -#define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \ - do { \ - using namespace eprosima::fastdds::dds; \ - if (Log::GetVerbosity() >= Log::Kind::Warning) \ - { \ - std::stringstream fastdds_log_ss_tmp__; \ - fastdds_log_ss_tmp__ << msg; \ - Log::QueueLog( \ - fastdds_log_ss_tmp__.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Warning); \ - } \ +#define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \ + do { \ + if (eprosima::fastdds::dds::Log::GetVerbosity() >= eprosima::fastdds::dds::Log::Kind::Warning) \ + { \ + std::stringstream fastdds_log_ss_tmp__; \ + fastdds_log_ss_tmp__ << msg; \ + eprosima::fastdds::dds::Log::QueueLog( \ + fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \ + eprosima::fastdds::dds::Log::Kind::Warning); \ + } \ } while (0) #elif (__INTERNALDEBUG || _INTERNALDEBUG) -#define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \ +#define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \ do { \ auto fastdds_log_lambda_tmp__ = [&]() \ { \ @@ -351,16 +352,16 @@ class LogConsumer ((defined(__INTERNALDEBUG) || defined(_INTERNALDEBUG)) && (defined(_DEBUG) || defined(__DEBUG) || \ !defined(NDEBUG)))) -#define EPROSIMA_LOG_INFO_IMPL_(cat, msg) \ - do { \ - using namespace eprosima::fastdds::dds; \ - if (Log::GetVerbosity() >= Log::Kind::Info) \ - { \ - std::stringstream fastdds_log_ss_tmp__; \ - fastdds_log_ss_tmp__ << msg; \ - Log::QueueLog(fastdds_log_ss_tmp__.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, \ - Log::Kind::Info); \ - } \ +#define EPROSIMA_LOG_INFO_IMPL_(cat, msg) \ + do { \ + if (eprosima::fastdds::dds::Log::GetVerbosity() >= eprosima::fastdds::dds::Log::Kind::Info) \ + { \ + std::stringstream fastdds_log_ss_tmp__; \ + fastdds_log_ss_tmp__ << msg; \ + eprosima::fastdds::dds::Log::QueueLog( \ + fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \ + eprosima::fastdds::dds::Log::Kind::Info); \ + } \ } while (0) #elif (__INTERNALDEBUG || _INTERNALDEBUG) diff --git a/include/fastdds/dds/xtypes/common.hpp b/include/fastdds/dds/xtypes/common.hpp index 3001d6120f4..3a2032fb38b 100644 --- a/include/fastdds/dds/xtypes/common.hpp +++ b/include/fastdds/dds/xtypes/common.hpp @@ -13,7 +13,7 @@ // limitations under the License. /*! - * @file + * @file common.hpp * This file contains common definitions for the different XTypes modules. */ @@ -43,8 +43,8 @@ enum class TryConstructKind : uint32_t TRIM }; -/** - * @brief PlacementKind values (@verbatim annotation) +/*! + * @brief PlacementKind values (verbatim annotation) */ enum class PlacementKind : uint32_t { diff --git a/include/fastdds/dds/xtypes/dynamic_types/AnnotationDescriptor.hpp b/include/fastdds/dds/xtypes/dynamic_types/AnnotationDescriptor.hpp index 5eaef141de7..781bed34cf9 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/AnnotationDescriptor.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/AnnotationDescriptor.hpp @@ -45,7 +45,7 @@ class FASTDDS_EXPORTED_API AnnotationDescriptor /*! * Modifies the underlying type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void type( traits::ref_type type) = 0; diff --git a/include/fastdds/dds/xtypes/dynamic_types/DynamicData.hpp b/include/fastdds/dds/xtypes/dynamic_types/DynamicData.hpp index 6aefb983224..d1c29039eb3 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/DynamicData.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/DynamicData.hpp @@ -168,7 +168,7 @@ class DynamicData : public std::enable_shared_from_this /*! * Retrieves an \b int32 value associated to an identifier. * @param[inout] value \b int32 to populate - * @param[in] Id identifier of the member to query. + * @param[in] id identifier of the member to query. * @return @ref ReturnCode_t * @retval RETCODE_OK when the value was retrieved successfully. * @retval RETCODE_BAD_PARAMETER when the @ref MemberId is invalid or the member type is not promotable to \b int32. @@ -516,7 +516,7 @@ class DynamicData : public std::enable_shared_from_this /*! * Sets an \b bool value associated to an identifier - * @param[in] Id identifier of the member to set. + * @param[in] id identifier of the member to set. * @param[in] value \b bool to set. * @return @ref ReturnCode_t * @retval RETCODE_OK when the value was set successfully. diff --git a/include/fastdds/dds/xtypes/dynamic_types/DynamicDataFactory.hpp b/include/fastdds/dds/xtypes/dynamic_types/DynamicDataFactory.hpp index a1dc29fcc77..688363347e8 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/DynamicDataFactory.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/DynamicDataFactory.hpp @@ -57,7 +57,7 @@ class DynamicDataFactory : public std::enable_shared_from_this /*! * Returns the member that corresponds to the specified name. * @param[inout] member @ref DynamicTypeMember reference used to return the reference to the member. + * @param[in] name Member name of the member being queried. * @return @ref ReturnCode_t * @retval RETCODE_OK when the member was found. * @retval RETCODE_BAD_PARAMETER when the member doesn't exist. @@ -154,7 +155,7 @@ class DynamicType : public std::enable_shared_from_this /** * State comparison according with the [standard] sections \b 7.5.2.8.4 - * @param[in] other @DynamicType reference to compare to + * @param[in] other @ref DynamicType reference to compare to * @return \b bool `true` on equality */ FASTDDS_EXPORTED_API virtual bool equals( diff --git a/include/fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilder.hpp b/include/fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilder.hpp index 9ea32a56ecf..dcda644b415 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilder.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/DynamicTypeBuilder.hpp @@ -70,7 +70,7 @@ class DynamicTypeBuilder : public std::enable_shared_from_this::ref_type type) = 0; /*! - * Creates a new @ref DynamicTypeBuilder reference based on the given @ref TypeObject instance. - * @param[in] type_object @ref TypeObject instance to be used. + * Creates a new @ref DynamicTypeBuilder reference based on the given @ref xtypes::TypeObject instance. + * @param[in] type_object @ref xtypes::TypeObject instance to be used. * @return New @ref DynamicTypeBuilder reference. Nil reference returned in error case. */ FASTDDS_EXPORTED_API virtual traits::ref_type create_type_w_type_object( @@ -117,7 +117,7 @@ class DynamicTypeBuilderFactory : public std::enable_shared_from_this::ref_type create_array_type( @@ -126,8 +126,8 @@ class DynamicTypeBuilderFactory : public std::enable_shared_from_this /** * State comparison according with the [standard] sections \b 7.5.2.6.3 - * @param[in] other @DynamicTypeMember reference to compare to + * @param[in] other @ref DynamicTypeMember reference to compare to * @return \b bool `true` on equality */ FASTDDS_EXPORTED_API virtual bool equals( diff --git a/include/fastdds/dds/xtypes/dynamic_types/MemberDescriptor.hpp b/include/fastdds/dds/xtypes/dynamic_types/MemberDescriptor.hpp index a39a03fceb8..9c6f7b111ee 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/MemberDescriptor.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/MemberDescriptor.hpp @@ -75,7 +75,7 @@ class FASTDDS_EXPORTED_API MemberDescriptor /*! * Modifies the underlying @ref MemberId. - * @param[in] @ref MemberId to be set. + * @param[in] id @ref MemberId to be set. */ virtual void id( MemberId id) = 0; @@ -94,7 +94,7 @@ class FASTDDS_EXPORTED_API MemberDescriptor /*! * Modifies the underlying member's type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void type( traits::ref_type type) = 0; @@ -151,14 +151,14 @@ class FASTDDS_EXPORTED_API MemberDescriptor /*! * Modifies the labels the member belongs to by copy. - * @param[in] @ref UnionCaseLabelSeq + * @param[in] label @ref UnionCaseLabelSeq */ virtual void label( const UnionCaseLabelSeq& label) = 0; /*! * Modifies the labels the member belongs to by move. - * @param[in] @ref UnionCaseLabelSeq + * @param[in] label @ref UnionCaseLabelSeq */ virtual void label( UnionCaseLabelSeq&& label) = 0; diff --git a/include/fastdds/dds/xtypes/dynamic_types/TypeDescriptor.hpp b/include/fastdds/dds/xtypes/dynamic_types/TypeDescriptor.hpp index f5512402c26..b7a5b10b6d7 100644 --- a/include/fastdds/dds/xtypes/dynamic_types/TypeDescriptor.hpp +++ b/include/fastdds/dds/xtypes/dynamic_types/TypeDescriptor.hpp @@ -48,7 +48,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying @ref TypeKind. - * @param[in] @ref TypeKind to be set. + * @param[in] kind @ref TypeKind to be set. */ virtual void kind( TypeKind kind) = 0; @@ -93,7 +93,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying base type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void base_type( traits::ref_type type) = 0; @@ -112,7 +112,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying discriminator type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void discriminator_type( traits::ref_type type) = 0; @@ -131,14 +131,14 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying bound by copy. - * @param[in] @ref BoundSeq + * @param[in] bound @ref BoundSeq */ virtual void bound( const BoundSeq& bound) = 0; /*! * Modifies the underlying bound by move. - * @param[in] @ref BoundSeq + * @param[in] bound @ref BoundSeq */ virtual void bound( BoundSeq&& bound) = 0; @@ -157,7 +157,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying element type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void element_type( traits::ref_type type) = 0; @@ -176,7 +176,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the underlying key element type reference. - * @param[in] @ref DynamicType reference. + * @param[in] type @ref DynamicType reference. */ virtual void key_element_type( traits::ref_type type) = 0; @@ -196,7 +196,7 @@ class FASTDDS_EXPORTED_API TypeDescriptor /*! * Modifies the extensibility kind. - * @param[in] @ref ExtensibilityKind + * @param[in] extensibility_kind @ref ExtensibilityKind */ virtual void extensibility_kind( ExtensibilityKind extensibility_kind) = 0; @@ -214,8 +214,8 @@ class FASTDDS_EXPORTED_API TypeDescriptor virtual bool& is_nested() = 0; /*! - * Mofifies the is_nested property. - * @param[in] Boolean + * Modifies the is_nested property. + * @param[in] is_nested Boolean value to be set. */ virtual void is_nested( bool is_nested) = 0; diff --git a/include/fastdds/dds/xtypes/type_representation/TypeObject.hpp b/include/fastdds/dds/xtypes/type_representation/TypeObject.hpp index af46c4f8dbe..3be6383ca03 100644 --- a/include/fastdds/dds/xtypes/type_representation/TypeObject.hpp +++ b/include/fastdds/dds/xtypes/type_representation/TypeObject.hpp @@ -13,7 +13,7 @@ // limitations under the License. /*! - * @file TypeObject.h + * @file TypeObject.hpp * This header file contains the declaration of the described types in the IDL file. * * This file was generated by the tool fastddsgen. diff --git a/include/fastdds/dds/xtypes/type_representation/TypeObjectUtils.hpp b/include/fastdds/dds/xtypes/type_representation/TypeObjectUtils.hpp index ebc37899b0d..960bd72b36a 100644 --- a/include/fastdds/dds/xtypes/type_representation/TypeObjectUtils.hpp +++ b/include/fastdds/dds/xtypes/type_representation/TypeObjectUtils.hpp @@ -53,7 +53,7 @@ class TypeObjectUtils * * @param[in] discriminator TypeObjectHashId discriminator to be set. * @param[in] hash StronglyConnectedComponent equivalence hash to be set. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given discriminator is not + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given discriminator is not * EK_COMPLETE/EK_MINIMAL. * @return const TypeObjectHashId instance. */ @@ -80,7 +80,7 @@ class TypeObjectUtils * @param[in] must_understand must_understand annotation value. * @param[in] key key annotation value. * @param[in] external external annotation value. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if both key and optional flags are + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if both key and optional flags are * enabled. * @return StructMemberFlag instance. */ @@ -173,7 +173,7 @@ class TypeObjectUtils * * @pre bound > 0 (INVALID_SBOUND) * @param[in] bound Bound for the small string/wstring. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if bound is 0. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if bound is 0. * @return const StringSTypeDefn instance. */ FASTDDS_EXPORTED_API static const StringSTypeDefn build_string_s_type_defn( @@ -184,7 +184,7 @@ class TypeObjectUtils * * @pre bound > 255 * @param[in] bound Bound for the large string/wstring. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if bound is lower than 256. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if bound is lower than 256. * @return const StringLTypeDefn instance. */ FASTDDS_EXPORTED_API static const StringLTypeDefn build_string_l_type_defn( @@ -196,7 +196,7 @@ class TypeObjectUtils * @param[in] equiv_kind EquivalenceKind: EK_MINIMAL/EK_COMPLETE/EK_BOTH * @param[in] element_flags CollectionElementFlags to be set. This element must be constructed with the corresponding * builder to ensure its consistency. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError if the given element_flags are inconsistent. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError if the given element_flags are inconsistent. * This exception is only thrown in Debug build mode. * @return const PlainCollectionHeader instance. */ @@ -210,9 +210,9 @@ class TypeObjectUtils * @pre bound > 0 (INVALID_SBOUND) * @pre element_identifier has been initialized. * @param[in] header PlainCollectionHeader to be set. - * @param[in] bound Sequence bound. + * @param[in] s_bound Sequence bound. * @param[in] element_identifier Sequence element TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. The given bound is 0. * 2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header. * 3. Inconsistent header (only in Debug build mode). @@ -230,9 +230,9 @@ class TypeObjectUtils * @pre bound > 255 * @pre element_identifier has been initialized. * @param[in] header PlainCollectionHeader to be set. - * @param[in] bound Sequence bound. + * @param[in] l_bound Sequence bound. * @param[in] element_identifier Sequence element TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. Bound lower than 256. * 2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header. * 3. Inconsistent header (only in Debug build mode). @@ -241,7 +241,7 @@ class TypeObjectUtils */ FASTDDS_EXPORTED_API static const PlainSequenceLElemDefn build_plain_sequence_l_elem_defn( const PlainCollectionHeader& header, - LBound bound, + LBound l_bound, const eprosima::fastcdr::external& element_identifier); /** @@ -272,7 +272,7 @@ class TypeObjectUtils * @param[in] header PlainCollectionHeader to be set. * @param[in] array_bound_seq Bounds for the array dimensions. * @param[in] element_identifier Array element TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. Any given bound in array_bound_seq is 0. * 2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header. * 3. Inconsistent header (only in Debug build mode). @@ -292,7 +292,7 @@ class TypeObjectUtils * @param[in] header PlainCollectionHeader to be set. * @param[in] array_bound_seq Bounds for the array dimensions. * @param[in] element_identifier Array element TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. Any given bound in array_bound_seq is 0. * 2. There is no dimension with a bound greater than 255. * 3. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header. @@ -315,7 +315,7 @@ class TypeObjectUtils * @param[in] element_identifier Map element TypeIdentifier. * @param[in] key_flags Flags applying to map key. * @param[in] key_identifier Map key TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. Given bound is zero (INVALID_SBOUND) * 2. Inconsistent element_identifier EquivalenceKind with the one contained in the header. * 3. Direct hash key_identifier or indirect hash TypeIdentifier with exception to string/wstring. @@ -343,7 +343,7 @@ class TypeObjectUtils * @param[in] element_identifier Map element TypeIdentifier. * @param[in] key_flags Flags applying to map key. * @param[in] key_identifier Map key TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception * 1. Given bound is lower than 256 * 2. Inconsistent element_identifier EquivalenceKind with the one contained in the header. * 3. Direct hash key_identifier or indirect hash TypeIdentifier with exception to string/wstring. @@ -392,7 +392,7 @@ class TypeObjectUtils * @param[in] string StringSTypeDefn union member to set. * @param[in] type_name Type name to be registered. * @param[in] wstring Flag to build a wstring. Default false. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -410,7 +410,7 @@ class TypeObjectUtils * @param[in] string StringLTypeDefn union member to set. * @param[in] type_name Type name to be registered. * @param[in] wstring Flag to build a wstring. Default false. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -427,7 +427,7 @@ class TypeObjectUtils * * @param[in] plain_seq PlainSequenceSElemDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -443,7 +443,7 @@ class TypeObjectUtils * * @param[in] plain_seq PlainSequenceLElemDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -459,7 +459,7 @@ class TypeObjectUtils * * @param[in] plain_array PlainArraySElemDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -475,7 +475,7 @@ class TypeObjectUtils * * @param[in] plain_array PlainArrayLElemDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -491,7 +491,7 @@ class TypeObjectUtils * * @param[in] plain_map PlainMapSTypeDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -507,7 +507,7 @@ class TypeObjectUtils * * @param[in] plain_map PlainMapLTypeDefn union member to set. * @param[in] type_name Type name to be registered. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given member is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given member is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with @@ -717,7 +717,7 @@ class TypeObjectUtils * @brief Add AppliedAnnotationParameter to the sequence. * * @param[in out] param_seq AppliedAnnotationParameter sequence to be modified. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the parameter being added has + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the parameter being added has * already been included in the sequence. * @param[in] param AppliedAnnotationParameter to be added. */ @@ -730,7 +730,7 @@ class TypeObjectUtils * * @param[in] annotation_typeid Annotation TypeIdentifier. * @param[in] param_seq Annotation parameters. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given annotation_typeid TypeIdentifier does not correspond to an annotation TypeObject (only in * Debug build mode). * 2. Given AppliedAnnotationParameterSeq is inconsistent (only in Debug build mode). @@ -747,7 +747,7 @@ class TypeObjectUtils * * @param[in out] ann_custom_seq AppliedAnnotation sequence to be modified. * @param[in] ann_custom AppliedAnnotation to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given AppliedAnnotation is not consistent (only in Debug build mode). * 2. Given AppliedAnnotation is already present in the sequence. */ @@ -790,7 +790,7 @@ class TypeObjectUtils * @param[in] member_id Member identifier. * @param[in] member_flags Member flags: optional, must_understand, key, and external. * @param[in] member_type_id Member TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception: * 1. The given flags are not consistent (only in Debug build mode). * 2. The given TypeIdentifier is not consistent (only in Debug build mode). * @return const CommonStructMember instance. @@ -806,7 +806,7 @@ class TypeObjectUtils * @param[in] name Member name. * @param[in] ann_builtin Member builtin annotations. * @param[in] ann_custom Member custom annotations. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Empty member name. * 2. Given AppliedAnnotationSeq is not consistent (only Debug build mode). * @return const CompleteMemberDetail instance. @@ -825,7 +825,7 @@ class TypeObjectUtils * * @param[in] common CommonStructMember to be set. * @param[in] detail CompleteMemberDetail to be set. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonStructMember is inconsistent (only Debug build mode). * 2. Given CompleteMemberDetail is inconsistent (only Debug build mode). * @return const CompleteMemberDetail instance. @@ -838,8 +838,8 @@ class TypeObjectUtils * @brief Add CompleteStructMember to the sequence. * * @param[in out] member_seq CompleteStructMember sequence to be modified. - * @param[in] ann_custom CompleteStructMember to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @param[in] member CompleteStructMember to be added. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CompleteStructMember is not consistent (only in Debug build mode). * 2. There is already another member in the sequence with the same member id or the same member name * (only in Debug build mode). @@ -856,7 +856,7 @@ class TypeObjectUtils * @brief Build AppliedBuiltinTypeAnnotations instance. * * @param[in] verbatim AppliedVerbatimAnnotation to be set. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given verbatim annotation + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given verbatim annotation * is inconsistent (only in Debug build mode). * @return const AppliedBuiltinTypeAnnotations instance. */ @@ -873,7 +873,7 @@ class TypeObjectUtils * @param[in] ann_builtin Verbatim annotation. * @param[in] ann_custom Applied annotations. * @param[in] type_name Name of the type. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given type_name is empty. * 2. any applied annotation is not consistent (only Debug build mode). * @return const CompleteTypeDetail instance. @@ -888,7 +888,7 @@ class TypeObjectUtils * * @param[in] base_type TypeIdentifier of the parent structure (inheritance). * @param[in] detail CompleteTypeDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given TypeIdentifier is not consistent (direct HASH or empty TypeIdentifier). In Debug build * mode the corresponding TypeObject is also checked in case of direct HASH TypeIdentifier. * 2. Given CompleteTypeDetail is not consistent (only in Debug build mode). @@ -908,7 +908,7 @@ class TypeObjectUtils * @param[in] struct_flags StructTypeFlags. * @param[in] header CompleteStructHeader. * @param[in] member_seq Sequence of CompleteStructMembers. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given StructTypeFlag is not consistent (only in Debug build mode). * 2. Given CompleteStructHeader is not consistent (only in Debug build mode). * 3. Given CompleteStructMemberSeq is not consistent (only in Debug build mode). @@ -943,7 +943,7 @@ class TypeObjectUtils * @param[in] member_flags Member flags. * @param[in] type_id Member TypeIdentifier. * @param[in] label_seq Member applicable case labels. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given UnionMemberFlags are not consistent (only Debug build mode). * 2. Given TypeIdentifier is not consistent (only Debug build mode). * @return const CommonUnionMember instance. @@ -959,7 +959,7 @@ class TypeObjectUtils * * @param[in] common CommonUnionMember. * @param[in] detail CompleteMemberDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonUnionMember is not consistent (only in Debug build mode). * 2. Given CompleteMemberDetail is not consistent (only in Debug build mode). * @return const CompleteUnionMember instance. @@ -973,7 +973,7 @@ class TypeObjectUtils * * @param[in out] complete_union_member_seq Sequence to be modified. * @param[in] member Complete union member to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CompleteUnionMember is not consistent (only in Debug build mode). * 2. There is already another member in the sequence with the same member id or the same member name * (only in Debug build mode). @@ -995,7 +995,7 @@ class TypeObjectUtils * * @param[in] member_flags Discriminator flags. * @param[in] type_id Discriminator TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given discriminator flags are inconsistent (only in Debug build mode). * 2. Given TypeIdentifier is not consistent. * XTypes v1.3 Clause 7.2.2.4.4.3 The discriminator of a union must be one of the following types: @@ -1014,7 +1014,7 @@ class TypeObjectUtils * @param[in] common CommonDiscriminatorMember. * @param[in] ann_builtin Verbatim annotation. * @param[in] ann_custom Applied annotations. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonDiscriminatorMember is inconsistent (only in Debug build mode). * 2. AppliedBuiltinTypeAnnotation is inconsistent (only in Debug build mode). * 3. Any given AppliedAnnotation is inconsistent (only in Debug build mode). @@ -1034,7 +1034,7 @@ class TypeObjectUtils * @brief Build CompleteUnionHeader instance. * * @param detail CompleteTypeDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given CompleteTypeDetail is + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given CompleteTypeDetail is * not consistent (only in Debug build mode). * @return const CompleteUnionHeader instance. */ @@ -1052,7 +1052,7 @@ class TypeObjectUtils * @param[in] header * @param[in] discriminator * @param[in] member_seq - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given UnionTypeFlags are not consistent (only in Debug build mode). * 2. Given CompleteUnionHeader is not consistent (only in Debug build mode). * 3. Given CompleteDiscriminatorMember inconsistent (only in Debug build mode). @@ -1077,7 +1077,7 @@ class TypeObjectUtils * * @param[in] member_flags AnnotationParameterFlag: empty. No flags apply. It must be zero. * @param[in] member_type_id Member TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given AnnotationParameterFlag are not empty. * 2. Given TypeIdentifier is not consistent (only in Debug build mode). * @return const CommonAnnotationParameter instance. @@ -1092,7 +1092,7 @@ class TypeObjectUtils * @param[in] common CommonAnnotationParameter. * @param[in] name Member name. * @param[in] default_value Annotation default value. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonAnnotationParameter is inconsistent (only in Debug build mode). * 2. CommonAnnotationParameter TypeIdentifier is inconsistent with AnnotationParameterValue type. * 3. Given parameter name is empty. @@ -1108,7 +1108,7 @@ class TypeObjectUtils * * @param[in out] sequence Sequence to be modified. * @param[in] param Complete annotation parameter to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CompleteAnnotationParameter is not consistent (only in Debug build mode). * 2. There is already another member in the sequence with the same member id or the same member name * (only in Debug build mode). @@ -1125,7 +1125,7 @@ class TypeObjectUtils * @brief Build CompleteAnnotationHeader instance. * * @param[in] annotation_name Qualified annotation type name. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError if the annotation_name is empty. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError if the annotation_name is empty. * @return const CompleteAnnotationHeader instance. */ FASTDDS_EXPORTED_API static const CompleteAnnotationHeader build_complete_annotation_header( @@ -1141,7 +1141,7 @@ class TypeObjectUtils * @param[in] annotation_flag Unused. No flags apply. It must be 0. * @param[in] header CompleteAnnotationHeader. * @param[in] member_seq CompleteAnnotationParameter sequence. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any annotation flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Any CompleteAnnotationParameter in the sequence is inconsistent (only in Debug build mode). @@ -1163,7 +1163,7 @@ class TypeObjectUtils * * @param[in] related_flags AliasMemberFlag: unused. No flags apply. It must be 0. * @param[in] related_type Related TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any alias member flag is set. * 2. Non-consistent TypeIdentifier (only in Debug build mode). * @return const CommonAliasBody instance. @@ -1178,10 +1178,10 @@ class TypeObjectUtils * @param[in] common CommonAliasBody. * @param[in] ann_builtin Applied builtin member annotations: unit, max, min, range, hashid * @param[in] ann_custom Applied custom annotations - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonAliasBody is inconsistent (only Debug build mode). * 2. AppliedAnnotationSeq is inconsistent (only Debug build mode). - * 3. @hashid builtin annotation is set. + * 3. hashid builtin annotation is set. * @return const CompleteAliasBody instance. */ FASTDDS_EXPORTED_API static const CompleteAliasBody build_complete_alias_body( @@ -1197,7 +1197,7 @@ class TypeObjectUtils * @brief Build CompleteAliasHeader instance. * * @param[in] detail Complete type detail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given CompleteTypeDetail is + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given CompleteTypeDetail is * inconsistent (only in Debug build mode). * @return const CompleteAliasHeader instance. */ @@ -1214,7 +1214,7 @@ class TypeObjectUtils * @param[in] alias_flags Alias type flags: unused. No flags apply. It must be zero. * @param[in] header CompleteAliasHeader. * @param[in] body CompleteAliasBody. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any alias type flag is set. * 2. Inconsistent header and/or body (only in Debug build mode). * @return const CompleteAliasType instance. @@ -1235,9 +1235,9 @@ class TypeObjectUtils * * @param[in] ann_builtin Applied builtin member annotations: unit, max, min, range, hashid * @param[in] ann_custom Applied custom annotations - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. AppliedAnnotationSeq is inconsistent (only Debug build mode). - * 2. @hashid builtin annotation is applied. + * 2. hashid builtin annotation is applied. * @return const CompleteElementDetail instance. */ FASTDDS_EXPORTED_API static const CompleteElementDetail build_complete_element_detail( @@ -1249,7 +1249,7 @@ class TypeObjectUtils * * @param[in] element_flags CollectionElementFlag. * @param[in] type TypeIdentifier. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given collection element flags are not consistent (only in Debug build mode). * 2. Given TypeIdentifier is not consistent (only in Debug build mode). * @return const CommonCollectionElement instance @@ -1263,7 +1263,7 @@ class TypeObjectUtils * * @param[in] common CommonCollectionElement. * @param[in] detail CompleteElementDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonCollectionElement is not consistent (only in Debug build mode). * 2. Given CompleteElementDetail is not consistent (only in Debug build mode). * @return const CompleteCollectionElement instance @@ -1280,7 +1280,7 @@ class TypeObjectUtils * @brief Build CommonCollectionHeader instance. * * @param[in] bound Collection bound. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given bound is not + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given bound is not * consistent. * @return const CommonCollectionHeader instance. */ @@ -1292,7 +1292,7 @@ class TypeObjectUtils * * @param[in] common CommonCollectionHeader * @param[in] detail CompleteTypeDetail - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonCollectionHeader is inconsistent (only in Debug build mode). * 2. Given CompleteTypeDetail is inconsistent (only in Debug build mode). * @return const CompleteCollectionHeader instance. @@ -1313,7 +1313,7 @@ class TypeObjectUtils * @param[in] collection_flag collection type flag: unused. No flags apply. It must be 0. * @param[in] header CompleteCollectionHeader. * @param[in] element CompleteCollectionElement. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any collection flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Given element is inconsistent (only in Debug build mode). @@ -1334,7 +1334,7 @@ class TypeObjectUtils * @brief Build CommonArrayHeader instance. * * @param[in] bound_seq Sequence of the dimension's bounds. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if any given bound is 0 (invalid). + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if any given bound is 0 (invalid). * @return const CommonArrayHeader instance. */ FASTDDS_EXPORTED_API static const CommonArrayHeader build_common_array_header( @@ -1345,7 +1345,7 @@ class TypeObjectUtils * * @param[in] common CommonArrayHeader. * @param[in] detail CompleteTypeDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonArrayHeader is inconsistent (only in Debug build mode). * 2. Given CompleteTypeDetail is inconsistent (only in Debug build mode). * @return const CompleteArrayHeader instance. @@ -1364,7 +1364,7 @@ class TypeObjectUtils * @param[in] collection_flag collection type flag: unused. No flags apply. It must be 0. * @param[in] header CompleteArrayHeader. * @param[in] element CompleteCollectionElement. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any collection flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Given element is inconsistent (only in Debug build mode). @@ -1388,7 +1388,7 @@ class TypeObjectUtils * @param[in] header CompleteArrayHeader. * @param[in] key CompleteCollectionElement describing map key. * @param[in] element CompleteCollectionElement describing map element. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any collection flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Given key TypeIdentifier is inconsistent. @@ -1413,7 +1413,7 @@ class TypeObjectUtils * * @param[in] value Enumerated literal value. * @param[in] flags Enumerated literal flags: only default flag apply. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if any other flag different from + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if any other flag different from * default is set (only in Debug build mode). * @return const CommonEnumeratedLiteral instance. */ @@ -1426,7 +1426,7 @@ class TypeObjectUtils * * @param[in] common CommonEnumeratedLiteral. * @param[in] detail CompleteMemberDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonEnumeratedLiteral is inconsistent (only in Debug build mode). * 2. Given CompleteMemberDetail is inconsistent (only in Debug build mode). * @return const CompleteEnumeratedLiteral instance. @@ -1440,7 +1440,7 @@ class TypeObjectUtils * * @param[in] sequence Sequence to be modified. * @param[in out] enum_literal CompleteEnumeratedLiteral to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonEnumeratedLiteral is not consistent (only in Debug build mode). * 2. There is already another literal in the sequence with the same value or the same member name * (only in Debug build mode). @@ -1457,10 +1457,10 @@ class TypeObjectUtils * @brief Build CommonEnumeratedHeader instance. * * @param[in] bit_bound XTypes v1.3 Clause 7.3.1.2.1.5 It is important to note that the value member of the - * [@bit_bound] annotation may take any value from 1 to 32, inclusive, when this annotation is + * [bit_bound] annotation may take any value from 1 to 32, inclusive, when this annotation is * applied to an enumerated type. * @param[in] bitmask Flag in case that the header being built corresponds to a Bitmask. By default is false. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given bit_bound is not + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given bit_bound is not * consistent. * @return const CommonEnumeratedHeader instance. */ @@ -1475,7 +1475,7 @@ class TypeObjectUtils * @param[in] detail CompleteTypeDetail. * @param[in] bitmask flag set if the given header corresponds to a bitmask. Only required in Debug build mode. * Set to false by default. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonEnumeratedHeader is inconsistent (only in Debug build mode). * 2. Given CompleteTypeDetail is inconsistent (only in Debug build mode). * @return const CompleteEnumeratedHeader instance. @@ -1495,7 +1495,7 @@ class TypeObjectUtils * @param[in] enum_flags Enumeration flags: unused. No flags apply. It must be 0. * @param[in] header CompleteEnumeratedHeader. * @param[in] literal_seq Sequence of CompleteEnumeratedLiterals. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any flag is set. * 2. Given CompleteEnumeratedHeader is inconsistent (only in Debug build mode). * 3. Given CompleteEnumeratedLiteralSeq is inconsistent (only in Debug build mode). @@ -1517,7 +1517,7 @@ class TypeObjectUtils * * @param[in] position Bit position in the bitmask. * @param[in] flags Bit flags: unused. No flags apply. It must be 0. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. any given flag is set. * 2. given position is inconsistent. XTypes v1.3 Clause 7.2.2.4.1.2 Each bit in this subset is * identified by name and by an index, numbered from 0 to (bound-1). The bound must be greater than @@ -1533,7 +1533,7 @@ class TypeObjectUtils * * @param[in] common CommonBitflag. * @param[in] detail CompleteMemberDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonBitflag is inconsistent (only in Debug build mode). * 2. Given CompleteMemberDetail is inconsistent (only in Debug build mode). * 3. Non-applicable builtin annotations applied. @@ -1548,7 +1548,7 @@ class TypeObjectUtils * * @param[in out] sequence Sequence to be modified. * @param[in] bitflag CompleteBitflag to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given bitflag is inconsistent (only in Debug build mode). * 2. There is already another bitflag in the sequence with the same position or the same name * (only in Debug build mode). @@ -1573,7 +1573,7 @@ class TypeObjectUtils * @param[in] bitmask_flags Bitmask flags: unused. No flags apply. It must be 0. * @param[in] header CompleteBitmaskHeader/CompleteEnumeratedHeader * @param[in] flag_seq Sequence of CompleteBitflag. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. any given flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Given Bitflag sequence is inconsistent (only in Debug build mode). @@ -1591,12 +1591,12 @@ class TypeObjectUtils * * @param[in] position Bitfield starting position bit. * @param[in] flags Bitfield flags: unused. No flags apply. It must be 0. - * @param[in] bitcount Bitfield number of bits. IDL v4.2 Clause 7.4.13.4.3.2 The first one () is + * @param[in] bitcount Bitfield number of bits. IDL v4.2 Clause 7.4.13.4.3.2 The first one (positive_int_const) is * the number of bits that can be stored (its [bitfield] size). The maximum value is 64. * @param[in] holder_type Type used to manipulate the bitfield. IDL v4.2 Clause 7.4.13.4.3.2 The second optional one - * () specifies the type that will be used to manipulate the bit field as a + * (destination_type) specifies the type that will be used to manipulate the bit field as a * whole. This type can be boolean, octet or any integer type either signed or unsigned. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given position is not consistent. * 2. Any flag is set. * 3. Given bitcount is not consistent. @@ -1614,7 +1614,7 @@ class TypeObjectUtils * * @param[in] common CommonBitfield. * @param[in] detail CompleteMemberDetail. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given CommonBitfield is inconsistent (only Debug build mode). * 2. Give CompleteMemberDetail is inconsistent (only Debug build mode). * 3. Non-applicable builtin annotations are applied. @@ -1629,7 +1629,7 @@ class TypeObjectUtils * * @param[in out] sequence Sequence to be modified. * @param[in] bitfield CompleteBitfield to be added. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Given bitfield is inconsistent (only in Debug build mode). * 2. There is another bitfield with the same name and/or the same position. */ @@ -1645,7 +1645,7 @@ class TypeObjectUtils * @brief Build CompleteBitsetHeader instance. * * @param[in] detail CompleteTypeDetail - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given CompleteTypeDetail is + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given CompleteTypeDetail is * inconsistent (only in Debug build mode). * @return const CompleteBitsetHeader instance. */ @@ -1662,7 +1662,7 @@ class TypeObjectUtils * @param[in] bitset_flags Bitset flags: unused. No flags apply. It must be 0. * @param[in] header CompleteBitsetHeader. * @param[in] field_seq Sequence of complete bitfields. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if: + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if: * 1. Any given flag is set. * 2. Given header is inconsistent (only in Debug build mode). * 3. Given bitfield sequence is inconsistent (only in Debug build mode). @@ -1692,7 +1692,7 @@ class TypeObjectUtils * * @param[in] alias_type CompleteAliasType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1709,7 +1709,7 @@ class TypeObjectUtils * * @param[in] annotation_type CompleteAnnotationType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1726,7 +1726,7 @@ class TypeObjectUtils * * @param[in] struct_type CompleteStructType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1743,7 +1743,7 @@ class TypeObjectUtils * * @param[in] union_type CompleteUnionType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1760,7 +1760,7 @@ class TypeObjectUtils * * @param[in] bitset_type CompleteBitsetType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1777,7 +1777,7 @@ class TypeObjectUtils * * @param[in] sequence_type CompleteSequenceType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1794,7 +1794,7 @@ class TypeObjectUtils * * @param[in] array_type CompleteArrayType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1811,7 +1811,7 @@ class TypeObjectUtils * * @param[in] map_type CompleteMapType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1828,7 +1828,7 @@ class TypeObjectUtils * * @param[in] enumerated_type CompleteEnumeratedType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1845,7 +1845,7 @@ class TypeObjectUtils * * @param[in] bitmask_type CompleteBitmaskType. * @param[in] type_name Name to be registered in the registry. - * @exception eprosima::fastdds::dds::xtypesv1_3::InvalidArgumentError exception if the given type is inconsistent + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given type is inconsistent * (only in Debug build mode). * @return ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. * RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with @@ -1867,6 +1867,16 @@ class TypeObjectUtils FASTDDS_EXPORTED_API static const NameHash name_hash( const std::string& name); + /** + * @brief Check TypeObject consistency. + * + * @param[in] type_object Instance to be checked. + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given + * TypeObject is not consistent. + */ + static void type_object_consistency( + const TypeObject& type_object); + private: friend class TypeObjectRegistry; @@ -2238,7 +2248,7 @@ class TypeObjectUtils /** * @brief Check direct hash TypeIdentifier consistency. * - * @param[in] equivalence_hash Instance to be checked. + * @param[in] type_id Instance to be checked. * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given TypeIdentifier is * not consistent. */ @@ -2248,7 +2258,7 @@ class TypeObjectUtils /** * @brief Check TypeIdentifier consistency. * - * @param[in] plain_map Instance to be checked. + * @param[in] type_identifier Instance to be checked. * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given TypeIdentifier is * not consistent. */ @@ -2330,7 +2340,7 @@ class TypeObjectUtils * * @param[in] common_struct_member CommonStructMember to be checked. * @param[in] complete_member_detail CompleteMemberDetail to be checked. - * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the @hashid builtin applied + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the hashid builtin applied * annotation is set and inconsistent with the member id. */ static void common_struct_member_and_complete_member_detail_consistency( @@ -2341,7 +2351,7 @@ class TypeObjectUtils * @brief Check consistency between a string value and the MemberId (algorithm XTypes v1.3 Clause 7.3.1.2.1.1) * * @param[in] member_id MemberId to be checked. - * @param[in] string_value String provided with either @hashid annotation or the member name. + * @param[in] string_value String provided with either hashid annotation or the member name. * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given data is inconsistent. */ static void string_member_id_consistency( @@ -2451,9 +2461,9 @@ class TypeObjectUtils /** * @brief Check cross-consistency between CommonStructMember and CompleteMemberDetail. * - * @param[in] common_struct_member CommonStructMember to be checked. + * @param[in] common_union_member CommonStructMember to be checked. * @param[in] complete_member_detail CompleteMemberDetail to be checked. - * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the @hashid builtin annotation is + * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the hashid builtin annotation is * set and the member id is not consistent. */ static void common_union_member_complete_member_detail_consistency( @@ -2623,7 +2633,7 @@ class TypeObjectUtils const CommonAliasBody& common_alias_body); /** - * @brief Check that @hashid builtin annotation has not been set. + * @brief Check that hashid builtin annotation has not been set. * * @param[in] ann_builtin Instance to be checked. * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given @@ -3036,17 +3046,6 @@ class TypeObjectUtils */ static void minimal_type_object_consistency( const MinimalTypeObject& minimal_type_object); - - /** - * @brief Check TypeObject consistency. - * - * @param[in] type_object Instance to be checked. - * @exception eprosima::fastdds::dds::xtypes::InvalidArgumentError exception if the given - * TypeObject is not consistent. - */ - static void type_object_consistency( - const TypeObject& type_object); - }; } // xtypes diff --git a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h index bcc0124b9b5..307f8f6d4d0 100644 --- a/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h +++ b/include/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -443,6 +443,7 @@ class RTPSParticipantAttributes (this->security_log_thread == b.security_log_thread) && #endif // if HAVE_SECURITY (this->discovery_server_thread == b.discovery_server_thread) && + (this->typelookup_service_thread == b.typelookup_service_thread) && (this->builtin_transports_reception_threads == b.builtin_transports_reception_threads); } @@ -559,6 +560,9 @@ class RTPSParticipantAttributes //! Thread settings for the discovery server thread fastdds::rtps::ThreadSettings discovery_server_thread; + //! Thread settings for the builtin TypeLookup service requests and replies threads + fastdds::rtps::ThreadSettings typelookup_service_thread; + //! Thread settings for the builtin transports reception threads fastdds::rtps::ThreadSettings builtin_transports_reception_threads; diff --git a/include/fastdds/rtps/security/logging/Logging.h b/include/fastdds/rtps/security/logging/Logging.h index 51ccbc1658b..7e684b4faad 100644 --- a/include/fastdds/rtps/security/logging/Logging.h +++ b/include/fastdds/rtps/security/logging/Logging.h @@ -243,22 +243,22 @@ bool Logging::compose_header( MESSAGE, \ std::string(CLASS ",") + __func__, \ EXCEPTION); \ - } \ - else { \ + } \ + else { \ switch (LEVEL){ \ case LoggingLevel::EMERGENCY_LEVEL: \ case LoggingLevel::ALERT_LEVEL: \ case LoggingLevel::CRITICAL_LEVEL: \ case LoggingLevel::ERROR_LEVEL: \ - EPROSIMA_LOG_ERROR(SECURITY, MESSAGE); \ + EPROSIMA_LOG_ERROR(SECURITY, MESSAGE); \ break; \ case LoggingLevel::WARNING_LEVEL: \ - EPROSIMA_LOG_WARNING(SECURITY, MESSAGE); \ + EPROSIMA_LOG_WARNING(SECURITY, MESSAGE); \ break; \ case LoggingLevel::NOTICE_LEVEL: \ case LoggingLevel::INFORMATIONAL_LEVEL: \ case LoggingLevel::DEBUG_LEVEL: \ - EPROSIMA_LOG_INFO(SECURITY, MESSAGE); \ + EPROSIMA_LOG_INFO(SECURITY, MESSAGE); \ break; \ } \ } \ diff --git a/include/fastdds/statistics/rtps/monitor_service/connections_fwd.hpp b/include/fastdds/statistics/rtps/monitor_service/connections_fwd.hpp index 0f6ee4ef799..abea1e4cf1e 100644 --- a/include/fastdds/statistics/rtps/monitor_service/connections_fwd.hpp +++ b/include/fastdds/statistics/rtps/monitor_service/connections_fwd.hpp @@ -13,7 +13,7 @@ // limitations under the License. /** - * @file connection_fwd.hpp + * @file connections_fwd.hpp * */ diff --git a/resources/xsd/fastdds_profiles.xsd b/resources/xsd/fastdds_profiles.xsd index e9e5d7d6706..84b8a6fa5f2 100644 --- a/resources/xsd/fastdds_profiles.xsd +++ b/resources/xsd/fastdds_profiles.xsd @@ -142,6 +142,7 @@ ├ builtin_controllers_sender_thread [threadSettingsType], ├ timed_events_thread [threadSettingsType], ├ discovery_server_thread [threadSettingsType], + ├ typelookup_service_thread [threadSettingsType], ├ builtin_transports_reception_threads [threadSettingsType], └ security_log_thread [threadSettingsType]--> @@ -186,6 +187,7 @@ + diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp index 4960c44aade..2b924742abd 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.cpp @@ -109,7 +109,7 @@ bool TypeLookupManager::init( participant_ = protocols->mp_participantImpl; builtin_protocols_ = protocols; - local_instance_name_ = get_instance_name(participant_->getGuid().guidPrefix); + local_instance_name_ = get_instance_name(participant_->getGuid()); temp_reader_proxy_data_ = new fastrtps::rtps::ReaderProxyData( protocols->mp_participantImpl->getRTPSParticipantAttributes().allocation.locators.max_unicast_locators, @@ -256,89 +256,76 @@ void TypeLookupManager::remove_remote_endpoints( SampleIdentity TypeLookupManager::get_type_dependencies( const xtypes::TypeIdentifierSeq& id_seq, - const fastrtps::rtps::GuidPrefix_t& type_server) const + const fastrtps::rtps::GUID_t& type_server, + const std::vector& continuation_point) const { - SampleIdentity id = INVALID_SAMPLE_IDENTITY; - TypeLookup_getTypeDependencies_In in; - in.type_ids() = id_seq; + in.type_ids(id_seq); + if (!continuation_point.empty()) + { + in.continuation_point(continuation_point); + } + + // Create a generic TypeLookup_Request TypeLookup_RequestPubSubType type; - TypeLookup_Request* request = static_cast(type.createData()); + TypeLookup_Request* request = create_request(type_server, type); + + // Add the specific data to the request request->data().getTypeDependencies(in); - if (send_request(type_server, *request)) + SampleIdentity id = INVALID_SAMPLE_IDENTITY; + if (send(*request)) { id = request->header().requestId(); } + // Delete request data after sending type.deleteData(request); return id; } SampleIdentity TypeLookupManager::get_types( const xtypes::TypeIdentifierSeq& id_seq, - const fastrtps::rtps::GuidPrefix_t& type_server) const + const fastrtps::rtps::GUID_t& type_server) const { - SampleIdentity id = INVALID_SAMPLE_IDENTITY; - TypeLookup_getTypes_In in; - in.type_ids() = id_seq; + in.type_ids(id_seq); + + // Create a generic TypeLookup_Request TypeLookup_RequestPubSubType type; - TypeLookup_Request* request = static_cast(type.createData()); + TypeLookup_Request* request = create_request(type_server, type); + + // Add the specific data to the request request->data().getTypes(in); - if (send_request(type_server, *request)) + SampleIdentity id = INVALID_SAMPLE_IDENTITY; + if (send(*request)) { id = request->header().requestId(); } + // Delete request data after sending type.deleteData(request); return id; } ReturnCode_t TypeLookupManager::async_get_type( - eprosima::ProxyPool::smart_ptr&& temp_writer_data, + eprosima::ProxyPool::smart_ptr& temp_writer_data, const AsyncGetTypeWriterCallback& callback) { - ReturnCode_t result = check_type_identifier_received(std::move(temp_writer_data), callback); - if (RETCODE_OK == result) - { - // The type is already known, invoke the callback - callback(std::move(temp_writer_data)); - } - return result; + return check_type_identifier_received( + temp_writer_data, callback, async_get_type_writer_callbacks_); } ReturnCode_t TypeLookupManager::async_get_type( - eprosima::ProxyPool::smart_ptr&& temp_reader_data, + eprosima::ProxyPool::smart_ptr& temp_reader_data, const AsyncGetTypeReaderCallback& callback) { - ReturnCode_t result = check_type_identifier_received(std::move(temp_reader_data), callback); - if (RETCODE_OK == result) - { - // The type is already known, invoke the callback - callback(std::move(temp_reader_data)); - } - return result; -} - -ReturnCode_t TypeLookupManager::check_type_identifier_received( - eprosima::ProxyPool::smart_ptr&& temp_writer_data, - const AsyncGetTypeWriterCallback& callback) -{ - return check_type_identifier_received_impl( - std::move(temp_writer_data), callback, async_get_type_writer_callbacks_); -} - -ReturnCode_t TypeLookupManager::check_type_identifier_received( - eprosima::ProxyPool::smart_ptr&& temp_reader_data, - const AsyncGetTypeReaderCallback& callback) -{ - return check_type_identifier_received_impl( - std::move(temp_reader_data), callback, async_get_type_reader_callbacks_); + return check_type_identifier_received( + temp_reader_data, callback, async_get_type_reader_callbacks_); } template -ReturnCode_t TypeLookupManager::check_type_identifier_received_impl( - typename eprosima::ProxyPool::smart_ptr&& temp_proxy_data, +ReturnCode_t TypeLookupManager::check_type_identifier_received( + typename eprosima::ProxyPool::smart_ptr& temp_proxy_data, const AsyncCallback& callback, std::unordered_map::smart_ptr, @@ -346,46 +333,80 @@ ReturnCode_t TypeLookupManager::check_type_identifier_received_impl( { xtypes::TypeIdentfierWithSize type_identifier_with_size = temp_proxy_data->type_information().type_information.complete().typeid_with_size(); - fastrtps::rtps::GuidPrefix_t type_server = temp_proxy_data->guid().guidPrefix; + fastrtps::rtps::GUID_t type_server = temp_proxy_data->guid(); // Check if the type is known if (fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). is_type_identifier_known(type_identifier_with_size)) { + // The type is already known, invoke the callback + callback(temp_proxy_data); return RETCODE_OK; } - // Check if TypeIdentfierWithSize already exists in the map - std::lock_guard lock(async_get_types_mutex_); - auto it = async_get_type_callbacks.find(type_identifier_with_size); - if (it != async_get_type_callbacks.end()) { - // TypeIdentfierWithSize exists, add the callback - it->second.push_back(std::make_pair(std::move(temp_proxy_data), callback)); - // Return without sending new request + // Check if TypeIdentfierWithSize already exists in the map + std::lock_guard lock(async_get_types_mutex_); + auto it = async_get_type_callbacks.find(type_identifier_with_size); + if (it != async_get_type_callbacks.end()) + { + // TypeIdentfierWithSize exists, add the callback + it->second.push_back(std::make_pair(std::move(temp_proxy_data), callback)); + // Return without sending new request + return RETCODE_NO_DATA; + } + } + + // TypeIdentfierWithSize doesn't exist, create a new entry + SampleIdentity get_type_dependencies_request = get_type_dependencies( + {type_identifier_with_size.type_id()}, type_server); + if (INVALID_SAMPLE_IDENTITY != get_type_dependencies_request) + { + // Store the sent requests and callback + add_async_get_type_request(get_type_dependencies_request, type_identifier_with_size); + std::vector::smart_ptr, AsyncCallback>> types; + types.push_back(std::make_pair(std::move(temp_proxy_data), callback)); + async_get_type_callbacks.emplace(type_identifier_with_size, std::move(types)); + return RETCODE_NO_DATA; } else { - // TypeIdentfierWithSize doesn't exist, create a new entry - xtypes::TypeIdentifierSeq unknown_type{type_identifier_with_size.type_id()}; - SampleIdentity get_type_dependencies_request = get_type_dependencies(unknown_type, type_server); - if (INVALID_SAMPLE_IDENTITY != get_type_dependencies_request) - { - // Store the sent requests and callback - add_async_get_type_request(get_type_dependencies_request, type_identifier_with_size); - std::vector::smart_ptr, AsyncCallback>> types; - types.push_back(std::make_pair(std::move(temp_proxy_data), callback)); - async_get_type_callbacks.emplace(type_identifier_with_size, std::move(types)); + // Failed to send request, return error + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Failed to send get_type_dependencies request"); + return RETCODE_ERROR; + } +} - return RETCODE_NO_DATA; +void TypeLookupManager::notify_callbacks( + xtypes::TypeIdentfierWithSize type_identifier_with_size) +{ + bool removed = false; + // Check that type is pending to be resolved + auto writer_callbacks_it = async_get_type_writer_callbacks_.find(type_identifier_with_size); + if (writer_callbacks_it != async_get_type_writer_callbacks_.end()) + { + for (auto& proxy_callback_pair : writer_callbacks_it->second) + { + proxy_callback_pair.second(proxy_callback_pair.first); } - else + removed = true; + } + + auto reader_callbacks_it = async_get_type_reader_callbacks_.find(type_identifier_with_size); + if (reader_callbacks_it != async_get_type_reader_callbacks_.end()) + { + for (auto& proxy_callback_pair : reader_callbacks_it->second) { - // Failed to send request, return error - EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Failed to send get_type_dependencies request"); - return RETCODE_ERROR; + proxy_callback_pair.second(proxy_callback_pair.first); } + removed = true; + } + + if (removed) + { + // Erase the solved TypeIdentfierWithSize + remove_async_get_type_callback(type_identifier_with_size); } } @@ -405,6 +426,7 @@ bool TypeLookupManager::add_async_get_type_request( "Error in TypeLookupManager::add_async_get_type_request: " << e.what()); return false; } + } bool TypeLookupManager::remove_async_get_type_callback( @@ -445,6 +467,24 @@ bool TypeLookupManager::remove_async_get_type_callback( "Error in TypeLookupManager::remove_async_get_type_callback: " << e.what()); return false; } + +} + +bool TypeLookupManager::remove_async_get_type_request( + SampleIdentity request) +{ + std::unique_lock lock(async_get_types_mutex_); + try + { + async_get_type_requests_.erase(request); + return true; + } + catch (const std::exception& e) + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, + "Error in TypeLookupManager::remove_async_get_type_request: " << e.what()); + return false; + } } bool TypeLookupManager::create_endpoints() @@ -469,6 +509,19 @@ bool TypeLookupManager::create_endpoints() watt.endpoint.topicKind = fastrtps::rtps::NO_KEY; watt.endpoint.reliabilityKind = fastrtps::rtps::RELIABLE; watt.endpoint.durabilityKind = fastrtps::rtps::VOLATILE; + watt.mode = fastrtps::rtps::ASYNCHRONOUS_WRITER; + + ReaderAttributes ratt; + ratt.endpoint.unicastLocatorList = builtin_protocols_->m_metatrafficUnicastLocatorList; + ratt.endpoint.multicastLocatorList = builtin_protocols_->m_metatrafficMulticastLocatorList; + ratt.endpoint.external_unicast_locators = builtin_protocols_->m_att.metatraffic_external_unicast_locators; + ratt.endpoint.ignore_non_matching_locators = pattr.ignore_non_matching_locators; + ratt.endpoint.remoteLocatorList = builtin_protocols_->m_initialPeersList; + ratt.matched_writers_allocation = pattr.allocation.participants; + ratt.expectsInlineQos = true; + ratt.endpoint.topicKind = fastrtps::rtps::NO_KEY; + ratt.endpoint.reliabilityKind = fastrtps::rtps::RELIABLE; + ratt.endpoint.durabilityKind = fastrtps::rtps::VOLATILE; // Built-in request writer request_listener_ = new TypeLookupRequestListener(this); @@ -489,9 +542,28 @@ bool TypeLookupManager::create_endpoints() else { EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup request writer creation failed."); - delete builtin_request_writer_history_; - builtin_request_writer_history_ = nullptr; - return false; + ret = false; + } + + // Built-in request reader + builtin_request_reader_history_ = new ReaderHistory(hatt); + + RTPSReader* req_reader; + if (participant_->createReader( + &req_reader, + ratt, + builtin_request_reader_history_, + request_listener_, + fastrtps::rtps::c_EntityId_TypeLookup_request_reader, + true)) + { + builtin_request_reader_ = dynamic_cast(req_reader); + EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request reader created."); + } + else + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup request reader creation failed."); + ret = false; } // Built-in reply writer @@ -513,46 +585,7 @@ bool TypeLookupManager::create_endpoints() else { EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup reply writer creation failed."); - delete builtin_reply_writer_history_; - builtin_reply_writer_history_ = nullptr; - return false; - } - - ReaderAttributes ratt; - ratt.endpoint.unicastLocatorList = builtin_protocols_->m_metatrafficUnicastLocatorList; - ratt.endpoint.multicastLocatorList = builtin_protocols_->m_metatrafficMulticastLocatorList; - ratt.endpoint.external_unicast_locators = builtin_protocols_->m_att.metatraffic_external_unicast_locators; - ratt.endpoint.ignore_non_matching_locators = pattr.ignore_non_matching_locators; - ratt.endpoint.remoteLocatorList = builtin_protocols_->m_initialPeersList; - ratt.matched_writers_allocation = pattr.allocation.participants; - ratt.expectsInlineQos = true; - ratt.endpoint.topicKind = fastrtps::rtps::NO_KEY; - ratt.endpoint.reliabilityKind = fastrtps::rtps::RELIABLE; - ratt.endpoint.durabilityKind = fastrtps::rtps::VOLATILE; - - // Built-in request reader - builtin_request_reader_history_ = new ReaderHistory(hatt); - - RTPSReader* req_reader; - if (participant_->createReader( - &req_reader, - ratt, - builtin_request_reader_history_, - request_listener_, - fastrtps::rtps::c_EntityId_TypeLookup_request_reader, - true)) - { - builtin_request_reader_ = dynamic_cast(req_reader); - EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE, "Builtin Typelookup request reader created."); - } - else - { - EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup request reader creation failed."); - delete builtin_request_reader_history_; - builtin_request_reader_history_ = nullptr; - delete request_listener_; - request_listener_ = nullptr; - return false; + ret = false; } // Built-in reply reader @@ -573,11 +606,7 @@ bool TypeLookupManager::create_endpoints() else { EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE, "Typelookup reply reader creation failed."); - delete builtin_reply_reader_history_; - builtin_reply_reader_history_ = nullptr; - delete reply_listener_; - reply_listener_ = nullptr; - return false; + ret = false; } // Clean up if something failed. @@ -622,189 +651,188 @@ bool TypeLookupManager::create_endpoints() return ret; } -bool TypeLookupManager::send_request( - const fastrtps::rtps::GuidPrefix_t& type_server, - TypeLookup_Request& request) const +TypeLookup_Request* TypeLookupManager::create_request( + const fastrtps::rtps::GUID_t& type_server, + TypeLookup_RequestPubSubType& pupsubtype) const { - request.header().instanceName() = get_instance_name(type_server); - request.header().requestId().writer_guid(guid_rtps_2_dds(builtin_request_writer_->getGuid())); - request.header().requestId().sequence_number(sequence_number_rtps_2_dds(request_seq_number_)); + TypeLookup_Request* request = static_cast(pupsubtype.createData()); + request->header().instanceName() = get_instance_name(type_server); + request->header().requestId().writer_guid(guid_rtps_2_dds(builtin_request_writer_->getGuid())); + request->header().requestId().sequence_number(sequence_number_rtps_2_dds(request_seq_number_)); request_seq_number_++; + return request; +} - CacheChange_t* change = builtin_request_writer_->new_change( - [&request]() - { - eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv1); - size_t current_alignment {0}; - return static_cast(calculator.calculate_serialized_size(request, current_alignment) + 4); - }, - ALIVE); - - if (change != nullptr) +bool TypeLookupManager::send( + TypeLookup_Request& request) const +{ + if (!send_impl(request, &request_type_, builtin_request_writer_, builtin_request_writer_history_)) { - CDRMessage_t msg(change->serializedPayload); - - bool valid = CDRMessage::addOctet(&msg, 0); - change->serializedPayload.encapsulation = static_cast(PL_DEFAULT_ENCAPSULATION); - msg.msg_endian = DEFAULT_ENDIAN; - valid &= CDRMessage::addOctet(&msg, PL_DEFAULT_ENCAPSULATION); - valid &= CDRMessage::addUInt16(&msg, 0); - - change->serializedPayload.pos = msg.pos; - change->serializedPayload.length = msg.length; - - SerializedPayload_t payload; - payload.max_size = change->serializedPayload.max_size - 4; - payload.data = change->serializedPayload.data + 4; - if (valid && request_type_.serialize(&request, &payload, DataRepresentationId_t::XCDR2_DATA_REPRESENTATION)) - { - change->serializedPayload.length += payload.length; - change->serializedPayload.pos += payload.pos; - payload.data = nullptr; - return builtin_request_writer_history_->add_change(change); - } + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error sending request."); + return false; } - builtin_request_writer_history_->remove_change(change); - return false; + return true; } -bool TypeLookupManager::send_reply( +bool TypeLookupManager::send( TypeLookup_Reply& reply) const { - CacheChange_t* change = builtin_reply_writer_->new_change( - [&reply]() + if (!send_impl(reply, &reply_type_, builtin_reply_writer_, builtin_reply_writer_history_)) + { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error sending reply."); + return false; + } + return true; +} + +template +bool TypeLookupManager::send_impl( + Type& msg, + PubSubType* pubsubtype, + fastrtps::rtps::StatefulWriter* writer, + fastrtps::rtps::WriterHistory* writer_history) const +{ + // Create a new CacheChange_t using the provided StatefulWriter + CacheChange_t* change = writer->new_change( + [&msg]() { - eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv1); + // Calculate the serialized size of the message using a CdrSizeCalculator + eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; - return static_cast(calculator.calculate_serialized_size(reply, current_alignment) + 4); + return static_cast(calculator.calculate_serialized_size(msg, current_alignment) + 4); }, ALIVE); - if (change != nullptr) + // Check if the creation of CacheChange_t was successful + if (!change) { - CDRMessage_t msg(change->serializedPayload); + return false; + } - bool valid = CDRMessage::addOctet(&msg, 0); - change->serializedPayload.encapsulation = static_cast(PL_DEFAULT_ENCAPSULATION); - msg.msg_endian = DEFAULT_ENDIAN; - valid &= CDRMessage::addOctet(&msg, PL_DEFAULT_ENCAPSULATION); - valid &= CDRMessage::addUInt16(&msg, 0); + // Prepare the payload for sending the message + SerializedPayload_t payload; + payload.max_size = change->serializedPayload.max_size; + payload.data = change->serializedPayload.data; - change->serializedPayload.pos = msg.pos; - change->serializedPayload.length = msg.length; + // Serialize the message using the provided PubSubType + bool result = pubsubtype->serialize(&msg, &payload, DataRepresentationId_t::XCDR2_DATA_REPRESENTATION); + // If serialization was successful, update the change and add it to the WriterHistory + if (result) + { + change->serializedPayload.length += payload.length; + change->serializedPayload.pos += payload.pos; + result = writer_history->add_change(change); + } + // Release the payload data + payload.data = nullptr; - SerializedPayload_t payload; - payload.max_size = change->serializedPayload.max_size - 4; - payload.data = change->serializedPayload.data + 4; - if (valid && reply_type_.serialize(&reply, &payload, DataRepresentationId_t::XCDR2_DATA_REPRESENTATION)) - { - change->serializedPayload.length += payload.length; - change->serializedPayload.pos += payload.pos; - payload.data = nullptr; - return builtin_reply_writer_history_->add_change(change); - } + // If adding the change to WriterHistory failed, remove the change + if (!result) + { + writer_history->remove_change(change); } - builtin_request_writer_history_->remove_change(change); - return false; + + return result; } -bool TypeLookupManager::receive_request( +bool TypeLookupManager::prepare_receive_payload( fastrtps::rtps::CacheChange_t& change, - TypeLookup_Request& request) const + SerializedPayload_t& payload) const { CDRMessage_t msg(change.serializedPayload); msg.pos += 1; - octet encapsulation = 0; - CDRMessage::readOctet(&msg, &encapsulation); - if (encapsulation == PL_CDR_BE) - { - msg.msg_endian = BIGEND; - } - else if (encapsulation == PL_CDR_LE) - { - msg.msg_endian = LITTLEEND; - } - else + + payload.max_size = change.serializedPayload.max_size; + payload.length = change.serializedPayload.length; + payload.data = change.serializedPayload.data; + return true; +} + +bool TypeLookupManager::receive( + fastrtps::rtps::CacheChange_t& change, + TypeLookup_Request& request) const +{ + if (!receive_impl(change, request, &request_type_)) { + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error receiving request."); return false; } - change.serializedPayload.encapsulation = static_cast(encapsulation); - msg.pos += 2; // Skip encapsulation options. - SerializedPayload_t payload; - payload.max_size = change.serializedPayload.max_size - 4; - payload.length = change.serializedPayload.length - 4; - payload.data = change.serializedPayload.data + 4; - bool result = request_type_.deserialize(&payload, &request); - payload.data = nullptr; - if (result && request.header().instanceName() != local_instance_name_) + //Compare only the "dds.builtin.TOS." + guid.guidPrefix + if ((request.header().instanceName().to_string()).substr(0, 40) != local_instance_name_.substr(0, 40)) { // Ignore request - result = false; + return false; } - return result; + return true; } -bool TypeLookupManager::receive_reply( +bool TypeLookupManager::receive( fastrtps::rtps::CacheChange_t& change, TypeLookup_Reply& reply) const { - CDRMessage_t msg(change.serializedPayload); - msg.pos += 1; - octet encapsulation = 0; - CDRMessage::readOctet(&msg, &encapsulation); - if (encapsulation == PL_CDR_BE) - { - msg.msg_endian = BIGEND; - } - else if (encapsulation == PL_CDR_LE) + if (!receive_impl(change, reply, &reply_type_)) { - msg.msg_endian = LITTLEEND; + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE, "Error receiving reply."); + return false; } - else + + if (guid_dds_2_rtps(reply.header().relatedRequestId().writer_guid()) != builtin_request_writer_->getGuid()) { + // Ignore reply return false; } - change.serializedPayload.encapsulation = static_cast(encapsulation); - msg.pos += 2; // Skip encapsulation options. + return true; +} +template +bool TypeLookupManager::receive_impl( + fastrtps::rtps::CacheChange_t& change, + Type& msg, + PubSubType* pubsubtype) const +{ SerializedPayload_t payload; - payload.max_size = change.serializedPayload.max_size - 4; - payload.length = change.serializedPayload.length - 4; - payload.data = change.serializedPayload.data + 4; - bool result = reply_type_.deserialize(&payload, &reply); - payload.data = nullptr; - if (result && - guid_dds_2_rtps(reply.header().relatedRequestId().writer_guid()) != builtin_request_writer_->getGuid()) + if (!prepare_receive_payload(change, payload)) { - // Ignore reply - result = false; + return false; } + + bool result = pubsubtype->deserialize(&payload, &msg); + payload.data = nullptr; + return result; } std::string TypeLookupManager::get_instance_name( - const fastrtps::rtps::GuidPrefix_t guid) const + const fastrtps::rtps::GUID_t guid) const { std::stringstream ss; - ss << guid; + ss << std::hex; + for (const auto& elem : guid.guidPrefix.value) + { + ss << std::setw(2) << std::setfill('0') << static_cast(elem); + } + for (const auto& elem : guid.entityId.value) + { + ss << std::setw(2) << std::setfill('0') << static_cast(elem); + } + std::string str = ss.str(); std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); + return static_cast(std::tolower(c)); }); - str.erase(std::remove(str.begin(), str.end(), '.'), str.end()); return "dds.builtin.TOS." + str; } -void TypeLookupManager::request_cache_change_acked( +void TypeLookupManager::remove_builtin_request_writer_history_change( fastrtps::rtps::CacheChange_t* change) { builtin_request_writer_history_->remove_change(change); } -void TypeLookupManager::reply_cache_change_acked( +void TypeLookupManager::remove_builtin_reply_writer_history_change( fastrtps::rtps::CacheChange_t* change) { builtin_reply_writer_history_->remove_change(change); diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp index 56780262461..a9b90c92bb3 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp @@ -17,8 +17,8 @@ * */ -#ifndef _FASTDDS_TYPELOOKUP_SERVICE_MANAGER_HPP -#define _FASTDDS_TYPELOOKUP_SERVICE_MANAGER_HPP +#ifndef _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_MANAGER_HPP_ +#define _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_MANAGER_HPP_ #include #include @@ -104,9 +104,9 @@ namespace builtin { const SampleIdentity INVALID_SAMPLE_IDENTITY; using AsyncGetTypeWriterCallback = std::function< - void (eprosima::ProxyPool::smart_ptr && temp_writer_data)>; + void (eprosima::ProxyPool::smart_ptr&)>; using AsyncGetTypeReaderCallback = std::function< - void (eprosima::ProxyPool::smart_ptr && temp_reader_data)>; + void (eprosima::ProxyPool::smart_ptr&)>; /** * Class TypeLookupManager that implements the TypeLookup Service described in the DDS-XTYPES 1.3 specification. @@ -115,7 +115,9 @@ using AsyncGetTypeReaderCallback = std::function< class TypeLookupManager { friend class TypeLookupRequestListener; + friend class TypeLookupRequestWListener; friend class TypeLookupReplyListener; + friend class TypeLookupReplyWListener; public: @@ -144,7 +146,7 @@ class TypeLookupManager /** * Remove remote endpoints from the typelookup service. - * @param pdata Pointer to the ParticipantProxyData to remove + * @param pdata Pointer to the ParticipantProxyData to remove. */ void remove_remote_endpoints( fastrtps::rtps::ParticipantProxyData* pdata); @@ -153,23 +155,25 @@ class TypeLookupManager * Create and send a request using the builtin TypeLookup Service to retrieve all the type dependencies * associated with a sequence of TypeIdentifiers. * @param id_seq[in] Sequence of TypeIdentifiers for which dependencies are needed. - * @param type_server[in] GuidPrefix corresponding to the remote participant which TypeInformation is being solved. - * @return The SampleIdentity of the request sended. + * @param type_server[in] GUID corresponding to the remote participant which TypeInformation is being resolved. + * @param continuation_point[in] Continuation point for a previous partially answered request. + * @return The SampleIdentity of the sent request. */ SampleIdentity get_type_dependencies( const xtypes::TypeIdentifierSeq& id_seq, - const fastrtps::rtps::GuidPrefix_t& type_server) const; + const fastrtps::rtps::GUID_t& type_server, + const std::vector& continuation_point = std::vector()) const; /** - * Create and send a request using the builtin TypeLookup Service to retrieve TypeObjects associated with a + * Create and send a request using the built-in TypeLookup Service to retrieve TypeObjects associated with a * sequence of TypeIdentifiers. * @param id_seq[in] Sequence of TypeIdentifiers for which TypeObjects are to be retrieved. - * @param type_server[in] GuidPrefix corresponding to the remote participant which TypeInformation is being solved. - * @return The SampleIdentity of the request sended. + * @param type_server[in] GUID corresponding to the remote participant whose TypeInformation is being resolved. + * @return The SampleIdentity of the sent request. */ SampleIdentity get_types( const xtypes::TypeIdentifierSeq& id_seq, - const fastrtps::rtps::GuidPrefix_t& type_server) const; + const fastrtps::rtps::GUID_t& type_server) const; /** * Use builtin TypeLookup service to solve the type and dependencies of a given TypeInformation. @@ -181,34 +185,15 @@ class TypeLookupManager * RETCODE_ERROR if any request was not sent correctly. */ ReturnCode_t async_get_type( - eprosima::ProxyPool::smart_ptr&& temp_proxy_data, + eprosima::ProxyPool::smart_ptr& temp_proxy_data, const AsyncGetTypeWriterCallback& callback); ReturnCode_t async_get_type( - eprosima::ProxyPool::smart_ptr&& temp_proxy_data, + eprosima::ProxyPool::smart_ptr& temp_proxy_data, const AsyncGetTypeReaderCallback& callback); -private: +protected: /** - * Checks if the given TypeIdentfierWithSize is known by the TypeObjectRegistry. - * Uses get_type_dependencies() and get_types() to get those that are not known. - * Adds a callback to the async_get_type_callbacks_ entry of the TypeIdentfierWithSize, or creates a new one if - * TypeIdentfierWithSize was not in the map before - * @param temp_proxy_data[in] Temporary Writer/Reader ProxyData that originated the request. - * @param callback[in] Callback to add. - * @return ReturnCode_t RETCODE_OK if type is known. - * RETCODE_NO_DATA if the type is being discovered. - * RETCODE_ERROR if the request was not sent or the callback was not added correctly. - */ - ReturnCode_t check_type_identifier_received( - eprosima::ProxyPool::smart_ptr&& temp_writer_data, - const AsyncGetTypeWriterCallback& callback); - ReturnCode_t check_type_identifier_received( - eprosima::ProxyPool::smart_ptr&& temp_reader_data, - const AsyncGetTypeReaderCallback& callback); - - /** - * Implementation for check_type_identifier_received method. * Checks if the given TypeIdentfierWithSize is known by the TypeObjectRegistry. * Uses get_type_dependencies() and get_types() to get those that are not known. * Adds a callback to the async_get_type_callbacks_ entry of the TypeIdentfierWithSize, or creates a new one if @@ -221,19 +206,26 @@ class TypeLookupManager * RETCODE_ERROR if the request was not sent or the callback was not added correctly. */ template - ReturnCode_t check_type_identifier_received_impl( - typename eprosima::ProxyPool::smart_ptr&& temp_proxy_data, + ReturnCode_t check_type_identifier_received( + typename eprosima::ProxyPool::smart_ptr& temp_proxy_data, const AsyncCallback& callback, std::unordered_map::smart_ptr, AsyncCallback>>>& async_get_type_callbacks); + /** + * Notifies callbacks for a given TypeIdentfierWithSize. + * @param type_identifier_with_size[in] TypeIdentfierWithSize of the callbacks to notify. + */ + void notify_callbacks( + xtypes::TypeIdentfierWithSize type_identifier_with_size); + /** * Adds a callback to the async_get_type_callbacks_ entry of the TypeIdentfierWithSize, or creates a new one if - * TypeIdentfierWithSize was not in the map before - * @param request[in] SampleIdentity of the request + * TypeIdentfierWithSize was not in the map before. + * @param request[in] SampleIdentity of the request. * @param type_identifier_with_size[in] TypeIdentfierWithSize that originated the request. - * @return true if added. false otherwise + * @return true if added. false otherwise. */ bool add_async_get_type_request( const SampleIdentity& request, @@ -242,49 +234,104 @@ class TypeLookupManager /** * Removes a TypeIdentfierWithSize from the async_get_type_callbacks_. * @param type_identifier_with_size[in] TypeIdentfierWithSize to be removed. - * @return true if removed. false otherwise + * @return true if removed, false otherwise. */ bool remove_async_get_type_callback( const xtypes::TypeIdentfierWithSize& type_identifier_with_size); /** - * Complete requests common fields, create CacheChange, serialize request and add change to writer history. - * @param type_id[in] TypeIdentfierWithSize that originated the request. + * Removes a SampleIdentity from the async_get_type_callbacks_. + * @param request[in] SampleIdentity to be removed. + * @return true if removed, false otherwise. + */ + bool remove_async_get_type_request( + SampleIdentity request); + + /** + * Creates a TypeLookup_Request for the given type_server. + * @param type_server[in] GUID corresponding to the remote participant. + * @param pupsubtype[out] PubSubType in charge of TypeLookup_Request . + * @return the TypeLookup_Request created. + */ + TypeLookup_Request* create_request( + const fastrtps::rtps::GUID_t& type_server, + TypeLookup_RequestPubSubType& pupsubtype) const; + + /** + * Uses the send_impl with the appropriate parameters. * @param request[in] TypeLookup_Request to be sent. * @return true if request was sent, false otherwise. */ - bool send_request( - const fastrtps::rtps::GuidPrefix_t& type_server, + bool send( TypeLookup_Request& request) const; - /** - * Complete reply common fields, create CacheChange, serialize reply and add change to writer history. + * Uses the send_impl with the appropriate parameters. * @param reply[in] TypeLookup_Reply to be sent. * @return true if reply was sent, false otherwise. */ - bool send_reply( + bool send( TypeLookup_Reply& reply) const; /** - * Used for request reception. Deserialize the request and check if it is directed to the local DomainParticipant. - * @param change[in] CacheChange_t of the request - * @param request[out] TypeLookup_Request after deserialization + * Implementation for the send methods. + * Creates CacheChange, serializes the message and adds change to writer history. + * @param msg[in] Message to be sent. + * @param pubsubtype[in] PubSubType of the msg. + * @param writer[in]Pointer to the RTPSWriter. + * @param writer_history[in] Pointer to the Writer History. + * @return true if message was sent, false otherwise. + */ + template + bool send_impl( + Type& msg, + PubSubType* pubsubtype, + fastrtps::rtps::StatefulWriter* writer, + fastrtps::rtps::WriterHistory* writer_history) const; + + /** + * Prepares the received payload of a CacheChange before deserializing. + * @param change[in] CacheChange_t received. + * @param payload[out] SerializedPayload_t prepared. + * @return true if received payload is prepared, false otherwise. + */ + bool prepare_receive_payload( + fastrtps::rtps::CacheChange_t& change, + fastrtps::rtps::SerializedPayload_t& payload) const; + + /** + * Uses the receive_impl with the appropriate parameters and checks if it is directed to the local DomainParticipant. + * @param change[in] CacheChange_t of the request. + * @param request[out] TypeLookup_Request after deserialization. * @return true if the request is deserialized and directed to the local participant, false otherwise. */ - bool receive_request( + bool receive( fastrtps::rtps::CacheChange_t& change, TypeLookup_Request& request) const; /** - * Used for reply reception. Deserialize and check that the reply's recipient is the local participant. - * @param change[in] CacheChange_t of the reply - * @param reply[out] TypeLookup_Reply after deserialize + * Uses the receive_impl with the appropriate parameters and checks if the reply's recipient is the local participant. + * @param change[in] CacheChange_t of the reply. + * @param reply[out] TypeLookup_Reply after deserialization. * @return true if the request is deserialized and the reply's recipient is us, false otherwise. */ - bool receive_reply( + bool receive( fastrtps::rtps::CacheChange_t& change, TypeLookup_Reply& reply) const; + /** + * Implementation for the receive methods. + * Derializes the message received. + * @param change[in] CacheChange_t of the message. + * @param msg[in] Message to be sent. + * @param pubsubtype[in] PubSubType of the msg. + * @return true if message is correct, false otherwise. + */ + template + bool receive_impl( + fastrtps::rtps::CacheChange_t& change, + Type& msg, + PubSubType* pubsubtype) const; + /** * Get the RTPS participant * @return RTPS participant @@ -295,12 +342,12 @@ class TypeLookupManager } /** - * Create instance name as defined in section 7.6.3.3.4 XTypes 1.3 specification - * @param guid[in] GuidPrefix_t to be included in the instance name + * Create instance name as defined in section 7.6.3.3.4 XTypes 1.3 specification. + * @param guid[in] GUID to be included in the instance name. * @return The instance name. */ std::string get_instance_name( - const fastrtps::rtps::GuidPrefix_t guid) const; + const fastrtps::rtps::GUID_t guid) const; /** * Create the builtin endpoints used in the TypeLookupManager. @@ -308,83 +355,91 @@ class TypeLookupManager */ bool create_endpoints(); - //!Pointer to the local RTPSParticipant. + /** + * Removes a change from the builtin_request_writer_history_. + * @param change[in] CacheChange_t to be removed. + */ + void remove_builtin_request_writer_history_change( + fastrtps::rtps::CacheChange_t* change); + + /** + * Removes a change from the builtin_reply_writer_history_. + * @param change[in] CacheChange_t to be removed. + */ + void remove_builtin_reply_writer_history_change( + fastrtps::rtps::CacheChange_t* change); + + //! Pointer to the local RTPSParticipant. fastrtps::rtps::RTPSParticipantImpl* participant_ = nullptr; - //!Own instance name + //! Own instance name. std::string local_instance_name_; - //!Pointer to the BuiltinProtocols class. + //! Pointer to the BuiltinProtocols class. fastrtps::rtps::BuiltinProtocols* builtin_protocols_ = nullptr; - //!Pointer to the RTPSWriter for the TypeLookup_Request. + //! Pointer to the RTPSWriter for the TypeLookup_Request. fastrtps::rtps::StatefulWriter* builtin_request_writer_ = nullptr; - //!Pointer to the RTPSReader for the TypeLookup_Request. + //! Pointer to the RTPSReader for the TypeLookup_Request. fastrtps::rtps::StatefulReader* builtin_request_reader_ = nullptr; - //!Pointer to the RTPSWriter for the TypeLookup_Reply. + //! Pointer to the RTPSWriter for the TypeLookup_Reply. fastrtps::rtps::StatefulWriter* builtin_reply_writer_ = nullptr; - //!Pointer to the RTPSReader for the TypeLookup_Reply. + //! Pointer to the RTPSReader for the TypeLookup_Reply. fastrtps::rtps::StatefulReader* builtin_reply_reader_ = nullptr; - //!Pointer to the Writer History of TypeLookup_Request + //! Pointer to the Writer History of TypeLookup_Request. fastrtps::rtps::WriterHistory* builtin_request_writer_history_ = nullptr; - //!Pointer to the Writer History of TypeLookup_Reply + //! Pointer to the Writer History of TypeLookup_Reply. fastrtps::rtps::WriterHistory* builtin_reply_writer_history_ = nullptr; - //!Pointer to the Reader History of TypeLookup_Request + //! Pointer to the Reader History of TypeLookup_Request. fastrtps::rtps::ReaderHistory* builtin_request_reader_history_ = nullptr; - //!Pointer to the Reader History of TypeLookup_Reply + //! Pointer to the Reader History of TypeLookup_Reply. fastrtps::rtps::ReaderHistory* builtin_reply_reader_history_ = nullptr; - //!Request Listener object. + //! Request Listener object. TypeLookupRequestListener* request_listener_ = nullptr; - //!Reply Listener object. + //! Reply Listener object. TypeLookupReplyListener* reply_listener_ = nullptr; - //!Mutex to protect access to temp_reader_proxy_data_ and temp_writer_proxy_data_ + //! Mutex to protect access to temp_reader_proxy_data_ and temp_writer_proxy_data_. std::mutex temp_data_lock_; - //!Pointer to the temp ReaderProxyData used for assigments + //! Pointer to the temp ReaderProxyData used for assigments. fastrtps::rtps::ReaderProxyData* temp_reader_proxy_data_ = nullptr; - //!Pointer to the temp WriterProxyData used for assigments + //! Pointer to the temp WriterProxyData used for assigments. fastrtps::rtps::WriterProxyData* temp_writer_proxy_data_ = nullptr; mutable fastrtps::rtps::SequenceNumber_t request_seq_number_; mutable TypeLookup_RequestPubSubType request_type_; mutable TypeLookup_ReplyPubSubType reply_type_; - //!Mutex to protect access to async_get_type_callbacks_ and async_get_type_requests_ + //! Mutex to protect access to async_get_type_callbacks_ and async_get_type_requests_. std::mutex async_get_types_mutex_; - //!Collection of all the WriterProxyData and their callbacks related to a TypeIdentfierWithSize, hashed by its TypeIdentfierWithSize. + //! Collection of all the WriterProxyData and their callbacks related to a TypeIdentfierWithSize, hashed by its TypeIdentfierWithSize. std::unordered_map < xtypes::TypeIdentfierWithSize, std::vector::smart_ptr, AsyncGetTypeWriterCallback>>> async_get_type_writer_callbacks_; - //!Collection of all the ReaderProxyData and their callbacks related to a TypeIdentfierWithSize, hashed by its TypeIdentfierWithSize. + //! Collection of all the ReaderProxyData and their callbacks related to a TypeIdentfierWithSize, hashed by its TypeIdentfierWithSize. std::unordered_map < xtypes::TypeIdentfierWithSize, std::vector::smart_ptr, AsyncGetTypeReaderCallback>>> async_get_type_reader_callbacks_; - //!Collection SampleIdentity and the TypeIdentfierWithSize it originated from, hashed by its SampleIdentity. + //! Collection of all SampleIdentity and the TypeIdentfierWithSize it originated from, hashed by its SampleIdentity. std::unordered_map async_get_type_requests_; - - void request_cache_change_acked( - fastrtps::rtps::CacheChange_t* change); - - void reply_cache_change_acked( - fastrtps::rtps::CacheChange_t* change); }; } /* namespace builtin */ } /* namespace dds */ } /* namespace fastdds */ } /* namespace eprosima */ -#endif /* _FASTDDS_TYPELOOKUP_SERVICE_MANAGER_HPP */ +#endif /* _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_MANAGER_HPP_ */ diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp index 0b0092b03e1..8823824099e 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.cpp @@ -19,22 +19,15 @@ #include -#include #include -#include -#include -#include -#include -#include -#include +#include #include - +#include using eprosima::fastrtps::rtps::RTPSReader; using eprosima::fastrtps::rtps::CacheChange_t; using eprosima::fastdds::dds::Log; - using eprosima::fastrtps::rtps::c_EntityId_TypeLookup_reply_writer; namespace eprosima { @@ -46,67 +39,277 @@ TypeLookupReplyListener::TypeLookupReplyListener( TypeLookupManager* manager) : typelookup_manager_(manager) { + start_reply_processor_thread(); } TypeLookupReplyListener::~TypeLookupReplyListener() { + stop_reply_processor_thread(); } -void TypeLookupReplyListener::onNewCacheChangeAdded( - RTPSReader* reader, - const CacheChange_t* const changeIN) +void TypeLookupReplyListener::start_reply_processor_thread() { - CacheChange_t* change = const_cast(changeIN); + std::unique_lock guard(replies_processor_cv_mutex_); + // Check if is not already in progress and the thread is not joinable + if (!processing_ && !replies_processor_thread.joinable()) + { + processing_ = true; + // Lambda function to be executed by the thread + auto thread_func = [this]() + { + process_reply(); + }; + // Create and start the processing thread + replies_processor_thread = eprosima::create_thread(thread_func, + typelookup_manager_->participant_->getAttributes().typelookup_service_thread, + "dds.tls.replies.%u"); + } +} - if (change->writerGUID.entityId != c_EntityId_TypeLookup_reply_writer) +void TypeLookupReplyListener::stop_reply_processor_thread() +{ { - EPROSIMA_LOG_WARNING(TL_REPLY_READER, "Received data from a bad endpoint."); - reader->getHistory()->remove_change(change); + // Set processing_ to false to signal the processing thread to stop + std::unique_lock guard(replies_processor_cv_mutex_); + processing_ = false; } - EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE_REPLY_LISTENER, "Received new cache change"); - TypeLookup_Reply reply; - if (typelookup_manager_->receive_reply(*change, reply)) + if (replies_processor_thread.joinable()) { - switch (reply.return_value()._d()) + // Notify the processing thread to wake up and check the exit condition + replies_processor_cv_.notify_all(); + // Check if the calling thread is not the processing thread and join it + if (!replies_processor_thread.is_calling_thread()) { - case TypeLookup_getTypes_HashId: + replies_processor_thread.join(); + } + } +} + +void TypeLookupReplyListener::process_reply() +{ + std::unique_lock guard(replies_processor_cv_mutex_); + + while (processing_) + { + // Wait until either processing is done or there are replies in the queue + replies_processor_cv_.wait(guard, + [&]() + { + return !processing_ || !replies_queue_.empty(); + }); + + if (!replies_queue_.empty()) + { + TypeLookup_Reply& reply = replies_queue_.front().reply; { - const TypeLookup_getTypes_Out types = reply.return_value().getType().result(); - for (auto pair : types.types()) + // Process the TypeLookup_Reply based on its type + switch (reply.return_value()._d()) { - if (pair.type_object()._d() == eprosima::fastdds::dds::xtypes::EK_COMPLETE) // Just in case + case TypeLookup_getTypes_HashId: { - // TODO (adelcampo) Change to xtypes with TypeObjectRegistry - // If build_dynamic_type failed, just sent the nullptr already contained on it. - // tlm_->participant_->getListener()->on_type_discovery( - // tlm_->participant_->getUserRTPSParticipant(), - // reply.header.requestId, - // "", // No topic_name available - // &pair.type_identifier(), - // &pair.type_object(), - // DynamicType_ptr(nullptr)); + check_get_types_reply(reply.header().relatedRequestId(), + reply.return_value().getType().result(), reply.header().relatedRequestId()); + break; } + case TypeLookup_getDependencies_HashId: + { + check_get_type_dependencies_reply( + reply.header().relatedRequestId(), replies_queue_.front().type_server, + reply.return_value().getTypeDependencies().result()); + break; + } + default: + // If the type of request is not known, log an error + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Received unknown reply operation type in type lookup service."); + break; } - // TODO Call a callback once the job is done - break; } - case TypeLookup_getDependencies_HashId: + // Remove the requests from the queue + replies_queue_.pop(); + } + } +} + +void TypeLookupReplyListener::check_get_types_reply( + const SampleIdentity& request_id, + const TypeLookup_getTypes_Out& reply, + SampleIdentity related_request) +{ + // Check if the received reply SampleIdentity corresponds to an outstanding request + auto requests_it = typelookup_manager_->async_get_type_requests_.find(request_id); + if (requests_it != typelookup_manager_->async_get_type_requests_.end()) + { + ReturnCode_t register_result = RETCODE_OK; + for (xtypes::TypeIdentifierTypeObjectPair pair : reply.types()) + { + if (RETCODE_OK != fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + register_type_object(pair.type_identifier(), pair.type_object())) { - //const TypeLookup_getTypeDependencies_Out dependencies = - // reply.return_value.getTypeDependencies().result(); - - // TODO (adelcampo) Change to xtypes with TypeObjectRegistry - // tlm_->get_RTPS_participant()->getListener()->on_type_dependencies_reply( - // tlm_->builtin_protocols_->mp_participantImpl->getUserRTPSParticipant(), - // reply.header().relatedRequestId(), - // reply.return_value().getTypeDependencies().result().dependent_typeids()); - break; + // If any of the types is not registered, log error + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Error registering remote type"); + register_result = RETCODE_ERROR; } - default: - break; } + + if (RETCODE_OK == register_result) + { + // Check if the get_type_dependencies related to this reply required a continuation_point + std::unique_lock guard(replies_with_continuation_mutex_); + auto it = std::find(replies_with_continuation_.begin(), replies_with_continuation_.end(), related_request); + if (it != replies_with_continuation_.end()) + { + // If it did, remove it from the list and continue + replies_with_continuation_.erase(it); + } + else + { + // If it did not, check that the type that originated the request is consistent + // before notifying the callbacks associated with the request + try + { + xtypes::TypeObject type_object; + fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer().get_type_object( + requests_it->second.type_id(), type_object); + xtypes::TypeObjectUtils::type_object_consistency(type_object); + + typelookup_manager_->notify_callbacks(requests_it->second); + } + catch (const std::exception& exception) + { + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Error registering remote type: " << exception.what()); + } + } + } + + // Remove the processed SampleIdentity from the outstanding requests + typelookup_manager_->remove_async_get_type_request(request_id); } +} + +void TypeLookupReplyListener::check_get_type_dependencies_reply( + const SampleIdentity& request_id, + const fastrtps::rtps::GUID_t type_server, + const TypeLookup_getTypeDependencies_Out& reply) +{ + // Check if the received reply SampleIdentity corresponds to an outstanding request + auto requests_it = typelookup_manager_->async_get_type_requests_.find(request_id); + if (requests_it == typelookup_manager_->async_get_type_requests_.end()) + { + // The reply is not associated with any outstanding request, ignore it + return; + } + + // Add the dependent types to the list for the get_type request + xtypes::TypeIdentifierSeq needed_types; + std::unordered_set unique_types; + + for (xtypes::TypeIdentfierWithSize type : reply.dependent_typeids()) + { + // Check if the type is known + if (!fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + is_type_identifier_known(type)) + { + // Insert the type into the unordered_set and check if the insertion was successful + if (unique_types.insert(type.type_id()).second) + { + // If the insertion was successful, it means the type was not already in the set + needed_types.push_back(type.type_id()); + } + // If the insertion was not successful, the type is a duplicate and can be ignored + } + } + + // If there is no continuation point, add the parent type + if (reply.continuation_point().empty()) + { + needed_types.push_back(requests_it->second.type_id()); + } + // Make a new request with the continuation point + else + { + SampleIdentity next_request_id = typelookup_manager_-> + get_type_dependencies({requests_it->second.type_id()}, type_server, + reply.continuation_point()); + if (INVALID_SAMPLE_IDENTITY != next_request_id) + { + // Store the sent requests and associated TypeIdentfierWithSize + typelookup_manager_->add_async_get_type_request(next_request_id, requests_it->second); + } + else + { + // Failed to send request + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, "Failed to send get_type_dependencies request"); + } + } + + // Send the type request + SampleIdentity get_types_request = typelookup_manager_->get_types(needed_types, type_server); + + if (INVALID_SAMPLE_IDENTITY != get_types_request) + { + // Store the type request + typelookup_manager_->add_async_get_type_request(get_types_request, requests_it->second); + + // If this get_types request has a continuation_point, store it in the list + if (!reply.continuation_point().empty()) + { + std::unique_lock guard(replies_with_continuation_mutex_); + replies_with_continuation_.push_back(get_types_request); + } + } + else + { + // Failed to send request + EPROSIMA_LOG_ERROR(TYPELOOKUP_SERVICE_REPLY_LISTENER, "Failed to send get_types request"); + } + + // Remove the processed SampleIdentity from the outstanding requests + typelookup_manager_->remove_async_get_type_request(request_id); +} + +void TypeLookupReplyListener::onNewCacheChangeAdded( + RTPSReader* reader, + const CacheChange_t* const change_in) +{ + CacheChange_t* change = const_cast(change_in); + + // Check if the data is received from the expected TypeLookup Reply writer + if (change->writerGUID.entityId != c_EntityId_TypeLookup_reply_writer) + { + // Log a warning and remove the change from the history + EPROSIMA_LOG_WARNING(TL_REPLY_READER, "Received data from a bad endpoint."); + reader->getHistory()->remove_change(change); + return; + } + + // Process the received TypeLookup Reply and handle different types of replies + TypeLookup_Reply reply; + if (typelookup_manager_->receive(*change, reply)) + { + // Check if the reply has any exceptions + if (reply.header().remoteEx() != rpc::RemoteExceptionCode_t::REMOTE_EX_OK) + { + // TODO: Implement specific handling for each exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REPLY_LISTENER, + "Received reply with exception code: " << static_cast(reply.header().remoteEx())); + // If the reply was not ok, ignore it + return; + } + + // Add reply to the processing queue + replies_queue_.push(ReplyWithServerGUID{reply, change->writerGUID}); + { + // Notify processor + std::unique_lock guard(replies_processor_cv_mutex_); + replies_processor_cv_.notify_all(); + } + } + + // Remove the processed cache change from the history reader->getHistory()->remove_change(change); } @@ -114,10 +317,11 @@ void TypeLookupReplyListener::onWriterChangeReceivedByAll( fastrtps::rtps::RTPSWriter*, fastrtps::rtps::CacheChange_t* change) { - typelookup_manager_->reply_cache_change_acked(change); + typelookup_manager_->remove_builtin_reply_writer_history_change(change); } } // namespace builtin + } // namespace dds } // namespace fastdds } // namespace eprosima diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.hpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.hpp index 1209c5c1a41..aa2df3fbaf1 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.hpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupReplyListener.hpp @@ -17,12 +17,22 @@ * */ -#ifndef TYPELOOKUP_REPLY_LISTENER_HPP_ -#define TYPELOOKUP_REPLY_LISTENER_HPP_ -#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC +#ifndef _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REPLY_LISTENER_HPP_ +#define _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REPLY_LISTENER_HPP_ -#include -#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include namespace eprosima { namespace fastrtps { @@ -40,6 +50,12 @@ namespace builtin { class TypeLookupManager; +struct ReplyWithServerGUID +{ + TypeLookup_Reply reply; + fastrtps::rtps::GUID_t type_server; +}; + /** * Class TypeLookupReplyListener that receives the typelookup request messages of remote endpoints. * @ingroup TYPES_MODULE @@ -50,7 +66,7 @@ class TypeLookupReplyListener : public fastrtps::rtps::ReaderListener, public fa /** * @brief Constructor - * @param manager Pointer to the TypeLookupManager + * @param manager Pointer to the TypeLookupManager. */ TypeLookupReplyListener( TypeLookupManager* manager); @@ -60,33 +76,81 @@ class TypeLookupReplyListener : public fastrtps::rtps::ReaderListener, public fa */ virtual ~TypeLookupReplyListener() override; +protected: + + /** + * @brief Starts the thread that process the received replies. + */ + void start_reply_processor_thread(); + /** - * @brief Method call when this class is notified of a new cache change - * @param reader The reader receiving the cache change - * @param change The cache change + * @brief Stops the thread that process the received replies. + */ + void stop_reply_processor_thread(); + + /** + * @brief Process the replies in the queue. + */ + void process_reply(); + + /** + * @brief Registers TypeIdentifier and TypeObject in TypeObjectRegistry. + * This method also notifies all type related callbacks and removes the current SampleIdentity from the pending request list. + * @param request_id[in] The SampleIdentity of the request. + * @param reply[in] The reply data. + * @param related_request[in] The request that this reply answers. + */ + void check_get_types_reply( + const SampleIdentity& request_id, + const TypeLookup_getTypes_Out& reply, + SampleIdentity related_request); + + /** + * @brief Checks if all dependencies are solved. + * If they are not, sends next request and adds it to the list. + * If they are, sends get_types request and adds it to the list. + * Also removes the current SampleIdentity from the list. + * @param request_id[in] The SampleIdentity of the request. + * @param type_server[in] GUID corresponding to the remote participant which TypeInformation is being solved. + * @param reply[in] The reply data. + */ + void check_get_type_dependencies_reply( + const SampleIdentity& request_id, + const fastrtps::rtps::GUID_t type_server, + const TypeLookup_getTypeDependencies_Out& reply); + + /** + * @brief Method called when this class is notified of a new cache change. + * @param reader The reader receiving the cache change. + * @param change The cache change. */ void onNewCacheChangeAdded( fastrtps::rtps::RTPSReader* reader, const fastrtps::rtps::CacheChange_t* const change) override; - /** - * @brief This method is called when all the readers matched with this Writer acknowledge that a cache - * change has been received. - * @param change The cache change - */ void onWriterChangeReceivedByAll( fastrtps::rtps::RTPSWriter*, fastrtps::rtps::CacheChange_t* change) override; -private: - - //! A pointer to the typelookup manager + //! A pointer to the typelookup manager. TypeLookupManager* typelookup_manager_; + + //! Mutex to protect access to replies_with_continuation_. + std::mutex replies_with_continuation_mutex_; + + //! Collection of the replies that needed continuation points. + std::vector replies_with_continuation_; + + eprosima::thread replies_processor_thread; + std::queue replies_queue_; + std::mutex replies_processor_cv_mutex_; + std::condition_variable replies_processor_cv_; + bool processing_ = false; + rtps::ThreadSettings replies_processor_thread_settings_; }; } /* namespace builtin */ } /* namespace dds */ } /* namespace fastdds */ } /* namespace eprosima */ -#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC -#endif /* TYPELOOKUP_REPLY_LISTENER_HPP_*/ +#endif /* _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REPLY_LISTENER_HPP_*/ diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp index dfe39fcb5f8..608ac76f5f9 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.cpp @@ -19,15 +19,11 @@ #include -#include - -#include -#include #include -#include -#include -#include +#include +#include +#include using eprosima::fastrtps::rtps::RTPSReader; using eprosima::fastrtps::rtps::CacheChange_t; @@ -40,100 +36,414 @@ namespace fastdds { namespace dds { namespace builtin { +//! Constant that specifies the maximum number of dependent types to be included per reply. +//! This number is calculated considering the MTU. +const int32_t MAX_DEPENDENCIES_PER_REPLY = 75; + +/** + * @brief Calculates the opaque value of continuation point. + * @param continuation_point[in] The continuation point. + * @return The value of the continuation_point. + */ +inline size_t calculate_continuation_point( + const std::vector& continuation_point) +{ + size_t result = 0; + for (size_t i = 0; i < continuation_point.size(); ++i) + { + result = (result << 8) | continuation_point[i]; + } + return result; +} + +/** + * @brief Creates a continuation point with the given value. + * @param value[in] The desired value. + * @return The continuation_point. + */ +inline std::vector create_continuation_point( + size_t value) +{ + std::vector continuation_point(32, 0); + + for (size_t value_i = 0; value_i < value; value_i++) + { + for (size_t i = continuation_point.size() - 1; i != SIZE_MAX; --i) + { + if (continuation_point[i] < 255) + { + ++continuation_point[i]; + // Break after successful increment + break; + } + else + { + continuation_point[i] = 0; + } + } + } + return continuation_point; +} + TypeLookupRequestListener::TypeLookupRequestListener( TypeLookupManager* manager) : typelookup_manager_(manager) { + start_request_processor_thread(); } TypeLookupRequestListener::~TypeLookupRequestListener() { + stop_request_processor_thread(); } -void TypeLookupRequestListener::onNewCacheChangeAdded( - RTPSReader* reader, - const CacheChange_t* const changeIN) +void TypeLookupRequestListener::start_request_processor_thread() { - CacheChange_t* change = const_cast(changeIN); + std::unique_lock guard(request_processor_cv_mutex_); + // Check if is not already in progress and the thread is not joinable + if (!processing_ && !request_processor_thread.joinable()) + { + processing_ = true; + // Lambda function to be executed by the thread + auto thread_func = [this]() + { + process_requests(); + }; + // Create and start the processing thread + request_processor_thread = eprosima::create_thread(thread_func, + typelookup_manager_->participant_->getAttributes().typelookup_service_thread, + "dds.tls.requests.%u"); + } +} - if (change->writerGUID.entityId != c_EntityId_TypeLookup_request_writer) +void TypeLookupRequestListener::stop_request_processor_thread() +{ { - EPROSIMA_LOG_WARNING(TL_REQUEST_READER, "Received data from a bad endpoint."); - reader->getHistory()->remove_change(change); + // Set processing_ to false to signal the processing thread to stop + std::unique_lock guard(request_processor_cv_mutex_); + processing_ = false; } - EPROSIMA_LOG_INFO(TYPELOOKUP_SERVICE_REQUEST_LISTENER, "Received new cache change"); - TypeLookup_Request request; - if (typelookup_manager_->receive_request(*change, request)) + if (request_processor_thread.joinable()) { - switch (request.data()._d()) + // Notify the processing thread to wake up and check the exit condition + request_processor_cv_.notify_all(); + // Check if the calling thread is not the processing thread and join it + if (!request_processor_thread.is_calling_thread()) { - case TypeLookup_getTypes_HashId: - { - const TypeLookup_getTypes_In in = request.data().getTypes(); - TypeLookup_getTypes_Out out; + request_processor_thread.join(); + } + } +} + +void TypeLookupRequestListener::process_requests() +{ + std::unique_lock guard(request_processor_cv_mutex_); - for (const xtypes::TypeIdentifier& type_id : in.type_ids()) + while (processing_) + { + // Wait until either processing is done or there are requests in the queue + request_processor_cv_.wait(guard, + [&]() { - xtypes::TypeObject obj; - // TODO (adelcampo) Change to xtypes - // const TypeIdentifier* obj_ident = factory_->typelookup_get_type(type_id, obj); - xtypes::TypeIdentifier* obj_ident = nullptr; + return !processing_ || !requests_queue_.empty(); + }); - if (obj_ident != nullptr && obj._d() != fastdds::dds::xtypes::TK_NONE) + if (!requests_queue_.empty()) + { + TypeLookup_Request& request = requests_queue_.front(); + { + // Process the TypeLookup_Request based on its type + switch (request.data()._d()) + { + case TypeLookup_getTypes_HashId: { - xtypes::TypeIdentifierTypeObjectPair pair; - pair.type_identifier(type_id); - pair.type_object(obj); - out.types().push_back(std::move(pair)); + check_get_types_request(request.header().requestId(), request.data().getTypes()); + break; } - - if (obj_ident != nullptr && !(type_id == *obj_ident)) + case TypeLookup_getDependencies_HashId: { - xtypes::TypeIdentifierPair pair; - pair.type_identifier1(*obj_ident); - pair.type_identifier2(type_id); - out.complete_to_minimal().push_back(std::move(pair)); + check_get_type_dependencies_request(request.header().requestId(), + request.data().getTypeDependencies()); + break; } + default: + // If the type of request is not known, log an error and answer with an exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Received unknown request in type lookup service."); + answer_request(request.header().requestId(), + rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_OPERATION); + break; } + } + // Remove the requests from the queue + requests_queue_.pop(); + } + } +} - TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.createData()); - TypeLookup_getTypes_Result result; - result.result(out); - reply->return_value().getType(result); - reply->header().relatedRequestId() = request.header().requestId(); +void TypeLookupRequestListener::check_get_types_request( + SampleIdentity request_id, + const TypeLookup_getTypes_In& request) +{ + // Always Sends EK_COMPLETE + // TODO: Add a property to the participant to configure this behavior. Allowing it to respond with EK_MINIMAL when possible. + TypeLookup_getTypes_Out out; + ReturnCode_t type_result = RETCODE_ERROR; + xtypes::TypeObject obj; + xtypes::TypeIdentifier complete_id; + xtypes::TypeIdentifier minimal_id; + // Iterate through requested type_ids + for (const xtypes::TypeIdentifier& type_id : request.type_ids()) + { + // If TypeIdentifier is EK_MINIMAL add complete_to_minimal to answer + if (type_id._d() == xtypes::EK_MINIMAL) + { + minimal_id = type_id; + // Get complete TypeIdentifier from registry + complete_id = fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_complementary_type_identifier(minimal_id); - typelookup_manager_->send_reply(*reply); - typelookup_manager_->reply_type_.deleteData(reply); + xtypes::TypeIdentifierPair id_pair; + id_pair.type_identifier1(complete_id); + id_pair.type_identifier2(minimal_id); + // Add the id pair to the result + out.complete_to_minimal().push_back(std::move(id_pair)); + } + else + { + complete_id = type_id; + } - break; + type_result = fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_type_object(complete_id, obj); + if (RETCODE_OK != type_result) + { + // If any object is unknown, abort and answer with exception + break; + } + + xtypes::TypeIdentifierTypeObjectPair id_obj_pair; + id_obj_pair.type_identifier(complete_id); + id_obj_pair.type_object(obj); + // Add the id/obj pair to the result + out.types().push_back(std::move(id_obj_pair)); + } + + // Handle the result based on the type_result + if (RETCODE_OK == type_result) + { + // Prepare and send the reply for successful operation + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_OK, out); + } + else if (RETCODE_NO_DATA == type_result) + { + // Log error for type not found and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not found in the registry."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + else if (RETCODE_PRECONDITION_NOT_MET == type_result) + { + // Log error for invalid argument and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not a direct hash."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_INVALID_ARGUMENT); + } +} + +void TypeLookupRequestListener::check_get_type_dependencies_request( + SampleIdentity request_id, + const TypeLookup_getTypeDependencies_In& request) +{ + std::unordered_set type_dependencies; + ReturnCode_t type_dependencies_result = RETCODE_ERROR; + if (!request.type_ids().empty()) + { + // Check if the received request has been done before and needed a continuation point + std::lock_guard lock(requests_with_continuation_mutex_); + if (!request.continuation_point().empty()) + { + auto requests_it = requests_with_continuation_.find(request.type_ids()); + if (requests_it != requests_with_continuation_.end()) + { + // Get the dependencies without checking the registry + type_dependencies = requests_it->second; + type_dependencies_result = RETCODE_OK; } - case TypeLookup_getDependencies_HashId: + else { - const TypeLookup_getTypeDependencies_In in = request.data().getTypeDependencies(); - TypeLookup_getTypeDependencies_Out out; - //for (size_t index = 0; index < in.type_ids.size(); ++index) - { - // TODO (adelcampo) Change to xtypes - // out.dependent_typeids = factory_->typelookup_get_type_dependencies( - // in.type_ids, in.continuation_point, out.continuation_point, 255); // TODO: Make configurable? - } + // If the the received request is not found, log error and answer with exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Error processing ongoing type dependencies request."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + } + else + { + // Get the dependencies from the registry + type_dependencies_result = + fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer(). + get_type_dependencies(request.type_ids(), type_dependencies); - TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.createData()); - TypeLookup_getTypeDependencies_Result result; - result.result(out); - reply->return_value().getTypeDependencies(result); - reply->header().relatedRequestId() = request.header().requestId(); + // If there are too many dependent types, store the type dependencies for future requests + if (type_dependencies_result == RETCODE_OK && type_dependencies.size() > MAX_DEPENDENCIES_PER_REPLY) + { + requests_with_continuation_.emplace(request.type_ids(), type_dependencies); + } + } + } - typelookup_manager_->send_reply(*reply); - typelookup_manager_->reply_type_.deleteData(reply); + // Handle the result based on the type_dependencies_result + if (RETCODE_OK == type_dependencies_result) + { + // Prepare and send the reply for successful operation + TypeLookup_getTypeDependencies_Out out = prepare_get_type_dependencies_response( + request.type_ids(), type_dependencies, request.continuation_point()); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_OK, out); + } + else if (RETCODE_NO_DATA == type_dependencies_result) + { + // Log error for type not found and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not found in the registry."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_UNKNOWN_EXCEPTION); + } + else if (RETCODE_BAD_PARAMETER == type_dependencies_result) + { + // Log error for invalid argument and reply with appropriate exception + EPROSIMA_LOG_WARNING(TYPELOOKUP_SERVICE_REQUEST_LISTENER, + "Requested TypeIdentifier is not a direct hash."); + answer_request(request_id, rpc::RemoteExceptionCode_t::REMOTE_EX_INVALID_ARGUMENT); + } +} - break; +TypeLookup_getTypeDependencies_Out TypeLookupRequestListener::prepare_get_type_dependencies_response( + const xtypes::TypeIdentifierSeq& id_seq, + const std::unordered_set& type_dependencies, + const std::vector& continuation_point) +{ + TypeLookup_getTypeDependencies_Out out; + + // Check if all dependencies can be sent in a single response + if (type_dependencies.size() < MAX_DEPENDENCIES_PER_REPLY) + { + for (const auto& type_identifier : type_dependencies) + { + out.dependent_typeids().emplace_back(type_identifier); + } + } + else + { + size_t start_index = 0; + // Check if a continuation point is provided, and calculate starting point if there is + if (!continuation_point.empty()) + { + start_index = calculate_continuation_point(continuation_point) * MAX_DEPENDENCIES_PER_REPLY; + } + + // Copy the dependencies within the specified range directly to out + auto start_it = std::next(type_dependencies.begin(), start_index); + auto end_it = std::next(start_it, std::min(MAX_DEPENDENCIES_PER_REPLY, + type_dependencies.size() - start_index)); + for (auto it = start_it; it != end_it; ++it) + { + out.dependent_typeids().emplace_back(*it); + } + + if ((start_index + MAX_DEPENDENCIES_PER_REPLY) > type_dependencies.size()) + { + // If all dependent types have been sent, remove from map + std::lock_guard lock(requests_with_continuation_mutex_); + auto requests_it = requests_with_continuation_.find(id_seq); + if (requests_it != requests_with_continuation_.end()) + { + requests_with_continuation_.erase(requests_it); } - default: - break; } + else + { + // Set the continuation point for the next request + out.continuation_point(create_continuation_point(calculate_continuation_point(continuation_point) + 1)); + } + } + + return out; +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypeDependencies_Out& out) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.createData()); + TypeLookup_getTypeDependencies_Result result; + result.result(out); + reply->return_value().getTypeDependencies(result); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.deleteData(reply); +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypes_Out& out) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.createData()); + TypeLookup_getTypes_Result result; + result.result(out); + reply->return_value().getType(result); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.deleteData(reply); +} + +void TypeLookupRequestListener::answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code) +{ + TypeLookup_Reply* reply = static_cast(typelookup_manager_->reply_type_.createData()); + reply->header().relatedRequestId(request_id); + reply->header().remoteEx(exception_code); + + typelookup_manager_->send(*reply); + typelookup_manager_->reply_type_.deleteData(reply); +} + +void TypeLookupRequestListener::onNewCacheChangeAdded( + RTPSReader* reader, + const CacheChange_t* const changeIN) +{ + CacheChange_t* change = const_cast(changeIN); + + // Check if the data is received from the expected TypeLookup Request writer + if (change->writerGUID.entityId != c_EntityId_TypeLookup_request_writer) + { + // Log a warning and remove the change from the history + EPROSIMA_LOG_WARNING(TL_REQUEST_READER, "Received data from a bad endpoint."); + reader->getHistory()->remove_change(change); + return; } + + // Process the received TypeLookup Request and handle different types of requests + TypeLookup_Request request; + if (typelookup_manager_->receive(*change, request)) + { + // Add request to the processing queue + requests_queue_.push(request); + { + // Notify processor + std::unique_lock guard(request_processor_cv_mutex_); + request_processor_cv_.notify_all(); + } + } + + // Remove the processed cache change from the history reader->getHistory()->remove_change(change); } @@ -141,10 +451,11 @@ void TypeLookupRequestListener::onWriterChangeReceivedByAll( fastrtps::rtps::RTPSWriter*, fastrtps::rtps::CacheChange_t* change) { - typelookup_manager_->request_cache_change_acked(change); + typelookup_manager_->remove_builtin_request_writer_history_change(change); } } // namespace builtin + } // namespace dds } // namespace fastdds } // namespace eprosima diff --git a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.hpp b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.hpp index aebd5d30160..4ee685e60e9 100644 --- a/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.hpp +++ b/src/cpp/fastdds/builtin/type_lookup_service/TypeLookupRequestListener.hpp @@ -17,12 +17,44 @@ * */ -#ifndef TYPELOOKUP_REQUEST_LISTENER_HPP_ -#define TYPELOOKUP_REQUEST_LISTENER_HPP_ -#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC +#ifndef _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REQUEST_LISTENER_HPP_ +#define _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REQUEST_LISTENER_HPP_ -#include -#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace std { + +template <> +struct hash +{ + std::size_t operator ()( + const eprosima::fastdds::dds::xtypes::TypeIdentifierSeq& k) const + { + std::size_t hash_value = 0; + for (const auto& id : k) + { + hash_value ^= (static_cast(id.equivalence_hash()[0]) << 16) | + (static_cast(id.equivalence_hash()[1]) << 8) | + (static_cast(id.equivalence_hash()[2])); + } + return hash_value; + } + +}; + +} // std namespace eprosima { namespace fastrtps { @@ -49,45 +81,115 @@ class TypeLookupRequestListener : public fastrtps::rtps::ReaderListener, public public: /** - * @brief Constructor - * @param manager Pointer to the TypeLookupManager + * @brief Constructor. + * @param manager Pointer to the TypeLookupManager. */ TypeLookupRequestListener( TypeLookupManager* manager); /** - * @brief Destructor + * @brief Destructor. */ virtual ~TypeLookupRequestListener() override; +protected: + + /** + * @brief Starts the thread that process the received requests. + */ + void start_request_processor_thread(); + + /** + * @brief Stops the thread that process the received requests. + */ + void stop_request_processor_thread(); + + /** + * @brief Process the requests in the queue. + */ + void process_requests(); + /** - * @brief Method call when this class is notified of a new cache change - * @param reader The reader receiving the cache change - * @param change The cache change + * @brief Gets TypeObject from TypeObjectRegistry, creates and sends reply. + * @param request_id[in] The SampleIdentity of the request. + * @param request[in] The request data. + */ + void check_get_types_request( + SampleIdentity request_id, + const TypeLookup_getTypes_In& request); + + /** + * @brief Gets type dependencies from TypeObjectRegistry, creates and sends reply. + * @param request_id[in] The SampleIdentity of the request. + * @param request[in] The request data. + */ + void check_get_type_dependencies_request( + SampleIdentity request_id, + const TypeLookup_getTypeDependencies_In& request); + + /** + * @brief Creates a TypeLookup_getTypeDependencies_Out using continuation points to manage size. + * @param id_seq[in] Sequence of TypeIdentifiers for which dependencies are needed. + * @param type_dependencies[in] The full list of dependencies of the type. + * @param continuation_point[in] The continuation point of the previous request. + * @return The reply containing the dependent types. + */ + TypeLookup_getTypeDependencies_Out prepare_get_type_dependencies_response( + const xtypes::TypeIdentifierSeq& id_seq, + const std::unordered_set& type_dependencies, + const std::vector& continuation_point); + + /** + * @brief Creates and sends the TypeLookup_Reply. + * @param request_id[in] The SampleIdentity of the request. + * @param exception_code[in] The RemoteExceptionCode_t used in the header. + * @param out[in] Reply to the query included in the received request. + */ + void answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypeDependencies_Out& out); + void answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code, + TypeLookup_getTypes_Out& out); + void answer_request( + SampleIdentity request_id, + rpc::RemoteExceptionCode_t exception_code); + + /** + * @brief Method call when this class is notified of a new cache change. + * @param reader The reader receiving the cache change. + * @param change The cache change. */ void onNewCacheChangeAdded( fastrtps::rtps::RTPSReader* reader, const fastrtps::rtps::CacheChange_t* const change) override; - /** - * @brief This method is called when all the readers matched with this Writer acknowledge that a cache - * change has been received. - * @param change The cache change - */ void onWriterChangeReceivedByAll( fastrtps::rtps::RTPSWriter*, fastrtps::rtps::CacheChange_t* change) override; -private: - - //! A pointer to the typelookup manager + //! A pointer to the typelookup manager. TypeLookupManager* typelookup_manager_; + //! Mutex to protect access to requests_with_continuation_. + std::mutex requests_with_continuation_mutex_; + + //! Collection of the requests that needed continuation points. + std::unordered_map > requests_with_continuation_; + + eprosima::thread request_processor_thread; + std::queue requests_queue_; + std::mutex request_processor_cv_mutex_; + std::condition_variable request_processor_cv_; + bool processing_ = false; + rtps::ThreadSettings request_processor_thread_settings_; }; } /* namespace builtin */ } /* namespace dds */ } /* namespace fastdds */ } /* namespace eprosima */ -#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC -#endif /* TYPELOOKUP_REQUEST_LISTENER_HPP_*/ +#endif /* _FASTDDS_BUILTIN_TYPE_LOOKUP_SERVICE_TYPE_LOOKUP_REQUEST_LISTENER_HPP_*/ diff --git a/src/cpp/fastdds/core/policy/QosPoliciesSerializer.hpp b/src/cpp/fastdds/core/policy/QosPoliciesSerializer.hpp index d8a15a752a4..08bd98f598a 100644 --- a/src/cpp/fastdds/core/policy/QosPoliciesSerializer.hpp +++ b/src/cpp/fastdds/core/policy/QosPoliciesSerializer.hpp @@ -1045,7 +1045,7 @@ template<> inline uint32_t QosPoliciesSerializer::cdr_serialized_size( const xtypes::TypeInformationParameter& qos_policy) { - eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; size_t size = calculator.calculate_serialized_size(qos_policy.type_information, current_alignment) + 4; return 2 + 2 + static_cast(size); @@ -1056,7 +1056,7 @@ inline bool QosPoliciesSerializer::add_to_cdr_ const xtypes::TypeInformationParameter& qos_policy, fastrtps::rtps::CDRMessage_t* cdr_message) { - eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; size_t size = calculator.calculate_serialized_size(qos_policy.type_information, @@ -1065,10 +1065,10 @@ inline bool QosPoliciesSerializer::add_to_cdr_ eprosima::fastcdr::FastBuffer fastbuffer((char*) payload.data, payload.max_size); eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, - eprosima::fastcdr::CdrVersion::XCDRv1); // Object that serializes the data. + eprosima::fastcdr::CdrVersion::XCDRv2); // Object that serializes the data. payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - ser.serialize_encapsulation(); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR2); ser << qos_policy.type_information; #if FASTCDR_VERSION_MAJOR == 1 @@ -1102,18 +1102,10 @@ inline bool QosPoliciesSerializer::read_conten fastrtps::rtps::CDRMessage::readData(cdr_message, payload.data, parameter_length); // Object that manages the raw buffer. - eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN -#if FASTCDR_VERSION_MAJOR == 1 - , eprosima::fastcdr::Cdr::CdrType::DDS_CDR -#endif // FASTCDR_VERSION_MAJOR == 1 - ); - + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + eprosima::fastcdr::CdrVersion::XCDRv2); try { - // Deserialize encapsulation. - deser.read_encapsulation(); - payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - deser >> qos_policy.type_information; qos_policy.assigned(true); } diff --git a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp index daf990f0e08..ac99c2d19d4 100644 --- a/src/cpp/fastdds/domain/DomainParticipantImpl.cpp +++ b/src/cpp/fastdds/domain/DomainParticipantImpl.cpp @@ -1563,7 +1563,9 @@ void DomainParticipantImpl::MyRTPSParticipantListener::onReaderDiscovery( Sentry sentinel(this); if (sentinel) { - participant_->listener_->on_subscriber_discovery(participant_->participant_, std::move(info)); + bool should_be_ignored = false; + participant_->listener_->on_data_reader_discovery(participant_->participant_, std::move(info), + should_be_ignored); } } @@ -1574,7 +1576,9 @@ void DomainParticipantImpl::MyRTPSParticipantListener::onWriterDiscovery( Sentry sentinel(this); if (sentinel) { - participant_->listener_->on_publisher_discovery(participant_->participant_, std::move(info)); + bool should_be_ignored = false; + participant_->listener_->on_data_writer_discovery(participant_->participant_, std::move(info), + should_be_ignored); } } @@ -1825,6 +1829,12 @@ bool DomainParticipantImpl::can_qos_be_updated( EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, "Participant discovery_server_thread cannot be changed after the participant is enabled"); } + if (!(to.typelookup_service_thread() == from.typelookup_service_thread())) + { + updatable = false; + EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK, + "Participant typelookup_service_thread cannot be changed after the participant is enabled"); + } #if HAVE_SECURITY if (!(to.security_log_thread() == from.security_log_thread())) { diff --git a/src/cpp/fastdds/utils/QosConverters.cpp b/src/cpp/fastdds/utils/QosConverters.cpp index 038c39f5e61..a72537c23b8 100644 --- a/src/cpp/fastdds/utils/QosConverters.cpp +++ b/src/cpp/fastdds/utils/QosConverters.cpp @@ -161,6 +161,7 @@ void set_qos_from_attributes( qos.builtin_controllers_sender_thread() = attr.builtin_controllers_sender_thread; qos.timed_events_thread() = attr.timed_events_thread; qos.discovery_server_thread() = attr.discovery_server_thread; + qos.typelookup_service_thread() = attr.typelookup_service_thread; #if HAVE_SECURITY qos.security_log_thread() = attr.security_log_thread; #endif // if HAVE_SECURITY @@ -209,6 +210,7 @@ void set_attributes_from_qos( attr.builtin_controllers_sender_thread = qos.builtin_controllers_sender_thread(); attr.timed_events_thread = qos.timed_events_thread(); attr.discovery_server_thread = qos.discovery_server_thread(); + attr.typelookup_service_thread = qos.typelookup_service_thread(); #if HAVE_SECURITY attr.security_log_thread = qos.security_log_thread(); #endif // if HAVE_SECURITY diff --git a/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.cpp b/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.cpp index cc41f40bac7..7329161c7b9 100644 --- a/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.cpp +++ b/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.cpp @@ -73,7 +73,7 @@ ReturnCode_t TypeObjectRegistry::register_type_object( auto type_ids_result = local_type_identifiers_.insert({type_name, type_ids}); auto min_entry_result = type_registry_entries_.insert({type_ids.type_identifier1(), minimal_entry}); auto max_entry_result = type_registry_entries_.insert({type_ids.type_identifier2(), complete_entry}); - if (!type_ids_result.second || !min_entry_result.second || !max_entry_result.second) + if (!type_ids_result.second || !max_entry_result.second) { if (local_type_identifiers_[type_name] != type_ids || type_registry_entries_[type_ids.type_identifier1()] != minimal_entry || @@ -128,7 +128,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().seq_sdefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().seq_sdefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().seq_sdefn().element_identifier()))); } break; @@ -138,7 +138,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().seq_ldefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().seq_ldefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().seq_ldefn().element_identifier()))); } break; @@ -148,7 +148,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().array_sdefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().array_sdefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().array_sdefn().element_identifier()))); } break; @@ -158,7 +158,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().array_ldefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().array_ldefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().array_ldefn().element_identifier()))); } break; @@ -168,7 +168,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().map_sdefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().map_sdefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().map_sdefn().element_identifier()))); } if (TypeObjectUtils::is_direct_hash_type_identifier(*type_identifier.map_sdefn().key_identifier())) @@ -178,7 +178,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); } type_identifiers.type_identifier1().map_sdefn().key_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().map_sdefn().key_identifier()))); } break; @@ -188,7 +188,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); type_identifiers.type_identifier1().map_ldefn().header().equiv_kind(EK_MINIMAL); type_identifiers.type_identifier1().map_ldefn().element_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().map_ldefn().element_identifier()))); } if (TypeObjectUtils::is_direct_hash_type_identifier(*type_identifier.map_ldefn().key_identifier())) @@ -198,7 +198,7 @@ ReturnCode_t TypeObjectRegistry::register_type_identifier( type_identifiers.type_identifier2(type_identifier); } type_identifiers.type_identifier1().map_ldefn().key_identifier(new TypeIdentifier( - minimal_from_complete_type_identifier( + get_complementary_type_identifier( *type_identifiers.type_identifier2().map_ldefn().key_identifier()))); } break; @@ -438,15 +438,6 @@ ReturnCode_t TypeObjectRegistry::register_type_object( const TypeObject& type_object) { uint32_t type_object_serialized_size = 0; - try - { - TypeObjectUtils::type_object_consistency(type_object); - } - catch (const InvalidArgumentError& exception) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Inconsistent CompleteTypeObject: " << exception.what()); - return eprosima::fastdds::dds::RETCODE_PRECONDITION_NOT_MET; - } if (type_identifier._d() != type_object._d() || type_identifier != calculate_type_identifier(type_object, type_object_serialized_size)) { @@ -696,6 +687,31 @@ ReturnCode_t TypeObjectRegistry::get_dependencies_from_type_object( return ret_code; } +const TypeIdentifier TypeObjectRegistry::get_complementary_type_identifier( + const TypeIdentifier& type_id) +{ + std::lock_guard data_guard(type_object_registry_mutex_); + for (const auto& it : local_type_identifiers_) + { + if (it.second.type_identifier1() == type_id) + { + if (TK_NONE != it.second.type_identifier2()._d()) + { + return it.second.type_identifier2(); + } + else + { + return it.second.type_identifier1(); + } + } + else if (it.second.type_identifier2() == type_id) + { + return it.second.type_identifier1(); + } + } + return type_id; +} + ReturnCode_t TypeObjectRegistry::get_type_dependencies_impl( const TypeIdentifierSeq& type_identifiers, std::unordered_set& type_dependencies) diff --git a/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.hpp b/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.hpp index e0c8b4c869c..6a65a476d53 100644 --- a/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.hpp +++ b/src/cpp/fastdds/xtypes/type_representation/TypeObjectRegistry.hpp @@ -227,6 +227,9 @@ class TypeObjectRegistry : public ITypeObjectRegistry * @brief Register a remote TypeObject. * This auxiliary method might register only the minimal TypeObject and TypeIdentifier or register both * TypeObjects constructing the minimal from the complete TypeObject information. + * TypeObject consistency is not checked in this method as the order of the dependencies received by the + * TypeLookupService is not guaranteed. + * The consistency is checked by the TypeLookupService after all denpendencies are registered * * @pre TypeIdentifier discriminator must match TypeObject discriminator. * TypeIdentifier consistency is only checked in Debug build mode. @@ -237,7 +240,6 @@ class TypeObjectRegistry : public ITypeObjectRegistry * RETCODE_PRECONDITION_NOT_MET if the discriminators differ. * RETCODE_PRECONDITION_NOT_MET if the TypeIdentifier is not consistent with the given * TypeObject. - * RETCODE_PRECONDITION_NOT_MET if the given TypeObject is not consistent. */ ReturnCode_t register_type_object( const TypeIdentifier& type_identifier, @@ -269,6 +271,18 @@ class TypeObjectRegistry : public ITypeObjectRegistry const TypeObject& type_object, std::unordered_set& type_dependencies); + /** + * @brief Get Complementary TypeIdentifier. + * Meaning that if the given TypeIdentifier is a complete TypeIdentifier, + * the returned TypeIdentifier will be the minimal TypeIdentifier and vice versa. + * + * @param type_id TypeIdentifier of which the complementary is to be obtained. + * @return TypeIdentifier complementary to the given type_id. + * Same TypeIdentifier if the given TypeIdentifier does not have complementary. + */ + const TypeIdentifier get_complementary_type_identifier( + const TypeIdentifier& type_id); + // Only DomainParticipantFactory is allowed to instantiate the TypeObjectRegistry class. // It cannot be protected as the standard library needs to access the constructor to allocate the resources. // Rule of zero: resource managing types. diff --git a/src/cpp/fastdds/xtypes/type_representation/TypeObjectUtils.cpp b/src/cpp/fastdds/xtypes/type_representation/TypeObjectUtils.cpp index c446a530a55..4cccc9b041e 100644 --- a/src/cpp/fastdds/xtypes/type_representation/TypeObjectUtils.cpp +++ b/src/cpp/fastdds/xtypes/type_representation/TypeObjectUtils.cpp @@ -216,7 +216,7 @@ const PlainCollectionHeader TypeObjectUtils::build_plain_collection_header( const PlainSequenceSElemDefn TypeObjectUtils::build_plain_sequence_s_elem_defn( const PlainCollectionHeader& header, - SBound bound, + SBound s_bound, const eprosima::fastcdr::external& element_identifier) { #if !defined(NDEBUG) @@ -226,25 +226,25 @@ const PlainSequenceSElemDefn TypeObjectUtils::build_plain_sequence_s_elem_defn( plain_collection_type_identifier_header_consistency(header, *element_identifier); PlainSequenceSElemDefn plain_sequence_s_elem_defn; plain_sequence_s_elem_defn.header(header); - plain_sequence_s_elem_defn.bound(bound); + plain_sequence_s_elem_defn.bound(s_bound); plain_sequence_s_elem_defn.element_identifier(element_identifier); return plain_sequence_s_elem_defn; } const PlainSequenceLElemDefn TypeObjectUtils::build_plain_sequence_l_elem_defn( const PlainCollectionHeader& header, - LBound bound, + LBound l_bound, const eprosima::fastcdr::external& element_identifier) { #if !defined(NDEBUG) plain_collection_header_consistency(header); type_identifier_consistency(*element_identifier); #endif // !defined(NDEBUG) - l_bound_consistency(bound); + l_bound_consistency(l_bound); plain_collection_type_identifier_header_consistency(header, *element_identifier); PlainSequenceLElemDefn plain_sequence_l_elem_defn; plain_sequence_l_elem_defn.header(header); - plain_sequence_l_elem_defn.bound(bound); + plain_sequence_l_elem_defn.bound(l_bound); plain_sequence_l_elem_defn.element_identifier(element_identifier); return plain_sequence_l_elem_defn; } @@ -1817,6 +1817,22 @@ const NameHash TypeObjectUtils::name_hash( return name_hashed; } +void TypeObjectUtils::type_object_consistency( + const TypeObject& type_object) +{ + switch (type_object._d()) + { + case EK_COMPLETE: + complete_type_object_consistency(type_object.complete()); + break; + case EK_MINIMAL: + minimal_type_object_consistency(type_object.minimal()); + break; + default: + throw InvalidArgumentError("Inconsistent TypeObject"); + } +} + void TypeObjectUtils::set_try_construct_behavior( MemberFlag& member_flag, TryConstructKind try_construct_kind) @@ -3547,22 +3563,6 @@ void TypeObjectUtils::minimal_type_object_consistency( } } -void TypeObjectUtils::type_object_consistency( - const TypeObject& type_object) -{ - switch (type_object._d()) - { - case EK_COMPLETE: - complete_type_object_consistency(type_object.complete()); - break; - case EK_MINIMAL: - minimal_type_object_consistency(type_object.minimal()); - break; - default: - throw InvalidArgumentError("Inconsistent TypeObject"); - } -} - } // xtypes } // dds } // fastdds diff --git a/src/cpp/rtps/builtin/BuiltinProtocols.cpp b/src/cpp/rtps/builtin/BuiltinProtocols.cpp index 2d3072dac63..420fc946da1 100644 --- a/src/cpp/rtps/builtin/BuiltinProtocols.cpp +++ b/src/cpp/rtps/builtin/BuiltinProtocols.cpp @@ -52,6 +52,9 @@ BuiltinProtocols::BuiltinProtocols() BuiltinProtocols::~BuiltinProtocols() { + // This needs to be done first because of the WriterProxydata and ReaderProxyData smart_ptr + delete typelookup_manager_; + // Send participant is disposed if (mp_PDP != nullptr) { @@ -61,7 +64,7 @@ BuiltinProtocols::~BuiltinProtocols() // TODO Auto-generated destructor stub delete mp_WLP; delete mp_PDP; - delete typelookup_manager_; + } bool BuiltinProtocols::initBuiltinProtocols( diff --git a/src/cpp/rtps/builtin/data/ReaderProxyData.cpp b/src/cpp/rtps/builtin/data/ReaderProxyData.cpp index a7e663f8f34..4eddeee26c5 100644 --- a/src/cpp/rtps/builtin/data/ReaderProxyData.cpp +++ b/src/cpp/rtps/builtin/data/ReaderProxyData.cpp @@ -288,14 +288,6 @@ uint32_t ReaderProxyData::get_serialized_size( ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size( m_qos.m_disablePositiveACKs); } - if (m_type_id && m_type_id->m_type_identifier._d() != fastdds::dds::xtypes::TK_NONE) - { - ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size(*m_type_id); - } - if (m_type && m_type->m_type_object._d() != fastdds::dds::xtypes::TK_NONE) - { - ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size(*m_type); - } if (m_type_information && m_type_information->assigned()) { ret_val += @@ -550,23 +542,14 @@ bool ReaderProxyData::writeToCDRMessage( return false; } } - - if (m_type_id && m_type_id->m_type_identifier._d() != fastdds::dds::xtypes::TK_NONE) - { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(*m_type_id, msg)) - { - return false; - } - } - - if (m_type && m_type->m_type_object._d() != fastdds::dds::xtypes::TK_NONE) + if (m_type_information && m_type_information->assigned()) { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(*m_type, msg)) + if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(* + m_type_information, msg)) { return false; } } - if (m_properties.size() > 0) { if (!fastdds::dds::ParameterSerializer::add_to_cdr_message(m_properties, msg)) @@ -615,15 +598,6 @@ bool ReaderProxyData::writeToCDRMessage( } } - if (m_type_information && m_type_information->assigned()) - { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(* - m_type_information, msg)) - { - return false; - } - } - if ((m_qos.data_sharing.send_always() || m_qos.data_sharing.hasChanged) && m_qos.data_sharing.kind() != fastdds::dds::OFF) { @@ -974,27 +948,20 @@ bool ReaderProxyData::readFromCDRMessage( } case fastdds::dds::PID_TYPE_IDV1: { - if (!fastdds::dds::QosPoliciesSerializer::read_from_cdr_message(type_id(), msg, - plength)) - { - return false; - } + EPROSIMA_LOG_WARNING(RTPS_PROXY_DATA, + "Reception of TypeIdentifiers is not supported. They will be ignored."); break; } case fastdds::dds::PID_TYPE_OBJECTV1: { - if (!fastdds::dds::QosPoliciesSerializer::read_from_cdr_message(type(), msg, - plength)) - { - return false; - } + EPROSIMA_LOG_WARNING(RTPS_PROXY_DATA, + "Reception of TypeObjects is not supported. They will be ignored."); break; } case fastdds::dds::PID_TYPE_INFORMATION: { if (!fastdds::dds::QosPoliciesSerializer:: - read_from_cdr_message( - type_information(), msg, plength)) + read_from_cdr_message(type_information(), msg, plength)) { return false; } diff --git a/src/cpp/rtps/builtin/data/WriterProxyData.cpp b/src/cpp/rtps/builtin/data/WriterProxyData.cpp index 74e0c07c5b1..f7a65bbd2fc 100644 --- a/src/cpp/rtps/builtin/data/WriterProxyData.cpp +++ b/src/cpp/rtps/builtin/data/WriterProxyData.cpp @@ -296,14 +296,6 @@ uint32_t WriterProxyData::get_serialized_size( { ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size(m_qos.m_groupData); } - if (m_type_id && m_type_id->m_type_identifier._d() != fastdds::dds::xtypes::TK_NONE) - { - ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size(*m_type_id); - } - if (m_type && m_type->m_type_object._d() != fastdds::dds::xtypes::TK_NONE) - { - ret_val += fastdds::dds::QosPoliciesSerializer::cdr_serialized_size(*m_type); - } if (m_type_information && m_type_information->assigned()) { ret_val += @@ -564,23 +556,14 @@ bool WriterProxyData::writeToCDRMessage( return false; } } - - if (m_type_id && m_type_id->m_type_identifier._d() != fastdds::dds::xtypes::TK_NONE) - { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(*m_type_id, msg)) - { - return false; - } - } - - if (m_type && m_type->m_type_object._d() != fastdds::dds::xtypes::TK_NONE) + if (m_type_information && m_type_information->assigned()) { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(*m_type, msg)) + if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(* + m_type_information, msg)) { return false; } } - if (m_properties.size() > 0) { if (!fastdds::dds::ParameterSerializer::add_to_cdr_message(m_properties, msg)) @@ -611,14 +594,7 @@ bool WriterProxyData::writeToCDRMessage( } } - if (m_type_information && m_type_information->assigned()) - { - if (!fastdds::dds::QosPoliciesSerializer::add_to_cdr_message(* - m_type_information, msg)) - { - return false; - } - } + return fastdds::dds::ParameterSerializer::add_parameter_sentinel(msg); } @@ -963,27 +939,20 @@ bool WriterProxyData::readFromCDRMessage( } case fastdds::dds::PID_TYPE_IDV1: { - if (!fastdds::dds::QosPoliciesSerializer::read_from_cdr_message(type_id(), msg, - plength)) - { - return false; - } + EPROSIMA_LOG_WARNING(RTPS_PROXY_DATA, + "Reception of TypeIdentifiers is not supported. They will be ignored"); break; } case fastdds::dds::PID_TYPE_OBJECTV1: { - if (!fastdds::dds::QosPoliciesSerializer::read_from_cdr_message(type(), msg, - plength)) - { - return false; - } + EPROSIMA_LOG_WARNING(RTPS_PROXY_DATA, + "Reception of TypeObjects is not supported. They will be ignored"); break; } case fastdds::dds::PID_TYPE_INFORMATION: { if (!fastdds::dds::QosPoliciesSerializer:: - read_from_cdr_message( - type_information(), msg, plength)) + read_from_cdr_message(type_information(), msg, plength)) { return false; } diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp index 9dc7c837e89..67c4a9657c6 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp @@ -163,7 +163,7 @@ bool EDP::newLocalReaderProxyData( #endif // if HAVE_SECURITY if (att.auto_fill_type_information) { - // TypeInformation, TypeObject and TypeIdentifier + // TypeInformation if (!att.type_information.assigned()) { fastdds::dds::xtypes::TypeInformation type_info; @@ -171,8 +171,7 @@ bool EDP::newLocalReaderProxyData( eprosima::fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer() .get_type_information(rpd->typeName().c_str(), type_info)) { - // TODO (adelcampo) Change to xtypes - // rpd->type_information() = type_info; + rpd->type_information() = type_info; } } } @@ -271,7 +270,7 @@ bool EDP::newLocalWriterProxyData( if (att.auto_fill_type_information) { - // TypeInformation, TypeObject and TypeIdentifier + // TypeInformation if (!att.type_information.assigned()) { fastdds::dds::xtypes::TypeInformation type_info; @@ -279,8 +278,7 @@ bool EDP::newLocalWriterProxyData( eprosima::fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer() .get_type_information(wpd->typeName().c_str(), type_info)) { - // TODO (adelcampo) Change to xtypes - // wpd->type_information() = type_info; + wpd->type_information() = type_info; } } } @@ -366,7 +364,7 @@ bool EDP::updatedLocalReader( if (att.auto_fill_type_information) { - // TypeInformation, TypeObject and TypeIdentifier + // TypeInformation if (!rdata->type_information().assigned()) { fastdds::dds::xtypes::TypeInformation type_info; @@ -374,8 +372,7 @@ bool EDP::updatedLocalReader( eprosima::fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer() .get_type_information(rdata->typeName().c_str(), type_info)) { - // TODO (adelcampo) Change to xtypes - // rdata->type_information() = type_info; + rdata->type_information() = type_info; } } } @@ -434,7 +431,7 @@ bool EDP::updatedLocalWriter( if (att.auto_fill_type_information) { - // TypeInformation, TypeObject and TypeIdentifier + // TypeInformation if (!wdata->type_information().assigned()) { fastdds::dds::xtypes::TypeInformation type_info; @@ -442,8 +439,7 @@ bool EDP::updatedLocalWriter( eprosima::fastrtps::rtps::RTPSDomainImpl::get_instance()->type_object_registry_observer() .get_type_information(wdata->typeName().c_str(), type_info)) { - // TODO (adelcampo) Change to xtypes - // wdata->type_information() = *type_info; + wdata->type_information() = type_info; } } } @@ -579,6 +575,24 @@ bool EDP::valid_matching( return false; } + if ((wdata->has_type_information() && wdata->type_information().assigned()) && + (rdata->has_type_information() && rdata->type_information().assigned())) + { + if (wdata->type_information().type_information != rdata->type_information().type_information) + { + reason.set(MatchingFailureMask::different_typeinfo); + return false; + } + } + else + { + if (wdata->typeName() != rdata->typeName()) + { + reason.set(MatchingFailureMask::inconsistent_topic); + return false; + } + } + if (wdata->topicKind() != rdata->topicKind()) { EPROSIMA_LOG_WARNING(RTPS_EDP, "INCOMPATIBLE QOS:Remote Reader " << rdata->guid() << " is publishing in topic " diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDP.h b/src/cpp/rtps/builtin/discovery/endpoint/EDP.h index 17de21eb38f..e105c64d5d8 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDP.h +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDP.h @@ -88,6 +88,9 @@ class EDP //! Bit index for matching failing due to inconsistent partitions static const uint32_t partitions = (0x00000001 << 3u); + + //! Bit index for matching failing due to incompatible TypeInformation + static const uint32_t different_typeinfo = (0x00000001 << 4u); }; /** diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.cpp index 8fa05ee493e..23c4156e7f3 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.cpp @@ -62,8 +62,7 @@ void EDPServerPUBListener::onNewCacheChangeAdded( EPROSIMA_LOG_WARNING(RTPS_EDP_LISTENER, "Received change with no Key"); } - // Get writer's GUID and EDP publications' reader history - GUID_t auxGUID = iHandle2GUID(change->instanceHandle); + // Get EDP publications' reader history ReaderHistory* reader_history = reader->getHistory(); // Related_sample_identity could be lost in message delivered, so we set as sample_identity @@ -78,49 +77,62 @@ void EDPServerPUBListener::onNewCacheChangeAdded( change->writer_info.previous = nullptr; change->writer_info.num_sent_submessages = 0; - // String to store the topic of the writer - std::string topic_name = ""; - // DATA(w) case: new writer or updated information about an existing writer if (change->kind == ALIVE) { + EndpointAddedCallback writer_added_callback = + std::bind(&EDPServerPUBListener::continue_with_writer, this, reader, change); + // Note: add_writer_from_change() removes the change from the EDP publications' reader history, but it does not // return it to the pool - add_writer_from_change(reader, reader_history, change, sedp_, false); + add_writer_from_change(reader, reader_history, change, sedp_, false, writer_added_callback); - // Retrieve the topic after creating the WriterProxyData (in add_writer_from_change()). This way, not matter + // DATA(w) case: Retrieve the topic after creating the WriterProxyData (in add_writer_from_change()). This way, not matter // whether the DATA(w) is a new one or an update, the WriterProxyData exists, and so the topic can be retrieved - auto temp_writer_data = get_pdp()->get_temporary_writer_proxies_pool().get(); - if (get_pdp()->lookupWriterProxyData(auxGUID, *temp_writer_data)) - { - topic_name = temp_writer_data->topicName().to_string(); - } + + // Stop and wait for callback in case of TypeLookupService needed time to process the types + return; } // DATA(Uw) case else { EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, "Disposed Remote Writer, removing..."); - // Retrieve the topic before removing the WriterProxyData. We need it to add the DATA(Uw) to the database - auto temp_writer_data = get_pdp()->get_temporary_writer_proxies_pool().get(); - if (get_pdp()->lookupWriterProxyData(auxGUID, *temp_writer_data)) - { - topic_name = temp_writer_data->topicName().to_string(); - } - else - { - EPROSIMA_LOG_WARNING(RTPS_EDP_LISTENER, "Writer Proxy Data missing for change " << auxGUID); - } - + // DATA(Uw) case: Retrieve the topic before removing the WriterProxyData. We need it to add the DATA(Uw) to the database + GUID_t auxGUID = iHandle2GUID(change->instanceHandle); + std::string topic_name = get_writer_proxy_topic_name(auxGUID); // Remove WriterProxy data information get_pdp()->removeWriterProxyData(auxGUID); - // Removing change from history, not returning the change to the pool, since the ownership will be yielded to - // the database + // Removing change from history, not returning the change to the pool, since the ownership will be yielded to the database reader_history->remove_change(reader_history->find_change(change), false); + + notify_discoverydatabase(topic_name, reader, change); } +} +std::string EDPServerPUBListener::get_writer_proxy_topic_name( + GUID_t auxGUID) +{ + std::string topic_name = ""; + auto temp_writer_data = get_pdp()->get_temporary_writer_proxies_pool().get(); + if (get_pdp()->lookupWriterProxyData(auxGUID, *temp_writer_data)) + { + topic_name = temp_writer_data->topicName().to_string(); + } + else + { + EPROSIMA_LOG_WARNING(RTPS_EDP_LISTENER, "Writer Proxy Data missing for change " << auxGUID); + } + return topic_name; +} + +void EDPServerPUBListener::notify_discoverydatabase( + std::string topic_name, + RTPSReader* reader, + CacheChange_t* change) +{ // Notify the DiscoveryDataBase if it is enabled already // In case it is not enable, the change should not be updated or released because it is been // updated from a backup @@ -140,12 +152,21 @@ void EDPServerPUBListener::onNewCacheChangeAdded( reader->releaseCache(change); } } + EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, "-------------------- " << sedp_->mp_RTPSParticipant->getGuid() << " --------------------"); EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, "------------------ EDP PUB SERVER LISTENER END ------------------"); EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, ""); } +void EDPServerPUBListener::continue_with_writer( + RTPSReader* reader, + CacheChange_t* change) +{ + std::string topic_name = get_writer_proxy_topic_name(iHandle2GUID(change->instanceHandle)); + notify_discoverydatabase(topic_name, reader, change); +} + PDPServer* EDPServerSUBListener::get_pdp() { return sedp_->get_pdp(); @@ -188,31 +209,24 @@ void EDPServerSUBListener::onNewCacheChangeAdded( change->writer_info.previous = nullptr; change->writer_info.num_sent_submessages = 0; - // Get readers's GUID and EDP subscriptions' reader history - GUID_t auxGUID = iHandle2GUID(change->instanceHandle); + // Get EDP subscriptions' reader history ReaderHistory* reader_history = reader->getHistory(); - // String to store the topic of the reader - std::string topic_name = ""; - // DATA(r) case: new reader or updated information about an existing reader if (change->kind == ALIVE) { + EndpointAddedCallback reader_added_callback = + std::bind(&EDPServerSUBListener::continue_with_reader, this, reader, change); + // Note: add_reader_from_change() removes the change from the EDP subscriptions' reader history, but it does not // return it to the pool - add_reader_from_change(reader, reader_history, change, sedp_, false); + add_reader_from_change(reader, reader_history, change, sedp_, false, reader_added_callback); - // Retrieve the topic after creating the ReaderProxyData (in add_reader_from_change()). This way, not matter + // DATA(w) case: Retrieve the topic after creating the ReaderProxyData (in add_reader_from_change()). This way, not matter // whether the DATA(r) is a new one or an update, the ReaderProxyData exists, and so the topic can be retrieved - auto temp_reader_data = get_pdp()->get_temporary_reader_proxies_pool().get(); - if (get_pdp()->lookupReaderProxyData(auxGUID, *temp_reader_data)) - { - topic_name = temp_reader_data->topicName().to_string(); - } - else - { - EPROSIMA_LOG_WARNING(RTPS_EDP_LISTENER, "Reader Proxy Data missing for change " << auxGUID); - } + + // Stop and wait for callback in case of TypeLookupService needed time to process the types + return; } // DATA(Ur) case else @@ -220,12 +234,9 @@ void EDPServerSUBListener::onNewCacheChangeAdded( //REMOVE WRITER FROM OUR READERS: EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, "Disposed Remote Reader, removing..."); - // Retrieve the topic before removing the ReaderProxyData. We need it to add the DATA(Ur) to the database - auto temp_reader_data = get_pdp()->get_temporary_reader_proxies_pool().get(); - if (get_pdp()->lookupReaderProxyData(auxGUID, *temp_reader_data)) - { - topic_name = temp_reader_data->topicName().to_string(); - } + // DATA(Uw) case: Retrieve the topic before removing the ReaderProxyData. We need it to add the DATA(Ur) to the database + GUID_t auxGUID = iHandle2GUID(change->instanceHandle); + std::string topic_name = get_reader_proxy_topic_name(auxGUID); // Remove ReaderProxy data information get_pdp()->removeReaderProxyData(auxGUID); @@ -233,8 +244,32 @@ void EDPServerSUBListener::onNewCacheChangeAdded( // Removing change from history, not returning the change to the pool, since the ownership will be yielded to // the database reader_history->remove_change(reader_history->find_change(change), false); + + notify_discoverydatabase(topic_name, reader, change); + } +} + +std::string EDPServerSUBListener::get_reader_proxy_topic_name( + GUID_t auxGUID) +{ + std::string topic_name = ""; + auto temp_reader_data = get_pdp()->get_temporary_reader_proxies_pool().get(); + if (get_pdp()->lookupReaderProxyData(auxGUID, *temp_reader_data)) + { + topic_name = temp_reader_data->topicName().to_string(); + } + else + { + EPROSIMA_LOG_WARNING(RTPS_EDP_LISTENER, "Reader Proxy Data missing for change " << auxGUID); } + return topic_name; +} +void EDPServerSUBListener::notify_discoverydatabase( + std::string topic_name, + RTPSReader* reader, + CacheChange_t* change) +{ // Notify the DiscoveryDataBase if it is enabled already // In case it is not enable, the change should not be updated or released because it is been // updated from a backup @@ -261,6 +296,14 @@ void EDPServerSUBListener::onNewCacheChangeAdded( EPROSIMA_LOG_INFO(RTPS_EDP_LISTENER, ""); } +void EDPServerSUBListener::continue_with_reader( + RTPSReader* reader, + CacheChange_t* change) +{ + std::string topic_name = get_reader_proxy_topic_name(iHandle2GUID(change->instanceHandle)); + notify_discoverydatabase(topic_name, reader, change); +} + } /* namespace rtps */ } // namespace fastdds } /* namespace eprosima */ diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.hpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.hpp index 8a3d1bd4694..5dd370ec426 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.hpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPServerListeners.hpp @@ -74,6 +74,18 @@ class EDPServerPUBListener : public fastrtps::rtps::EDPBasePUBListener private: + std::string get_writer_proxy_topic_name( + fastrtps::rtps::GUID_t auxGUID); + + void notify_discoverydatabase( + std::string topic_name, + fastrtps::rtps::RTPSReader* reader, + fastrtps::rtps::CacheChange_t* change); + + void continue_with_writer( + fastrtps::rtps::RTPSReader* reader, + fastrtps::rtps::CacheChange_t* change); + //!Pointer to the EDPServer EDPServer* sedp_; }; @@ -108,6 +120,18 @@ class EDPServerSUBListener : public fastrtps::rtps::EDPBaseSUBListener private: + std::string get_reader_proxy_topic_name( + fastrtps::rtps::GUID_t auxGUID); + + void notify_discoverydatabase( + std::string topic_name, + fastrtps::rtps::RTPSReader* reader, + fastrtps::rtps::CacheChange_t* change); + + void continue_with_reader( + fastrtps::rtps::RTPSReader* reader, + fastrtps::rtps::CacheChange_t* change); + //!Pointer to the EDPServer EDPServer* sedp_; }; diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp index 5cece62baf8..5a3deab0908 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp @@ -39,6 +39,7 @@ using ParameterList = eprosima::fastdds::dds::ParameterList; + // Release reader lock to avoid ABBA lock. PDP mutex should always be first. // Keep change information on local variables to check consistency later #define PREVENT_PDP_DEADLOCK(reader, change, pdp) \ @@ -65,7 +66,8 @@ void EDPBasePUBListener::add_writer_from_change( ReaderHistory* reader_history, CacheChange_t* change, EDP* edp, - bool release_change /*=true*/) + bool release_change /*= true*/, + const EndpointAddedCallback& writer_added_callback /* = nullptr*/) { //LOAD INFORMATION IN DESTINATION WRITER PROXY DATA const NetworkFactory& network = edp->mp_RTPSParticipant->network_factory(); @@ -83,8 +85,8 @@ void EDPBasePUBListener::add_writer_from_change( // Callback function to continue after typelookup is complete fastdds::dds::builtin::AsyncGetTypeWriterCallback after_typelookup_callback = - [reader, reader_history, change, edp, release_change, &network] - (eprosima::ProxyPool::smart_ptr&& temp_writer_data) + [reader, change, edp, &network, writer_added_callback] + (eprosima::ProxyPool::smart_ptr& temp_writer_data) { //LOAD INFORMATION IN DESTINATION WRITER PROXY DATA auto copy_data_fun = [&temp_writer_data, &network]( @@ -115,27 +117,42 @@ void EDPBasePUBListener::add_writer_from_change( // release temporary proxy temp_writer_data.reset(); - reader_history->remove_change(reader_history->find_change(change), release_change); - - // At this point, we can release the reader lock because the change is not used - reader->getMutex().unlock(); - if (writer_data != nullptr) { edp->pairing_writer_proxy_with_any_local_reader(participant_guid, writer_data); + if (nullptr != writer_added_callback) + { + writer_added_callback(reader, change); + } } else { EPROSIMA_LOG_WARNING(RTPS_EDP, "Received message from UNKNOWN RTPSParticipant, removing"); } - - // Take the reader lock again if needed. - reader->getMutex().lock(); }; - edp->mp_RTPSParticipant->typelookup_manager()->async_get_type( - std::move(temp_writer_data), - after_typelookup_callback); + // Remove change from history. + reader_history->remove_change(reader_history->find_change(change), release_change); + + // At this point, we can release the reader lock because the change is not used + reader->getMutex().unlock(); + + // Check if TypeInformation exists to start the typelookup service + if (temp_writer_data->type_information().assigned()) + { + edp->mp_RTPSParticipant->typelookup_manager()->async_get_type( + temp_writer_data, + after_typelookup_callback); + } + // If TypeInformation does not exist, try fallback mechanism + else + { + EPROSIMA_LOG_INFO(RTPS_EDP, "EDPBasePUBListener: No TypeInformation. Trying fallback mechanism"); + after_typelookup_callback(temp_writer_data); + } + + // Take the reader lock again if needed. + reader->getMutex().lock(); } } @@ -189,7 +206,8 @@ void EDPBaseSUBListener::add_reader_from_change( ReaderHistory* reader_history, CacheChange_t* change, EDP* edp, - bool release_change /*=true*/) + bool release_change /*= true*/, + const EndpointAddedCallback& reader_added_callback /* = nullptr*/) { //LOAD INFORMATION IN TEMPORAL READER PROXY DATA const NetworkFactory& network = edp->mp_RTPSParticipant->network_factory(); @@ -207,8 +225,8 @@ void EDPBaseSUBListener::add_reader_from_change( // Callback function to continue after typelookup is complete fastdds::dds::builtin::AsyncGetTypeReaderCallback after_typelookup_callback = - [reader, reader_history, change, edp, release_change, &network] - (eprosima::ProxyPool::smart_ptr&& temp_reader_data) + [reader, change, edp, &network, reader_added_callback] + (eprosima::ProxyPool::smart_ptr& temp_reader_data) { auto copy_data_fun = [&temp_reader_data, &network]( ReaderProxyData* data, @@ -239,28 +257,42 @@ void EDPBaseSUBListener::add_reader_from_change( // Release the temporary proxy temp_reader_data.reset(); - // Remove change from history. - reader_history->remove_change(reader_history->find_change(change), release_change); - - // At this point we can release reader lock, cause change is not used - reader->getMutex().unlock(); - if (reader_data != nullptr) //ADDED NEW DATA { edp->pairing_reader_proxy_with_any_local_writer(participant_guid, reader_data); + if (nullptr != reader_added_callback) + { + reader_added_callback(reader, change); + } } else { EPROSIMA_LOG_WARNING(RTPS_EDP, "From UNKNOWN RTPSParticipant, removing"); } - - // Take again the reader lock. - reader->getMutex().lock(); }; - edp->mp_RTPSParticipant->typelookup_manager()->async_get_type( - std::move(temp_reader_data), - after_typelookup_callback); + // Remove change from history. + reader_history->remove_change(reader_history->find_change(change), release_change); + + // At this point, we can release the reader lock because the change is not used + reader->getMutex().unlock(); + + // Check if TypeInformation exists to start the typelookup service + if (temp_reader_data->type_information().assigned()) + { + edp->mp_RTPSParticipant->typelookup_manager()->async_get_type( + temp_reader_data, + after_typelookup_callback); + } + // If TypeInformation does not exist, try fallback mechanism + else + { + EPROSIMA_LOG_INFO(RTPS_EDP, "EDPBasePUBListener: No TypeInformation. Trying fallback mechanism"); + after_typelookup_callback(temp_reader_data); + } + + // Take the reader lock again if needed. + reader->getMutex().lock(); } } diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h index 7d9dade4425..9c9c34b54ac 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h @@ -33,6 +33,9 @@ namespace eprosima { namespace fastrtps { namespace rtps { +using EndpointAddedCallback = std::function< + void (RTPSReader* reader, const CacheChange_t* change)>; + class RTPSReader; struct CacheChange_t; @@ -77,7 +80,9 @@ class EDPBasePUBListener : public EDPListener ReaderHistory* reader_history, CacheChange_t* change, EDP* edp, - bool release_change = true); + bool release_change = true, + const EndpointAddedCallback& writer_added_callback = nullptr + ); }; /** @@ -99,7 +104,9 @@ class EDPBaseSUBListener : public EDPListener ReaderHistory* reader_history, CacheChange_t* change, EDP* edp, - bool release_change = true); + bool release_change = true, + const EndpointAddedCallback& reader_added_callback = nullptr + ); }; /*! diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp index 35b4d1f2b8d..f41b1ed59fd 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -576,6 +577,8 @@ void PDPClient::perform_builtin_endpoints_matching( { mp_builtin->mp_WLP->assignRemoteEndpoints(pdata, true); } + + mp_builtin->typelookup_manager_->assign_remote_endpoints(pdata); } void PDPClient::removeRemoteEndpoints( diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp index 7efa3119066..9ce04ef45e4 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -721,6 +722,8 @@ void PDPServer::perform_builtin_endpoints_matching( { mp_builtin->mp_WLP->assignRemoteEndpoints(pdata, true); } + + mp_builtin->typelookup_manager_->assign_remote_endpoints(pdata); } void PDPServer::removeRemoteEndpoints( diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 3ce84a22815..e394a63349b 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -2486,6 +2486,14 @@ XMLP_ret XMLParser::fillDataNode( return XMLP_ret::XML_ERROR; } } + else if (strcmp(name, TYPELOOKUP_SERVICE_THREAD) == 0) + { + if (XMLP_ret::XML_OK != + getXMLThreadSettings(*p_aux0, participant_node.get()->rtps.typelookup_service_thread)) + { + return XMLP_ret::XML_ERROR; + } + } else if (strcmp(name, BUILTIN_TRANSPORTS_RECEPTION_THREADS) == 0) { if (XMLP_ret::XML_OK != diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index a165d102853..11b01382b21 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -146,6 +146,7 @@ const char* MAX_USER_DATA = "max_user_data"; const char* MAX_PARTITIONS = "max_partitions"; const char* TIMED_EVENTS_THREAD = "timed_events_thread"; const char* DISCOVERY_SERVER_THREAD = "discovery_server_thread"; +const char* TYPELOOKUP_SERVICE_THREAD = "typelookup_service_thread"; const char* SECURITY_LOG_THREAD = "security_log_thread"; const char* BUILTIN_TRANSPORTS_RECEPTION_THREADS = "builtin_transports_reception_threads"; const char* BUILTIN_CONTROLLERS_SENDER_THREAD = "builtin_controllers_sender_thread"; diff --git a/src/cpp/xmlparser/XMLParserCommon.h b/src/cpp/xmlparser/XMLParserCommon.h index 9b7c18e34a2..d157facebb2 100644 --- a/src/cpp/xmlparser/XMLParserCommon.h +++ b/src/cpp/xmlparser/XMLParserCommon.h @@ -162,6 +162,7 @@ extern const char* MAX_USER_DATA; extern const char* MAX_PARTITIONS; extern const char* TIMED_EVENTS_THREAD; extern const char* DISCOVERY_SERVER_THREAD; +extern const char* TYPELOOKUP_SERVICE_THREAD; extern const char* SECURITY_LOG_THREAD; extern const char* BUILTIN_TRANSPORTS_RECEPTION_THREADS; extern const char* BUILTIN_CONTROLLERS_SENDER_THREAD; diff --git a/test/blackbox/api/dds-pim/PubSubReader.hpp b/test/blackbox/api/dds-pim/PubSubReader.hpp index 5c1e62ccce4..00df6c72cd0 100644 --- a/test/blackbox/api/dds-pim/PubSubReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubReader.hpp @@ -113,9 +113,10 @@ class PubSubReader } } - void on_publisher_discovery( + void on_data_writer_discovery( eprosima::fastdds::dds::DomainParticipant*, - eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info) override + eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { if (reader_.onEndpointDiscovery_ != nullptr) { @@ -145,7 +146,7 @@ class PubSubReader private: using eprosima::fastdds::dds::DomainParticipantListener::on_participant_discovery; - using eprosima::fastdds::dds::DomainParticipantListener::on_publisher_discovery; + using eprosima::fastdds::dds::DomainParticipantListener::on_data_writer_discovery; ParticipantListener& operator =( const ParticipantListener&) = delete; diff --git a/test/blackbox/api/dds-pim/PubSubWriter.hpp b/test/blackbox/api/dds-pim/PubSubWriter.hpp index 81e21ba9ab9..a1caf168ed1 100644 --- a/test/blackbox/api/dds-pim/PubSubWriter.hpp +++ b/test/blackbox/api/dds-pim/PubSubWriter.hpp @@ -115,9 +115,10 @@ class PubSubWriter #endif // if HAVE_SECURITY - void on_subscriber_discovery( + void on_data_reader_discovery( eprosima::fastdds::dds::DomainParticipant*, - eprosima::fastrtps::rtps::ReaderDiscoveryInfo&& info) override + eprosima::fastrtps::rtps::ReaderDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { if (info.status == eprosima::fastrtps::rtps::ReaderDiscoveryInfo::DISCOVERED_READER) { @@ -134,9 +135,10 @@ class PubSubWriter } } - void on_publisher_discovery( + void on_data_writer_discovery( eprosima::fastdds::dds::DomainParticipant*, - eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info) override + eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { if (info.status == eprosima::fastrtps::rtps::WriterDiscoveryInfo::DISCOVERED_WRITER) { @@ -155,8 +157,8 @@ class PubSubWriter private: using eprosima::fastdds::dds::DomainParticipantListener::on_participant_discovery; - using eprosima::fastdds::dds::DomainParticipantListener::on_publisher_discovery; - using eprosima::fastdds::dds::DomainParticipantListener::on_subscriber_discovery; + using eprosima::fastdds::dds::DomainParticipantListener::on_data_writer_discovery; + using eprosima::fastdds::dds::DomainParticipantListener::on_data_reader_discovery; ParticipantListener& operator =( const ParticipantListener&) = delete; diff --git a/test/blackbox/api/dds-pim/PubSubWriterReader.hpp b/test/blackbox/api/dds-pim/PubSubWriterReader.hpp index 59cc3c6f4d7..96348c98e96 100644 --- a/test/blackbox/api/dds-pim/PubSubWriterReader.hpp +++ b/test/blackbox/api/dds-pim/PubSubWriterReader.hpp @@ -108,9 +108,10 @@ class PubSubWriterReader } } - void on_subscriber_discovery( + void on_data_reader_discovery( eprosima::fastdds::dds::DomainParticipant* participant, - eprosima::fastrtps::rtps::ReaderDiscoveryInfo&& info) override + eprosima::fastrtps::rtps::ReaderDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { (void)participant; @@ -129,9 +130,10 @@ class PubSubWriterReader } } - void on_publisher_discovery( + void on_data_writer_discovery( eprosima::fastdds::dds::DomainParticipant* participant, - eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info) override + eprosima::fastrtps::rtps::WriterDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { (void)participant; @@ -171,8 +173,8 @@ class PubSubWriterReader private: using eprosima::fastdds::dds::DomainParticipantListener::on_participant_discovery; - using eprosima::fastdds::dds::DomainParticipantListener::on_publisher_discovery; - using eprosima::fastdds::dds::DomainParticipantListener::on_subscriber_discovery; + using eprosima::fastdds::dds::DomainParticipantListener::on_data_writer_discovery; + using eprosima::fastdds::dds::DomainParticipantListener::on_data_reader_discovery; //! Mutex guarding all info collections mutable std::mutex info_mutex_; diff --git a/test/dds/communication/CMakeLists.txt b/test/dds/communication/CMakeLists.txt index 6aac5677baa..ee6ec3d8312 100644 --- a/test/dds/communication/CMakeLists.txt +++ b/test/dds/communication/CMakeLists.txt @@ -25,26 +25,27 @@ include_directories(${Asio_INCLUDE_DIR}) # Binaries ############################################################################### -# Dynamic types test -set(DDS_PUBLISHER_DYNAMIC_SOURCE - PublisherDynamic.cpp - ) -add_executable(DDSSimpleCommunicationDynamicPublisher ${DDS_PUBLISHER_DYNAMIC_SOURCE}) -target_compile_definitions(DDSSimpleCommunicationDynamicPublisher PRIVATE - $<$>,$>:__DEBUG> - $<$:__INTERNALDEBUG> # Internal debug activated. - ) -target_link_libraries(DDSSimpleCommunicationDynamicPublisher fastdds fastcdr foonathan_memory ${CMAKE_DL_LIBS}) - -set(DDS_SUBSCRIBER_DYNAMIC_SOURCE - SubscriberDynamic.cpp - ) -add_executable(DDSSimpleCommunicationDynamicSubscriber ${DDS_SUBSCRIBER_DYNAMIC_SOURCE}) -target_compile_definitions(DDSSimpleCommunicationDynamicSubscriber PRIVATE - $<$>,$>:__DEBUG> - $<$:__INTERNALDEBUG> # Internal debug activated. - ) -target_link_libraries(DDSSimpleCommunicationDynamicSubscriber fastdds fastcdr foonathan_memory ${CMAKE_DL_LIBS}) +# TODO Restore when Dynamic types are registered in TypeObjectRegistry +# # Dynamic types test +# set(DDS_PUBLISHER_DYNAMIC_SOURCE +# PublisherDynamic.cpp +# ) +# add_executable(DDSSimpleCommunicationDynamicPublisher ${DDS_PUBLISHER_DYNAMIC_SOURCE}) +# target_compile_definitions(DDSSimpleCommunicationDynamicPublisher PRIVATE +# $<$>,$>:__DEBUG> +# $<$:__INTERNALDEBUG> # Internal debug activated. +# ) +# target_link_libraries(DDSSimpleCommunicationDynamicPublisher fastdds fastcdr foonathan_memory ${CMAKE_DL_LIBS}) + +# set(DDS_SUBSCRIBER_DYNAMIC_SOURCE +# SubscriberDynamic.cpp +# ) +# add_executable(DDSSimpleCommunicationDynamicSubscriber ${DDS_SUBSCRIBER_DYNAMIC_SOURCE}) +# target_compile_definitions(DDSSimpleCommunicationDynamicSubscriber PRIVATE +# $<$>,$>:__DEBUG> +# $<$:__INTERNALDEBUG> # Internal debug activated. +# ) +# target_link_libraries(DDSSimpleCommunicationDynamicSubscriber fastdds fastcdr foonathan_memory ${CMAKE_DL_LIBS}) # Standard tests set(COMMON_SOURCE @@ -94,9 +95,10 @@ target_link_libraries(DDSCommunicationPubSub fastdds fastcdr foonathan_memory ${ ############################################################################### # Necessary files ############################################################################### -# Dynamic types test -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/simple_communication_dynamic.py - ${CMAKE_CURRENT_BINARY_DIR}/simple_communication_dynamic.py COPYONLY) +# TODO Restore when Dynamic types are registered in TypeObjectRegistry +# # Dynamic types test +# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/simple_communication_dynamic.py +# ${CMAKE_CURRENT_BINARY_DIR}/simple_communication_dynamic.py COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/example_type_profile.xml ${CMAKE_CURRENT_BINARY_DIR}/example_type_profile.xml COPYONLY) @@ -180,22 +182,24 @@ endif() # Tests specification ############################################################################### if(Python3_Interpreter_FOUND) - # Dynamic types test - add_test(NAME DDSSimpleCommunicationTypeDiscovery - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/simple_communication_dynamic.py) - - # Set test with label NoMemoryCheck - set_property(TEST DDSSimpleCommunicationTypeDiscovery PROPERTY LABELS "NoMemoryCheck") - set_property(TEST DDSSimpleCommunicationTypeDiscovery PROPERTY ENVIRONMENT - "DDS_SIMPLE_COMMUNICATION_PUBLISHER_BIN=$") - set_property(TEST DDSSimpleCommunicationTypeDiscovery APPEND PROPERTY ENVIRONMENT - "DDS_SIMPLE_COMMUNICATION_SUBSCRIBER_BIN=$") - if(WIN32) - string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}") - set_property(TEST DDSSimpleCommunicationTypeDiscovery APPEND PROPERTY ENVIRONMENT - "PATH=$\\;$\\;${WIN_PATH}") - endif() + # TODO Restore when Dynamic types are registered in TypeObjectRegistry + # # Dynamic types test + # add_test(NAME DDSSimpleCommunicationTypeDiscovery + # COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/simple_communication_dynamic.py) + + # # Set test with label NoMemoryCheck + # set_property(TEST DDSSimpleCommunicationTypeDiscovery PROPERTY LABELS "NoMemoryCheck") + + # set_property(TEST DDSSimpleCommunicationTypeDiscovery PROPERTY ENVIRONMENT + # "DDS_SIMPLE_COMMUNICATION_PUBLISHER_BIN=$") + # set_property(TEST DDSSimpleCommunicationTypeDiscovery APPEND PROPERTY ENVIRONMENT + # "DDS_SIMPLE_COMMUNICATION_SUBSCRIBER_BIN=$") + # if(WIN32) + # string(REPLACE ";" "\\;" WIN_PATH "$ENV{PATH}") + # set_property(TEST DDSSimpleCommunicationTypeDiscovery APPEND PROPERTY ENVIRONMENT + # "PATH=$\\;$\\;${WIN_PATH}") + # endif() # Standard types test set(TEST_BUILDER ${BINARY_TEST_DIR}test_build.py) diff --git a/test/dds/communication/PublisherDynamic.cpp b/test/dds/communication/PublisherDynamic.cpp index 817e99d470b..b2a2e0e878e 100644 --- a/test/dds/communication/PublisherDynamic.cpp +++ b/test/dds/communication/PublisherDynamic.cpp @@ -245,9 +245,8 @@ int main( } DynamicType::_ref_type dyn_type; - if (RETCODE_OK != - DomainParticipantFactory::get_instance()->get_dynamic_type_builder_from_xml_by_name("TypeLookup", - dyn_type)) + if (RETCODE_OK != DomainParticipantFactory::get_instance()-> + get_dynamic_type_builder_from_xml_by_name("TypeLookup", dyn_type)) { std::cout << "Error getting dynamic type from XML file" << std::endl; return 1; @@ -308,6 +307,7 @@ int main( data->set_uint32_value(1, 1); DynamicData::_ref_type inner {data->loan_value(2)}; inner->set_byte_value(0, 10); + data->return_loaned_value(inner); while (run) { @@ -329,6 +329,7 @@ int main( octet inner_count; inner->get_byte_value(inner_count, 0); inner->set_byte_value(0, inner_count + 1); + data->return_loaned_value(inner); std::this_thread::sleep_for(std::chrono::milliseconds(250)); } diff --git a/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h index fcc6ab17f96..2ec5e6c784e 100644 --- a/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h +++ b/test/mock/rtps/RTPSParticipantAttributes/fastdds/rtps/attributes/RTPSParticipantAttributes.h @@ -464,6 +464,7 @@ class RTPSParticipantAttributes (this->security_log_thread == b.security_log_thread) && #endif // if HAVE_SECURITY (this->discovery_server_thread == b.discovery_server_thread) && + (this->typelookup_service_thread == b.typelookup_service_thread) && (this->builtin_transports_reception_threads == b.builtin_transports_reception_threads); } @@ -617,6 +618,9 @@ class RTPSParticipantAttributes //! Thread settings for the discovery server thread fastdds::rtps::ThreadSettings discovery_server_thread; + //! Thread settings for the builtin TypeLookup service requests and replies threads + fastdds::rtps::ThreadSettings typelookup_service_thread; + //! Thread settings for the builtin transports reception threads fastdds::rtps::ThreadSettings builtin_transports_reception_threads; diff --git a/test/mock/rtps/TypeLookupManager/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp b/test/mock/rtps/TypeLookupManager/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp index 27a49169974..a6c6da79944 100644 --- a/test/mock/rtps/TypeLookupManager/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp +++ b/test/mock/rtps/TypeLookupManager/fastdds/builtin/type_lookup_service/TypeLookupManager.hpp @@ -44,7 +44,7 @@ namespace fastdds { namespace dds { namespace builtin { -const fastrtps::rtps::SampleIdentity INVALID_SAMPLE_IDENTITY; +extern const fastrtps::rtps::SampleIdentity INVALID_SAMPLE_IDENTITY; /** * Class TypeLookupManager that implements the TypeLookup Service described in the DDS-XTYPES 1.2 specification. diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index 3cb4fd2acf4..a3b73f88001 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -3159,6 +3159,11 @@ TEST(ParticipantTests, UpdatableDomainParticipantQos) pqos.discovery_server_thread().affinity = 1; ASSERT_EQ(participant->set_qos(pqos), RETCODE_IMMUTABLE_POLICY); + // Check that the typelookup_service_thread can not be changed in an enabled participant + participant->get_qos(pqos); + pqos.typelookup_service_thread().affinity = 1; + ASSERT_EQ(participant->set_qos(pqos), RETCODE_IMMUTABLE_POLICY); + #if HAVE_SECURITY // Check that the security_log_thread can not be changed in an enabled participant participant->get_qos(pqos); diff --git a/test/unittest/dds/profiles/test_xml_for_string_profile.xml b/test/unittest/dds/profiles/test_xml_for_string_profile.xml index 50c0a6bcbc8..b82c883fcaa 100644 --- a/test/unittest/dds/profiles/test_xml_for_string_profile.xml +++ b/test/unittest/dds/profiles/test_xml_for_string_profile.xml @@ -138,6 +138,10 @@ 15 1048576 + + 15 + 1048576 + 15 1048576 @@ -283,6 +287,10 @@ 15 1048576 + + 15 + 1048576 + 15 1048576 diff --git a/test/unittest/dds/profiles/test_xml_profile.xml b/test/unittest/dds/profiles/test_xml_profile.xml index 7b7f8ded7f4..3d8c3604ed8 100644 --- a/test/unittest/dds/profiles/test_xml_profile.xml +++ b/test/unittest/dds/profiles/test_xml_profile.xml @@ -135,6 +135,10 @@ 15 1048576 + + 15 + 1048576 + 15 1048576 @@ -280,6 +284,10 @@ 15 1048576 + + 15 + 1048576 + 15 1048576 diff --git a/test/unittest/dds/publisher/DataWriterTests.cpp b/test/unittest/dds/publisher/DataWriterTests.cpp index 0c66f5bb374..d7cb0828a88 100644 --- a/test/unittest/dds/publisher/DataWriterTests.cpp +++ b/test/unittest/dds/publisher/DataWriterTests.cpp @@ -372,9 +372,10 @@ TEST(DataWriterTests, get_guid) { public: - void on_publisher_discovery( + void on_data_writer_discovery( DomainParticipant*, - fastrtps::rtps::WriterDiscoveryInfo&& info) + fastrtps::rtps::WriterDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { std::unique_lock lock(mutex); if (fastrtps::rtps::WriterDiscoveryInfo::DISCOVERED_WRITER == info.status) @@ -390,7 +391,7 @@ TEST(DataWriterTests, get_guid) private: - using DomainParticipantListener::on_publisher_discovery; + using DomainParticipantListener::on_data_writer_discovery; } discovery_listener; diff --git a/test/unittest/dds/subscriber/DataReaderTests.cpp b/test/unittest/dds/subscriber/DataReaderTests.cpp index 38d1bb55267..0b34fe93837 100644 --- a/test/unittest/dds/subscriber/DataReaderTests.cpp +++ b/test/unittest/dds/subscriber/DataReaderTests.cpp @@ -578,9 +578,10 @@ TEST_F(DataReaderTests, get_guid) { public: - void on_subscriber_discovery( + void on_data_reader_discovery( DomainParticipant*, - ReaderDiscoveryInfo&& info) + ReaderDiscoveryInfo&& info, + bool& /*should_be_ignored*/) override { std::unique_lock lock(mutex); if (ReaderDiscoveryInfo::DISCOVERED_READER == info.status) @@ -596,7 +597,7 @@ TEST_F(DataReaderTests, get_guid) private: - using DomainParticipantListener::on_subscriber_discovery; + using DomainParticipantListener::on_data_reader_discovery; } discovery_listener; diff --git a/test/unittest/dds/xtypes/type_representation/TypeObjectUtilsTests.cpp b/test/unittest/dds/xtypes/type_representation/TypeObjectUtilsTests.cpp index 48d20f3f588..55cbd0b5d6a 100644 --- a/test/unittest/dds/xtypes/type_representation/TypeObjectUtilsTests.cpp +++ b/test/unittest/dds/xtypes/type_representation/TypeObjectUtilsTests.cpp @@ -3451,5 +3451,7 @@ int main( char** argv) { testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + int ret_value = RUN_ALL_TESTS(); + eprosima::fastdds::dds::Log::KillThread(); + return ret_value; } diff --git a/test/unittest/rtps/builtin/BuiltinDataSerializationTests.cpp b/test/unittest/rtps/builtin/BuiltinDataSerializationTests.cpp index b35f180aad9..76cd708b1bc 100644 --- a/test/unittest/rtps/builtin/BuiltinDataSerializationTests.cpp +++ b/test/unittest/rtps/builtin/BuiltinDataSerializationTests.cpp @@ -140,8 +140,9 @@ TEST(BuiltinDataSerializationTests, ok_with_defaults) } } -// Regression test for redmine issue #10547 -TEST(BuiltinDataSerializationTests, ignore_unsupported_type_info) +// Regression test for redmine issue #10547. +// Update against OpenDDS 3.27. With this version we can read the remote DATA(w). +TEST(BuiltinDataSerializationTests, interoperability_with_opendds_3_27) { // DATA(w) { @@ -153,16 +154,17 @@ TEST(BuiltinDataSerializationTests, ignore_unsupported_type_info) // Topic name 0x05, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, - // Type information - 0x75, 0x00, 0x50, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x99, 0x5e, 0xfc, 0xdb, 0xda, 0xbe, 0xd5, 0xb3, 0x3d, 0xe3, - 0xea, 0x3a, 0x4b, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x10, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Type name 0x07, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, + // Type information + 0x75, 0x00, 0x58, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x4b, 0x28, 0x4d, 0xe3, 0xa2, 0x4e, 0x5f, 0x86, 0x58, 0x5c, + 0x57, 0x88, 0xf6, 0x00, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x1c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reliability 0x1a, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xf5, 0x05, @@ -171,15 +173,27 @@ TEST(BuiltinDataSerializationTests, ignore_unsupported_type_info) 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // Endpoint GUID 0x5a, 0x00, 0x10, 0x00, - 0x01, 0x03, 0x08, 0x00, 0x27, 0x5c, 0x4f, 0x05, 0x0f, 0x19, 0x05, 0xea, 0x00, 0x00, 0x00, 0x02, + 0x01, 0x03, 0x74, 0x04, 0xf1, 0x0b, 0x6b, 0x16, 0x94, 0x6c, 0x26, 0x73, 0x00, 0x00, 0x00, 0x02, // Multicast locator 0x30, 0x00, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe9, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0x00, 0x02, // Unicast locator 0x2f, 0x00, 0x18, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x3e, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0xb4, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x27, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x11, 0x00, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x50, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x8b, // Sentinel 0x01, 0x00, 0x00, 0x00 }; @@ -203,35 +217,45 @@ TEST(BuiltinDataSerializationTests, ignore_unsupported_type_info) 0x05, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x43, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, // Type information - 0x75, 0x00, 0x50, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xf1, 0x80, 0x99, 0x5e, 0xfc, 0xdb, 0xda, 0xbe, 0xd5, 0xb3, 0x3d, 0xe3, - 0xea, 0x3a, 0x4b, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x10, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x58, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0xf1, 0x8b, 0x4b, 0x28, 0x4d, 0xe3, 0xa2, 0x4e, 0x5f, 0x86, 0x58, 0x5c, + 0x57, 0x88, 0xf6, 0x00, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x1c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Type name 0x07, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, // Reliability 0x1a, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, - // Endpoint GUID - 0x5a, 0x00, 0x10, 0x00, - 0x01, 0x03, 0x08, 0x00, 0x27, 0x5c, 0x4f, 0x05, 0x0f, 0x40, 0x29, 0x9d, 0x00, 0x00, 0x00, 0x07, // Data representation 0x73, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x94, 0xd0, 0x00, 0x00, + // Endpoint GUID + 0x5a, 0x00, 0x10, 0x00, + 0x01, 0x03, 0x74, 0x04, 0xf1, 0x0b, 0x6b, 0x16, 0x84, 0x3e, 0x9d, 0x2b, 0x00, 0x00, 0x00, 0x07, // Multicast locator 0x30, 0x00, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe9, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0x00, 0x02, // Unicast locator 0x2f, 0x00, 0x18, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x45, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0xb4, - // Type consistency - 0x74, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x27, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x11, 0x00, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x00, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x50, 0x01, + 0x2f, 0x00, 0x18, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x8b, // Sentinel 0x01, 0x00, 0x00, 0x00 }; diff --git a/test/unittest/rtps/discovery/EdpTests.cpp b/test/unittest/rtps/discovery/EdpTests.cpp index 5075625579f..f092e87bbbe 100644 --- a/test/unittest/rtps/discovery/EdpTests.cpp +++ b/test/unittest/rtps/discovery/EdpTests.cpp @@ -133,6 +133,8 @@ class EdpTests : public ::testing::Test void set_incompatible_type() { rdata->typeName("AnotherTypeName"); + rdata->type_information().assigned(false); + wdata->type_information().assigned(false); } void check_expectations( diff --git a/test/unittest/xmlparser/test_xml_deprecated.xml b/test/unittest/xmlparser/test_xml_deprecated.xml index 742ffad487a..baa203da3df 100644 --- a/test/unittest/xmlparser/test_xml_deprecated.xml +++ b/test/unittest/xmlparser/test_xml_deprecated.xml @@ -165,6 +165,12 @@ 12 12 + + 12 + 12 + 12 + 12 + 12 12 diff --git a/test/unittest/xmlparser/test_xml_profile.xml b/test/unittest/xmlparser/test_xml_profile.xml index 7e850567d7d..f75239b65db 100644 --- a/test/unittest/xmlparser/test_xml_profile.xml +++ b/test/unittest/xmlparser/test_xml_profile.xml @@ -181,6 +181,12 @@ 12 12 + + 12 + 12 + 12 + 12 + 12 12 diff --git a/test/unittest/xmlparser/test_xml_profile_env_var.xml b/test/unittest/xmlparser/test_xml_profile_env_var.xml index 8ecf1c12cd8..57428c1151a 100644 --- a/test/unittest/xmlparser/test_xml_profile_env_var.xml +++ b/test/unittest/xmlparser/test_xml_profile_env_var.xml @@ -162,6 +162,12 @@ ${XML_PROFILES_ENV_VAR_160} ${XML_PROFILES_ENV_VAR_161} + + ${XML_PROFILES_ENV_VAR_158} + ${XML_PROFILES_ENV_VAR_159} + ${XML_PROFILES_ENV_VAR_160} + ${XML_PROFILES_ENV_VAR_161} + ${XML_PROFILES_ENV_VAR_158} ${XML_PROFILES_ENV_VAR_159} diff --git a/test/unittest/xmlparser/test_xml_rooted_deprecated.xml b/test/unittest/xmlparser/test_xml_rooted_deprecated.xml index 48e6926cab8..3a5939c3cf8 100644 --- a/test/unittest/xmlparser/test_xml_rooted_deprecated.xml +++ b/test/unittest/xmlparser/test_xml_rooted_deprecated.xml @@ -140,6 +140,12 @@ 12 12 + + 12 + 12 + 12 + 12 + 12 12 diff --git a/test/unittest/xmlparser/test_xml_rooted_profile.xml b/test/unittest/xmlparser/test_xml_rooted_profile.xml index a8fb6503d6d..d02b379f79a 100644 --- a/test/unittest/xmlparser/test_xml_rooted_profile.xml +++ b/test/unittest/xmlparser/test_xml_rooted_profile.xml @@ -155,6 +155,12 @@ 12 12 + + 12 + 12 + 12 + 12 + 12 12