diff --git a/rcl/include/rcl/client.h b/rcl/include/rcl/client.h index 97dade4f2..7ca81d2a8 100644 --- a/rcl/include/rcl/client.h +++ b/rcl/include/rcl/client.h @@ -26,6 +26,8 @@ extern "C" #include "rcl/node.h" #include "rcl/visibility_control.h" +#include "rmw/listener_callback_type.h" + /// Internal rcl client implementation struct. struct rcl_client_impl_t; @@ -407,6 +409,14 @@ RCL_PUBLIC bool rcl_client_is_valid(const rcl_client_t * client); +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_client_set_listener_callback( + const rcl_client_t * client, + rmw_listener_callback_t listener_callback, + const void * user_data); + #ifdef __cplusplus } #endif diff --git a/rcl/include/rcl/event.h b/rcl/include/rcl/event.h index 6798a9d5e..d5974483a 100644 --- a/rcl/include/rcl/event.h +++ b/rcl/include/rcl/event.h @@ -193,6 +193,15 @@ RCL_PUBLIC bool rcl_event_is_valid(const rcl_event_t * event); +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_event_set_listener_callback( + const rcl_event_t * event, + rmw_listener_callback_t listener_callback, + const void * user_data, + bool use_previous_events); + #ifdef __cplusplus } #endif diff --git a/rcl/include/rcl/guard_condition.h b/rcl/include/rcl/guard_condition.h index 9f40ccd6c..007874516 100644 --- a/rcl/include/rcl/guard_condition.h +++ b/rcl/include/rcl/guard_condition.h @@ -26,6 +26,8 @@ extern "C" #include "rcl/types.h" #include "rcl/visibility_control.h" +#include "rmw/listener_callback_type.h" + /// Internal rcl guard condition implementation struct. struct rcl_guard_condition_impl_t; @@ -258,6 +260,15 @@ RCL_WARN_UNUSED rmw_guard_condition_t * rcl_guard_condition_get_rmw_handle(const rcl_guard_condition_t * guard_condition); +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_guard_condition_set_listener_callback( + const rcl_guard_condition_t * guard_condition, + rmw_listener_callback_t listener_callback, + const void * user_data, + bool use_previous_events); + #ifdef __cplusplus } #endif diff --git a/rcl/include/rcl/service.h b/rcl/include/rcl/service.h index a73cb3802..787d29a71 100644 --- a/rcl/include/rcl/service.h +++ b/rcl/include/rcl/service.h @@ -26,6 +26,8 @@ extern "C" #include "rcl/node.h" #include "rcl/visibility_control.h" +#include "rmw/listener_callback_type.h" + /// Internal rcl implementation struct. struct rcl_service_impl_t; @@ -421,6 +423,14 @@ RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t * service); +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_service_set_listener_callback( + const rcl_service_t * service, + rmw_listener_callback_t listener_callback, + const void * user_data); + #ifdef __cplusplus } #endif diff --git a/rcl/include/rcl/subscription.h b/rcl/include/rcl/subscription.h index e0d2dce5f..18a950f6d 100644 --- a/rcl/include/rcl/subscription.h +++ b/rcl/include/rcl/subscription.h @@ -26,6 +26,7 @@ extern "C" #include "rcl/node.h" #include "rcl/visibility_control.h" +#include "rmw/listener_callback_type.h" #include "rmw/message_sequence.h" /// Internal rcl implementation struct. @@ -604,6 +605,14 @@ RCL_PUBLIC bool rcl_subscription_can_loan_messages(const rcl_subscription_t * subscription); +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_subscription_set_listener_callback( + const rcl_subscription_t * subscription, + rmw_listener_callback_t listener_callback, + const void * user_data); + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/client.c b/rcl/src/rcl/client.c index 53dc77ca1..1c35e9456 100644 --- a/rcl/src/rcl/client.c +++ b/rcl/src/rcl/client.c @@ -280,6 +280,19 @@ rcl_client_is_valid(const rcl_client_t * client) client->impl->rmw_handle, "client's rmw handle is invalid", return false); return true; } + +rcl_ret_t +rcl_client_set_listener_callback( + const rcl_client_t * client, + rmw_listener_callback_t listener_callback, + const void * user_data) +{ + return rmw_client_set_listener_callback( + client->impl->rmw_handle, + listener_callback, + user_data); +} + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/event.c b/rcl/src/rcl/event.c index c79c60ce6..b4cf09b69 100644 --- a/rcl/src/rcl/event.c +++ b/rcl/src/rcl/event.c @@ -218,6 +218,20 @@ rcl_event_is_valid(const rcl_event_t * event) return true; } +rcl_ret_t +rcl_event_set_listener_callback( + const rcl_event_t * event, + rmw_listener_callback_t listener_callback, + const void * user_data, + bool use_previous_events) +{ + return rmw_event_set_listener_callback( + &event->impl->rmw_handle, + listener_callback, + user_data, + use_previous_events); +} + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/guard_condition.c b/rcl/src/rcl/guard_condition.c index d7e17afda..cac4bfc42 100644 --- a/rcl/src/rcl/guard_condition.c +++ b/rcl/src/rcl/guard_condition.c @@ -186,6 +186,20 @@ rcl_guard_condition_get_rmw_handle(const rcl_guard_condition_t * guard_condition return guard_condition->impl->rmw_handle; } +rcl_ret_t +rcl_guard_condition_set_listener_callback( + const rcl_guard_condition_t * guard_condition, + rmw_listener_callback_t listener_callback, + const void * user_data, + bool use_previous_events) +{ + return rmw_guard_condition_set_listener_callback( + guard_condition->impl->rmw_handle, + listener_callback, + user_data, + use_previous_events); +} + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/service.c b/rcl/src/rcl/service.c index 251ab66b1..dd39176a8 100644 --- a/rcl/src/rcl/service.c +++ b/rcl/src/rcl/service.c @@ -301,6 +301,19 @@ rcl_service_is_valid(const rcl_service_t * service) return true; } +rcl_ret_t +rcl_service_set_listener_callback( + const rcl_service_t * service, + rmw_listener_callback_t listener_callback, + const void * user_data) +{ + return rmw_service_set_listener_callback( + service->impl->rmw_handle, + listener_callback, + user_data); +} + + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/subscription.c b/rcl/src/rcl/subscription.c index 611994356..57fc2dc46 100644 --- a/rcl/src/rcl/subscription.c +++ b/rcl/src/rcl/subscription.c @@ -437,6 +437,18 @@ rcl_subscription_can_loan_messages(const rcl_subscription_t * subscription) return subscription->impl->rmw_handle->can_loan_messages; } +rcl_ret_t +rcl_subscription_set_listener_callback( + const rcl_subscription_t * subscription, + rmw_listener_callback_t listener_callback, + const void * user_data) +{ + return rmw_subscription_set_listener_callback( + subscription->impl->rmw_handle, + listener_callback, + user_data); +} + #ifdef __cplusplus } #endif diff --git a/rcl_action/include/rcl_action/action_client.h b/rcl_action/include/rcl_action/action_client.h index 430d05e66..8050d1dd7 100644 --- a/rcl_action/include/rcl_action/action_client.h +++ b/rcl_action/include/rcl_action/action_client.h @@ -25,6 +25,8 @@ extern "C" #include "rcl/macros.h" #include "rcl/node.h" +#include "rmw/listener_callback_type.h" + /// Internal action client implementation struct. struct rcl_action_client_impl_t; @@ -741,6 +743,37 @@ bool rcl_action_client_is_valid( const rcl_action_client_t * action_client); +/// Get the action client events ID. +/** + * This function fills the array passed as argument + * with the action client events ID. + * The IDs are pointers to the action client entities + * which respond to action client events. + * \param[in] action_client pointer to the action client + * \param[in] events_id the array to store the IDs + */ +RCL_ACTION_PUBLIC +void +rcl_action_client_get_events_id( + const rcl_action_client_t * action_client, + const void * events_id[]); + +/// Set the action client listeners callback +/** + * This function set the listener callbacks to the + * entities conforming the action client. + * \param[in] action_client pointer to the action client + * \param[in] listener_callback the listener callback + * \param[in] user_data array of data used by the callbacks + */ +RCL_ACTION_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_action_client_set_listeners_callback( + const rcl_action_client_t * action_client, + rmw_listener_callback_t listener_callback, + const void * user_data[]); + #ifdef __cplusplus } #endif diff --git a/rcl_action/include/rcl_action/action_server.h b/rcl_action/include/rcl_action/action_server.h index 79abff41f..bd07bf848 100644 --- a/rcl_action/include/rcl_action/action_server.h +++ b/rcl_action/include/rcl_action/action_server.h @@ -27,6 +27,8 @@ extern "C" #include "rcl/node.h" #include "rcl/time.h" +#include "rmw/listener_callback_type.h" + #include "rosidl_runtime_c/action_type_support_struct.h" /// Internal rcl_action implementation struct. @@ -930,6 +932,37 @@ RCL_WARN_UNUSED bool rcl_action_server_is_valid_except_context(const rcl_action_server_t * action_server); +/// Get the action server events ID. +/** + * This function fills the array passed as argument + * with the action server events ID. + * The IDs are pointers to the action server entities + * which respond to action server events. + * \param[in] action_server pointer to the action server + * \param[in] events_id the array to store the IDs + */ +RCL_ACTION_PUBLIC +void +rcl_action_server_get_events_id( + const rcl_action_server_t * action_server, + const void * events_id[]); + +/// Set the action server listeners callback +/** + * This function set the listener callbacks to the + * entities conforming the action server. + * \param[in] action_server pointer to the action server + * \param[in] listener_callback the listener callback + * \param[in] user_data array of data used by the callbacks + */ +RCL_ACTION_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_action_server_set_listeners_callback( + const rcl_action_server_t * action_server, + rmw_listener_callback_t listener_callback, + const void * user_data[]); + #ifdef __cplusplus } #endif diff --git a/rcl_action/include/rcl_action/types.h b/rcl_action/include/rcl_action/types.h index d5f60e446..bd4b14091 100644 --- a/rcl_action/include/rcl_action/types.h +++ b/rcl_action/include/rcl_action/types.h @@ -113,6 +113,26 @@ typedef enum rcl_action_goal_event_t GOAL_EVENT_NUM_EVENTS } rcl_action_goal_event_t; +/// Action client entities +typedef enum rcl_action_client_entity_type_t +{ + GOAL_CLIENT = 0, + RESULT_CLIENT, + CANCEL_CLIENT, + FEEDBACK_SUBSCRIPTION, + STATUS_SUBSCRIPTION, + ACTION_CLIENT_NUM_ENTITIES +} rcl_action_client_entity_type_t; + +/// Action server entities +typedef enum rcl_action_server_entity_type_t +{ + GOAL_SERVICE = 0, + CANCEL_SERVICE, + RESULT_SERVICE, + ACTION_SERVER_NUM_ENTITIES +} rcl_action_server_entity_type_t; + /// Return a rcl_action_goal_info_t with members set to zero values. RCL_ACTION_PUBLIC RCL_WARN_UNUSED diff --git a/rcl_action/src/rcl_action/action_client.c b/rcl_action/src/rcl_action/action_client.c index 58ab0a9a0..5d68ea2df 100644 --- a/rcl_action/src/rcl_action/action_client.c +++ b/rcl_action/src/rcl_action/action_client.c @@ -647,6 +647,86 @@ rcl_action_client_wait_set_get_entities_ready( return RCL_RET_OK; } +void rcl_action_client_get_events_id( + const rcl_action_client_t * action_client, + const void * events_id[]) +{ + events_id[GOAL_CLIENT] = &action_client->impl->goal_client; + events_id[RESULT_CLIENT] = &action_client->impl->result_client; + events_id[CANCEL_CLIENT] = &action_client->impl->cancel_client; + events_id[FEEDBACK_SUBSCRIPTION] = &action_client->impl->feedback_subscription; + events_id[STATUS_SUBSCRIPTION] = &action_client->impl->status_subscription; +} + +rcl_ret_t +rcl_action_client_set_listeners_callback( + const rcl_action_client_t * action_client, + rmw_listener_callback_t listener_callback, + const void * user_data[]) +{ + if (!rcl_action_client_is_valid(action_client)) { + return RCL_RET_ACTION_CLIENT_INVALID; + } + + const void * goal_client_data = NULL; + const void * cancel_client_data = NULL; + const void * result_client_data = NULL; + const void * feedback_subscription_data = NULL; + const void * status_subscription_data = NULL; + + if (user_data) { + goal_client_data = user_data[GOAL_CLIENT]; + cancel_client_data = user_data[CANCEL_CLIENT]; + result_client_data = user_data[RESULT_CLIENT]; + feedback_subscription_data = user_data[FEEDBACK_SUBSCRIPTION]; + status_subscription_data = user_data[STATUS_SUBSCRIPTION]; + } + + rcl_ret_t ret; + + ret = rcl_client_set_listener_callback( + &action_client->impl->goal_client, + listener_callback, + goal_client_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_client_set_listener_callback( + &action_client->impl->cancel_client, + listener_callback, + cancel_client_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_client_set_listener_callback( + &action_client->impl->result_client, + listener_callback, + result_client_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_subscription_set_listener_callback( + &action_client->impl->feedback_subscription, + listener_callback, + feedback_subscription_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_subscription_set_listener_callback( + &action_client->impl->status_subscription, + listener_callback, + status_subscription_data); + if (ret != RCL_RET_OK) { + return ret; + } + + return RCL_RET_OK; +} + #ifdef __cplusplus } #endif diff --git a/rcl_action/src/rcl_action/action_server.c b/rcl_action/src/rcl_action/action_server.c index cbed688eb..51553d73c 100644 --- a/rcl_action/src/rcl_action/action_server.c +++ b/rcl_action/src/rcl_action/action_server.c @@ -1054,6 +1054,64 @@ rcl_action_server_wait_set_get_entities_ready( return RCL_RET_OK; } +void rcl_action_server_get_events_id( + const rcl_action_server_t * action_server, + const void * events_id[]) +{ + events_id[GOAL_SERVICE] = &action_server->impl->goal_service; + events_id[RESULT_SERVICE] = &action_server->impl->result_service; + events_id[CANCEL_SERVICE] = &action_server->impl->cancel_service; +} + +rcl_ret_t +rcl_action_server_set_listeners_callback( + const rcl_action_server_t * action_server, + rmw_listener_callback_t listener_callback, + const void * user_data[]) +{ + if (!rcl_action_server_is_valid_except_context(action_server)) { + return RCL_RET_ACTION_SERVER_INVALID; + } + + const void * goal_service_data = NULL; + const void * cancel_service_data = NULL; + const void * result_service_data = NULL; + + if (user_data) { + goal_service_data = user_data[GOAL_SERVICE]; + cancel_service_data = user_data[CANCEL_SERVICE]; + result_service_data = user_data[RESULT_SERVICE]; + } + + rcl_ret_t ret; + + ret = rcl_service_set_listener_callback( + &action_server->impl->goal_service, + listener_callback, + goal_service_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_service_set_listener_callback( + &action_server->impl->cancel_service, + listener_callback, + cancel_service_data); + if (ret != RCL_RET_OK) { + return ret; + } + + ret = rcl_service_set_listener_callback( + &action_server->impl->result_service, + listener_callback, + result_service_data); + if (ret != RCL_RET_OK) { + return ret; + } + + return RCL_RET_OK; +} + #ifdef __cplusplus } #endif