From 59e63c869f56d0dd2446368b24ff89e902fb1a1a Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 21 Dec 2022 22:21:14 -0800 Subject: [PATCH 01/18] Implement first cut Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 6 ++ rmw/include/rmw/features.h | 5 ++ rmw/include/rmw/rmw.h | 1 + rmw/include/rmw/runtime_type.h | 141 +++++++++++++++++++++++++++++ rmw/package.xml | 2 + rmw/src/runtime_type.c | 160 +++++++++++++++++++++++++++++++++ 6 files changed, 315 insertions(+) create mode 100644 rmw/include/rmw/runtime_type.h create mode 100644 rmw/src/runtime_type.c diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index 0ab7b35b..c459a941 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -18,6 +18,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() find_package(ament_cmake_ros REQUIRED) +find_package(serialization_support_lib REQUIRED) find_package(rcutils REQUIRED) find_package(rosidl_runtime_c REQUIRED) @@ -37,6 +38,7 @@ set(rmw_sources "src/network_flow_endpoint.c" "src/publisher_options.c" "src/qos_string_conversions.c" + "src/runtime_type.c" "src/sanity_checks.c" "src/security_options.c" "src/subscription_content_filter_options.c" @@ -54,6 +56,9 @@ add_library(${PROJECT_NAME} ${rmw_sources}) target_include_directories(${PROJECT_NAME} PUBLIC "$" "$") +target_link_libraries(${PROJECT_NAME} + serialization_support_lib::serialization_support_lib +) if(BUILD_TESTING AND NOT RCUTILS_DISABLE_FAULT_INJECTION) target_compile_definitions(${PROJECT_NAME} PUBLIC RCUTILS_ENABLE_FAULT_INJECTION) @@ -76,6 +81,7 @@ ament_export_libraries(${PROJECT_NAME}) # Export modern CMake targets ament_export_targets(${PROJECT_NAME}) +ament_export_dependencies(serialization_support_lib) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) diff --git a/rmw/include/rmw/features.h b/rmw/include/rmw/features.h index 367b586e..f454fc45 100644 --- a/rmw/include/rmw/features.h +++ b/rmw/include/rmw/features.h @@ -46,6 +46,11 @@ typedef enum RMW_PUBLIC_TYPE rmw_feature_e /// `rmw_message_info_t.reception_sequence_number` is filled correctly /// by the rmw implementation. RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER = 1, + /// deferred description runtime type rosidl_message_type_support_t structs are allowed, and the + /// middleware MUST populate them on type discovery + RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY = 2, + /// runtime type subscriptions will use take_dynamic_data_message_with_info() + RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA = 3, } rmw_feature_t; /// Query if a feature is supported by the rmw implementation. diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index d9a5e5d9..03c861f5 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -106,6 +106,7 @@ extern "C" #include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" +#include "rmw/runtime_type.h" // TODO(methylDragon): NEW!! #include "rmw/subscription_options.h" #include "rmw/types.h" #include "rmw/visibility_control.h" diff --git a/rmw/include/rmw/runtime_type.h b/rmw/include/rmw/runtime_type.h new file mode 100644 index 00000000..99b19e60 --- /dev/null +++ b/rmw/include/rmw/runtime_type.h @@ -0,0 +1,141 @@ +// Copyright 2022 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMW__RUNTIME_TYPE_H_ +#define RMW__RUNTIME_TYPE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmw/features.h" +#include "rmw/types.h" +#include "rmw/visibility_control.h" + +#include "serialization_support_lib/types.h" +#include "serialization_support_lib/api/serialization_support.h" +#include "rosidl_runtime_c/message_type_support_struct.h" + +/// Interfaces for runtime interface reflection + +// RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= +/// String identifying the typesupport introspection implementation in use. +// NOTE(methylDragon): I don't know if this is supposed to be in an identifier.h file +RMW_PUBLIC +extern const char * rmw_typesupport_runtime_type_introspection_c__identifier; + + +// This struct is meant to be populated fully if the rosidl_message_type_support_t is constructed +// with a given description on the client library end (since the descrpition is obtained via +// services). +// +// Otherwise, it is deferred MUST be populated on type discovery, if the middleware supports it +typedef struct runtime_type_ts_impl_s { + bool take_dynamic_data; // Take dynamic data at the middleware level + // Get from middleware specific link-time function: + // rmw_middleware_can_take_dynamic_data() + + const char * topic_name; // MAYBE??? + type_description_t * desc; // Might be unused if dynamic_type is obtained directly + serialization_support_t * ser; + ser_dynamic_type_t * dynamic_type; + ser_dynamic_data_t * dynamic_data; +} runtime_type_ts_impl_t; + +// TODO(methylDragon): !!! Document that the user is in charge of the lifetime of the struct... +// TODO(methylDragon): ... How do I do this? ^ +// NOTE(methylDragon): My use of the serialization_support_lib::type_description_t struct is for +// convenience only. We should be passing the TypeDescription message + +/// Get runtime type message typesupport with bound message description +/// If the user passes a NULL desc, it is deferred instead, the middleware is responsibile for +/// populating the fields on type discovery!!! +RMW_PUBLIC +RMW_WARN_UNUSED +rosidl_message_type_support_t * +rmw_get_runtime_type_message_typesupport_handle( + serialization_support_t * ser_support, + bool middleware_supports_type_discovery, + bool middleware_can_take_dynamic_data, + type_description_t * desc); + +/// Finalize a rosidl_message_type_support_t obtained with +/// rmw_get_runtime_type_message_typesupport_handle +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_runtime_type_message_typesupport_handle_fini(rosidl_message_type_support_t * type_support); + +/// Construct serialization support-specific ser_dynamic_type_t from a given type description +RMW_PUBLIC +RMW_WARN_UNUSED +ser_dynamic_type_t * +rmw_get_dynamic_type_from_description(serialization_support_t * ser, type_description_t * desc); + +RMW_PUBLIC +RMW_WARN_UNUSED +ser_dynamic_data_t * +rmw_get_dynamic_data_from_dynamic_type(serialization_support_t * ser, ser_dynamic_type_t * type); + + +// INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_take_dynamic_data_message_with_info( + const rmw_subscription_t * subscription, + ser_dynamic_data_t * dynamic_data, + bool * taken, + rmw_message_info_t * message_info, + rmw_subscription_allocation_t * allocation); + +RMW_PUBLIC +RMW_WARN_UNUSED +serialization_support_t * +rmw_get_serialization_support(const char * serialization_lib_name); + +// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's +// dynamic type matches the layout of the buffer +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_serialized_to_dynamic_data( + rmw_serialized_message_t * serialized_message, ser_dynamic_data_t * dyn_data); + +// TODO(methylDragon): Nice to have only +// RMW_PUBLIC +// RMW_WARN_UNUSED +// rmw_ret_t +// rmw_get_dynamic_type_from_middleware( +// const rmw_node_t * node, +// const char * topic_name, +// const rosidl_message_type_support_t type_support, +// ser_dynamic_type_t * dynamic_type); +// +// RMW_PUBLIC +// RMW_WARN_UNUSED +// rmw_ret_t +// rmw_get_dynamic_data_from_middleware( +// const rmw_node_t * node, +// const char * topic_name, +// const rosidl_message_type_support_t type_support, +// ser_dynamic_data_t * dynamic_data); + + +#ifdef __cplusplus +} +#endif + +#endif // RMW__RUNTIME_TYPE_H_ diff --git a/rmw/package.xml b/rmw/package.xml index d5aa2838..13ebe12a 100644 --- a/rmw/package.xml +++ b/rmw/package.xml @@ -16,10 +16,12 @@ ament_cmake_ros ament_cmake_version + serialization_support_lib rcutils rosidl_runtime_c + serialization_support_lib rcutils rosidl_runtime_c diff --git a/rmw/src/runtime_type.c b/rmw/src/runtime_type.c new file mode 100644 index 00000000..c0bf7299 --- /dev/null +++ b/rmw/src/runtime_type.c @@ -0,0 +1,160 @@ +// Copyright 2022 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rcutils/logging_macros.h" +#include "serialization_support_lib/description.h" +#include "rosidl_runtime_c/message_type_support_struct.h" + +#include "rmw/runtime_type.h" + + +const char * rmw_typesupport_runtime_type_introspection_c__identifier = + "rmw_typesupport_runtime_type_introspection_c"; + +// NOTE(methylDragon): My use of the serialization_support_lib::type_description_t struct is for +// convenience only. We should be passing the TypeDescription message + +// NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just +// use the FastRTPS support then? + +/// Create a rosidl_message_type_support_t from a TypeDescription message +rosidl_message_type_support_t * +rmw_get_runtime_type_message_typesupport_handle( + serialization_support_t * ser_support, + bool middleware_supports_type_discovery, + bool middleware_can_take_dynamic_data, + type_description_t * desc) +{ + if (!middleware_supports_type_discovery && desc == NULL) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Middleware does not support type discovery! Deferred runtime type" + "message type support will never be populated! You must provide a type " + "description!"); + return NULL; + } + + // TODO(methylDragon): Do I need to use an allocator...? + rosidl_message_type_support_t * ts = + (rosidl_message_type_support_t *)(calloc(1, sizeof(rosidl_message_type_support_t))); + if(!ts) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not allocate rosidl_message_type_support_t struct"); + return NULL; + } + + ts->typesupport_identifier = rmw_typesupport_runtime_type_introspection_c__identifier; + + // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE + ts->data = calloc(1, sizeof(runtime_type_ts_impl_t)); + if(!ts) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not allocate runtime_type_ts_impl_t struct"); + if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not finalize runtime type typesupport"); + } + return NULL; + } + + runtime_type_ts_impl_t * ts_impl = (runtime_type_ts_impl_t *)ts->data; + + ts_impl->take_dynamic_data = middleware_can_take_dynamic_data; + ts_impl->ser = ser_support; + ts->func = get_message_typesupport_handle_function; + + // TODO(methylDragon): This is just temporary. We'd ideally pass in the TypeDescription msg + // The type_description_t object doesn't support default values + ts_impl->desc = desc; + + ts_impl->dynamic_type = rmw_get_dynamic_type_from_description(ts_impl->ser, desc); + if (!ts_impl->dynamic_type) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not construct dynamic type for runtime_type_ts_impl_t struct"); + if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not finalize runtime type typesupport"); + } + return NULL; + } + + ts_impl->dynamic_data = + rmw_get_dynamic_data_from_dynamic_type(ts_impl->ser, ts_impl->dynamic_type); + if (!ts_impl->dynamic_data) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not construct dynamic data for runtime_type_ts_impl_t struct"); + if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + "Could not finalize runtime type typesupport"); + } + return NULL; + } + + return ts; +} + +rmw_ret_t +rmw_runtime_type_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) +{ + RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT); + + // NOTE(methylDragon): Ignores const... + if (ts->typesupport_identifier != rmw_typesupport_runtime_type_introspection_c__identifier) + { + RCUTILS_SET_ERROR_MSG("type support not from this implementation"); + return RMW_RET_INVALID_ARGUMENT; + } + + if (ts->data) { + runtime_type_ts_impl_t * ts_impl = (runtime_type_ts_impl_t *)ts->data; + + if (ts_impl->desc) { + type_description_fini(ts_impl->desc); + } + + if (ts_impl->dynamic_type) { + ser_type_fini(ts_impl->ser, ts_impl->dynamic_type); + } + + if (ts_impl->dynamic_data) { + ser_data_fini(ts_impl->ser, ts_impl->dynamic_data); + } + } + free(ts); + + return RMW_RET_OK; +} + + +ser_dynamic_type_t * +rmw_get_dynamic_type_from_description(serialization_support_t * ser, type_description_t * desc) +{ + return ser_construct_type_from_description(ser, desc); +} + + +ser_dynamic_data_t * +rmw_get_dynamic_data_from_dynamic_type(serialization_support_t * ser, ser_dynamic_type_t * type) +{ + return ser_data_init_from_type(ser, type); +} + + +#ifdef __cplusplus +} +#endif From de4edd087537833774dba4cec3d7746978c9df46 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 27 Feb 2023 13:11:35 -0800 Subject: [PATCH 02/18] Migrate to rosidl_dynamic_typesupport and update field IDs Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 8 +- .../{runtime_type.h => dynamic_typesupport.h} | 75 +++++++++++------ rmw/include/rmw/features.h | 2 +- rmw/include/rmw/rmw.h | 2 +- rmw/package.xml | 4 +- .../{runtime_type.c => dynamic_typesupport.c} | 83 ++++++++++--------- 6 files changed, 101 insertions(+), 73 deletions(-) rename rmw/include/rmw/{runtime_type.h => dynamic_typesupport.h} (53%) rename rmw/src/{runtime_type.c => dynamic_typesupport.c} (51%) diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index c459a941..c54cf6e5 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -18,7 +18,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() find_package(ament_cmake_ros REQUIRED) -find_package(serialization_support_lib REQUIRED) +find_package(rosidl_dynamic_typesupport REQUIRED) find_package(rcutils REQUIRED) find_package(rosidl_runtime_c REQUIRED) @@ -38,7 +38,7 @@ set(rmw_sources "src/network_flow_endpoint.c" "src/publisher_options.c" "src/qos_string_conversions.c" - "src/runtime_type.c" + "src/dynamic_typesupport.c" "src/sanity_checks.c" "src/security_options.c" "src/subscription_content_filter_options.c" @@ -57,7 +57,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC "$" "$") target_link_libraries(${PROJECT_NAME} - serialization_support_lib::serialization_support_lib + rosidl_dynamic_typesupport::rosidl_dynamic_typesupport ) if(BUILD_TESTING AND NOT RCUTILS_DISABLE_FAULT_INJECTION) @@ -81,7 +81,7 @@ ament_export_libraries(${PROJECT_NAME}) # Export modern CMake targets ament_export_targets(${PROJECT_NAME}) -ament_export_dependencies(serialization_support_lib) +ament_export_dependencies(rosidl_dynamic_typesupport) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) diff --git a/rmw/include/rmw/runtime_type.h b/rmw/include/rmw/dynamic_typesupport.h similarity index 53% rename from rmw/include/rmw/runtime_type.h rename to rmw/include/rmw/dynamic_typesupport.h index 99b19e60..171712b6 100644 --- a/rmw/include/rmw/runtime_type.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RMW__RUNTIME_TYPE_H_ -#define RMW__RUNTIME_TYPE_H_ +#ifndef RMW__DYNAMIC_TYPESUPPORT_H_ +#define RMW__DYNAMIC_TYPESUPPORT_H_ #ifdef __cplusplus extern "C" @@ -24,8 +24,8 @@ extern "C" #include "rmw/types.h" #include "rmw/visibility_control.h" -#include "serialization_support_lib/types.h" -#include "serialization_support_lib/api/serialization_support.h" +#include "rosidl_dynamic_typesupport/types.h" +#include "rosidl_dynamic_typesupport/api/serialization_support.h" #include "rosidl_runtime_c/message_type_support_struct.h" /// Interfaces for runtime interface reflection @@ -34,7 +34,7 @@ extern "C" /// String identifying the typesupport introspection implementation in use. // NOTE(methylDragon): I don't know if this is supposed to be in an identifier.h file RMW_PUBLIC -extern const char * rmw_typesupport_runtime_type_introspection_c__identifier; +extern const char * rmw_dynamic_typesupport_c__identifier; // This struct is meant to be populated fully if the rosidl_message_type_support_t is constructed @@ -42,21 +42,31 @@ extern const char * rmw_typesupport_runtime_type_introspection_c__identifier; // services). // // Otherwise, it is deferred MUST be populated on type discovery, if the middleware supports it -typedef struct runtime_type_ts_impl_s { +typedef struct rmw_dynamic_typesupport_impl_s { bool take_dynamic_data; // Take dynamic data at the middleware level // Get from middleware specific link-time function: // rmw_middleware_can_take_dynamic_data() const char * topic_name; // MAYBE??? type_description_t * desc; // Might be unused if dynamic_type is obtained directly - serialization_support_t * ser; - ser_dynamic_type_t * dynamic_type; - ser_dynamic_data_t * dynamic_data; -} runtime_type_ts_impl_t; + rosidl_dynamic_typesupport_serialization_support_t * serialization_support; + + // NOTE(methylDragon): I'm unsure if these are necessary. Though I think they are convenient. + // dynamic_type moreso than dynamic_data. + // + // I'd err on including them to be able to support more middlewares + // + // The dynamic_type allows us to do a one time alloc and reuse it for + // subscription creation and data creation + // The dynamic_data allows us to either reuse it, or clone it, but it's + // technically redundant because data can be created from dynamic_type + rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type; + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data; +} rmw_dynamic_typesupport_impl_t; // TODO(methylDragon): !!! Document that the user is in charge of the lifetime of the struct... // TODO(methylDragon): ... How do I do this? ^ -// NOTE(methylDragon): My use of the serialization_support_lib::type_description_t struct is for +// NOTE(methylDragon): My use of the rosidl_dynamic_typesupport::type_description_t struct is for // convenience only. We should be passing the TypeDescription message /// Get runtime type message typesupport with bound message description @@ -65,54 +75,65 @@ typedef struct runtime_type_ts_impl_s { RMW_PUBLIC RMW_WARN_UNUSED rosidl_message_type_support_t * -rmw_get_runtime_type_message_typesupport_handle( - serialization_support_t * ser_support, +rmw_get_dynamic_message_typesupport_handle( + rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, type_description_t * desc); /// Finalize a rosidl_message_type_support_t obtained with -/// rmw_get_runtime_type_message_typesupport_handle +/// rmw_get_dynamic_message_typesupport_handle RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_runtime_type_message_typesupport_handle_fini(rosidl_message_type_support_t * type_support); +rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * type_support); -/// Construct serialization support-specific ser_dynamic_type_t from a given type description +/// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given type description RMW_PUBLIC RMW_WARN_UNUSED -ser_dynamic_type_t * -rmw_get_dynamic_type_from_description(serialization_support_t * ser, type_description_t * desc); +rosidl_dynamic_typesupport_dynamic_type_t * +rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, type_description_t * desc); RMW_PUBLIC RMW_WARN_UNUSED -ser_dynamic_data_t * -rmw_get_dynamic_data_from_dynamic_type(serialization_support_t * ser, ser_dynamic_type_t * type); +rosidl_dynamic_typesupport_dynamic_data_t * +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_dynamic_typesupport_dynamic_type_t * type); + +RMW_PUBLIC +RMW_WARN_UNUSED +rosidl_dynamic_typesupport_dynamic_data_t * +rmw_clone_dynamic_data(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_dynamic_typesupport_dynamic_data_t * data); // INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_take_dynamic_data_message_with_info( +rmw_take_dynamic_message_with_info( const rmw_subscription_t * subscription, - ser_dynamic_data_t * dynamic_data, + // TODO(methylDragon): To replace with rmw_dynamic_message_t * + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, bool * taken, rmw_message_info_t * message_info, rmw_subscription_allocation_t * allocation); RMW_PUBLIC RMW_WARN_UNUSED -serialization_support_t * +rosidl_dynamic_typesupport_serialization_support_t * rmw_get_serialization_support(const char * serialization_lib_name); // NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's // dynamic type matches the layout of the buffer +/// The user must provide a rosidl_dynamic_typesupport_dynamic_data_t with dynamic data impl +/// that matches the serialization library used. It must also match the layout of the buffer if the +/// serialization library cannot infer the layout from the buffer alone. RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t +// TODO(methylDragon): Convert to rmw_serialized_message_to_dynamic_message +// Or maybe just an additional interface? rmw_serialized_to_dynamic_data( - rmw_serialized_message_t * serialized_message, ser_dynamic_data_t * dyn_data); + rmw_serialized_message_t * serialized_message, rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); // TODO(methylDragon): Nice to have only // RMW_PUBLIC @@ -122,7 +143,7 @@ rmw_serialized_to_dynamic_data( // const rmw_node_t * node, // const char * topic_name, // const rosidl_message_type_support_t type_support, -// ser_dynamic_type_t * dynamic_type); +// rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type); // // RMW_PUBLIC // RMW_WARN_UNUSED @@ -131,11 +152,11 @@ rmw_serialized_to_dynamic_data( // const rmw_node_t * node, // const char * topic_name, // const rosidl_message_type_support_t type_support, -// ser_dynamic_data_t * dynamic_data); +// rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); #ifdef __cplusplus } #endif -#endif // RMW__RUNTIME_TYPE_H_ +#endif // RMW__DYNAMIC_TYPESUPPORT_H_ diff --git a/rmw/include/rmw/features.h b/rmw/include/rmw/features.h index f454fc45..76d372ed 100644 --- a/rmw/include/rmw/features.h +++ b/rmw/include/rmw/features.h @@ -49,7 +49,7 @@ typedef enum RMW_PUBLIC_TYPE rmw_feature_e /// deferred description runtime type rosidl_message_type_support_t structs are allowed, and the /// middleware MUST populate them on type discovery RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY = 2, - /// runtime type subscriptions will use take_dynamic_data_message_with_info() + /// runtime type subscriptions will use take_dynamic_message_with_info() RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA = 3, } rmw_feature_t; diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index 03c861f5..2a21bb87 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -106,7 +106,7 @@ extern "C" #include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" -#include "rmw/runtime_type.h" // TODO(methylDragon): NEW!! +#include "rmw/dynamic_typesupport.h" // TODO(methylDragon): NEW!! #include "rmw/subscription_options.h" #include "rmw/types.h" #include "rmw/visibility_control.h" diff --git a/rmw/package.xml b/rmw/package.xml index 13ebe12a..a103e28a 100644 --- a/rmw/package.xml +++ b/rmw/package.xml @@ -16,12 +16,12 @@ ament_cmake_ros ament_cmake_version - serialization_support_lib + rosidl_dynamic_typesupport rcutils rosidl_runtime_c - serialization_support_lib + rosidl_dynamic_typesupport rcutils rosidl_runtime_c diff --git a/rmw/src/runtime_type.c b/rmw/src/dynamic_typesupport.c similarity index 51% rename from rmw/src/runtime_type.c rename to rmw/src/dynamic_typesupport.c index c0bf7299..74d57235 100644 --- a/rmw/src/runtime_type.c +++ b/rmw/src/dynamic_typesupport.c @@ -18,16 +18,16 @@ extern "C" #endif #include "rcutils/logging_macros.h" -#include "serialization_support_lib/description.h" +#include "rosidl_dynamic_typesupport/description.h" #include "rosidl_runtime_c/message_type_support_struct.h" -#include "rmw/runtime_type.h" +#include "rmw/dynamic_typesupport.h" -const char * rmw_typesupport_runtime_type_introspection_c__identifier = - "rmw_typesupport_runtime_type_introspection_c"; +const char * rmw_dynamic_typesupport_c__identifier = + "rmw_dynamic_typesupport_c"; -// NOTE(methylDragon): My use of the serialization_support_lib::type_description_t struct is for +// NOTE(methylDragon): My use of the rosidl_dynamic_typesupport::type_description_t struct is for // convenience only. We should be passing the TypeDescription message // NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just @@ -35,14 +35,14 @@ const char * rmw_typesupport_runtime_type_introspection_c__identifier = /// Create a rosidl_message_type_support_t from a TypeDescription message rosidl_message_type_support_t * -rmw_get_runtime_type_message_typesupport_handle( - serialization_support_t * ser_support, +rmw_get_dynamic_message_typesupport_handle( + rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, type_description_t * desc) { if (!middleware_supports_type_discovery && desc == NULL) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Middleware does not support type discovery! Deferred runtime type" "message type support will never be populated! You must provide a type " "description!"); @@ -53,53 +53,53 @@ rmw_get_runtime_type_message_typesupport_handle( rosidl_message_type_support_t * ts = (rosidl_message_type_support_t *)(calloc(1, sizeof(rosidl_message_type_support_t))); if(!ts) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not allocate rosidl_message_type_support_t struct"); return NULL; } - ts->typesupport_identifier = rmw_typesupport_runtime_type_introspection_c__identifier; + ts->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE - ts->data = calloc(1, sizeof(runtime_type_ts_impl_t)); + ts->data = calloc(1, sizeof(rmw_dynamic_typesupport_impl_t)); if(!ts) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, - "Could not allocate runtime_type_ts_impl_t struct"); - if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not allocate rmw_dynamic_typesupport_impl_t struct"); + if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not finalize runtime type typesupport"); } return NULL; } - runtime_type_ts_impl_t * ts_impl = (runtime_type_ts_impl_t *)ts->data; + rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; ts_impl->take_dynamic_data = middleware_can_take_dynamic_data; - ts_impl->ser = ser_support; + ts_impl->serialization_support = serialization_support; ts->func = get_message_typesupport_handle_function; // TODO(methylDragon): This is just temporary. We'd ideally pass in the TypeDescription msg // The type_description_t object doesn't support default values ts_impl->desc = desc; - ts_impl->dynamic_type = rmw_get_dynamic_type_from_description(ts_impl->ser, desc); + ts_impl->dynamic_type = rmw_init_dynamic_type_from_description(ts_impl->serialization_support, desc); if (!ts_impl->dynamic_type) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, - "Could not construct dynamic type for runtime_type_ts_impl_t struct"); - if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not construct dynamic type for rmw_dynamic_typesupport_impl_t struct"); + if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not finalize runtime type typesupport"); } return NULL; } ts_impl->dynamic_data = - rmw_get_dynamic_data_from_dynamic_type(ts_impl->ser, ts_impl->dynamic_type); + rmw_init_dynamic_data_from_dynamic_type(ts_impl->serialization_support, ts_impl->dynamic_type); if (!ts_impl->dynamic_data) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, - "Could not construct dynamic data for runtime_type_ts_impl_t struct"); - if (rmw_runtime_type_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_typesupport_runtime_type_introspection_c__identifier, + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not construct dynamic data for rmw_dynamic_typesupport_impl_t struct"); + if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not finalize runtime type typesupport"); } return NULL; @@ -109,30 +109,30 @@ rmw_get_runtime_type_message_typesupport_handle( } rmw_ret_t -rmw_runtime_type_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) +rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) { RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT); // NOTE(methylDragon): Ignores const... - if (ts->typesupport_identifier != rmw_typesupport_runtime_type_introspection_c__identifier) + if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { RCUTILS_SET_ERROR_MSG("type support not from this implementation"); return RMW_RET_INVALID_ARGUMENT; } if (ts->data) { - runtime_type_ts_impl_t * ts_impl = (runtime_type_ts_impl_t *)ts->data; + rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; if (ts_impl->desc) { type_description_fini(ts_impl->desc); } if (ts_impl->dynamic_type) { - ser_type_fini(ts_impl->ser, ts_impl->dynamic_type); + rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->serialization_support, ts_impl->dynamic_type); } if (ts_impl->dynamic_data) { - ser_data_fini(ts_impl->ser, ts_impl->dynamic_data); + rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->serialization_support, ts_impl->dynamic_data); } } free(ts); @@ -141,17 +141,24 @@ rmw_runtime_type_message_typesupport_handle_fini(rosidl_message_type_support_t * } -ser_dynamic_type_t * -rmw_get_dynamic_type_from_description(serialization_support_t * ser, type_description_t * desc) +rosidl_dynamic_typesupport_dynamic_type_t * +rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, type_description_t * desc) { - return ser_construct_type_from_description(ser, desc); + return rosidl_dynamic_typesupport_dynamic_type_init_from_description(serialization_support, desc); } -ser_dynamic_data_t * -rmw_get_dynamic_data_from_dynamic_type(serialization_support_t * ser, ser_dynamic_type_t * type) +rosidl_dynamic_typesupport_dynamic_data_t * +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_dynamic_typesupport_dynamic_type_t * type) { - return ser_data_init_from_type(ser, type); + return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(serialization_support, type); +} + + +rosidl_dynamic_typesupport_dynamic_data_t * +rmw_clone_dynamic_data(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_dynamic_typesupport_dynamic_data_t * data) +{ + return rosidl_dynamic_typesupport_dynamic_data_clone(serialization_support, data); } From 7036afca835cc3a09756b68989d9f237d98349f7 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 28 Feb 2023 13:38:54 -0800 Subject: [PATCH 03/18] Refactor dynamic typesupport to couple serialization support to objects Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_typesupport.h | 11 +++++++---- rmw/src/dynamic_typesupport.c | 14 +++++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_typesupport.h index 171712b6..cea73523 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -92,17 +92,19 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * type RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_type_t * -rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, type_description_t * desc); +rmw_init_dynamic_type_from_description( + rosidl_dynamic_typesupport_serialization_support_t * serialization_support, + type_description_t * desc); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_dynamic_typesupport_dynamic_type_t * type); +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * type); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_dynamic_typesupport_dynamic_data_t * data); +rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data); // INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== @@ -133,7 +135,8 @@ rmw_ret_t // TODO(methylDragon): Convert to rmw_serialized_message_to_dynamic_message // Or maybe just an additional interface? rmw_serialized_to_dynamic_data( - rmw_serialized_message_t * serialized_message, rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); + rmw_serialized_message_t * serialized_message, + rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); // TODO(methylDragon): Nice to have only // RMW_PUBLIC diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_typesupport.c index 74d57235..c8b26da9 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_typesupport.c @@ -94,7 +94,7 @@ rmw_get_dynamic_message_typesupport_handle( } ts_impl->dynamic_data = - rmw_init_dynamic_data_from_dynamic_type(ts_impl->serialization_support, ts_impl->dynamic_type); + rmw_init_dynamic_data_from_dynamic_type(ts_impl->dynamic_type); if (!ts_impl->dynamic_data) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not construct dynamic data for rmw_dynamic_typesupport_impl_t struct"); @@ -128,11 +128,11 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) } if (ts_impl->dynamic_type) { - rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->serialization_support, ts_impl->dynamic_type); + rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_type); } if (ts_impl->dynamic_data) { - rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->serialization_support, ts_impl->dynamic_data); + rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_data); } } free(ts); @@ -149,16 +149,16 @@ rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_ rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_dynamic_typesupport_dynamic_type_t * type) +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * type) { - return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(serialization_support, type); + return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type); } rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_dynamic_typesupport_dynamic_data_t * data) +rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data) { - return rosidl_dynamic_typesupport_dynamic_data_clone(serialization_support, data); + return rosidl_dynamic_typesupport_dynamic_data_clone(data); } From 04e62fe62412bf06ccee43692071cbad050219cd Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 15 Mar 2023 00:19:47 -0700 Subject: [PATCH 04/18] Implement dynamic data serialize and deserialize Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_typesupport.h | 32 +++++++++++++++------------ rmw/src/dynamic_typesupport.c | 29 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_typesupport.h index cea73523..35c87ea8 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -106,6 +106,24 @@ RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data); +// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's +// dynamic type matches the layout of the buffer +/// The user must provide a rosidl_dynamic_typesupport_dynamic_data_t with dynamic data impl +/// that matches the serialization library used to serialize the buffer. It must also match the +/// layout of the buffer if the serialization library cannot infer the layout from the buffer alone. +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_serialized_to_dynamic_data( + rmw_serialized_message_t * serialized_message, + rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); + +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_dynamic_data_to_serialized( + rmw_serialized_message_t * serialized_message, + rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); // INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== RMW_PUBLIC @@ -124,20 +142,6 @@ RMW_WARN_UNUSED rosidl_dynamic_typesupport_serialization_support_t * rmw_get_serialization_support(const char * serialization_lib_name); -// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's -// dynamic type matches the layout of the buffer -/// The user must provide a rosidl_dynamic_typesupport_dynamic_data_t with dynamic data impl -/// that matches the serialization library used. It must also match the layout of the buffer if the -/// serialization library cannot infer the layout from the buffer alone. -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -// TODO(methylDragon): Convert to rmw_serialized_message_to_dynamic_message -// Or maybe just an additional interface? -rmw_serialized_to_dynamic_data( - rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); - // TODO(methylDragon): Nice to have only // RMW_PUBLIC // RMW_WARN_UNUSED diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_typesupport.c index c8b26da9..04f9e235 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_typesupport.c @@ -162,6 +162,35 @@ rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data) } +rmw_ret_t +rmw_serialized_to_dynamic_data( + rmw_serialized_message_t * serialized_message, + rosidl_dynamic_typesupport_dynamic_data_t * dyn_data) +{ + if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dyn_data, serialized_message)) { + return RMW_RET_OK; + } else { + RMW_SET_ERROR_MSG("could not deserialize serialized message to dynamic data: " + "dynamic data not enough memory"); + return RMW_RET_ERROR; + } +} + + +rmw_ret_t +rmw_dynamic_data_to_serialized( + rosidl_dynamic_typesupport_dynamic_data_t * dyn_data, + rmw_serialized_message_t * serialized_message) +{ + if (rosidl_dynamic_typesupport_dynamic_data_serialize(dyn_data, serialized_message)) { + return RMW_RET_OK; + } else { + RMW_SET_ERROR_MSG("could not serialize dynamic data to serialized message!"); + return RMW_RET_ERROR; + } +} + + #ifdef __cplusplus } #endif From 7f9452ab1217df95132944265e6533826bd52c13 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 15 Mar 2023 01:34:26 -0700 Subject: [PATCH 05/18] Migrate to rosidl type description Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_typesupport.h | 57 ++++++++++------ rmw/include/rmw/features.h | 4 +- rmw/src/dynamic_typesupport.c | 96 +++++++++++++++------------ 3 files changed, 91 insertions(+), 66 deletions(-) diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_typesupport.h index 35c87ea8..6a864e2e 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -24,9 +24,10 @@ extern "C" #include "rmw/types.h" #include "rmw/visibility_control.h" -#include "rosidl_dynamic_typesupport/types.h" -#include "rosidl_dynamic_typesupport/api/serialization_support.h" -#include "rosidl_runtime_c/message_type_support_struct.h" +#include +#include +#include +#include /// Interfaces for runtime interface reflection @@ -41,14 +42,17 @@ extern const char * rmw_dynamic_typesupport_c__identifier; // with a given description on the client library end (since the descrpition is obtained via // services). // -// Otherwise, it is deferred MUST be populated on type discovery, if the middleware supports it +// Otherwise, it is deferred and MUST be populated on type discovery, if the middleware supports it +// +// Ownership: +// - The struct owns its `description` field. It is responsible for deallocating it. typedef struct rmw_dynamic_typesupport_impl_s { bool take_dynamic_data; // Take dynamic data at the middleware level // Get from middleware specific link-time function: // rmw_middleware_can_take_dynamic_data() const char * topic_name; // MAYBE??? - type_description_t * desc; // Might be unused if dynamic_type is obtained directly + rosidl_runtime_c__type_description__TypeDescription * description; // Might be unused if dynamic_type is obtained directly rosidl_dynamic_typesupport_serialization_support_t * serialization_support; // NOTE(methylDragon): I'm unsure if these are necessary. Though I think they are convenient. @@ -64,14 +68,27 @@ typedef struct rmw_dynamic_typesupport_impl_s { rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data; } rmw_dynamic_typesupport_impl_t; -// TODO(methylDragon): !!! Document that the user is in charge of the lifetime of the struct... -// TODO(methylDragon): ... How do I do this? ^ -// NOTE(methylDragon): My use of the rosidl_dynamic_typesupport::type_description_t struct is for -// convenience only. We should be passing the TypeDescription message - -/// Get runtime type message typesupport with bound message description -/// If the user passes a NULL desc, it is deferred instead, the middleware is responsibile for -/// populating the fields on type discovery!!! +/// Get dynamic type message typesupport with bound 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 rosidl_message_type_support_t * @@ -79,7 +96,7 @@ rmw_get_dynamic_message_typesupport_handle( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, - type_description_t * desc); + rosidl_runtime_c__type_description__TypeDescription * description); /// Finalize a rosidl_message_type_support_t obtained with /// rmw_get_dynamic_message_typesupport_handle @@ -94,17 +111,17 @@ RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_type_t * rmw_init_dynamic_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - type_description_t * desc); + rosidl_runtime_c__type_description__TypeDescription * description); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * type); +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data); +rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); // NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's // dynamic type matches the layout of the buffer @@ -116,14 +133,14 @@ RMW_WARN_UNUSED rmw_ret_t rmw_serialized_to_dynamic_data( rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t rmw_dynamic_data_to_serialized( - rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dyn_data); + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, + rmw_serialized_message_t * serialized_message); // INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== RMW_PUBLIC diff --git a/rmw/include/rmw/features.h b/rmw/include/rmw/features.h index 76d372ed..086bf328 100644 --- a/rmw/include/rmw/features.h +++ b/rmw/include/rmw/features.h @@ -46,10 +46,10 @@ typedef enum RMW_PUBLIC_TYPE rmw_feature_e /// `rmw_message_info_t.reception_sequence_number` is filled correctly /// by the rmw implementation. RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER = 1, - /// deferred description runtime type rosidl_message_type_support_t structs are allowed, and the + /// deferred description dynamic type rosidl_message_type_support_t structs are allowed, and the /// middleware MUST populate them on type discovery RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY = 2, - /// runtime type subscriptions will use take_dynamic_message_with_info() + /// dynamic type subscriptions will use take_dynamic_message_with_info() RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA = 3, } rmw_feature_t; diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_typesupport.c index 04f9e235..799d9c23 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_typesupport.c @@ -17,19 +17,17 @@ extern "C" { #endif -#include "rcutils/logging_macros.h" -#include "rosidl_dynamic_typesupport/description.h" -#include "rosidl_runtime_c/message_type_support_struct.h" - #include "rmw/dynamic_typesupport.h" +#include +#include +#include +#include + const char * rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; -// NOTE(methylDragon): My use of the rosidl_dynamic_typesupport::type_description_t struct is for -// convenience only. We should be passing the TypeDescription message - // NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just // use the FastRTPS support then? @@ -39,11 +37,11 @@ rmw_get_dynamic_message_typesupport_handle( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, - type_description_t * desc) + rosidl_runtime_c__type_description__TypeDescription * description) { - if (!middleware_supports_type_discovery && desc == NULL) { + if (!middleware_supports_type_discovery && description == NULL) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Middleware does not support type discovery! Deferred runtime type" + "Middleware does not support type discovery! Deferred dynamic type" "message type support will never be populated! You must provide a type " "description!"); return NULL; @@ -65,11 +63,7 @@ rmw_get_dynamic_message_typesupport_handle( if(!ts) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not allocate rmw_dynamic_typesupport_impl_t struct"); - if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not finalize runtime type typesupport"); - } - return NULL; + goto fail; } rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; @@ -78,19 +72,28 @@ rmw_get_dynamic_message_typesupport_handle( ts_impl->serialization_support = serialization_support; ts->func = get_message_typesupport_handle_function; - // TODO(methylDragon): This is just temporary. We'd ideally pass in the TypeDescription msg - // The type_description_t object doesn't support default values - ts_impl->desc = desc; + if (description) { + ts_impl->description = rosidl_runtime_c__type_description__TypeDescription__create(); + if (ts_impl->description == NULL) { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not create type description to assign into"); + goto fail; + } + + if (!rosidl_runtime_c__type_description__TypeDescription__copy( + description, ts_impl->description)) + { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not copy type description"); + goto fail; + } + } - ts_impl->dynamic_type = rmw_init_dynamic_type_from_description(ts_impl->serialization_support, desc); + ts_impl->dynamic_type = rmw_init_dynamic_type_from_description(ts_impl->serialization_support, description); if (!ts_impl->dynamic_type) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not construct dynamic type for rmw_dynamic_typesupport_impl_t struct"); - if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not finalize runtime type typesupport"); - } - return NULL; + goto fail; } ts_impl->dynamic_data = @@ -98,14 +101,17 @@ rmw_get_dynamic_message_typesupport_handle( if (!ts_impl->dynamic_data) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not construct dynamic data for rmw_dynamic_typesupport_impl_t struct"); - if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not finalize runtime type typesupport"); - } - return NULL; + goto fail; } return ts; + +fail: + if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "Could not finalize dynamic type typesupport"); + } + return NULL; } rmw_ret_t @@ -123,8 +129,8 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) if (ts->data) { rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; - if (ts_impl->desc) { - type_description_fini(ts_impl->desc); + if (ts_impl->description) { + rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->description); } if (ts_impl->dynamic_type) { @@ -142,36 +148,37 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) rosidl_dynamic_typesupport_dynamic_type_t * -rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, type_description_t * desc) +rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_runtime_c__type_description__TypeDescription * description) { - return rosidl_dynamic_typesupport_dynamic_type_init_from_description(serialization_support, desc); + return rosidl_dynamic_typesupport_dynamic_type_init_from_description(serialization_support, description); } rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * type) +rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type) { - return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type); + return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(dynamic_type); } rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * data) +rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data) { - return rosidl_dynamic_typesupport_dynamic_data_clone(data); + return rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_data); } rmw_ret_t rmw_serialized_to_dynamic_data( rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dyn_data) + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data) { - if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dyn_data, serialized_message)) { + if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dynamic_data, serialized_message)) { return RMW_RET_OK; } else { - RMW_SET_ERROR_MSG("could not deserialize serialized message to dynamic data: " - "dynamic data not enough memory"); + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "could not deserialize serialized message to dynamic data: " + "dynamic data not enough memory"); return RMW_RET_ERROR; } } @@ -179,13 +186,14 @@ rmw_serialized_to_dynamic_data( rmw_ret_t rmw_dynamic_data_to_serialized( - rosidl_dynamic_typesupport_dynamic_data_t * dyn_data, + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, rmw_serialized_message_t * serialized_message) { - if (rosidl_dynamic_typesupport_dynamic_data_serialize(dyn_data, serialized_message)) { + if (rosidl_dynamic_typesupport_dynamic_data_serialize(dynamic_data, serialized_message)) { return RMW_RET_OK; } else { - RMW_SET_ERROR_MSG("could not serialize dynamic data to serialized message!"); + RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, + "could not serialize dynamic data to serialized message!"); return RMW_RET_ERROR; } } From 695f1fc18940dc6791e63b73a64a9f83765f36db Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 16 Mar 2023 18:16:13 -0700 Subject: [PATCH 06/18] Fix const Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_typesupport.h | 11 +++++++++-- rmw/src/dynamic_typesupport.c | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_typesupport.h index 6a864e2e..21555e45 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -46,6 +46,13 @@ extern const char * rmw_dynamic_typesupport_c__identifier; // // Ownership: // - The struct owns its `description` field. It is responsible for deallocating it. +// - The struct owns its `serialization_support` field. It is responsible for deallocating it. +// - The struct owns its `dynamic_type` field. It is responsible for deallocating it. +// - The struct owns its `dynamic_data` field. It is responsible for deallocating it. +// +// Downstream classes are expected to borrow the `serialization_support` field, and potentially the +// `dynamic_type` and `dynamic_data` fields. As such, it is important that this struct outlives +// those downstream classes. typedef struct rmw_dynamic_typesupport_impl_s { bool take_dynamic_data; // Take dynamic data at the middleware level // Get from middleware specific link-time function: @@ -96,7 +103,7 @@ rmw_get_dynamic_message_typesupport_handle( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, - rosidl_runtime_c__type_description__TypeDescription * description); + const rosidl_runtime_c__type_description__TypeDescription * description); /// Finalize a rosidl_message_type_support_t obtained with /// rmw_get_dynamic_message_typesupport_handle @@ -111,7 +118,7 @@ RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_type_t * rmw_init_dynamic_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - rosidl_runtime_c__type_description__TypeDescription * description); + const rosidl_runtime_c__type_description__TypeDescription * description); RMW_PUBLIC RMW_WARN_UNUSED diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_typesupport.c index 799d9c23..dc35d333 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_typesupport.c @@ -37,7 +37,7 @@ rmw_get_dynamic_message_typesupport_handle( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, bool middleware_can_take_dynamic_data, - rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription * description) { if (!middleware_supports_type_discovery && description == NULL) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, @@ -148,7 +148,7 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) rosidl_dynamic_typesupport_dynamic_type_t * -rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, rosidl_runtime_c__type_description__TypeDescription * description) +rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_runtime_c__type_description__TypeDescription * description) { return rosidl_dynamic_typesupport_dynamic_type_init_from_description(serialization_support, description); } From 3514c49dbf37d2d86cf28dd7cfb3842f82a300c7 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 28 Mar 2023 10:49:48 -0700 Subject: [PATCH 07/18] Use allocators for memory management Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_typesupport.h | 2 -- rmw/src/dynamic_typesupport.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_typesupport.h index 21555e45..a1cc453c 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_typesupport.h @@ -37,7 +37,6 @@ extern "C" RMW_PUBLIC extern const char * rmw_dynamic_typesupport_c__identifier; - // This struct is meant to be populated fully if the rosidl_message_type_support_t is constructed // with a given description on the client library end (since the descrpition is obtained via // services). @@ -58,7 +57,6 @@ typedef struct rmw_dynamic_typesupport_impl_s { // Get from middleware specific link-time function: // rmw_middleware_can_take_dynamic_data() - const char * topic_name; // MAYBE??? rosidl_runtime_c__type_description__TypeDescription * description; // Might be unused if dynamic_type is obtained directly rosidl_dynamic_typesupport_serialization_support_t * serialization_support; diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_typesupport.c index dc35d333..84bcd458 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_typesupport.c @@ -19,6 +19,7 @@ extern "C" #include "rmw/dynamic_typesupport.h" +#include #include #include #include @@ -48,8 +49,9 @@ rmw_get_dynamic_message_typesupport_handle( } // TODO(methylDragon): Do I need to use an allocator...? - rosidl_message_type_support_t * ts = - (rosidl_message_type_support_t *)(calloc(1, sizeof(rosidl_message_type_support_t))); + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + rosidl_message_type_support_t * ts = allocator.zero_allocate( + 1, sizeof(rosidl_message_type_support_t), allocator.state); if(!ts) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not allocate rosidl_message_type_support_t struct"); @@ -59,7 +61,7 @@ rmw_get_dynamic_message_typesupport_handle( ts->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE - ts->data = calloc(1, sizeof(rmw_dynamic_typesupport_impl_t)); + ts->data = allocator.zero_allocate(1, sizeof(rmw_dynamic_typesupport_impl_t), allocator.state); if(!ts) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, "Could not allocate rmw_dynamic_typesupport_impl_t struct"); @@ -128,21 +130,19 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) if (ts->data) { rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; - if (ts_impl->description) { rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->description); } - if (ts_impl->dynamic_type) { rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_type); } - if (ts_impl->dynamic_data) { rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_data); } } - free(ts); - + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + allocator.deallocate((void *)ts->data, allocator.state); + allocator.deallocate(ts, allocator.state); return RMW_RET_OK; } From 4e4a7a3f89ad05ca8abc88226e5f7df1410c925c Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 28 Mar 2023 21:23:50 -0700 Subject: [PATCH 08/18] Call ts dynamic_message_typesupport and make description mandatory Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 2 +- ...upport.h => dynamic_message_typesupport.h} | 86 ++++++++++--------- rmw/include/rmw/features.h | 2 +- rmw/include/rmw/rmw.h | 2 +- ...upport.c => dynamic_message_typesupport.c} | 85 ++++++++++-------- 5 files changed, 99 insertions(+), 78 deletions(-) rename rmw/include/rmw/{dynamic_typesupport.h => dynamic_message_typesupport.h} (68%) rename rmw/src/{dynamic_typesupport.c => dynamic_message_typesupport.c} (68%) diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index c54cf6e5..d9064b47 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -38,7 +38,7 @@ set(rmw_sources "src/network_flow_endpoint.c" "src/publisher_options.c" "src/qos_string_conversions.c" - "src/dynamic_typesupport.c" + "src/dynamic_message_typesupport.c" "src/sanity_checks.c" "src/security_options.c" "src/subscription_content_filter_options.c" diff --git a/rmw/include/rmw/dynamic_typesupport.h b/rmw/include/rmw/dynamic_message_typesupport.h similarity index 68% rename from rmw/include/rmw/dynamic_typesupport.h rename to rmw/include/rmw/dynamic_message_typesupport.h index a1cc453c..a8ca6742 100644 --- a/rmw/include/rmw/dynamic_typesupport.h +++ b/rmw/include/rmw/dynamic_message_typesupport.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RMW__DYNAMIC_TYPESUPPORT_H_ -#define RMW__DYNAMIC_TYPESUPPORT_H_ +#ifndef RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ +#define RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ #ifdef __cplusplus extern "C" @@ -21,7 +21,7 @@ extern "C" #endif #include "rmw/features.h" -#include "rmw/types.h" +#include "rmw/serialized_message.h" #include "rmw/visibility_control.h" #include @@ -29,6 +29,7 @@ extern "C" #include #include + /// Interfaces for runtime interface reflection // RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= @@ -37,41 +38,36 @@ extern "C" RMW_PUBLIC extern const char * rmw_dynamic_typesupport_c__identifier; -// This struct is meant to be populated fully if the rosidl_message_type_support_t is constructed -// with a given description on the client library end (since the descrpition is obtained via -// services). +// Every field of this struct is expected to be populated. // -// Otherwise, it is deferred and MUST be populated on type discovery, if the middleware supports it +// NOTE(methylDragon): There is an opportunity to defer the population of the members by waiting +// for discovery, but this path is currently not supported. // // Ownership: // - The struct owns its `description` field. It is responsible for deallocating it. // - The struct owns its `serialization_support` field. It is responsible for deallocating it. -// - The struct owns its `dynamic_type` field. It is responsible for deallocating it. -// - The struct owns its `dynamic_data` field. It is responsible for deallocating it. +// - The struct owns its `dynamic_message_type` field. It is responsible for deallocating it. +// - The struct owns its `dynamic_message` field. It is responsible for deallocating it. // // Downstream classes are expected to borrow the `serialization_support` field, and potentially the -// `dynamic_type` and `dynamic_data` fields. As such, it is important that this struct outlives -// those downstream classes. -typedef struct rmw_dynamic_typesupport_impl_s { - bool take_dynamic_data; // Take dynamic data at the middleware level - // Get from middleware specific link-time function: - // rmw_middleware_can_take_dynamic_data() - - rosidl_runtime_c__type_description__TypeDescription * description; // Might be unused if dynamic_type is obtained directly +// `dynamic_message_type` and `dynamic_message` fields. As such, it is important that this struct +// outlives those downstream classes. +typedef struct rmw_dynamic_message_typesupport_impl_s { + rosidl_runtime_c__type_description__TypeDescription * description; rosidl_dynamic_typesupport_serialization_support_t * serialization_support; // NOTE(methylDragon): I'm unsure if these are necessary. Though I think they are convenient. - // dynamic_type moreso than dynamic_data. + // dynamic_message_type moreso than dynamic_message. // // I'd err on including them to be able to support more middlewares // - // The dynamic_type allows us to do a one time alloc and reuse it for + // The dynamic_message_type allows us to do a one time alloc and reuse it for // subscription creation and data creation - // The dynamic_data allows us to either reuse it, or clone it, but it's - // technically redundant because data can be created from dynamic_type - rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type; - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data; -} rmw_dynamic_typesupport_impl_t; + // The dynamic_message allows us to either reuse it, or clone it, but it's + // technically redundant because data can be created from dynamic_message_type + rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type; + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message; +} rmw_dynamic_message_typesupport_impl_t; /// Get dynamic type message typesupport with bound message description /** @@ -97,14 +93,16 @@ typedef struct rmw_dynamic_typesupport_impl_s { RMW_PUBLIC RMW_WARN_UNUSED rosidl_message_type_support_t * -rmw_get_dynamic_message_typesupport_handle( +rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - bool middleware_can_take_dynamic_data, const rosidl_runtime_c__type_description__TypeDescription * description); /// Finalize a rosidl_message_type_support_t obtained with -/// rmw_get_dynamic_message_typesupport_handle +/// rmw_dynamic_message_typesupport_handle_init, 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 @@ -114,21 +112,21 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * type RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_type_t * -rmw_init_dynamic_type_from_description( +rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_runtime_c__type_description__TypeDescription * description); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type); +rmw_init_dynamic_message_from_dynamic_message_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type); RMW_PUBLIC RMW_WARN_UNUSED rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); +rmw_clone_dynamic_message(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); -// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic data's +// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic message's // dynamic type matches the layout of the buffer /// The user must provide a rosidl_dynamic_typesupport_dynamic_data_t with dynamic data impl /// that matches the serialization library used to serialize the buffer. It must also match the @@ -136,25 +134,33 @@ rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_serialized_to_dynamic_data( +rmw_serialized_to_dynamic_message( rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_dynamic_data_to_serialized( - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, +rmw_dynamic_message_to_serialized( + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, rmw_serialized_message_t * serialized_message); // INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_take_dynamic_message( + const rmw_subscription_t * subscription, + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, + bool * taken, + rmw_subscription_allocation_t * allocation); + RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t rmw_take_dynamic_message_with_info( const rmw_subscription_t * subscription, - // TODO(methylDragon): To replace with rmw_dynamic_message_t * - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, bool * taken, rmw_message_info_t * message_info, rmw_subscription_allocation_t * allocation); @@ -172,7 +178,7 @@ rmw_get_serialization_support(const char * serialization_lib_name); // const rmw_node_t * node, // const char * topic_name, // const rosidl_message_type_support_t type_support, -// rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type); +// rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type); // // RMW_PUBLIC // RMW_WARN_UNUSED @@ -181,11 +187,11 @@ rmw_get_serialization_support(const char * serialization_lib_name); // const rmw_node_t * node, // const char * topic_name, // const rosidl_message_type_support_t type_support, -// rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data); +// rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); #ifdef __cplusplus } #endif -#endif // RMW__DYNAMIC_TYPESUPPORT_H_ +#endif // RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ diff --git a/rmw/include/rmw/features.h b/rmw/include/rmw/features.h index 086bf328..18ef2fb6 100644 --- a/rmw/include/rmw/features.h +++ b/rmw/include/rmw/features.h @@ -50,7 +50,7 @@ typedef enum RMW_PUBLIC_TYPE rmw_feature_e /// middleware MUST populate them on type discovery RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY = 2, /// dynamic type subscriptions will use take_dynamic_message_with_info() - RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA = 3, + RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE = 3, } rmw_feature_t; /// Query if a feature is supported by the rmw implementation. diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index 2a21bb87..760bb888 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -106,7 +106,7 @@ extern "C" #include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" -#include "rmw/dynamic_typesupport.h" // TODO(methylDragon): NEW!! +#include "rmw/dynamic_message_typesupport.h" // TODO(methylDragon): NEW!! #include "rmw/subscription_options.h" #include "rmw/types.h" #include "rmw/visibility_control.h" diff --git a/rmw/src/dynamic_typesupport.c b/rmw/src/dynamic_message_typesupport.c similarity index 68% rename from rmw/src/dynamic_typesupport.c rename to rmw/src/dynamic_message_typesupport.c index 84bcd458..ba0c31c5 100644 --- a/rmw/src/dynamic_typesupport.c +++ b/rmw/src/dynamic_message_typesupport.c @@ -17,7 +17,7 @@ extern "C" { #endif -#include "rmw/dynamic_typesupport.h" +#include "rmw/dynamic_message_typesupport.h" #include #include @@ -26,18 +26,16 @@ extern "C" #include -const char * rmw_dynamic_typesupport_c__identifier = - "rmw_dynamic_typesupport_c"; +const char * rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; // NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just // use the FastRTPS support then? /// Create a rosidl_message_type_support_t from a TypeDescription message rosidl_message_type_support_t * -rmw_get_dynamic_message_typesupport_handle( +rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - bool middleware_can_take_dynamic_data, const rosidl_runtime_c__type_description__TypeDescription * description) { if (!middleware_supports_type_discovery && description == NULL) { @@ -47,8 +45,20 @@ rmw_get_dynamic_message_typesupport_handle( "description!"); return NULL; } + if (description == NULL) { // TODO: Remove if and when the deferred description path is supported + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Deferred type description is not currently supported. You must provide a type description."); + return NULL; + } + + if (serialization_support == NULL) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "serialization_support cannot be nullptr."); + return NULL; + } - // TODO(methylDragon): Do I need to use an allocator...? rcutils_allocator_t allocator = rcutils_get_default_allocator(); rosidl_message_type_support_t * ts = allocator.zero_allocate( 1, sizeof(rosidl_message_type_support_t), allocator.state); @@ -60,17 +70,17 @@ rmw_get_dynamic_message_typesupport_handle( ts->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; - // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE - ts->data = allocator.zero_allocate(1, sizeof(rmw_dynamic_typesupport_impl_t), allocator.state); + ts->data = + allocator.zero_allocate(1, sizeof(rmw_dynamic_message_typesupport_impl_t), allocator.state); if(!ts) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not allocate rmw_dynamic_typesupport_impl_t struct"); + "Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); goto fail; } - rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; + rmw_dynamic_message_typesupport_impl_t * ts_impl = + (rmw_dynamic_message_typesupport_impl_t *)ts->data; - ts_impl->take_dynamic_data = middleware_can_take_dynamic_data; ts_impl->serialization_support = serialization_support; ts->func = get_message_typesupport_handle_function; @@ -91,18 +101,18 @@ rmw_get_dynamic_message_typesupport_handle( } } - ts_impl->dynamic_type = rmw_init_dynamic_type_from_description(ts_impl->serialization_support, description); - if (!ts_impl->dynamic_type) { + ts_impl->dynamic_message_type = rmw_init_dynamic_message_type_from_description(ts_impl->serialization_support, description); + if (!ts_impl->dynamic_message_type) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not construct dynamic type for rmw_dynamic_typesupport_impl_t struct"); + "Could not construct dynamic type for rmw_dynamic_message_typesupport_impl_t struct"); goto fail; } - ts_impl->dynamic_data = - rmw_init_dynamic_data_from_dynamic_type(ts_impl->dynamic_type); - if (!ts_impl->dynamic_data) { + ts_impl->dynamic_message = + rmw_init_dynamic_message_from_dynamic_message_type(ts_impl->dynamic_message_type); + if (!ts_impl->dynamic_message) { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not construct dynamic data for rmw_dynamic_typesupport_impl_t struct"); + "Could not construct dynamic data for rmw_dynamic_message_typesupport_impl_t struct"); goto fail; } @@ -129,51 +139,56 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) } if (ts->data) { - rmw_dynamic_typesupport_impl_t * ts_impl = (rmw_dynamic_typesupport_impl_t *)ts->data; + rmw_dynamic_message_typesupport_impl_t * ts_impl = + (rmw_dynamic_message_typesupport_impl_t *)ts->data; if (ts_impl->description) { rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->description); } - if (ts_impl->dynamic_type) { - rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_type); + if (ts_impl->dynamic_message_type) { + rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_message_type); } - if (ts_impl->dynamic_data) { - rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_data); + if (ts_impl->dynamic_message) { + rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_message); } } rcutils_allocator_t allocator = rcutils_get_default_allocator(); allocator.deallocate((void *)ts->data, allocator.state); + allocator.deallocate((void *)ts->type_hash, allocator.state); allocator.deallocate(ts, allocator.state); return RMW_RET_OK; } rosidl_dynamic_typesupport_dynamic_type_t * -rmw_init_dynamic_type_from_description(rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_runtime_c__type_description__TypeDescription * description) +rmw_init_dynamic_message_type_from_description( + rosidl_dynamic_typesupport_serialization_support_t * serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description) { - return rosidl_dynamic_typesupport_dynamic_type_init_from_description(serialization_support, description); + return rosidl_dynamic_typesupport_dynamic_type_init_from_description( + serialization_support, description); } rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_data_from_dynamic_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_type) +rmw_init_dynamic_message_from_dynamic_message_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type) { - return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(dynamic_type); + return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(dynamic_message_type); } rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_data(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data) +rmw_clone_dynamic_message(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message) { - return rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_data); + return rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_message); } rmw_ret_t -rmw_serialized_to_dynamic_data( +rmw_serialized_to_dynamic_message( rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data) + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message) { - if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dynamic_data, serialized_message)) { + if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dynamic_message, serialized_message)) { return RMW_RET_OK; } else { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, @@ -185,11 +200,11 @@ rmw_serialized_to_dynamic_data( rmw_ret_t -rmw_dynamic_data_to_serialized( - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_data, +rmw_dynamic_message_to_serialized( + rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, rmw_serialized_message_t * serialized_message) { - if (rosidl_dynamic_typesupport_dynamic_data_serialize(dynamic_data, serialized_message)) { + if (rosidl_dynamic_typesupport_dynamic_data_serialize(dynamic_message, serialized_message)) { return RMW_RET_OK; } else { RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, From 0e278b833330552e87116adef38cdfd08f65e72b Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 03:47:46 -0700 Subject: [PATCH 09/18] Migrate methods to use return types Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_message_typesupport.h | 28 ++-- rmw/src/dynamic_message_typesupport.c | 154 ++++++++++-------- 2 files changed, 102 insertions(+), 80 deletions(-) diff --git a/rmw/include/rmw/dynamic_message_typesupport.h b/rmw/include/rmw/dynamic_message_typesupport.h index a8ca6742..063bae8d 100644 --- a/rmw/include/rmw/dynamic_message_typesupport.h +++ b/rmw/include/rmw/dynamic_message_typesupport.h @@ -92,11 +92,12 @@ typedef struct rmw_dynamic_message_typesupport_impl_s { */ RMW_PUBLIC RMW_WARN_UNUSED -rosidl_message_type_support_t * +rmw_ret_t rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - const rosidl_runtime_c__type_description__TypeDescription * description); + const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_message_type_support_t ** ts); // OUT /// Finalize a rosidl_message_type_support_t obtained with /// rmw_dynamic_message_typesupport_handle_init, which has dynamically allocated members @@ -111,20 +112,25 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * type /// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given type description RMW_PUBLIC RMW_WARN_UNUSED -rosidl_dynamic_typesupport_dynamic_type_t * +rmw_ret_t rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description); + const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_dynamic_typesupport_dynamic_type_t ** ts); // OUT RMW_PUBLIC RMW_WARN_UNUSED -rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_message_from_dynamic_message_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type); +rmw_ret_t +rmw_init_dynamic_message_from_dynamic_message_type( + rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, + rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type); // OUT RMW_PUBLIC RMW_WARN_UNUSED -rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_message(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); +rmw_ret_t +rmw_clone_dynamic_message( + const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, + rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message); // OUT // NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic message's // dynamic type matches the layout of the buffer @@ -167,8 +173,10 @@ rmw_take_dynamic_message_with_info( RMW_PUBLIC RMW_WARN_UNUSED -rosidl_dynamic_typesupport_serialization_support_t * -rmw_get_serialization_support(const char * serialization_lib_name); +rmw_ret_t +rmw_get_serialization_support( + const char * serialization_lib_name, + rosidl_dynamic_typesupport_serialization_support_t ** serialization_support); // OUT // TODO(methylDragon): Nice to have only // RMW_PUBLIC diff --git a/rmw/src/dynamic_message_typesupport.c b/rmw/src/dynamic_message_typesupport.c index ba0c31c5..229c6c05 100644 --- a/rmw/src/dynamic_message_typesupport.c +++ b/rmw/src/dynamic_message_typesupport.c @@ -17,7 +17,9 @@ extern "C" { #endif +#include "rmw/convert_rcutils_ret_to_rmw_ret.h" #include "rmw/dynamic_message_typesupport.h" +#include "rmw/error_handling.h" #include #include @@ -32,98 +34,93 @@ const char * rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c" // use the FastRTPS support then? /// Create a rosidl_message_type_support_t from a TypeDescription message -rosidl_message_type_support_t * +rmw_ret_t rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - const rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_message_type_support_t ** ts) { if (!middleware_supports_type_discovery && description == NULL) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Middleware does not support type discovery! Deferred dynamic type" - "message type support will never be populated! You must provide a type " - "description!"); - return 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; } if (description == NULL) { // TODO: Remove if and when the deferred description path is supported - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, + RMW_SET_ERROR_MSG( "Deferred type description is not currently supported. You must provide a type description."); - return NULL; - } - - if (serialization_support == NULL) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "serialization_support cannot be nullptr."); - return NULL; + return RMW_RET_INVALID_ARGUMENT; } + RMW_CHECK_ARGUMENT_FOR_NULL(serialization_support, RMW_RET_INVALID_ARGUMENT); + rmw_ret_t ret = RMW_RET_ERROR; rcutils_allocator_t allocator = rcutils_get_default_allocator(); - rosidl_message_type_support_t * ts = allocator.zero_allocate( - 1, sizeof(rosidl_message_type_support_t), allocator.state); - if(!ts) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not allocate rosidl_message_type_support_t struct"); - return NULL; + *ts = allocator.zero_allocate(1, sizeof(rosidl_message_type_support_t), allocator.state); + if (!*ts) { + RMW_SET_ERROR_MSG("Could not allocate rosidl_message_type_support_t struct"); + return RMW_RET_BAD_ALLOC; } - ts->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; + (*ts)->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; - ts->data = - allocator.zero_allocate(1, sizeof(rmw_dynamic_message_typesupport_impl_t), allocator.state); - if(!ts) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); + (*ts)->data = allocator.zero_allocate( + 1, sizeof(rmw_dynamic_message_typesupport_impl_t), allocator.state); + if (!ts) { + RMW_SET_ERROR_MSG("Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); + ret = RMW_RET_BAD_ALLOC; goto fail; } rmw_dynamic_message_typesupport_impl_t * ts_impl = - (rmw_dynamic_message_typesupport_impl_t *)ts->data; + (rmw_dynamic_message_typesupport_impl_t *) (*ts)->data; ts_impl->serialization_support = serialization_support; - ts->func = get_message_typesupport_handle_function; + (*ts)->func = get_message_typesupport_handle_function; if (description) { ts_impl->description = rosidl_runtime_c__type_description__TypeDescription__create(); if (ts_impl->description == NULL) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not create type description to assign into"); + RMW_SET_ERROR_MSG("Could not create type description to assign into"); + ret = RMW_RET_BAD_ALLOC; goto fail; } if (!rosidl_runtime_c__type_description__TypeDescription__copy( description, ts_impl->description)) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not copy type description"); + RMW_SET_ERROR_MSG("Could not copy type description"); + ret = RMW_RET_ERROR; goto fail; } } - ts_impl->dynamic_message_type = rmw_init_dynamic_message_type_from_description(ts_impl->serialization_support, description); - if (!ts_impl->dynamic_message_type) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not construct dynamic type for rmw_dynamic_message_typesupport_impl_t struct"); + ret = rmw_convert_rcutils_ret_to_rmw_ret( + rmw_init_dynamic_message_type_from_description( + ts_impl->serialization_support, description, &ts_impl->dynamic_message_type)); + if (ret != RMW_RET_OK || !ts_impl->dynamic_message_type) { + RMW_SET_ERROR_MSG( + "Could not construct dynamic type for rmw_dynamic_message_typesupport_impl_t struct"); goto fail; } - ts_impl->dynamic_message = - rmw_init_dynamic_message_from_dynamic_message_type(ts_impl->dynamic_message_type); - if (!ts_impl->dynamic_message) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not construct dynamic data for rmw_dynamic_message_typesupport_impl_t struct"); + ret = rmw_init_dynamic_message_from_dynamic_message_type( + ts_impl->dynamic_message_type, &ts_impl->dynamic_message); + if (ret != RMW_RET_OK || !ts_impl->dynamic_message) { + RMW_SET_ERROR_MSG( + "Could not construct dynamic data for rmw_dynamic_message_typesupport_impl_t struct"); goto fail; } - return ts; + return RMW_RET_OK; fail: - if (rmw_dynamic_message_typesupport_handle_fini(ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "Could not finalize dynamic type typesupport"); + if (rmw_dynamic_message_typesupport_handle_fini(*ts) != RMW_RET_OK) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not finalize dynamic type typesupport"); } - return NULL; + return ret; } rmw_ret_t @@ -132,8 +129,7 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT); // NOTE(methylDragon): Ignores const... - if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) - { + if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { RCUTILS_SET_ERROR_MSG("type support not from this implementation"); return RMW_RET_INVALID_ARGUMENT; } @@ -159,27 +155,36 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) } -rosidl_dynamic_typesupport_dynamic_type_t * +rmw_ret_t rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_dynamic_typesupport_dynamic_type_t ** ts) { - return rosidl_dynamic_typesupport_dynamic_type_init_from_description( - serialization_support, description); + return rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_typesupport_dynamic_type_init_from_description( + serialization_support, description, ts)); } -rosidl_dynamic_typesupport_dynamic_data_t * -rmw_init_dynamic_message_from_dynamic_message_type(rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type) +rmw_ret_t +rmw_init_dynamic_message_from_dynamic_message_type( + rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, + rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type) { - return rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(dynamic_message_type); + return rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + dynamic_message_type, cloned_dynamic_message_type)); } -rosidl_dynamic_typesupport_dynamic_data_t * -rmw_clone_dynamic_message(const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message) +rmw_ret_t +rmw_clone_dynamic_message( + const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, + rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message) { - return rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_message); + return rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_message, cloned_dynamic_message)); } @@ -188,13 +193,18 @@ rmw_serialized_to_dynamic_message( rmw_serialized_message_t * serialized_message, rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message) { - if (rosidl_dynamic_typesupport_dynamic_data_deserialize(dynamic_message, serialized_message)) { + bool success; + rmw_ret_t ret = rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_typesupport_dynamic_data_deserialize( + dynamic_message, serialized_message, &success)); + + if (success) { return RMW_RET_OK; } else { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "could not deserialize serialized message to dynamic data: " - "dynamic data not enough memory"); - return RMW_RET_ERROR; + RMW_SET_ERROR_MSG( + "could not deserialize serialized message to dynamic data: " + "dynamic data not enough memory"); + return ret; } } @@ -204,12 +214,16 @@ rmw_dynamic_message_to_serialized( rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, rmw_serialized_message_t * serialized_message) { - if (rosidl_dynamic_typesupport_dynamic_data_serialize(dynamic_message, serialized_message)) { + bool success; + rmw_ret_t ret = rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_typesupport_dynamic_data_serialize( + dynamic_message, serialized_message, &success)); + + if (success) { return RMW_RET_OK; } else { - RCUTILS_LOG_ERROR_NAMED(rmw_dynamic_typesupport_c__identifier, - "could not serialize dynamic data to serialized message!"); - return RMW_RET_ERROR; + RMW_SET_ERROR_MSG("could not serialize dynamic data to serialized message!"); + return ret; } } From 713abbf2881b9b54d888761e62347d4b653600d8 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 05:31:39 -0700 Subject: [PATCH 10/18] Lint Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_message_typesupport.h | 14 ++++++++------ rmw/src/dynamic_message_typesupport.c | 11 ++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rmw/include/rmw/dynamic_message_typesupport.h b/rmw/include/rmw/dynamic_message_typesupport.h index 063bae8d..5bc62297 100644 --- a/rmw/include/rmw/dynamic_message_typesupport.h +++ b/rmw/include/rmw/dynamic_message_typesupport.h @@ -20,15 +20,15 @@ extern "C" { #endif -#include "rmw/features.h" -#include "rmw/serialized_message.h" -#include "rmw/visibility_control.h" - #include #include #include #include +#include "rmw/features.h" +#include "rmw/serialized_message.h" +#include "rmw/visibility_control.h" + /// Interfaces for runtime interface reflection @@ -52,7 +52,8 @@ extern const char * rmw_dynamic_typesupport_c__identifier; // Downstream classes are expected to borrow the `serialization_support` field, and potentially the // `dynamic_message_type` and `dynamic_message` fields. As such, it is important that this struct // outlives those downstream classes. -typedef struct rmw_dynamic_message_typesupport_impl_s { +typedef struct rmw_dynamic_message_typesupport_impl_s +{ rosidl_runtime_c__type_description__TypeDescription * description; rosidl_dynamic_typesupport_serialization_support_t * serialization_support; @@ -109,7 +110,8 @@ RMW_WARN_UNUSED rmw_ret_t rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * type_support); -/// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given type description +/// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given +/// type description RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t diff --git a/rmw/src/dynamic_message_typesupport.c b/rmw/src/dynamic_message_typesupport.c index 229c6c05..8cc5e20d 100644 --- a/rmw/src/dynamic_message_typesupport.c +++ b/rmw/src/dynamic_message_typesupport.c @@ -17,16 +17,16 @@ extern "C" { #endif -#include "rmw/convert_rcutils_ret_to_rmw_ret.h" -#include "rmw/dynamic_message_typesupport.h" -#include "rmw/error_handling.h" - #include #include #include #include #include +#include "rmw/convert_rcutils_ret_to_rmw_ret.h" +#include "rmw/dynamic_message_typesupport.h" +#include "rmw/error_handling.h" + const char * rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; @@ -47,7 +47,8 @@ rmw_dynamic_message_typesupport_handle_init( "never be populated. You must provide a type description."); return RMW_RET_INVALID_ARGUMENT; } - if (description == NULL) { // TODO: Remove if and when the deferred description path is supported + // TODO(methylDragon): Remove if and when the deferred description path is supported + if (description == NULL) { RMW_SET_ERROR_MSG( "Deferred type description is not currently supported. You must provide a type description."); return RMW_RET_INVALID_ARGUMENT; From 598628c37ac1128d654845115b0d40971699e1fc Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 19:25:50 -0700 Subject: [PATCH 11/18] Support type hashes Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_message_typesupport.h | 1 + rmw/src/dynamic_message_typesupport.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/rmw/include/rmw/dynamic_message_typesupport.h b/rmw/include/rmw/dynamic_message_typesupport.h index 5bc62297..450fe4a7 100644 --- a/rmw/include/rmw/dynamic_message_typesupport.h +++ b/rmw/include/rmw/dynamic_message_typesupport.h @@ -98,6 +98,7 @@ rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_type_hash_t * type_hash, rosidl_message_type_support_t ** ts); // OUT /// Finalize a rosidl_message_type_support_t obtained with diff --git a/rmw/src/dynamic_message_typesupport.c b/rmw/src/dynamic_message_typesupport.c index 8cc5e20d..dfe84add 100644 --- a/rmw/src/dynamic_message_typesupport.c +++ b/rmw/src/dynamic_message_typesupport.c @@ -39,6 +39,7 @@ rmw_dynamic_message_typesupport_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, const rosidl_runtime_c__type_description__TypeDescription * description, + rosidl_type_hash_t * type_hash, rosidl_message_type_support_t ** ts) { if (!middleware_supports_type_discovery && description == NULL) { @@ -54,6 +55,8 @@ rmw_dynamic_message_typesupport_handle_init( 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(ts, RMW_RET_INVALID_ARGUMENT); rmw_ret_t ret = RMW_RET_ERROR; rcutils_allocator_t allocator = rcutils_get_default_allocator(); @@ -64,6 +67,7 @@ rmw_dynamic_message_typesupport_handle_init( } (*ts)->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; + (*ts)->type_hash = type_hash; (*ts)->data = allocator.zero_allocate( 1, sizeof(rmw_dynamic_message_typesupport_impl_t), allocator.state); From 65869ca70e1dea0633e3a3a39129bbbb939369e6 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 2 Apr 2023 03:23:40 -0700 Subject: [PATCH 12/18] Fix windows build Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 2 +- rmw/include/rmw/dynamic_message_typesupport.h | 6 +--- .../dynamic_message_typesupport_identifier.h | 35 +++++++++++++++++++ rmw/include/rmw/rmw.h | 2 +- rmw/include/rmw/types.h | 1 + rmw/src/dynamic_message_typesupport.c | 1 + 6 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 rmw/include/rmw/dynamic_message_typesupport_identifier.h diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index d9064b47..bedc68cf 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -29,6 +29,7 @@ set(rmw_sources "src/allocators.c" "src/convert_rcutils_ret_to_rmw_ret.c" "src/discovery_options.c" + "src/dynamic_message_typesupport.c" "src/event.c" "src/init.c" "src/init_options.c" @@ -38,7 +39,6 @@ set(rmw_sources "src/network_flow_endpoint.c" "src/publisher_options.c" "src/qos_string_conversions.c" - "src/dynamic_message_typesupport.c" "src/sanity_checks.c" "src/security_options.c" "src/subscription_content_filter_options.c" diff --git a/rmw/include/rmw/dynamic_message_typesupport.h b/rmw/include/rmw/dynamic_message_typesupport.h index 450fe4a7..52913198 100644 --- a/rmw/include/rmw/dynamic_message_typesupport.h +++ b/rmw/include/rmw/dynamic_message_typesupport.h @@ -25,6 +25,7 @@ extern "C" #include #include +#include "rmw/dynamic_message_typesupport_identifier.h" #include "rmw/features.h" #include "rmw/serialized_message.h" #include "rmw/visibility_control.h" @@ -33,11 +34,6 @@ extern "C" /// Interfaces for runtime interface reflection // RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= -/// String identifying the typesupport introspection implementation in use. -// NOTE(methylDragon): I don't know if this is supposed to be in an identifier.h file -RMW_PUBLIC -extern const char * rmw_dynamic_typesupport_c__identifier; - // Every field of this struct is expected to be populated. // // NOTE(methylDragon): There is an opportunity to defer the population of the members by waiting diff --git a/rmw/include/rmw/dynamic_message_typesupport_identifier.h b/rmw/include/rmw/dynamic_message_typesupport_identifier.h new file mode 100644 index 00000000..4f8ede15 --- /dev/null +++ b/rmw/include/rmw/dynamic_message_typesupport_identifier.h @@ -0,0 +1,35 @@ +// Copyright 2022 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ +#define RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ + +#include "rmw/visibility_control.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// String identifying the typesupport introspection implementation in use. +RMW_PUBLIC +extern const char * rmw_dynamic_typesupport_c__identifier; + + +#ifdef __cplusplus +} +#endif + +#endif // RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index 760bb888..9d3771f0 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -106,7 +106,7 @@ extern "C" #include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" -#include "rmw/dynamic_message_typesupport.h" // TODO(methylDragon): NEW!! +#include "rmw/dynamic_message_typesupport.h" #include "rmw/subscription_options.h" #include "rmw/types.h" #include "rmw/visibility_control.h" diff --git a/rmw/include/rmw/types.h b/rmw/include/rmw/types.h index 9fc101ab..0e70bf33 100644 --- a/rmw/include/rmw/types.h +++ b/rmw/include/rmw/types.h @@ -27,6 +27,7 @@ extern "C" // map rcutils specific log levels to rmw speicfic type #include +#include "rmw/dynamic_message_typesupport_identifier.h" #include "rmw/events_statuses/events_statuses.h" #include "rmw/init.h" #include "rmw/init_options.h" diff --git a/rmw/src/dynamic_message_typesupport.c b/rmw/src/dynamic_message_typesupport.c index dfe84add..60377f56 100644 --- a/rmw/src/dynamic_message_typesupport.c +++ b/rmw/src/dynamic_message_typesupport.c @@ -25,6 +25,7 @@ extern "C" #include "rmw/convert_rcutils_ret_to_rmw_ret.h" #include "rmw/dynamic_message_typesupport.h" +#include "rmw/dynamic_message_typesupport_identifier.h" #include "rmw/error_handling.h" From 284384adc13b02738907dacbc8c7a132ef22a2b2 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 2 Apr 2023 21:47:29 -0700 Subject: [PATCH 13/18] Use dynamic typesupport identifier getter Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 3 +- ...pport.h => dynamic_message_type_support.h} | 50 ++++-- .../rmw/dynamic_typesupport_identifier.h | 44 +++++ rmw/include/rmw/rmw.h | 2 +- rmw/include/rmw/types.h | 2 +- ...pport.c => dynamic_message_type_support.c} | 165 ++++++++++++++---- .../dynamic_typesupport_identifier.c} | 19 +- 7 files changed, 221 insertions(+), 64 deletions(-) rename rmw/include/rmw/{dynamic_message_typesupport.h => dynamic_message_type_support.h} (79%) create mode 100644 rmw/include/rmw/dynamic_typesupport_identifier.h rename rmw/src/{dynamic_message_typesupport.c => dynamic_message_type_support.c} (55%) rename rmw/{include/rmw/dynamic_message_typesupport_identifier.h => src/dynamic_typesupport_identifier.c} (66%) diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index bedc68cf..47cf0682 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -29,7 +29,8 @@ set(rmw_sources "src/allocators.c" "src/convert_rcutils_ret_to_rmw_ret.c" "src/discovery_options.c" - "src/dynamic_message_typesupport.c" + "src/dynamic_message_type_support.c" + "src/dynamic_typesupport_identifier.c" "src/event.c" "src/init.c" "src/init_options.c" diff --git a/rmw/include/rmw/dynamic_message_typesupport.h b/rmw/include/rmw/dynamic_message_type_support.h similarity index 79% rename from rmw/include/rmw/dynamic_message_typesupport.h rename to rmw/include/rmw/dynamic_message_type_support.h index 52913198..1b1b274b 100644 --- a/rmw/include/rmw/dynamic_message_typesupport.h +++ b/rmw/include/rmw/dynamic_message_type_support.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ -#define RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ +#ifndef RMW__DYNAMIC_MESSAGE_TYPE_SUPPORT_H_ +#define RMW__DYNAMIC_MESSAGE_TYPE_SUPPORT_H_ #ifdef __cplusplus extern "C" @@ -24,8 +24,9 @@ extern "C" #include #include #include +#include -#include "rmw/dynamic_message_typesupport_identifier.h" +#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/features.h" #include "rmw/serialized_message.h" #include "rmw/visibility_control.h" @@ -48,9 +49,13 @@ extern "C" // Downstream classes are expected to borrow the `serialization_support` field, and potentially the // `dynamic_message_type` and `dynamic_message` fields. As such, it is important that this struct // outlives those downstream classes. -typedef struct rmw_dynamic_message_typesupport_impl_s +typedef struct rmw_dynamic_message_type_support_impl_s { - rosidl_runtime_c__type_description__TypeDescription * description; + rosidl_type_hash_t * type_hash; + rosidl_runtime_c__type_description__TypeDescription * type_description; + + // NOTE(methylDragon): Unused for now, but placed here just in case + rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources; rosidl_dynamic_typesupport_serialization_support_t * serialization_support; // NOTE(methylDragon): I'm unsure if these are necessary. Though I think they are convenient. @@ -64,7 +69,25 @@ typedef struct rmw_dynamic_message_typesupport_impl_s // technically redundant because data can be created from dynamic_message_type rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type; rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message; -} rmw_dynamic_message_typesupport_impl_t; +} rmw_dynamic_message_type_support_impl_t; + +/// Return type_hash member in rmw_dynamic_message_type_support_impl_t +RMW_PUBLIC +const rosidl_type_hash_t * +rmw_dynamic_message_type_support_get_type_hash_function( + const rosidl_message_type_support_t * type_support); + +/// Return description member in rmw_dynamic_message_type_support_impl_t +RMW_PUBLIC +const rosidl_runtime_c__type_description__TypeDescription * +rmw_dynamic_message_type_support_get_type_description_function( + const rosidl_message_type_support_t * type_support); + +/// Return type_description_sources member in rmw_dynamic_message_type_support_impl_t +RMW_PUBLIC +const rosidl_runtime_c__type_description__TypeSource__Sequence * +rmw_dynamic_message_type_support_get_type_description_sources_function( + const rosidl_message_type_support_t * type_support); /// Get dynamic type message typesupport with bound message description /** @@ -90,22 +113,23 @@ typedef struct rmw_dynamic_message_typesupport_impl_s RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_dynamic_message_typesupport_handle_init( +rmw_dynamic_message_type_support_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - const rosidl_runtime_c__type_description__TypeDescription * description, - rosidl_type_hash_t * type_hash, + 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, rosidl_message_type_support_t ** ts); // OUT /// Finalize a rosidl_message_type_support_t obtained with -/// rmw_dynamic_message_typesupport_handle_init, which has dynamically allocated members +/// rmw_dynamic_message_type_support_handle_init, 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_typesupport_handle_fini(rosidl_message_type_support_t * type_support); +rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * type_support); /// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given /// type description @@ -114,7 +138,7 @@ RMW_WARN_UNUSED rmw_ret_t rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription * type_description, rosidl_dynamic_typesupport_dynamic_type_t ** ts); // OUT RMW_PUBLIC @@ -201,4 +225,4 @@ rmw_get_serialization_support( } #endif -#endif // RMW__DYNAMIC_MESSAGE_TYPESUPPORT_H_ +#endif // RMW__DYNAMIC_MESSAGE_TYPE_SUPPORT_H_ diff --git a/rmw/include/rmw/dynamic_typesupport_identifier.h b/rmw/include/rmw/dynamic_typesupport_identifier.h new file mode 100644 index 00000000..81aa8a5e --- /dev/null +++ b/rmw/include/rmw/dynamic_typesupport_identifier.h @@ -0,0 +1,44 @@ +// Copyright 2022 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ +#define RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ + +#include "rmw/macros.h" +#include "rmw/visibility_control.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// String identifying the typesupport introspection implementation in use. +extern const char * const rmw_dynamic_typesupport_c__identifier; + +/// Get the name of the rmw_dynamic_typesupport_c identifier +/** + * \return Name of rmw_dynamic_typesupport_c identifier + */ +RMW_PUBLIC +RMW_WARN_UNUSED +const char * +rmw_get_dynamic_typesupport_identifier(void); + + +#ifdef __cplusplus +} +#endif + +#endif // RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ diff --git a/rmw/include/rmw/rmw.h b/rmw/include/rmw/rmw.h index 9d3771f0..164f47dc 100644 --- a/rmw/include/rmw/rmw.h +++ b/rmw/include/rmw/rmw.h @@ -106,7 +106,7 @@ extern "C" #include "rmw/message_sequence.h" #include "rmw/publisher_options.h" #include "rmw/qos_profiles.h" -#include "rmw/dynamic_message_typesupport.h" +#include "rmw/dynamic_message_type_support.h" #include "rmw/subscription_options.h" #include "rmw/types.h" #include "rmw/visibility_control.h" diff --git a/rmw/include/rmw/types.h b/rmw/include/rmw/types.h index 0e70bf33..55716e25 100644 --- a/rmw/include/rmw/types.h +++ b/rmw/include/rmw/types.h @@ -27,7 +27,7 @@ extern "C" // map rcutils specific log levels to rmw speicfic type #include -#include "rmw/dynamic_message_typesupport_identifier.h" +#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/events_statuses/events_statuses.h" #include "rmw/init.h" #include "rmw/init_options.h" diff --git a/rmw/src/dynamic_message_typesupport.c b/rmw/src/dynamic_message_type_support.c similarity index 55% rename from rmw/src/dynamic_message_typesupport.c rename to rmw/src/dynamic_message_type_support.c index 60377f56..3fe87702 100644 --- a/rmw/src/dynamic_message_typesupport.c +++ b/rmw/src/dynamic_message_type_support.c @@ -22,43 +22,48 @@ extern "C" #include #include #include +#include #include "rmw/convert_rcutils_ret_to_rmw_ret.h" -#include "rmw/dynamic_message_typesupport.h" -#include "rmw/dynamic_message_typesupport_identifier.h" +#include "rmw/dynamic_message_type_support.h" +#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/error_handling.h" +#include "rmw/visibility_control.h" -const char * rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; - // NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just // use the FastRTPS support then? /// Create a rosidl_message_type_support_t from a TypeDescription message rmw_ret_t -rmw_dynamic_message_typesupport_handle_init( +rmw_dynamic_message_type_support_handle_init( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, - const rosidl_runtime_c__type_description__TypeDescription * description, - rosidl_type_hash_t * type_hash, + 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, rosidl_message_type_support_t ** ts) { - if (!middleware_supports_type_discovery && description == NULL) { + 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 (description == NULL) { + 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(ts, RMW_RET_INVALID_ARGUMENT); + // NOTE(methylDragon): Not supported for now + // RMW_CHECK_ARGUMENT_FOR_NULL(type_description_sources, RMW_RET_INVALID_ARGUMENT); + rmw_ret_t ret = RMW_RET_ERROR; rcutils_allocator_t allocator = rcutils_get_default_allocator(); *ts = allocator.zero_allocate(1, sizeof(rosidl_message_type_support_t), allocator.state); @@ -67,46 +72,79 @@ rmw_dynamic_message_typesupport_handle_init( return RMW_RET_BAD_ALLOC; } - (*ts)->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; - (*ts)->type_hash = type_hash; - (*ts)->data = allocator.zero_allocate( - 1, sizeof(rmw_dynamic_message_typesupport_impl_t), allocator.state); + 1, sizeof(rmw_dynamic_message_type_support_impl_t), allocator.state); if (!ts) { - RMW_SET_ERROR_MSG("Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); + RMW_SET_ERROR_MSG("Could not allocate rmw_dynamic_message_type_support_impl_t struct"); ret = RMW_RET_BAD_ALLOC; goto fail; } - rmw_dynamic_message_typesupport_impl_t * ts_impl = - (rmw_dynamic_message_typesupport_impl_t *) (*ts)->data; + rmw_dynamic_message_type_support_impl_t * ts_impl = + (rmw_dynamic_message_type_support_impl_t *) (*ts)->data; - ts_impl->serialization_support = serialization_support; - (*ts)->func = get_message_typesupport_handle_function; + // Copy init type hash (never null (checked above)) + ts_impl->type_hash = allocator.zero_allocate(1, sizeof(rosidl_type_hash_t), allocator.state); + if (!ts_impl->type_hash) { + RMW_SET_ERROR_MSG("Could not create type hash to assign into"); + ret = RMW_RET_BAD_ALLOC; + goto fail; + } - if (description) { - ts_impl->description = rosidl_runtime_c__type_description__TypeDescription__create(); - if (ts_impl->description == NULL) { - RMW_SET_ERROR_MSG("Could not create type description to assign into"); + ts_impl->type_hash->version = type_hash->version; + memcpy(ts_impl->type_hash->value, type_hash->value, sizeof(type_hash->value)); + + // Copy init type description (never null (checked above)) + ts_impl->type_description = rosidl_runtime_c__type_description__TypeDescription__create(); + if (ts_impl->type_description == NULL) { + RMW_SET_ERROR_MSG("Could not create type description to assign into"); + ret = RMW_RET_BAD_ALLOC; + goto fail; + } + + if (!rosidl_runtime_c__type_description__TypeDescription__copy( + type_description, ts_impl->type_description)) + { + RMW_SET_ERROR_MSG("Could not copy type description"); + ret = RMW_RET_ERROR; + goto fail; + } + + // Copy init type description sources (might be null) + if (type_description_sources != NULL) { + ts_impl->type_description_sources = + rosidl_runtime_c__type_description__TypeSource__Sequence__create( + type_description_sources->size); + if (ts_impl->type_description_sources == NULL) { + RMW_SET_ERROR_MSG("Could not create type description sources sequence to assign into"); ret = RMW_RET_BAD_ALLOC; goto fail; } - if (!rosidl_runtime_c__type_description__TypeDescription__copy( - description, ts_impl->description)) + if (!rosidl_runtime_c__type_description__TypeSource__Sequence__copy( + type_description_sources, ts_impl->type_description_sources)) { - RMW_SET_ERROR_MSG("Could not copy type description"); + RMW_SET_ERROR_MSG("Could not copy type description sources"); ret = RMW_RET_ERROR; goto fail; } } + ts_impl->serialization_support = serialization_support; + + (*ts)->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; + (*ts)->func = get_message_typesupport_handle_function; + (*ts)->get_type_hash_func = rmw_dynamic_message_type_support_get_type_hash_function; + (*ts)->get_type_description_func = rmw_dynamic_message_type_support_get_type_description_function; + (*ts)->get_type_description_sources_func = + rmw_dynamic_message_type_support_get_type_description_sources_function; + ret = rmw_convert_rcutils_ret_to_rmw_ret( rmw_init_dynamic_message_type_from_description( - ts_impl->serialization_support, description, &ts_impl->dynamic_message_type)); + ts_impl->serialization_support, type_description, &ts_impl->dynamic_message_type)); if (ret != RMW_RET_OK || !ts_impl->dynamic_message_type) { RMW_SET_ERROR_MSG( - "Could not construct dynamic type for rmw_dynamic_message_typesupport_impl_t struct"); + "Could not construct dynamic type for rmw_dynamic_message_type_support_impl_t struct"); goto fail; } @@ -114,14 +152,14 @@ rmw_dynamic_message_typesupport_handle_init( ts_impl->dynamic_message_type, &ts_impl->dynamic_message); if (ret != RMW_RET_OK || !ts_impl->dynamic_message) { RMW_SET_ERROR_MSG( - "Could not construct dynamic data for rmw_dynamic_message_typesupport_impl_t struct"); + "Could not construct dynamic data for rmw_dynamic_message_type_support_impl_t struct"); goto fail; } return RMW_RET_OK; fail: - if (rmw_dynamic_message_typesupport_handle_fini(*ts) != RMW_RET_OK) { + if (rmw_dynamic_message_type_support_handle_fini(*ts) != RMW_RET_OK) { RCUTILS_LOG_ERROR_NAMED( rmw_dynamic_typesupport_c__identifier, "Could not finalize dynamic type typesupport"); @@ -129,8 +167,54 @@ rmw_dynamic_message_typesupport_handle_init( return ret; } + +const rosidl_type_hash_t * +rmw_dynamic_message_type_support_get_type_hash_function( + const rosidl_message_type_support_t * type_support) +{ + const rosidl_message_type_support_t * ts = get_message_typesupport_handle( + type_support, rmw_dynamic_typesupport_c__identifier); + if (ts == NULL) { + return NULL; + } + rmw_dynamic_message_type_support_impl_t * ts_impl = + (rmw_dynamic_message_type_support_impl_t *) ts->data; + return ts_impl->type_hash; +} + + +const rosidl_runtime_c__type_description__TypeDescription * +rmw_dynamic_message_type_support_get_type_description_function( + const rosidl_message_type_support_t * type_support) +{ + const rosidl_message_type_support_t * ts = get_message_typesupport_handle( + type_support, rmw_dynamic_typesupport_c__identifier); + if (ts == NULL) { + return NULL; + } + rmw_dynamic_message_type_support_impl_t * ts_impl = + (rmw_dynamic_message_type_support_impl_t *) ts->data; + return ts_impl->type_description; +} + + +const rosidl_runtime_c__type_description__TypeSource__Sequence * +rmw_dynamic_message_type_support_get_type_description_sources_function( + const rosidl_message_type_support_t * type_support) +{ + const rosidl_message_type_support_t * ts = get_message_typesupport_handle( + type_support, rmw_dynamic_typesupport_c__identifier); + if (ts == NULL) { + return NULL; + } + rmw_dynamic_message_type_support_impl_t * ts_impl = + (rmw_dynamic_message_type_support_impl_t *) ts->data; + return ts_impl->type_description_sources; +} + + rmw_ret_t -rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) +rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts) { RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT); @@ -140,11 +224,17 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) return RMW_RET_INVALID_ARGUMENT; } + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + if (ts->data) { - rmw_dynamic_message_typesupport_impl_t * ts_impl = - (rmw_dynamic_message_typesupport_impl_t *)ts->data; - if (ts_impl->description) { - rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->description); + rmw_dynamic_message_type_support_impl_t * ts_impl = + (rmw_dynamic_message_type_support_impl_t *)ts->data; + if (ts_impl->type_description) { + rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->type_description); + } + if (ts_impl->type_description_sources) { + rosidl_runtime_c__type_description__TypeSource__Sequence__fini( + ts_impl->type_description_sources); } if (ts_impl->dynamic_message_type) { rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_message_type); @@ -152,10 +242,9 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) if (ts_impl->dynamic_message) { rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_message); } + allocator.deallocate(ts_impl->type_hash, allocator.state); } - rcutils_allocator_t allocator = rcutils_get_default_allocator(); allocator.deallocate((void *)ts->data, allocator.state); - allocator.deallocate((void *)ts->type_hash, allocator.state); allocator.deallocate(ts, allocator.state); return RMW_RET_OK; } @@ -164,12 +253,12 @@ rmw_dynamic_message_typesupport_handle_fini(rosidl_message_type_support_t * ts) rmw_ret_t rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription * type_description, rosidl_dynamic_typesupport_dynamic_type_t ** ts) { return rmw_convert_rcutils_ret_to_rmw_ret( rosidl_dynamic_typesupport_dynamic_type_init_from_description( - serialization_support, description, ts)); + serialization_support, type_description, ts)); } diff --git a/rmw/include/rmw/dynamic_message_typesupport_identifier.h b/rmw/src/dynamic_typesupport_identifier.c similarity index 66% rename from rmw/include/rmw/dynamic_message_typesupport_identifier.h rename to rmw/src/dynamic_typesupport_identifier.c index 4f8ede15..d47234d9 100644 --- a/rmw/include/rmw/dynamic_message_typesupport_identifier.h +++ b/rmw/src/dynamic_typesupport_identifier.c @@ -12,24 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ -#define RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ - -#include "rmw/visibility_control.h" - #ifdef __cplusplus extern "C" { #endif +#include "rmw/dynamic_typesupport_identifier.h" -/// String identifying the typesupport introspection implementation in use. -RMW_PUBLIC -extern const char * rmw_dynamic_typesupport_c__identifier; + +const char * const rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; + +const char * +rmw_get_dynamic_typesupport_identifier() +{ + return rmw_dynamic_typesupport_c__identifier; +} #ifdef __cplusplus } #endif - -#endif // RMW__DYNAMIC_MESSAGE_TYPESUPPORT_IDENTIFIER_H_ From ffd631490e48a09b636f7630c276fdaee5952159 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 4 Apr 2023 05:10:28 -0700 Subject: [PATCH 14/18] Move dynamic type support struct to rosidl and fix mem issues Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 1 - .../rmw/dynamic_message_type_support.h | 73 ++----- .../rmw/dynamic_typesupport_identifier.h | 44 ---- rmw/include/rmw/types.h | 1 - rmw/src/dynamic_message_type_support.c | 189 ++---------------- rmw/src/dynamic_typesupport_identifier.c | 34 ---- 6 files changed, 28 insertions(+), 314 deletions(-) delete mode 100644 rmw/include/rmw/dynamic_typesupport_identifier.h delete mode 100644 rmw/src/dynamic_typesupport_identifier.c diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index 47cf0682..a9faf192 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -30,7 +30,6 @@ set(rmw_sources "src/convert_rcutils_ret_to_rmw_ret.c" "src/discovery_options.c" "src/dynamic_message_type_support.c" - "src/dynamic_typesupport_identifier.c" "src/event.c" "src/init.c" "src/init_options.c" diff --git a/rmw/include/rmw/dynamic_message_type_support.h b/rmw/include/rmw/dynamic_message_type_support.h index 1b1b274b..8d62fee7 100644 --- a/rmw/include/rmw/dynamic_message_type_support.h +++ b/rmw/include/rmw/dynamic_message_type_support.h @@ -20,13 +20,15 @@ extern "C" { #endif -#include #include +#include +#include +#include + #include #include #include -#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/features.h" #include "rmw/serialized_message.h" #include "rmw/visibility_control.h" @@ -35,60 +37,6 @@ extern "C" /// Interfaces for runtime interface reflection // RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= -// Every field of this struct is expected to be populated. -// -// NOTE(methylDragon): There is an opportunity to defer the population of the members by waiting -// for discovery, but this path is currently not supported. -// -// Ownership: -// - The struct owns its `description` field. It is responsible for deallocating it. -// - The struct owns its `serialization_support` field. It is responsible for deallocating it. -// - The struct owns its `dynamic_message_type` field. It is responsible for deallocating it. -// - The struct owns its `dynamic_message` field. It is responsible for deallocating it. -// -// Downstream classes are expected to borrow the `serialization_support` field, and potentially the -// `dynamic_message_type` and `dynamic_message` fields. As such, it is important that this struct -// outlives those downstream classes. -typedef struct rmw_dynamic_message_type_support_impl_s -{ - rosidl_type_hash_t * type_hash; - rosidl_runtime_c__type_description__TypeDescription * type_description; - - // NOTE(methylDragon): Unused for now, but placed here just in case - rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources; - rosidl_dynamic_typesupport_serialization_support_t * serialization_support; - - // NOTE(methylDragon): I'm unsure if these are necessary. Though I think they are convenient. - // dynamic_message_type moreso than dynamic_message. - // - // I'd err on including them to be able to support more middlewares - // - // The dynamic_message_type allows us to do a one time alloc and reuse it for - // subscription creation and data creation - // The dynamic_message allows us to either reuse it, or clone it, but it's - // technically redundant because data can be created from dynamic_message_type - rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type; - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message; -} rmw_dynamic_message_type_support_impl_t; - -/// Return type_hash member in rmw_dynamic_message_type_support_impl_t -RMW_PUBLIC -const rosidl_type_hash_t * -rmw_dynamic_message_type_support_get_type_hash_function( - const rosidl_message_type_support_t * type_support); - -/// Return description member in rmw_dynamic_message_type_support_impl_t -RMW_PUBLIC -const rosidl_runtime_c__type_description__TypeDescription * -rmw_dynamic_message_type_support_get_type_description_function( - const rosidl_message_type_support_t * type_support); - -/// Return type_description_sources member in rmw_dynamic_message_type_support_impl_t -RMW_PUBLIC -const rosidl_runtime_c__type_description__TypeSource__Sequence * -rmw_dynamic_message_type_support_get_type_description_sources_function( - const rosidl_message_type_support_t * type_support); - /// Get dynamic type message typesupport with bound message description /** * NOTE: Take note of the ownership rules for the returned struct and the `description` argument! @@ -121,7 +69,7 @@ rmw_dynamic_message_type_support_handle_init( const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources, rosidl_message_type_support_t ** ts); // OUT -/// Finalize a rosidl_message_type_support_t obtained with +/// Destroy a rosidl_message_type_support_t obtained with /// rmw_dynamic_message_type_support_handle_init, which has dynamically allocated members /// /// NOTE: Using this on a statically allocated typesupport will cause undefined behavior! @@ -129,7 +77,16 @@ rmw_dynamic_message_type_support_handle_init( RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * type_support); +rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * type_support); + +/// Get the name of the rmw_dynamic_typesupport_c identifier +/** + * \return Name of rmw_dynamic_typesupport_c identifier + */ +RMW_PUBLIC +RMW_WARN_UNUSED +const char * +rmw_get_dynamic_typesupport_identifier(void); /// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given /// type description diff --git a/rmw/include/rmw/dynamic_typesupport_identifier.h b/rmw/include/rmw/dynamic_typesupport_identifier.h deleted file mode 100644 index 81aa8a5e..00000000 --- a/rmw/include/rmw/dynamic_typesupport_identifier.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2022 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ -#define RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ - -#include "rmw/macros.h" -#include "rmw/visibility_control.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/// String identifying the typesupport introspection implementation in use. -extern const char * const rmw_dynamic_typesupport_c__identifier; - -/// Get the name of the rmw_dynamic_typesupport_c identifier -/** - * \return Name of rmw_dynamic_typesupport_c identifier - */ -RMW_PUBLIC -RMW_WARN_UNUSED -const char * -rmw_get_dynamic_typesupport_identifier(void); - - -#ifdef __cplusplus -} -#endif - -#endif // RMW__DYNAMIC_TYPESUPPORT_IDENTIFIER_H_ diff --git a/rmw/include/rmw/types.h b/rmw/include/rmw/types.h index 55716e25..9fc101ab 100644 --- a/rmw/include/rmw/types.h +++ b/rmw/include/rmw/types.h @@ -27,7 +27,6 @@ extern "C" // map rcutils specific log levels to rmw speicfic type #include -#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/events_statuses/events_statuses.h" #include "rmw/init.h" #include "rmw/init_options.h" diff --git a/rmw/src/dynamic_message_type_support.c b/rmw/src/dynamic_message_type_support.c index 3fe87702..65e957c1 100644 --- a/rmw/src/dynamic_message_type_support.c +++ b/rmw/src/dynamic_message_type_support.c @@ -19,6 +19,8 @@ extern "C" #include #include +#include +#include #include #include #include @@ -26,7 +28,6 @@ extern "C" #include "rmw/convert_rcutils_ret_to_rmw_ret.h" #include "rmw/dynamic_message_type_support.h" -#include "rmw/dynamic_typesupport_identifier.h" #include "rmw/error_handling.h" #include "rmw/visibility_control.h" @@ -56,6 +57,7 @@ rmw_dynamic_message_type_support_handle_init( "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); @@ -64,189 +66,24 @@ rmw_dynamic_message_type_support_handle_init( // NOTE(methylDragon): Not supported for now // RMW_CHECK_ARGUMENT_FOR_NULL(type_description_sources, RMW_RET_INVALID_ARGUMENT); - rmw_ret_t ret = RMW_RET_ERROR; - rcutils_allocator_t allocator = rcutils_get_default_allocator(); - *ts = allocator.zero_allocate(1, sizeof(rosidl_message_type_support_t), allocator.state); - if (!*ts) { - RMW_SET_ERROR_MSG("Could not allocate rosidl_message_type_support_t struct"); - return RMW_RET_BAD_ALLOC; - } - - (*ts)->data = allocator.zero_allocate( - 1, sizeof(rmw_dynamic_message_type_support_impl_t), allocator.state); - if (!ts) { - RMW_SET_ERROR_MSG("Could not allocate rmw_dynamic_message_type_support_impl_t struct"); - ret = RMW_RET_BAD_ALLOC; - goto fail; - } - - rmw_dynamic_message_type_support_impl_t * ts_impl = - (rmw_dynamic_message_type_support_impl_t *) (*ts)->data; - - // Copy init type hash (never null (checked above)) - ts_impl->type_hash = allocator.zero_allocate(1, sizeof(rosidl_type_hash_t), allocator.state); - if (!ts_impl->type_hash) { - RMW_SET_ERROR_MSG("Could not create type hash to assign into"); - ret = RMW_RET_BAD_ALLOC; - goto fail; - } - - ts_impl->type_hash->version = type_hash->version; - memcpy(ts_impl->type_hash->value, type_hash->value, sizeof(type_hash->value)); - - // Copy init type description (never null (checked above)) - ts_impl->type_description = rosidl_runtime_c__type_description__TypeDescription__create(); - if (ts_impl->type_description == NULL) { - RMW_SET_ERROR_MSG("Could not create type description to assign into"); - ret = RMW_RET_BAD_ALLOC; - goto fail; - } - - if (!rosidl_runtime_c__type_description__TypeDescription__copy( - type_description, ts_impl->type_description)) - { - RMW_SET_ERROR_MSG("Could not copy type description"); - ret = RMW_RET_ERROR; - goto fail; - } - - // Copy init type description sources (might be null) - if (type_description_sources != NULL) { - ts_impl->type_description_sources = - rosidl_runtime_c__type_description__TypeSource__Sequence__create( - type_description_sources->size); - if (ts_impl->type_description_sources == NULL) { - RMW_SET_ERROR_MSG("Could not create type description sources sequence to assign into"); - ret = RMW_RET_BAD_ALLOC; - goto fail; - } - - if (!rosidl_runtime_c__type_description__TypeSource__Sequence__copy( - type_description_sources, ts_impl->type_description_sources)) - { - RMW_SET_ERROR_MSG("Could not copy type description sources"); - ret = RMW_RET_ERROR; - goto fail; - } - } - - ts_impl->serialization_support = serialization_support; - - (*ts)->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; - (*ts)->func = get_message_typesupport_handle_function; - (*ts)->get_type_hash_func = rmw_dynamic_message_type_support_get_type_hash_function; - (*ts)->get_type_description_func = rmw_dynamic_message_type_support_get_type_description_function; - (*ts)->get_type_description_sources_func = - rmw_dynamic_message_type_support_get_type_description_sources_function; - - ret = rmw_convert_rcutils_ret_to_rmw_ret( - rmw_init_dynamic_message_type_from_description( - ts_impl->serialization_support, type_description, &ts_impl->dynamic_message_type)); - if (ret != RMW_RET_OK || !ts_impl->dynamic_message_type) { - RMW_SET_ERROR_MSG( - "Could not construct dynamic type for rmw_dynamic_message_type_support_impl_t struct"); - goto fail; - } - - ret = rmw_init_dynamic_message_from_dynamic_message_type( - ts_impl->dynamic_message_type, &ts_impl->dynamic_message); - if (ret != RMW_RET_OK || !ts_impl->dynamic_message) { - RMW_SET_ERROR_MSG( - "Could not construct dynamic data for rmw_dynamic_message_type_support_impl_t struct"); - goto fail; - } - - return RMW_RET_OK; - -fail: - if (rmw_dynamic_message_type_support_handle_fini(*ts) != RMW_RET_OK) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not finalize dynamic type typesupport"); - } - return ret; -} - - -const rosidl_type_hash_t * -rmw_dynamic_message_type_support_get_type_hash_function( - const rosidl_message_type_support_t * type_support) -{ - const rosidl_message_type_support_t * ts = get_message_typesupport_handle( - type_support, rmw_dynamic_typesupport_c__identifier); - if (ts == NULL) { - return NULL; - } - rmw_dynamic_message_type_support_impl_t * ts_impl = - (rmw_dynamic_message_type_support_impl_t *) ts->data; - return ts_impl->type_hash; -} - - -const rosidl_runtime_c__type_description__TypeDescription * -rmw_dynamic_message_type_support_get_type_description_function( - const rosidl_message_type_support_t * type_support) -{ - const rosidl_message_type_support_t * ts = get_message_typesupport_handle( - type_support, rmw_dynamic_typesupport_c__identifier); - if (ts == NULL) { - return NULL; - } - rmw_dynamic_message_type_support_impl_t * ts_impl = - (rmw_dynamic_message_type_support_impl_t *) ts->data; - return ts_impl->type_description; -} - - -const rosidl_runtime_c__type_description__TypeSource__Sequence * -rmw_dynamic_message_type_support_get_type_description_sources_function( - const rosidl_message_type_support_t * type_support) -{ - const rosidl_message_type_support_t * ts = get_message_typesupport_handle( - type_support, rmw_dynamic_typesupport_c__identifier); - if (ts == NULL) { - return NULL; - } - rmw_dynamic_message_type_support_impl_t * ts_impl = - (rmw_dynamic_message_type_support_impl_t *) ts->data; - return ts_impl->type_description_sources; + return rmw_convert_rcutils_ret_to_rmw_ret( + rosidl_dynamic_message_type_support_handle_init( + serialization_support, type_hash, type_description, type_description_sources, ts)); } rmw_ret_t -rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts) +rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * ts) { RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT); + return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_destroy(ts)); +} - // NOTE(methylDragon): Ignores const... - if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { - RCUTILS_SET_ERROR_MSG("type support not from this implementation"); - return RMW_RET_INVALID_ARGUMENT; - } - - rcutils_allocator_t allocator = rcutils_get_default_allocator(); - if (ts->data) { - rmw_dynamic_message_type_support_impl_t * ts_impl = - (rmw_dynamic_message_type_support_impl_t *)ts->data; - if (ts_impl->type_description) { - rosidl_runtime_c__type_description__TypeDescription__fini(ts_impl->type_description); - } - if (ts_impl->type_description_sources) { - rosidl_runtime_c__type_description__TypeSource__Sequence__fini( - ts_impl->type_description_sources); - } - if (ts_impl->dynamic_message_type) { - rosidl_dynamic_typesupport_dynamic_type_fini(ts_impl->dynamic_message_type); - } - if (ts_impl->dynamic_message) { - rosidl_dynamic_typesupport_dynamic_data_fini(ts_impl->dynamic_message); - } - allocator.deallocate(ts_impl->type_hash, allocator.state); - } - allocator.deallocate((void *)ts->data, allocator.state); - allocator.deallocate(ts, allocator.state); - return RMW_RET_OK; +const char * +rmw_get_dynamic_typesupport_identifier(void) +{ + return rosidl_dynamic_typesupport_c__identifier; } diff --git a/rmw/src/dynamic_typesupport_identifier.c b/rmw/src/dynamic_typesupport_identifier.c deleted file mode 100644 index d47234d9..00000000 --- a/rmw/src/dynamic_typesupport_identifier.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2022 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "rmw/dynamic_typesupport_identifier.h" - - -const char * const rmw_dynamic_typesupport_c__identifier = "rmw_dynamic_typesupport_c"; - -const char * -rmw_get_dynamic_typesupport_identifier() -{ - return rmw_dynamic_typesupport_c__identifier; -} - - -#ifdef __cplusplus -} -#endif From 2bc4c62515f954bf401df2427f25ecd8fb725ea7 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 6 Apr 2023 11:13:35 -0700 Subject: [PATCH 15/18] Refine CMakeLists and package.xml Signed-off-by: methylDragon --- rmw/CMakeLists.txt | 4 ++-- rmw/package.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index a9faf192..e536e517 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -18,9 +18,9 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() find_package(ament_cmake_ros REQUIRED) -find_package(rosidl_dynamic_typesupport REQUIRED) find_package(rcutils REQUIRED) +find_package(rosidl_dynamic_typesupport REQUIRED) find_package(rosidl_runtime_c REQUIRED) include(cmake/configure_rmw_library.cmake) @@ -72,6 +72,7 @@ configure_rmw_library(${PROJECT_NAME} LANGUAGE "C") ament_export_dependencies( rcutils + rosidl_dynamic_typesupport rosidl_runtime_c ) @@ -81,7 +82,6 @@ ament_export_libraries(${PROJECT_NAME}) # Export modern CMake targets ament_export_targets(${PROJECT_NAME}) -ament_export_dependencies(rosidl_dynamic_typesupport) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) diff --git a/rmw/package.xml b/rmw/package.xml index a103e28a..3bd0ec8d 100644 --- a/rmw/package.xml +++ b/rmw/package.xml @@ -16,15 +16,15 @@ ament_cmake_ros ament_cmake_version - rosidl_dynamic_typesupport rcutils rosidl_runtime_c + rosidl_dynamic_typesupport - rosidl_dynamic_typesupport rcutils rosidl_runtime_c + rosidl_dynamic_typesupport ament_cmake_gmock ament_lint_auto From a836ae881cb81efb1c8805231db41d3cdf727948 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 6 Apr 2023 11:24:54 -0700 Subject: [PATCH 16/18] Clean up whitespace Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_message_type_support.h | 2 -- rmw/src/dynamic_message_type_support.c | 9 --------- 2 files changed, 11 deletions(-) diff --git a/rmw/include/rmw/dynamic_message_type_support.h b/rmw/include/rmw/dynamic_message_type_support.h index 8d62fee7..755f1f2f 100644 --- a/rmw/include/rmw/dynamic_message_type_support.h +++ b/rmw/include/rmw/dynamic_message_type_support.h @@ -33,7 +33,6 @@ extern "C" #include "rmw/serialized_message.h" #include "rmw/visibility_control.h" - /// Interfaces for runtime interface reflection // RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= @@ -177,7 +176,6 @@ rmw_get_serialization_support( // const rosidl_message_type_support_t type_support, // rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); - #ifdef __cplusplus } #endif diff --git a/rmw/src/dynamic_message_type_support.c b/rmw/src/dynamic_message_type_support.c index 65e957c1..75fe6fd2 100644 --- a/rmw/src/dynamic_message_type_support.c +++ b/rmw/src/dynamic_message_type_support.c @@ -31,7 +31,6 @@ extern "C" #include "rmw/error_handling.h" #include "rmw/visibility_control.h" - // NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just // use the FastRTPS support then? @@ -71,7 +70,6 @@ rmw_dynamic_message_type_support_handle_init( serialization_support, type_hash, type_description, type_description_sources, ts)); } - rmw_ret_t rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * ts) { @@ -79,14 +77,12 @@ rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_destroy(ts)); } - const char * rmw_get_dynamic_typesupport_identifier(void) { return rosidl_dynamic_typesupport_c__identifier; } - rmw_ret_t rmw_init_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, @@ -98,7 +94,6 @@ rmw_init_dynamic_message_type_from_description( serialization_support, type_description, ts)); } - rmw_ret_t rmw_init_dynamic_message_from_dynamic_message_type( rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, @@ -109,7 +104,6 @@ rmw_init_dynamic_message_from_dynamic_message_type( dynamic_message_type, cloned_dynamic_message_type)); } - rmw_ret_t rmw_clone_dynamic_message( const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, @@ -119,7 +113,6 @@ rmw_clone_dynamic_message( rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_message, cloned_dynamic_message)); } - rmw_ret_t rmw_serialized_to_dynamic_message( rmw_serialized_message_t * serialized_message, @@ -140,7 +133,6 @@ rmw_serialized_to_dynamic_message( } } - rmw_ret_t rmw_dynamic_message_to_serialized( rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, @@ -159,7 +151,6 @@ rmw_dynamic_message_to_serialized( } } - #ifdef __cplusplus } #endif From 8eebcdb01560af17738bb75da1606b44181bffba Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 6 Apr 2023 21:14:57 -0700 Subject: [PATCH 17/18] Use create instead of init Signed-off-by: methylDragon --- rmw/include/rmw/dynamic_message_type_support.h | 8 ++++---- rmw/src/dynamic_message_type_support.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rmw/include/rmw/dynamic_message_type_support.h b/rmw/include/rmw/dynamic_message_type_support.h index 755f1f2f..ea9e78fb 100644 --- a/rmw/include/rmw/dynamic_message_type_support.h +++ b/rmw/include/rmw/dynamic_message_type_support.h @@ -60,7 +60,7 @@ extern "C" RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_dynamic_message_type_support_handle_init( +rmw_dynamic_message_type_support_handle_create( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, const rosidl_type_hash_t * type_hash, @@ -69,7 +69,7 @@ rmw_dynamic_message_type_support_handle_init( rosidl_message_type_support_t ** ts); // OUT /// Destroy a rosidl_message_type_support_t obtained with -/// rmw_dynamic_message_type_support_handle_init, which has dynamically allocated members +/// `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.) @@ -92,7 +92,7 @@ rmw_get_dynamic_typesupport_identifier(void); RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_init_dynamic_message_type_from_description( +rmw_create_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_runtime_c__type_description__TypeDescription * type_description, rosidl_dynamic_typesupport_dynamic_type_t ** ts); // OUT @@ -100,7 +100,7 @@ rmw_init_dynamic_message_type_from_description( RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t -rmw_init_dynamic_message_from_dynamic_message_type( +rmw_create_dynamic_message_from_dynamic_message_type( rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type); // OUT diff --git a/rmw/src/dynamic_message_type_support.c b/rmw/src/dynamic_message_type_support.c index 75fe6fd2..6bb24949 100644 --- a/rmw/src/dynamic_message_type_support.c +++ b/rmw/src/dynamic_message_type_support.c @@ -36,7 +36,7 @@ extern "C" /// Create a rosidl_message_type_support_t from a TypeDescription message rmw_ret_t -rmw_dynamic_message_type_support_handle_init( +rmw_dynamic_message_type_support_handle_create( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, bool middleware_supports_type_discovery, const rosidl_type_hash_t * type_hash, @@ -66,7 +66,7 @@ rmw_dynamic_message_type_support_handle_init( // 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( + rosidl_dynamic_message_type_support_handle_create( serialization_support, type_hash, type_description, type_description_sources, ts)); } @@ -84,23 +84,23 @@ rmw_get_dynamic_typesupport_identifier(void) } rmw_ret_t -rmw_init_dynamic_message_type_from_description( +rmw_create_dynamic_message_type_from_description( rosidl_dynamic_typesupport_serialization_support_t * serialization_support, const rosidl_runtime_c__type_description__TypeDescription * type_description, rosidl_dynamic_typesupport_dynamic_type_t ** ts) { return rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_type_init_from_description( + rosidl_dynamic_typesupport_dynamic_type_create_from_description( serialization_support, type_description, ts)); } rmw_ret_t -rmw_init_dynamic_message_from_dynamic_message_type( +rmw_create_dynamic_message_from_dynamic_message_type( rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type) { return rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + rosidl_dynamic_typesupport_dynamic_data_create_from_dynamic_type( dynamic_message_type, cloned_dynamic_message_type)); } From 31f89e80c0f5783e1055e51e0deb8586c13a107d Mon Sep 17 00:00:00 2001 From: methylDragon Date: Fri, 7 Apr 2023 18:05:36 -0700 Subject: [PATCH 18/18] Remove RMW interfaces Signed-off-by: methylDragon --- .../rmw/dynamic_message_type_support.h | 96 ----------- rmw/src/dynamic_message_type_support.c | 156 ------------------ 2 files changed, 252 deletions(-) delete mode 100644 rmw/src/dynamic_message_type_support.c diff --git a/rmw/include/rmw/dynamic_message_type_support.h b/rmw/include/rmw/dynamic_message_type_support.h index ea9e78fb..64c58d28 100644 --- a/rmw/include/rmw/dynamic_message_type_support.h +++ b/rmw/include/rmw/dynamic_message_type_support.h @@ -35,102 +35,6 @@ extern "C" /// Interfaces for runtime interface reflection -// RUNTIME INTERFACE REFLECTION TYPE SUPPORT ======================================================= -/// Get dynamic type message typesupport with bound 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_create( - 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, - rosidl_message_type_support_t ** ts); // OUT - -/// Destroy 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_destroy(rosidl_message_type_support_t * type_support); - -/// Get the name of the rmw_dynamic_typesupport_c identifier -/** - * \return Name of rmw_dynamic_typesupport_c identifier - */ -RMW_PUBLIC -RMW_WARN_UNUSED -const char * -rmw_get_dynamic_typesupport_identifier(void); - -/// Construct serialization support-specific rosidl_dynamic_typesupport_dynamic_type_t from a given -/// type description -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -rmw_create_dynamic_message_type_from_description( - rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * type_description, - rosidl_dynamic_typesupport_dynamic_type_t ** ts); // OUT - -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -rmw_create_dynamic_message_from_dynamic_message_type( - rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, - rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type); // OUT - -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -rmw_clone_dynamic_message( - const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, - rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message); // OUT - -// NOTE(methylDragon): The responsibility is on the user to ensure that the dynamic message's -// dynamic type matches the layout of the buffer -/// The user must provide a rosidl_dynamic_typesupport_dynamic_data_t with dynamic data impl -/// that matches the serialization library used to serialize the buffer. It must also match the -/// layout of the buffer if the serialization library cannot infer the layout from the buffer alone. -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -rmw_serialized_to_dynamic_message( - rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message); - -RMW_PUBLIC -RMW_WARN_UNUSED -rmw_ret_t -rmw_dynamic_message_to_serialized( - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, - rmw_serialized_message_t * serialized_message); - -// INTERFACES FOR RMW IMPLEMENTATIONS TO FULFILL =================================================== RMW_PUBLIC RMW_WARN_UNUSED rmw_ret_t diff --git a/rmw/src/dynamic_message_type_support.c b/rmw/src/dynamic_message_type_support.c deleted file mode 100644 index 6bb24949..00000000 --- a/rmw/src/dynamic_message_type_support.c +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2022 Open Source Robotics Foundation, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rmw/convert_rcutils_ret_to_rmw_ret.h" -#include "rmw/dynamic_message_type_support.h" -#include "rmw/error_handling.h" -#include "rmw/visibility_control.h" - -// NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just -// use the FastRTPS support then? - -/// 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, - 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, - 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(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_create( - serialization_support, type_hash, type_description, type_description_sources, 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); - return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_destroy(ts)); -} - -const char * -rmw_get_dynamic_typesupport_identifier(void) -{ - return rosidl_dynamic_typesupport_c__identifier; -} - -rmw_ret_t -rmw_create_dynamic_message_type_from_description( - rosidl_dynamic_typesupport_serialization_support_t * serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * type_description, - rosidl_dynamic_typesupport_dynamic_type_t ** ts) -{ - return rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_type_create_from_description( - serialization_support, type_description, ts)); -} - -rmw_ret_t -rmw_create_dynamic_message_from_dynamic_message_type( - rosidl_dynamic_typesupport_dynamic_type_t * dynamic_message_type, - rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message_type) -{ - return rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_data_create_from_dynamic_type( - dynamic_message_type, cloned_dynamic_message_type)); -} - -rmw_ret_t -rmw_clone_dynamic_message( - const rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, - rosidl_dynamic_typesupport_dynamic_data_t ** cloned_dynamic_message) -{ - return rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_data_clone(dynamic_message, cloned_dynamic_message)); -} - -rmw_ret_t -rmw_serialized_to_dynamic_message( - rmw_serialized_message_t * serialized_message, - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message) -{ - bool success; - rmw_ret_t ret = rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_data_deserialize( - dynamic_message, serialized_message, &success)); - - if (success) { - return RMW_RET_OK; - } else { - RMW_SET_ERROR_MSG( - "could not deserialize serialized message to dynamic data: " - "dynamic data not enough memory"); - return ret; - } -} - -rmw_ret_t -rmw_dynamic_message_to_serialized( - rosidl_dynamic_typesupport_dynamic_data_t * dynamic_message, - rmw_serialized_message_t * serialized_message) -{ - bool success; - rmw_ret_t ret = rmw_convert_rcutils_ret_to_rmw_ret( - rosidl_dynamic_typesupport_dynamic_data_serialize( - dynamic_message, serialized_message, &success)); - - if (success) { - return RMW_RET_OK; - } else { - RMW_SET_ERROR_MSG("could not serialize dynamic data to serialized message!"); - return ret; - } -} - -#ifdef __cplusplus -} -#endif