diff --git a/rmw/include/rmw/dynamic_message_type_support.h b/rmw/include/rmw/dynamic_message_type_support.h
index ea9e78fb..3b84d391 100644
--- a/rmw/include/rmw/dynamic_message_type_support.h
+++ b/rmw/include/rmw/dynamic_message_type_support.h
@@ -36,7 +36,50 @@ extern "C"
/// Interfaces for runtime interface reflection
// RUNTIME INTERFACE REFLECTION TYPE SUPPORT =======================================================
-/// Get dynamic type message typesupport with bound message description
+/// Initialize dynamic type message typesupport, binding message description
+/**
+ * NOTE: Take note of the ownership rules for the returned struct and the `description` argument!
+ *
+ * If the user passes a NULL description, it is deferred instead, the middleware is responsibile
+ * for populating the fields on type discovery!!!
+ *
+ * Ownership:
+ * - The `rosidl_message_type_support_t *` returned from this function has different ownership
+ * rules compared to the statically allocated `rosidl_message_type_support_t` structs from
+ * code-generated types!
+ * - The caller is responsible for deallocating the returned pointer
+ *
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ */
+RMW_PUBLIC
+RMW_WARN_UNUSED
+rmw_ret_t
+rmw_dynamic_message_type_support_handle_init(
+ rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
+ bool middleware_supports_type_discovery,
+ const rosidl_type_hash_t * type_hash,
+ const rosidl_runtime_c__type_description__TypeDescription * type_description,
+ const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
+ rcutils_allocator_t * allocator,
+ rosidl_message_type_support_t * ts); // OUT
+
+/// Finalize a rosidl_message_type_support_t obtained with
+/// `rmw_dynamic_message_type_support_handle_create()`, which has dynamically allocated members
+///
+/// NOTE: Using this on a statically allocated typesupport will cause undefined behavior!
+/// (Static memory will get freed in that case.)
+RMW_PUBLIC
+RMW_WARN_UNUSED
+rmw_ret_t
+rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts);
+
+/// Create dynamic type message typesupport with bound message description
/**
* NOTE: Take note of the ownership rules for the returned struct and the `description` argument!
*
@@ -66,6 +109,7 @@ rmw_dynamic_message_type_support_handle_create(
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
+ rcutils_allocator_t * allocator,
rosidl_message_type_support_t ** ts); // OUT
/// Destroy a rosidl_message_type_support_t obtained with
diff --git a/rmw/src/dynamic_message_type_support.c b/rmw/src/dynamic_message_type_support.c
index 6bb24949..8a5b2e8b 100644
--- a/rmw/src/dynamic_message_type_support.c
+++ b/rmw/src/dynamic_message_type_support.c
@@ -33,8 +33,52 @@ extern "C"
// NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just
// use the FastRTPS support then?
+rmw_ret_t
+rmw_dynamic_message_type_support_handle_init(
+ rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
+ bool middleware_supports_type_discovery,
+ const rosidl_type_hash_t * type_hash,
+ const rosidl_runtime_c__type_description__TypeDescription * type_description,
+ const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
+ rcutils_allocator_t * allocator,
+ rosidl_message_type_support_t * ts)
+{
+ if (!middleware_supports_type_discovery && type_description == NULL) {
+ RMW_SET_ERROR_MSG(
+ "Middleware does not support type discovery. Deferred dynamic type message type support will "
+ "never be populated. You must provide a type description.");
+ return RMW_RET_INVALID_ARGUMENT;
+ }
+ // TODO(methylDragon): Remove if and when the deferred description path is supported
+ if (type_description == NULL) {
+ RMW_SET_ERROR_MSG(
+ "Deferred type description is not currently supported. You must provide a type description.");
+ return RMW_RET_INVALID_ARGUMENT;
+ }
+
+ RMW_CHECK_ARGUMENT_FOR_NULL(serialization_support, RMW_RET_INVALID_ARGUMENT);
+ RMW_CHECK_ARGUMENT_FOR_NULL(type_hash, RMW_RET_INVALID_ARGUMENT);
+ RMW_CHECK_ARGUMENT_FOR_NULL(type_description, RMW_RET_INVALID_ARGUMENT);
+ RMW_CHECK_ARGUMENT_FOR_NULL(allocator, RMW_RET_INVALID_ARGUMENT);
+ RMW_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);
+
+ // NOTE(methylDragon): Not supported for now
+ // RMW_CHECK_ARGUMENT_FOR_NULL(type_description_sources, RMW_RET_INVALID_ARGUMENT);
+
+ return rmw_convert_rcutils_ret_to_rmw_ret(
+ rosidl_dynamic_message_type_support_handle_init(
+ serialization_support, type_hash, type_description, type_description_sources, allocator, ts));
+}
+
+rmw_ret_t
+rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts)
+{
+ if (!ts) {
+ return RCUTILS_RET_OK;
+ }
+ return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_fini(ts));
+}
-/// Create a rosidl_message_type_support_t from a TypeDescription message
rmw_ret_t
rmw_dynamic_message_type_support_handle_create(
rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
@@ -42,6 +86,7 @@ rmw_dynamic_message_type_support_handle_create(
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
+ rcutils_allocator_t * allocator,
rosidl_message_type_support_t ** ts)
{
if (!middleware_supports_type_discovery && type_description == NULL) {
@@ -60,6 +105,7 @@ rmw_dynamic_message_type_support_handle_create(
RMW_CHECK_ARGUMENT_FOR_NULL(serialization_support, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_hash, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_description, RMW_RET_INVALID_ARGUMENT);
+ RMW_CHECK_ARGUMENT_FOR_NULL(allocator, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);
// NOTE(methylDragon): Not supported for now
@@ -67,13 +113,15 @@ rmw_dynamic_message_type_support_handle_create(
return rmw_convert_rcutils_ret_to_rmw_ret(
rosidl_dynamic_message_type_support_handle_create(
- serialization_support, type_hash, type_description, type_description_sources, ts));
+ serialization_support, type_hash, type_description, type_description_sources, allocator, ts));
}
rmw_ret_t
rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * ts)
{
- RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);
+ if (!ts) {
+ return RCUTILS_RET_OK;
+ }
return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_destroy(ts));
}