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"
35 return zero_service_event_publisher;
41 RCL_CHECK_FOR_NULL_WITH_MSG(
42 service_event_publisher,
"service_event_publisher is invalid",
return false);
43 RCL_CHECK_FOR_NULL_WITH_MSG(
45 "service_event_publisher's service type support is invalid",
return false);
47 RCL_SET_ERROR_MSG(
"service_event_publisher's clock is invalid");
53 static rcl_ret_t introspection_create_publisher(
60 service_event_publisher->
publisher = allocator.allocate(
62 RCL_CHECK_FOR_NULL_WITH_MSG(
72 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
73 service_event_publisher->
publisher = NULL;
74 rcutils_reset_error();
75 RCL_SET_ERROR_MSG(rcl_get_error_string().str);
82 rcl_ret_t rcl_service_event_publisher_init(
87 const char * service_name,
88 const rosidl_service_type_support_t * service_type_support)
116 rcutils_reset_error();
117 RCL_SET_ERROR_MSG(
"clock is invalid");
121 RCUTILS_LOG_DEBUG_NAMED(
122 ROS_PACKAGE_NAME,
"Initializing service introspection for service name '%s'", service_name);
126 service_event_publisher->
clock = clock;
129 size_t topic_length = strlen(service_name) + strlen(RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX) + 1;
131 topic_length, allocator.state);
132 RCL_CHECK_FOR_NULL_WITH_MSG(
134 "allocating memory for service introspection topic name failed",
140 "%s%s", service_name, RCL_SERVICE_INTROSPECTION_TOPIC_POSTFIX);
142 ret = introspection_create_publisher(service_event_publisher, node);
144 goto free_topic_name;
147 RCUTILS_LOG_DEBUG_NAMED(
148 ROS_PACKAGE_NAME,
"Service introspection for service '%s' initialized", service_name);
158 rcl_ret_t rcl_service_event_publisher_fini(
169 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
180 if (service_event_publisher->
publisher) {
182 allocator.deallocate(service_event_publisher->
publisher, allocator.state);
183 service_event_publisher->
publisher = NULL;
195 rcl_ret_t rcl_send_service_event_message(
197 const uint8_t event_type,
198 const void * ros_response_request,
199 const int64_t sequence_number,
200 const uint8_t guid[16])
210 if (!rcl_service_event_publisher_is_valid(service_event_publisher)) {
229 if (RMW_RET_OK != ret) {
230 rcutils_reset_error();
231 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
235 rosidl_service_introspection_info_t info = {
236 .event_type = event_type,
238 .stamp_nanosec = now % (1000LL * 1000LL * 1000LL),
239 .sequence_number = sequence_number,
242 memcpy(info.client_gid, guid, 16);
244 void * service_introspection_message;
246 ros_response_request = NULL;
248 switch (event_type) {
249 case service_msgs__msg__ServiceEventInfo__REQUEST_RECEIVED:
250 case service_msgs__msg__ServiceEventInfo__REQUEST_SENT:
251 service_introspection_message =
253 &info, &allocator, ros_response_request, NULL);
255 case service_msgs__msg__ServiceEventInfo__RESPONSE_RECEIVED:
256 case service_msgs__msg__ServiceEventInfo__RESPONSE_SENT:
257 service_introspection_message =
259 &info, &allocator, NULL, ros_response_request);
262 rcutils_reset_error();
263 RCL_SET_ERROR_MSG(
"unsupported event type");
266 RCL_CHECK_FOR_NULL_WITH_MSG(
267 service_introspection_message,
"service_introspection_message is NULL",
return RCL_RET_ERROR);
273 service_introspection_message, &allocator);
275 rcutils_reset_error();
276 RCL_SET_ERROR_MSG(rmw_get_error_string().str);
283 rcl_service_event_publisher_change_state(
285 rcl_service_introspection_state_t introspection_state)
287 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.