Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

content filtered topic for action feedback subscription #901

Open
wants to merge 20 commits into
base: rolling
Choose a base branch
from
Open
31 changes: 31 additions & 0 deletions rcl/include/rcl/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,37 @@ extern "C"

#define RCL_UNUSED(x) RCUTILS_UNUSED(x)

#define RCL_RET_FROM_RCUTIL_RET(rcl_ret_var, rcutils_expr) \
{ \
rcutils_ret_t rcutils_ret = rcutils_expr; \
if (RCUTILS_RET_OK != rcutils_ret) { \
if (rcutils_error_is_set()) { \
RCL_SET_ERROR_MSG(rcutils_get_error_string().str); \
} else { \
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("rcutils_ret_t code: %i", rcutils_ret); \
} \
} \
switch (rcutils_ret) { \
case RCUTILS_RET_OK: \
rcl_ret_var = RCL_RET_OK; \
break; \
case RCUTILS_RET_ERROR: \
rcl_ret_var = RCL_RET_ERROR; \
break; \
case RCUTILS_RET_BAD_ALLOC: \
rcl_ret_var = RCL_RET_BAD_ALLOC; \
break; \
case RCUTILS_RET_INVALID_ARGUMENT: \
rcl_ret_var = RCL_RET_INVALID_ARGUMENT; \
break; \
case RCUTILS_RET_NOT_INITIALIZED: \
rcl_ret_var = RCL_RET_NOT_INIT; \
break; \
default: \
rcl_ret_var = RCUTILS_RET_ERROR; \
} \
}

#ifdef __cplusplus
}
#endif
Expand Down
187 changes: 187 additions & 0 deletions rcl/include/rcl/subscription.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ typedef struct rcl_subscription_options_s
rmw_subscription_options_t rmw_subscription_options;
} rcl_subscription_options_t;

typedef struct rcl_subscription_content_filter_options_s
{
/// Custom allocator for the options, used for incidental allocations.
/** For default behavior (malloc/free), see: rcl_get_default_allocator() */
rcl_allocator_t allocator;
/// rmw specific subscription content filter options
rmw_subscription_content_filter_options_t * rmw_subscription_content_filter_options;
} rcl_subscription_content_filter_options_t;

/// Return a rcl_subscription_t struct with members set to `NULL`.
/**
* Should be called to get a null rcl_subscription_t before passing to
Expand Down Expand Up @@ -208,6 +217,184 @@ RCL_WARN_UNUSED
rcl_subscription_options_t
rcl_subscription_get_default_options(void);

/// Reclaim resources held inside rcl_subscription_options_t structure.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] option The structure which its resources have to be deallocated.
* \return `RCL_RET_OK` if the memory was successfully freed, or
* \return `RCL_RET_INVALID_ARGUMENT` if option is NULL, or
* \return `RCL_RET_BAD_ALLOC` if deallocating memory fails.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_options_fini(rcl_subscription_options_t * option);

/// Set the content filter options for the given subscription options.
/**
* \param[in] filter_expression The filter expression.
* \param[in] expression_parameters_argc The expression parameters argc.
* \param[in] expression_parameter_argv The expression parameters argv.
* \param[out] options The subscription options to be set.
* \return `RCL_RET_OK` if set options successfully, or
* \return `RCL_RET_INVALID_ARGUMENT` if arguments invalid, or
* \return `RCL_RET_BAD_ALLOC` if allocating memory fails.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_options_set_content_filter_options(
const char * filter_expression,
size_t expression_parameters_argc,
const char * expression_parameter_argv[],
rcl_subscription_options_t * options);

/// Return the default subscription content filter options.
/**
* The defaults are:
*
* - allocator = rcl_get_default_allocator()
* - rmw_subscription_content_filter_options = NULL;
*
* \return A structure containing the default options for a subscription.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_subscription_content_filter_options_t
rcl_subscription_get_default_content_filter_options(void);

/// Allocate.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] option The structure which its resources have to be deallocated.
* \return `RCL_RET_OK` if the memory was successfully freed, or
* \return `RCL_RET_INVALID_ARGUMENT` if option is NULL, or
* if its allocator is invalid and the structure contains initialized memory.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_content_filter_options_init(
const char * filter_expression,
size_t expression_parameters_argc,
const char * expression_parameter_argv[],
rcl_subscription_content_filter_options_t * options);

RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_content_filter_options_set(
const char * filter_expression,
size_t expression_parameters_argc,
const char * expression_parameter_argv[],
rcl_subscription_content_filter_options_t * options);

/// Reclaim rcl_subscription_content_filter_options_t structure.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] options The structure which its resources have to be deallocated.
* \return `RCL_RET_OK` if the memory was successfully freed, or
* \return `RCL_RET_INVALID_ARGUMENT` if option is NULL, or
* if its allocator is invalid and the structure contains initialized memory.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_content_filter_options_fini(
rcl_subscription_content_filter_options_t * options);

/// Check if the content filtered topic feature is enabled in the subscription.
/**
* Depending on the middleware and whether cft is enabled in the subscription.
*
* \return `true` if the content filtered topic of `subscription` is enabled, otherwise `false`
*/
RCL_PUBLIC
RCL_WARN_UNUSED
bool
rcl_subscription_is_cft_enabled(const rcl_subscription_t * subscription);

/// Set the filter expression and expression parameters for the subscription.
/**
* This function will set a filter expression and an array of expression parameters
* for the given subscription.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | No
* Uses Atomics | Maybe [1]
* Lock-Free | Maybe [1]
*
* \param[in] subscription The subscription to set content filter options.
* \param[in] options The rcl content filter options.
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_INVALID_ARGUMENT` if `subscription` is NULL, or
* \return `RCL_RET_INVALID_ARGUMENT` if `rcl_content_filter_options` is NULL, or
* \return `RCL_RET_UNSUPPORTED` if the implementation does not support content filter topic, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_set_content_filter(
const rcl_subscription_t * subscription,
const rcl_subscription_content_filter_options_t * options
);

/// Retrieve the filter expression of the subscription.
/**
* This function will return an filter expression by the given subscription.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | Maybe [1]
* Lock-Free | Maybe [1]
*
* \param[in] subscription The subscription object to inspect.
* \param[out] options The rcl content filter options.
* It is up to the caller to finalize this options later on, using
* rcl_subscription_content_filter_options_fini().
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_INVALID_ARGUMENT` if `subscription` is NULL, or
* \return `RCL_RET_INVALID_ARGUMENT` if `options` is NULL, or
* \return `RCL_RET_BAD_ALLOC` if memory allocation fails, or
* \return `RCL_RET_UNSUPPORTED` if the implementation does not support content filter topic, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_get_content_filter(
const rcl_subscription_t * subscription,
rcl_subscription_content_filter_options_t * options
);

/// Take a ROS message from a topic using a rcl subscription.
/**
* It is the job of the caller to ensure that the type of the ros_message
Expand Down
32 changes: 1 addition & 31 deletions rcl/src/rcl/logging_rosout.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "rcl/allocator.h"
#include "rcl/error_handling.h"
#include "rcl/logging_rosout.h"
#include "rcl/macros.h"
#include "rcl/node.h"
#include "rcl/publisher.h"
#include "rcl/time.h"
Expand Down Expand Up @@ -43,37 +44,6 @@ extern "C"
return RCL_RET_OK; \
}

#define RCL_RET_FROM_RCUTIL_RET(rcl_ret_var, rcutils_expr) \
{ \
rcutils_ret_t rcutils_ret = rcutils_expr; \
if (RCUTILS_RET_OK != rcutils_ret) { \
if (rcutils_error_is_set()) { \
RCL_SET_ERROR_MSG(rcutils_get_error_string().str); \
} else { \
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("rcutils_ret_t code: %i", rcutils_ret); \
} \
} \
switch (rcutils_ret) { \
case RCUTILS_RET_OK: \
rcl_ret_var = RCL_RET_OK; \
break; \
case RCUTILS_RET_ERROR: \
rcl_ret_var = RCL_RET_ERROR; \
break; \
case RCUTILS_RET_BAD_ALLOC: \
rcl_ret_var = RCL_RET_BAD_ALLOC; \
break; \
case RCUTILS_RET_INVALID_ARGUMENT: \
rcl_ret_var = RCL_RET_INVALID_ARGUMENT; \
break; \
case RCUTILS_RET_NOT_INITIALIZED: \
rcl_ret_var = RCL_RET_NOT_INIT; \
break; \
default: \
rcl_ret_var = RCUTILS_RET_ERROR; \
} \
}

typedef struct rosout_map_entry_t
{
rcl_node_t * node;
Expand Down
Loading