ROS 2 rclcpp + rcl - rolling  rolling-4d14414d
ROS 2 C++ Client Library with ROS Client Library
dynamic_message_type_support.c
1 // Copyright 2022 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 #include <rcutils/logging_macros.h>
21 #include <rosidl_runtime_c/message_type_support_struct.h>
22 #include <rosidl_runtime_c/type_description/type_description__struct.h>
23 
24 #include "rmw/dynamic_message_type_support.h"
25 
26 #include "rcl/allocator.h"
27 #include "rcl/common.h"
28 #include "rcl/error_handling.h"
29 #include "rcl/dynamic_message_type_support.h"
30 #include "rcl/type_hash.h"
31 #include "rcl/types.h"
32 
33 
36 rcl_dynamic_message_type_support_handle_init(
37  const char * serialization_lib_name,
38  const rosidl_runtime_c__type_description__TypeDescription * description,
39  rcl_allocator_t * allocator,
40  rosidl_message_type_support_t * ts)
41 {
42  RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RCUTILS_RET_INVALID_ARGUMENT);
43  RCUTILS_CHECK_ARGUMENT_FOR_NULL(allocator, RCUTILS_RET_INVALID_ARGUMENT);
44  if (!rcutils_allocator_is_valid(allocator)) {
45  RCUTILS_SET_ERROR_MSG("allocator is invalid");
46  return RCUTILS_RET_INVALID_ARGUMENT;
47  }
48 
49  // TODO(methylDragon): Remove if and when the deferred description path is supported
50  if (description == NULL) {
51  RCUTILS_SET_ERROR_MSG(
52  "Deferred type description is not currently supported. You must provide a type description.");
53  return RCUTILS_RET_INVALID_ARGUMENT;
54  }
55 
56  bool middleware_supports_type_discovery = rmw_feature_supported(
57  RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY);
58  if (!middleware_supports_type_discovery && description == NULL) {
59  RCL_SET_ERROR_MSG(
60  "Middleware does not support type discovery. Deferred dynamic type message type support will "
61  "never be populated. You must provide a type description.");
62  return RCUTILS_RET_INVALID_ARGUMENT;
63  }
64  // TODO(methylDragon): Remove if and when the deferred description path is supported
65  if (description == NULL) {
66  RCL_SET_ERROR_MSG(
67  "Deferred type description is not currently supported. You must provide a type description.");
68  return RCUTILS_RET_INVALID_ARGUMENT;
69  }
70 
71  rosidl_dynamic_typesupport_serialization_support_t serialization_support;
72  rcl_ret_t ret = rcl_convert_rmw_ret_to_rcl_ret(
73  rmw_serialization_support_init(serialization_lib_name, allocator, &serialization_support));
74  if (ret != RCL_RET_OK) {
75  RCL_SET_ERROR_MSG("failed to get serialization support");
76  if (ret == RCL_RET_OK) { // It means serialization support was NULL
77  return RCL_RET_ERROR;
78  } else {
79  return ret;
80  }
81  }
82 
83  rosidl_type_hash_t type_hash;
84  ret = rcl_calculate_type_hash(
85  // TODO(methylDragon): Replace this cast with the conversion function when it is ready
86  // Either a custom function, or from https://github.com/ros2/rcl/pull/1052
87  (const type_description_interfaces__msg__TypeDescription *) description, &type_hash);
88  if (ret != RCL_RET_OK) {
89  RCL_SET_ERROR_MSG("failed to get type hash");
90  return ret;
91  }
92 
93  ret = rcl_convert_rcutils_ret_to_rcl_ret(
94  rosidl_dynamic_message_type_support_handle_init(
95  &serialization_support,
96  &type_hash, // type_hash
97  description, // type_description
98  NULL, // type_description_sources
99  allocator,
100  ts
101  )
102  );
103  if (ret != RCL_RET_OK) {
104  rcutils_error_string_t error_string = rcutils_get_error_string();
105  rcutils_reset_error();
106  RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
107  "failed to init rosidl_message_type_support:\n%s", error_string.str);
108  return ret;
109  }
110 
111  return RCL_RET_OK;
112 }
113 
114 rcl_ret_t
115 rcl_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts)
116 {
117  RCL_CHECK_ARGUMENT_FOR_NULL(ts, RCL_RET_INVALID_ARGUMENT);
118  return rcl_convert_rcutils_ret_to_rcl_ret(rosidl_dynamic_message_type_support_handle_fini(ts));
119 }
120 
121 #ifdef __cplusplus
122 }
123 #endif
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:35
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:29
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24