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

Unique network flows #880

Merged
merged 8 commits into from
Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rcl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ set(${PROJECT_NAME}_sources
src/rcl/logging_rosout.c
src/rcl/logging.c
src/rcl/log_level.c
src/rcl/network_flow_endpoints.c
src/rcl/node.c
src/rcl/node_options.c
src/rcl/publisher.c
Expand Down
136 changes: 136 additions & 0 deletions rcl/include/rcl/network_flow_endpoints.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2020 Ericsson AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#ifndef RCL__NETWORK_FLOW_ENDPOINTS_H_
#define RCL__NETWORK_FLOW_ENDPOINTS_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include <rmw/network_flow_endpoint.h>
#include <rmw/network_flow_endpoint_array.h>

#include "rcl/allocator.h"
#include "rcl/arguments.h"
#include "rcl/context.h"
#include "rcl/macros.h"
#include "rcl/publisher.h"
#include "rcl/subscription.h"
#include "rcl/types.h"
#include "rcl/visibility_control.h"

typedef rmw_network_flow_endpoint_t rcl_network_flow_endpoint_t;
typedef rmw_network_flow_endpoint_array_t rcl_network_flow_endpoint_array_t;
typedef rmw_transport_protocol_t rcl_transport_protocol_t;
typedef rmw_internet_protocol_t rcl_internet_protocol_t;

#define rcl_get_zero_initialized_network_flow_endpoint_array \
rmw_get_zero_initialized_network_flow_endpoint_array
#define rcl_network_flow_endpoint_array_fini rmw_network_flow_endpoint_array_fini

#define rcl_network_flow_endpoint_get_transport_protocol_string \
rmw_network_flow_endpoint_get_transport_protocol_string
#define rcl_network_flow_endpoint_get_internet_protocol_string \
rmw_network_flow_endpoint_get_internet_protocol_string

/// Get network flow endpoints of a publisher
/**
* Query the underlying middleware for a given publisher's network flow endpoints
*
* The `publisher` argument must point to a valid publisher.
*
* The `allocator` argument must be a valid allocator.
*
* The `network_flow_endpoint_array` argument must be allocated and zero-initialized.
* The function returns network flow endpoints in the `network_flow_endpoint_array` argument,
* using the allocator to allocate memory for the `network_flow_endpoint_array`
* argument's internal data structures whenever required. The caller is
* reponsible for memory deallocation by passing the `network_flow_endpoint_array`
* argument to `rcl_network_flow_endpoint_array_fini` function.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Maybe [1]
* <i>[1] implementation may need to protect the data structure with a lock</i>
*
* \param[in] publisher the publisher instance to inspect
* \param[in] allocator allocator to be used when allocating space for network_flow_endpoint_array_t
* \param[out] network_flow_endpoint_array the network flow endpoints
* \return `RCL_RET_OK` if successful, or
* \return `RCL_RET_INVALID_ARGUMENT` if any argument is null, or
* \return `RCL_RET_BAD_ALLOC` if memory allocation fails, or
* \return `RCL_RET_UNSUPPORTED` if not supported, or
* \return `RCL_RET_ERROR` if an unexpected error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_publisher_get_network_flow_endpoints(
const rcl_publisher_t * publisher,
rcutils_allocator_t * allocator,
rcl_network_flow_endpoint_array_t * network_flow_endpoint_array);

/// Get network flow endpoints of a subscription
/**
* Query the underlying middleware for a given subscription's network flow endpoints
*
* The `subscription` argument must point to a valid subscription.
*
* The `allocator` argument must be a valid allocator.
*
* The `network_flow_endpoint_array` argument must be allocated and zero-initialized.
* The function returns network flow endpoints in the `network_flow_endpoint_array` argument,
* using the allocator to allocate memory for the `network_flow_endpoint_array`
* argument's internal data structures whenever required. The caller is
* reponsible for memory deallocation by passing the `network_flow_endpoint_array`
* argument to `rcl_network_flow_endpoint_array_fini` function.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Maybe [1]
* <i>[1] implementation may need to protect the data structure with a lock</i>
*
* \param[in] subscription the subscription instance to inspect
* \param[in] allocator allocator to be used when allocating space for network_flow_endpoint_array_t
* \param[out] network_flow_endpoint_array the network flow endpoints
* \return `RCL_RET_OK` if successful, or
* \return `RCL_RET_INVALID_ARGUMENT` if any argument is null, or
* \return `RCL_RET_BAD_ALLOC` if memory allocation fails, or
* \return `RCL_RET_UNSUPPORTED` if not supported, or
* \return `RCL_RET_ERROR` if an unexpected error occurs.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_subscription_get_network_flow_endpoints(
const rcl_subscription_t * subscription,
rcutils_allocator_t * allocator,
rcl_network_flow_endpoint_array_t * network_flow_endpoint_array);

#ifdef __cplusplus
}
#endif

#endif // RCL__NETWORK_FLOW_ENDPOINTS_H_
121 changes: 121 additions & 0 deletions rcl/src/rcl/network_flow_endpoints.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright 2020 Ericsson AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifdef __cplusplus
extern "C"
{
#endif

#include "rcl/error_handling.h"
#include "rcl/graph.h"
#include "rcl/network_flow_endpoints.h"
#include "rcl/publisher.h"
#include "rcl/subscription.h"

#include "rcutils/allocator.h"
#include "rcutils/macros.h"
#include "rcutils/types.h"

#include "rmw/error_handling.h"
#include "rmw/get_network_flow_endpoints.h"
#include "rmw/network_flow_endpoint_array.h"
#include "rmw/types.h"

#include "./common.h"

rcl_ret_t
__validate_network_flow_endpoint_array(
rcl_network_flow_endpoint_array_t * network_flow_endpoint_array)
{
RCL_CHECK_ARGUMENT_FOR_NULL(network_flow_endpoint_array, RCL_RET_INVALID_ARGUMENT);

rmw_error_string_t error_string;
rmw_ret_t rmw_ret = rmw_network_flow_endpoint_array_check_zero(network_flow_endpoint_array);
if (rmw_ret != RMW_RET_OK) {
error_string = rmw_get_error_string();
rmw_reset_error();
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
"rcl_network_flow_endpoint_array_t must be zero initialized: %s,\n"
"Use rcl_get_zero_initialized_network_flow_endpoint_array",
error_string.str);
}

return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}

rcl_ret_t
rcl_publisher_get_network_flow_endpoints(
const rcl_publisher_t * publisher,
rcutils_allocator_t * allocator,
rcl_network_flow_endpoint_array_t * network_flow_endpoint_array)
{
if (!rcl_publisher_is_valid(publisher)) {
return RCL_RET_INVALID_ARGUMENT;
}

RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);

rcl_ret_t rcl_ret = __validate_network_flow_endpoint_array(
network_flow_endpoint_array);
if (rcl_ret != RCL_RET_OK) {
return rcl_ret;
}

rmw_error_string_t error_string;
rmw_ret_t rmw_ret = rmw_publisher_get_network_flow_endpoints(
rcl_publisher_get_rmw_handle(publisher),
allocator,
network_flow_endpoint_array);
if (rmw_ret != RMW_RET_OK) {
error_string = rmw_get_error_string();
rmw_reset_error();
RCL_SET_ERROR_MSG(error_string.str);
}
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}

rcl_ret_t
rcl_subscription_get_network_flow_endpoints(
const rcl_subscription_t * subscription,
rcutils_allocator_t * allocator,
rcl_network_flow_endpoint_array_t * network_flow_endpoint_array)
{
if (!rcl_subscription_is_valid(subscription)) {
return RCL_RET_INVALID_ARGUMENT;
}

RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);

rcl_ret_t rcl_ret = __validate_network_flow_endpoint_array(
network_flow_endpoint_array);
if (rcl_ret != RCL_RET_OK) {
return rcl_ret;
}

rmw_error_string_t error_string;
rmw_ret_t rmw_ret = rmw_subscription_get_network_flow_endpoints(
rcl_subscription_get_rmw_handle(subscription),
allocator,
network_flow_endpoint_array);
if (rmw_ret != RMW_RET_OK) {
error_string = rmw_get_error_string();
rmw_reset_error();
RCL_SET_ERROR_MSG(error_string.str);
}
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}

#ifdef __cplusplus
}
#endif
9 changes: 9 additions & 0 deletions rcl/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,15 @@ function(test_target_function)
AMENT_DEPENDENCIES ${rmw_implementation}
)

rcl_add_custom_gtest(test_network_flow_endpoints${target_suffix}
SRCS rcl/test_network_flow_endpoints.cpp
ENV ${rmw_implementation_env_var}
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../src/rcl/
LIBRARIES ${PROJECT_NAME} mimick
AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp" "test_msgs"
)

# Launch tests

rcl_add_custom_executable(service_fixture${target_suffix}
Expand Down
Loading