Skip to content

Commit

Permalink
Get network flows of publishers and subscriptions
Browse files Browse the repository at this point in the history
Signed-off-by: Ananya Muddukrishna <ananya.x.muddukrishna@ericsson.com>
  • Loading branch information
Ananya Muddukrishna committed Dec 14, 2020
1 parent 1f5a713 commit b7ea7c0
Show file tree
Hide file tree
Showing 5 changed files with 637 additions and 0 deletions.
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.c
src/rcl/node.c
src/rcl/node_options.c
src/rcl/publisher.c
Expand Down
142 changes: 142 additions & 0 deletions rcl/include/rcl/network_flow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// 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_H_
#define RCL__NETWORK_FLOW_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include <rmw/network_flow.h>
#include <rmw/network_flow_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_t rcl_network_flow_t;
typedef rmw_network_flow_array_t rcl_network_flow_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_array \
rmw_get_zero_initialized_network_flow_array
#define rcl_network_flow_array_fini rmw_network_flow_array_fini

#define rcl_network_flow_get_transport_protocol_string \
rmw_network_flow_get_transport_protocol_string
#define rcl_network_flow_get_internet_protocol_string \
rmw_network_flow_get_internet_protocol_string

/// Get network flows of a publisher
/**
* Query the underlying middleware for a given publisher's network flows
*
* The `publisher` argument must point to a valid publisher.
*
* The `allocator` argument must be a valid allocator.
*
* The `network_flow_array` argument must be allocated and zero-initialized.
* The function returns network flows in the `network_flow_array` argument,
* using the allocator to allocate memory for the `network_flow_array`
* argument's internal data structures whenever required. The caller is
* reponsible for memory deallocation by passing the `network_flow_array`
* argument to `rcl_network_flow_array_fini` function.
*
* \todo TODO(anamud): Are the same network flows returned by successive calls
* to this 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_array_t
* \param[out] network_flow_array the network flows
* \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(
const rcl_publisher_t * publisher,
rcutils_allocator_t * allocator,
rcl_network_flow_array_t * network_flow_array);

/// Get network flows of a subscription
/**
* Query the underlying middleware for a given subscription's network flows
*
* The `subscription` argument must point to a valid subscription.
*
* The `allocator` argument must be a valid allocator.
*
* The `network_flow_array` argument must be allocated and zero-initialized.
* The function returns network flows in the `network_flow_array` argument,
* using the allocator to allocate memory for the `network_flow_array`
* argument's internal data structures whenever required. The caller is
* reponsible for memory deallocation by passing the `network_flow_array`
* argument to `rcl_network_flow_array_fini` function.
*
* \todo TODO(anamud): Are the same network flows returned by successive calls
* to this 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_array_t
* \param[out] network_flow_array the network flows
* \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(
const rcl_subscription_t * subscription,
rcutils_allocator_t * allocator,
rcl_network_flow_array_t * network_flow_array);

#ifdef __cplusplus
}
#endif

#endif // RCL__NETWORK_FLOW_H_
118 changes: 118 additions & 0 deletions rcl/src/rcl/network_flow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// 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.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.h"
#include "rmw/network_flow_array.h"
#include "rmw/types.h"

#include "./common.h"

rcl_ret_t
__validate_allocator_and_network_flow_array(
rcutils_allocator_t * allocator,
rcl_network_flow_array_t * network_flow_array)
{
RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);

RCL_CHECK_ARGUMENT_FOR_NULL(network_flow_array, RCL_RET_INVALID_ARGUMENT);

rmw_error_string_t error_string;
rmw_ret_t rmw_ret = rmw_network_flow_array_check_zero(network_flow_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_array_t must be zero initialized: %s,\n"
"Use rcl_get_zero_initialized_network_flow_array",
error_string.str);
}

return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}

rcl_ret_t
rcl_publisher_get_network_flow(
const rcl_publisher_t * publisher,
rcutils_allocator_t * allocator,
rcl_network_flow_array_t * network_flow_array)
{
if (!rcl_publisher_is_valid(publisher)) {
return RCL_RET_INVALID_ARGUMENT;
}

rcl_ret_t rcl_ret = __validate_allocator_and_network_flow_array(allocator, network_flow_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(
rcl_publisher_get_rmw_handle(publisher),
allocator,
network_flow_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(
const rcl_subscription_t * subscription,
rcutils_allocator_t * allocator,
rcl_network_flow_array_t * network_flow_array)
{
if (!rcl_subscription_is_valid(subscription)) {
return RCL_RET_INVALID_ARGUMENT;
}

rcl_ret_t rcl_ret = __validate_allocator_and_network_flow_array(allocator, network_flow_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(
rcl_subscription_get_rmw_handle(subscription),
allocator,
network_flow_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 @@ -318,6 +318,15 @@ function(test_target_function)
AMENT_DEPENDENCIES ${rmw_implementation}
)

rcl_add_custom_gtest(test_network_flow${target_suffix}
SRCS rcl/test_network_flow.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

0 comments on commit b7ea7c0

Please sign in to comment.