ROS 2 rclcpp + rcl - rolling  rolling-e7363f10
ROS 2 C++ Client Library with ROS Client Library
init_options.c
1 // Copyright 2015 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 "rcl/init_options.h"
21 
22 #include <stddef.h>
23 
24 #include "./common.h"
25 #include "./init_options_impl.h"
26 
27 #include "rcl/allocator.h"
28 #include "rcl/error_handling.h"
29 #include "rcl/types.h"
30 
31 #include "rcutils/logging_macros.h"
32 
33 #include "rmw/error_handling.h"
34 #include "rmw/init.h"
35 #include "rmw/ret_types.h"
36 
39 {
40  return (const rcl_init_options_t) {
41  .impl = 0,
42  }; // NOLINT(readability/braces): false positive
43 }
44 
46 static inline
48 _rcl_init_options_zero_init(rcl_init_options_t * init_options, rcl_allocator_t allocator)
49 {
50  init_options->impl = allocator.allocate(sizeof(rcl_init_options_impl_t), allocator.state);
51  RCL_CHECK_FOR_NULL_WITH_MSG(
52  init_options->impl,
53  "failed to allocate memory for init options impl",
54  return RCL_RET_BAD_ALLOC);
55  init_options->impl->allocator = allocator;
56  init_options->impl->rmw_init_options = rmw_get_zero_initialized_init_options();
57 
58  return RCL_RET_OK;
59 }
60 
63 {
64  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
65  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
66  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
67  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
68 
69  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
70  if (NULL != init_options->impl) {
71  RCL_SET_ERROR_MSG("given init_options (rcl_init_options_t) is already initialized");
72  return RCL_RET_ALREADY_INIT;
73  }
75 
76  rcl_ret_t ret = _rcl_init_options_zero_init(init_options, allocator);
77  if (RCL_RET_OK != ret) {
78  return ret;
79  }
80  rmw_ret_t rmw_ret = rmw_init_options_init(&(init_options->impl->rmw_init_options), allocator);
81  if (RMW_RET_OK != rmw_ret) {
82  allocator.deallocate(init_options->impl, allocator.state);
83  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
84  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
85  }
86 
87  // rmw defaults discovery range to LOCALHOST
88  // Intentionally set discovery options to NOT_SET so we can determine
89  // if a user intentionally sets them later
90  init_options->impl->rmw_init_options.discovery_options.automatic_discovery_range =
91  RMW_AUTOMATIC_DISCOVERY_RANGE_NOT_SET;
92  return RCL_RET_OK;
93 }
94 
97 {
98  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
99  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
100  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
101  RCUTILS_CAN_SET_MSG_AND_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
102 
103  RCL_CHECK_ARGUMENT_FOR_NULL(src, RCL_RET_INVALID_ARGUMENT);
104  RCL_CHECK_ARGUMENT_FOR_NULL(src->impl, RCL_RET_INVALID_ARGUMENT);
105  RCL_CHECK_ALLOCATOR(&src->impl->allocator, return RCL_RET_INVALID_ARGUMENT);
106  RCL_CHECK_ARGUMENT_FOR_NULL(dst, RCL_RET_INVALID_ARGUMENT);
107  if (NULL != dst->impl) {
108  RCL_SET_ERROR_MSG("given dst (rcl_init_options_t) is already initialized");
109  return RCL_RET_ALREADY_INIT;
110  }
111 
112  // initialize dst (since we know it's in a zero initialized state)
113  rcl_ret_t ret = _rcl_init_options_zero_init(dst, src->impl->allocator);
114  if (RCL_RET_OK != ret) {
115  return ret; // error already set
116  }
117 
118  // copy src information into dst
119  rmw_ret_t rmw_ret =
120  rmw_init_options_copy(&(src->impl->rmw_init_options), &(dst->impl->rmw_init_options));
121  if (RMW_RET_OK != rmw_ret) {
122  rmw_error_string_t error_string = rmw_get_error_string();
123  rmw_reset_error();
124  ret = rcl_init_options_fini(dst);
125  if (RCL_RET_OK != ret) {
126  RCUTILS_LOG_ERROR_NAMED(
127  "rcl",
128  "failed to finalize dst rcl_init_options while handling failure to "
129  "copy rmw_init_options, original ret '%d' and error: %s", rmw_ret, error_string.str);
130  return ret; // error already set
131  }
132  RCL_SET_ERROR_MSG(error_string.str);
133  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
134  }
135 
136  return RCL_RET_OK;
137 }
138 
139 rcl_ret_t
141 {
142  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
143  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
144  rcl_allocator_t allocator = init_options->impl->allocator;
145  RCL_CHECK_ALLOCATOR(&allocator, return RCL_RET_INVALID_ARGUMENT);
146  rmw_ret_t rmw_ret = rmw_init_options_fini(&(init_options->impl->rmw_init_options));
147  if (RMW_RET_OK != rmw_ret) {
148  RCL_SET_ERROR_MSG(rmw_get_error_string().str);
149  return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
150  }
151  allocator.deallocate(init_options->impl, allocator.state);
152  return RCL_RET_OK;
153 }
154 
155 rcl_ret_t
156 rcl_init_options_get_domain_id(const rcl_init_options_t * init_options, size_t * domain_id)
157 {
158  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
159  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
160  RCL_CHECK_ARGUMENT_FOR_NULL(domain_id, RCL_RET_INVALID_ARGUMENT);
161  *domain_id = init_options->impl->rmw_init_options.domain_id;
162  return RCL_RET_OK;
163 }
164 
165 rcl_ret_t
166 rcl_init_options_set_domain_id(rcl_init_options_t * init_options, size_t domain_id)
167 {
168  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, RCL_RET_INVALID_ARGUMENT);
169  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, RCL_RET_INVALID_ARGUMENT);
170  init_options->impl->rmw_init_options.domain_id = domain_id;
171  return RCL_RET_OK;
172 }
173 
174 rmw_init_options_t *
176 {
177  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, NULL);
178  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, NULL);
179  return &(init_options->impl->rmw_init_options);
180 }
181 
182 const rcl_allocator_t *
184 {
185  RCL_CHECK_ARGUMENT_FOR_NULL(init_options, NULL);
186  RCL_CHECK_ARGUMENT_FOR_NULL(init_options->impl, NULL);
187  return &(init_options->impl->allocator);
188 }
189 
190 #ifdef __cplusplus
191 }
192 #endif
#define RCL_CHECK_ALLOCATOR(allocator, fail_statement)
Check that the given allocator is initialized.
Definition: allocator.h:49
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_init(rcl_init_options_t *init_options, rcl_allocator_t allocator)
Initialize given init_options with the default values and implementation specific values.
Definition: init_options.c:62
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_set_domain_id(rcl_init_options_t *init_options, size_t domain_id)
Set a domain id in the init options provided.
Definition: init_options.c:166
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_copy(const rcl_init_options_t *src, rcl_init_options_t *dst)
Copy the given source init_options to the destination init_options.
Definition: init_options.c:96
RCL_PUBLIC RCL_WARN_UNUSED rcl_init_options_t rcl_get_zero_initialized_init_options(void)
Return a zero initialized rcl_init_options_t struct.
Definition: init_options.c:38
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_get_domain_id(const rcl_init_options_t *init_options, size_t *domain_id)
Return the domain_id stored in the init options.
Definition: init_options.c:156
RCL_PUBLIC RCL_WARN_UNUSED const rcl_allocator_t * rcl_init_options_get_allocator(const rcl_init_options_t *init_options)
Return the allocator stored in the init_options.
Definition: init_options.c:183
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_init_options_fini(rcl_init_options_t *init_options)
Finalize the given init_options.
Definition: init_options.c:140
RCL_PUBLIC RCL_WARN_UNUSED rmw_init_options_t * rcl_init_options_get_rmw_init_options(rcl_init_options_t *init_options)
Return the rmw init options which are stored internally.
Definition: init_options.c:175
Encapsulation of init options and implementation defined init options.
Definition: init_options.h:38
rcl_init_options_impl_t * impl
Implementation specific pointer.
Definition: init_options.h:40
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
Definition: types.h:42
#define RCL_RET_OK
Success return code.
Definition: types.h:28
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:34
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:36
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:30
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:25