15 #include "rcl/service_event_publisher.h"
23 #include "rcl/error_handling.h"
26 #include "rcl/service_introspection.h"
29 #include "rcutils/logging_macros.h"
30 #include "rcutils/error_handling.h"
31 #include "rcutils/macros.h"
32 #include "rmw/error_handling.h"
33 #include "rmw/ret_types.h"
34 #include "service_msgs/msg/service_event_info.h"
40 return zero_service_event_publisher;
46 RCL_CHECK_FOR_NULL_WITH_MSG(
47 service_event_publisher,
"service_event_publisher is invalid",
return false);
48 RCL_CHECK_FOR_NULL_WITH_MSG(
50 "service_event_publisher's service type support is invalid",
return false);
52 RCL_SET_ERROR_MSG(
"service_event_publisher's clock is invalid");
58 static rcl_ret_t introspection_create_publisher(
65 service_event_publisher->
publisher = allocator.allocate(
67 RCL_CHECK_FOR_NULL_WITH_MSG(
77 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
78 service_event_publisher->
publisher = NULL;
79 rcutils_reset_error();
80 RCL_SET_ERROR_MSG(rcl_get_error_string().str);
87 rcl_ret_t rcl_service_event_publisher_init(
92 const char * service_name,
93 const rosidl_service_type_support_t * service_type_support)
121 rcutils_reset_error();
122 RCL_SET_ERROR_MSG(
"clock is invalid");
126 RCUTILS_LOG_DEBUG_NAMED(
127 ROS_PACKAGE_NAME,
"Initializing service introspection for service name '%s'", service_name);
131 service_event_publisher->
clock = clock;
134 size_t topic_length = strlen(service_name) + strlen(RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX) + 1;
136 topic_length, allocator.state);
137 RCL_CHECK_FOR_NULL_WITH_MSG(
139 "allocating memory for service introspection topic name failed",
145 "%s%s", service_name, RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX);
147 ret = introspection_create_publisher(service_event_publisher, node);
149 goto free_topic_name;
152 RCUTILS_LOG_DEBUG_NAMED(
153 ROS_PACKAGE_NAME,
"Service introspection for service '%s' initialized", service_name);
163 rcl_ret_t rcl_service_event_publisher_fini(
174 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
185 if (service_event_publisher->
publisher) {
187 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
188 service_event_publisher->
publisher = NULL;
200 rcl_ret_t rcl_send_service_event_message(
202 const uint8_t event_type,
203 const void * ros_response_request,
204 const int64_t sequence_number,
205 const uint8_t guid[16])
215 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
234 if (RMW_RET_OK != ret) {
235 rcutils_reset_error();
236 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
240 rosidl_service_introspection_info_t info = {
241 .event_type = event_type,
243 .stamp_nanosec = now % (1000LL * 1000LL * 1000LL),
244 .sequence_number = sequence_number,
247 memcpy(info.client_gid, guid, 16);
249 void * service_introspection_message;
251 ros_response_request = NULL;
253 switch (event_type) {
254 case service_msgs__msg__ServiceEventInfo__REQUEST_RECEIVED:
255 case service_msgs__msg__ServiceEventInfo__REQUEST_SENT:
256 service_introspection_message =
258 &info, &allocator, ros_response_request, NULL);
260 case service_msgs__msg__ServiceEventInfo__RESPONSE_RECEIVED:
261 case service_msgs__msg__ServiceEventInfo__RESPONSE_SENT:
262 service_introspection_message =
264 &info, &allocator, NULL, ros_response_request);
267 rcutils_reset_error();
268 RCL_SET_ERROR_MSG(
"unsupported event type");
271 RCL_CHECK_FOR_NULL_WITH_MSG(
272 service_introspection_message,
"service_introspection_message is NULL",
return RCL_RET_ERROR);
278 service_introspection_message, &allocator);
280 rcutils_reset_error();
281 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
288 rcl_service_event_publisher_change_state(
290 rcl_service_introspection_state_t introspection_state)
292 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.