diff --git a/rmw_fastrtps_cpp/CMakeLists.txt b/rmw_fastrtps_cpp/CMakeLists.txt
index 45314ad1a..c5a3f8c9c 100644
--- a/rmw_fastrtps_cpp/CMakeLists.txt
+++ b/rmw_fastrtps_cpp/CMakeLists.txt
@@ -32,6 +32,7 @@ endif()
find_package(ament_cmake_ros REQUIRED)
find_package(rcutils REQUIRED)
+find_package(rmw_dds_common REQUIRED)
find_package(rmw_fastrtps_shared_cpp REQUIRED)
find_package(fastrtps_cmake_module REQUIRED)
@@ -53,6 +54,9 @@ add_library(rmw_fastrtps_cpp
src/get_service.cpp
src/get_subscriber.cpp
src/identifier.cpp
+ src/listener_thread.cpp
+ src/publisher.cpp
+ src/register_node.cpp
src/rmw_logging.cpp
src/rmw_client.cpp
src/rmw_compare_gids_equal.cpp
@@ -70,6 +74,7 @@ add_library(rmw_fastrtps_cpp
src/rmw_publisher.cpp
src/rmw_request.cpp
src/rmw_response.cpp
+ src/rmw_security.cpp
src/rmw_serialize.cpp
src/rmw_service.cpp
src/rmw_service_names_and_types.cpp
@@ -81,7 +86,11 @@ add_library(rmw_fastrtps_cpp
src/rmw_wait.cpp
src/rmw_wait_set.cpp
src/serialization_format.cpp
+ src/subscription.cpp
src/type_support_common.cpp
+ src/gid__type_support.cpp
+ src/node_entities_info__type_support.cpp
+ src/participant_entities_info__type_support.cpp
)
target_link_libraries(rmw_fastrtps_cpp
fastcdr fastrtps)
@@ -91,6 +100,7 @@ ament_target_dependencies(rmw_fastrtps_cpp
"rcutils"
"rosidl_typesupport_fastrtps_c"
"rosidl_typesupport_fastrtps_cpp"
+ "rmw_dds_common"
"rmw_fastrtps_shared_cpp"
"rmw"
"rosidl_generator_c"
@@ -121,6 +131,11 @@ register_rmw_implementation(
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
+
+ ament_add_gtest(test_gid_message test/test_gid_message.cpp)
+ if(TARGET test_gid_message)
+ target_link_libraries(test_gid_message ${PROJECT_NAME})
+ endif()
endif()
ament_package(
diff --git a/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/publisher.hpp b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/publisher.hpp
new file mode 100644
index 000000000..e59b3ccd1
--- /dev/null
+++ b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/publisher.hpp
@@ -0,0 +1,36 @@
+// Copyright 2017-2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_CPP__PUBLISHER_HPP_
+#define RMW_FASTRTPS_CPP__PUBLISHER_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_cpp
+{
+
+rmw_publisher_t *
+create_publisher(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_publisher_options_t * publisher_options,
+ bool keyed,
+ bool create_publisher_listener);
+
+} // namespace rmw_fastrtps_cpp
+
+#endif // RMW_FASTRTPS_CPP__PUBLISHER_HPP_
diff --git a/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/register_node.hpp b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/register_node.hpp
new file mode 100644
index 000000000..2ab12b6b0
--- /dev/null
+++ b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/register_node.hpp
@@ -0,0 +1,41 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_CPP__REGISTER_NODE_HPP_
+#define RMW_FASTRTPS_CPP__REGISTER_NODE_HPP_
+
+#include "rmw/init.h"
+#include "rmw/types.h"
+
+namespace rmw_fastrtps_cpp
+{
+
+/// Register node in context.
+/**
+ * Function that should be called when creating a node,
+ * before using `context->impl`.
+ */
+rmw_ret_t
+register_node(rmw_context_t * context);
+
+/// Unregister node in context.
+/**
+ * Function that should be called when destroying a node.
+ */
+rmw_ret_t
+unregister_node(rmw_context_t * context);
+
+} // namespace rmw_fastrtps_cpp
+
+#endif // RMW_FASTRTPS_CPP__REGISTER_NODE_HPP_
diff --git a/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/subscription.hpp b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/subscription.hpp
new file mode 100644
index 000000000..a35d03f15
--- /dev/null
+++ b/rmw_fastrtps_cpp/include/rmw_fastrtps_cpp/subscription.hpp
@@ -0,0 +1,38 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_CPP__SUBSCRIPTION_HPP_
+#define RMW_FASTRTPS_CPP__SUBSCRIPTION_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw/subscription_options.h"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_cpp
+{
+
+rmw_subscription_t *
+create_subscription(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_subscription_options_t * subscription_options,
+ bool keyed,
+ bool create_subscription_listener);
+
+} // namespace rmw_fastrtps_cpp
+
+#endif // RMW_FASTRTPS_CPP__SUBSCRIPTION_HPP_
diff --git a/rmw_fastrtps_cpp/package.xml b/rmw_fastrtps_cpp/package.xml
index 94d7105a5..1bc9da807 100644
--- a/rmw_fastrtps_cpp/package.xml
+++ b/rmw_fastrtps_cpp/package.xml
@@ -20,6 +20,7 @@
fastrtps_cmake_module
rcutils
rmw
+ rmw_dds_common
rmw_fastrtps_shared_cpp
rosidl_generator_c
rosidl_generator_cpp
@@ -30,6 +31,7 @@
fastrtps
fastrtps_cmake_module
rcutils
+ rmw_dds_common
rmw_fastrtps_shared_cpp
rmw
rosidl_generator_c
diff --git a/rmw_fastrtps_cpp/src/get_participant.cpp b/rmw_fastrtps_cpp/src/get_participant.cpp
index c489f3d4c..120086460 100644
--- a/rmw_fastrtps_cpp/src/get_participant.cpp
+++ b/rmw_fastrtps_cpp/src/get_participant.cpp
@@ -15,6 +15,8 @@
#include "rmw_fastrtps_cpp/get_participant.hpp"
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+
#include "rmw_fastrtps_cpp/identifier.hpp"
namespace rmw_fastrtps_cpp
@@ -29,7 +31,7 @@ get_participant(rmw_node_t * node)
if (node->implementation_identifier != eprosima_fastrtps_identifier) {
return nullptr;
}
- auto impl = static_cast(node->data);
+ auto impl = static_cast(node->context->impl->participant_info);
return impl->participant;
}
diff --git a/rmw_fastrtps_cpp/src/gid__type_support.cpp b/rmw_fastrtps_cpp/src/gid__type_support.cpp
new file mode 100644
index 000000000..1e6d41ee2
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/gid__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/gid__struct.hpp"
+#include "rmw_dds_common/msg/gid__rosidl_typesupport_fastrtps_cpp.hpp"
+#include "rmw_fastrtps_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_fastrtps_cpp, rmw_dds_common, msg, Gid)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, Gid)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_cpp/src/listener_thread.cpp b/rmw_fastrtps_cpp/src/listener_thread.cpp
new file mode 100644
index 000000000..590ed07ed
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/listener_thread.cpp
@@ -0,0 +1,170 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+#include
+#include
+#include
+
+#include "rcutils/macros.h"
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/init.h"
+#include "rmw/ret_types.h"
+#include "rmw/rmw.h"
+#include "rmw/types.h"
+#include "rmw/impl/cpp/macros.hpp"
+
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/gid_utils.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+
+#include "listener_thread.hpp"
+
+using rmw_dds_common::operator<<;
+
+static
+void
+node_listener(rmw_context_t * context);
+
+rmw_ret_t
+rmw_fastrtps_cpp::run_listener_thread(rmw_context_t * context)
+{
+ auto common_context = static_cast(context->impl->common);
+ common_context->thread_is_running.store(true);
+ common_context->listener_thread_gc = rmw_create_guard_condition(context);
+ if (common_context->listener_thread_gc) {
+ try {
+ common_context->listener_thread = std::thread(node_listener, context);
+ return RMW_RET_OK;
+ } catch (const std::exception & exc) {
+ RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Failed to create std::thread: %s", exc.what());
+ } catch (...) {
+ RMW_SET_ERROR_MSG("Failed to create std::thread");
+ }
+ } else {
+ RMW_SET_ERROR_MSG("Failed to create guard condition");
+ }
+ common_context->thread_is_running.store(false);
+ if (common_context->listener_thread_gc) {
+ if (RMW_RET_OK != rmw_destroy_guard_condition(common_context->listener_thread_gc)) {
+ fprintf(
+ stderr,
+ RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__function__) ":"
+ RCUTILS_STRINGIFY(__LINE__) ": Failed to destroy guard condition");
+ }
+ }
+ return RMW_RET_ERROR;
+}
+
+rmw_ret_t
+rmw_fastrtps_cpp::join_listener_thread(rmw_context_t * context)
+{
+ auto common_context = static_cast(context->impl->common);
+ common_context->thread_is_running.exchange(false);
+ rmw_ret_t rmw_ret = rmw_trigger_guard_condition(common_context->listener_thread_gc);
+ if (RMW_RET_OK != rmw_ret) {
+ return rmw_ret;
+ }
+ try {
+ common_context->listener_thread.join();
+ } catch (const std::exception & exc) {
+ RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Failed to join std::thread: %s", exc.what());
+ return RMW_RET_ERROR;
+ } catch (...) {
+ RMW_SET_ERROR_MSG("Failed to join std::thread");
+ return RMW_RET_ERROR;
+ }
+ rmw_ret = rmw_destroy_guard_condition(common_context->listener_thread_gc);
+ if (RMW_RET_OK != rmw_ret) {
+ return rmw_ret;
+ }
+ return RMW_RET_OK;
+}
+
+#define TERMINATE(msg) \
+ do { \
+ fprintf( \
+ stderr, \
+ RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__function__) ":" \
+ RCUTILS_STRINGIFY(__LINE__) RCUTILS_STRINGIFY(msg) ": %s, terminating ...", \
+ rmw_get_error_string().str); \
+ std::terminate(); \
+ } while (0)
+
+void
+node_listener(rmw_context_t * context)
+{
+ assert(nullptr != context);
+ assert(nullptr != context->impl);
+ assert(nullptr != context->impl->common);
+ auto common_context = static_cast(context->impl->common);
+ while (common_context->thread_is_running.load()) {
+ assert(nullptr != common_context->sub);
+ assert(nullptr != common_context->sub->data);
+ void * subscriptions_buffer[] = {common_context->sub->data};
+ void * guard_conditions_buffer[] = {common_context->listener_thread_gc->data};
+ rmw_subscriptions_t subscriptions;
+ rmw_guard_conditions_t guard_conditions;
+ subscriptions.subscriber_count = 1;
+ subscriptions.subscribers = subscriptions_buffer;
+ guard_conditions.guard_condition_count = 1;
+ guard_conditions.guard_conditions = guard_conditions_buffer;
+ // number of conditions of a subscription is 2
+ rmw_wait_set_t * wait_set = rmw_create_wait_set(context, 2);
+ if (nullptr == wait_set) {
+ TERMINATE("failed to create wait set");
+ }
+ if (RMW_RET_OK != rmw_wait(
+ &subscriptions,
+ &guard_conditions,
+ nullptr,
+ nullptr,
+ nullptr,
+ wait_set,
+ nullptr))
+ {
+ TERMINATE("rmw_wait failed");
+ }
+ if (subscriptions_buffer[0]) {
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg;
+ bool taken;
+ if (RMW_RET_OK != rmw_take(
+ common_context->sub,
+ static_cast(&msg),
+ &taken,
+ nullptr))
+ {
+ TERMINATE("rmw_take failed");
+ }
+ if (taken) {
+ if (std::memcmp(
+ reinterpret_cast(common_context->gid.data),
+ reinterpret_cast(&msg.gid.data),
+ RMW_GID_STORAGE_SIZE) == 0)
+ {
+ // ignore local messages
+ continue;
+ }
+ common_context->graph_cache.update_participant_entities(msg);
+ }
+ }
+ if (RMW_RET_OK != rmw_destroy_wait_set(wait_set)) {
+ TERMINATE("failed to destroy wait set");
+ }
+ }
+}
diff --git a/rmw_fastrtps_cpp/src/listener_thread.hpp b/rmw_fastrtps_cpp/src/listener_thread.hpp
new file mode 100644
index 000000000..f6b2cab9e
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/listener_thread.hpp
@@ -0,0 +1,30 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 LISTENER_THREAD_HPP_
+#define LISTENER_THREAD_HPP_
+
+#include "rmw/init.h"
+
+namespace rmw_fastrtps_cpp
+{
+
+rmw_ret_t
+run_listener_thread(rmw_context_t * context);
+
+rmw_ret_t
+join_listener_thread(rmw_context_t * context);
+
+} // namespace rmw_fastrtps_cpp
+#endif // LISTENER_THREAD_HPP_
diff --git a/rmw_fastrtps_cpp/src/node_entities_info__type_support.cpp b/rmw_fastrtps_cpp/src/node_entities_info__type_support.cpp
new file mode 100644
index 000000000..b068dc273
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/node_entities_info__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/node_entities_info__struct.hpp"
+#include "rmw_dds_common/msg/node_entities_info__rosidl_typesupport_fastrtps_cpp.hpp"
+#include "rmw_fastrtps_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_fastrtps_cpp, rmw_dds_common, msg, NodeEntitiesInfo)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, NodeEntitiesInfo)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_cpp/src/participant_entities_info__type_support.cpp b/rmw_fastrtps_cpp/src/participant_entities_info__type_support.cpp
new file mode 100644
index 000000000..ce27b9ad6
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/participant_entities_info__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/participant_entities_info__struct.hpp"
+#include "rmw_dds_common/msg/participant_entities_info__rosidl_typesupport_fastrtps_cpp.hpp"
+#include "rmw_fastrtps_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_fastrtps_cpp, rmw_dds_common, msg, ParticipantEntitiesInfo)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, ParticipantEntitiesInfo)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_cpp/src/publisher.cpp b/rmw_fastrtps_cpp/src/publisher.cpp
new file mode 100644
index 000000000..434094454
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/publisher.cpp
@@ -0,0 +1,180 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// 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.
+
+#include
+
+#include "fastrtps/Domain.h"
+#include "fastrtps/participant/Participant.h"
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/rmw.h"
+
+#include "rmw_fastrtps_shared_cpp/create_rmw_gid.hpp"
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/custom_publisher_info.hpp"
+#include "rmw_fastrtps_shared_cpp/names.hpp"
+#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
+#include "rmw_fastrtps_shared_cpp/qos.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+
+#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/publisher.hpp"
+
+#include "type_support_common.hpp"
+
+using Domain = eprosima::fastrtps::Domain;
+using Participant = eprosima::fastrtps::Participant;
+using TopicDataType = eprosima::fastrtps::TopicDataType;
+
+rmw_publisher_t *
+rmw_fastrtps_cpp::create_publisher(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_publisher_options_t * publisher_options,
+ bool keyed,
+ bool create_publisher_listener)
+{
+ if (!participant_info) {
+ RMW_SET_ERROR_MSG("participant_info is null");
+ return nullptr;
+ }
+ if (!topic_name || strlen(topic_name) == 0) {
+ RMW_SET_ERROR_MSG("publisher topic is null or empty string");
+ return nullptr;
+ }
+ if (!qos_policies) {
+ RMW_SET_ERROR_MSG("qos_policies is null");
+ return nullptr;
+ }
+ if (!publisher_options) {
+ RMW_SET_ERROR_MSG("publisher_options is null");
+ return nullptr;
+ }
+
+ const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
+ type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_C);
+ if (!type_support) {
+ type_support = get_message_typesupport_handle(
+ type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_CPP);
+ if (!type_support) {
+ RMW_SET_ERROR_MSG("type support not from this implementation");
+ return nullptr;
+ }
+ }
+
+ CustomPublisherInfo * info = nullptr;
+ rmw_publisher_t * rmw_publisher = nullptr;
+ eprosima::fastrtps::PublisherAttributes publisherParam;
+
+ if (!is_valid_qos(*qos_policies)) {
+ return nullptr;
+ }
+
+ // Load default XML profile.
+ Domain::getDefaultPublisherAttributes(publisherParam);
+
+ // TODO(karsten1987) Verify consequences for std::unique_ptr?
+ info = new (std::nothrow) CustomPublisherInfo();
+ if (!info) {
+ RMW_SET_ERROR_MSG("failed to allocate CustomPublisherInfo");
+ return nullptr;
+ }
+
+ info->typesupport_identifier_ = type_support->typesupport_identifier;
+ info->type_support_impl_ = type_support->data;
+
+ auto callbacks = static_cast(type_support->data);
+ std::string type_name = _create_type_name(callbacks);
+ if (!Domain::getRegisteredType(participant_info->participant, type_name.c_str(),
+ reinterpret_cast(&info->type_support_)))
+ {
+ info->type_support_ = new (std::nothrow) MessageTypeSupport_cpp(callbacks);
+ if (!info->type_support_) {
+ RMW_SET_ERROR_MSG("Failed to allocate MessageTypeSupport");
+ goto fail;
+ }
+ _register_type(participant_info->participant, info->type_support_);
+ }
+
+ if (!participant_info->leave_middleware_default_qos) {
+ publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
+ publisherParam.historyMemoryPolicy =
+ eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
+ }
+
+ publisherParam.topic.topicKind =
+ keyed ? eprosima::fastrtps::rtps::WITH_KEY : eprosima::fastrtps::rtps::NO_KEY;
+ publisherParam.topic.topicDataType = type_name;
+ publisherParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
+
+ if (!get_datawriter_qos(*qos_policies, publisherParam)) {
+ RMW_SET_ERROR_MSG("failed to get datawriter qos");
+ goto fail;
+ }
+
+ info->listener_ = nullptr;
+ if (create_publisher_listener) {
+ info->listener_ = new (std::nothrow) PubListener(info);
+ if (!info->listener_) {
+ RMW_SET_ERROR_MSG("create_publisher() could not create publisher listener");
+ goto fail;
+ }
+ }
+
+ info->publisher_ = Domain::createPublisher(
+ participant_info->participant,
+ publisherParam,
+ info->listener_);
+ if (!info->publisher_) {
+ RMW_SET_ERROR_MSG("create_publisher() could not create publisher");
+ goto fail;
+ }
+
+ info->publisher_gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->publisher_->getGuid());
+
+ rmw_publisher = rmw_publisher_allocate();
+ if (!rmw_publisher) {
+ RMW_SET_ERROR_MSG("failed to allocate publisher");
+ goto fail;
+ }
+ rmw_publisher->implementation_identifier = eprosima_fastrtps_identifier;
+ rmw_publisher->data = info;
+ rmw_publisher->topic_name = reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
+
+ if (!rmw_publisher->topic_name) {
+ RMW_SET_ERROR_MSG("failed to allocate memory for publisher topic name");
+ goto fail;
+ }
+
+ memcpy(const_cast(rmw_publisher->topic_name), topic_name, strlen(topic_name) + 1);
+
+ rmw_publisher->options = *publisher_options;
+
+ return rmw_publisher;
+
+fail:
+ if (info) {
+ delete info->type_support_;
+ delete info->listener_;
+ delete info;
+ }
+ rmw_publisher_free(rmw_publisher);
+
+ return nullptr;
+}
diff --git a/rmw_fastrtps_cpp/src/register_node.cpp b/rmw_fastrtps_cpp/src/register_node.cpp
new file mode 100644
index 000000000..89a22b096
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/register_node.cpp
@@ -0,0 +1,217 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include "rmw_fastrtps_cpp/register_node.hpp"
+
+#include
+#include
+
+#include "rmw/error_handling.h"
+#include "rmw/init.h"
+#include "rmw/qos_profiles.h"
+
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/publisher.hpp"
+#include "rmw_fastrtps_cpp/subscription.hpp"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/participant.hpp"
+#include "rmw_fastrtps_shared_cpp/publisher.hpp"
+#include "rmw_fastrtps_shared_cpp/subscription.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+
+#include "listener_thread.hpp"
+
+using rmw_dds_common::msg::ParticipantEntitiesInfo;
+
+static
+rmw_ret_t
+init_context_impl(rmw_context_t * context)
+{
+ rmw_publisher_options_t publisher_options = rmw_get_default_publisher_options();
+ rmw_subscription_options_t subscription_options = rmw_get_default_subscription_options();
+
+ // This is currently not implemented in fastrtps
+ subscription_options.ignore_local_publications = true;
+
+ std::unique_ptr common_context(
+ new(std::nothrow) rmw_dds_common::Context());
+ if (!common_context) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ std::unique_ptr>
+ participant_info(
+ rmw_fastrtps_shared_cpp::create_participant(
+ eprosima_fastrtps_identifier,
+ context->options.domain_id,
+ &context->options.security_options,
+ (context->options.localhost_only == RMW_LOCALHOST_ONLY_ENABLED) ? 1 : 0,
+ common_context.get()),
+ [&](CustomParticipantInfo * participant_info) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_participant(participant_info)) {
+ fprintf(
+ stderr, "Failed to destroy participant after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!participant_info) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ rmw_qos_profile_t qos = rmw_qos_profile_default;
+
+ qos.avoid_ros_namespace_conventions = false; // Change this to true after testing
+ qos.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
+ qos.depth = 1;
+ qos.durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
+ qos.reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
+
+ std::unique_ptr>
+ publisher(
+ rmw_fastrtps_cpp::create_publisher(
+ participant_info.get(),
+ rosidl_typesupport_cpp::get_message_type_support_handle(),
+ "_participant_info",
+ &qos,
+ &publisher_options,
+ false, // our fastrtps typesupport doesn't support keyed topics
+ true),
+ [&](rmw_publisher_t * pub) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_publisher(
+ eprosima_fastrtps_identifier,
+ participant_info.get(),
+ pub))
+ {
+ fprintf(
+ stderr, "Failed to destroy publisher after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!publisher) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ // If we would have support for keyed topics, this could be KEEP_LAST and depth 1.
+ qos.history = RMW_QOS_POLICY_HISTORY_KEEP_ALL;
+ std::unique_ptr>
+ subscription(
+ rmw_fastrtps_cpp::create_subscription(
+ participant_info.get(),
+ rosidl_typesupport_cpp::get_message_type_support_handle(),
+ "_participant_info",
+ &qos,
+ &subscription_options,
+ false, // our fastrtps typesupport doesn't support keyed topics
+ true),
+ [&](rmw_subscription_t * sub) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_subscription(
+ eprosima_fastrtps_identifier,
+ participant_info.get(),
+ sub))
+ {
+ fprintf(
+ stderr, "Failed to destroy subscription after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!subscription) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ common_context->gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, participant_info->participant->getGuid());
+ common_context->pub = publisher.get();
+ common_context->sub = subscription.get();
+
+ context->impl->common = common_context.get();
+ context->impl->participant_info = participant_info.get();
+
+ if (RMW_RET_OK != rmw_fastrtps_cpp::run_listener_thread(context)) {
+ return RMW_RET_ERROR;
+ }
+ common_context->graph_cache.add_participant(common_context->gid);
+
+ publisher.release();
+ subscription.release();
+ common_context.release();
+ participant_info.release();
+ return RMW_RET_OK;
+}
+
+rmw_ret_t
+rmw_fastrtps_cpp::register_node(rmw_context_t * context)
+{
+ assert(context);
+ assert(context->impl);
+
+ std::lock_guard guard(context->impl->mutex);
+
+ if (!context->impl->count) {
+ rmw_ret_t ret = init_context_impl(context);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ }
+ context->impl->count++;
+ return RMW_RET_OK;
+}
+
+rmw_ret_t
+rmw_fastrtps_cpp::unregister_node(rmw_context_t * context)
+{
+ assert(context);
+ assert(context->impl);
+
+ std::lock_guard guard(context->impl->mutex);
+ if (0u == --context->impl->count) {
+ rmw_ret_t ret;
+ ret = rmw_fastrtps_cpp::join_listener_thread(context);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+
+ auto common_context = static_cast(context->impl->common);
+ auto participant_info = static_cast(context->impl->participant_info);
+
+ common_context->graph_cache.remove_participant(common_context->gid);
+ ret = rmw_fastrtps_shared_cpp::destroy_subscription(
+ eprosima_fastrtps_identifier,
+ participant_info,
+ common_context->sub);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ ret = rmw_fastrtps_shared_cpp::destroy_publisher(
+ eprosima_fastrtps_identifier,
+ participant_info,
+ common_context->pub);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ ret = rmw_fastrtps_shared_cpp::destroy_participant(participant_info);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ delete common_context;
+ context->impl->common = nullptr;
+ context->impl->participant_info = nullptr;
+ }
+ return RMW_RET_OK;
+}
diff --git a/rmw_fastrtps_cpp/src/rmw_client.cpp b/rmw_fastrtps_cpp/src/rmw_client.cpp
index ec81fa301..07a34dfbf 100644
--- a/rmw_fastrtps_cpp/src/rmw_client.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_client.cpp
@@ -25,6 +25,7 @@
#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_cpp/identifier.hpp"
@@ -62,13 +63,15 @@ rmw_create_client(
return nullptr;
}
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
+ auto common_context = static_cast(node->context->impl->common);
+ auto participant_info =
+ static_cast(node->context->impl->participant_info);
+ if (!participant_info) {
+ RMW_SET_ERROR_MSG("participant info is null");
return nullptr;
}
- Participant * participant = impl->participant;
+ Participant * participant = participant_info->participant;
if (!participant) {
RMW_SET_ERROR_MSG("participant handle is null");
return nullptr;
@@ -126,7 +129,7 @@ rmw_create_client(
_register_type(participant, info->response_type_support_);
}
- if (!impl->leave_middleware_default_qos) {
+ if (!participant_info->leave_middleware_default_qos) {
subscriberParam.historyMemoryPolicy =
eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
}
@@ -136,7 +139,7 @@ rmw_create_client(
subscriberParam.topic.topicName = _create_topic_name(
qos_policies, ros_service_response_prefix, service_name, "Reply");
- if (!impl->leave_middleware_default_qos) {
+ if (!participant_info->leave_middleware_default_qos) {
publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
publisherParam.historyMemoryPolicy =
eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
@@ -202,15 +205,54 @@ rmw_create_client(
}
memcpy(const_cast(rmw_client->service_name), service_name, strlen(service_name) + 1);
+ {
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_publisher_->getGuid());
+ common_context->graph_cache.associate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
+ gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_subscriber_->getGuid());
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_reader(
+ gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ goto fail;
+ }
+ }
+
return rmw_client;
fail:
if (info != nullptr) {
if (info->request_publisher_ != nullptr) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_publisher_->getGuid());
+ common_context->graph_cache.dissociate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removePublisher(info->request_publisher_);
}
if (info->response_subscriber_ != nullptr) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_subscriber_->getGuid());
+ common_context->graph_cache.dissociate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removeSubscriber(info->response_subscriber_);
}
@@ -222,7 +264,7 @@ rmw_create_client(
delete info->listener_;
}
- if (impl) {
+ if (participant_info) {
if (info->request_type_support_ != nullptr) {
rmw_fastrtps_shared_cpp::_unregister_type(participant, info->request_type_support_);
}
diff --git a/rmw_fastrtps_cpp/src/rmw_init.cpp b/rmw_fastrtps_cpp/src/rmw_init.cpp
index 4334babea..36ab04176 100644
--- a/rmw_fastrtps_cpp/src/rmw_init.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_init.cpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,10 +13,33 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include
+
+#include "rcutils/strdup.h"
+#include "rcutils/types.h"
+
+#include "rmw/init.h"
#include "rmw/impl/cpp/macros.hpp"
+#include "rmw/init_options.h"
+#include "rmw/publisher_options.h"
#include "rmw/rmw.h"
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/participant.hpp"
+#include "rmw_fastrtps_shared_cpp/publisher.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+#include "rmw_fastrtps_shared_cpp/subscription.hpp"
+
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+
#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/publisher.hpp"
+#include "rmw_fastrtps_cpp/subscription.hpp"
+
+#include "listener_thread.hpp"
extern "C"
{
@@ -32,6 +56,17 @@ rmw_init_options_init(rmw_init_options_t * init_options, rcutils_allocator_t all
init_options->implementation_identifier = eprosima_fastrtps_identifier;
init_options->allocator = allocator;
init_options->impl = nullptr;
+ init_options->name = rcutils_strdup("", allocator);
+ if (!init_options->name) {
+ RMW_SET_ERROR_MSG("failed to copy context name");
+ return RMW_RET_BAD_ALLOC;
+ }
+ init_options->namespace_ = rcutils_strdup("", allocator);
+ if (!init_options->namespace_) {
+ allocator.deallocate(init_options->name, allocator.state);
+ RMW_SET_ERROR_MSG("failed to copy context namespace");
+ return RMW_RET_BAD_ALLOC;
+ }
return RMW_RET_OK;
}
@@ -49,27 +84,62 @@ rmw_init_options_copy(const rmw_init_options_t * src, rmw_init_options_t * dst)
RMW_SET_ERROR_MSG("expected zero-initialized dst");
return RMW_RET_INVALID_ARGUMENT;
}
+ const rcutils_allocator_t * allocator = &src->allocator;
+ rmw_ret_t ret = RMW_RET_OK;
+
*dst = *src;
- return RMW_RET_OK;
+ dst->name = NULL;
+ dst->namespace_ = NULL;
+ dst->security_options = rmw_get_zero_initialized_security_options();
+
+ dst->name = rcutils_strdup(src->name, *allocator);
+ if (!dst->name) {
+ ret = RMW_RET_BAD_ALLOC;
+ goto fail;
+ }
+ dst->namespace_ = rcutils_strdup(src->namespace_, *allocator);
+ if (!dst->namespace_) {
+ ret = RMW_RET_BAD_ALLOC;
+ goto fail;
+ }
+ return rmw_security_options_copy(&src->security_options, allocator, &dst->security_options);
+fail:
+ allocator->deallocate(dst->name, allocator->state);
+ allocator->deallocate(dst->namespace_, allocator->state);
+ return ret;
}
rmw_ret_t
rmw_init_options_fini(rmw_init_options_t * init_options)
{
RMW_CHECK_ARGUMENT_FOR_NULL(init_options, RMW_RET_INVALID_ARGUMENT);
- RCUTILS_CHECK_ALLOCATOR(&(init_options->allocator), return RMW_RET_INVALID_ARGUMENT);
+ rcutils_allocator_t & allocator = init_options->allocator;
+ RCUTILS_CHECK_ALLOCATOR(&allocator, return RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
init_options,
init_options->implementation_identifier,
eprosima_fastrtps_identifier,
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
+ allocator.deallocate(init_options->name, allocator.state);
+ allocator.deallocate(init_options->namespace_, allocator.state);
+ rmw_security_options_fini(&init_options->security_options, &allocator);
*init_options = rmw_get_zero_initialized_init_options();
return RMW_RET_OK;
}
+using rmw_dds_common::msg::ParticipantEntitiesInfo;
+
rmw_ret_t
rmw_init(const rmw_init_options_t * options, rmw_context_t * context)
{
+ std::unique_ptr clean_when_fail(
+ context,
+ [](rmw_context_t * context)
+ {
+ *context = rmw_get_zero_initialized_context();
+ });
+ rmw_ret_t ret = RMW_RET_OK;
+
RCUTILS_CHECK_ARGUMENT_FOR_NULL(options, RMW_RET_INVALID_ARGUMENT);
RCUTILS_CHECK_ARGUMENT_FOR_NULL(context, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
@@ -79,7 +149,24 @@ rmw_init(const rmw_init_options_t * options, rmw_context_t * context)
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
context->instance_id = options->instance_id;
context->implementation_identifier = eprosima_fastrtps_identifier;
- context->impl = nullptr;
+
+ std::unique_ptr context_impl(new rmw_context_impl_t());
+ if (!context_impl) {
+ RMW_SET_ERROR_MSG("failed to allocate context impl");
+ return RMW_RET_BAD_ALLOC;
+ }
+ context->options = rmw_get_zero_initialized_init_options();
+ ret = rmw_init_options_copy(options, &context->options);
+ if (RMW_RET_OK != ret) {
+ if (RMW_RET_OK != rmw_init_options_fini(&context->options)) {
+ fprintf(
+ stderr,
+ "Failed to destroy init options after ':" RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ return ret;
+ }
+ context->impl = context_impl.release();
+ clean_when_fail.release();
return RMW_RET_OK;
}
@@ -106,8 +193,7 @@ rmw_context_fini(rmw_context_t * context)
context->implementation_identifier,
eprosima_fastrtps_identifier,
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
- // context impl is explicitly supposed to be nullptr for now, see rmw_init's code
- // RCUTILS_CHECK_ARGUMENT_FOR_NULL(context->impl, RMW_RET_INVALID_ARGUMENT);
+ delete context->impl;
*context = rmw_get_zero_initialized_context();
return RMW_RET_OK;
}
diff --git a/rmw_fastrtps_cpp/src/rmw_node.cpp b/rmw_fastrtps_cpp/src/rmw_node.cpp
index 5d7492d06..be8dc1236 100644
--- a/rmw_fastrtps_cpp/src/rmw_node.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_node.cpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,11 +24,13 @@
#include "rmw/allocators.h"
#include "rmw/error_handling.h"
#include "rmw/impl/cpp/macros.hpp"
+#include "rmw/ret_types.h"
#include "rmw/rmw.h"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/register_node.hpp"
extern "C"
{
@@ -37,25 +40,37 @@ rmw_create_node(
const char * name,
const char * namespace_,
size_t domain_id,
- const rmw_node_security_options_t * security_options,
+ const rmw_security_options_t * security_options,
bool localhost_only)
{
+ (void)domain_id;
+ (void)security_options;
+ (void)localhost_only;
RCUTILS_CHECK_ARGUMENT_FOR_NULL(context, NULL);
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
init context,
context->implementation_identifier,
eprosima_fastrtps_identifier,
// TODO(wjwwood): replace this with RMW_RET_INCORRECT_RMW_IMPLEMENTATION when refactored
- return NULL);
+ return nullptr);
+
+ if (RMW_RET_OK != rmw_fastrtps_cpp::register_node(context)) {
+ return nullptr;
+ }
+
return rmw_fastrtps_shared_cpp::__rmw_create_node(
- eprosima_fastrtps_identifier, name, namespace_, domain_id, security_options, localhost_only);
+ context, eprosima_fastrtps_identifier, name, namespace_);
}
rmw_ret_t
rmw_destroy_node(rmw_node_t * node)
{
- return rmw_fastrtps_shared_cpp::__rmw_destroy_node(
+ rmw_ret_t ret = rmw_fastrtps_shared_cpp::__rmw_destroy_node(
eprosima_fastrtps_identifier, node);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ return rmw_fastrtps_cpp::unregister_node(node->context);
}
rmw_ret_t
diff --git a/rmw_fastrtps_cpp/src/rmw_publisher.cpp b/rmw_fastrtps_cpp/src/rmw_publisher.cpp
index dba510c25..45557ec51 100644
--- a/rmw_fastrtps_cpp/src/rmw_publisher.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_publisher.cpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,18 +21,14 @@
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
#include "rmw_fastrtps_shared_cpp/custom_publisher_info.hpp"
-#include "rmw_fastrtps_shared_cpp/names.hpp"
-#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
-#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/publisher.hpp"
-#include "./type_support_common.hpp"
-
-using Domain = eprosima::fastrtps::Domain;
-using Participant = eprosima::fastrtps::Participant;
-using TopicDataType = eprosima::fastrtps::TopicDataType;
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
extern "C"
{
@@ -76,165 +73,40 @@ rmw_create_publisher(
return nullptr;
}
- if (!topic_name || strlen(topic_name) == 0) {
- RMW_SET_ERROR_MSG("publisher topic is null or empty string");
- return nullptr;
- }
-
- if (!qos_policies) {
- RMW_SET_ERROR_MSG("qos_policies is null");
- return nullptr;
- }
-
- if (!publisher_options) {
- RMW_SET_ERROR_MSG("publisher_options is null");
- return nullptr;
- }
+ rmw_publisher_t * publisher = rmw_fastrtps_cpp::create_publisher(
+ static_cast(node->context->impl->participant_info),
+ type_supports,
+ topic_name,
+ qos_policies,
+ publisher_options,
+ false,
+ true);
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
+ if (!publisher) {
return nullptr;
}
- Participant * participant = impl->participant;
- if (!participant) {
- RMW_SET_ERROR_MSG("participant handle is null");
- return nullptr;
- }
+ auto common_context = static_cast(node->context->impl->common);
- const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
- type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_C);
- if (!type_support) {
- type_support = get_message_typesupport_handle(
- type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_CPP);
- if (!type_support) {
- RMW_SET_ERROR_MSG("type support not from this implementation");
- return nullptr;
- }
- }
-
- CustomPublisherInfo * info = nullptr;
- rmw_publisher_t * rmw_publisher = nullptr;
- eprosima::fastrtps::PublisherAttributes publisherParam;
- const eprosima::fastrtps::rtps::GUID_t * guid = nullptr;
-
- if (!is_valid_qos(*qos_policies)) {
- return nullptr;
- }
-
- // Load default XML profile.
- Domain::getDefaultPublisherAttributes(publisherParam);
-
- // TODO(karsten1987) Verify consequences for std::unique_ptr?
- info = new (std::nothrow) CustomPublisherInfo();
- if (!info) {
- RMW_SET_ERROR_MSG("failed to allocate CustomPublisherInfo");
- return nullptr;
- }
-
- info->typesupport_identifier_ = type_support->typesupport_identifier;
- info->type_support_impl_ = type_support->data;
-
- auto callbacks = static_cast(type_support->data);
- std::string type_name = _create_type_name(callbacks);
- if (!Domain::getRegisteredType(participant, type_name.c_str(),
- reinterpret_cast(&info->type_support_)))
+ auto info = static_cast(publisher->data);
{
- info->type_support_ = new (std::nothrow) MessageTypeSupport_cpp(callbacks);
- if (!info->type_support_) {
- RMW_SET_ERROR_MSG("Failed to allocate MessageTypeSupport");
- goto fail;
- }
- _register_type(participant, info->type_support_);
- }
-
- if (!impl->leave_middleware_default_qos) {
- publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
- publisherParam.historyMemoryPolicy =
- eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
- }
-
- publisherParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
- publisherParam.topic.topicDataType = type_name;
- publisherParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
-
- // 1 Heartbeat every 10ms
- // publisherParam.times.heartbeatPeriod.seconds = 0;
- // publisherParam.times.heartbeatPeriod.fraction = 42949673;
-
- // 300000 bytes each 10ms
- // ThroughputControllerDescriptor throughputController{3000000, 10};
- // publisherParam.throughputController = throughputController;
-
- if (!get_datawriter_qos(*qos_policies, publisherParam)) {
- RMW_SET_ERROR_MSG("failed to get datawriter qos");
- goto fail;
- }
-
- info->listener_ = new (std::nothrow) PubListener(info);
- if (!info->listener_) {
- RMW_SET_ERROR_MSG("create_publisher() could not create publisher listener");
- goto fail;
- }
-
- info->publisher_ = Domain::createPublisher(participant, publisherParam, info->listener_);
- if (!info->publisher_) {
- RMW_SET_ERROR_MSG("create_publisher() could not create publisher");
- goto fail;
- }
-
- info->publisher_gid.implementation_identifier = eprosima_fastrtps_identifier;
- static_assert(
- sizeof(eprosima::fastrtps::rtps::GUID_t) <= RMW_GID_STORAGE_SIZE,
- "RMW_GID_STORAGE_SIZE insufficient to store the rmw_fastrtps_cpp GID implementation."
- );
-
- memset(info->publisher_gid.data, 0, RMW_GID_STORAGE_SIZE);
- guid = &info->publisher_->getGuid();
- if (!guid) {
- RMW_SET_ERROR_MSG("no guid found for publisher");
- goto fail;
- }
- memcpy(info->publisher_gid.data, guid, sizeof(eprosima::fastrtps::rtps::GUID_t));
-
- rmw_publisher = rmw_publisher_allocate();
- if (!rmw_publisher) {
- RMW_SET_ERROR_MSG("failed to allocate publisher");
- goto fail;
- }
- rmw_publisher->can_loan_messages = false;
- rmw_publisher->implementation_identifier = eprosima_fastrtps_identifier;
- rmw_publisher->data = info;
- rmw_publisher->topic_name = reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
-
- if (!rmw_publisher->topic_name) {
- RMW_SET_ERROR_MSG("failed to allocate memory for publisher topic name");
- goto fail;
- }
-
- memcpy(const_cast(rmw_publisher->topic_name), topic_name, strlen(topic_name) + 1);
-
- rmw_publisher->options = *publisher_options;
-
- return rmw_publisher;
-
-fail:
- if (info) {
- if (info->type_support_ != nullptr) {
- delete info->type_support_;
- }
- if (info->listener_ != nullptr) {
- delete info->listener_;
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_writer(
+ info->publisher_gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ rmw_fastrtps_shared_cpp::__rmw_destroy_publisher(
+ eprosima_fastrtps_identifier, node, publisher);
+ return nullptr;
}
- delete info;
}
-
- if (rmw_publisher) {
- rmw_publisher_free(rmw_publisher);
- }
-
- return nullptr;
+ return publisher;
}
rmw_ret_t
diff --git a/rmw_fastrtps_cpp/src/rmw_security.cpp b/rmw_fastrtps_cpp/src/rmw_security.cpp
new file mode 100644
index 000000000..6774438dd
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/rmw_security.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include "rmw/security.h"
+
+extern "C"
+{
+bool
+rmw_use_node_name_in_security_directory_lookup()
+{
+ return false;
+}
+} // extern "C"
diff --git a/rmw_fastrtps_cpp/src/rmw_service.cpp b/rmw_fastrtps_cpp/src/rmw_service.cpp
index 1226c2cef..923e90995 100644
--- a/rmw_fastrtps_cpp/src/rmw_service.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_service.cpp
@@ -36,10 +36,11 @@
#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_cpp/identifier.hpp"
-#include "./type_support_common.hpp"
+#include "type_support_common.hpp"
using Domain = eprosima::fastrtps::Domain;
using Participant = eprosima::fastrtps::Participant;
@@ -74,7 +75,9 @@ rmw_create_service(
return nullptr;
}
- const CustomParticipantInfo * impl = static_cast(node->data);
+ const CustomParticipantInfo * impl =
+ static_cast(node->context->impl->participant_info);
+ auto common_context = static_cast(node->context->impl->common);
if (!impl) {
RMW_SET_ERROR_MSG("node impl is null");
return nullptr;
@@ -140,7 +143,6 @@ rmw_create_service(
subscriberParam.historyMemoryPolicy =
eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
}
-
subscriberParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
subscriberParam.topic.topicDataType = request_type_name;
subscriberParam.topic.topicName = _create_topic_name(
@@ -208,16 +210,55 @@ rmw_create_service(
}
memcpy(const_cast(rmw_service->service_name), service_name, strlen(service_name) + 1);
+ {
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_subscriber_->getGuid());
+ common_context->graph_cache.associate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
+ gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_publisher_->getGuid());
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_writer(
+ gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ goto fail;
+ }
+ }
+
return rmw_service;
fail:
if (info) {
if (info->response_publisher_) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_publisher_->getGuid());
+ common_context->graph_cache.dissociate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removePublisher(info->response_publisher_);
}
if (info->request_subscriber_) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_subscriber_->getGuid());
+ common_context->graph_cache.dissociate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removeSubscriber(info->request_subscriber_);
}
diff --git a/rmw_fastrtps_cpp/src/rmw_subscription.cpp b/rmw_fastrtps_cpp/src/rmw_subscription.cpp
index 17ec03807..3a1d884ee 100644
--- a/rmw_fastrtps_cpp/src/rmw_subscription.cpp
+++ b/rmw_fastrtps_cpp/src/rmw_subscription.cpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,8 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include
#include
+#include
#include "rmw/allocators.h"
#include "rmw/error_handling.h"
@@ -21,21 +22,11 @@
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
#include "rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp"
-#include "rmw_fastrtps_shared_cpp/names.hpp"
-#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
-#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
-
-#include "fastrtps/participant/Participant.h"
-#include "fastrtps/subscriber/Subscriber.h"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_cpp/identifier.hpp"
-
-#include "./type_support_common.hpp"
-
-using Domain = eprosima::fastrtps::Domain;
-using Participant = eprosima::fastrtps::Participant;
-using TopicDataType = eprosima::fastrtps::TopicDataType;
+#include "rmw_fastrtps_cpp/subscription.hpp"
extern "C"
{
@@ -80,136 +71,40 @@ rmw_create_subscription(
return nullptr;
}
- if (!topic_name || strlen(topic_name) == 0) {
- RMW_SET_ERROR_MSG("subscription topic is null or empty string");
- return nullptr;
- }
-
- if (!qos_policies) {
- RMW_SET_ERROR_MSG("qos_profile is null");
- return nullptr;
- }
-
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
- return nullptr;
- }
-
- Participant * participant = impl->participant;
- if (!participant) {
- RMW_SET_ERROR_MSG("participant handle is null");
- return nullptr;
- }
-
- const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
- type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_C);
- if (!type_support) {
- type_support = get_message_typesupport_handle(
- type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_CPP);
- if (!type_support) {
- RMW_SET_ERROR_MSG("type support not from this implementation");
- return nullptr;
- }
- }
-
- if (!is_valid_qos(*qos_policies)) {
- return nullptr;
- }
-
- CustomSubscriberInfo * info = nullptr;
- rmw_subscription_t * rmw_subscription = nullptr;
- eprosima::fastrtps::SubscriberAttributes subscriberParam;
-
- // Load default XML profile.
- Domain::getDefaultSubscriberAttributes(subscriberParam);
-
- info = new (std::nothrow) CustomSubscriberInfo();
- if (!info) {
- RMW_SET_ERROR_MSG("failed to allocate CustomSubscriberInfo");
+ auto participant_info =
+ static_cast(node->context->impl->participant_info);
+ rmw_subscription_t * subscription = rmw_fastrtps_cpp::create_subscription(
+ participant_info,
+ type_supports,
+ topic_name,
+ qos_policies,
+ subscription_options,
+ false, // use no keyed topic
+ true); // create subscription listener
+ if (!subscription) {
return nullptr;
}
- info->typesupport_identifier_ = type_support->typesupport_identifier;
- info->type_support_impl_ = type_support->data;
-
- auto callbacks = static_cast(type_support->data);
- std::string type_name = _create_type_name(callbacks);
- if (!Domain::getRegisteredType(participant, type_name.c_str(),
- reinterpret_cast(&info->type_support_)))
+ auto common_context = static_cast(node->context->impl->common);
+ auto info = static_cast(subscription->data);
{
- info->type_support_ = new (std::nothrow) MessageTypeSupport_cpp(callbacks);
- if (!info->type_support_) {
- RMW_SET_ERROR_MSG("failed to allocate MessageTypeSupport_cpp");
- goto fail;
- }
- _register_type(participant, info->type_support_);
- }
-
- if (!impl->leave_middleware_default_qos) {
- subscriberParam.historyMemoryPolicy =
- eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
- }
-
- subscriberParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
- subscriberParam.topic.topicDataType = type_name;
- subscriberParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
-
- if (!get_datareader_qos(*qos_policies, subscriberParam)) {
- RMW_SET_ERROR_MSG("failed to get datareader qos");
- goto fail;
- }
-
- info->listener_ = new (std::nothrow) SubListener(info);
- if (!info->listener_) {
- RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber listener");
- goto fail;
- }
-
- info->subscriber_ = Domain::createSubscriber(participant, subscriberParam, info->listener_);
- if (!info->subscriber_) {
- RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber");
- goto fail;
- }
-
- rmw_subscription = rmw_subscription_allocate();
- if (!rmw_subscription) {
- RMW_SET_ERROR_MSG("failed to allocate subscription");
- goto fail;
- }
- rmw_subscription->implementation_identifier = eprosima_fastrtps_identifier;
- rmw_subscription->data = info;
- rmw_subscription->topic_name =
- reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
-
- if (!rmw_subscription->topic_name) {
- RMW_SET_ERROR_MSG("failed to allocate memory for subscription topic name");
- goto fail;
- }
-
- memcpy(const_cast(rmw_subscription->topic_name), topic_name, strlen(topic_name) + 1);
-
- rmw_subscription->options = *subscription_options;
- rmw_subscription->can_loan_messages = false;
- return rmw_subscription;
-
-fail:
-
- if (info != nullptr) {
- if (info->type_support_ != nullptr) {
- delete info->type_support_;
- }
- if (info->listener_ != nullptr) {
- delete info->listener_;
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_reader(
+ info->subscription_gid_, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ rmw_fastrtps_shared_cpp::__rmw_destroy_subscription(
+ eprosima_fastrtps_identifier, node, subscription);
+ return nullptr;
}
- delete info;
}
-
- if (rmw_subscription) {
- rmw_subscription_free(rmw_subscription);
- }
-
- return nullptr;
+ return subscription;
}
rmw_ret_t
diff --git a/rmw_fastrtps_cpp/src/subscription.cpp b/rmw_fastrtps_cpp/src/subscription.cpp
new file mode 100644
index 000000000..b886261f9
--- /dev/null
+++ b/rmw_fastrtps_cpp/src/subscription.cpp
@@ -0,0 +1,171 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+#include
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/rmw.h"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp"
+#include "rmw_fastrtps_shared_cpp/names.hpp"
+#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
+#include "rmw_fastrtps_shared_cpp/qos.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+
+#include "fastrtps/participant/Participant.h"
+#include "fastrtps/subscriber/Subscriber.h"
+
+#include "rmw_fastrtps_cpp/identifier.hpp"
+#include "rmw_fastrtps_cpp/subscription.hpp"
+
+#include "type_support_common.hpp"
+
+using Domain = eprosima::fastrtps::Domain;
+using Participant = eprosima::fastrtps::Participant;
+using TopicDataType = eprosima::fastrtps::TopicDataType;
+
+
+namespace rmw_fastrtps_cpp
+{
+
+rmw_subscription_t *
+create_subscription(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_subscription_options_t * subscription_options,
+ bool keyed,
+ bool create_subscription_listener)
+{
+ if (!topic_name || strlen(topic_name) == 0) {
+ RMW_SET_ERROR_MSG("subscription topic is null or empty string");
+ return nullptr;
+ }
+ if (!qos_policies) {
+ RMW_SET_ERROR_MSG("qos_policies is null");
+ return nullptr;
+ }
+ if (!subscription_options) {
+ RMW_SET_ERROR_MSG("subscription_options is null");
+ return nullptr;
+ }
+ if (!participant_info) {
+ RMW_SET_ERROR_MSG("participant_info is null");
+ return nullptr;
+ }
+ Participant * participant = participant_info->participant;
+ if (!participant) {
+ RMW_SET_ERROR_MSG("participant handle is null");
+ return nullptr;
+ }
+ const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
+ type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_C);
+ if (!type_support) {
+ type_support = get_message_typesupport_handle(
+ type_supports, RMW_FASTRTPS_CPP_TYPESUPPORT_CPP);
+ if (!type_support) {
+ RMW_SET_ERROR_MSG("type support not from this implementation");
+ return nullptr;
+ }
+ }
+ if (!is_valid_qos(*qos_policies)) {
+ return nullptr;
+ }
+ CustomSubscriberInfo * info = nullptr;
+ rmw_subscription_t * rmw_subscription = nullptr;
+ eprosima::fastrtps::SubscriberAttributes subscriberParam;
+
+ // Load default XML profile.
+ Domain::getDefaultSubscriberAttributes(subscriberParam);
+ info = new (std::nothrow) CustomSubscriberInfo();
+ if (!info) {
+ RMW_SET_ERROR_MSG("failed to allocate CustomSubscriberInfo");
+ return nullptr;
+ }
+ info->typesupport_identifier_ = type_support->typesupport_identifier;
+ info->type_support_impl_ = type_support->data;
+
+ auto callbacks = static_cast(type_support->data);
+ std::string type_name = _create_type_name(callbacks);
+ if (!Domain::getRegisteredType(participant, type_name.c_str(),
+ reinterpret_cast(&info->type_support_)))
+ {
+ info->type_support_ = new (std::nothrow) MessageTypeSupport_cpp(callbacks);
+ if (!info->type_support_) {
+ RMW_SET_ERROR_MSG("failed to allocate MessageTypeSupport_cpp");
+ goto fail;
+ }
+ _register_type(participant, info->type_support_);
+ }
+ if (!participant_info->leave_middleware_default_qos) {
+ subscriberParam.historyMemoryPolicy =
+ eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
+ }
+
+ subscriberParam.topic.topicKind =
+ keyed ? eprosima::fastrtps::rtps::WITH_KEY : eprosima::fastrtps::rtps::NO_KEY;
+ subscriberParam.topic.topicDataType = type_name;
+ subscriberParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
+
+ if (!get_datareader_qos(*qos_policies, subscriberParam)) {
+ RMW_SET_ERROR_MSG("failed to get datareader qos");
+ goto fail;
+ }
+ info->listener_ = nullptr;
+ if (create_subscription_listener) {
+ info->listener_ = new (std::nothrow) SubListener(info);
+ if (!info->listener_) {
+ RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber listener");
+ goto fail;
+ }
+ }
+ info->subscriber_ = Domain::createSubscriber(participant, subscriberParam, info->listener_);
+ if (!info->subscriber_) {
+ RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber");
+ goto fail;
+ }
+ info->subscription_gid_ = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->subscriber_->getGuid());
+ rmw_subscription = rmw_subscription_allocate();
+ if (!rmw_subscription) {
+ RMW_SET_ERROR_MSG("failed to allocate subscription");
+ goto fail;
+ }
+ rmw_subscription->implementation_identifier = eprosima_fastrtps_identifier;
+ rmw_subscription->data = info;
+ rmw_subscription->topic_name =
+ reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
+ if (!rmw_subscription->topic_name) {
+ RMW_SET_ERROR_MSG("failed to allocate memory for subscription topic name");
+ goto fail;
+ }
+ memcpy(const_cast(rmw_subscription->topic_name), topic_name, strlen(topic_name) + 1);
+
+ rmw_subscription->options = *subscription_options;
+ return rmw_subscription;
+
+fail:
+ if (info != nullptr) {
+ delete info->type_support_;
+ delete info->listener_;
+ delete info;
+ }
+ rmw_subscription_free(rmw_subscription);
+ return nullptr;
+}
+} // namespace rmw_fastrtps_cpp
diff --git a/rmw_fastrtps_cpp/test/test_gid_message.cpp b/rmw_fastrtps_cpp/test/test_gid_message.cpp
new file mode 100644
index 000000000..f6f30c53a
--- /dev/null
+++ b/rmw_fastrtps_cpp/test/test_gid_message.cpp
@@ -0,0 +1,42 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+#include
+
+#include "rmw_dds_common/msg/gid.hpp"
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rosidl_typesupport_fastrtps_cpp/identifier.hpp"
+
+using rmw_dds_common::msg::Gid;
+
+
+TEST(Test_gid, constructor_destructor) {
+ Gid gid;
+ ASSERT_EQ(24u, gid.data.size());
+ gid.data[0] = 'a';
+}
+
+TEST(Test_gid, get_typesupport) {
+ const rosidl_message_type_support_t * type_support_1 =
+ rosidl_typesupport_cpp::get_message_type_support_handle();
+ const rosidl_message_type_support_t * type_support_2 = get_message_typesupport_handle(
+ type_support_1, rosidl_typesupport_fastrtps_cpp::typesupport_identifier);
+
+ ASSERT_EQ(type_support_1->typesupport_identifier, type_support_2->typesupport_identifier);
+ ASSERT_EQ(type_support_1->data, type_support_2->data);
+ ASSERT_EQ(type_support_1->func, type_support_2->func);
+}
diff --git a/rmw_fastrtps_dynamic_cpp/CMakeLists.txt b/rmw_fastrtps_dynamic_cpp/CMakeLists.txt
index c64f4215b..793d58ccc 100644
--- a/rmw_fastrtps_dynamic_cpp/CMakeLists.txt
+++ b/rmw_fastrtps_dynamic_cpp/CMakeLists.txt
@@ -33,6 +33,7 @@ find_package(ament_cmake_ros REQUIRED)
find_package(rcpputils REQUIRED)
find_package(rcutils REQUIRED)
+find_package(rmw_dds_common REQUIRED)
find_package(rmw_fastrtps_shared_cpp REQUIRED)
find_package(fastrtps_cmake_module REQUIRED)
@@ -56,8 +57,13 @@ add_library(rmw_fastrtps_dynamic_cpp
src/get_publisher.cpp
src/get_service.cpp
src/get_subscriber.cpp
+ src/gid__type_support.cpp
src/identifier.cpp
- src/rmw_logging.cpp
+ src/listener_thread.cpp
+ src/node_entities_info__type_support.cpp
+ src/participant_entities_info__type_support.cpp
+ src/publisher.cpp
+ src/register_node.cpp
src/rmw_client.cpp
src/rmw_compare_gids_equal.cpp
src/rmw_count.cpp
@@ -67,6 +73,7 @@ add_library(rmw_fastrtps_dynamic_cpp
src/rmw_get_topic_endpoint_info.cpp
src/rmw_guard_condition.cpp
src/rmw_init.cpp
+ src/rmw_logging.cpp
src/rmw_node.cpp
src/rmw_node_info_and_types.cpp
src/rmw_node_names.cpp
@@ -74,6 +81,7 @@ add_library(rmw_fastrtps_dynamic_cpp
src/rmw_publisher.cpp
src/rmw_request.cpp
src/rmw_response.cpp
+ src/rmw_security.cpp
src/rmw_serialize.cpp
src/rmw_service.cpp
src/rmw_service_names_and_types.cpp
@@ -84,8 +92,9 @@ add_library(rmw_fastrtps_dynamic_cpp
src/rmw_trigger_guard_condition.cpp
src/rmw_wait.cpp
src/rmw_wait_set.cpp
- src/type_support_common.cpp
src/serialization_format.cpp
+ src/subscription.cpp
+ src/type_support_common.cpp
)
target_link_libraries(rmw_fastrtps_dynamic_cpp
fastcdr fastrtps)
@@ -98,6 +107,7 @@ ament_target_dependencies(rmw_fastrtps_dynamic_cpp
"rosidl_typesupport_fastrtps_cpp"
"rosidl_typesupport_introspection_c"
"rosidl_typesupport_introspection_cpp"
+ "rmw_dds_common"
"rmw_fastrtps_shared_cpp"
"rmw"
"rosidl_generator_c"
diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/publisher.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/publisher.hpp
new file mode 100644
index 000000000..4f98b6c14
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/publisher.hpp
@@ -0,0 +1,36 @@
+// Copyright 2017-2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_DYNAMIC_CPP__PUBLISHER_HPP_
+#define RMW_FASTRTPS_DYNAMIC_CPP__PUBLISHER_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_dynamic_cpp
+{
+
+rmw_publisher_t *
+create_publisher(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_publisher_options_t * publisher_options,
+ bool keyed,
+ bool create_publisher_listener);
+
+} // namespace rmw_fastrtps_dynamic_cpp
+
+#endif // RMW_FASTRTPS_DYNAMIC_CPP__PUBLISHER_HPP_
diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/register_node.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/register_node.hpp
new file mode 100644
index 000000000..5abde1349
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/register_node.hpp
@@ -0,0 +1,41 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_DYNAMIC_CPP__REGISTER_NODE_HPP_
+#define RMW_FASTRTPS_DYNAMIC_CPP__REGISTER_NODE_HPP_
+
+#include "rmw/init.h"
+#include "rmw/types.h"
+
+namespace rmw_fastrtps_dynamic_cpp
+{
+
+/// Register node in context.
+/**
+ * Function that should be called when creating a node,
+ * before using `context->impl`.
+ */
+rmw_ret_t
+register_node(rmw_context_t * context);
+
+/// Unregister node in context.
+/**
+ * Function that should be called when destroying a node.
+ */
+rmw_ret_t
+unregister_node(rmw_context_t * context);
+
+} // namespace rmw_fastrtps_dynamic_cpp
+
+#endif // RMW_FASTRTPS_DYNAMIC_CPP__REGISTER_NODE_HPP_
diff --git a/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/subscription.hpp b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/subscription.hpp
new file mode 100644
index 000000000..0db879040
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/include/rmw_fastrtps_dynamic_cpp/subscription.hpp
@@ -0,0 +1,38 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_DYNAMIC_CPP__SUBSCRIPTION_HPP_
+#define RMW_FASTRTPS_DYNAMIC_CPP__SUBSCRIPTION_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw/subscription_options.h"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_dynamic_cpp
+{
+
+rmw_subscription_t *
+create_subscription(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_subscription_options_t * subscription_options,
+ bool keyed,
+ bool create_subscription_listener);
+
+} // namespace rmw_fastrtps_dynamic_cpp
+
+#endif // RMW_FASTRTPS_DYNAMIC_CPP__SUBSCRIPTION_HPP_
diff --git a/rmw_fastrtps_dynamic_cpp/package.xml b/rmw_fastrtps_dynamic_cpp/package.xml
index 5dfb470bf..cfc49d436 100644
--- a/rmw_fastrtps_dynamic_cpp/package.xml
+++ b/rmw_fastrtps_dynamic_cpp/package.xml
@@ -19,6 +19,7 @@
rcpputils
rcutils
rmw
+ rmw_dds_common
rmw_fastrtps_shared_cpp
rosidl_generator_c
rosidl_typesupport_fastrtps_c
@@ -32,6 +33,7 @@
rcpputils
rcutils
rmw
+ rmw_dds_common
rmw_fastrtps_shared_cpp
rosidl_generator_c
rosidl_typesupport_fastrtps_c
diff --git a/rmw_fastrtps_dynamic_cpp/src/get_participant.cpp b/rmw_fastrtps_dynamic_cpp/src/get_participant.cpp
index ba7aa5c5e..a1c2107de 100644
--- a/rmw_fastrtps_dynamic_cpp/src/get_participant.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/get_participant.cpp
@@ -15,6 +15,7 @@
#include "rmw_fastrtps_dynamic_cpp/get_participant.hpp"
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
namespace rmw_fastrtps_dynamic_cpp
@@ -29,7 +30,7 @@ get_participant(rmw_node_t * node)
if (node->implementation_identifier != eprosima_fastrtps_identifier) {
return nullptr;
}
- auto impl = static_cast(node->data);
+ auto impl = static_cast(node->context->impl->participant_info);
return impl->participant;
}
diff --git a/rmw_fastrtps_dynamic_cpp/src/gid__type_support.cpp b/rmw_fastrtps_dynamic_cpp/src/gid__type_support.cpp
new file mode 100644
index 000000000..2e54e1d69
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/gid__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/gid__struct.hpp"
+#include "rmw_dds_common/msg/gid__rosidl_typesupport_introspection_cpp.hpp"
+#include "rmw_fastrtps_dynamic_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_introspection_cpp, rmw_dds_common, msg, Gid)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, Gid)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_dynamic_cpp/src/listener_thread.cpp b/rmw_fastrtps_dynamic_cpp/src/listener_thread.cpp
new file mode 100644
index 000000000..34c3208a3
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/listener_thread.cpp
@@ -0,0 +1,170 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+#include
+#include
+#include
+
+#include "rcutils/macros.h"
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/init.h"
+#include "rmw/ret_types.h"
+#include "rmw/rmw.h"
+#include "rmw/types.h"
+#include "rmw/impl/cpp/macros.hpp"
+
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/gid_utils.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+
+#include "listener_thread.hpp"
+
+using rmw_dds_common::operator<<;
+
+static
+void
+node_listener(rmw_context_t * context);
+
+rmw_ret_t
+rmw_fastrtps_dynamic_cpp::run_listener_thread(rmw_context_t * context)
+{
+ auto common_context = static_cast(context->impl->common);
+ common_context->thread_is_running.store(true);
+ common_context->listener_thread_gc = rmw_create_guard_condition(context);
+ if (common_context->listener_thread_gc) {
+ try {
+ common_context->listener_thread = std::thread(node_listener, context);
+ return RMW_RET_OK;
+ } catch (const std::exception & exc) {
+ RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Failed to create std::thread: %s", exc.what());
+ } catch (...) {
+ RMW_SET_ERROR_MSG("Failed to create std::thread");
+ }
+ } else {
+ RMW_SET_ERROR_MSG("Failed to create guard condition");
+ }
+ common_context->thread_is_running.store(false);
+ if (common_context->listener_thread_gc) {
+ if (RMW_RET_OK != rmw_destroy_guard_condition(common_context->listener_thread_gc)) {
+ fprintf(
+ stderr,
+ RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__function__) ":"
+ RCUTILS_STRINGIFY(__LINE__) ": Failed to destroy guard condition");
+ }
+ }
+ return RMW_RET_ERROR;
+}
+
+rmw_ret_t
+rmw_fastrtps_dynamic_cpp::join_listener_thread(rmw_context_t * context)
+{
+ auto common_context = static_cast(context->impl->common);
+ common_context->thread_is_running.exchange(false);
+ rmw_ret_t rmw_ret = rmw_trigger_guard_condition(common_context->listener_thread_gc);
+ if (RMW_RET_OK != rmw_ret) {
+ return rmw_ret;
+ }
+ try {
+ common_context->listener_thread.join();
+ } catch (const std::exception & exc) {
+ RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Failed to join std::thread: %s", exc.what());
+ return RMW_RET_ERROR;
+ } catch (...) {
+ RMW_SET_ERROR_MSG("Failed to join std::thread");
+ return RMW_RET_ERROR;
+ }
+ rmw_ret = rmw_destroy_guard_condition(common_context->listener_thread_gc);
+ if (RMW_RET_OK != rmw_ret) {
+ return rmw_ret;
+ }
+ return RMW_RET_OK;
+}
+
+#define TERMINATE(msg) \
+ do { \
+ fprintf( \
+ stderr, \
+ RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__function__) ":" \
+ RCUTILS_STRINGIFY(__LINE__) RCUTILS_STRINGIFY(msg) ": %s, terminating ...", \
+ rmw_get_error_string().str); \
+ std::terminate(); \
+ } while (0)
+
+void
+node_listener(rmw_context_t * context)
+{
+ assert(nullptr != context);
+ assert(nullptr != context->impl);
+ assert(nullptr != context->impl->common);
+ auto common_context = static_cast(context->impl->common);
+ while (common_context->thread_is_running.load()) {
+ assert(nullptr != common_context->sub);
+ assert(nullptr != common_context->sub->data);
+ void * subscriptions_buffer[] = {common_context->sub->data};
+ void * guard_conditions_buffer[] = {common_context->listener_thread_gc->data};
+ rmw_subscriptions_t subscriptions;
+ rmw_guard_conditions_t guard_conditions;
+ subscriptions.subscriber_count = 1;
+ subscriptions.subscribers = subscriptions_buffer;
+ guard_conditions.guard_condition_count = 1;
+ guard_conditions.guard_conditions = guard_conditions_buffer;
+ // number of conditions of a subscription is 2
+ rmw_wait_set_t * wait_set = rmw_create_wait_set(context, 2);
+ if (nullptr == wait_set) {
+ TERMINATE("failed to create wait set");
+ }
+ if (RMW_RET_OK != rmw_wait(
+ &subscriptions,
+ &guard_conditions,
+ nullptr,
+ nullptr,
+ nullptr,
+ wait_set,
+ nullptr))
+ {
+ TERMINATE("rmw_wait failed");
+ }
+ if (subscriptions_buffer[0]) {
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg;
+ bool taken;
+ if (RMW_RET_OK != rmw_take(
+ common_context->sub,
+ static_cast(&msg),
+ &taken,
+ nullptr))
+ {
+ TERMINATE("rmw_take failed");
+ }
+ if (taken) {
+ if (std::memcmp(
+ reinterpret_cast(common_context->gid.data),
+ reinterpret_cast(&msg.gid.data),
+ RMW_GID_STORAGE_SIZE) == 0)
+ {
+ // ignore local messages
+ continue;
+ }
+ common_context->graph_cache.update_participant_entities(msg);
+ }
+ }
+ if (RMW_RET_OK != rmw_destroy_wait_set(wait_set)) {
+ TERMINATE("failed to destroy wait set");
+ }
+ }
+}
diff --git a/rmw_fastrtps_dynamic_cpp/src/listener_thread.hpp b/rmw_fastrtps_dynamic_cpp/src/listener_thread.hpp
new file mode 100644
index 000000000..f66644788
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/listener_thread.hpp
@@ -0,0 +1,30 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 LISTENER_THREAD_HPP_
+#define LISTENER_THREAD_HPP_
+
+#include "rmw/init.h"
+
+namespace rmw_fastrtps_dynamic_cpp
+{
+
+rmw_ret_t
+run_listener_thread(rmw_context_t * context);
+
+rmw_ret_t
+join_listener_thread(rmw_context_t * context);
+
+} // namespace rmw_fastrtps_dynamic_cpp
+#endif // LISTENER_THREAD_HPP_
diff --git a/rmw_fastrtps_dynamic_cpp/src/node_entities_info__type_support.cpp b/rmw_fastrtps_dynamic_cpp/src/node_entities_info__type_support.cpp
new file mode 100644
index 000000000..d03555f01
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/node_entities_info__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/node_entities_info__struct.hpp"
+#include "rmw_dds_common/msg/node_entities_info__rosidl_typesupport_introspection_cpp.hpp"
+#include "rmw_fastrtps_dynamic_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_introspection_cpp, rmw_dds_common, msg, NodeEntitiesInfo)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, NodeEntitiesInfo)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_dynamic_cpp/src/participant_entities_info__type_support.cpp b/rmw_fastrtps_dynamic_cpp/src/participant_entities_info__type_support.cpp
new file mode 100644
index 000000000..c9d5cb3bf
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/participant_entities_info__type_support.cpp
@@ -0,0 +1,52 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+
+#include "rosidl_generator_c/message_type_support_struct.h"
+// rosidl_typesupport_cpp/message_type_support.hpp is installed by rosidl_generator_cpp
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+#include "rmw_dds_common/msg/participant_entities_info__struct.hpp"
+#include "rmw_dds_common/msg/participant_entities_info__rosidl_typesupport_introspection_cpp.hpp"
+#include "rmw_fastrtps_dynamic_cpp/visibility_control.h"
+
+namespace rosidl_typesupport_cpp
+{
+
+template<>
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+get_message_type_support_handle()
+{
+ return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_introspection_cpp, rmw_dds_common, msg, ParticipantEntitiesInfo)();
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+RMW_FASTRTPS_DYNAMIC_CPP_PUBLIC
+const rosidl_message_type_support_t *
+ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
+ rosidl_typesupport_cpp, rmw_dds_common, msg, ParticipantEntitiesInfo)()
+{
+ return get_message_type_support_handle();
+}
+
+#ifdef __cplusplus
+}
+#endif
+} // namespace rosidl_typesupport_cpp
diff --git a/rmw_fastrtps_dynamic_cpp/src/publisher.cpp b/rmw_fastrtps_dynamic_cpp/src/publisher.cpp
new file mode 100644
index 000000000..6c4011853
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/publisher.cpp
@@ -0,0 +1,198 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// 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.
+
+#include
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/rmw.h"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/custom_publisher_info.hpp"
+#include "rmw_fastrtps_shared_cpp/names.hpp"
+#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
+#include "rmw_fastrtps_shared_cpp/qos.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+
+#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/publisher.hpp"
+
+#include "type_support_common.hpp"
+
+using Domain = eprosima::fastrtps::Domain;
+using Participant = eprosima::fastrtps::Participant;
+using TopicDataType = eprosima::fastrtps::TopicDataType;
+
+rmw_publisher_t *
+rmw_fastrtps_dynamic_cpp::create_publisher(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_publisher_options_t * publisher_options,
+ bool keyed,
+ bool create_publisher_listener)
+{
+ (void)keyed;
+ (void)create_publisher_listener;
+
+ if (!participant_info) {
+ RMW_SET_ERROR_MSG("participant_info is null");
+ return nullptr;
+ }
+
+ if (!topic_name || strlen(topic_name) == 0) {
+ RMW_SET_ERROR_MSG("publisher topic is null or empty string");
+ return nullptr;
+ }
+
+ if (!qos_policies) {
+ RMW_SET_ERROR_MSG("qos_policies is null");
+ return nullptr;
+ }
+
+ if (!publisher_options) {
+ RMW_SET_ERROR_MSG("publisher_options is null");
+ return nullptr;
+ }
+
+ Participant * participant = participant_info->participant;
+ if (!participant) {
+ RMW_SET_ERROR_MSG("participant handle is null");
+ return nullptr;
+ }
+
+ const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
+ type_supports, rosidl_typesupport_introspection_c__identifier);
+ if (!type_support) {
+ type_support = get_message_typesupport_handle(
+ type_supports, rosidl_typesupport_introspection_cpp::typesupport_identifier);
+ if (!type_support) {
+ RMW_SET_ERROR_MSG("type support not from this implementation");
+ return nullptr;
+ }
+ }
+
+ if (!is_valid_qos(*qos_policies)) {
+ return nullptr;
+ }
+
+ CustomPublisherInfo * info = nullptr;
+ rmw_publisher_t * rmw_publisher = nullptr;
+ eprosima::fastrtps::PublisherAttributes publisherParam;
+ const eprosima::fastrtps::rtps::GUID_t * guid = nullptr;
+
+ // Load default XML profile.
+ Domain::getDefaultPublisherAttributes(publisherParam);
+
+ // TODO(karsten1987) Verify consequences for std::unique_ptr?
+ info = new (std::nothrow) CustomPublisherInfo();
+ if (!info) {
+ RMW_SET_ERROR_MSG("failed to allocate CustomPublisherInfo");
+ return nullptr;
+ }
+ info->typesupport_identifier_ = type_support->typesupport_identifier;
+ info->type_support_impl_ = type_support->data;
+
+ std::string type_name = _create_type_name(
+ type_support->data, info->typesupport_identifier_);
+ if (!Domain::getRegisteredType(participant, type_name.c_str(),
+ reinterpret_cast(&info->type_support_)))
+ {
+ info->type_support_ = _create_message_type_support(type_support->data,
+ info->typesupport_identifier_);
+ _register_type(participant, info->type_support_);
+ }
+
+ if (!participant_info->leave_middleware_default_qos) {
+ publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
+ publisherParam.historyMemoryPolicy =
+ eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
+ }
+
+ publisherParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
+ publisherParam.topic.topicDataType = type_name;
+ publisherParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
+
+ // 1 Heartbeat every 10ms
+ // publisherParam.times.heartbeatPeriod.seconds = 0;
+ // publisherParam.times.heartbeatPeriod.fraction = 42949673;
+
+ // 300000 bytes each 10ms
+ // ThroughputControllerDescriptor throughputController{3000000, 10};
+ // publisherParam.throughputController = throughputController;
+
+ if (!get_datawriter_qos(*qos_policies, publisherParam)) {
+ RMW_SET_ERROR_MSG("failed to get datawriter qos");
+ goto fail;
+ }
+
+ info->listener_ = new (std::nothrow) PubListener(info);
+ if (!info->listener_) {
+ RMW_SET_ERROR_MSG("create_publisher() could not create publisher listener");
+ goto fail;
+ }
+
+ info->publisher_ = Domain::createPublisher(participant, publisherParam, info->listener_);
+ if (!info->publisher_) {
+ RMW_SET_ERROR_MSG("create_publisher() could not create publisher");
+ goto fail;
+ }
+
+ info->publisher_gid.implementation_identifier = eprosima_fastrtps_identifier;
+ static_assert(
+ sizeof(eprosima::fastrtps::rtps::GUID_t) <= RMW_GID_STORAGE_SIZE,
+ "RMW_GID_STORAGE_SIZE insufficient to store the rmw_fastrtps_dynamic_cpp GID implementation."
+ );
+
+ memset(info->publisher_gid.data, 0, RMW_GID_STORAGE_SIZE);
+ guid = &info->publisher_->getGuid();
+ if (!guid) {
+ RMW_SET_ERROR_MSG("no guid found for publisher");
+ goto fail;
+ }
+ memcpy(info->publisher_gid.data, guid, sizeof(eprosima::fastrtps::rtps::GUID_t));
+
+ rmw_publisher = rmw_publisher_allocate();
+ if (!rmw_publisher) {
+ RMW_SET_ERROR_MSG("failed to allocate publisher");
+ goto fail;
+ }
+ rmw_publisher->can_loan_messages = false;
+ rmw_publisher->implementation_identifier = eprosima_fastrtps_identifier;
+ rmw_publisher->data = info;
+ rmw_publisher->topic_name = reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
+
+ if (!rmw_publisher->topic_name) {
+ RMW_SET_ERROR_MSG("failed to allocate memory for publisher topic name");
+ goto fail;
+ }
+
+ memcpy(const_cast(rmw_publisher->topic_name), topic_name, strlen(topic_name) + 1);
+
+ rmw_publisher->options = *publisher_options;
+
+ return rmw_publisher;
+
+fail:
+ if (info) {
+ delete info->type_support_;
+ delete info->listener_;
+ delete info;
+ }
+ rmw_publisher_free(rmw_publisher);
+
+ return nullptr;
+}
diff --git a/rmw_fastrtps_dynamic_cpp/src/register_node.cpp b/rmw_fastrtps_dynamic_cpp/src/register_node.cpp
new file mode 100644
index 000000000..6ab88330a
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/register_node.cpp
@@ -0,0 +1,217 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include "rmw_fastrtps_dynamic_cpp/register_node.hpp"
+
+#include
+#include
+
+#include "rmw/error_handling.h"
+#include "rmw/init.h"
+#include "rmw/qos_profiles.h"
+
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/publisher.hpp"
+#include "rmw_fastrtps_dynamic_cpp/subscription.hpp"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/participant.hpp"
+#include "rmw_fastrtps_shared_cpp/publisher.hpp"
+#include "rmw_fastrtps_shared_cpp/subscription.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+
+#include "listener_thread.hpp"
+
+using rmw_dds_common::msg::ParticipantEntitiesInfo;
+
+static
+rmw_ret_t
+init_context_impl(rmw_context_t * context)
+{
+ rmw_publisher_options_t publisher_options = rmw_get_default_publisher_options();
+ rmw_subscription_options_t subscription_options = rmw_get_default_subscription_options();
+
+ // This is currently not implemented in fastrtps
+ subscription_options.ignore_local_publications = true;
+
+ std::unique_ptr common_context(
+ new(std::nothrow) rmw_dds_common::Context());
+ if (!common_context) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ std::unique_ptr>
+ participant_info(
+ rmw_fastrtps_shared_cpp::create_participant(
+ eprosima_fastrtps_identifier,
+ context->options.domain_id,
+ &context->options.security_options,
+ (context->options.localhost_only == RMW_LOCALHOST_ONLY_ENABLED) ? 1 : 0,
+ common_context.get()),
+ [&](CustomParticipantInfo * participant_info) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_participant(participant_info)) {
+ fprintf(
+ stderr, "Failed to destroy participant after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!participant_info) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ rmw_qos_profile_t qos = rmw_qos_profile_default;
+
+ qos.avoid_ros_namespace_conventions = false; // Change this to true after testing
+ qos.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
+ qos.depth = 1;
+ qos.durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
+ qos.reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
+
+ std::unique_ptr>
+ publisher(
+ rmw_fastrtps_dynamic_cpp::create_publisher(
+ participant_info.get(),
+ rosidl_typesupport_cpp::get_message_type_support_handle(),
+ "_participant_info",
+ &qos,
+ &publisher_options,
+ false, // our fastrtps typesupport doesn't support keyed topics
+ true),
+ [&](rmw_publisher_t * pub) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_publisher(
+ eprosima_fastrtps_identifier,
+ participant_info.get(),
+ pub))
+ {
+ fprintf(
+ stderr, "Failed to destroy publisher after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!publisher) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ // If we would have support for keyed topics, this could be KEEP_LAST and depth 1.
+ qos.history = RMW_QOS_POLICY_HISTORY_KEEP_ALL;
+ std::unique_ptr>
+ subscription(
+ rmw_fastrtps_dynamic_cpp::create_subscription(
+ participant_info.get(),
+ rosidl_typesupport_cpp::get_message_type_support_handle(),
+ "_participant_info",
+ &qos,
+ &subscription_options,
+ false, // our fastrtps typesupport doesn't support keyed topics
+ true),
+ [&](rmw_subscription_t * sub) {
+ if (RMW_RET_OK != rmw_fastrtps_shared_cpp::destroy_subscription(
+ eprosima_fastrtps_identifier,
+ participant_info.get(),
+ sub))
+ {
+ fprintf(
+ stderr, "Failed to destroy subscription after function: '"
+ RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ });
+ if (!subscription) {
+ return RMW_RET_BAD_ALLOC;
+ }
+
+ common_context->gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, participant_info->participant->getGuid());
+ common_context->pub = publisher.get();
+ common_context->sub = subscription.get();
+
+ context->impl->common = common_context.get();
+ context->impl->participant_info = participant_info.get();
+
+ if (RMW_RET_OK != rmw_fastrtps_dynamic_cpp::run_listener_thread(context)) {
+ return RMW_RET_ERROR;
+ }
+ common_context->graph_cache.add_participant(common_context->gid);
+
+ publisher.release();
+ subscription.release();
+ common_context.release();
+ participant_info.release();
+ return RMW_RET_OK;
+}
+
+rmw_ret_t
+rmw_fastrtps_dynamic_cpp::register_node(rmw_context_t * context)
+{
+ assert(context);
+ assert(context->impl);
+
+ std::lock_guard guard(context->impl->mutex);
+
+ if (!context->impl->count) {
+ rmw_ret_t ret = init_context_impl(context);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ }
+ context->impl->count++;
+ return RMW_RET_OK;
+}
+
+rmw_ret_t
+rmw_fastrtps_dynamic_cpp::unregister_node(rmw_context_t * context)
+{
+ assert(context);
+ assert(context->impl);
+
+ std::lock_guard guard(context->impl->mutex);
+ if (0u == --context->impl->count) {
+ rmw_ret_t ret;
+ ret = rmw_fastrtps_dynamic_cpp::join_listener_thread(context);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+
+ auto common_context = static_cast(context->impl->common);
+ auto participant_info = static_cast(context->impl->participant_info);
+
+ common_context->graph_cache.remove_participant(common_context->gid);
+ ret = rmw_fastrtps_shared_cpp::destroy_subscription(
+ eprosima_fastrtps_identifier,
+ participant_info,
+ common_context->sub);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ ret = rmw_fastrtps_shared_cpp::destroy_publisher(
+ eprosima_fastrtps_identifier,
+ participant_info,
+ common_context->pub);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ ret = rmw_fastrtps_shared_cpp::destroy_participant(participant_info);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ delete common_context;
+ context->impl->common = nullptr;
+ context->impl->participant_info = nullptr;
+ }
+ return RMW_RET_OK;
+}
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_client.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_client.cpp
index f2bf46dc2..39554fbf0 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_client.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_client.cpp
@@ -29,6 +29,7 @@
#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
@@ -67,13 +68,15 @@ rmw_create_client(
return nullptr;
}
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
+ auto common_context = static_cast(node->context->impl->common);
+ auto participant_info =
+ static_cast(node->context->impl->participant_info);
+ if (!participant_info) {
+ RMW_SET_ERROR_MSG("participant info is null");
return nullptr;
}
- Participant * participant = impl->participant;
+ Participant * participant = participant_info->participant;
if (!participant) {
RMW_SET_ERROR_MSG("participant handle is null");
return nullptr;
@@ -133,7 +136,7 @@ rmw_create_client(
_register_type(participant, info->response_type_support_);
}
- if (!impl->leave_middleware_default_qos) {
+ if (!participant_info->leave_middleware_default_qos) {
subscriberParam.historyMemoryPolicy =
eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
}
@@ -143,7 +146,7 @@ rmw_create_client(
subscriberParam.topic.topicName = _create_topic_name(
qos_policies, ros_service_response_prefix, service_name, "Reply");
- if (!impl->leave_middleware_default_qos) {
+ if (!participant_info->leave_middleware_default_qos) {
publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
publisherParam.historyMemoryPolicy =
eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
@@ -209,15 +212,54 @@ rmw_create_client(
}
memcpy(const_cast(rmw_client->service_name), service_name, strlen(service_name) + 1);
+ {
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_publisher_->getGuid());
+ common_context->graph_cache.associate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
+ gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_subscriber_->getGuid());
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_reader(
+ gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ goto fail;
+ }
+ }
+
return rmw_client;
fail:
if (info != nullptr) {
if (info->request_publisher_ != nullptr) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_publisher_->getGuid());
+ common_context->graph_cache.dissociate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removePublisher(info->request_publisher_);
}
if (info->response_subscriber_ != nullptr) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_subscriber_->getGuid());
+ common_context->graph_cache.dissociate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removeSubscriber(info->response_subscriber_);
}
@@ -229,7 +271,7 @@ rmw_create_client(
delete info->listener_;
}
- if (impl) {
+ if (participant_info) {
if (info->request_type_support_ != nullptr) {
rmw_fastrtps_shared_cpp::_unregister_type(participant, info->request_type_support_);
}
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_init.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_init.cpp
index 3e57dfbb8..7a979829a 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_init.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_init.cpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,10 +13,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include
+
+#include "rcutils/types.h"
+
#include "rmw/impl/cpp/macros.hpp"
+#include "rmw/init.h"
+#include "rmw/init_options.h"
+#include "rmw/publisher_options.h"
#include "rmw/rmw.h"
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/participant.hpp"
+#include "rmw_fastrtps_shared_cpp/publisher.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
+#include "rmw_fastrtps_shared_cpp/subscription.hpp"
+
+#include "rosidl_typesupport_cpp/message_type_support.hpp"
+
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/publisher.hpp"
+#include "rmw_fastrtps_dynamic_cpp/subscription.hpp"
+
+#include "listener_thread.hpp"
extern "C"
{
@@ -67,9 +90,19 @@ rmw_init_options_fini(rmw_init_options_t * init_options)
return RMW_RET_OK;
}
+using rmw_dds_common::msg::ParticipantEntitiesInfo;
+
rmw_ret_t
rmw_init(const rmw_init_options_t * options, rmw_context_t * context)
{
+ std::unique_ptr clean_when_fail(
+ context,
+ [](rmw_context_t * context)
+ {
+ *context = rmw_get_zero_initialized_context();
+ });
+ rmw_ret_t ret = RMW_RET_OK;
+
RCUTILS_CHECK_ARGUMENT_FOR_NULL(options, RMW_RET_INVALID_ARGUMENT);
RCUTILS_CHECK_ARGUMENT_FOR_NULL(context, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
@@ -79,7 +112,23 @@ rmw_init(const rmw_init_options_t * options, rmw_context_t * context)
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
context->instance_id = options->instance_id;
context->implementation_identifier = eprosima_fastrtps_identifier;
- context->impl = nullptr;
+
+ std::unique_ptr context_impl(new rmw_context_impl_t());
+ if (!context_impl) {
+ return RMW_RET_BAD_ALLOC;
+ }
+ context->options = rmw_get_zero_initialized_init_options();
+ ret = rmw_init_options_copy(options, &context->options);
+ if (RMW_RET_OK != ret) {
+ if (RMW_RET_OK != rmw_init_options_fini(&context->options)) {
+ fprintf(
+ stderr,
+ "Failed to destroy init options after ':" RCUTILS_STRINGIFY(__function__) "' failed.\n");
+ }
+ return ret;
+ }
+ context->impl = context_impl.release();
+ clean_when_fail.release();
return RMW_RET_OK;
}
@@ -106,8 +155,7 @@ rmw_context_fini(rmw_context_t * context)
context->implementation_identifier,
eprosima_fastrtps_identifier,
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
- // context impl is explicitly supposed to be nullptr for now, see rmw_init's code
- // RCUTILS_CHECK_ARGUMENT_FOR_NULL(context->impl, RMW_RET_INVALID_ARGUMENT);
+ delete context->impl;
*context = rmw_get_zero_initialized_context();
return RMW_RET_OK;
}
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_node.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_node.cpp
index 09c6166e9..7fe7fb4f4 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_node.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_node.cpp
@@ -28,6 +28,7 @@
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/register_node.hpp"
extern "C"
{
@@ -37,9 +38,12 @@ rmw_create_node(
const char * name,
const char * namespace_,
size_t domain_id,
- const rmw_node_security_options_t * security_options,
+ const rmw_security_options_t * security_options,
bool localhost_only)
{
+ (void)domain_id;
+ (void)security_options;
+ (void)localhost_only;
RCUTILS_CHECK_ARGUMENT_FOR_NULL(context, NULL);
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
init context,
@@ -47,15 +51,24 @@ rmw_create_node(
eprosima_fastrtps_identifier,
// TODO(wjwwood): replace this with RMW_RET_INCORRECT_RMW_IMPLEMENTATION when refactored
return NULL);
+
+ if (RMW_RET_OK != rmw_fastrtps_dynamic_cpp::register_node(context)) {
+ return nullptr;
+ }
+
return rmw_fastrtps_shared_cpp::__rmw_create_node(
- eprosima_fastrtps_identifier, name, namespace_, domain_id, security_options, localhost_only);
+ context, eprosima_fastrtps_identifier, name, namespace_);
}
rmw_ret_t
rmw_destroy_node(rmw_node_t * node)
{
- return rmw_fastrtps_shared_cpp::__rmw_destroy_node(
+ rmw_ret_t ret = rmw_fastrtps_shared_cpp::__rmw_destroy_node(
eprosima_fastrtps_identifier, node);
+ if (RMW_RET_OK != ret) {
+ return ret;
+ }
+ return rmw_fastrtps_dynamic_cpp::unregister_node(node->context);
}
rmw_ret_t
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp
index 50093dc96..c0309cffc 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_publisher.cpp
@@ -20,14 +20,14 @@
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
#include "rmw_fastrtps_shared_cpp/custom_publisher_info.hpp"
-#include "rmw_fastrtps_shared_cpp/names.hpp"
-#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
-#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/publisher.hpp"
-#include "type_support_common.hpp"
+#include "rmw_dds_common/context.hpp"
+#include "rmw_dds_common/msg/participant_entities_info.hpp"
using Domain = eprosima::fastrtps::Domain;
using Participant = eprosima::fastrtps::Participant;
@@ -76,161 +76,42 @@ rmw_create_publisher(
return nullptr;
}
- if (!topic_name || strlen(topic_name) == 0) {
- RMW_SET_ERROR_MSG("publisher topic is null or empty string");
- return nullptr;
- }
+ auto impl = static_cast(node->context->impl->participant_info);
- if (!qos_policies) {
- RMW_SET_ERROR_MSG("qos_policies is null");
- return nullptr;
- }
-
- if (!publisher_options) {
- RMW_SET_ERROR_MSG("publisher_options is null");
- return nullptr;
- }
+ rmw_publisher_t * publisher = rmw_fastrtps_dynamic_cpp::create_publisher(
+ impl,
+ type_supports,
+ topic_name,
+ qos_policies,
+ publisher_options,
+ false,
+ true);
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
+ if (!publisher) {
return nullptr;
}
- Participant * participant = impl->participant;
- if (!participant) {
- RMW_SET_ERROR_MSG("participant handle is null");
- return nullptr;
- }
-
- const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
- type_supports, rosidl_typesupport_introspection_c__identifier);
- if (!type_support) {
- type_support = get_message_typesupport_handle(
- type_supports, rosidl_typesupport_introspection_cpp::typesupport_identifier);
- if (!type_support) {
- RMW_SET_ERROR_MSG("type support not from this implementation");
- return nullptr;
- }
- }
+ auto common_context = static_cast(node->context->impl->common);
- if (!is_valid_qos(*qos_policies)) {
- return nullptr;
- }
-
- CustomPublisherInfo * info = nullptr;
- rmw_publisher_t * rmw_publisher = nullptr;
- eprosima::fastrtps::PublisherAttributes publisherParam;
- const eprosima::fastrtps::rtps::GUID_t * guid = nullptr;
-
- // Load default XML profile.
- Domain::getDefaultPublisherAttributes(publisherParam);
-
- // TODO(karsten1987) Verify consequences for std::unique_ptr?
- info = new (std::nothrow) CustomPublisherInfo();
- if (!info) {
- RMW_SET_ERROR_MSG("failed to allocate CustomPublisherInfo");
- return nullptr;
- }
- info->typesupport_identifier_ = type_support->typesupport_identifier;
- info->type_support_impl_ = type_support->data;
-
- std::string type_name = _create_type_name(
- type_support->data, info->typesupport_identifier_);
- if (!Domain::getRegisteredType(participant, type_name.c_str(),
- reinterpret_cast(&info->type_support_)))
+ auto info = static_cast(publisher->data);
{
- info->type_support_ = _create_message_type_support(type_support->data,
- info->typesupport_identifier_);
- _register_type(participant, info->type_support_);
- }
-
- if (!impl->leave_middleware_default_qos) {
- publisherParam.qos.m_publishMode.kind = eprosima::fastrtps::ASYNCHRONOUS_PUBLISH_MODE;
- publisherParam.historyMemoryPolicy =
- eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
- }
-
- publisherParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
- publisherParam.topic.topicDataType = type_name;
- publisherParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
-
- // 1 Heartbeat every 10ms
- // publisherParam.times.heartbeatPeriod.seconds = 0;
- // publisherParam.times.heartbeatPeriod.fraction = 42949673;
-
- // 300000 bytes each 10ms
- // ThroughputControllerDescriptor throughputController{3000000, 10};
- // publisherParam.throughputController = throughputController;
-
- if (!get_datawriter_qos(*qos_policies, publisherParam)) {
- RMW_SET_ERROR_MSG("failed to get datawriter qos");
- goto fail;
- }
-
- info->listener_ = new (std::nothrow) PubListener(info);
- if (!info->listener_) {
- RMW_SET_ERROR_MSG("create_publisher() could not create publisher listener");
- goto fail;
- }
-
- info->publisher_ = Domain::createPublisher(participant, publisherParam, info->listener_);
- if (!info->publisher_) {
- RMW_SET_ERROR_MSG("create_publisher() could not create publisher");
- goto fail;
- }
-
- info->publisher_gid.implementation_identifier = eprosima_fastrtps_identifier;
- static_assert(
- sizeof(eprosima::fastrtps::rtps::GUID_t) <= RMW_GID_STORAGE_SIZE,
- "RMW_GID_STORAGE_SIZE insufficient to store the rmw_fastrtps_dynamic_cpp GID implementation."
- );
-
- memset(info->publisher_gid.data, 0, RMW_GID_STORAGE_SIZE);
- guid = &info->publisher_->getGuid();
- if (!guid) {
- RMW_SET_ERROR_MSG("no guid found for publisher");
- goto fail;
- }
- memcpy(info->publisher_gid.data, guid, sizeof(eprosima::fastrtps::rtps::GUID_t));
-
- rmw_publisher = rmw_publisher_allocate();
- if (!rmw_publisher) {
- RMW_SET_ERROR_MSG("failed to allocate publisher");
- goto fail;
- }
- rmw_publisher->can_loan_messages = false;
- rmw_publisher->implementation_identifier = eprosima_fastrtps_identifier;
- rmw_publisher->data = info;
- rmw_publisher->topic_name = reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
-
- if (!rmw_publisher->topic_name) {
- RMW_SET_ERROR_MSG("failed to allocate memory for publisher topic name");
- goto fail;
- }
-
- memcpy(const_cast(rmw_publisher->topic_name), topic_name, strlen(topic_name) + 1);
-
- rmw_publisher->options = *publisher_options;
-
- return rmw_publisher;
-
-fail:
- if (info) {
- if (info->type_support_ != nullptr) {
- delete info->type_support_;
- }
- if (info->listener_ != nullptr) {
- delete info->listener_;
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_writer(
+ info->publisher_gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ rmw_fastrtps_shared_cpp::__rmw_destroy_publisher(
+ eprosima_fastrtps_identifier, node, publisher);
+ return nullptr;
}
- delete info;
}
-
- if (rmw_publisher) {
- rmw_publisher_free(rmw_publisher);
- }
-
- return nullptr;
+ return publisher;
}
rmw_ret_t
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_security.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_security.cpp
new file mode 100644
index 000000000..6774438dd
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_security.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include "rmw/security.h"
+
+extern "C"
+{
+bool
+rmw_use_node_name_in_security_directory_lookup()
+{
+ return false;
+}
+} // extern "C"
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_service.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_service.cpp
index 8a04615e7..e1cbf420e 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_service.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_service.cpp
@@ -35,6 +35,7 @@
#include "rosidl_typesupport_introspection_cpp/identifier.hpp"
#include "rosidl_typesupport_introspection_c/identifier.h"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
#include "rmw_fastrtps_shared_cpp/custom_service_info.hpp"
#include "rmw_fastrtps_shared_cpp/names.hpp"
@@ -79,7 +80,9 @@ rmw_create_service(
return nullptr;
}
- const CustomParticipantInfo * impl = static_cast(node->data);
+ const CustomParticipantInfo * impl =
+ static_cast(node->context->impl->participant_info);
+ auto common_context = static_cast(node->context->impl->common);
if (!impl) {
RMW_SET_ERROR_MSG("node impl is null");
return nullptr;
@@ -215,16 +218,55 @@ rmw_create_service(
}
memcpy(const_cast(rmw_service->service_name), service_name, strlen(service_name) + 1);
+ {
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_subscriber_->getGuid());
+ common_context->graph_cache.associate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
+ gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_publisher_->getGuid());
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_writer(
+ gid, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ goto fail;
+ }
+ }
+
return rmw_service;
fail:
if (info) {
if (info->response_publisher_) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->response_publisher_->getGuid());
+ common_context->graph_cache.dissociate_writer(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removePublisher(info->response_publisher_);
}
if (info->request_subscriber_) {
+ rmw_gid_t gid = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->request_subscriber_->getGuid());
+ common_context->graph_cache.dissociate_reader(
+ gid,
+ common_context->gid,
+ node->name,
+ node->namespace_);
Domain::removeSubscriber(info->request_subscriber_);
}
diff --git a/rmw_fastrtps_dynamic_cpp/src/rmw_subscription.cpp b/rmw_fastrtps_dynamic_cpp/src/rmw_subscription.cpp
index b07f98e99..1c74dd625 100644
--- a/rmw_fastrtps_dynamic_cpp/src/rmw_subscription.cpp
+++ b/rmw_fastrtps_dynamic_cpp/src/rmw_subscription.cpp
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include
#include
+#include
#include "rmw/allocators.h"
#include "rmw/error_handling.h"
@@ -21,15 +21,11 @@
#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
#include "rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp"
-#include "rmw_fastrtps_shared_cpp/names.hpp"
-#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
-#include "rmw_fastrtps_shared_cpp/qos.hpp"
#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
-
-#include "fastrtps/participant/Participant.h"
-#include "fastrtps/subscriber/Subscriber.h"
+#include "rmw_fastrtps_shared_cpp/rmw_context_impl.hpp"
#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/subscription.hpp"
#include "type_support_common.hpp"
@@ -80,137 +76,41 @@ rmw_create_subscription(
return nullptr;
}
- if (!topic_name || strlen(topic_name) == 0) {
- RMW_SET_ERROR_MSG("subscription topic is null or empty string");
- return nullptr;
- }
-
- if (!qos_policies) {
- RMW_SET_ERROR_MSG("qos_policies is null");
- return nullptr;
- }
-
- if (!subscription_options) {
- RMW_SET_ERROR_MSG("subscription_options is null");
- return nullptr;
- }
-
- auto impl = static_cast(node->data);
- if (!impl) {
- RMW_SET_ERROR_MSG("node impl is null");
- return nullptr;
- }
-
- Participant * participant = impl->participant;
- if (!participant) {
- RMW_SET_ERROR_MSG("participant handle is null");
- return nullptr;
- }
-
- const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
- type_supports, rosidl_typesupport_introspection_c__identifier);
- if (!type_support) {
- type_support = get_message_typesupport_handle(
- type_supports, rosidl_typesupport_introspection_cpp::typesupport_identifier);
- if (!type_support) {
- RMW_SET_ERROR_MSG("type support not from this implementation");
- return nullptr;
- }
- }
-
- if (!is_valid_qos(*qos_policies)) {
- return nullptr;
- }
-
- CustomSubscriberInfo * info = nullptr;
- rmw_subscription_t * rmw_subscription = nullptr;
- eprosima::fastrtps::SubscriberAttributes subscriberParam;
-
- // Load default XML profile.
- Domain::getDefaultSubscriberAttributes(subscriberParam);
+ auto participant_info =
+ static_cast(node->context->impl->participant_info);
- info = new (std::nothrow) CustomSubscriberInfo();
- if (!info) {
- RMW_SET_ERROR_MSG("failed to allocate CustomSubscriberInfo");
+ rmw_subscription_t * subscription = rmw_fastrtps_dynamic_cpp::create_subscription(
+ participant_info,
+ type_supports,
+ topic_name,
+ qos_policies,
+ subscription_options,
+ false,
+ true);
+ if (!subscription) {
return nullptr;
}
- info->typesupport_identifier_ = type_support->typesupport_identifier;
- info->type_support_impl_ = type_support->data;
- std::string type_name = _create_type_name(
- type_support->data, info->typesupport_identifier_);
- if (!Domain::getRegisteredType(participant, type_name.c_str(),
- reinterpret_cast(&info->type_support_)))
+ auto common_context = static_cast(node->context->impl->common);
+ auto info = static_cast(subscription->data);
{
- info->type_support_ = _create_message_type_support(type_support->data,
- info->typesupport_identifier_);
- _register_type(participant, info->type_support_);
- }
-
- if (!impl->leave_middleware_default_qos) {
- subscriberParam.historyMemoryPolicy =
- eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
- }
-
- subscriberParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
- subscriberParam.topic.topicDataType = type_name;
- subscriberParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
-
- if (!get_datareader_qos(*qos_policies, subscriberParam)) {
- RMW_SET_ERROR_MSG("failed to get datareader qos");
- goto fail;
- }
-
- info->listener_ = new (std::nothrow) SubListener(info);
- if (!info->listener_) {
- RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber listener");
- goto fail;
- }
-
- info->subscriber_ = Domain::createSubscriber(participant, subscriberParam, info->listener_);
- if (!info->subscriber_) {
- RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber");
- goto fail;
- }
-
- rmw_subscription = rmw_subscription_allocate();
- if (!rmw_subscription) {
- RMW_SET_ERROR_MSG("failed to allocate subscription");
- goto fail;
- }
- rmw_subscription->implementation_identifier = eprosima_fastrtps_identifier;
- rmw_subscription->data = info;
- rmw_subscription->topic_name =
- reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
-
- if (!rmw_subscription->topic_name) {
- RMW_SET_ERROR_MSG("failed to allocate memory for subscription topic name");
- goto fail;
- }
-
- memcpy(const_cast(rmw_subscription->topic_name), topic_name, strlen(topic_name) + 1);
-
- rmw_subscription->options = *subscription_options;
- rmw_subscription->can_loan_messages = false;
- return rmw_subscription;
-
-fail:
-
- if (info != nullptr) {
- if (info->type_support_ != nullptr) {
- delete info->type_support_;
- }
- if (info->listener_ != nullptr) {
- delete info->listener_;
+ // Update graph
+ std::lock_guard guard(common_context->node_update_mutex);
+ rmw_dds_common::msg::ParticipantEntitiesInfo msg =
+ common_context->graph_cache.associate_reader(
+ info->subscription_gid_, common_context->gid, node->name, node->namespace_);
+ rmw_ret_t rmw_ret = rmw_fastrtps_shared_cpp::__rmw_publish(
+ eprosima_fastrtps_identifier,
+ common_context->pub,
+ static_cast(&msg),
+ nullptr);
+ if (RMW_RET_OK != rmw_ret) {
+ rmw_fastrtps_shared_cpp::__rmw_destroy_subscription(
+ eprosima_fastrtps_identifier, node, subscription);
+ return nullptr;
}
- delete info;
}
-
- if (rmw_subscription) {
- rmw_subscription_free(rmw_subscription);
- }
-
- return nullptr;
+ return subscription;
}
rmw_ret_t
diff --git a/rmw_fastrtps_dynamic_cpp/src/subscription.cpp b/rmw_fastrtps_dynamic_cpp/src/subscription.cpp
new file mode 100644
index 000000000..1a36812a2
--- /dev/null
+++ b/rmw_fastrtps_dynamic_cpp/src/subscription.cpp
@@ -0,0 +1,176 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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.
+
+#include
+#include
+
+#include "rmw/allocators.h"
+#include "rmw/error_handling.h"
+#include "rmw/rmw.h"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+#include "rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp"
+#include "rmw_fastrtps_shared_cpp/names.hpp"
+#include "rmw_fastrtps_shared_cpp/namespace_prefix.hpp"
+#include "rmw_fastrtps_shared_cpp/qos.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+
+#include "fastrtps/participant/Participant.h"
+#include "fastrtps/subscriber/Subscriber.h"
+
+#include "rmw_fastrtps_dynamic_cpp/identifier.hpp"
+#include "rmw_fastrtps_dynamic_cpp/subscription.hpp"
+
+#include "type_support_common.hpp"
+
+using Domain = eprosima::fastrtps::Domain;
+using Participant = eprosima::fastrtps::Participant;
+using TopicDataType = eprosima::fastrtps::TopicDataType;
+
+
+namespace rmw_fastrtps_dynamic_cpp
+{
+
+rmw_subscription_t *
+create_subscription(
+ const CustomParticipantInfo * participant_info,
+ const rosidl_message_type_support_t * type_supports,
+ const char * topic_name,
+ const rmw_qos_profile_t * qos_policies,
+ const rmw_subscription_options_t * subscription_options,
+ bool keyed,
+ bool create_subscription_listener)
+{
+ (void)keyed;
+ (void)create_subscription_listener;
+
+ if (!topic_name || strlen(topic_name) == 0) {
+ RMW_SET_ERROR_MSG("subscription topic is null or empty string");
+ return nullptr;
+ }
+
+ if (!qos_policies) {
+ RMW_SET_ERROR_MSG("qos_policies is null");
+ return nullptr;
+ }
+
+ if (!subscription_options) {
+ RMW_SET_ERROR_MSG("subscription_options is null");
+ return nullptr;
+ }
+
+ Participant * participant = participant_info->participant;
+ if (!participant) {
+ RMW_SET_ERROR_MSG("participant handle is null");
+ return nullptr;
+ }
+
+ const rosidl_message_type_support_t * type_support = get_message_typesupport_handle(
+ type_supports, rosidl_typesupport_introspection_c__identifier);
+ if (!type_support) {
+ type_support = get_message_typesupport_handle(
+ type_supports, rosidl_typesupport_introspection_cpp::typesupport_identifier);
+ if (!type_support) {
+ RMW_SET_ERROR_MSG("type support not from this implementation");
+ return nullptr;
+ }
+ }
+
+ if (!is_valid_qos(*qos_policies)) {
+ return nullptr;
+ }
+
+ CustomSubscriberInfo * info = nullptr;
+ rmw_subscription_t * rmw_subscription = nullptr;
+ eprosima::fastrtps::SubscriberAttributes subscriberParam;
+
+ // Load default XML profile.
+ Domain::getDefaultSubscriberAttributes(subscriberParam);
+
+ info = new (std::nothrow) CustomSubscriberInfo();
+ if (!info) {
+ RMW_SET_ERROR_MSG("failed to allocate CustomSubscriberInfo");
+ return nullptr;
+ }
+ info->typesupport_identifier_ = type_support->typesupport_identifier;
+ info->type_support_impl_ = type_support->data;
+
+ std::string type_name = _create_type_name(
+ type_support->data, info->typesupport_identifier_);
+ if (!Domain::getRegisteredType(participant, type_name.c_str(),
+ reinterpret_cast(&info->type_support_)))
+ {
+ info->type_support_ = _create_message_type_support(type_support->data,
+ info->typesupport_identifier_);
+ _register_type(participant, info->type_support_);
+ }
+
+ if (!participant_info->leave_middleware_default_qos) {
+ subscriberParam.historyMemoryPolicy =
+ eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
+ }
+
+ subscriberParam.topic.topicKind = eprosima::fastrtps::rtps::NO_KEY;
+ subscriberParam.topic.topicDataType = type_name;
+ subscriberParam.topic.topicName = _create_topic_name(qos_policies, ros_topic_prefix, topic_name);
+
+ if (!get_datareader_qos(*qos_policies, subscriberParam)) {
+ RMW_SET_ERROR_MSG("failed to get datareader qos");
+ goto fail;
+ }
+
+ info->listener_ = new (std::nothrow) SubListener(info);
+ if (!info->listener_) {
+ RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber listener");
+ goto fail;
+ }
+
+ info->subscriber_ = Domain::createSubscriber(participant, subscriberParam, info->listener_);
+ if (!info->subscriber_) {
+ RMW_SET_ERROR_MSG("create_subscriber() could not create subscriber");
+ goto fail;
+ }
+ info->subscription_gid_ = rmw_fastrtps_shared_cpp::create_rmw_gid(
+ eprosima_fastrtps_identifier, info->subscriber_->getGuid());
+ rmw_subscription = rmw_subscription_allocate();
+ if (!rmw_subscription) {
+ RMW_SET_ERROR_MSG("failed to allocate subscription");
+ goto fail;
+ }
+ rmw_subscription->implementation_identifier = eprosima_fastrtps_identifier;
+ rmw_subscription->data = info;
+ rmw_subscription->topic_name =
+ reinterpret_cast(rmw_allocate(strlen(topic_name) + 1));
+
+ if (!rmw_subscription->topic_name) {
+ RMW_SET_ERROR_MSG("failed to allocate memory for subscription topic name");
+ goto fail;
+ }
+
+ memcpy(const_cast(rmw_subscription->topic_name), topic_name, strlen(topic_name) + 1);
+
+ rmw_subscription->options = *subscription_options;
+ rmw_subscription->can_loan_messages = false;
+ return rmw_subscription;
+
+fail:
+ if (info != nullptr) {
+ delete info->type_support_;
+ delete info->listener_;
+ delete info;
+ }
+ rmw_subscription_free(rmw_subscription);
+ return nullptr;
+}
+} // namespace rmw_fastrtps_dynamic_cpp
diff --git a/rmw_fastrtps_shared_cpp/CMakeLists.txt b/rmw_fastrtps_shared_cpp/CMakeLists.txt
index a8ba7c2f5..9d06fa5fe 100644
--- a/rmw_fastrtps_shared_cpp/CMakeLists.txt
+++ b/rmw_fastrtps_shared_cpp/CMakeLists.txt
@@ -37,6 +37,7 @@ find_package(ament_cmake_ros REQUIRED)
find_package(rcpputils REQUIRED)
find_package(rcutils REQUIRED)
+find_package(rmw_dds_common REQUIRED)
find_package(fastrtps_cmake_module REQUIRED)
find_package(fastcdr REQUIRED CONFIG)
@@ -49,8 +50,11 @@ include_directories(include)
add_library(rmw_fastrtps_shared_cpp
src/custom_publisher_info.cpp
src/custom_subscriber_info.cpp
+ src/create_rmw_gid.cpp
src/demangle.cpp
src/namespace_prefix.cpp
+ src/participant.cpp
+ src/publisher.cpp
src/qos.cpp
src/rmw_client.cpp
src/rmw_compare_gids_equal.cpp
@@ -75,6 +79,7 @@ add_library(rmw_fastrtps_shared_cpp
src/rmw_trigger_guard_condition.cpp
src/rmw_wait.cpp
src/rmw_wait_set.cpp
+ src/subscription.cpp
src/TypeSupport_impl.cpp
)
@@ -87,6 +92,7 @@ ament_target_dependencies(rmw_fastrtps_shared_cpp
"rcpputils"
"rcutils"
"rmw"
+ "rmw_dds_common"
)
# Causes the visibility macros to use dllexport rather than dllimport,
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/create_rmw_gid.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/create_rmw_gid.hpp
new file mode 100644
index 000000000..0435bc4ab
--- /dev/null
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/create_rmw_gid.hpp
@@ -0,0 +1,33 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_SHARED_CPP__CREATE_RMW_GID_HPP_
+#define RMW_FASTRTPS_SHARED_CPP__CREATE_RMW_GID_HPP_
+
+#include "fastrtps/rtps/common/Guid.h"
+
+#include "rmw/types.h"
+
+#include "rmw_fastrtps_shared_cpp/visibility_control.h"
+
+namespace rmw_fastrtps_shared_cpp
+{
+
+RMW_FASTRTPS_SHARED_CPP_PUBLIC
+rmw_gid_t
+create_rmw_gid(const char * identifier, const eprosima::fastrtps::rtps::GUID_t & guid);
+
+} // namespace rmw_fastrtps_shared_cpp
+
+#endif // RMW_FASTRTPS_SHARED_CPP__CREATE_RMW_GID_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_participant_info.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_participant_info.hpp
index 3ce19dbd3..48ae2a221 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_participant_info.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_participant_info.hpp
@@ -20,6 +20,7 @@
#include
#include
+#include "fastrtps/rtps/common/InstanceHandle.h"
#include "fastrtps/attributes/ParticipantAttributes.h"
#include "fastrtps/participant/Participant.h"
#include "fastrtps/participant/ParticipantListener.h"
@@ -27,12 +28,16 @@
#include "rcpputils/thread_safety_annotations.hpp"
#include "rcutils/logging_macros.h"
-#include "rmw/impl/cpp/key_value.hpp"
+#include "rmw/qos_profiles.h"
#include "rmw/rmw.h"
-#include "rmw_common.hpp"
+#include "rmw_dds_common/context.hpp"
-#include "topic_cache.hpp"
+#include "rmw_fastrtps_shared_cpp/create_rmw_gid.hpp"
+#include "rmw_fastrtps_shared_cpp/qos.hpp"
+#include "rmw_fastrtps_shared_cpp/rmw_common.hpp"
+
+using rmw_dds_common::operator<<;
class ParticipantListener;
@@ -53,88 +58,27 @@ typedef struct CustomParticipantInfo
class ParticipantListener : public eprosima::fastrtps::ParticipantListener
{
public:
- explicit ParticipantListener(rmw_guard_condition_t * graph_guard_condition)
- : graph_guard_condition_(graph_guard_condition)
+ explicit ParticipantListener(
+ rmw_guard_condition_t * graph_guard_condition,
+ rmw_dds_common::Context * context)
+ : context(context),
+ graph_guard_condition_(graph_guard_condition)
{}
void onParticipantDiscovery(
eprosima::fastrtps::Participant *,
eprosima::fastrtps::rtps::ParticipantDiscoveryInfo && info) override
{
+ // We aren't monitoring discovered participants, just dropped and removed.
+ // Participants are added to the Graph when they send a ParticipantEntitiesInfo message.
if (
- info.status != eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT &&
info.status != eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT &&
info.status != eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DROPPED_PARTICIPANT)
{
return;
}
-
- std::lock_guard guard(names_mutex_);
- if (eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT == info.status) {
- // ignore already known GUIDs
- if (discovered_names.find(info.info.m_guid) == discovered_names.end()) {
- auto map = rmw::impl::cpp::parse_key_value(info.info.m_userData);
- auto name_found = map.find("name");
- auto ns_found = map.find("namespace");
-
- std::string name;
- if (name_found != map.end()) {
- name = std::string(name_found->second.begin(), name_found->second.end());
- }
-
- std::string namespace_;
- if (ns_found != map.end()) {
- namespace_ = std::string(ns_found->second.begin(), ns_found->second.end());
- }
-
- if (name.empty()) {
- // use participant name if no name was found in the user data
- name = info.info.m_participantName;
- }
- // ignore discovered participants without a name
- if (!name.empty()) {
- discovered_names[info.info.m_guid] = name;
- discovered_namespaces[info.info.m_guid] = namespace_;
- }
- }
- } else {
- {
- auto it = discovered_names.find(info.info.m_guid);
- // only consider known GUIDs
- if (it != discovered_names.end()) {
- discovered_names.erase(it);
- }
- }
- {
- auto it = discovered_namespaces.find(info.info.m_guid);
- // only consider known GUIDs
- if (it != discovered_namespaces.end()) {
- discovered_namespaces.erase(it);
- }
- }
- }
- }
-
- std::vector get_discovered_names() const
- {
- std::lock_guard guard(names_mutex_);
- std::vector names(discovered_names.size());
- size_t i = 0;
- for (auto it : discovered_names) {
- names[i++] = it.second;
- }
- return names;
- }
-
- std::vector get_discovered_namespaces() const
- {
- std::lock_guard guard(names_mutex_);
- std::vector namespaces(discovered_namespaces.size());
- size_t i = 0;
- for (auto it : discovered_namespaces) {
- namespaces[i++] = it.second;
- }
- return namespaces;
+ context->graph_cache.remove_participant(rmw_fastrtps_shared_cpp::create_rmw_gid(
+ graph_guard_condition_->implementation_identifier, info.info.m_guid));
}
void onSubscriberDiscovery(
@@ -159,27 +103,34 @@ class ParticipantListener : public eprosima::fastrtps::ParticipantListener
}
}
+private:
template
- void process_discovery_info(T & proxyData, bool is_alive, bool is_reader)
+ void
+ process_discovery_info(T & proxyData, bool is_alive, bool is_reader)
{
- auto & topic_cache =
- is_reader ? reader_topic_cache : writer_topic_cache;
bool trigger;
{
- std::lock_guard guard(topic_cache.getMutex());
if (is_alive) {
- trigger = topic_cache().addTopic(
- proxyData.RTPSParticipantKey(),
- proxyData.guid(),
+ rmw_qos_profile_t qos_profile = rmw_qos_profile_unknown;
+ dds_qos_to_rmw_qos(proxyData.m_qos, &qos_profile);
+
+ trigger = context->graph_cache.add_entity(
+ rmw_fastrtps_shared_cpp::create_rmw_gid(
+ graph_guard_condition_->implementation_identifier,
+ proxyData.guid()),
proxyData.topicName().to_string(),
proxyData.typeName().to_string(),
- proxyData.m_qos);
+ rmw_fastrtps_shared_cpp::create_rmw_gid(
+ graph_guard_condition_->implementation_identifier,
+ iHandle2GUID(proxyData.RTPSParticipantKey())),
+ qos_profile,
+ is_reader);
} else {
- trigger = topic_cache().removeTopic(
- proxyData.RTPSParticipantKey(),
- proxyData.guid(),
- proxyData.topicName().to_string(),
- proxyData.typeName().to_string());
+ trigger = context->graph_cache.remove_entity(
+ rmw_fastrtps_shared_cpp::create_rmw_gid(
+ graph_guard_condition_->implementation_identifier,
+ proxyData.guid()),
+ is_reader);
}
}
if (trigger) {
@@ -189,12 +140,7 @@ class ParticipantListener : public eprosima::fastrtps::ParticipantListener
}
}
- using guid_map_t = std::map;
- mutable std::mutex names_mutex_;
- guid_map_t discovered_names RCPPUTILS_TSA_GUARDED_BY(names_mutex_);
- guid_map_t discovered_namespaces RCPPUTILS_TSA_GUARDED_BY(names_mutex_);
- LockedObject reader_topic_cache;
- LockedObject writer_topic_cache;
+ rmw_dds_common::Context * context;
rmw_guard_condition_t * graph_guard_condition_;
};
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp
index 7d213f742..e46bf9e81 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/custom_subscriber_info.hpp
@@ -34,7 +34,7 @@
class SubListener;
-typedef struct CustomSubscriberInfo : public CustomEventInfo
+struct CustomSubscriberInfo : public CustomEventInfo
{
virtual ~CustomSubscriberInfo() = default;
@@ -42,12 +42,13 @@ typedef struct CustomSubscriberInfo : public CustomEventInfo
SubListener * listener_;
rmw_fastrtps_shared_cpp::TypeSupport * type_support_;
const void * type_support_impl_;
+ rmw_gid_t subscription_gid_;
const char * typesupport_identifier_;
RMW_FASTRTPS_SHARED_CPP_PUBLIC
EventListenerInterface *
getListener() const final;
-} CustomSubscriberInfo;
+};
class SubListener : public EventListenerInterface, public eprosima::fastrtps::SubscriberListener
{
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp
index a03c71aa8..423286d19 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/names.hpp
@@ -15,27 +15,27 @@
#ifndef RMW_FASTRTPS_SHARED_CPP__NAMES_HPP_
#define RMW_FASTRTPS_SHARED_CPP__NAMES_HPP_
+#include
+
#include "fastrtps/utils/fixed_size_string.hpp"
#include "rmw/types.h"
#include "namespace_prefix.hpp"
-/// Construct a topic name according to proper conventions.
+/// Construct a topic name.
/**
- * \param[in] qos_profile The QoS profile for the topic.
* \param[in] prefix Required prefix for topic name.
* \param[in] base Required name of the topic.
* \param[in] suffix Optional suffix for topic name.
*/
inline
-eprosima::fastrtps::string_255
-_create_topic_name(
- const rmw_qos_profile_t * qos_profile,
+std::string
+_mangle_topic_name(
const char * prefix,
const char * base,
const char * suffix = nullptr)
{
std::ostringstream topicName;
- if (!qos_profile->avoid_ros_namespace_conventions && prefix) {
+ if (prefix) {
topicName << prefix;
}
topicName << base;
@@ -45,4 +45,25 @@ _create_topic_name(
return topicName.str();
}
+/// Construct a topic name according to proper conventions.
+/**
+ * \param[in] qos_profile The QoS profile for the topic.
+ * \param[in] prefix Required prefix for topic name.
+ * \param[in] base Required name of the topic.
+ * \param[in] suffix Optional suffix for topic name.
+ */
+inline
+std::string
+_create_topic_name(
+ const rmw_qos_profile_t * qos_profile,
+ const char * prefix,
+ const char * base,
+ const char * suffix = nullptr)
+{
+ if (qos_profile->avoid_ros_namespace_conventions) {
+ prefix = nullptr;
+ }
+ return _mangle_topic_name(prefix, base, suffix);
+}
+
#endif // RMW_FASTRTPS_SHARED_CPP__NAMES_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp
index fa4512497..08bb3a787 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/namespace_prefix.hpp
@@ -29,6 +29,16 @@ RMW_FASTRTPS_SHARED_CPP_PUBLIC extern const char * const ros_service_response_pr
RMW_FASTRTPS_SHARED_CPP_PUBLIC extern const std::vector _ros_prefixes;
} // extern "C"
+/// Returns `name` stripped of `prefix` if exists, if not return "".
+/**
+ * \param[in] name string that will be stripped from prefix
+ * \param[in] prefix prefix to be stripped
+ * \return name stripped of prefix, or
+ * \return "" if name doesn't start with prefix
+ */
+std::string
+_resolve_prefix(const std::string & name, const std::string & prefix);
+
/// Return the ROS specific prefix if it exists, otherwise "".
std::string
_get_ros_prefix_if_exists(const std::string & topic_name);
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/participant.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/participant.hpp
new file mode 100644
index 000000000..b5608f632
--- /dev/null
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/participant.hpp
@@ -0,0 +1,39 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_SHARED_CPP__PARTICIPANT_HPP_
+#define RMW_FASTRTPS_SHARED_CPP__PARTICIPANT_HPP_
+
+#include "rmw/types.h"
+
+#include "rmw_dds_common/context.hpp"
+
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_shared_cpp
+{
+
+CustomParticipantInfo *
+create_participant(
+ const char * identifier,
+ size_t domain_id,
+ const rmw_security_options_t * security_options,
+ bool localhost_only,
+ rmw_dds_common::Context * common_context);
+
+rmw_ret_t
+destroy_participant(CustomParticipantInfo * info);
+} // namespace rmw_fastrtps_shared_cpp
+
+#endif // RMW_FASTRTPS_SHARED_CPP__PARTICIPANT_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/publisher.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/publisher.hpp
new file mode 100644
index 000000000..3dae78b6c
--- /dev/null
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/publisher.hpp
@@ -0,0 +1,32 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_SHARED_CPP__PUBLISHER_HPP_
+#define RMW_FASTRTPS_SHARED_CPP__PUBLISHER_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_shared_cpp
+{
+
+rmw_ret_t
+destroy_publisher(
+ const char * identifier,
+ CustomParticipantInfo * participant_info,
+ rmw_publisher_t * publisher);
+
+} // namespace rmw_fastrtps_shared_cpp
+
+#endif // RMW_FASTRTPS_SHARED_CPP__PUBLISHER_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/qos.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/qos.hpp
index fed276204..1857abba7 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/qos.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/qos.hpp
@@ -1,3 +1,4 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
// Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,11 +16,15 @@
#ifndef RMW_FASTRTPS_SHARED_CPP__QOS_HPP_
#define RMW_FASTRTPS_SHARED_CPP__QOS_HPP_
+#include "fastrtps/attributes/PublisherAttributes.h"
+#include "fastrtps/attributes/SubscriberAttributes.h"
+#include "fastrtps/qos/QosPolicies.h"
+#include "fastrtps/qos/ReaderQos.h"
+#include "fastrtps/qos/WriterQos.h"
+
#include "rmw/rmw.h"
-#include "./visibility_control.h"
-#include "fastrtps/qos/WriterQos.h"
-#include "fastrtps/qos/ReaderQos.h"
+#include "rmw_fastrtps_shared_cpp/visibility_control.h"
namespace eprosima
{
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_common.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_common.hpp
index a73ce8fbf..567abde87 100644
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_common.hpp
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_common.hpp
@@ -86,12 +86,10 @@ __rmw_set_log_severity(rmw_log_severity_t severity);
RMW_FASTRTPS_SHARED_CPP_PUBLIC
rmw_node_t *
__rmw_create_node(
+ rmw_context_t * context,
const char * identifier,
const char * name,
- const char * namespace_,
- size_t domain_id,
- const rmw_node_security_options_t * security_options,
- bool localhost_only);
+ const char * namespace_);
RMW_FASTRTPS_SHARED_CPP_PUBLIC
rmw_ret_t
@@ -143,7 +141,7 @@ RMW_FASTRTPS_SHARED_CPP_PUBLIC
rmw_ret_t
__rmw_destroy_publisher(
const char * identifier,
- rmw_node_t * node,
+ const rmw_node_t * node,
rmw_publisher_t * publisher);
RMW_FASTRTPS_SHARED_CPP_PUBLIC
@@ -261,7 +259,7 @@ RMW_FASTRTPS_SHARED_CPP_PUBLIC
rmw_ret_t
__rmw_destroy_subscription(
const char * identifier,
- rmw_node_t * node,
+ const rmw_node_t * node,
rmw_subscription_t * subscription);
RMW_FASTRTPS_SHARED_CPP_PUBLIC
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_context_impl.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_context_impl.hpp
new file mode 100644
index 000000000..6a985561a
--- /dev/null
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/rmw_context_impl.hpp
@@ -0,0 +1,28 @@
+// Copyright 2020 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_SHARED_CPP__RMW_CONTEXT_IMPL_HPP_
+#define RMW_FASTRTPS_SHARED_CPP__RMW_CONTEXT_IMPL_HPP_
+
+#include
+
+struct rmw_context_impl_t
+{
+ void * common;
+ void * participant_info;
+ std::mutex mutex;
+ uint64_t count;
+};
+
+#endif // RMW_FASTRTPS_SHARED_CPP__RMW_CONTEXT_IMPL_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/subscription.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/subscription.hpp
new file mode 100644
index 000000000..b959a3669
--- /dev/null
+++ b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/subscription.hpp
@@ -0,0 +1,32 @@
+// Copyright 2019 Open Source Robotics Foundation, Inc.
+//
+// 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 RMW_FASTRTPS_SHARED_CPP__SUBSCRIPTION_HPP_
+#define RMW_FASTRTPS_SHARED_CPP__SUBSCRIPTION_HPP_
+
+#include "rmw/rmw.h"
+#include "rmw_fastrtps_shared_cpp/custom_participant_info.hpp"
+
+namespace rmw_fastrtps_shared_cpp
+{
+
+rmw_ret_t
+destroy_subscription(
+ const char * identifier,
+ CustomParticipantInfo * participant_info,
+ rmw_subscription_t * subscription);
+
+} // namespace rmw_fastrtps_shared_cpp
+
+#endif // RMW_FASTRTPS_SHARED_CPP__SUBSCRIPTION_HPP_
diff --git a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/topic_cache.hpp b/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/topic_cache.hpp
deleted file mode 100644
index a6201a3fb..000000000
--- a/rmw_fastrtps_shared_cpp/include/rmw_fastrtps_shared_cpp/topic_cache.hpp
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-//
-// 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 RMW_FASTRTPS_SHARED_CPP__TOPIC_CACHE_HPP_
-#define RMW_FASTRTPS_SHARED_CPP__TOPIC_CACHE_HPP_
-
-#include
-#include
-#include