15 #include "rcl/service_event_publisher.h"
20 #include "rcl/macros.h"
21 #include "rcl/error_handling.h"
24 #include "rcl/service_introspection.h"
27 #include "rcutils/logging_macros.h"
28 #include "rcutils/macros.h"
29 #include "rmw/error_handling.h"
30 #include "service_msgs/msg/service_event_info.h"
36 return zero_service_event_publisher;
42 RCL_CHECK_FOR_NULL_WITH_MSG(
43 service_event_publisher,
"service_event_publisher is invalid",
return false);
44 RCL_CHECK_FOR_NULL_WITH_MSG(
46 "service_event_publisher's service type support is invalid",
return false);
48 RCL_SET_ERROR_MSG(
"service_event_publisher's clock is invalid");
54 static rcl_ret_t introspection_create_publisher(
61 service_event_publisher->
publisher = allocator.allocate(
63 RCL_CHECK_FOR_NULL_WITH_MSG(
73 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
74 service_event_publisher->
publisher = NULL;
75 rcutils_reset_error();
76 RCL_SET_ERROR_MSG(rcl_get_error_string().str);
83 rcl_ret_t rcl_service_event_publisher_init(
88 const char * service_name,
89 const rosidl_service_type_support_t * service_type_support)
117 rcutils_reset_error();
118 RCL_SET_ERROR_MSG(
"clock is invalid");
122 RCUTILS_LOG_DEBUG_NAMED(
123 ROS_PACKAGE_NAME,
"Initializing service introspection for service name '%s'", service_name);
127 service_event_publisher->
clock = clock;
130 size_t topic_length = strlen(service_name) + strlen(RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX) + 1;
132 topic_length, allocator.state);
133 RCL_CHECK_FOR_NULL_WITH_MSG(
135 "allocating memory for service introspection topic name failed",
141 "%s%s", service_name, RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX);
143 ret = introspection_create_publisher(service_event_publisher, node);
145 goto free_topic_name;
148 RCUTILS_LOG_DEBUG_NAMED(
149 ROS_PACKAGE_NAME,
"Service introspection for service '%s' initialized", service_name);
159 rcl_ret_t rcl_service_event_publisher_fini(
170 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
181 if (service_event_publisher->
publisher) {
183 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
184 service_event_publisher->
publisher = NULL;
196 rcl_ret_t rcl_send_service_event_message(
198 const uint8_t event_type,
199 const void * ros_response_request,
200 const int64_t sequence_number,
201 const uint8_t guid[16])
211 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
230 if (RMW_RET_OK != ret) {
231 rcutils_reset_error();
232 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
236 rosidl_service_introspection_info_t info = {
237 .event_type = event_type,
239 .stamp_nanosec = now % (1000LL * 1000LL * 1000LL),
240 .sequence_number = sequence_number,
243 memcpy(info.client_gid, guid, 16);
245 void * service_introspection_message;
247 ros_response_request = NULL;
249 switch (event_type) {
250 case service_msgs__msg__ServiceEventInfo__REQUEST_RECEIVED:
251 case service_msgs__msg__ServiceEventInfo__REQUEST_SENT:
252 service_introspection_message =
254 &info, &allocator, ros_response_request, NULL);
256 case service_msgs__msg__ServiceEventInfo__RESPONSE_RECEIVED:
257 case service_msgs__msg__ServiceEventInfo__RESPONSE_SENT:
258 service_introspection_message =
260 &info, &allocator, NULL, ros_response_request);
263 rcutils_reset_error();
264 RCL_SET_ERROR_MSG(
"unsupported event type");
267 RCL_CHECK_FOR_NULL_WITH_MSG(
268 service_introspection_message,
"service_introspection_message is NULL",
return RCL_RET_ERROR);
274 service_introspection_message, &allocator);
276 rcutils_reset_error();
277 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
284 rcl_service_event_publisher_change_state(
286 rcl_service_introspection_state_t introspection_state)
288 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
RCL_PUBLIC bool rcl_node_is_valid(const rcl_node_t *node)
Return true if the node is valid, else false.
RCL_PUBLIC bool rcl_node_is_valid_except_context(const rcl_node_t *node)
Return true if node is valid, except for the context being valid.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_init(rcl_publisher_t *publisher, const rcl_node_t *node, const rosidl_message_type_support_t *type_support, const char *topic_name, const rcl_publisher_options_t *options)
Initialize a rcl publisher.
RCL_PUBLIC bool rcl_publisher_is_valid(const rcl_publisher_t *publisher)
Return true if the publisher is valid, otherwise false.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publish(const rcl_publisher_t *publisher, const void *ros_message, rmw_publisher_allocation_t *allocation)
Publish a ROS message on a topic using a publisher.
RCL_PUBLIC RCL_WARN_UNUSED rcl_publisher_t rcl_get_zero_initialized_publisher(void)
Return a rcl_publisher_t struct with members set to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_publisher_fini(rcl_publisher_t *publisher, rcl_node_t *node)
Finalize a rcl_publisher_t.
Encapsulation of a time source.
Structure which encapsulates a ROS Node.
Options available for a rcl publisher.
rcl_allocator_t allocator
Custom allocator for the publisher, used for incidental allocations.
Structure which encapsulates a ROS Publisher.
char * service_event_topic_name
Name of service introspection topic: <service_name>/<RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX>
const rosidl_service_type_support_t * service_type_support
Handle to service typesupport.
rcl_publisher_options_t publisher_options
Publisher options for service event publisher.
rcl_service_introspection_state_t introspection_state
Current state of introspection; off, metadata, or contents.
rcl_publisher_t * publisher
Handle to publisher for publishing service events.
rcl_clock_t * clock
Handle to clock for timestamping service events.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_clock_get_now(rcl_clock_t *clock, rcl_time_point_value_t *time_point_value)
Fill the time point value with the current value of the associated clock.
#define RCL_NS_TO_S
Convenience macro to convert nanoseconds to seconds.
rcutils_time_point_value_t rcl_time_point_value_t
A single point in time, measured in nanoseconds since the Unix epoch.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_clock_valid(rcl_clock_t *clock)
Check if the clock has valid values.
#define RCL_RET_ALREADY_INIT
rcl_init() already called return code.
#define RCL_RET_OK
Success return code.
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
#define RCL_RET_ERROR
Unspecified error return code.
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
#define RCL_RET_TOPIC_NAME_INVALID
Topic name does not pass validation.
#define RCL_RET_ALREADY_SHUTDOWN
rcl_shutdown() already called return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
#define RCL_RET_PUBLISHER_INVALID
Invalid rcl_publisher_t given return code.