From 1f80c012b2a62fc5b8d001a300068ffb8fd7adff Mon Sep 17 00:00:00 2001 From: eduponz Date: Tue, 18 Jun 2024 15:25:29 +0200 Subject: [PATCH 01/46] Refs #21188: Update header guards in other examples Signed-off-by: eduponz --- examples/cpp/content_filter/CLIParser.hpp | 6 +++--- .../cpp/content_filter/CustomContentFilter.hpp | 14 ++++++++++++++ .../content_filter/CustomContentFilterFactory.hpp | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/examples/cpp/content_filter/CLIParser.hpp b/examples/cpp/content_filter/CLIParser.hpp index 291ce9a2d22..de6f13eea3c 100644 --- a/examples/cpp/content_filter/CLIParser.hpp +++ b/examples/cpp/content_filter/CLIParser.hpp @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifndef FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CLIPARSER_HPP +#define FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CLIPARSER_HPP + #include #include #include @@ -19,9 +22,6 @@ #include -#ifndef FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CLIPARSER_HPP -#define FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CLIPARSER_HPP - namespace eprosima { namespace fastdds { namespace examples { diff --git a/examples/cpp/content_filter/CustomContentFilter.hpp b/examples/cpp/content_filter/CustomContentFilter.hpp index ae63b9759f3..9d99f9b2f5d 100644 --- a/examples/cpp/content_filter/CustomContentFilter.hpp +++ b/examples/cpp/content_filter/CustomContentFilter.hpp @@ -1,3 +1,17 @@ +// Copyright 2024 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. + #ifndef FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CUSTOMCONTENTFILTER_HPP #define FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CUSTOMCONTENTFILTER_HPP diff --git a/examples/cpp/content_filter/CustomContentFilterFactory.hpp b/examples/cpp/content_filter/CustomContentFilterFactory.hpp index aed72191c01..8d710e123c9 100644 --- a/examples/cpp/content_filter/CustomContentFilterFactory.hpp +++ b/examples/cpp/content_filter/CustomContentFilterFactory.hpp @@ -1,3 +1,17 @@ +// Copyright 2024 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. + #ifndef FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CUSTOMCONTENTFILTERFACTORY_HPP #define FASTDDS_EXAMPLES_CPP_CONTENT_FILTER__CUSTOMCONTENTFILTERFACTORY_HPP From 59b12333c4dee6192b5b5599e0418faf7197e6c9 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 19 Jun 2024 09:49:46 +0200 Subject: [PATCH 02/46] Refs #21188: CLIParser and example skeleton Signed-off-by: eduponz --- examples/CMakeLists.txt | 1 + examples/cpp/request_reply/Application.cpp | 62 ++++ examples/cpp/request_reply/Application.hpp | 57 ++++ examples/cpp/request_reply/CLIParser.hpp | 317 +++++++++++++++++++++ examples/cpp/request_reply/CMakeLists.txt | 64 +++++ examples/cpp/request_reply/ClientApp.cpp | 50 ++++ examples/cpp/request_reply/ClientApp.hpp | 54 ++++ examples/cpp/request_reply/README.md | 1 + examples/cpp/request_reply/ServerApp.cpp | 50 ++++ examples/cpp/request_reply/ServerApp.hpp | 55 ++++ examples/cpp/request_reply/main.cpp | 92 ++++++ 11 files changed, 803 insertions(+) create mode 100644 examples/cpp/request_reply/Application.cpp create mode 100644 examples/cpp/request_reply/Application.hpp create mode 100644 examples/cpp/request_reply/CLIParser.hpp create mode 100644 examples/cpp/request_reply/CMakeLists.txt create mode 100644 examples/cpp/request_reply/ClientApp.cpp create mode 100644 examples/cpp/request_reply/ClientApp.hpp create mode 100644 examples/cpp/request_reply/README.md create mode 100644 examples/cpp/request_reply/ServerApp.cpp create mode 100644 examples/cpp/request_reply/ServerApp.hpp create mode 100644 examples/cpp/request_reply/main.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0e302bf89dd..e90047deb56 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -21,6 +21,7 @@ add_subdirectory(cpp/dds) add_subdirectory(cpp/delivery_mechanisms) add_subdirectory(cpp/discovery_server) add_subdirectory(cpp/hello_world) +add_subdirectory(cpp/request_reply) add_subdirectory(cpp/rtps) add_subdirectory(cpp/xtypes) diff --git a/examples/cpp/request_reply/Application.cpp b/examples/cpp/request_reply/Application.cpp new file mode 100644 index 00000000000..c52266672fc --- /dev/null +++ b/examples/cpp/request_reply/Application.cpp @@ -0,0 +1,62 @@ +// Copyright 2024 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. + +/** + * @file Application.cpp + * + */ + +#include "Application.hpp" + +#include "CLIParser.hpp" +#include "ServerApp.hpp" +#include "ClientApp.hpp" + +using namespace eprosima::fastdds::dds; + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +//! Factory method to create a server or client +std::shared_ptr Application::make_app( + const CLIParser::config& config, + const std::string& service_name) +{ + std::shared_ptr entity; + switch (config.entity) + { + case CLIParser::EntityKind::SERVER: + { + entity = std::make_shared(config, service_name); + break; + } + case CLIParser::EntityKind::CLIENT: + { + entity = std::make_shared(config, service_name); + break; + } + case CLIParser::EntityKind::UNDEFINED: + default: + throw std::runtime_error("Entity initialization failed"); + break; + } + return entity; +} + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/request_reply/Application.hpp b/examples/cpp/request_reply/Application.hpp new file mode 100644 index 00000000000..41e533717d0 --- /dev/null +++ b/examples/cpp/request_reply/Application.hpp @@ -0,0 +1,57 @@ +// Copyright 2024 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. + +/** + * @file Application.hpp + * + */ + +#ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APPLICATION_HPP +#define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APPLICATION_HPP + +#include +#include + +#include "CLIParser.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +class Application +{ +public: + + //! Virtual destructor + virtual ~Application() = default; + + //! Run application + virtual void run() = 0; + + //! Trigger the end of execution + virtual void stop() = 0; + + //! Factory method to create applications based on configuration + static std::shared_ptr make_app( + const CLIParser::config& config, + const std::string& service_name); +}; + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APPLICATION_HPP */ diff --git a/examples/cpp/request_reply/CLIParser.hpp b/examples/cpp/request_reply/CLIParser.hpp new file mode 100644 index 00000000000..66655de48ed --- /dev/null +++ b/examples/cpp/request_reply/CLIParser.hpp @@ -0,0 +1,317 @@ +// Copyright 2024 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 +#include +#include +#include +#include +#include +#include + +#include + +#ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIPARSER_HPP +#define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIPARSER_HPP + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +using dds::Log; + +class CLIParser +{ +public: + + CLIParser() = delete; + + //! Entity kind enumeration + enum class EntityKind : std::uint8_t + { + SERVER, + CLIENT, + UNDEFINED + }; + + //! Operation enumeration + enum class Operation : std::uint8_t + { + ADDITION, + SUBTRACTION, + MULTIPLICATION, + DIVISION, + UNDEFINED + }; + + //! Configuration structure for the application + struct config + { + CLIParser::EntityKind entity = CLIParser::EntityKind::UNDEFINED; + CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; + std::int16_t x = 0; + std::int16_t y = 0; + }; + + /** + * @brief Print usage help message and exit with the given return code + * + * @param[in] return_code return code to exit with + * + * @warning This method finishes the execution of the program with the input return code + */ + static void print_help( + const std::uint8_t return_code) + { + std::cout << "Service to perform an operation on two 16-bit integers" << std::endl; + std::cout << "Usage: request_reply [options] [arguments]" << std::endl; + std::cout << "" << std::endl; + std::cout << "Entities:" << std::endl; + std::cout << " server Run a server entity" << std::endl; + std::cout << " client Run a client entity" << std::endl; + std::cout << "" << std::endl; + std::cout << "Common options:" << std::endl; + std::cout << " -h, --help Print this help message" << std::endl; + std::cout << "" << std::endl; + std::cout << "Client arguments:" << std::endl; + std::cout << " [NUMBER] <+|-|x|/> [NUMBER] Operation to be performed" << std::endl; + std::exit(return_code); + } + + /** + * @brief Parse the command line options and return the config object + * + * @param[in] argc number of arguments + * @param[in] argv array of arguments + * + * @return config object with the parsed options + * + * @warning This method finishes the execution of the program if the input arguments are invalid + */ + static config parse_cli_options( + const int argc, + const char* const argv[]) + { + config config; + + if (argc < 2) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "missing entity argument"); + print_help(EXIT_FAILURE); + } + + std::string first_argument = argv[1]; + + if (first_argument == "server" ) + { + config.entity = CLIParser::EntityKind::SERVER; + } + else if (first_argument == "client") + { + config.entity = CLIParser::EntityKind::CLIENT; + } + else if (first_argument == "-h" || first_argument == "--help") + { + print_help(EXIT_SUCCESS); + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "parsing entity argument " + first_argument); + print_help(EXIT_FAILURE); + } + + for (int i = 2; i < argc; ++i) + { + if (std::string(argv[i]) == "-h" || std::string(argv[i]) == "--help") + { + print_help(EXIT_SUCCESS); + } + } + + if (CLIParser::EntityKind::CLIENT == config.entity) + { + if (argc != 5) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "Incorrect number of arguments for client entity"); + print_help(EXIT_FAILURE); + } + + consume_client_arguments(argc, argv, config); + } + + return config; + } + + /** + * @brief Parse the signal number into the signal name + * + * @param[in] signum signal number + * + * @return std::string signal name + */ + static std::string parse_signal( + const int& signum) + { + switch (signum) + { + case SIGINT: + return "SIGINT"; + case SIGTERM: + return "SIGTERM"; +#ifndef _WIN32 + case SIGQUIT: + return "SIGQUIT"; + case SIGHUP: + return "SIGHUP"; +#endif // _WIN32 + default: + return "UNKNOWN SIGNAL"; + } + } + + /** + * @brief Parse the entity kind into std::string + * + * @param[in] entity entity kind + * + * @return std::string entity kind + */ + static std::string parse_entity_kind( + const EntityKind& entity) + { + switch (entity) + { + case EntityKind::SERVER: + return "Server"; + case EntityKind::CLIENT: + return "Client"; + case EntityKind::UNDEFINED: + default: + return "Undefined entity"; + } + } + +private: + + /** + * @brief Consume the client arguments and store them in the config object + * + * @param[in] argc number of arguments + * @param[in] argv array of arguments + * + * @param[in,out] config config object to store the arguments + * + * @warning This method finishes the execution of the program if the input arguments are invalid + */ + static void consume_client_arguments( + const int argc, + const char* const argv[], + config& config) + { + static_cast(argc); + assert(argc >= 5); + config.x = consume_int16_argument(argv[2]); + config.operation = consume_operation_argument(argv[3]); + config.y = consume_int16_argument(argv[4]); + } + + /** + * @brief Consume an int16 argument and return it + * + * @param[in] arg string argument to consume + * + * @return std::int16_t int16 argument + * + * @warning This method finishes the execution of the program if the input arguments are invalid + */ + static std::int16_t consume_int16_argument( + const std::string& arg) + { + std::int16_t value = 0; + + try + { + int input = std::stoi(arg); + + if (input < std::numeric_limits::min() || + input > std::numeric_limits::max()) + { + throw std::out_of_range("int16 argument out of range"); + } + + value = static_cast(input); + } + catch (const std::invalid_argument& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid int16 argument for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + catch (const std::out_of_range& e) + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "int16 argument out of range for " + arg + ": " + e.what()); + print_help(EXIT_FAILURE); + } + + return value; + } + + /** + * @brief Consume an operation argument and return it + * + * @param[in] arg string argument to consume + * + * @return Operation operation argument + * + * @warning This method finishes the execution of the program if the input arguments are invalid + */ + static Operation consume_operation_argument( + const std::string& arg) + { + Operation operation = Operation::UNDEFINED; + + if (arg == "+") + { + operation = Operation::ADDITION; + } + else if (arg == "-") + { + operation = Operation::SUBTRACTION; + } + else if (arg == "x") + { + operation = Operation::MULTIPLICATION; + } + else if (arg == "/") + { + operation = Operation::DIVISION; + } + else + { + EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid operation argument: " + arg); + print_help(EXIT_FAILURE); + } + + return operation; + } + +}; + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif // FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIPARSER_HPP diff --git a/examples/cpp/request_reply/CMakeLists.txt b/examples/cpp/request_reply/CMakeLists.txt new file mode 100644 index 00000000000..eeda0a3756a --- /dev/null +++ b/examples/cpp/request_reply/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright 2024 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. + +cmake_minimum_required(VERSION 3.20) + +project(fastdds_request_reply_example VERSION 1 LANGUAGES CXX) + +# Find requirements +if(NOT fastcdr_FOUND) + find_package(fastcdr 2 REQUIRED) +endif() + +if(NOT fastdds_FOUND) + find_package(fastdds 3 REQUIRED) +endif() + +#Check C++11 +include(CheckCXXCompilerFlag) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11) + if(NOT SUPPORTS_CXX11) + message(FATAL_ERROR "Compiler doesn't support C++11") + endif() +endif() + +message(STATUS "Configuring ${PROJECT_NAME}...") +file(GLOB REQUEST_REPLY_SOURCES_CXX "*.cxx") +file(GLOB REQUEST_REPLY_SOURCES_CPP "*.cpp") + +add_executable(request_reply ${REQUEST_REPLY_SOURCES_CXX} ${REQUEST_REPLY_SOURCES_CPP}) +target_compile_definitions(request_reply PRIVATE + $<$>,$>:__DEBUG> + $<$:__INTERNALDEBUG> # Internal debug activated. + $<$:SHM_TRANSPORT_BUILTIN> # Enable SHM as built-in transport +) +target_link_libraries(request_reply fastdds fastcdr) +install(TARGETS request_reply + RUNTIME DESTINATION ${DATA_INSTALL_DIR}/fastdds/examples/cpp/request_reply/${BIN_INSTALL_DIR}) + +# Copy the XML files over to the build directory +file(GLOB_RECURSE XML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.xml) +# for each xml file detected +foreach(XML_FILE_COMPLETE_PATH ${XML_FILES}) + # obtain the file name + get_filename_component(XML_FILE ${XML_FILE_COMPLETE_PATH} NAME_WE) + # copy the file from src to build folders + configure_file( + ${XML_FILE_COMPLETE_PATH} # from full src path + ${CMAKE_CURRENT_BINARY_DIR}/${XML_FILE}.xml # to relative build path + COPYONLY) + install(FILES ${XML_FILE_COMPLETE_PATH} + DESTINATION ${DATA_INSTALL_DIR}/fastdds/examples/cpp/request_reply/${BIN_INSTALL_DIR}) +endforeach() diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp new file mode 100644 index 00000000000..9568e47bbae --- /dev/null +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -0,0 +1,50 @@ +// Copyright 2024 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. + +/** + * @file ClientApp.cpp + * + */ + +#include "ClientApp.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +ClientApp::ClientApp( + const CLIParser::config& config, + const std::string& service_name) +{ + static_cast(config); + static_cast(service_name); +} + +ClientApp::~ClientApp() +{ +} + +void ClientApp::run() +{ +} + +void ClientApp::stop() +{ +} + +} // namespace request_reply { +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp new file mode 100644 index 00000000000..0319e29bce3 --- /dev/null +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -0,0 +1,54 @@ +// Copyright 2024 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. + +/** + * @file ClientApp.hpp + * + */ + +#ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP +#define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP + +#include "Application.hpp" +#include "CLIParser.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +class ClientApp : public Application +{ +public: + + ClientApp( + const CLIParser::config& config, + const std::string& service_name); + + ~ClientApp(); + + //! Run subscriber + void run() override; + + //! Trigger the end of execution + void stop() override; + +}; + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP */ diff --git a/examples/cpp/request_reply/README.md b/examples/cpp/request_reply/README.md new file mode 100644 index 00000000000..47d94118beb --- /dev/null +++ b/examples/cpp/request_reply/README.md @@ -0,0 +1 @@ +# Request-Reply example diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp new file mode 100644 index 00000000000..0cc39825573 --- /dev/null +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -0,0 +1,50 @@ +// Copyright 2024 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. + +/** + * @file ServerApp.cpp + * + */ + +#include "ServerApp.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +ServerApp::ServerApp( + const CLIParser::config& config, + const std::string& service_name) +{ + static_cast(config); + static_cast(service_name); +} + +ServerApp::~ServerApp() +{ +} + +void ServerApp::run() +{ +} + +void ServerApp::stop() +{ +} + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp new file mode 100644 index 00000000000..ff1c5ffb383 --- /dev/null +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -0,0 +1,55 @@ +// Copyright 2024 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. + +/** + * @file ServerApp.hpp + * + */ + +#ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__SERVERAPP_HPP +#define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__SERVERAPP_HPP + +#include + +#include "Application.hpp" +#include "CLIParser.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +class ServerApp : public Application +{ +public: + + ServerApp( + const CLIParser::config& config, + const std::string& service_name); + + ~ServerApp(); + + //! Run server + void run() override; + + //! Stop server + void stop() override; +}; + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif /* FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__SERVERAPP_HPP */ diff --git a/examples/cpp/request_reply/main.cpp b/examples/cpp/request_reply/main.cpp new file mode 100644 index 00000000000..792570dae5d --- /dev/null +++ b/examples/cpp/request_reply/main.cpp @@ -0,0 +1,92 @@ +// Copyright 2024 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. + +/** + * @file main.cpp + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Application.hpp" +#include "CLIParser.hpp" + +using eprosima::fastdds::dds::Log; + +using namespace eprosima::fastdds::examples::request_reply; + +std::function stop_app_handler; + +void signal_handler( + int signum) +{ + stop_app_handler(signum); +} + +int main( + int argc, + char** argv) +{ + auto ret = EXIT_SUCCESS; + const std::string service_name = "calculator_service"; + CLIParser::config config = CLIParser::parse_cli_options(argc, argv); + + std::string app_name = CLIParser::parse_entity_kind(config.entity); + std::shared_ptr app; + + try + { + app = Application::make_app(config, service_name); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(app_name, e.what()); + ret = EXIT_FAILURE; + } + + if (EXIT_FAILURE != ret) + { + std::thread thread(&Application::run, app); + + stop_app_handler = [&](int signum) + { + std::cout << "\n" << CLIParser::parse_signal(signum) << " received, stopping " << app_name + << " execution." << std::endl; + app->stop(); + }; + + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + #ifndef _WIN32 + signal(SIGQUIT, signal_handler); + signal(SIGHUP, signal_handler); + #endif // _WIN32 + + std::cout << app_name << " running. Please press Ctrl+C to stop the " + << app_name << " at any time." << std::endl; + + thread.join(); + } + + Log::Reset(); + return ret; +} From ea54cea66f5f53a10bcbbb2ac41df33ec3c21a11 Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 27 Jun 2024 16:26:14 +0200 Subject: [PATCH 03/46] Refs #21188: Add IDL and type support Signed-off-by: eduponz --- examples/cpp/request_reply/Calculator.hpp | 386 ++++++++++++++++ examples/cpp/request_reply/Calculator.idl | 22 + .../cpp/request_reply/CalculatorCdrAux.hpp | 54 +++ .../cpp/request_reply/CalculatorCdrAux.ipp | 210 +++++++++ .../request_reply/CalculatorPubSubTypes.cxx | 422 ++++++++++++++++++ .../request_reply/CalculatorPubSubTypes.hpp | 224 ++++++++++ .../CalculatorTypeObjectSupport.cxx | 305 +++++++++++++ .../CalculatorTypeObjectSupport.hpp | 80 ++++ 8 files changed, 1703 insertions(+) create mode 100644 examples/cpp/request_reply/Calculator.hpp create mode 100644 examples/cpp/request_reply/Calculator.idl create mode 100644 examples/cpp/request_reply/CalculatorCdrAux.hpp create mode 100644 examples/cpp/request_reply/CalculatorCdrAux.ipp create mode 100644 examples/cpp/request_reply/CalculatorPubSubTypes.cxx create mode 100644 examples/cpp/request_reply/CalculatorPubSubTypes.hpp create mode 100644 examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx create mode 100644 examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp diff --git a/examples/cpp/request_reply/Calculator.hpp b/examples/cpp/request_reply/Calculator.hpp new file mode 100644 index 00000000000..d87ec4c9b14 --- /dev/null +++ b/examples/cpp/request_reply/Calculator.hpp @@ -0,0 +1,386 @@ +// Copyright 2016 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. + +/*! + * @file Calculator.hpp + * This header file contains the declaration of the described types in the IDL file. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__CALCULATOR_HPP +#define FAST_DDS_GENERATED__CALCULATOR_HPP + +#include +#include + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(CALCULATOR_SOURCE) +#define CALCULATOR_DllAPI __declspec( dllexport ) +#else +#define CALCULATOR_DllAPI __declspec( dllimport ) +#endif // CALCULATOR_SOURCE +#else +#define CALCULATOR_DllAPI +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define CALCULATOR_DllAPI +#endif // _WIN32 + +/*! + * @brief This class represents the enumeration CalculatorOperationType defined by the user in the IDL file. + * @ingroup Calculator + */ +enum class CalculatorOperationType : int32_t +{ + ADDITION, + SUBTRACTION, + MULTIPLICATION, + DIVISION +}; +/*! + * @brief This class represents the structure CalculatorRequestType defined by the user in the IDL file. + * @ingroup Calculator + */ +class CalculatorRequestType +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport CalculatorRequestType() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~CalculatorRequestType() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object CalculatorRequestType that will be copied. + */ + eProsima_user_DllExport CalculatorRequestType( + const CalculatorRequestType& x) + { + m_operation = x.m_operation; + + m_x = x.m_x; + + m_y = x.m_y; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object CalculatorRequestType that will be copied. + */ + eProsima_user_DllExport CalculatorRequestType( + CalculatorRequestType&& x) noexcept + { + m_operation = x.m_operation; + m_x = x.m_x; + m_y = x.m_y; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object CalculatorRequestType that will be copied. + */ + eProsima_user_DllExport CalculatorRequestType& operator =( + const CalculatorRequestType& x) + { + + m_operation = x.m_operation; + + m_x = x.m_x; + + m_y = x.m_y; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object CalculatorRequestType that will be copied. + */ + eProsima_user_DllExport CalculatorRequestType& operator =( + CalculatorRequestType&& x) noexcept + { + + m_operation = x.m_operation; + m_x = x.m_x; + m_y = x.m_y; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x CalculatorRequestType object to compare. + */ + eProsima_user_DllExport bool operator ==( + const CalculatorRequestType& x) const + { + return (m_operation == x.m_operation && + m_x == x.m_x && + m_y == x.m_y); + } + + /*! + * @brief Comparison operator. + * @param x CalculatorRequestType object to compare. + */ + eProsima_user_DllExport bool operator !=( + const CalculatorRequestType& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member operation + * @param _operation New value for member operation + */ + eProsima_user_DllExport void operation( + CalculatorOperationType _operation) + { + m_operation = _operation; + } + + /*! + * @brief This function returns the value of member operation + * @return Value of member operation + */ + eProsima_user_DllExport CalculatorOperationType operation() const + { + return m_operation; + } + + /*! + * @brief This function returns a reference to member operation + * @return Reference to member operation + */ + eProsima_user_DllExport CalculatorOperationType& operation() + { + return m_operation; + } + + + /*! + * @brief This function sets a value in member x + * @param _x New value for member x + */ + eProsima_user_DllExport void x( + int16_t _x) + { + m_x = _x; + } + + /*! + * @brief This function returns the value of member x + * @return Value of member x + */ + eProsima_user_DllExport int16_t x() const + { + return m_x; + } + + /*! + * @brief This function returns a reference to member x + * @return Reference to member x + */ + eProsima_user_DllExport int16_t& x() + { + return m_x; + } + + + /*! + * @brief This function sets a value in member y + * @param _y New value for member y + */ + eProsima_user_DllExport void y( + int16_t _y) + { + m_y = _y; + } + + /*! + * @brief This function returns the value of member y + * @return Value of member y + */ + eProsima_user_DllExport int16_t y() const + { + return m_y; + } + + /*! + * @brief This function returns a reference to member y + * @return Reference to member y + */ + eProsima_user_DllExport int16_t& y() + { + return m_y; + } + + + +private: + + CalculatorOperationType m_operation{CalculatorOperationType::ADDITION}; + int16_t m_x{0}; + int16_t m_y{0}; + +}; +/*! + * @brief This class represents the structure CalculatorReplyType defined by the user in the IDL file. + * @ingroup Calculator + */ +class CalculatorReplyType +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport CalculatorReplyType() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~CalculatorReplyType() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object CalculatorReplyType that will be copied. + */ + eProsima_user_DllExport CalculatorReplyType( + const CalculatorReplyType& x) + { + m_z = x.m_z; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object CalculatorReplyType that will be copied. + */ + eProsima_user_DllExport CalculatorReplyType( + CalculatorReplyType&& x) noexcept + { + m_z = x.m_z; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object CalculatorReplyType that will be copied. + */ + eProsima_user_DllExport CalculatorReplyType& operator =( + const CalculatorReplyType& x) + { + + m_z = x.m_z; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object CalculatorReplyType that will be copied. + */ + eProsima_user_DllExport CalculatorReplyType& operator =( + CalculatorReplyType&& x) noexcept + { + + m_z = x.m_z; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x CalculatorReplyType object to compare. + */ + eProsima_user_DllExport bool operator ==( + const CalculatorReplyType& x) const + { + return (m_z == x.m_z); + } + + /*! + * @brief Comparison operator. + * @param x CalculatorReplyType object to compare. + */ + eProsima_user_DllExport bool operator !=( + const CalculatorReplyType& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member z + * @param _z New value for member z + */ + eProsima_user_DllExport void z( + int32_t _z) + { + m_z = _z; + } + + /*! + * @brief This function returns the value of member z + * @return Value of member z + */ + eProsima_user_DllExport int32_t z() const + { + return m_z; + } + + /*! + * @brief This function returns a reference to member z + * @return Reference to member z + */ + eProsima_user_DllExport int32_t& z() + { + return m_z; + } + + + +private: + + int32_t m_z{0}; + +}; + +#endif // _FAST_DDS_GENERATED_CALCULATOR_HPP_ + + diff --git a/examples/cpp/request_reply/Calculator.idl b/examples/cpp/request_reply/Calculator.idl new file mode 100644 index 00000000000..4306b9bf2d8 --- /dev/null +++ b/examples/cpp/request_reply/Calculator.idl @@ -0,0 +1,22 @@ +@extensibility(APPENDABLE) +enum CalculatorOperationType +{ + ADDITION, + SUBTRACTION, + MULTIPLICATION, + DIVISION +}; + +@extensibility(APPENDABLE) +struct CalculatorRequestType +{ + CalculatorOperationType operation; + short x; + short y; +}; + +@extensibility(APPENDABLE) +struct CalculatorReplyType +{ + long z; +}; diff --git a/examples/cpp/request_reply/CalculatorCdrAux.hpp b/examples/cpp/request_reply/CalculatorCdrAux.hpp new file mode 100644 index 00000000000..8119c875fec --- /dev/null +++ b/examples/cpp/request_reply/CalculatorCdrAux.hpp @@ -0,0 +1,54 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorCdrAux.hpp + * This source file contains some definitions of CDR related functions. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP +#define FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP + +#include "Calculator.hpp" + +constexpr uint32_t CalculatorRequestType_max_cdr_typesize {12UL}; +constexpr uint32_t CalculatorRequestType_max_key_cdr_typesize {0UL}; + +constexpr uint32_t CalculatorReplyType_max_cdr_typesize {8UL}; +constexpr uint32_t CalculatorReplyType_max_key_cdr_typesize {0UL}; + + + +namespace eprosima { +namespace fastcdr { + +class Cdr; +class CdrSizeCalculator; + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data); + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP + diff --git a/examples/cpp/request_reply/CalculatorCdrAux.ipp b/examples/cpp/request_reply/CalculatorCdrAux.ipp new file mode 100644 index 00000000000..4052fd5e9e5 --- /dev/null +++ b/examples/cpp/request_reply/CalculatorCdrAux.ipp @@ -0,0 +1,210 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorCdrAux.ipp + * This source file contains some declarations of CDR related functions. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP +#define FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP + +#include "CalculatorCdrAux.hpp" + +#include +#include + + +#include +using namespace eprosima::fastcdr::exception; + +namespace eprosima { +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorRequestType& data, + size_t& current_alignment) +{ + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.operation(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.x(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.y(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) +{ + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.operation() + << eprosima::fastcdr::MemberId(1) << data.x() + << eprosima::fastcdr::MemberId(2) << data.y() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorRequestType& data) +{ + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.operation(); + break; + + case 1: + dcdr >> data.x(); + break; + + case 2: + dcdr >> data.y(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) +{ + static_cast(scdr); + static_cast(data); +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorReplyType& data, + size_t& current_alignment) +{ + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.z(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) +{ + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.z() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorReplyType& data) +{ + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.z(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) +{ + static_cast(scdr); + static_cast(data); +} + + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP + diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx new file mode 100644 index 00000000000..ecd48faa290 --- /dev/null +++ b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx @@ -0,0 +1,422 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorPubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastddsgen. + */ + +#include "CalculatorPubSubTypes.hpp" + +#include +#include + +#include "CalculatorCdrAux.hpp" +#include "CalculatorTypeObjectSupport.hpp" + +using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; +using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; +using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; + +CalculatorRequestTypePubSubType::CalculatorRequestTypePubSubType() +{ + setName("CalculatorRequestType"); + uint32_t type_size = +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(CalculatorRequestType::getMaxCdrSerializedSize()); +#else + CalculatorRequestType_max_cdr_typesize; +#endif + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + m_typeSize = type_size + 4; /*encapsulation*/ + m_isGetKeyDefined = false; + uint32_t keyLength = CalculatorRequestType_max_key_cdr_typesize > 16 ? CalculatorRequestType_max_key_cdr_typesize : 16; + m_keyBuffer = reinterpret_cast(malloc(keyLength)); + memset(m_keyBuffer, 0, keyLength); +} + +CalculatorRequestTypePubSubType::~CalculatorRequestTypePubSubType() +{ + if (m_keyBuffer != nullptr) + { + free(m_keyBuffer); + } +} + +bool CalculatorRequestTypePubSubType::serialize( + const void* const data, + SerializedPayload_t* payload, + DataRepresentationId_t data_representation) +{ + const CalculatorRequestType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; +#if FASTCDR_VERSION_MAJOR > 1 + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); +#endif // FASTCDR_VERSION_MAJOR > 1 + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length +#if FASTCDR_VERSION_MAJOR == 1 + payload->length = static_cast(ser.getSerializedDataLength()); +#else + payload->length = static_cast(ser.get_serialized_data_length()); +#endif // FASTCDR_VERSION_MAJOR == 1 + return true; +} + +bool CalculatorRequestTypePubSubType::deserialize( + SerializedPayload_t* payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + CalculatorRequestType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN +#if FASTCDR_VERSION_MAJOR == 1 + , eprosima::fastcdr::Cdr::CdrType::DDS_CDR +#endif // FASTCDR_VERSION_MAJOR == 1 + ); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +std::function CalculatorRequestTypePubSubType::getSerializedSizeProvider( + const void* const data, + DataRepresentationId_t data_representation) +{ + return [data, data_representation]() -> uint32_t + { +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(data_representation); + return static_cast(type::getCdrSerializedSize(*static_cast(data))) + + 4u /*encapsulation*/; +#else + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +#endif // FASTCDR_VERSION_MAJOR == 1 + }; +} + +void* CalculatorRequestTypePubSubType::createData() +{ + return reinterpret_cast(new CalculatorRequestType()); +} + +void CalculatorRequestTypePubSubType::deleteData( + void* data) +{ + delete(reinterpret_cast(data)); +} + +bool CalculatorRequestTypePubSubType::getKey( + const void* const data, + InstanceHandle_t* handle, + bool force_md5) +{ + if (!m_isGetKeyDefined) + { + return false; + } + + const CalculatorRequestType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), + CalculatorRequestType_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); +#if FASTCDR_VERSION_MAJOR == 1 + p_type->serializeKey(ser); +#else + eprosima::fastcdr::serialize_key(ser, *p_type); +#endif // FASTCDR_VERSION_MAJOR == 1 + if (force_md5 || CalculatorRequestType_max_key_cdr_typesize > 16) + { + m_md5.init(); +#if FASTCDR_VERSION_MAJOR == 1 + m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); +#else + m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); +#endif // FASTCDR_VERSION_MAJOR == 1 + m_md5.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_md5.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_keyBuffer[i]; + } + } + return true; +} + +void CalculatorRequestTypePubSubType::register_type_object_representation() +{ + register_CalculatorRequestType_type_identifier(type_identifiers_); +} + +CalculatorReplyTypePubSubType::CalculatorReplyTypePubSubType() +{ + setName("CalculatorReplyType"); + uint32_t type_size = +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(CalculatorReplyType::getMaxCdrSerializedSize()); +#else + CalculatorReplyType_max_cdr_typesize; +#endif + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + m_typeSize = type_size + 4; /*encapsulation*/ + m_isGetKeyDefined = false; + uint32_t keyLength = CalculatorReplyType_max_key_cdr_typesize > 16 ? CalculatorReplyType_max_key_cdr_typesize : 16; + m_keyBuffer = reinterpret_cast(malloc(keyLength)); + memset(m_keyBuffer, 0, keyLength); +} + +CalculatorReplyTypePubSubType::~CalculatorReplyTypePubSubType() +{ + if (m_keyBuffer != nullptr) + { + free(m_keyBuffer); + } +} + +bool CalculatorReplyTypePubSubType::serialize( + const void* const data, + SerializedPayload_t* payload, + DataRepresentationId_t data_representation) +{ + const CalculatorReplyType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; +#if FASTCDR_VERSION_MAJOR > 1 + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); +#endif // FASTCDR_VERSION_MAJOR > 1 + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length +#if FASTCDR_VERSION_MAJOR == 1 + payload->length = static_cast(ser.getSerializedDataLength()); +#else + payload->length = static_cast(ser.get_serialized_data_length()); +#endif // FASTCDR_VERSION_MAJOR == 1 + return true; +} + +bool CalculatorReplyTypePubSubType::deserialize( + SerializedPayload_t* payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + CalculatorReplyType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN +#if FASTCDR_VERSION_MAJOR == 1 + , eprosima::fastcdr::Cdr::CdrType::DDS_CDR +#endif // FASTCDR_VERSION_MAJOR == 1 + ); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +std::function CalculatorReplyTypePubSubType::getSerializedSizeProvider( + const void* const data, + DataRepresentationId_t data_representation) +{ + return [data, data_representation]() -> uint32_t + { +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(data_representation); + return static_cast(type::getCdrSerializedSize(*static_cast(data))) + + 4u /*encapsulation*/; +#else + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +#endif // FASTCDR_VERSION_MAJOR == 1 + }; +} + +void* CalculatorReplyTypePubSubType::createData() +{ + return reinterpret_cast(new CalculatorReplyType()); +} + +void CalculatorReplyTypePubSubType::deleteData( + void* data) +{ + delete(reinterpret_cast(data)); +} + +bool CalculatorReplyTypePubSubType::getKey( + const void* const data, + InstanceHandle_t* handle, + bool force_md5) +{ + if (!m_isGetKeyDefined) + { + return false; + } + + const CalculatorReplyType* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), + CalculatorReplyType_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); +#if FASTCDR_VERSION_MAJOR == 1 + p_type->serializeKey(ser); +#else + eprosima::fastcdr::serialize_key(ser, *p_type); +#endif // FASTCDR_VERSION_MAJOR == 1 + if (force_md5 || CalculatorReplyType_max_key_cdr_typesize > 16) + { + m_md5.init(); +#if FASTCDR_VERSION_MAJOR == 1 + m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); +#else + m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); +#endif // FASTCDR_VERSION_MAJOR == 1 + m_md5.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_md5.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_keyBuffer[i]; + } + } + return true; +} + +void CalculatorReplyTypePubSubType::register_type_object_representation() +{ + register_CalculatorReplyType_type_identifier(type_identifiers_); +} + + +// Include auxiliary functions like for serializing/deserializing. +#include "CalculatorCdrAux.ipp" diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.hpp b/examples/cpp/request_reply/CalculatorPubSubTypes.hpp new file mode 100644 index 00000000000..aaa3a479c35 --- /dev/null +++ b/examples/cpp/request_reply/CalculatorPubSubTypes.hpp @@ -0,0 +1,224 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorPubSubTypes.hpp + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastddsgen. + */ + + +#ifndef FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP +#define FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP + +#include +#include +#include +#include +#include + +#include "Calculator.hpp" + + +#if !defined(GEN_API_VER) || (GEN_API_VER != 2) +#error \ + Generated Calculator is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. +#endif // GEN_API_VER + + +/*! + * @brief This class represents the TopicDataType of the type CalculatorRequestType defined by the user in the IDL file. + * @ingroup Calculator + */ +class CalculatorRequestTypePubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef CalculatorRequestType type; + + eProsima_user_DllExport CalculatorRequestTypePubSubType(); + + eProsima_user_DllExport ~CalculatorRequestTypePubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload) override + { + return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t* payload, + void* data) override; + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data) override + { + return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool getKey( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t* ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* createData() override; + + eProsima_user_DllExport void deleteData( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + eProsima_user_DllExport inline bool is_plain() const override + { + return false; + } + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + eprosima::fastdds::MD5 m_md5; + unsigned char* m_keyBuffer; + +}; + +/*! + * @brief This class represents the TopicDataType of the type CalculatorReplyType defined by the user in the IDL file. + * @ingroup Calculator + */ +class CalculatorReplyTypePubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef CalculatorReplyType type; + + eProsima_user_DllExport CalculatorReplyTypePubSubType(); + + eProsima_user_DllExport ~CalculatorReplyTypePubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload) override + { + return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t* payload, + void* data) override; + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data) override + { + return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool getKey( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t* ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* createData() override; + + eProsima_user_DllExport void deleteData( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + eProsima_user_DllExport inline bool is_plain() const override + { + return false; + } + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + eprosima::fastdds::MD5 m_md5; + unsigned char* m_keyBuffer; + +}; + +#endif // FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP + diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx new file mode 100644 index 00000000000..efc22f1d5e6 --- /dev/null +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx @@ -0,0 +1,305 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen. + */ + +#include "CalculatorTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Calculator.hpp" + + +using namespace eprosima::fastdds::dds::xtypes; + +void register_CalculatorOperationType_type_identifier( + TypeIdentifierPair& type_ids_CalculatorOperationType) +{ + ReturnCode_t return_code_CalculatorOperationType {eprosima::fastdds::dds::RETCODE_OK}; + return_code_CalculatorOperationType = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "CalculatorOperationType", type_ids_CalculatorOperationType); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorOperationType) + { + EnumTypeFlag enum_flags_CalculatorOperationType = 0; + BitBound bit_bound_CalculatorOperationType = 32; + CommonEnumeratedHeader common_CalculatorOperationType = TypeObjectUtils::build_common_enumerated_header(bit_bound_CalculatorOperationType); + QualifiedTypeName type_name_CalculatorOperationType = "CalculatorOperationType"; + eprosima::fastcdr::optional type_ann_builtin_CalculatorOperationType; + eprosima::fastcdr::optional ann_custom_CalculatorOperationType; + AppliedAnnotationSeq tmp_ann_custom_CalculatorOperationType; + eprosima::fastcdr::optional verbatim_CalculatorOperationType; + if (!tmp_ann_custom_CalculatorOperationType.empty()) + { + ann_custom_CalculatorOperationType = tmp_ann_custom_CalculatorOperationType; + } + + CompleteTypeDetail detail_CalculatorOperationType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorOperationType, ann_custom_CalculatorOperationType, type_name_CalculatorOperationType.to_string()); + CompleteEnumeratedHeader header_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_header(common_CalculatorOperationType, detail_CalculatorOperationType); + CompleteEnumeratedLiteralSeq literal_seq_CalculatorOperationType; + { + EnumeratedLiteralFlag flags_ADDITION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_ADDITION = TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); + eprosima::fastcdr::optional member_ann_builtin_ADDITION; + ann_custom_CalculatorOperationType.reset(); + MemberName name_ADDITION = "ADDITION"; + CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, member_ann_builtin_ADDITION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal(common_ADDITION, detail_ADDITION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_ADDITION); + } + { + EnumeratedLiteralFlag flags_SUBTRACTION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, flags_SUBTRACTION); + eprosima::fastcdr::optional member_ann_builtin_SUBTRACTION; + ann_custom_CalculatorOperationType.reset(); + MemberName name_SUBTRACTION = "SUBTRACTION"; + CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, member_ann_builtin_SUBTRACTION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal(common_SUBTRACTION, detail_SUBTRACTION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_SUBTRACTION); + } + { + EnumeratedLiteralFlag flags_MULTIPLICATION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, flags_MULTIPLICATION); + eprosima::fastcdr::optional member_ann_builtin_MULTIPLICATION; + ann_custom_CalculatorOperationType.reset(); + MemberName name_MULTIPLICATION = "MULTIPLICATION"; + CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail(name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal(common_MULTIPLICATION, detail_MULTIPLICATION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_MULTIPLICATION); + } + { + EnumeratedLiteralFlag flags_DIVISION = TypeObjectUtils::build_enumerated_literal_flag(false); + CommonEnumeratedLiteral common_DIVISION = TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); + eprosima::fastcdr::optional member_ann_builtin_DIVISION; + ann_custom_CalculatorOperationType.reset(); + MemberName name_DIVISION = "DIVISION"; + CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, member_ann_builtin_DIVISION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal(common_DIVISION, detail_DIVISION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_DIVISION); + } + CompleteEnumeratedType enumerated_type_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_type(enum_flags_CalculatorOperationType, header_CalculatorOperationType, + literal_seq_CalculatorOperationType); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_CalculatorOperationType, type_name_CalculatorOperationType.to_string(), type_ids_CalculatorOperationType)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "CalculatorOperationType already registered in TypeObjectRegistry for a different type."); + } + } +}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_CalculatorRequestType_type_identifier( + TypeIdentifierPair& type_ids_CalculatorRequestType) +{ + + ReturnCode_t return_code_CalculatorRequestType {eprosima::fastdds::dds::RETCODE_OK}; + return_code_CalculatorRequestType = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "CalculatorRequestType", type_ids_CalculatorRequestType); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorRequestType) + { + StructTypeFlag struct_flags_CalculatorRequestType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_CalculatorRequestType = "CalculatorRequestType"; + eprosima::fastcdr::optional type_ann_builtin_CalculatorRequestType; + eprosima::fastcdr::optional ann_custom_CalculatorRequestType; + AppliedAnnotationSeq tmp_ann_custom_CalculatorRequestType; + eprosima::fastcdr::optional verbatim_CalculatorRequestType; + if (!tmp_ann_custom_CalculatorRequestType.empty()) + { + ann_custom_CalculatorRequestType = tmp_ann_custom_CalculatorRequestType; + } + + CompleteTypeDetail detail_CalculatorRequestType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorRequestType, ann_custom_CalculatorRequestType, type_name_CalculatorRequestType.to_string()); + CompleteStructHeader header_CalculatorRequestType; + header_CalculatorRequestType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorRequestType); + CompleteStructMemberSeq member_seq_CalculatorRequestType; + { + TypeIdentifierPair type_ids_operation; + ReturnCode_t return_code_operation {eprosima::fastdds::dds::RETCODE_OK}; + return_code_operation = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "CalculatorOperationType", type_ids_operation); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_operation) + { + ::register_CalculatorOperationType_type_identifier(type_ids_operation); + } + StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_operation = 0x00000000; + bool common_operation_ec {false}; + CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_operation, common_operation_ec))}; + if (!common_operation_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure operation member TypeIdentifier inconsistent."); + return; + } + MemberName name_operation = "operation"; + eprosima::fastcdr::optional member_ann_builtin_operation; + ann_custom_CalculatorRequestType.reset(); + CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, member_ann_builtin_operation, ann_custom_CalculatorRequestType); + CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, detail_operation); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_operation); + } + { + TypeIdentifierPair type_ids_x; + ReturnCode_t return_code_x {eprosima::fastdds::dds::RETCODE_OK}; + return_code_x = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int16_t", type_ids_x); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_x) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "x Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_x = 0x00000001; + bool common_x_ec {false}; + CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_x, common_x_ec))}; + if (!common_x_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure x member TypeIdentifier inconsistent."); + return; + } + MemberName name_x = "x"; + eprosima::fastcdr::optional member_ann_builtin_x; + ann_custom_CalculatorRequestType.reset(); + CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, ann_custom_CalculatorRequestType); + CompleteStructMember member_x = TypeObjectUtils::build_complete_struct_member(common_x, detail_x); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_x); + } + { + TypeIdentifierPair type_ids_y; + ReturnCode_t return_code_y {eprosima::fastdds::dds::RETCODE_OK}; + return_code_y = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int16_t", type_ids_y); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_y) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "y Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_y = 0x00000002; + bool common_y_ec {false}; + CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_y, common_y_ec))}; + if (!common_y_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure y member TypeIdentifier inconsistent."); + return; + } + MemberName name_y = "y"; + eprosima::fastcdr::optional member_ann_builtin_y; + ann_custom_CalculatorRequestType.reset(); + CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, ann_custom_CalculatorRequestType); + CompleteStructMember member_y = TypeObjectUtils::build_complete_struct_member(common_y, detail_y); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_y); + } + CompleteStructType struct_type_CalculatorRequestType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorRequestType, header_CalculatorRequestType, member_seq_CalculatorRequestType); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorRequestType, type_name_CalculatorRequestType.to_string(), type_ids_CalculatorRequestType)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "CalculatorRequestType already registered in TypeObjectRegistry for a different type."); + } + } +} +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_CalculatorReplyType_type_identifier( + TypeIdentifierPair& type_ids_CalculatorReplyType) +{ + + ReturnCode_t return_code_CalculatorReplyType {eprosima::fastdds::dds::RETCODE_OK}; + return_code_CalculatorReplyType = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "CalculatorReplyType", type_ids_CalculatorReplyType); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorReplyType) + { + StructTypeFlag struct_flags_CalculatorReplyType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_CalculatorReplyType = "CalculatorReplyType"; + eprosima::fastcdr::optional type_ann_builtin_CalculatorReplyType; + eprosima::fastcdr::optional ann_custom_CalculatorReplyType; + AppliedAnnotationSeq tmp_ann_custom_CalculatorReplyType; + eprosima::fastcdr::optional verbatim_CalculatorReplyType; + if (!tmp_ann_custom_CalculatorReplyType.empty()) + { + ann_custom_CalculatorReplyType = tmp_ann_custom_CalculatorReplyType; + } + + CompleteTypeDetail detail_CalculatorReplyType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorReplyType, ann_custom_CalculatorReplyType, type_name_CalculatorReplyType.to_string()); + CompleteStructHeader header_CalculatorReplyType; + header_CalculatorReplyType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorReplyType); + CompleteStructMemberSeq member_seq_CalculatorReplyType; + { + TypeIdentifierPair type_ids_z; + ReturnCode_t return_code_z {eprosima::fastdds::dds::RETCODE_OK}; + return_code_z = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_z); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_z) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "z Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_z = 0x00000000; + bool common_z_ec {false}; + CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_z, common_z_ec))}; + if (!common_z_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure z member TypeIdentifier inconsistent."); + return; + } + MemberName name_z = "z"; + eprosima::fastcdr::optional member_ann_builtin_z; + ann_custom_CalculatorReplyType.reset(); + CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, ann_custom_CalculatorReplyType); + CompleteStructMember member_z = TypeObjectUtils::build_complete_struct_member(common_z, detail_z); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_z); + } + CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorReplyType, type_name_CalculatorReplyType.to_string(), type_ids_CalculatorReplyType)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "CalculatorReplyType already registered in TypeObjectRegistry for a different type."); + } + } +} + diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp b/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp new file mode 100644 index 00000000000..1fb9bccf445 --- /dev/null +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp @@ -0,0 +1,80 @@ +// Copyright 2016 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. + +/*! + * @file CalculatorTypeObjectSupport.hpp + * Header file containing the API required to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP +#define FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP + +#include + + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +/** + * @brief Register CalculatorOperationType related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_CalculatorOperationType_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); +/** + * @brief Register CalculatorRequestType related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_CalculatorRequestType_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); +/** + * @brief Register CalculatorReplyType related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_CalculatorReplyType_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + + +#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#endif // FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP From 67ec669e47f6b5d1293869b5c2ad2e6a0e803083 Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 27 Jun 2024 16:26:27 +0200 Subject: [PATCH 04/46] Refs #21188: Add Server initialization Signed-off-by: eduponz --- examples/cpp/request_reply/Application.cpp | 2 +- examples/cpp/request_reply/ServerApp.cpp | 175 ++++++++++++++++++++- examples/cpp/request_reply/ServerApp.hpp | 50 +++++- 3 files changed, 220 insertions(+), 7 deletions(-) diff --git a/examples/cpp/request_reply/Application.cpp b/examples/cpp/request_reply/Application.cpp index c52266672fc..2001b763096 100644 --- a/examples/cpp/request_reply/Application.cpp +++ b/examples/cpp/request_reply/Application.cpp @@ -40,7 +40,7 @@ std::shared_ptr Application::make_app( { case CLIParser::EntityKind::SERVER: { - entity = std::make_shared(config, service_name); + entity = std::make_shared(service_name); break; } case CLIParser::EntityKind::CLIENT: diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 0cc39825573..2b737a26bfc 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -19,17 +19,164 @@ #include "ServerApp.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Calculator.hpp" +#include "CalculatorPubSubTypes.hpp" + namespace eprosima { namespace fastdds { namespace examples { namespace request_reply { ServerApp::ServerApp( - const CLIParser::config& config, const std::string& service_name) + : participant_(nullptr) + , request_type_(nullptr) + , request_topic_(nullptr) + , subscriber_(nullptr) + , request_reader_(nullptr) + , reply_type_(nullptr) + , reply_topic_(nullptr) + , publisher_(nullptr) + , reply_writer_(nullptr) { - static_cast(config); - static_cast(service_name); + // Create the participant + auto factory = DomainParticipantFactory::get_instance(); + + if (nullptr == factory) + { + throw std::runtime_error("Failed to get participant factory instance"); + } + + participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); + + if (nullptr == participant_) + { + throw std::runtime_error("Participant initialization failed"); + } + + /********** REQUEST ENTITIES **********/ + // Create the request TypeSupport + request_type_.reset(new CalculatorRequestTypePubSubType()); + + if (nullptr == request_type_) + { + throw std::runtime_error("Failed to create request type"); + } + + // Register the type + if (RETCODE_OK != request_type_.register_type(participant_)) + { + throw std::runtime_error("Failed to register request type"); + } + + // Create the request topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_topic_qos(topic_qos)) + { + throw std::runtime_error("Failed to get default topic qos"); + } + + request_topic_ = participant_->create_topic("rq/" + service_name, request_type_.get_type_name(), topic_qos); + + if (nullptr == request_topic_) + { + throw std::runtime_error("Request topic initialization failed"); + } + + // Create the subscriber + SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_subscriber_qos(sub_qos)) + { + throw std::runtime_error("Failed to get default subscriber qos"); + } + + subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none()); + + if (nullptr == subscriber_) + { + throw std::runtime_error("Subscriber initialization failed"); + } + + // Create the request reader + DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT; + + if (RETCODE_OK != subscriber_->get_default_datareader_qos(reader_qos)) + { + throw std::runtime_error("Failed to get default datareader qos"); + } + + request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos, this, StatusMask::all()); + + if (nullptr == request_reader_) + { + throw std::runtime_error("Request reader initialization failed"); + } + + /********** REPLY ENTITIES **********/ + // Create the reply TypeSupport + reply_type_.reset(new CalculatorReplyTypePubSubType()); + + if (nullptr == reply_type_) + { + throw std::runtime_error("Failed to create reply type"); + } + + // Register the type + if (RETCODE_OK != reply_type_.register_type(participant_)) + { + throw std::runtime_error("Failed to register reply type"); + } + + // Create the reply topic + reply_topic_ = participant_->create_topic("rr/" + service_name, reply_type_.get_type_name(), topic_qos); + + if (nullptr == reply_topic_) + { + throw std::runtime_error("Reply topic initialization failed"); + } + + // Create the publisher + PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_publisher_qos(pub_qos)) + { + throw std::runtime_error("Failed to get default publisher qos"); + } + + publisher_ = participant_->create_publisher(pub_qos, nullptr, StatusMask::none()); + + if (nullptr == publisher_) + { + throw std::runtime_error("Publisher initialization failed"); + } + + // Create the reply writer + DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT; + + if (RETCODE_OK != publisher_->get_default_datawriter_qos(writer_qos)) + { + throw std::runtime_error("Failed to get default datawriter qos"); + } + + reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos, this, StatusMask::all()); + + if (nullptr == reply_writer_) + { + throw std::runtime_error("Reply writer initialization failed"); + } } ServerApp::~ServerApp() @@ -44,6 +191,28 @@ void ServerApp::stop() { } +void ServerApp::on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) +{ + static_cast(writer); + static_cast(info); +} + +void ServerApp::on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) +{ + static_cast(reader); + static_cast(info); +} + +void ServerApp::on_data_available( + DataReader* reader) +{ + static_cast(reader); +} + } // namespace request_reply } // namespace examples } // namespace fastdds diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index ff1c5ffb383..589218dd99a 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -22,20 +22,30 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "Application.hpp" -#include "CLIParser.hpp" namespace eprosima { namespace fastdds { namespace examples { namespace request_reply { -class ServerApp : public Application +using namespace eprosima::fastdds::dds; + +class ServerApp : public Application, public DataWriterListener, public DataReaderListener { public: ServerApp( - const CLIParser::config& config, const std::string& service_name); ~ServerApp(); @@ -45,6 +55,40 @@ class ServerApp : public Application //! Stop server void stop() override; + + //! Publication matched method + void on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) override; + + //! Subscription matched method + void on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) override; + + //! Request received method + void on_data_available( + DataReader* reader) override; + +private: + + DomainParticipant* participant_; + + TypeSupport request_type_; + + Topic* request_topic_; + + Subscriber* subscriber_; + + DataReader* request_reader_; + + TypeSupport reply_type_; + + Topic* reply_topic_; + + Publisher* publisher_; + + DataWriter* reply_writer_; }; } // namespace request_reply From 30bbd9c9f59e20801d42b24527ef412d24d43e80 Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 27 Jun 2024 16:30:25 +0200 Subject: [PATCH 05/46] Refs #21188: Add Server on_subscription_matched Signed-off-by: eduponz --- examples/cpp/request_reply/ServerApp.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 2b737a26bfc..28aeb75021c 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -19,6 +19,7 @@ #include "ServerApp.hpp" +#include #include #include @@ -200,11 +201,22 @@ void ServerApp::on_publication_matched( } void ServerApp::on_subscription_matched( - DataReader* reader, + DataReader* /* reader */, const SubscriptionMatchedStatus& info) { - static_cast(reader); - static_cast(info); + if (info.current_count_change == 1) + { + std::cout << "Remote request writer matched." << std::endl; + } + else if (info.current_count_change == -1) + { + std::cout << "Remote request writer unmatched." << std::endl; + } + else + { + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + } } void ServerApp::on_data_available( From f802cca432ea85383dd7b5b4a218c32104471ae1 Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 27 Jun 2024 21:32:33 +0200 Subject: [PATCH 06/46] Refs #21188: Add Client initialization Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 187 ++++++++++++++++++++++- examples/cpp/request_reply/ClientApp.hpp | 62 +++++++- 2 files changed, 245 insertions(+), 4 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 9568e47bbae..d0a3480c0c9 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -19,17 +19,168 @@ #include "ClientApp.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Calculator.hpp" +#include "CalculatorPubSubTypes.hpp" + namespace eprosima { namespace fastdds { namespace examples { namespace request_reply { +using namespace eprosima::fastdds::dds; + ClientApp::ClientApp( const CLIParser::config& config, const std::string& service_name) + : request_input_(config) + , participant_(nullptr) + , request_type_(nullptr) + , request_topic_(nullptr) + , publisher_(nullptr) + , request_writer_(nullptr) + , reply_type_(nullptr) + , reply_topic_(nullptr) + , subscriber_(nullptr) + , reply_reader_(nullptr) { - static_cast(config); - static_cast(service_name); + // Create the participant + auto factory = DomainParticipantFactory::get_instance(); + + if (nullptr == factory) + { + throw std::runtime_error("Failed to get participant factory instance"); + } + + participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); + + if (nullptr == participant_) + { + throw std::runtime_error("Participant initialization failed"); + } + + /********** REQUEST ENTITIES **********/ + // Create the request TypeSupport + request_type_.reset(new CalculatorRequestTypePubSubType()); + + if (nullptr == request_type_) + { + throw std::runtime_error("Failed to create request type"); + } + + // Register the type + if (RETCODE_OK != request_type_.register_type(participant_)) + { + throw std::runtime_error("Failed to register request type"); + } + + // Create the request topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_topic_qos(topic_qos)) + { + throw std::runtime_error("Failed to get default topic qos"); + } + + request_topic_ = participant_->create_topic("rq/" + service_name, request_type_.get_type_name(), topic_qos); + + if (nullptr == request_topic_) + { + throw std::runtime_error("Request topic initialization failed"); + } + + // Create the publisher + PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_publisher_qos(pub_qos)) + { + throw std::runtime_error("Failed to get default publisher qos"); + } + + publisher_ = participant_->create_publisher(pub_qos, nullptr, StatusMask::none()); + + if (nullptr == publisher_) + { + throw std::runtime_error("Publisher initialization failed"); + } + + // Create the request writer + DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT; + + if (RETCODE_OK != publisher_->get_default_datawriter_qos(writer_qos)) + { + throw std::runtime_error("Failed to get default datawriter qos"); + } + + request_writer_ = publisher_->create_datawriter(request_topic_, writer_qos, this, StatusMask::all()); + + if (nullptr == request_writer_) + { + throw std::runtime_error("Request writer initialization failed"); + } + + /********** REPLY ENTITIES **********/ + // Create the reply TypeSupport + reply_type_.reset(new CalculatorReplyTypePubSubType()); + + if (nullptr == reply_type_) + { + throw std::runtime_error("Failed to create reply type"); + } + + // Register the type + if (RETCODE_OK != reply_type_.register_type(participant_)) + { + throw std::runtime_error("Failed to register reply type"); + } + + // Create the reply topic + reply_topic_ = participant_->create_topic("rr/" + service_name, reply_type_.get_type_name(), topic_qos); + + if (nullptr == reply_topic_) + { + throw std::runtime_error("Reply topic initialization failed"); + } + + // Create the subscriber + SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; + + if (RETCODE_OK != participant_->get_default_subscriber_qos(sub_qos)) + { + throw std::runtime_error("Failed to get default subscriber qos"); + } + + subscriber_ = participant_->create_subscriber(sub_qos, nullptr, StatusMask::none()); + + if (nullptr == subscriber_) + { + throw std::runtime_error("Subscriber initialization failed"); + } + + // Create the request reader + DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT; + + if (RETCODE_OK != subscriber_->get_default_datareader_qos(reader_qos)) + { + throw std::runtime_error("Failed to get default datareader qos"); + } + + reply_reader_ = subscriber_->create_datareader(reply_topic_, reader_qos, this, StatusMask::all()); + + if (nullptr == reply_reader_) + { + throw std::runtime_error("Reply reader initialization failed"); + } } ClientApp::~ClientApp() @@ -44,7 +195,37 @@ void ClientApp::stop() { } -} // namespace request_reply { +void ClientApp::on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) +{ + static_cast(writer); + static_cast(info); +} + +void ClientApp::on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) +{ + static_cast(reader); + static_cast(info); +} + +void ClientApp::on_data_available( + DataReader* reader) +{ + static_cast(reader); +} + +ClientApp::RequestInput::RequestInput( + const CLIParser::config& config) + : operation(config.operation) + , x(config.x) + , y(config.y) +{ +} + +} // namespace request_reply } // namespace examples } // namespace fastdds } // namespace eprosima diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 0319e29bce3..74b8eada235 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -20,6 +20,18 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "Application.hpp" #include "CLIParser.hpp" @@ -28,7 +40,9 @@ namespace fastdds { namespace examples { namespace request_reply { -class ClientApp : public Application +using namespace eprosima::fastdds::dds; + +class ClientApp : public Application, public DataReaderListener, public DataWriterListener { public: @@ -44,6 +58,52 @@ class ClientApp : public Application //! Trigger the end of execution void stop() override; + //! Publication matched method + void on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) override; + + //! Subscription matched method + void on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) override; + + //! Reply received method + void on_data_available( + DataReader* reader) override; + +private: + + struct RequestInput + { + RequestInput(const CLIParser::config& config); + + CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; + + std::int16_t x = 0; + + std::int16_t y = 0; + }; + + RequestInput request_input_; + + DomainParticipant* participant_; + + TypeSupport request_type_; + + Topic* request_topic_; + + Publisher* publisher_; + + DataWriter* request_writer_; + + TypeSupport reply_type_; + + Topic* reply_topic_; + + Subscriber* subscriber_; + + DataReader* reply_reader_; }; } // namespace request_reply From 7829aeda60c1f04d6da00254f72e2479e0b9c53c Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 27 Jun 2024 22:16:17 +0200 Subject: [PATCH 07/46] Refs #21188: Add Client on_publication_matched Signed-off-by: eduponz --- examples/cpp/request_reply/Calculator.hpp | 26 +- .../cpp/request_reply/CalculatorCdrAux.ipp | 295 +++++++++--------- .../request_reply/CalculatorPubSubTypes.cxx | 30 +- .../CalculatorTypeObjectSupport.cxx | 181 +++++++---- examples/cpp/request_reply/ClientApp.cpp | 27 +- examples/cpp/request_reply/ClientApp.hpp | 64 ++++ 6 files changed, 385 insertions(+), 238 deletions(-) diff --git a/examples/cpp/request_reply/Calculator.hpp b/examples/cpp/request_reply/Calculator.hpp index d87ec4c9b14..ad1d51b8747 100644 --- a/examples/cpp/request_reply/Calculator.hpp +++ b/examples/cpp/request_reply/Calculator.hpp @@ -89,11 +89,11 @@ class CalculatorRequestType eProsima_user_DllExport CalculatorRequestType( const CalculatorRequestType& x) { - m_operation = x.m_operation; + m_operation = x.m_operation; - m_x = x.m_x; + m_x = x.m_x; - m_y = x.m_y; + m_y = x.m_y; } @@ -117,11 +117,11 @@ class CalculatorRequestType const CalculatorRequestType& x) { - m_operation = x.m_operation; + m_operation = x.m_operation; - m_x = x.m_x; + m_x = x.m_x; - m_y = x.m_y; + m_y = x.m_y; return *this; } @@ -148,8 +148,8 @@ class CalculatorRequestType const CalculatorRequestType& x) const { return (m_operation == x.m_operation && - m_x == x.m_x && - m_y == x.m_y); + m_x == x.m_x && + m_y == x.m_y); } /*! @@ -190,7 +190,6 @@ class CalculatorRequestType return m_operation; } - /*! * @brief This function sets a value in member x * @param _x New value for member x @@ -219,7 +218,6 @@ class CalculatorRequestType return m_x; } - /*! * @brief This function sets a value in member y * @param _y New value for member y @@ -248,8 +246,6 @@ class CalculatorRequestType return m_y; } - - private: CalculatorOperationType m_operation{CalculatorOperationType::ADDITION}; @@ -286,7 +282,7 @@ class CalculatorReplyType eProsima_user_DllExport CalculatorReplyType( const CalculatorReplyType& x) { - m_z = x.m_z; + m_z = x.m_z; } @@ -308,7 +304,7 @@ class CalculatorReplyType const CalculatorReplyType& x) { - m_z = x.m_z; + m_z = x.m_z; return *this; } @@ -373,8 +369,6 @@ class CalculatorReplyType return m_z; } - - private: int32_t m_z{0}; diff --git a/examples/cpp/request_reply/CalculatorCdrAux.ipp b/examples/cpp/request_reply/CalculatorCdrAux.ipp index 4052fd5e9e5..ba5c128f299 100644 --- a/examples/cpp/request_reply/CalculatorCdrAux.ipp +++ b/examples/cpp/request_reply/CalculatorCdrAux.ipp @@ -32,82 +32,85 @@ using namespace eprosima::fastcdr::exception; namespace eprosima { -namespace fastcdr { - -template<> -eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const CalculatorRequestType& data, - size_t& current_alignment) -{ - static_cast(data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size {calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment)}; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.operation(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), - data.x(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), - data.y(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; -} - -template<> -eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const CalculatorRequestType& data) -{ - eprosima::fastcdr::Cdr::state current_state(scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.operation() - << eprosima::fastcdr::MemberId(1) << data.x() - << eprosima::fastcdr::MemberId(2) << data.y() -; - scdr.end_serialize_type(current_state); -} - -template<> -eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - CalculatorRequestType& data) -{ - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + namespace fastcdr { + + template < > + eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorRequestType& data, + size_t& current_alignment) + { + static_cast < void > (data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size { + calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment) + }; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.operation(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.x(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.y(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; + } + + template < > + eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) + { + eprosima::fastcdr::Cdr::state current_state( + scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.operation() + << eprosima::fastcdr::MemberId(1) << data.x() + << eprosima::fastcdr::MemberId(2) << data.y() + ; + scdr.end_serialize_type(current_state); + } + + template < > + eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorRequestType& data) + { + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid)->bool { bool ret_value = true; switch (mid.id) { - case 0: - dcdr >> data.operation(); - break; + case 0: + dcdr >> data.operation(); + break; - case 1: - dcdr >> data.x(); - break; + case 1: + dcdr >> data.x(); + break; - case 2: - dcdr >> data.y(); - break; + case 2: + dcdr >> data.y(); + break; default: ret_value = false; @@ -115,75 +118,77 @@ eProsima_user_DllExport void deserialize( } return ret_value; }); -} - -void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const CalculatorRequestType& data) -{ - static_cast(scdr); - static_cast(data); -} - - -template<> -eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const CalculatorReplyType& data, - size_t& current_alignment) -{ - static_cast(data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size {calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment)}; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.z(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; -} - -template<> -eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const CalculatorReplyType& data) -{ - eprosima::fastcdr::Cdr::state current_state(scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.z() -; - scdr.end_serialize_type(current_state); -} - -template<> -eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - CalculatorReplyType& data) -{ - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + } + + void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) + { + static_cast < void > (scdr); + static_cast < void > (data); + } + + template < > + eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorReplyType& data, + size_t& current_alignment) + { + static_cast < void > (data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size { + calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment) + }; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.z(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; + } + + template < > + eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) + { + eprosima::fastcdr::Cdr::state current_state( + scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.z() + ; + scdr.end_serialize_type(current_state); + } + + template < > + eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorReplyType& data) + { + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid)->bool { bool ret_value = true; switch (mid.id) { - case 0: - dcdr >> data.z(); - break; + case 0: + dcdr >> data.z(); + break; default: ret_value = false; @@ -191,19 +196,17 @@ eProsima_user_DllExport void deserialize( } return ret_value; }); -} - -void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const CalculatorReplyType& data) -{ - static_cast(scdr); - static_cast(data); -} - + } + void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) + { + static_cast < void > (scdr); + static_cast < void > (data); + } -} // namespace fastcdr + } // namespace fastcdr } // namespace eprosima #endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx index ecd48faa290..be653403af7 100644 --- a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx +++ b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx @@ -36,14 +36,15 @@ CalculatorRequestTypePubSubType::CalculatorRequestTypePubSubType() setName("CalculatorRequestType"); uint32_t type_size = #if FASTCDR_VERSION_MAJOR == 1 - static_cast(CalculatorRequestType::getMaxCdrSerializedSize()); + static_cast(CalculatorRequestType::getMaxCdrSerializedSize()); #else - CalculatorRequestType_max_cdr_typesize; -#endif + CalculatorRequestType_max_cdr_typesize; +#endif // if FASTCDR_VERSION_MAJOR == 1 type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ m_typeSize = type_size + 4; /*encapsulation*/ m_isGetKeyDefined = false; - uint32_t keyLength = CalculatorRequestType_max_key_cdr_typesize > 16 ? CalculatorRequestType_max_key_cdr_typesize : 16; + uint32_t keyLength = CalculatorRequestType_max_key_cdr_typesize > + 16 ? CalculatorRequestType_max_key_cdr_typesize : 16; m_keyBuffer = reinterpret_cast(malloc(keyLength)); memset(m_keyBuffer, 0, keyLength); } @@ -150,8 +151,8 @@ std::function CalculatorRequestTypePubSubType::getSerializedSizeProv eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; } catch (eprosima::fastcdr::exception::Exception& /*exception*/) { @@ -189,7 +190,8 @@ bool CalculatorRequestTypePubSubType::getKey( CalculatorRequestType_max_key_cdr_typesize); // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, + eprosima::fastcdr::CdrVersion::XCDRv1); #if FASTCDR_VERSION_MAJOR == 1 p_type->serializeKey(ser); #else @@ -229,10 +231,10 @@ CalculatorReplyTypePubSubType::CalculatorReplyTypePubSubType() setName("CalculatorReplyType"); uint32_t type_size = #if FASTCDR_VERSION_MAJOR == 1 - static_cast(CalculatorReplyType::getMaxCdrSerializedSize()); + static_cast(CalculatorReplyType::getMaxCdrSerializedSize()); #else - CalculatorReplyType_max_cdr_typesize; -#endif + CalculatorReplyType_max_cdr_typesize; +#endif // if FASTCDR_VERSION_MAJOR == 1 type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ m_typeSize = type_size + 4; /*encapsulation*/ m_isGetKeyDefined = false; @@ -343,8 +345,8 @@ std::function CalculatorReplyTypePubSubType::getSerializedSizeProvid eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; } catch (eprosima::fastcdr::exception::Exception& /*exception*/) { @@ -382,7 +384,8 @@ bool CalculatorReplyTypePubSubType::getKey( CalculatorReplyType_max_key_cdr_typesize); // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, + eprosima::fastcdr::CdrVersion::XCDRv1); #if FASTCDR_VERSION_MAJOR == 1 p_type->serializeKey(ser); #else @@ -417,6 +420,5 @@ void CalculatorReplyTypePubSubType::register_type_object_representation() register_CalculatorReplyType_type_identifier(type_identifiers_); } - // Include auxiliary functions like for serializing/deserializing. #include "CalculatorCdrAux.ipp" diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx index efc22f1d5e6..dcaf7de67c3 100644 --- a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx @@ -43,13 +43,15 @@ void register_CalculatorOperationType_type_identifier( { ReturnCode_t return_code_CalculatorOperationType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorOperationType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "CalculatorOperationType", type_ids_CalculatorOperationType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorOperationType) { EnumTypeFlag enum_flags_CalculatorOperationType = 0; BitBound bit_bound_CalculatorOperationType = 32; - CommonEnumeratedHeader common_CalculatorOperationType = TypeObjectUtils::build_common_enumerated_header(bit_bound_CalculatorOperationType); + CommonEnumeratedHeader common_CalculatorOperationType = TypeObjectUtils::build_common_enumerated_header( + bit_bound_CalculatorOperationType); QualifiedTypeName type_name_CalculatorOperationType = "CalculatorOperationType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorOperationType; eprosima::fastcdr::optional ann_custom_CalculatorOperationType; @@ -60,71 +62,96 @@ void register_CalculatorOperationType_type_identifier( ann_custom_CalculatorOperationType = tmp_ann_custom_CalculatorOperationType; } - CompleteTypeDetail detail_CalculatorOperationType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorOperationType, ann_custom_CalculatorOperationType, type_name_CalculatorOperationType.to_string()); - CompleteEnumeratedHeader header_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_header(common_CalculatorOperationType, detail_CalculatorOperationType); + CompleteTypeDetail detail_CalculatorOperationType = TypeObjectUtils::build_complete_type_detail( + type_ann_builtin_CalculatorOperationType, ann_custom_CalculatorOperationType, + type_name_CalculatorOperationType.to_string()); + CompleteEnumeratedHeader header_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_header( + common_CalculatorOperationType, detail_CalculatorOperationType); CompleteEnumeratedLiteralSeq literal_seq_CalculatorOperationType; { EnumeratedLiteralFlag flags_ADDITION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_ADDITION = TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); + CommonEnumeratedLiteral common_ADDITION = + TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); eprosima::fastcdr::optional member_ann_builtin_ADDITION; ann_custom_CalculatorOperationType.reset(); MemberName name_ADDITION = "ADDITION"; - CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, member_ann_builtin_ADDITION, ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal(common_ADDITION, detail_ADDITION); + CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, + member_ann_builtin_ADDITION, + ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal( + common_ADDITION, detail_ADDITION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_ADDITION); } { EnumeratedLiteralFlag flags_SUBTRACTION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, flags_SUBTRACTION); + CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, + flags_SUBTRACTION); eprosima::fastcdr::optional member_ann_builtin_SUBTRACTION; ann_custom_CalculatorOperationType.reset(); MemberName name_SUBTRACTION = "SUBTRACTION"; - CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, member_ann_builtin_SUBTRACTION, ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal(common_SUBTRACTION, detail_SUBTRACTION); + CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, + member_ann_builtin_SUBTRACTION, + ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal( + common_SUBTRACTION, detail_SUBTRACTION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_SUBTRACTION); } { EnumeratedLiteralFlag flags_MULTIPLICATION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, flags_MULTIPLICATION); + CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, + flags_MULTIPLICATION); eprosima::fastcdr::optional member_ann_builtin_MULTIPLICATION; ann_custom_CalculatorOperationType.reset(); MemberName name_MULTIPLICATION = "MULTIPLICATION"; - CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail(name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal(common_MULTIPLICATION, detail_MULTIPLICATION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_MULTIPLICATION); + CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail( + name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal( + common_MULTIPLICATION, detail_MULTIPLICATION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, + literal_MULTIPLICATION); } { EnumeratedLiteralFlag flags_DIVISION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_DIVISION = TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); + CommonEnumeratedLiteral common_DIVISION = + TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); eprosima::fastcdr::optional member_ann_builtin_DIVISION; ann_custom_CalculatorOperationType.reset(); MemberName name_DIVISION = "DIVISION"; - CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, member_ann_builtin_DIVISION, ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal(common_DIVISION, detail_DIVISION); + CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, + member_ann_builtin_DIVISION, + ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal( + common_DIVISION, detail_DIVISION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_DIVISION); } - CompleteEnumeratedType enumerated_type_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_type(enum_flags_CalculatorOperationType, header_CalculatorOperationType, - literal_seq_CalculatorOperationType); + CompleteEnumeratedType enumerated_type_CalculatorOperationType = + TypeObjectUtils::build_complete_enumerated_type(enum_flags_CalculatorOperationType, + header_CalculatorOperationType, + literal_seq_CalculatorOperationType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_CalculatorOperationType, type_name_CalculatorOperationType.to_string(), type_ids_CalculatorOperationType)) + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_CalculatorOperationType, + type_name_CalculatorOperationType.to_string(), type_ids_CalculatorOperationType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "CalculatorOperationType already registered in TypeObjectRegistry for a different type."); + "CalculatorOperationType already registered in TypeObjectRegistry for a different type."); } } }// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method + void register_CalculatorRequestType_type_identifier( TypeIdentifierPair& type_ids_CalculatorRequestType) { ReturnCode_t return_code_CalculatorRequestType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorRequestType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "CalculatorRequestType", type_ids_CalculatorRequestType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorRequestType) { - StructTypeFlag struct_flags_CalculatorRequestType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); + StructTypeFlag struct_flags_CalculatorRequestType = TypeObjectUtils::build_struct_type_flag( + eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); QualifiedTypeName type_name_CalculatorRequestType = "CalculatorRequestType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorRequestType; eprosima::fastcdr::optional ann_custom_CalculatorRequestType; @@ -135,43 +162,56 @@ void register_CalculatorRequestType_type_identifier( ann_custom_CalculatorRequestType = tmp_ann_custom_CalculatorRequestType; } - CompleteTypeDetail detail_CalculatorRequestType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorRequestType, ann_custom_CalculatorRequestType, type_name_CalculatorRequestType.to_string()); + CompleteTypeDetail detail_CalculatorRequestType = TypeObjectUtils::build_complete_type_detail( + type_ann_builtin_CalculatorRequestType, ann_custom_CalculatorRequestType, + type_name_CalculatorRequestType.to_string()); CompleteStructHeader header_CalculatorRequestType; - header_CalculatorRequestType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorRequestType); + header_CalculatorRequestType = TypeObjectUtils::build_complete_struct_header( + TypeIdentifier(), detail_CalculatorRequestType); CompleteStructMemberSeq member_seq_CalculatorRequestType; { TypeIdentifierPair type_ids_operation; ReturnCode_t return_code_operation {eprosima::fastdds::dds::RETCODE_OK}; return_code_operation = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "CalculatorOperationType", type_ids_operation); if (eprosima::fastdds::dds::RETCODE_OK != return_code_operation) { - ::register_CalculatorOperationType_type_identifier(type_ids_operation); + ::register_CalculatorOperationType_type_identifier(type_ids_operation); } - StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); + StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag( + eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); MemberId member_id_operation = 0x00000000; bool common_operation_ec {false}; - CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_operation, common_operation_ec))}; + CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, + member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier( + type_ids_operation, + common_operation_ec))}; if (!common_operation_ec) { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure operation member TypeIdentifier inconsistent."); + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "Structure operation member TypeIdentifier inconsistent."); return; } MemberName name_operation = "operation"; eprosima::fastcdr::optional member_ann_builtin_operation; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, member_ann_builtin_operation, ann_custom_CalculatorRequestType); - CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, detail_operation); + CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, + member_ann_builtin_operation, + ann_custom_CalculatorRequestType); + CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, + detail_operation); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_operation); } { TypeIdentifierPair type_ids_x; ReturnCode_t return_code_x {eprosima::fastdds::dds::RETCODE_OK}; return_code_x = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "_int16_t", type_ids_x); if (eprosima::fastdds::dds::RETCODE_OK != return_code_x) @@ -180,11 +220,14 @@ void register_CalculatorRequestType_type_identifier( "x Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); + StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag( + eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); MemberId member_id_x = 0x00000001; bool common_x_ec {false}; - CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_x, common_x_ec))}; + CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier( + type_ids_x, + common_x_ec))}; if (!common_x_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure x member TypeIdentifier inconsistent."); @@ -193,7 +236,8 @@ void register_CalculatorRequestType_type_identifier( MemberName name_x = "x"; eprosima::fastcdr::optional member_ann_builtin_x; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, ann_custom_CalculatorRequestType); + CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, + ann_custom_CalculatorRequestType); CompleteStructMember member_x = TypeObjectUtils::build_complete_struct_member(common_x, detail_x); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_x); } @@ -201,7 +245,8 @@ void register_CalculatorRequestType_type_identifier( TypeIdentifierPair type_ids_y; ReturnCode_t return_code_y {eprosima::fastdds::dds::RETCODE_OK}; return_code_y = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "_int16_t", type_ids_y); if (eprosima::fastdds::dds::RETCODE_OK != return_code_y) @@ -210,11 +255,14 @@ void register_CalculatorRequestType_type_identifier( "y Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); + StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag( + eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); MemberId member_id_y = 0x00000002; bool common_y_ec {false}; - CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_y, common_y_ec))}; + CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier( + type_ids_y, + common_y_ec))}; if (!common_y_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure y member TypeIdentifier inconsistent."); @@ -223,19 +271,23 @@ void register_CalculatorRequestType_type_identifier( MemberName name_y = "y"; eprosima::fastcdr::optional member_ann_builtin_y; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, ann_custom_CalculatorRequestType); + CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, + ann_custom_CalculatorRequestType); CompleteStructMember member_y = TypeObjectUtils::build_complete_struct_member(common_y, detail_y); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_y); } - CompleteStructType struct_type_CalculatorRequestType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorRequestType, header_CalculatorRequestType, member_seq_CalculatorRequestType); + CompleteStructType struct_type_CalculatorRequestType = TypeObjectUtils::build_complete_struct_type( + struct_flags_CalculatorRequestType, header_CalculatorRequestType, member_seq_CalculatorRequestType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorRequestType, type_name_CalculatorRequestType.to_string(), type_ids_CalculatorRequestType)) + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorRequestType, + type_name_CalculatorRequestType.to_string(), type_ids_CalculatorRequestType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "CalculatorRequestType already registered in TypeObjectRegistry for a different type."); } } } + // TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method void register_CalculatorReplyType_type_identifier( TypeIdentifierPair& type_ids_CalculatorReplyType) @@ -243,12 +295,14 @@ void register_CalculatorReplyType_type_identifier( ReturnCode_t return_code_CalculatorReplyType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorReplyType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "CalculatorReplyType", type_ids_CalculatorReplyType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorReplyType) { - StructTypeFlag struct_flags_CalculatorReplyType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); + StructTypeFlag struct_flags_CalculatorReplyType = TypeObjectUtils::build_struct_type_flag( + eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); QualifiedTypeName type_name_CalculatorReplyType = "CalculatorReplyType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorReplyType; eprosima::fastcdr::optional ann_custom_CalculatorReplyType; @@ -259,15 +313,19 @@ void register_CalculatorReplyType_type_identifier( ann_custom_CalculatorReplyType = tmp_ann_custom_CalculatorReplyType; } - CompleteTypeDetail detail_CalculatorReplyType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorReplyType, ann_custom_CalculatorReplyType, type_name_CalculatorReplyType.to_string()); + CompleteTypeDetail detail_CalculatorReplyType = TypeObjectUtils::build_complete_type_detail( + type_ann_builtin_CalculatorReplyType, ann_custom_CalculatorReplyType, + type_name_CalculatorReplyType.to_string()); CompleteStructHeader header_CalculatorReplyType; - header_CalculatorReplyType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorReplyType); + header_CalculatorReplyType = TypeObjectUtils::build_complete_struct_header( + TypeIdentifier(), detail_CalculatorReplyType); CompleteStructMemberSeq member_seq_CalculatorReplyType; { TypeIdentifierPair type_ids_z; ReturnCode_t return_code_z {eprosima::fastdds::dds::RETCODE_OK}; return_code_z = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). + get_type_identifiers( "_int32_t", type_ids_z); if (eprosima::fastdds::dds::RETCODE_OK != return_code_z) @@ -276,11 +334,14 @@ void register_CalculatorReplyType_type_identifier( "z Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); + StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag( + eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); MemberId member_id_z = 0x00000000; bool common_z_ec {false}; - CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_z, common_z_ec))}; + CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier( + type_ids_z, + common_z_ec))}; if (!common_z_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure z member TypeIdentifier inconsistent."); @@ -289,17 +350,19 @@ void register_CalculatorReplyType_type_identifier( MemberName name_z = "z"; eprosima::fastcdr::optional member_ann_builtin_z; ann_custom_CalculatorReplyType.reset(); - CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, ann_custom_CalculatorReplyType); + CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, + ann_custom_CalculatorReplyType); CompleteStructMember member_z = TypeObjectUtils::build_complete_struct_member(common_z, detail_z); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_z); } - CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); + CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type( + struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorReplyType, type_name_CalculatorReplyType.to_string(), type_ids_CalculatorReplyType)) + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorReplyType, + type_name_CalculatorReplyType.to_string(), type_ids_CalculatorReplyType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "CalculatorReplyType already registered in TypeObjectRegistry for a different type."); } } } - diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index d0a3480c0c9..d1286dde66c 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -19,6 +19,7 @@ #include "ClientApp.hpp" +#include #include #include @@ -40,6 +41,10 @@ namespace request_reply { using namespace eprosima::fastdds::dds; +// Define the constexpr so the linker can find the static members +constexpr std::size_t ClientApp::request_writer_position_; +constexpr std::size_t ClientApp::reply_reader_position_; + ClientApp::ClientApp( const CLIParser::config& config, const std::string& service_name) @@ -196,11 +201,27 @@ void ClientApp::stop() } void ClientApp::on_publication_matched( - DataWriter* writer, + DataWriter* /* writer */, const PublicationMatchedStatus& info) { - static_cast(writer); - static_cast(info); + std::lock_guard lock(mtx_); + + if (info.current_count_change == 1) + { + std::cout << "Remote request reader matched." << std::endl; + matched_state_.increase(request_writer_position_); + } + else if (info.current_count_change == -1) + { + std::cout << "Remote request reader unmatched." << std::endl; + matched_state_.decrease(request_writer_position_); + } + else + { + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + } + cv_.notify_one(); } void ClientApp::on_subscription_matched( diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 74b8eada235..9d22dba3f5a 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -20,6 +20,12 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP +#include +#include +#include +#include +#include +#include #include #include @@ -104,6 +110,64 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit Subscriber* subscriber_; DataReader* reply_reader_; + + mutable std::mutex mtx_; + + std::condition_variable cv_; + + template + class Uint8CountSet + { + public: + void increase(const size_t& position) + { + assert(position <= (set_size - 1)); + if (inner_set_[position] < std::numeric_limits::max()) + { + inner_set_[position] += 1; + } + } + + void decrease(const size_t& position) + { + assert(position <= (set_size - 1)); + if (inner_set_[position] > 0) + { + inner_set_[position] -= 1; + } + } + + bool all() + { + bool all_different_from_zero = true; + + for (auto i = 0; i < set_size; i++) + { + if (inner_set_[i] == 0) + { + all_different_from_zero = false; + break; + } + } + + return all_different_from_zero; + } + + private: + std::array inner_set_ = {0}; + }; + + /** + * @brief Set to represent the matched count of the request-reply endpoints: + * + * - Position 0 represents matching status of request writer + * - Position 1 represents matching status of reply reader + */ + Uint8CountSet<2> matched_state_; + + static constexpr std::size_t request_writer_position_ = 0; + + static constexpr std::size_t reply_reader_position_ = 1; }; } // namespace request_reply From d59924196f426f3cc7955ba0e4f6aab2b344221f Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 07:12:32 +0200 Subject: [PATCH 08/46] Refs #21188: Uncrustify Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 9d22dba3f5a..28124947d60 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -82,7 +82,8 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit struct RequestInput { - RequestInput(const CLIParser::config& config); + RequestInput( + const CLIParser::config& config); CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; @@ -119,18 +120,23 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit class Uint8CountSet { public: - void increase(const size_t& position) + + void increase( + const size_t& position) { assert(position <= (set_size - 1)); + if (inner_set_[position] < std::numeric_limits::max()) { inner_set_[position] += 1; } } - void decrease(const size_t& position) + void decrease( + const size_t& position) { assert(position <= (set_size - 1)); + if (inner_set_[position] > 0) { inner_set_[position] -= 1; @@ -154,6 +160,7 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit } private: + std::array inner_set_ = {0}; }; From 7c51b2d1da07c5d1d949709874eb6323e69b26f2 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 09:59:03 +0200 Subject: [PATCH 09/46] Refs #21188: Code grouping Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 221 ++++++++++++++--------- examples/cpp/request_reply/ClientApp.hpp | 72 +++++--- examples/cpp/request_reply/ServerApp.cpp | 201 +++++++++++++-------- examples/cpp/request_reply/ServerApp.hpp | 24 +++ 4 files changed, 325 insertions(+), 193 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index d1286dde66c..13501e2a6f5 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -41,6 +41,18 @@ namespace request_reply { using namespace eprosima::fastdds::dds; +/******* HELPER FUNCTIONS DECLARATIONS *******/ +namespace detail { + +template +Topic* create_topic( + const std::string& topic_name, + DomainParticipant* participant, + TypeSupport& type); + +} // namespace detail + +/******** CLIENTAPP CLASS DEFINITION ********/ // Define the constexpr so the linker can find the static members constexpr std::size_t ClientApp::request_writer_position_; constexpr std::size_t ClientApp::reply_reader_position_; @@ -58,6 +70,63 @@ ClientApp::ClientApp( , reply_topic_(nullptr) , subscriber_(nullptr) , reply_reader_(nullptr) +{ + create_participant(); + create_request_entities(service_name); + create_reply_entities(service_name); +} + +ClientApp::~ClientApp() +{ +} + +void ClientApp::run() +{ +} + +void ClientApp::stop() +{ +} + +void ClientApp::on_publication_matched( + DataWriter* /* writer */, + const PublicationMatchedStatus& info) +{ + std::lock_guard lock(mtx_); + + if (info.current_count_change == 1) + { + std::cout << "Remote request reader matched." << std::endl; + matched_state_.increase(request_writer_position_); + } + else if (info.current_count_change == -1) + { + std::cout << "Remote request reader unmatched." << std::endl; + matched_state_.decrease(request_writer_position_); + } + else + { + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + } + cv_.notify_one(); +} + +void ClientApp::on_subscription_matched( + DataReader* reader, + const SubscriptionMatchedStatus& info) +{ + static_cast(reader); + static_cast(info); +} + +void ClientApp::on_data_available( + DataReader* reader) +{ + static_cast(reader); +} + +void ClientApp::create_participant() { // Create the participant auto factory = DomainParticipantFactory::get_instance(); @@ -73,36 +142,29 @@ ClientApp::ClientApp( { throw std::runtime_error("Participant initialization failed"); } +} - /********** REQUEST ENTITIES **********/ - // Create the request TypeSupport - request_type_.reset(new CalculatorRequestTypePubSubType()); - - if (nullptr == request_type_) - { - throw std::runtime_error("Failed to create request type"); - } +template<> +Topic* ClientApp::create_topic( + const std::string& topic_name, + TypeSupport& type) +{ + return detail::create_topic(topic_name, participant_, type); +} - // Register the type - if (RETCODE_OK != request_type_.register_type(participant_)) - { - throw std::runtime_error("Failed to register request type"); - } +template<> +Topic* ClientApp::create_topic( + const std::string& topic_name, + TypeSupport& type) +{ + return detail::create_topic(topic_name, participant_, type); +} +void ClientApp::create_request_entities( + const std::string& service_name) +{ // Create the request topic - TopicQos topic_qos = TOPIC_QOS_DEFAULT; - - if (RETCODE_OK != participant_->get_default_topic_qos(topic_qos)) - { - throw std::runtime_error("Failed to get default topic qos"); - } - - request_topic_ = participant_->create_topic("rq/" + service_name, request_type_.get_type_name(), topic_qos); - - if (nullptr == request_topic_) - { - throw std::runtime_error("Request topic initialization failed"); - } + request_topic_ = create_topic("rq/" + service_name, request_type_); // Create the publisher PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT; @@ -119,7 +181,7 @@ ClientApp::ClientApp( throw std::runtime_error("Publisher initialization failed"); } - // Create the request writer + // Create the writer DataWriterQos writer_qos = DATAWRITER_QOS_DEFAULT; if (RETCODE_OK != publisher_->get_default_datawriter_qos(writer_qos)) @@ -133,29 +195,13 @@ ClientApp::ClientApp( { throw std::runtime_error("Request writer initialization failed"); } +} - /********** REPLY ENTITIES **********/ - // Create the reply TypeSupport - reply_type_.reset(new CalculatorReplyTypePubSubType()); - - if (nullptr == reply_type_) - { - throw std::runtime_error("Failed to create reply type"); - } - - // Register the type - if (RETCODE_OK != reply_type_.register_type(participant_)) - { - throw std::runtime_error("Failed to register reply type"); - } - +void ClientApp::create_reply_entities( + const std::string& service_name) +{ // Create the reply topic - reply_topic_ = participant_->create_topic("rr/" + service_name, reply_type_.get_type_name(), topic_qos); - - if (nullptr == reply_topic_) - { - throw std::runtime_error("Reply topic initialization failed"); - } + reply_topic_ = create_topic("rr/" + service_name, reply_type_); // Create the subscriber SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; @@ -172,7 +218,7 @@ ClientApp::ClientApp( throw std::runtime_error("Subscriber initialization failed"); } - // Create the request reader + // Create the reader DataReaderQos reader_qos = DATAREADER_QOS_DEFAULT; if (RETCODE_OK != subscriber_->get_default_datareader_qos(reader_qos)) @@ -188,64 +234,61 @@ ClientApp::ClientApp( } } -ClientApp::~ClientApp() +ClientApp::RequestInput::RequestInput( + const CLIParser::config& config) + : operation(config.operation) + , x(config.x) + , y(config.y) { } -void ClientApp::run() -{ -} +/******* HELPER FUNCTIONS DEFINITIONS *******/ +namespace detail { -void ClientApp::stop() +template +Topic* create_topic( + const std::string& topic_name, + DomainParticipant* participant, + TypeSupport& type) { -} + assert(nullptr != participant); + assert(nullptr == type.get()); -void ClientApp::on_publication_matched( - DataWriter* /* writer */, - const PublicationMatchedStatus& info) -{ - std::lock_guard lock(mtx_); + Topic* topic = nullptr; - if (info.current_count_change == 1) + // Create the TypeSupport + type.reset(new TypeSupportClass()); + + if (nullptr == type) { - std::cout << "Remote request reader matched." << std::endl; - matched_state_.increase(request_writer_position_); + throw std::runtime_error("Failed to create type"); } - else if (info.current_count_change == -1) + + // Register the type + if (RETCODE_OK != type.register_type(participant)) { - std::cout << "Remote request reader unmatched." << std::endl; - matched_state_.decrease(request_writer_position_); + throw std::runtime_error("Failed to register type"); } - else + + // Create the topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + + if (RETCODE_OK != participant->get_default_topic_qos(topic_qos)) { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + throw std::runtime_error("Failed to get default topic qos"); } - cv_.notify_one(); -} -void ClientApp::on_subscription_matched( - DataReader* reader, - const SubscriptionMatchedStatus& info) -{ - static_cast(reader); - static_cast(info); -} + topic = participant->create_topic(topic_name, type.get_type_name(), topic_qos); -void ClientApp::on_data_available( - DataReader* reader) -{ - static_cast(reader); -} + if (nullptr == topic) + { + throw std::runtime_error("Request topic initialization failed"); + } -ClientApp::RequestInput::RequestInput( - const CLIParser::config& config) - : operation(config.operation) - , x(config.x) - , y(config.y) -{ + return topic; } +} // namespace detail } // namespace request_reply } // namespace examples } // namespace fastdds diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 28124947d60..c7387c183eb 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -39,6 +39,7 @@ #include #include "Application.hpp" +#include "CalculatorPubSubTypes.hpp" #include "CLIParser.hpp" namespace eprosima { @@ -92,30 +93,6 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit std::int16_t y = 0; }; - RequestInput request_input_; - - DomainParticipant* participant_; - - TypeSupport request_type_; - - Topic* request_topic_; - - Publisher* publisher_; - - DataWriter* request_writer_; - - TypeSupport reply_type_; - - Topic* reply_topic_; - - Subscriber* subscriber_; - - DataReader* reply_reader_; - - mutable std::mutex mtx_; - - std::condition_variable cv_; - template class Uint8CountSet { @@ -164,6 +141,43 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit std::array inner_set_ = {0}; }; + void create_participant(); + + template + Topic* create_topic( + const std::string& topic_name, + TypeSupport& type); + + void create_request_entities( + const std::string& service_name); + + void create_reply_entities( + const std::string& service_name); + + RequestInput request_input_; + + DomainParticipant* participant_; + + TypeSupport request_type_; + + Topic* request_topic_; + + Publisher* publisher_; + + DataWriter* request_writer_; + + TypeSupport reply_type_; + + Topic* reply_topic_; + + Subscriber* subscriber_; + + DataReader* reply_reader_; + + mutable std::mutex mtx_; + + std::condition_variable cv_; + /** * @brief Set to represent the matched count of the request-reply endpoints: * @@ -177,6 +191,16 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit static constexpr std::size_t reply_reader_position_ = 1; }; +template<> +Topic* ClientApp::create_topic( + const std::string& topic_name, + TypeSupport& type); + +template<> +Topic* ClientApp::create_topic( + const std::string& topic_name, + TypeSupport& type); + } // namespace request_reply } // namespace examples } // namespace fastdds diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 28aeb75021c..e28e9dd8551 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -39,6 +39,18 @@ namespace fastdds { namespace examples { namespace request_reply { +/******* HELPER FUNCTIONS DECLARATIONS *******/ +namespace detail { + +template +Topic* create_topic( + const std::string& topic_name, + DomainParticipant* participant, + TypeSupport& type); + +} // namespace detail + +/******** SERVERAPP CLASS DEFINITION ********/ ServerApp::ServerApp( const std::string& service_name) : participant_(nullptr) @@ -51,50 +63,94 @@ ServerApp::ServerApp( , publisher_(nullptr) , reply_writer_(nullptr) { - // Create the participant - auto factory = DomainParticipantFactory::get_instance(); + create_participant(); + create_request_entities(service_name); + create_reply_entities(service_name); +} - if (nullptr == factory) - { - throw std::runtime_error("Failed to get participant factory instance"); - } +ServerApp::~ServerApp() +{ +} - participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); +void ServerApp::run() +{ +} - if (nullptr == participant_) - { - throw std::runtime_error("Participant initialization failed"); - } +void ServerApp::stop() +{ +} - /********** REQUEST ENTITIES **********/ - // Create the request TypeSupport - request_type_.reset(new CalculatorRequestTypePubSubType()); +void ServerApp::on_publication_matched( + DataWriter* writer, + const PublicationMatchedStatus& info) +{ + static_cast(writer); + static_cast(info); +} - if (nullptr == request_type_) +void ServerApp::on_subscription_matched( + DataReader* /* reader */, + const SubscriptionMatchedStatus& info) +{ + if (info.current_count_change == 1) { - throw std::runtime_error("Failed to create request type"); + std::cout << "Remote request writer matched." << std::endl; } - - // Register the type - if (RETCODE_OK != request_type_.register_type(participant_)) + else if (info.current_count_change == -1) + { + std::cout << "Remote request writer unmatched." << std::endl; + } + else { - throw std::runtime_error("Failed to register request type"); + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; } +} - // Create the request topic - TopicQos topic_qos = TOPIC_QOS_DEFAULT; +void ServerApp::on_data_available( + DataReader* reader) +{ + static_cast(reader); +} + +void ServerApp::create_participant() +{ + // Create the participant + auto factory = DomainParticipantFactory::get_instance(); - if (RETCODE_OK != participant_->get_default_topic_qos(topic_qos)) + if (nullptr == factory) { - throw std::runtime_error("Failed to get default topic qos"); + throw std::runtime_error("Failed to get participant factory instance"); } - request_topic_ = participant_->create_topic("rq/" + service_name, request_type_.get_type_name(), topic_qos); + participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); - if (nullptr == request_topic_) + if (nullptr == participant_) { - throw std::runtime_error("Request topic initialization failed"); + throw std::runtime_error("Participant initialization failed"); } +} + +template<> +Topic* ServerApp::create_topic( + const std::string& topic_name, + TypeSupport& type) +{ + return detail::create_topic(topic_name, participant_, type); +} + +template<> +Topic* ServerApp::create_topic( + const std::string& topic_name, + TypeSupport& type) +{ + return detail::create_topic(topic_name, participant_, type); +} + +void ServerApp::create_request_entities( + const std::string& service_name) +{ + request_topic_ = create_topic("rq/" + service_name, request_type_); // Create the subscriber SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; @@ -125,29 +181,12 @@ ServerApp::ServerApp( { throw std::runtime_error("Request reader initialization failed"); } +} - /********** REPLY ENTITIES **********/ - // Create the reply TypeSupport - reply_type_.reset(new CalculatorReplyTypePubSubType()); - - if (nullptr == reply_type_) - { - throw std::runtime_error("Failed to create reply type"); - } - - // Register the type - if (RETCODE_OK != reply_type_.register_type(participant_)) - { - throw std::runtime_error("Failed to register reply type"); - } - - // Create the reply topic - reply_topic_ = participant_->create_topic("rr/" + service_name, reply_type_.get_type_name(), topic_qos); - - if (nullptr == reply_topic_) - { - throw std::runtime_error("Reply topic initialization failed"); - } +void ServerApp::create_reply_entities( + const std::string& service_name) +{ + reply_topic_ = create_topic("rr/" + service_name, reply_type_); // Create the publisher PublisherQos pub_qos = PUBLISHER_QOS_DEFAULT; @@ -180,51 +219,53 @@ ServerApp::ServerApp( } } -ServerApp::~ServerApp() -{ -} +/******* HELPER FUNCTIONS DEFINITIONS *******/ +namespace detail { -void ServerApp::run() +template +Topic* create_topic( + const std::string& topic_name, + DomainParticipant* participant, + TypeSupport& type) { -} + assert(nullptr != participant); + assert(nullptr == type.get()); -void ServerApp::stop() -{ -} + Topic* topic = nullptr; -void ServerApp::on_publication_matched( - DataWriter* writer, - const PublicationMatchedStatus& info) -{ - static_cast(writer); - static_cast(info); -} + // Create the TypeSupport + type.reset(new TypeSupportClass()); -void ServerApp::on_subscription_matched( - DataReader* /* reader */, - const SubscriptionMatchedStatus& info) -{ - if (info.current_count_change == 1) + if (nullptr == type) { - std::cout << "Remote request writer matched." << std::endl; + throw std::runtime_error("Failed to create type"); } - else if (info.current_count_change == -1) + + // Register the type + if (RETCODE_OK != type.register_type(participant)) { - std::cout << "Remote request writer unmatched." << std::endl; + throw std::runtime_error("Failed to register type"); } - else + + // Create the topic + TopicQos topic_qos = TOPIC_QOS_DEFAULT; + + if (RETCODE_OK != participant->get_default_topic_qos(topic_qos)) { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + throw std::runtime_error("Failed to get default topic qos"); } -} -void ServerApp::on_data_available( - DataReader* reader) -{ - static_cast(reader); + topic = participant->create_topic(topic_name, type.get_type_name(), topic_qos); + + if (nullptr == topic) + { + throw std::runtime_error("Request topic initialization failed"); + } + + return topic; } +} // namespace detail } // namespace request_reply } // namespace examples } // namespace fastdds diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index 589218dd99a..8e69325b88d 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -33,6 +33,7 @@ #include #include "Application.hpp" +#include "CalculatorPubSubTypes.hpp" namespace eprosima { namespace fastdds { @@ -72,6 +73,19 @@ class ServerApp : public Application, public DataWriterListener, public DataRead private: + void create_participant(); + + template + Topic* create_topic( + const std::string& topic_name, + TypeSupport& type); + + void create_request_entities( + const std::string& service_name); + + void create_reply_entities( + const std::string& service_name); + DomainParticipant* participant_; TypeSupport request_type_; @@ -91,6 +105,16 @@ class ServerApp : public Application, public DataWriterListener, public DataRead DataWriter* reply_writer_; }; +template<> +Topic* ServerApp::create_topic( + const std::string& topic_name, + TypeSupport& type); + +template<> +Topic* ServerApp::create_topic( + const std::string& topic_name, + TypeSupport& type); + } // namespace request_reply } // namespace examples } // namespace fastdds From ca43e5cbfb2c07fba2aa780b0ca911b8a1f3244b Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 10:33:27 +0200 Subject: [PATCH 10/46] Refs #21188: Refactor matched status and create a utils header Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 21 ++-- examples/cpp/request_reply/ClientApp.hpp | 76 +------------- examples/cpp/request_reply/app_utils.hpp | 126 +++++++++++++++++++++++ 3 files changed, 135 insertions(+), 88 deletions(-) create mode 100644 examples/cpp/request_reply/app_utils.hpp diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 13501e2a6f5..743162acff0 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include "Calculator.hpp" #include "CalculatorPubSubTypes.hpp" @@ -53,10 +55,6 @@ Topic* create_topic( } // namespace detail /******** CLIENTAPP CLASS DEFINITION ********/ -// Define the constexpr so the linker can find the static members -constexpr std::size_t ClientApp::request_writer_position_; -constexpr std::size_t ClientApp::reply_reader_position_; - ClientApp::ClientApp( const CLIParser::config& config, const std::string& service_name) @@ -94,15 +92,18 @@ void ClientApp::on_publication_matched( { std::lock_guard lock(mtx_); + rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.last_subscription_handle).guidPrefix; + if (info.current_count_change == 1) { std::cout << "Remote request reader matched." << std::endl; - matched_state_.increase(request_writer_position_); + + server_matched_status_.match_request_reader(server_guid_prefix, true); } else if (info.current_count_change == -1) { std::cout << "Remote request reader unmatched." << std::endl; - matched_state_.decrease(request_writer_position_); + server_matched_status_.match_request_reader(server_guid_prefix, false); } else { @@ -234,14 +235,6 @@ void ClientApp::create_reply_entities( } } -ClientApp::RequestInput::RequestInput( - const CLIParser::config& config) - : operation(config.operation) - , x(config.x) - , y(config.y) -{ -} - /******* HELPER FUNCTIONS DEFINITIONS *******/ namespace detail { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index c7387c183eb..1e38126240f 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -20,11 +20,7 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP -#include -#include #include -#include -#include #include #include @@ -38,6 +34,7 @@ #include #include +#include "app_utils.hpp" #include "Application.hpp" #include "CalculatorPubSubTypes.hpp" #include "CLIParser.hpp" @@ -81,66 +78,6 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit private: - struct RequestInput - { - RequestInput( - const CLIParser::config& config); - - CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; - - std::int16_t x = 0; - - std::int16_t y = 0; - }; - - template - class Uint8CountSet - { - public: - - void increase( - const size_t& position) - { - assert(position <= (set_size - 1)); - - if (inner_set_[position] < std::numeric_limits::max()) - { - inner_set_[position] += 1; - } - } - - void decrease( - const size_t& position) - { - assert(position <= (set_size - 1)); - - if (inner_set_[position] > 0) - { - inner_set_[position] -= 1; - } - } - - bool all() - { - bool all_different_from_zero = true; - - for (auto i = 0; i < set_size; i++) - { - if (inner_set_[i] == 0) - { - all_different_from_zero = false; - break; - } - } - - return all_different_from_zero; - } - - private: - - std::array inner_set_ = {0}; - }; - void create_participant(); template @@ -178,17 +115,8 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit std::condition_variable cv_; - /** - * @brief Set to represent the matched count of the request-reply endpoints: - * - * - Position 0 represents matching status of request writer - * - Position 1 represents matching status of reply reader - */ - Uint8CountSet<2> matched_state_; - - static constexpr std::size_t request_writer_position_ = 0; + RemoteServerMatchedStatus server_matched_status_; - static constexpr std::size_t reply_reader_position_ = 1; }; template<> diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp new file mode 100644 index 00000000000..c9d5fbbe72c --- /dev/null +++ b/examples/cpp/request_reply/app_utils.hpp @@ -0,0 +1,126 @@ +// Copyright 2024 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. + +/** + * @file app_utils.hpp + * + */ + +#ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APP_UTILS_HPP +#define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APP_UTILS_HPP + +#include +#include +#include +#include +#include + +#include + +#include "CLIParser.hpp" + +namespace eprosima { +namespace fastdds { +namespace examples { +namespace request_reply { + +struct RequestInput +{ + RequestInput( + const CLIParser::config& config) + : operation(config.operation) + , x(config.x) + , y(config.y) + { + } + + CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; + + std::int16_t x = 0; + + std::int16_t y = 0; +}; + +class RemoteServerMatchedStatus +{ +public: + + void match_request_reader( + const rtps::GuidPrefix_t& guid_prefix, + const bool& status) + { + matched_status_[guid_prefix].set(request_reader_position, status); + } + + void match_reply_writer( + const rtps::GuidPrefix_t& guid_prefix, + const bool& status) + { + matched_status_[guid_prefix].set(reply_writer_position, status); + } + + bool is_matched( + const rtps::GuidPrefix_t& guid_prefix) + { + return matched_status_[guid_prefix].all(); + } + +private: + + std::map> matched_status_; + + static const size_t request_reader_position = 0; + + static const size_t reply_writer_position = 1; +}; + +class RemoteClientMatchedStatus +{ +public: + + void match_request_writer( + const rtps::GuidPrefix_t& guid_prefix, + const bool& status) + { + matched_status_[guid_prefix].set(request_writer_position, status); + } + + void match_reply_reader( + const rtps::GuidPrefix_t& guid_prefix, + const bool& status) + { + matched_status_[guid_prefix].set(reply_reader_position, status); + } + + bool is_matched( + const rtps::GuidPrefix_t& guid_prefix) + { + return matched_status_[guid_prefix].all(); + } + +private: + + std::map> matched_status_; + + static const size_t request_writer_position = 0; + + static const size_t reply_reader_position = 1; +}; + +} // namespace request_reply +} // namespace examples +} // namespace fastdds +} // namespace eprosima + +#endif // FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APP_UTILS_HPP From 155efc43fbbf018faf07f8632d04552067f65039 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 10:40:29 +0200 Subject: [PATCH 11/46] Refs #21188: Client waits until a server is fully matched Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 30 +++++++++++++++++++++--- examples/cpp/request_reply/app_utils.hpp | 14 +++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 743162acff0..6afd88d6a78 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -80,6 +80,11 @@ ClientApp::~ClientApp() void ClientApp::run() { + std::unique_lock lock(mtx_); + cv_.wait(lock, [&]() + { + return server_matched_status_.is_any_server_matched(); + }); } void ClientApp::stop() @@ -114,11 +119,30 @@ void ClientApp::on_publication_matched( } void ClientApp::on_subscription_matched( - DataReader* reader, + DataReader* /* reader */, const SubscriptionMatchedStatus& info) { - static_cast(reader); - static_cast(info); + std::lock_guard lock(mtx_); + + rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.last_publication_handle).guidPrefix; + + if (info.current_count_change == 1) + { + std::cout << "Remote reply writer matched." << std::endl; + + server_matched_status_.match_reply_writer(server_guid_prefix, true); + } + else if (info.current_count_change == -1) + { + std::cout << "Remote reply writer unmatched." << std::endl; + server_matched_status_.match_reply_writer(server_guid_prefix, false); + } + else + { + std::cout << info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + } + cv_.notify_one(); } void ClientApp::on_data_available( diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index c9d5fbbe72c..87447f4a312 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -76,6 +76,20 @@ class RemoteServerMatchedStatus return matched_status_[guid_prefix].all(); } + bool is_any_server_matched() + { + bool any_server_matched = false; + for (const auto& status : matched_status_) + { + if (status.second.all()) + { + any_server_matched = true; + break; + } + } + return any_server_matched; + } + private: std::map> matched_status_; From 8b1075e7279c5c3cf4b833d9d89340ee101b07cb Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 10:52:12 +0200 Subject: [PATCH 12/46] Refs #21188: Server runs until it is stopped Signed-off-by: eduponz --- examples/cpp/request_reply/ServerApp.cpp | 13 +++++++++++++ examples/cpp/request_reply/ServerApp.hpp | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index e28e9dd8551..2d75129fa6d 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -20,6 +20,7 @@ #include "ServerApp.hpp" #include +#include #include #include @@ -74,10 +75,17 @@ ServerApp::~ServerApp() void ServerApp::run() { + std::unique_lock lock(mtx_); + cv_.wait(lock, [this]() -> bool + { + return is_stopped(); + }); } void ServerApp::stop() { + stop_.store(true); + cv_.notify_one(); } void ServerApp::on_publication_matched( @@ -219,6 +227,11 @@ void ServerApp::create_reply_entities( } } +bool ServerApp::is_stopped() +{ + return stop_.load(); +} + /******* HELPER FUNCTIONS DEFINITIONS *******/ namespace detail { diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index 8e69325b88d..e941f70502f 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -20,6 +20,9 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__SERVERAPP_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__SERVERAPP_HPP +#include +#include +#include #include #include @@ -86,6 +89,8 @@ class ServerApp : public Application, public DataWriterListener, public DataRead void create_reply_entities( const std::string& service_name); + bool is_stopped(); + DomainParticipant* participant_; TypeSupport request_type_; @@ -103,6 +108,12 @@ class ServerApp : public Application, public DataWriterListener, public DataRead Publisher* publisher_; DataWriter* reply_writer_; + + std::mutex mtx_; + + std::condition_variable cv_; + + std::atomic stop_; }; template<> From 5815b8eb6a7b4f72bc5c5624efeeb5c6d3514be8 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 28 Jun 2024 12:12:44 +0200 Subject: [PATCH 13/46] Refs #21188: Client sends requests which are put in a queue Signed-off-by: eduponz --- examples/cpp/request_reply/Calculator.hpp | 258 +++++++++++- examples/cpp/request_reply/Calculator.idl | 8 + .../cpp/request_reply/CalculatorCdrAux.hpp | 15 +- .../cpp/request_reply/CalculatorCdrAux.ipp | 393 +++++++++++------- .../request_reply/CalculatorPubSubTypes.cxx | 227 +++++++++- .../request_reply/CalculatorPubSubTypes.hpp | 91 ++++ .../CalculatorTypeObjectSupport.cxx | 369 ++++++++++------ .../CalculatorTypeObjectSupport.hpp | 12 + examples/cpp/request_reply/ClientApp.cpp | 29 +- examples/cpp/request_reply/ClientApp.hpp | 3 +- examples/cpp/request_reply/ServerApp.cpp | 70 +++- examples/cpp/request_reply/ServerApp.hpp | 15 + examples/cpp/request_reply/app_utils.hpp | 74 +++- 13 files changed, 1249 insertions(+), 315 deletions(-) diff --git a/examples/cpp/request_reply/Calculator.hpp b/examples/cpp/request_reply/Calculator.hpp index ad1d51b8747..19550d56dd2 100644 --- a/examples/cpp/request_reply/Calculator.hpp +++ b/examples/cpp/request_reply/Calculator.hpp @@ -22,6 +22,7 @@ #ifndef FAST_DDS_GENERATED__CALCULATOR_HPP #define FAST_DDS_GENERATED__CALCULATOR_HPP +#include #include #include @@ -60,6 +61,139 @@ enum class CalculatorOperationType : int32_t MULTIPLICATION, DIVISION }; +/*! + * @brief This class represents the structure ClientID defined by the user in the IDL file. + * @ingroup Calculator + */ +class ClientID +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport ClientID() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~ClientID() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object ClientID that will be copied. + */ + eProsima_user_DllExport ClientID( + const ClientID& x) + { + m_value = x.m_value; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object ClientID that will be copied. + */ + eProsima_user_DllExport ClientID( + ClientID&& x) noexcept + { + m_value = std::move(x.m_value); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object ClientID that will be copied. + */ + eProsima_user_DllExport ClientID& operator =( + const ClientID& x) + { + + m_value = x.m_value; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object ClientID that will be copied. + */ + eProsima_user_DllExport ClientID& operator =( + ClientID&& x) noexcept + { + + m_value = std::move(x.m_value); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x ClientID object to compare. + */ + eProsima_user_DllExport bool operator ==( + const ClientID& x) const + { + return (m_value == x.m_value); + } + + /*! + * @brief Comparison operator. + * @param x ClientID object to compare. + */ + eProsima_user_DllExport bool operator !=( + const ClientID& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member value + * @param _value New value to be copied in member value + */ + eProsima_user_DllExport void value( + const std::array& _value) + { + m_value = _value; + } + + /*! + * @brief This function moves the value in member value + * @param _value New value to be moved in member value + */ + eProsima_user_DllExport void value( + std::array&& _value) + { + m_value = std::move(_value); + } + + /*! + * @brief This function returns a constant reference to member value + * @return Constant reference to member value + */ + eProsima_user_DllExport const std::array& value() const + { + return m_value; + } + + /*! + * @brief This function returns a reference to member value + * @return Reference to member value + */ + eProsima_user_DllExport std::array& value() + { + return m_value; + } + + + +private: + + std::array m_value{0}; + +}; /*! * @brief This class represents the structure CalculatorRequestType defined by the user in the IDL file. * @ingroup Calculator @@ -89,11 +223,13 @@ class CalculatorRequestType eProsima_user_DllExport CalculatorRequestType( const CalculatorRequestType& x) { - m_operation = x.m_operation; + m_client_id = x.m_client_id; - m_x = x.m_x; + m_operation = x.m_operation; - m_y = x.m_y; + m_x = x.m_x; + + m_y = x.m_y; } @@ -104,6 +240,7 @@ class CalculatorRequestType eProsima_user_DllExport CalculatorRequestType( CalculatorRequestType&& x) noexcept { + m_client_id = std::move(x.m_client_id); m_operation = x.m_operation; m_x = x.m_x; m_y = x.m_y; @@ -117,11 +254,13 @@ class CalculatorRequestType const CalculatorRequestType& x) { - m_operation = x.m_operation; + m_client_id = x.m_client_id; - m_x = x.m_x; + m_operation = x.m_operation; - m_y = x.m_y; + m_x = x.m_x; + + m_y = x.m_y; return *this; } @@ -134,6 +273,7 @@ class CalculatorRequestType CalculatorRequestType&& x) noexcept { + m_client_id = std::move(x.m_client_id); m_operation = x.m_operation; m_x = x.m_x; m_y = x.m_y; @@ -147,9 +287,10 @@ class CalculatorRequestType eProsima_user_DllExport bool operator ==( const CalculatorRequestType& x) const { - return (m_operation == x.m_operation && - m_x == x.m_x && - m_y == x.m_y); + return (m_client_id == x.m_client_id && + m_operation == x.m_operation && + m_x == x.m_x && + m_y == x.m_y); } /*! @@ -162,6 +303,45 @@ class CalculatorRequestType return !(*this == x); } + /*! + * @brief This function copies the value in member client_id + * @param _client_id New value to be copied in member client_id + */ + eProsima_user_DllExport void client_id( + const ClientID& _client_id) + { + m_client_id = _client_id; + } + + /*! + * @brief This function moves the value in member client_id + * @param _client_id New value to be moved in member client_id + */ + eProsima_user_DllExport void client_id( + ClientID&& _client_id) + { + m_client_id = std::move(_client_id); + } + + /*! + * @brief This function returns a constant reference to member client_id + * @return Constant reference to member client_id + */ + eProsima_user_DllExport const ClientID& client_id() const + { + return m_client_id; + } + + /*! + * @brief This function returns a reference to member client_id + * @return Reference to member client_id + */ + eProsima_user_DllExport ClientID& client_id() + { + return m_client_id; + } + + /*! * @brief This function sets a value in member operation * @param _operation New value for member operation @@ -190,6 +370,7 @@ class CalculatorRequestType return m_operation; } + /*! * @brief This function sets a value in member x * @param _x New value for member x @@ -218,6 +399,7 @@ class CalculatorRequestType return m_x; } + /*! * @brief This function sets a value in member y * @param _y New value for member y @@ -246,8 +428,11 @@ class CalculatorRequestType return m_y; } + + private: + ClientID m_client_id; CalculatorOperationType m_operation{CalculatorOperationType::ADDITION}; int16_t m_x{0}; int16_t m_y{0}; @@ -282,7 +467,9 @@ class CalculatorReplyType eProsima_user_DllExport CalculatorReplyType( const CalculatorReplyType& x) { - m_z = x.m_z; + m_client_id = x.m_client_id; + + m_z = x.m_z; } @@ -293,6 +480,7 @@ class CalculatorReplyType eProsima_user_DllExport CalculatorReplyType( CalculatorReplyType&& x) noexcept { + m_client_id = std::move(x.m_client_id); m_z = x.m_z; } @@ -304,7 +492,9 @@ class CalculatorReplyType const CalculatorReplyType& x) { - m_z = x.m_z; + m_client_id = x.m_client_id; + + m_z = x.m_z; return *this; } @@ -317,6 +507,7 @@ class CalculatorReplyType CalculatorReplyType&& x) noexcept { + m_client_id = std::move(x.m_client_id); m_z = x.m_z; return *this; } @@ -328,7 +519,8 @@ class CalculatorReplyType eProsima_user_DllExport bool operator ==( const CalculatorReplyType& x) const { - return (m_z == x.m_z); + return (m_client_id == x.m_client_id && + m_z == x.m_z); } /*! @@ -341,6 +533,45 @@ class CalculatorReplyType return !(*this == x); } + /*! + * @brief This function copies the value in member client_id + * @param _client_id New value to be copied in member client_id + */ + eProsima_user_DllExport void client_id( + const ClientID& _client_id) + { + m_client_id = _client_id; + } + + /*! + * @brief This function moves the value in member client_id + * @param _client_id New value to be moved in member client_id + */ + eProsima_user_DllExport void client_id( + ClientID&& _client_id) + { + m_client_id = std::move(_client_id); + } + + /*! + * @brief This function returns a constant reference to member client_id + * @return Constant reference to member client_id + */ + eProsima_user_DllExport const ClientID& client_id() const + { + return m_client_id; + } + + /*! + * @brief This function returns a reference to member client_id + * @return Reference to member client_id + */ + eProsima_user_DllExport ClientID& client_id() + { + return m_client_id; + } + + /*! * @brief This function sets a value in member z * @param _z New value for member z @@ -369,8 +600,11 @@ class CalculatorReplyType return m_z; } + + private: + ClientID m_client_id; int32_t m_z{0}; }; diff --git a/examples/cpp/request_reply/Calculator.idl b/examples/cpp/request_reply/Calculator.idl index 4306b9bf2d8..f245d32f0ec 100644 --- a/examples/cpp/request_reply/Calculator.idl +++ b/examples/cpp/request_reply/Calculator.idl @@ -7,9 +7,16 @@ enum CalculatorOperationType DIVISION }; +@extensibility(APPENDABLE) +struct ClientID +{ + octet value[12]; +}; + @extensibility(APPENDABLE) struct CalculatorRequestType { + @key ClientID client_id; CalculatorOperationType operation; short x; short y; @@ -18,5 +25,6 @@ struct CalculatorRequestType @extensibility(APPENDABLE) struct CalculatorReplyType { + @key ClientID client_id; long z; }; diff --git a/examples/cpp/request_reply/CalculatorCdrAux.hpp b/examples/cpp/request_reply/CalculatorCdrAux.hpp index 8119c875fec..7b855d1f08f 100644 --- a/examples/cpp/request_reply/CalculatorCdrAux.hpp +++ b/examples/cpp/request_reply/CalculatorCdrAux.hpp @@ -24,11 +24,14 @@ #include "Calculator.hpp" -constexpr uint32_t CalculatorRequestType_max_cdr_typesize {12UL}; -constexpr uint32_t CalculatorRequestType_max_key_cdr_typesize {0UL}; +constexpr uint32_t CalculatorRequestType_max_cdr_typesize {28UL}; +constexpr uint32_t CalculatorRequestType_max_key_cdr_typesize {16UL}; -constexpr uint32_t CalculatorReplyType_max_cdr_typesize {8UL}; -constexpr uint32_t CalculatorReplyType_max_key_cdr_typesize {0UL}; +constexpr uint32_t CalculatorReplyType_max_cdr_typesize {24UL}; +constexpr uint32_t CalculatorReplyType_max_key_cdr_typesize {16UL}; + +constexpr uint32_t ClientID_max_cdr_typesize {16UL}; +constexpr uint32_t ClientID_max_key_cdr_typesize {0UL}; @@ -38,6 +41,10 @@ namespace fastcdr { class Cdr; class CdrSizeCalculator; +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const ClientID& data); + eProsima_user_DllExport void serialize_key( eprosima::fastcdr::Cdr& scdr, const CalculatorRequestType& data); diff --git a/examples/cpp/request_reply/CalculatorCdrAux.ipp b/examples/cpp/request_reply/CalculatorCdrAux.ipp index ba5c128f299..6f8974e51b0 100644 --- a/examples/cpp/request_reply/CalculatorCdrAux.ipp +++ b/examples/cpp/request_reply/CalculatorCdrAux.ipp @@ -32,85 +32,166 @@ using namespace eprosima::fastcdr::exception; namespace eprosima { - namespace fastcdr { - - template < > - eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const CalculatorRequestType& data, - size_t& current_alignment) - { - static_cast < void > (data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size { - calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment) - }; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.operation(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), - data.x(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), - data.y(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; - } - - template < > - eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const CalculatorRequestType& data) - { - eprosima::fastcdr::Cdr::state current_state( - scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.operation() - << eprosima::fastcdr::MemberId(1) << data.x() - << eprosima::fastcdr::MemberId(2) << data.y() - ; - scdr.end_serialize_type(current_state); - } - - template < > - eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - CalculatorRequestType& data) - { - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid)->bool +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const ClientID& data, + size_t& current_alignment) +{ + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.value(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const ClientID& data) +{ + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.value() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + ClientID& data) +{ + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool { bool ret_value = true; switch (mid.id) { - case 0: - dcdr >> data.operation(); - break; + case 0: + dcdr >> data.value(); + break; - case 1: - dcdr >> data.x(); + default: + ret_value = false; break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const ClientID& data) +{ + static_cast(scdr); + static_cast(data); +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorRequestType& data, + size_t& current_alignment) +{ + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.client_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.operation(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.x(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.y(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) +{ + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.client_id() + << eprosima::fastcdr::MemberId(1) << data.operation() + << eprosima::fastcdr::MemberId(2) << data.x() + << eprosima::fastcdr::MemberId(3) << data.y() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorRequestType& data) +{ + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.client_id(); + break; - case 2: - dcdr >> data.y(); - break; + case 1: + dcdr >> data.operation(); + break; + + case 2: + dcdr >> data.x(); + break; + + case 3: + dcdr >> data.y(); + break; default: ret_value = false; @@ -118,77 +199,88 @@ namespace eprosima { } return ret_value; }); - } - - void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const CalculatorRequestType& data) - { - static_cast < void > (scdr); - static_cast < void > (data); - } - - template < > - eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const CalculatorReplyType& data, - size_t& current_alignment) - { - static_cast < void > (data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size { - calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment) - }; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.z(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; - } - - template < > - eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const CalculatorReplyType& data) - { - eprosima::fastcdr::Cdr::state current_state( - scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.z() - ; - scdr.end_serialize_type(current_state); - } - - template < > - eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - CalculatorReplyType& data) - { - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid)->bool +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorRequestType& data) +{ + static_cast(scdr); + static_cast(data); + scdr << data.client_id(); + + + + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const CalculatorReplyType& data, + size_t& current_alignment) +{ + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.client_id(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.z(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) +{ + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.client_id() + << eprosima::fastcdr::MemberId(1) << data.z() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + CalculatorReplyType& data) +{ + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool { bool ret_value = true; switch (mid.id) { - case 0: - dcdr >> data.z(); - break; + case 0: + dcdr >> data.client_id(); + break; + + case 1: + dcdr >> data.z(); + break; default: ret_value = false; @@ -196,17 +288,22 @@ namespace eprosima { } return ret_value; }); - } +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const CalculatorReplyType& data) +{ + static_cast(scdr); + static_cast(data); + scdr << data.client_id(); + + +} + - void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const CalculatorReplyType& data) - { - static_cast < void > (scdr); - static_cast < void > (data); - } - } // namespace fastcdr +} // namespace fastcdr } // namespace eprosima #endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx index be653403af7..c4ed9303fe9 100644 --- a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx +++ b/examples/cpp/request_reply/CalculatorPubSubTypes.cxx @@ -31,20 +31,212 @@ using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; +ClientIDPubSubType::ClientIDPubSubType() +{ + setName("ClientID"); + uint32_t type_size = +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(ClientID::getMaxCdrSerializedSize()); +#else + ClientID_max_cdr_typesize; +#endif + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + m_typeSize = type_size + 4; /*encapsulation*/ + m_isGetKeyDefined = false; + uint32_t keyLength = ClientID_max_key_cdr_typesize > 16 ? ClientID_max_key_cdr_typesize : 16; + m_keyBuffer = reinterpret_cast(malloc(keyLength)); + memset(m_keyBuffer, 0, keyLength); +} + +ClientIDPubSubType::~ClientIDPubSubType() +{ + if (m_keyBuffer != nullptr) + { + free(m_keyBuffer); + } +} + +bool ClientIDPubSubType::serialize( + const void* const data, + SerializedPayload_t* payload, + DataRepresentationId_t data_representation) +{ + const ClientID* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; +#if FASTCDR_VERSION_MAJOR > 1 + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); +#endif // FASTCDR_VERSION_MAJOR > 1 + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length +#if FASTCDR_VERSION_MAJOR == 1 + payload->length = static_cast(ser.getSerializedDataLength()); +#else + payload->length = static_cast(ser.get_serialized_data_length()); +#endif // FASTCDR_VERSION_MAJOR == 1 + return true; +} + +bool ClientIDPubSubType::deserialize( + SerializedPayload_t* payload, + void* data) +{ + try + { + // Convert DATA to pointer of your type + ClientID* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN +#if FASTCDR_VERSION_MAJOR == 1 + , eprosima::fastcdr::Cdr::CdrType::DDS_CDR +#endif // FASTCDR_VERSION_MAJOR == 1 + ); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; +} + +std::function ClientIDPubSubType::getSerializedSizeProvider( + const void* const data, + DataRepresentationId_t data_representation) +{ + return [data, data_representation]() -> uint32_t + { +#if FASTCDR_VERSION_MAJOR == 1 + static_cast(data_representation); + return static_cast(type::getCdrSerializedSize(*static_cast(data))) + + 4u /*encapsulation*/; +#else + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } +#endif // FASTCDR_VERSION_MAJOR == 1 + }; +} + +void* ClientIDPubSubType::createData() +{ + return reinterpret_cast(new ClientID()); +} + +void ClientIDPubSubType::deleteData( + void* data) +{ + delete(reinterpret_cast(data)); +} + +bool ClientIDPubSubType::getKey( + const void* const data, + InstanceHandle_t* handle, + bool force_md5) +{ + if (!m_isGetKeyDefined) + { + return false; + } + + const ClientID* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), + ClientID_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); +#if FASTCDR_VERSION_MAJOR == 1 + p_type->serializeKey(ser); +#else + eprosima::fastcdr::serialize_key(ser, *p_type); +#endif // FASTCDR_VERSION_MAJOR == 1 + if (force_md5 || ClientID_max_key_cdr_typesize > 16) + { + m_md5.init(); +#if FASTCDR_VERSION_MAJOR == 1 + m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); +#else + m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); +#endif // FASTCDR_VERSION_MAJOR == 1 + m_md5.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_md5.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle->value[i] = m_keyBuffer[i]; + } + } + return true; +} + +void ClientIDPubSubType::register_type_object_representation() +{ + register_ClientID_type_identifier(type_identifiers_); +} + CalculatorRequestTypePubSubType::CalculatorRequestTypePubSubType() { setName("CalculatorRequestType"); uint32_t type_size = #if FASTCDR_VERSION_MAJOR == 1 - static_cast(CalculatorRequestType::getMaxCdrSerializedSize()); + static_cast(CalculatorRequestType::getMaxCdrSerializedSize()); #else - CalculatorRequestType_max_cdr_typesize; -#endif // if FASTCDR_VERSION_MAJOR == 1 + CalculatorRequestType_max_cdr_typesize; +#endif type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ m_typeSize = type_size + 4; /*encapsulation*/ - m_isGetKeyDefined = false; - uint32_t keyLength = CalculatorRequestType_max_key_cdr_typesize > - 16 ? CalculatorRequestType_max_key_cdr_typesize : 16; + m_isGetKeyDefined = true; + uint32_t keyLength = CalculatorRequestType_max_key_cdr_typesize > 16 ? CalculatorRequestType_max_key_cdr_typesize : 16; m_keyBuffer = reinterpret_cast(malloc(keyLength)); memset(m_keyBuffer, 0, keyLength); } @@ -151,8 +343,8 @@ std::function CalculatorRequestTypePubSubType::getSerializedSizeProv eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; } catch (eprosima::fastcdr::exception::Exception& /*exception*/) { @@ -190,8 +382,7 @@ bool CalculatorRequestTypePubSubType::getKey( CalculatorRequestType_max_key_cdr_typesize); // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, - eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); #if FASTCDR_VERSION_MAJOR == 1 p_type->serializeKey(ser); #else @@ -231,13 +422,13 @@ CalculatorReplyTypePubSubType::CalculatorReplyTypePubSubType() setName("CalculatorReplyType"); uint32_t type_size = #if FASTCDR_VERSION_MAJOR == 1 - static_cast(CalculatorReplyType::getMaxCdrSerializedSize()); + static_cast(CalculatorReplyType::getMaxCdrSerializedSize()); #else - CalculatorReplyType_max_cdr_typesize; -#endif // if FASTCDR_VERSION_MAJOR == 1 + CalculatorReplyType_max_cdr_typesize; +#endif type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ m_typeSize = type_size + 4; /*encapsulation*/ - m_isGetKeyDefined = false; + m_isGetKeyDefined = true; uint32_t keyLength = CalculatorReplyType_max_key_cdr_typesize > 16 ? CalculatorReplyType_max_key_cdr_typesize : 16; m_keyBuffer = reinterpret_cast(malloc(keyLength)); memset(m_keyBuffer, 0, keyLength); @@ -345,8 +536,8 @@ std::function CalculatorReplyTypePubSubType::getSerializedSizeProvid eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); size_t current_alignment {0}; return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; } catch (eprosima::fastcdr::exception::Exception& /*exception*/) { @@ -384,8 +575,7 @@ bool CalculatorReplyTypePubSubType::getKey( CalculatorReplyType_max_key_cdr_typesize); // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, - eprosima::fastcdr::CdrVersion::XCDRv1); + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); #if FASTCDR_VERSION_MAJOR == 1 p_type->serializeKey(ser); #else @@ -420,5 +610,6 @@ void CalculatorReplyTypePubSubType::register_type_object_representation() register_CalculatorReplyType_type_identifier(type_identifiers_); } + // Include auxiliary functions like for serializing/deserializing. #include "CalculatorCdrAux.ipp" diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.hpp b/examples/cpp/request_reply/CalculatorPubSubTypes.hpp index aaa3a479c35..5b7c9fed89f 100644 --- a/examples/cpp/request_reply/CalculatorPubSubTypes.hpp +++ b/examples/cpp/request_reply/CalculatorPubSubTypes.hpp @@ -38,6 +38,97 @@ #endif // GEN_API_VER +/*! + * @brief This class represents the TopicDataType of the type ClientID defined by the user in the IDL file. + * @ingroup Calculator + */ +class ClientIDPubSubType : public eprosima::fastdds::dds::TopicDataType +{ +public: + + typedef ClientID type; + + eProsima_user_DllExport ClientIDPubSubType(); + + eProsima_user_DllExport ~ClientIDPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload) override + { + return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t* payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t* payload, + void* data) override; + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data) override + { + return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); + } + + eProsima_user_DllExport std::function getSerializedSizeProvider( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool getKey( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t* ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* createData() override; + + eProsima_user_DllExport void deleteData( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + +#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + eProsima_user_DllExport inline bool is_plain() const override + { + return false; + } + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + +#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + +#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + eprosima::fastdds::MD5 m_md5; + unsigned char* m_keyBuffer; + +}; + /*! * @brief This class represents the TopicDataType of the type CalculatorRequestType defined by the user in the IDL file. * @ingroup Calculator diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx index dcaf7de67c3..24f48388d96 100644 --- a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx @@ -43,15 +43,13 @@ void register_CalculatorOperationType_type_identifier( { ReturnCode_t return_code_CalculatorOperationType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorOperationType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "CalculatorOperationType", type_ids_CalculatorOperationType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorOperationType) { EnumTypeFlag enum_flags_CalculatorOperationType = 0; BitBound bit_bound_CalculatorOperationType = 32; - CommonEnumeratedHeader common_CalculatorOperationType = TypeObjectUtils::build_common_enumerated_header( - bit_bound_CalculatorOperationType); + CommonEnumeratedHeader common_CalculatorOperationType = TypeObjectUtils::build_common_enumerated_header(bit_bound_CalculatorOperationType); QualifiedTypeName type_name_CalculatorOperationType = "CalculatorOperationType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorOperationType; eprosima::fastcdr::optional ann_custom_CalculatorOperationType; @@ -62,96 +60,171 @@ void register_CalculatorOperationType_type_identifier( ann_custom_CalculatorOperationType = tmp_ann_custom_CalculatorOperationType; } - CompleteTypeDetail detail_CalculatorOperationType = TypeObjectUtils::build_complete_type_detail( - type_ann_builtin_CalculatorOperationType, ann_custom_CalculatorOperationType, - type_name_CalculatorOperationType.to_string()); - CompleteEnumeratedHeader header_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_header( - common_CalculatorOperationType, detail_CalculatorOperationType); + CompleteTypeDetail detail_CalculatorOperationType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorOperationType, ann_custom_CalculatorOperationType, type_name_CalculatorOperationType.to_string()); + CompleteEnumeratedHeader header_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_header(common_CalculatorOperationType, detail_CalculatorOperationType); CompleteEnumeratedLiteralSeq literal_seq_CalculatorOperationType; { EnumeratedLiteralFlag flags_ADDITION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_ADDITION = - TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); + CommonEnumeratedLiteral common_ADDITION = TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); eprosima::fastcdr::optional member_ann_builtin_ADDITION; ann_custom_CalculatorOperationType.reset(); MemberName name_ADDITION = "ADDITION"; - CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, - member_ann_builtin_ADDITION, - ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal( - common_ADDITION, detail_ADDITION); + CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, member_ann_builtin_ADDITION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal(common_ADDITION, detail_ADDITION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_ADDITION); } { EnumeratedLiteralFlag flags_SUBTRACTION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, - flags_SUBTRACTION); + CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, flags_SUBTRACTION); eprosima::fastcdr::optional member_ann_builtin_SUBTRACTION; ann_custom_CalculatorOperationType.reset(); MemberName name_SUBTRACTION = "SUBTRACTION"; - CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, - member_ann_builtin_SUBTRACTION, - ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal( - common_SUBTRACTION, detail_SUBTRACTION); + CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, member_ann_builtin_SUBTRACTION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal(common_SUBTRACTION, detail_SUBTRACTION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_SUBTRACTION); } { EnumeratedLiteralFlag flags_MULTIPLICATION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, - flags_MULTIPLICATION); + CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, flags_MULTIPLICATION); eprosima::fastcdr::optional member_ann_builtin_MULTIPLICATION; ann_custom_CalculatorOperationType.reset(); MemberName name_MULTIPLICATION = "MULTIPLICATION"; - CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail( - name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal( - common_MULTIPLICATION, detail_MULTIPLICATION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, - literal_MULTIPLICATION); + CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail(name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal(common_MULTIPLICATION, detail_MULTIPLICATION); + TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_MULTIPLICATION); } { EnumeratedLiteralFlag flags_DIVISION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_DIVISION = - TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); + CommonEnumeratedLiteral common_DIVISION = TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); eprosima::fastcdr::optional member_ann_builtin_DIVISION; ann_custom_CalculatorOperationType.reset(); MemberName name_DIVISION = "DIVISION"; - CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, - member_ann_builtin_DIVISION, - ann_custom_CalculatorOperationType); - CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal( - common_DIVISION, detail_DIVISION); + CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, member_ann_builtin_DIVISION, ann_custom_CalculatorOperationType); + CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal(common_DIVISION, detail_DIVISION); TypeObjectUtils::add_complete_enumerated_literal(literal_seq_CalculatorOperationType, literal_DIVISION); } - CompleteEnumeratedType enumerated_type_CalculatorOperationType = - TypeObjectUtils::build_complete_enumerated_type(enum_flags_CalculatorOperationType, - header_CalculatorOperationType, - literal_seq_CalculatorOperationType); + CompleteEnumeratedType enumerated_type_CalculatorOperationType = TypeObjectUtils::build_complete_enumerated_type(enum_flags_CalculatorOperationType, header_CalculatorOperationType, + literal_seq_CalculatorOperationType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_CalculatorOperationType, - type_name_CalculatorOperationType.to_string(), type_ids_CalculatorOperationType)) + TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_CalculatorOperationType, type_name_CalculatorOperationType.to_string(), type_ids_CalculatorOperationType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "CalculatorOperationType already registered in TypeObjectRegistry for a different type."); + "CalculatorOperationType already registered in TypeObjectRegistry for a different type."); } } }// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_ClientID_type_identifier( + TypeIdentifierPair& type_ids_ClientID) +{ + + ReturnCode_t return_code_ClientID {eprosima::fastdds::dds::RETCODE_OK}; + return_code_ClientID = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "ClientID", type_ids_ClientID); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_ClientID) + { + StructTypeFlag struct_flags_ClientID = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_ClientID = "ClientID"; + eprosima::fastcdr::optional type_ann_builtin_ClientID; + eprosima::fastcdr::optional ann_custom_ClientID; + AppliedAnnotationSeq tmp_ann_custom_ClientID; + eprosima::fastcdr::optional verbatim_ClientID; + if (!tmp_ann_custom_ClientID.empty()) + { + ann_custom_ClientID = tmp_ann_custom_ClientID; + } + + CompleteTypeDetail detail_ClientID = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ClientID, ann_custom_ClientID, type_name_ClientID.to_string()); + CompleteStructHeader header_ClientID; + header_ClientID = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ClientID); + CompleteStructMemberSeq member_seq_ClientID; + { + TypeIdentifierPair type_ids_value; + ReturnCode_t return_code_value {eprosima::fastdds::dds::RETCODE_OK}; + return_code_value = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_array_uint8_t_12", type_ids_value); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_value) + { + return_code_value = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_byte", type_ids_value); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_value) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "Array element TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + bool element_identifier_anonymous_array_uint8_t_12_ec {false}; + TypeIdentifier* element_identifier_anonymous_array_uint8_t_12 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_value, element_identifier_anonymous_array_uint8_t_12_ec))}; + if (!element_identifier_anonymous_array_uint8_t_12_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Array element TypeIdentifier inconsistent."); + return; + } + EquivalenceKind equiv_kind_anonymous_array_uint8_t_12 = EK_COMPLETE; + if (TK_NONE == type_ids_value.type_identifier2()._d()) + { + equiv_kind_anonymous_array_uint8_t_12 = EK_BOTH; + } + CollectionElementFlag element_flags_anonymous_array_uint8_t_12 = 0; + PlainCollectionHeader header_anonymous_array_uint8_t_12 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_array_uint8_t_12, element_flags_anonymous_array_uint8_t_12); + { + SBoundSeq array_bound_seq; + TypeObjectUtils::add_array_dimension(array_bound_seq, static_cast(12)); + + PlainArraySElemDefn array_sdefn = TypeObjectUtils::build_plain_array_s_elem_defn(header_anonymous_array_uint8_t_12, array_bound_seq, + eprosima::fastcdr::external(element_identifier_anonymous_array_uint8_t_12)); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_array_type_identifier(array_sdefn, "anonymous_array_uint8_t_12", type_ids_value)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_array_uint8_t_12 already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_value = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_value = 0x00000000; + bool common_value_ec {false}; + CommonStructMember common_value {TypeObjectUtils::build_common_struct_member(member_id_value, member_flags_value, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_value, common_value_ec))}; + if (!common_value_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure value member TypeIdentifier inconsistent."); + return; + } + MemberName name_value = "value"; + eprosima::fastcdr::optional member_ann_builtin_value; + ann_custom_ClientID.reset(); + CompleteMemberDetail detail_value = TypeObjectUtils::build_complete_member_detail(name_value, member_ann_builtin_value, ann_custom_ClientID); + CompleteStructMember member_value = TypeObjectUtils::build_complete_struct_member(common_value, detail_value); + TypeObjectUtils::add_complete_struct_member(member_seq_ClientID, member_value); + } + CompleteStructType struct_type_ClientID = TypeObjectUtils::build_complete_struct_type(struct_flags_ClientID, header_ClientID, member_seq_ClientID); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_ClientID, type_name_ClientID.to_string(), type_ids_ClientID)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "ClientID already registered in TypeObjectRegistry for a different type."); + } + } +} +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method void register_CalculatorRequestType_type_identifier( TypeIdentifierPair& type_ids_CalculatorRequestType) { ReturnCode_t return_code_CalculatorRequestType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorRequestType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "CalculatorRequestType", type_ids_CalculatorRequestType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorRequestType) { - StructTypeFlag struct_flags_CalculatorRequestType = TypeObjectUtils::build_struct_type_flag( - eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); + StructTypeFlag struct_flags_CalculatorRequestType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); QualifiedTypeName type_name_CalculatorRequestType = "CalculatorRequestType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorRequestType; eprosima::fastcdr::optional ann_custom_CalculatorRequestType; @@ -162,56 +235,84 @@ void register_CalculatorRequestType_type_identifier( ann_custom_CalculatorRequestType = tmp_ann_custom_CalculatorRequestType; } - CompleteTypeDetail detail_CalculatorRequestType = TypeObjectUtils::build_complete_type_detail( - type_ann_builtin_CalculatorRequestType, ann_custom_CalculatorRequestType, - type_name_CalculatorRequestType.to_string()); + CompleteTypeDetail detail_CalculatorRequestType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorRequestType, ann_custom_CalculatorRequestType, type_name_CalculatorRequestType.to_string()); CompleteStructHeader header_CalculatorRequestType; - header_CalculatorRequestType = TypeObjectUtils::build_complete_struct_header( - TypeIdentifier(), detail_CalculatorRequestType); + header_CalculatorRequestType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorRequestType); CompleteStructMemberSeq member_seq_CalculatorRequestType; + { + TypeIdentifierPair type_ids_client_id; + ReturnCode_t return_code_client_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_client_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "ClientID", type_ids_client_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_client_id) + { + ::register_ClientID_type_identifier(type_ids_client_id); + } + StructMemberFlag member_flags_client_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, true, false); + MemberId member_id_client_id = 0x00000000; + bool common_client_id_ec {false}; + CommonStructMember common_client_id {TypeObjectUtils::build_common_struct_member(member_id_client_id, member_flags_client_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_client_id, common_client_id_ec))}; + if (!common_client_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure client_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_client_id = "client_id"; + eprosima::fastcdr::optional member_ann_builtin_client_id; + ann_custom_CalculatorRequestType.reset(); + AppliedAnnotationSeq tmp_ann_custom_client_id; + eprosima::fastcdr::optional unit_client_id; + eprosima::fastcdr::optional min_client_id; + eprosima::fastcdr::optional max_client_id; + eprosima::fastcdr::optional hash_id_client_id; + if (unit_client_id.has_value() || min_client_id.has_value() || max_client_id.has_value() || hash_id_client_id.has_value()) + { + member_ann_builtin_client_id = TypeObjectUtils::build_applied_builtin_member_annotations(unit_client_id, min_client_id, max_client_id, hash_id_client_id); + } + if (!tmp_ann_custom_client_id.empty()) + { + ann_custom_CalculatorRequestType = tmp_ann_custom_client_id; + } + CompleteMemberDetail detail_client_id = TypeObjectUtils::build_complete_member_detail(name_client_id, member_ann_builtin_client_id, ann_custom_CalculatorRequestType); + CompleteStructMember member_client_id = TypeObjectUtils::build_complete_struct_member(common_client_id, detail_client_id); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_client_id); + } { TypeIdentifierPair type_ids_operation; ReturnCode_t return_code_operation {eprosima::fastdds::dds::RETCODE_OK}; return_code_operation = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "CalculatorOperationType", type_ids_operation); if (eprosima::fastdds::dds::RETCODE_OK != return_code_operation) { - ::register_CalculatorOperationType_type_identifier(type_ids_operation); + ::register_CalculatorOperationType_type_identifier(type_ids_operation); } - StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag( - eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_operation = 0x00000000; + StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_operation = 0x00000001; bool common_operation_ec {false}; - CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, - member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier( - type_ids_operation, - common_operation_ec))}; + CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_operation, common_operation_ec))}; if (!common_operation_ec) { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "Structure operation member TypeIdentifier inconsistent."); + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure operation member TypeIdentifier inconsistent."); return; } MemberName name_operation = "operation"; eprosima::fastcdr::optional member_ann_builtin_operation; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, - member_ann_builtin_operation, - ann_custom_CalculatorRequestType); - CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, - detail_operation); + CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, member_ann_builtin_operation, ann_custom_CalculatorRequestType); + CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, detail_operation); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_operation); } { TypeIdentifierPair type_ids_x; ReturnCode_t return_code_x {eprosima::fastdds::dds::RETCODE_OK}; return_code_x = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "_int16_t", type_ids_x); if (eprosima::fastdds::dds::RETCODE_OK != return_code_x) @@ -220,14 +321,11 @@ void register_CalculatorRequestType_type_identifier( "x Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag( - eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_x = 0x00000001; + StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_x = 0x00000002; bool common_x_ec {false}; - CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier( - type_ids_x, - common_x_ec))}; + CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_x, common_x_ec))}; if (!common_x_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure x member TypeIdentifier inconsistent."); @@ -236,8 +334,7 @@ void register_CalculatorRequestType_type_identifier( MemberName name_x = "x"; eprosima::fastcdr::optional member_ann_builtin_x; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, - ann_custom_CalculatorRequestType); + CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, ann_custom_CalculatorRequestType); CompleteStructMember member_x = TypeObjectUtils::build_complete_struct_member(common_x, detail_x); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_x); } @@ -245,8 +342,7 @@ void register_CalculatorRequestType_type_identifier( TypeIdentifierPair type_ids_y; ReturnCode_t return_code_y {eprosima::fastdds::dds::RETCODE_OK}; return_code_y = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "_int16_t", type_ids_y); if (eprosima::fastdds::dds::RETCODE_OK != return_code_y) @@ -255,14 +351,11 @@ void register_CalculatorRequestType_type_identifier( "y Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag( - eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_y = 0x00000002; + StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_y = 0x00000003; bool common_y_ec {false}; - CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier( - type_ids_y, - common_y_ec))}; + CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_y, common_y_ec))}; if (!common_y_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure y member TypeIdentifier inconsistent."); @@ -271,23 +364,19 @@ void register_CalculatorRequestType_type_identifier( MemberName name_y = "y"; eprosima::fastcdr::optional member_ann_builtin_y; ann_custom_CalculatorRequestType.reset(); - CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, - ann_custom_CalculatorRequestType); + CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, ann_custom_CalculatorRequestType); CompleteStructMember member_y = TypeObjectUtils::build_complete_struct_member(common_y, detail_y); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorRequestType, member_y); } - CompleteStructType struct_type_CalculatorRequestType = TypeObjectUtils::build_complete_struct_type( - struct_flags_CalculatorRequestType, header_CalculatorRequestType, member_seq_CalculatorRequestType); + CompleteStructType struct_type_CalculatorRequestType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorRequestType, header_CalculatorRequestType, member_seq_CalculatorRequestType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorRequestType, - type_name_CalculatorRequestType.to_string(), type_ids_CalculatorRequestType)) + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorRequestType, type_name_CalculatorRequestType.to_string(), type_ids_CalculatorRequestType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "CalculatorRequestType already registered in TypeObjectRegistry for a different type."); } } } - // TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method void register_CalculatorReplyType_type_identifier( TypeIdentifierPair& type_ids_CalculatorReplyType) @@ -295,14 +384,12 @@ void register_CalculatorReplyType_type_identifier( ReturnCode_t return_code_CalculatorReplyType {eprosima::fastdds::dds::RETCODE_OK}; return_code_CalculatorReplyType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "CalculatorReplyType", type_ids_CalculatorReplyType); if (eprosima::fastdds::dds::RETCODE_OK != return_code_CalculatorReplyType) { - StructTypeFlag struct_flags_CalculatorReplyType = TypeObjectUtils::build_struct_type_flag( - eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); + StructTypeFlag struct_flags_CalculatorReplyType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); QualifiedTypeName type_name_CalculatorReplyType = "CalculatorReplyType"; eprosima::fastcdr::optional type_ann_builtin_CalculatorReplyType; eprosima::fastcdr::optional ann_custom_CalculatorReplyType; @@ -313,19 +400,56 @@ void register_CalculatorReplyType_type_identifier( ann_custom_CalculatorReplyType = tmp_ann_custom_CalculatorReplyType; } - CompleteTypeDetail detail_CalculatorReplyType = TypeObjectUtils::build_complete_type_detail( - type_ann_builtin_CalculatorReplyType, ann_custom_CalculatorReplyType, - type_name_CalculatorReplyType.to_string()); + CompleteTypeDetail detail_CalculatorReplyType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_CalculatorReplyType, ann_custom_CalculatorReplyType, type_name_CalculatorReplyType.to_string()); CompleteStructHeader header_CalculatorReplyType; - header_CalculatorReplyType = TypeObjectUtils::build_complete_struct_header( - TypeIdentifier(), detail_CalculatorReplyType); + header_CalculatorReplyType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_CalculatorReplyType); CompleteStructMemberSeq member_seq_CalculatorReplyType; + { + TypeIdentifierPair type_ids_client_id; + ReturnCode_t return_code_client_id {eprosima::fastdds::dds::RETCODE_OK}; + return_code_client_id = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "ClientID", type_ids_client_id); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_client_id) + { + ::register_ClientID_type_identifier(type_ids_client_id); + } + StructMemberFlag member_flags_client_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, true, false); + MemberId member_id_client_id = 0x00000000; + bool common_client_id_ec {false}; + CommonStructMember common_client_id {TypeObjectUtils::build_common_struct_member(member_id_client_id, member_flags_client_id, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_client_id, common_client_id_ec))}; + if (!common_client_id_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure client_id member TypeIdentifier inconsistent."); + return; + } + MemberName name_client_id = "client_id"; + eprosima::fastcdr::optional member_ann_builtin_client_id; + ann_custom_CalculatorReplyType.reset(); + AppliedAnnotationSeq tmp_ann_custom_client_id; + eprosima::fastcdr::optional unit_client_id; + eprosima::fastcdr::optional min_client_id; + eprosima::fastcdr::optional max_client_id; + eprosima::fastcdr::optional hash_id_client_id; + if (unit_client_id.has_value() || min_client_id.has_value() || max_client_id.has_value() || hash_id_client_id.has_value()) + { + member_ann_builtin_client_id = TypeObjectUtils::build_applied_builtin_member_annotations(unit_client_id, min_client_id, max_client_id, hash_id_client_id); + } + if (!tmp_ann_custom_client_id.empty()) + { + ann_custom_CalculatorReplyType = tmp_ann_custom_client_id; + } + CompleteMemberDetail detail_client_id = TypeObjectUtils::build_complete_member_detail(name_client_id, member_ann_builtin_client_id, ann_custom_CalculatorReplyType); + CompleteStructMember member_client_id = TypeObjectUtils::build_complete_struct_member(common_client_id, detail_client_id); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_client_id); + } { TypeIdentifierPair type_ids_z; ReturnCode_t return_code_z {eprosima::fastdds::dds::RETCODE_OK}; return_code_z = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry(). - get_type_identifiers( + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( "_int32_t", type_ids_z); if (eprosima::fastdds::dds::RETCODE_OK != return_code_z) @@ -334,14 +458,11 @@ void register_CalculatorReplyType_type_identifier( "z Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag( - eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_z = 0x00000000; + StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_z = 0x00000001; bool common_z_ec {false}; - CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier( - type_ids_z, - common_z_ec))}; + CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_z, common_z_ec))}; if (!common_z_ec) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure z member TypeIdentifier inconsistent."); @@ -350,19 +471,17 @@ void register_CalculatorReplyType_type_identifier( MemberName name_z = "z"; eprosima::fastcdr::optional member_ann_builtin_z; ann_custom_CalculatorReplyType.reset(); - CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, - ann_custom_CalculatorReplyType); + CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, ann_custom_CalculatorReplyType); CompleteStructMember member_z = TypeObjectUtils::build_complete_struct_member(common_z, detail_z); TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_z); } - CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type( - struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); + CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorReplyType, - type_name_CalculatorReplyType.to_string(), type_ids_CalculatorReplyType)) + TypeObjectUtils::build_and_register_struct_type_object(struct_type_CalculatorReplyType, type_name_CalculatorReplyType.to_string(), type_ids_CalculatorReplyType)) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "CalculatorReplyType already registered in TypeObjectRegistry for a different type."); } } } + diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp b/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp index 1fb9bccf445..5ca967afb91 100644 --- a/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp @@ -49,6 +49,18 @@ */ eProsima_user_DllExport void register_CalculatorOperationType_type_identifier( eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); +/** + * @brief Register ClientID related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_ClientID_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); /** * @brief Register CalculatorRequestType related TypeIdentifier. * Fully-descriptive TypeIdentifiers are directly registered. diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 6afd88d6a78..c4ff332d114 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -76,6 +76,14 @@ ClientApp::ClientApp( ClientApp::~ClientApp() { + if (nullptr != participant_) + { + // Delete DDS entities contained within the DomainParticipant + participant_->delete_contained_entities(); + + // Delete DomainParticipant + DomainParticipantFactory::get_shared_instance()->delete_participant(participant_); + } } void ClientApp::run() @@ -85,6 +93,11 @@ void ClientApp::run() { return server_matched_status_.is_any_server_matched(); }); + + if (!send_request()) + { + throw std::runtime_error("Failed to send request"); + } } void ClientApp::stop() @@ -154,7 +167,7 @@ void ClientApp::on_data_available( void ClientApp::create_participant() { // Create the participant - auto factory = DomainParticipantFactory::get_instance(); + auto factory = DomainParticipantFactory::get_shared_instance(); if (nullptr == factory) { @@ -259,6 +272,20 @@ void ClientApp::create_reply_entities( } } +bool ClientApp::send_request() +{ + CalculatorRequestType request; + + request.client_id(TypeConverter::to_calculator_type(participant_->guid().guidPrefix)); + request.operation(TypeConverter::to_calculator_type(request_input_.operation)); + request.x(request_input_.x); + request.y(request_input_.y); + + std::cout << "Sending request" << std::endl; + + return request_writer_->write(&request); +} + /******* HELPER FUNCTIONS DEFINITIONS *******/ namespace detail { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 1e38126240f..17a2fe95b6a 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -91,6 +91,8 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit void create_reply_entities( const std::string& service_name); + bool send_request(); + RequestInput request_input_; DomainParticipant* participant_; @@ -116,7 +118,6 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit std::condition_variable cv_; RemoteServerMatchedStatus server_matched_status_; - }; template<> diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 2d75129fa6d..527b86fa65f 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "Calculator.hpp" #include "CalculatorPubSubTypes.hpp" @@ -71,6 +73,22 @@ ServerApp::ServerApp( ServerApp::~ServerApp() { + if (nullptr != participant_) + { + // Delete DDS entities contained within the DomainParticipant + participant_->delete_contained_entities(); + + // Delete DomainParticipant + DomainParticipantFactory::get_instance()->delete_participant(participant_); + } + + // Cleanup the pending requests + while (requests_.size() > 0) + { + requests_.pop(); + } + + client_matched_status_.clear(); } void ServerApp::run() @@ -89,24 +107,48 @@ void ServerApp::stop() } void ServerApp::on_publication_matched( - DataWriter* writer, + DataWriter* /* writer */, const PublicationMatchedStatus& info) { - static_cast(writer); - static_cast(info); + std::lock_guard lock(mtx_); + + rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.last_subscription_handle).guidPrefix; + + if (info.current_count_change == 1) + { + std::cout << "Remote reply reader matched." << std::endl; + client_matched_status_.match_reply_reader(client_guid_prefix, true); + } + else if (info.current_count_change == -1) + { + std::cout << "Remote reply reader unmatched." << std::endl; + client_matched_status_.match_reply_reader(client_guid_prefix, false); + } + else + { + std::cout << info.current_count_change + << " is not a valid value for PublicationMatchedStatus current count change" << std::endl; + } } void ServerApp::on_subscription_matched( DataReader* /* reader */, const SubscriptionMatchedStatus& info) { + std::lock_guard lock(mtx_); + + rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.last_publication_handle).guidPrefix; + if (info.current_count_change == 1) { std::cout << "Remote request writer matched." << std::endl; + client_matched_status_.match_request_writer(client_guid_prefix, true); + } else if (info.current_count_change == -1) { std::cout << "Remote request writer unmatched." << std::endl; + client_matched_status_.match_request_writer(client_guid_prefix, false); } else { @@ -118,7 +160,27 @@ void ServerApp::on_subscription_matched( void ServerApp::on_data_available( DataReader* reader) { - static_cast(reader); + bool new_request = false; + + std::lock_guard lock(mtx_); + + SampleInfo info; + auto request = std::make_shared(); + + while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(request.get(), &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) + { + std::cout << "Request received from client!" << std::endl; + requests_.push({info, request}); + new_request = true; + } + } + + if (new_request) + { + cv_.notify_one(); + } } void ServerApp::create_participant() diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index e941f70502f..b1401daab39 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include #include @@ -31,10 +33,12 @@ #include #include #include +#include #include #include #include +#include "app_utils.hpp" #include "Application.hpp" #include "CalculatorPubSubTypes.hpp" @@ -114,6 +118,17 @@ class ServerApp : public Application, public DataWriterListener, public DataRead std::condition_variable cv_; std::atomic stop_; + + RemoteClientMatchedStatus client_matched_status_; + + struct Request + { + SampleInfo info; + std::shared_ptr request; + }; + + std::queue requests_; + }; template<> diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index 87447f4a312..b47d0973e7f 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -20,6 +20,7 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APP_UTILS_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__APP_UTILS_HPP +#include #include #include #include @@ -28,6 +29,7 @@ #include +#include "Calculator.hpp" #include "CLIParser.hpp" namespace eprosima { @@ -73,7 +75,16 @@ class RemoteServerMatchedStatus bool is_matched( const rtps::GuidPrefix_t& guid_prefix) { - return matched_status_[guid_prefix].all(); + bool is_server_matched = false; + + auto status = matched_status_.find(guid_prefix); + + if (status != matched_status_.end()) + { + is_server_matched = status->second.all(); + } + + return is_server_matched; } bool is_any_server_matched() @@ -90,6 +101,11 @@ class RemoteServerMatchedStatus return any_server_matched; } + void clear() + { + matched_status_.clear(); + } + private: std::map> matched_status_; @@ -120,7 +136,21 @@ class RemoteClientMatchedStatus bool is_matched( const rtps::GuidPrefix_t& guid_prefix) { - return matched_status_[guid_prefix].all(); + bool is_client_matched = false; + + auto status = matched_status_.find(guid_prefix); + + if (status != matched_status_.end()) + { + is_client_matched = status->second.all(); + } + + return is_client_matched; + } + + void clear() + { + matched_status_.clear(); } private: @@ -132,6 +162,46 @@ class RemoteClientMatchedStatus static const size_t reply_reader_position = 1; }; +struct TypeConverter +{ + static CalculatorOperationType to_calculator_type( + const CLIParser::Operation& operation) + { + CalculatorOperationType calculator_operation; + + switch (operation) + { + case CLIParser::Operation::ADDITION: + calculator_operation = CalculatorOperationType::ADDITION; + break; + case CLIParser::Operation::SUBTRACTION: + calculator_operation = CalculatorOperationType::SUBTRACTION; + break; + case CLIParser::Operation::MULTIPLICATION: + calculator_operation = CalculatorOperationType::MULTIPLICATION; + break; + case CLIParser::Operation::DIVISION: + calculator_operation = CalculatorOperationType::DIVISION; + break; + default: + throw std::invalid_argument("Invalid operation"); + break; + } + + return calculator_operation; + } + + static ClientID to_calculator_type( + const rtps::GuidPrefix_t& guid_prefix) + { + ClientID client_id; + std::copy(std::begin(guid_prefix.value), std::end(guid_prefix.value), std::begin(client_id.value())); + + return client_id; + } + +}; + } // namespace request_reply } // namespace examples } // namespace fastdds From d4b30f3e84281de0f7c6e104481185294abf52fe Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 09:36:33 +0200 Subject: [PATCH 14/46] Refs #21188: Rename reply z to result Signed-off-by: eduponz --- examples/cpp/request_reply/Calculator.hpp | 38 +++++++++---------- examples/cpp/request_reply/Calculator.idl | 2 +- .../cpp/request_reply/CalculatorCdrAux.ipp | 6 +-- .../CalculatorTypeObjectSupport.cxx | 34 ++++++++--------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/examples/cpp/request_reply/Calculator.hpp b/examples/cpp/request_reply/Calculator.hpp index 19550d56dd2..f2f2aa286a4 100644 --- a/examples/cpp/request_reply/Calculator.hpp +++ b/examples/cpp/request_reply/Calculator.hpp @@ -469,7 +469,7 @@ class CalculatorReplyType { m_client_id = x.m_client_id; - m_z = x.m_z; + m_result = x.m_result; } @@ -481,7 +481,7 @@ class CalculatorReplyType CalculatorReplyType&& x) noexcept { m_client_id = std::move(x.m_client_id); - m_z = x.m_z; + m_result = x.m_result; } /*! @@ -494,7 +494,7 @@ class CalculatorReplyType m_client_id = x.m_client_id; - m_z = x.m_z; + m_result = x.m_result; return *this; } @@ -508,7 +508,7 @@ class CalculatorReplyType { m_client_id = std::move(x.m_client_id); - m_z = x.m_z; + m_result = x.m_result; return *this; } @@ -520,7 +520,7 @@ class CalculatorReplyType const CalculatorReplyType& x) const { return (m_client_id == x.m_client_id && - m_z == x.m_z); + m_result == x.m_result); } /*! @@ -573,31 +573,31 @@ class CalculatorReplyType /*! - * @brief This function sets a value in member z - * @param _z New value for member z + * @brief This function sets a value in member result + * @param _result New value for member result */ - eProsima_user_DllExport void z( - int32_t _z) + eProsima_user_DllExport void result( + int32_t _result) { - m_z = _z; + m_result = _result; } /*! - * @brief This function returns the value of member z - * @return Value of member z + * @brief This function returns the value of member result + * @return Value of member result */ - eProsima_user_DllExport int32_t z() const + eProsima_user_DllExport int32_t result() const { - return m_z; + return m_result; } /*! - * @brief This function returns a reference to member z - * @return Reference to member z + * @brief This function returns a reference to member result + * @return Reference to member result */ - eProsima_user_DllExport int32_t& z() + eProsima_user_DllExport int32_t& result() { - return m_z; + return m_result; } @@ -605,7 +605,7 @@ class CalculatorReplyType private: ClientID m_client_id; - int32_t m_z{0}; + int32_t m_result{0}; }; diff --git a/examples/cpp/request_reply/Calculator.idl b/examples/cpp/request_reply/Calculator.idl index f245d32f0ec..3ee9dd377d1 100644 --- a/examples/cpp/request_reply/Calculator.idl +++ b/examples/cpp/request_reply/Calculator.idl @@ -26,5 +26,5 @@ struct CalculatorRequestType struct CalculatorReplyType { @key ClientID client_id; - long z; + long result; }; diff --git a/examples/cpp/request_reply/CalculatorCdrAux.ipp b/examples/cpp/request_reply/CalculatorCdrAux.ipp index 6f8974e51b0..ef2d0f63d9d 100644 --- a/examples/cpp/request_reply/CalculatorCdrAux.ipp +++ b/examples/cpp/request_reply/CalculatorCdrAux.ipp @@ -235,7 +235,7 @@ eProsima_user_DllExport size_t calculate_serialized_size( data.client_id(), current_alignment); calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), - data.z(), current_alignment); + data.result(), current_alignment); calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); @@ -256,7 +256,7 @@ eProsima_user_DllExport void serialize( scdr << eprosima::fastcdr::MemberId(0) << data.client_id() - << eprosima::fastcdr::MemberId(1) << data.z() + << eprosima::fastcdr::MemberId(1) << data.result() ; scdr.end_serialize_type(current_state); } @@ -279,7 +279,7 @@ eProsima_user_DllExport void deserialize( break; case 1: - dcdr >> data.z(); + dcdr >> data.result(); break; default: diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx index 24f48388d96..9ab9f99fa45 100644 --- a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx +++ b/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx @@ -446,34 +446,34 @@ void register_CalculatorReplyType_type_identifier( TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_client_id); } { - TypeIdentifierPair type_ids_z; - ReturnCode_t return_code_z {eprosima::fastdds::dds::RETCODE_OK}; - return_code_z = + TypeIdentifierPair type_ids_result; + ReturnCode_t return_code_result {eprosima::fastdds::dds::RETCODE_OK}; + return_code_result = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_int32_t", type_ids_z); + "_int32_t", type_ids_result); - if (eprosima::fastdds::dds::RETCODE_OK != return_code_z) + if (eprosima::fastdds::dds::RETCODE_OK != return_code_result) { EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "z Structure member TypeIdentifier unknown to TypeObjectRegistry."); + "result Structure member TypeIdentifier unknown to TypeObjectRegistry."); return; } - StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + StructMemberFlag member_flags_result = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, false, false, false, false); - MemberId member_id_z = 0x00000001; - bool common_z_ec {false}; - CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_z, common_z_ec))}; - if (!common_z_ec) + MemberId member_id_result = 0x00000001; + bool common_result_ec {false}; + CommonStructMember common_result {TypeObjectUtils::build_common_struct_member(member_id_result, member_flags_result, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_result, common_result_ec))}; + if (!common_result_ec) { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure z member TypeIdentifier inconsistent."); + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure result member TypeIdentifier inconsistent."); return; } - MemberName name_z = "z"; - eprosima::fastcdr::optional member_ann_builtin_z; + MemberName name_result = "result"; + eprosima::fastcdr::optional member_ann_builtin_result; ann_custom_CalculatorReplyType.reset(); - CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, ann_custom_CalculatorReplyType); - CompleteStructMember member_z = TypeObjectUtils::build_complete_struct_member(common_z, detail_z); - TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_z); + CompleteMemberDetail detail_result = TypeObjectUtils::build_complete_member_detail(name_result, member_ann_builtin_result, ann_custom_CalculatorReplyType); + CompleteStructMember member_result = TypeObjectUtils::build_complete_struct_member(common_result, detail_result); + TypeObjectUtils::add_complete_struct_member(member_seq_CalculatorReplyType, member_result); } CompleteStructType struct_type_CalculatorReplyType = TypeObjectUtils::build_complete_struct_type(struct_flags_CalculatorReplyType, header_CalculatorReplyType, member_seq_CalculatorReplyType); if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == From a4bf006c7ce9b6fba350ae169e7c923bd8e2c05e Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 09:41:33 +0200 Subject: [PATCH 15/46] Refs #21188: Server sends reply and client waits for it Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 54 +++++- examples/cpp/request_reply/ClientApp.hpp | 7 + examples/cpp/request_reply/ServerApp.cpp | 169 +++++++++++++++++-- examples/cpp/request_reply/ServerApp.hpp | 10 ++ examples/cpp/request_reply/app_utils.hpp | 15 ++ examples/cpp/request_reply/request_reply.xml | 54 ++++++ 6 files changed, 284 insertions(+), 25 deletions(-) create mode 100644 examples/cpp/request_reply/request_reply.xml diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index c4ff332d114..df292a7e188 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -19,6 +19,7 @@ #include "ClientApp.hpp" +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -68,10 +70,13 @@ ClientApp::ClientApp( , reply_topic_(nullptr) , subscriber_(nullptr) , reply_reader_(nullptr) + , stop_(false) { create_participant(); create_request_entities(service_name); create_reply_entities(service_name); + + std::cout << "Client initialized with ID: " << participant_->guid().guidPrefix << std::endl; } ClientApp::~ClientApp() @@ -88,20 +93,26 @@ ClientApp::~ClientApp() void ClientApp::run() { - std::unique_lock lock(mtx_); - cv_.wait(lock, [&]() - { - return server_matched_status_.is_any_server_matched(); - }); + { + std::unique_lock lock(mtx_); + cv_.wait(lock, [&]() + { + return server_matched_status_.is_any_server_matched(); + }); + } if (!send_request()) { throw std::runtime_error("Failed to send request"); } + + wait_for_reply(); } void ClientApp::stop() { + stop_.store(true); + cv_.notify_all(); } void ClientApp::on_publication_matched( @@ -128,7 +139,7 @@ void ClientApp::on_publication_matched( std::cout << info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; } - cv_.notify_one(); + cv_.notify_all(); } void ClientApp::on_subscription_matched( @@ -155,13 +166,26 @@ void ClientApp::on_subscription_matched( std::cout << info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; } - cv_.notify_one(); + cv_.notify_all(); } void ClientApp::on_data_available( DataReader* reader) { - static_cast(reader); + SampleInfo info; + CalculatorReplyType reply; + + while ((!is_stopped()) && (RETCODE_OK == reader->take_next_sample(&reply, &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) + { + rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; + std::cout << "Reply received from server " << server_guid_prefix + << " with result: " << reply.result() << std::endl; + stop(); + break; + } + } } void ClientApp::create_participant() @@ -286,6 +310,20 @@ bool ClientApp::send_request() return request_writer_->write(&request); } +bool ClientApp::is_stopped() +{ + return stop_.load(); +} + +void ClientApp::wait_for_reply() +{ + std::unique_lock lock(mtx_); + cv_.wait(lock, [&]() + { + return is_stopped(); + }); +} + /******* HELPER FUNCTIONS DEFINITIONS *******/ namespace detail { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 17a2fe95b6a..a7992a8a340 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -20,6 +20,7 @@ #ifndef FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP #define FASTDDS_EXAMPLES_CPP_REQUEST_REPLY__CLIENTAPP_HPP +#include #include #include #include @@ -93,6 +94,10 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit bool send_request(); + bool is_stopped(); + + void wait_for_reply(); + RequestInput request_input_; DomainParticipant* participant_; @@ -118,6 +123,8 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit std::condition_variable cv_; RemoteServerMatchedStatus server_matched_status_; + + std::atomic stop_; }; template<> diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 527b86fa65f..0834bd58dbc 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -19,13 +19,18 @@ #include "ServerApp.hpp" +#include #include +#include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -33,6 +38,7 @@ #include #include #include +#include #include "Calculator.hpp" #include "CalculatorPubSubTypes.hpp" @@ -65,14 +71,27 @@ ServerApp::ServerApp( , reply_topic_(nullptr) , publisher_(nullptr) , reply_writer_(nullptr) + , stop_(false) { + // Spawn the reply thread + reply_thread_ = std::thread(&ServerApp::reply_routine, this); + + // Create the DDS entities create_participant(); create_request_entities(service_name); create_reply_entities(service_name); + + std::cout << "Server initialized with ID: " << participant_->guid().guidPrefix << std::endl; } ServerApp::~ServerApp() { + // Join reply thread + if (reply_thread_.joinable()) + { + reply_thread_.join(); + } + if (nullptr != participant_) { // Delete DDS entities contained within the DomainParticipant @@ -103,7 +122,7 @@ void ServerApp::run() void ServerApp::stop() { stop_.store(true); - cv_.notify_one(); + cv_.notify_all(); } void ServerApp::on_publication_matched( @@ -116,12 +135,12 @@ void ServerApp::on_publication_matched( if (info.current_count_change == 1) { - std::cout << "Remote reply reader matched." << std::endl; + std::cout << "Remote reply reader matched with client " << client_guid_prefix << std::endl; client_matched_status_.match_reply_reader(client_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote reply reader unmatched." << std::endl; + std::cout << "Remote reply reader unmatched from client " << client_guid_prefix << std::endl; client_matched_status_.match_reply_reader(client_guid_prefix, false); } else @@ -141,13 +160,13 @@ void ServerApp::on_subscription_matched( if (info.current_count_change == 1) { - std::cout << "Remote request writer matched." << std::endl; + std::cout << "Remote request writer matched with client " << client_guid_prefix << std::endl; client_matched_status_.match_request_writer(client_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote request writer unmatched." << std::endl; + std::cout << "Remote request writer unmatched from client " << client_guid_prefix << std::endl; client_matched_status_.match_request_writer(client_guid_prefix, false); } else @@ -160,10 +179,6 @@ void ServerApp::on_subscription_matched( void ServerApp::on_data_available( DataReader* reader) { - bool new_request = false; - - std::lock_guard lock(mtx_); - SampleInfo info; auto request = std::make_shared(); @@ -171,15 +186,17 @@ void ServerApp::on_data_available( { if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { - std::cout << "Request received from client!" << std::endl; - requests_.push({info, request}); - new_request = true; - } - } + rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; + std::cout << "Request received from client " << client_guid_prefix << std::endl; - if (new_request) - { - cv_.notify_one(); + { + // Only lock to push the request into the queue so that the consumer thread gets + // a chance to process it in between subsequent takes + std::lock_guard lock(mtx_); + requests_.push({info, request}); + cv_.notify_all(); + } + } } } @@ -294,6 +311,124 @@ bool ServerApp::is_stopped() return stop_.load(); } +void ServerApp::reply_routine() +{ + while (!is_stopped()) + { + // Wait for a request to arrive + std::unique_lock lock(mtx_); + + cv_.wait(lock, [this]() -> bool + { + return requests_.size() > 0 || is_stopped(); + }); + + if (!is_stopped()) + { + // Process one request per iteration + Request request = requests_.front(); + requests_.pop(); + + rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(request.info.publication_handle).guidPrefix; + std::cout << "Processing request from client " << client_guid_prefix << std::endl; + + // If none to the client's endpoints are matched, ignore the request as the client is gone + if (!client_matched_status_.is_fully_unmatched(client_guid_prefix)) + { + std::cout << "Ignoring request from already gone client " << client_guid_prefix << std::endl; + continue; + } + + // If the request's client is not fully matched, save it for later + if (!client_matched_status_.is_matched(client_guid_prefix)) + { + std::cout << "Client " << client_guid_prefix << " not fully matched, saving request for later" << + std::endl; + requests_.push(request); + } + + // Calculate the result + std::int32_t result; + + // If the calculation fails, ignore the request, as the failure cause is a malformed request + if (!calculate(*request.request, result)) + { + std::cerr << "Failed to calculate result for request from client " << client_guid_prefix << std::endl; + continue; + } + + // Prepare the reply + CalculatorReplyType reply; + reply.client_id(request.request->client_id()); + reply.result(result); + + // Prepare the WriteParams to link the reply to the request + rtps::WriteParams write_params; + write_params.related_sample_identity().writer_guid(request.info.sample_identity.writer_guid()); + write_params.related_sample_identity().sequence_number(request.info.sample_identity.sequence_number()); + + // Send the reply + if (!reply_writer_->write(&reply, write_params)) + { + // In case of failure, save the request for a later retry + std::cerr << "Failed to send reply to client " << client_guid_prefix << std::endl; + requests_.push(request); + } + else + { + std::cout << "Reply sent to client " << client_guid_prefix << std::endl; + } + } + } +} + +bool ServerApp::calculate( + const CalculatorRequestType& request, + std::int32_t& result) +{ + bool success = true; + + switch (request.operation()) + { + case CalculatorOperationType::ADDITION: + { + result = request.x() + request.y(); + break; + } + case CalculatorOperationType::SUBTRACTION: + { + result = request.x() - request.y(); + break; + } + case CalculatorOperationType::MULTIPLICATION: + { + result = request.x() * request.y(); + break; + } + case CalculatorOperationType::DIVISION: + { + if (0 == request.y()) + { + std::cerr << "Division by zero request received" << std::endl; + success = false; + } + else + { + result = request.x() / request.y(); + } + break; + } + default: + { + std::cerr << "Unknown operation received" << std::endl; + success = false; + break; + } + } + + return success; +} + /******* HELPER FUNCTIONS DEFINITIONS *******/ namespace detail { diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index b1401daab39..bca93e40971 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -22,10 +22,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -95,6 +97,12 @@ class ServerApp : public Application, public DataWriterListener, public DataRead bool is_stopped(); + void reply_routine(); + + bool calculate( + const CalculatorRequestType& request, + std::int32_t& result); + DomainParticipant* participant_; TypeSupport request_type_; @@ -129,6 +137,8 @@ class ServerApp : public Application, public DataWriterListener, public DataRead std::queue requests_; + std::thread reply_thread_; + }; template<> diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index b47d0973e7f..64f6a7f2107 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -148,6 +148,21 @@ class RemoteClientMatchedStatus return is_client_matched; } + bool is_fully_unmatched( + const rtps::GuidPrefix_t& guid_prefix) + { + bool is_client_unmatched = false; + + auto status = matched_status_.find(guid_prefix); + + if (status != matched_status_.end()) + { + is_client_unmatched = !status->second.none(); + } + + return is_client_unmatched; + } + void clear() { matched_status_.clear(); diff --git a/examples/cpp/request_reply/request_reply.xml b/examples/cpp/request_reply/request_reply.xml new file mode 100644 index 00000000000..878878b21c3 --- /dev/null +++ b/examples/cpp/request_reply/request_reply.xml @@ -0,0 +1,54 @@ + + + + + 77 + + request_reply_participant + + + + + + TRANSIENT_LOCAL + + + RELIABLE + + + + + KEEP_LAST + 10000 + + + 10000 + 100 + 100 + + + + + + + + TRANSIENT_LOCAL + + + RELIABLE + + + + + KEEP_LAST + 10000 + + + 10000 + 100 + 100 + + + + + From 6473037741f44b9cc27a0f93e354d4833f16659a Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 09:49:43 +0200 Subject: [PATCH 16/46] Refs #21188: Move type support to dedicated directory Signed-off-by: eduponz --- examples/cpp/request_reply/CMakeLists.txt | 4 ++-- examples/cpp/request_reply/ClientApp.cpp | 4 ++-- examples/cpp/request_reply/ClientApp.hpp | 2 +- examples/cpp/request_reply/ServerApp.cpp | 4 ++-- examples/cpp/request_reply/ServerApp.hpp | 2 +- examples/cpp/request_reply/app_utils.hpp | 2 +- examples/cpp/request_reply/{ => types}/Calculator.hpp | 0 examples/cpp/request_reply/{ => types}/Calculator.idl | 0 examples/cpp/request_reply/{ => types}/CalculatorCdrAux.hpp | 0 examples/cpp/request_reply/{ => types}/CalculatorCdrAux.ipp | 0 .../cpp/request_reply/{ => types}/CalculatorPubSubTypes.cxx | 0 .../cpp/request_reply/{ => types}/CalculatorPubSubTypes.hpp | 0 .../request_reply/{ => types}/CalculatorTypeObjectSupport.cxx | 0 .../request_reply/{ => types}/CalculatorTypeObjectSupport.hpp | 0 14 files changed, 9 insertions(+), 9 deletions(-) rename examples/cpp/request_reply/{ => types}/Calculator.hpp (100%) rename examples/cpp/request_reply/{ => types}/Calculator.idl (100%) rename examples/cpp/request_reply/{ => types}/CalculatorCdrAux.hpp (100%) rename examples/cpp/request_reply/{ => types}/CalculatorCdrAux.ipp (100%) rename examples/cpp/request_reply/{ => types}/CalculatorPubSubTypes.cxx (100%) rename examples/cpp/request_reply/{ => types}/CalculatorPubSubTypes.hpp (100%) rename examples/cpp/request_reply/{ => types}/CalculatorTypeObjectSupport.cxx (100%) rename examples/cpp/request_reply/{ => types}/CalculatorTypeObjectSupport.hpp (100%) diff --git a/examples/cpp/request_reply/CMakeLists.txt b/examples/cpp/request_reply/CMakeLists.txt index eeda0a3756a..868bea9713a 100644 --- a/examples/cpp/request_reply/CMakeLists.txt +++ b/examples/cpp/request_reply/CMakeLists.txt @@ -35,8 +35,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") endif() message(STATUS "Configuring ${PROJECT_NAME}...") -file(GLOB REQUEST_REPLY_SOURCES_CXX "*.cxx") -file(GLOB REQUEST_REPLY_SOURCES_CPP "*.cpp") +file(GLOB_RECURSE REQUEST_REPLY_SOURCES_CXX "*.cxx") +file(GLOB_RECURSE REQUEST_REPLY_SOURCES_CPP "*.cpp") add_executable(request_reply ${REQUEST_REPLY_SOURCES_CXX} ${REQUEST_REPLY_SOURCES_CPP}) target_compile_definitions(request_reply PRIVATE diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index df292a7e188..d9501c251d3 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -35,8 +35,8 @@ #include #include -#include "Calculator.hpp" -#include "CalculatorPubSubTypes.hpp" +#include "types/Calculator.hpp" +#include "types/CalculatorPubSubTypes.hpp" namespace eprosima { namespace fastdds { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index a7992a8a340..aec24615016 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -37,8 +37,8 @@ #include "app_utils.hpp" #include "Application.hpp" -#include "CalculatorPubSubTypes.hpp" #include "CLIParser.hpp" +#include "types/CalculatorPubSubTypes.hpp" namespace eprosima { namespace fastdds { diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 0834bd58dbc..e4426d3ec9c 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -40,8 +40,8 @@ #include #include -#include "Calculator.hpp" -#include "CalculatorPubSubTypes.hpp" +#include "types/Calculator.hpp" +#include "types/CalculatorPubSubTypes.hpp" namespace eprosima { namespace fastdds { diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index bca93e40971..0e0a64ea917 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -42,7 +42,7 @@ #include "app_utils.hpp" #include "Application.hpp" -#include "CalculatorPubSubTypes.hpp" +#include "types/CalculatorPubSubTypes.hpp" namespace eprosima { namespace fastdds { diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index 64f6a7f2107..e435e6b04d7 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -29,8 +29,8 @@ #include -#include "Calculator.hpp" #include "CLIParser.hpp" +#include "types/Calculator.hpp" namespace eprosima { namespace fastdds { diff --git a/examples/cpp/request_reply/Calculator.hpp b/examples/cpp/request_reply/types/Calculator.hpp similarity index 100% rename from examples/cpp/request_reply/Calculator.hpp rename to examples/cpp/request_reply/types/Calculator.hpp diff --git a/examples/cpp/request_reply/Calculator.idl b/examples/cpp/request_reply/types/Calculator.idl similarity index 100% rename from examples/cpp/request_reply/Calculator.idl rename to examples/cpp/request_reply/types/Calculator.idl diff --git a/examples/cpp/request_reply/CalculatorCdrAux.hpp b/examples/cpp/request_reply/types/CalculatorCdrAux.hpp similarity index 100% rename from examples/cpp/request_reply/CalculatorCdrAux.hpp rename to examples/cpp/request_reply/types/CalculatorCdrAux.hpp diff --git a/examples/cpp/request_reply/CalculatorCdrAux.ipp b/examples/cpp/request_reply/types/CalculatorCdrAux.ipp similarity index 100% rename from examples/cpp/request_reply/CalculatorCdrAux.ipp rename to examples/cpp/request_reply/types/CalculatorCdrAux.ipp diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.cxx b/examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx similarity index 100% rename from examples/cpp/request_reply/CalculatorPubSubTypes.cxx rename to examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx diff --git a/examples/cpp/request_reply/CalculatorPubSubTypes.hpp b/examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp similarity index 100% rename from examples/cpp/request_reply/CalculatorPubSubTypes.hpp rename to examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx similarity index 100% rename from examples/cpp/request_reply/CalculatorTypeObjectSupport.cxx rename to examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx diff --git a/examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp similarity index 100% rename from examples/cpp/request_reply/CalculatorTypeObjectSupport.hpp rename to examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp From 4b52346cc049351b8fd1f31013abbd269c3c2017 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 09:58:23 +0200 Subject: [PATCH 17/46] Refs #21188: Server reply history cleanup when possible Signed-off-by: eduponz --- examples/cpp/request_reply/ServerApp.cpp | 14 ++++++++++++++ examples/cpp/request_reply/app_utils.hpp | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index e4426d3ec9c..924999b3690 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -142,6 +142,13 @@ void ServerApp::on_publication_matched( { std::cout << "Remote reply reader unmatched from client " << client_guid_prefix << std::endl; client_matched_status_.match_reply_reader(client_guid_prefix, false); + + // Remove old replies since no one is waiting for them + if (client_matched_status_.no_client_matched()) + { + std::size_t removed; + reply_writer_->clear_history(&removed); + } } else { @@ -168,6 +175,13 @@ void ServerApp::on_subscription_matched( { std::cout << "Remote request writer unmatched from client " << client_guid_prefix << std::endl; client_matched_status_.match_request_writer(client_guid_prefix, false); + + // Remove old replies since no one is waiting for them + if (client_matched_status_.no_client_matched()) + { + std::size_t removed; + reply_writer_->clear_history(&removed); + } } else { diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index e435e6b04d7..60c0846a480 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -163,6 +163,22 @@ class RemoteClientMatchedStatus return is_client_unmatched; } + bool no_client_matched() + { + bool no_client_matched = true; + + for (const auto& status : matched_status_) + { + if (status.second.any()) + { + no_client_matched = false; + break; + } + } + + return no_client_matched; + } + void clear() { matched_status_.clear(); From 6a5f56407d4207c112edd2953b9bde8a029f03b2 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 14:59:19 +0200 Subject: [PATCH 18/46] Refs #21188: Client uses CFT to only receive replies to its requests Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 19 +- examples/cpp/request_reply/ClientApp.hpp | 8 + examples/cpp/request_reply/app_utils.hpp | 10 +- .../cpp/request_reply/types/Calculator.hpp | 156 ++------------ .../cpp/request_reply/types/Calculator.idl | 10 +- .../request_reply/types/CalculatorCdrAux.hpp | 15 +- .../request_reply/types/CalculatorCdrAux.ipp | 80 +------- .../types/CalculatorPubSubTypes.cxx | 193 ------------------ .../types/CalculatorPubSubTypes.hpp | 95 +-------- .../types/CalculatorTypeObjectSupport.cxx | 128 +++--------- .../types/CalculatorTypeObjectSupport.hpp | 12 -- 11 files changed, 77 insertions(+), 649 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index d9501c251d3..30fb328f891 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -68,6 +68,8 @@ ClientApp::ClientApp( , request_writer_(nullptr) , reply_type_(nullptr) , reply_topic_(nullptr) + , reply_cf_topic_(nullptr) + , reply_topic_filter_expression_("") , subscriber_(nullptr) , reply_reader_(nullptr) , stop_(false) @@ -89,6 +91,9 @@ ClientApp::~ClientApp() // Delete DomainParticipant DomainParticipantFactory::get_shared_instance()->delete_participant(participant_); } + + server_matched_status_.clear(); + reply_topic_filter_parameters_.clear(); } void ClientApp::run() @@ -265,6 +270,18 @@ void ClientApp::create_reply_entities( // Create the reply topic reply_topic_ = create_topic("rr/" + service_name, reply_type_); + reply_topic_filter_expression_ = "client_id = '" + + TypeConverter::to_calculator_type(participant_->guid().guidPrefix) + "'"; + + reply_cf_topic_ = participant_->create_contentfilteredtopic("rr/" + service_name + "_cft", reply_topic_, + reply_topic_filter_expression_, + reply_topic_filter_parameters_); + + if (nullptr == reply_cf_topic_) + { + throw std::runtime_error("Failed to create CFT"); + } + // Create the subscriber SubscriberQos sub_qos = SUBSCRIBER_QOS_DEFAULT; @@ -288,7 +305,7 @@ void ClientApp::create_reply_entities( throw std::runtime_error("Failed to get default datareader qos"); } - reply_reader_ = subscriber_->create_datareader(reply_topic_, reader_qos, this, StatusMask::all()); + reply_reader_ = subscriber_->create_datareader(reply_cf_topic_, reader_qos, this, StatusMask::all()); if (nullptr == reply_reader_) { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index aec24615016..7ba38042e33 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include @@ -114,6 +116,12 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit Topic* reply_topic_; + ContentFilteredTopic* reply_cf_topic_; + + std::string reply_topic_filter_expression_; + + std::vector reply_topic_filter_parameters_; + Subscriber* subscriber_; DataReader* reply_reader_; diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index 60c0846a480..d7209ccc2d0 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -222,13 +223,12 @@ struct TypeConverter return calculator_operation; } - static ClientID to_calculator_type( + static std::string to_calculator_type( const rtps::GuidPrefix_t& guid_prefix) { - ClientID client_id; - std::copy(std::begin(guid_prefix.value), std::end(guid_prefix.value), std::begin(client_id.value())); - - return client_id; + std::ostringstream client_id; + client_id << guid_prefix; + return client_id.str(); } }; diff --git a/examples/cpp/request_reply/types/Calculator.hpp b/examples/cpp/request_reply/types/Calculator.hpp index f2f2aa286a4..56d1f977813 100644 --- a/examples/cpp/request_reply/types/Calculator.hpp +++ b/examples/cpp/request_reply/types/Calculator.hpp @@ -22,9 +22,10 @@ #ifndef FAST_DDS_GENERATED__CALCULATOR_HPP #define FAST_DDS_GENERATED__CALCULATOR_HPP -#include #include +#include #include +#include #if defined(_WIN32) #if defined(EPROSIMA_USER_DLL_EXPORT) @@ -61,139 +62,6 @@ enum class CalculatorOperationType : int32_t MULTIPLICATION, DIVISION }; -/*! - * @brief This class represents the structure ClientID defined by the user in the IDL file. - * @ingroup Calculator - */ -class ClientID -{ -public: - - /*! - * @brief Default constructor. - */ - eProsima_user_DllExport ClientID() - { - } - - /*! - * @brief Default destructor. - */ - eProsima_user_DllExport ~ClientID() - { - } - - /*! - * @brief Copy constructor. - * @param x Reference to the object ClientID that will be copied. - */ - eProsima_user_DllExport ClientID( - const ClientID& x) - { - m_value = x.m_value; - - } - - /*! - * @brief Move constructor. - * @param x Reference to the object ClientID that will be copied. - */ - eProsima_user_DllExport ClientID( - ClientID&& x) noexcept - { - m_value = std::move(x.m_value); - } - - /*! - * @brief Copy assignment. - * @param x Reference to the object ClientID that will be copied. - */ - eProsima_user_DllExport ClientID& operator =( - const ClientID& x) - { - - m_value = x.m_value; - - return *this; - } - - /*! - * @brief Move assignment. - * @param x Reference to the object ClientID that will be copied. - */ - eProsima_user_DllExport ClientID& operator =( - ClientID&& x) noexcept - { - - m_value = std::move(x.m_value); - return *this; - } - - /*! - * @brief Comparison operator. - * @param x ClientID object to compare. - */ - eProsima_user_DllExport bool operator ==( - const ClientID& x) const - { - return (m_value == x.m_value); - } - - /*! - * @brief Comparison operator. - * @param x ClientID object to compare. - */ - eProsima_user_DllExport bool operator !=( - const ClientID& x) const - { - return !(*this == x); - } - - /*! - * @brief This function copies the value in member value - * @param _value New value to be copied in member value - */ - eProsima_user_DllExport void value( - const std::array& _value) - { - m_value = _value; - } - - /*! - * @brief This function moves the value in member value - * @param _value New value to be moved in member value - */ - eProsima_user_DllExport void value( - std::array&& _value) - { - m_value = std::move(_value); - } - - /*! - * @brief This function returns a constant reference to member value - * @return Constant reference to member value - */ - eProsima_user_DllExport const std::array& value() const - { - return m_value; - } - - /*! - * @brief This function returns a reference to member value - * @return Reference to member value - */ - eProsima_user_DllExport std::array& value() - { - return m_value; - } - - - -private: - - std::array m_value{0}; - -}; /*! * @brief This class represents the structure CalculatorRequestType defined by the user in the IDL file. * @ingroup Calculator @@ -308,7 +176,7 @@ class CalculatorRequestType * @param _client_id New value to be copied in member client_id */ eProsima_user_DllExport void client_id( - const ClientID& _client_id) + const std::string& _client_id) { m_client_id = _client_id; } @@ -318,7 +186,7 @@ class CalculatorRequestType * @param _client_id New value to be moved in member client_id */ eProsima_user_DllExport void client_id( - ClientID&& _client_id) + std::string&& _client_id) { m_client_id = std::move(_client_id); } @@ -327,7 +195,7 @@ class CalculatorRequestType * @brief This function returns a constant reference to member client_id * @return Constant reference to member client_id */ - eProsima_user_DllExport const ClientID& client_id() const + eProsima_user_DllExport const std::string& client_id() const { return m_client_id; } @@ -336,7 +204,7 @@ class CalculatorRequestType * @brief This function returns a reference to member client_id * @return Reference to member client_id */ - eProsima_user_DllExport ClientID& client_id() + eProsima_user_DllExport std::string& client_id() { return m_client_id; } @@ -432,7 +300,7 @@ class CalculatorRequestType private: - ClientID m_client_id; + std::string m_client_id; CalculatorOperationType m_operation{CalculatorOperationType::ADDITION}; int16_t m_x{0}; int16_t m_y{0}; @@ -538,7 +406,7 @@ class CalculatorReplyType * @param _client_id New value to be copied in member client_id */ eProsima_user_DllExport void client_id( - const ClientID& _client_id) + const std::string& _client_id) { m_client_id = _client_id; } @@ -548,7 +416,7 @@ class CalculatorReplyType * @param _client_id New value to be moved in member client_id */ eProsima_user_DllExport void client_id( - ClientID&& _client_id) + std::string&& _client_id) { m_client_id = std::move(_client_id); } @@ -557,7 +425,7 @@ class CalculatorReplyType * @brief This function returns a constant reference to member client_id * @return Constant reference to member client_id */ - eProsima_user_DllExport const ClientID& client_id() const + eProsima_user_DllExport const std::string& client_id() const { return m_client_id; } @@ -566,7 +434,7 @@ class CalculatorReplyType * @brief This function returns a reference to member client_id * @return Reference to member client_id */ - eProsima_user_DllExport ClientID& client_id() + eProsima_user_DllExport std::string& client_id() { return m_client_id; } @@ -604,7 +472,7 @@ class CalculatorReplyType private: - ClientID m_client_id; + std::string m_client_id; int32_t m_result{0}; }; diff --git a/examples/cpp/request_reply/types/Calculator.idl b/examples/cpp/request_reply/types/Calculator.idl index 3ee9dd377d1..b3d5eda203d 100644 --- a/examples/cpp/request_reply/types/Calculator.idl +++ b/examples/cpp/request_reply/types/Calculator.idl @@ -7,16 +7,10 @@ enum CalculatorOperationType DIVISION }; -@extensibility(APPENDABLE) -struct ClientID -{ - octet value[12]; -}; - @extensibility(APPENDABLE) struct CalculatorRequestType { - @key ClientID client_id; + @key string client_id; CalculatorOperationType operation; short x; short y; @@ -25,6 +19,6 @@ struct CalculatorRequestType @extensibility(APPENDABLE) struct CalculatorReplyType { - @key ClientID client_id; + @key string client_id; long result; }; diff --git a/examples/cpp/request_reply/types/CalculatorCdrAux.hpp b/examples/cpp/request_reply/types/CalculatorCdrAux.hpp index 7b855d1f08f..1fefda14869 100644 --- a/examples/cpp/request_reply/types/CalculatorCdrAux.hpp +++ b/examples/cpp/request_reply/types/CalculatorCdrAux.hpp @@ -24,14 +24,11 @@ #include "Calculator.hpp" -constexpr uint32_t CalculatorRequestType_max_cdr_typesize {28UL}; -constexpr uint32_t CalculatorRequestType_max_key_cdr_typesize {16UL}; +constexpr uint32_t CalculatorRequestType_max_cdr_typesize {272UL}; +constexpr uint32_t CalculatorRequestType_max_key_cdr_typesize {260UL}; -constexpr uint32_t CalculatorReplyType_max_cdr_typesize {24UL}; -constexpr uint32_t CalculatorReplyType_max_key_cdr_typesize {16UL}; - -constexpr uint32_t ClientID_max_cdr_typesize {16UL}; -constexpr uint32_t ClientID_max_key_cdr_typesize {0UL}; +constexpr uint32_t CalculatorReplyType_max_cdr_typesize {268UL}; +constexpr uint32_t CalculatorReplyType_max_key_cdr_typesize {260UL}; @@ -41,10 +38,6 @@ namespace fastcdr { class Cdr; class CdrSizeCalculator; -eProsima_user_DllExport void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const ClientID& data); - eProsima_user_DllExport void serialize_key( eprosima::fastcdr::Cdr& scdr, const CalculatorRequestType& data); diff --git a/examples/cpp/request_reply/types/CalculatorCdrAux.ipp b/examples/cpp/request_reply/types/CalculatorCdrAux.ipp index ef2d0f63d9d..7b1ddfc73b9 100644 --- a/examples/cpp/request_reply/types/CalculatorCdrAux.ipp +++ b/examples/cpp/request_reply/types/CalculatorCdrAux.ipp @@ -34,82 +34,6 @@ using namespace eprosima::fastcdr::exception; namespace eprosima { namespace fastcdr { -template<> -eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const ClientID& data, - size_t& current_alignment) -{ - static_cast(data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size {calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment)}; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.value(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; -} - -template<> -eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const ClientID& data) -{ - eprosima::fastcdr::Cdr::state current_state(scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.value() -; - scdr.end_serialize_type(current_state); -} - -template<> -eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - ClientID& data) -{ - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool - { - bool ret_value = true; - switch (mid.id) - { - case 0: - dcdr >> data.value(); - break; - - default: - ret_value = false; - break; - } - return ret_value; - }); -} - -void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const ClientID& data) -{ - static_cast(scdr); - static_cast(data); -} - - template<> eProsima_user_DllExport size_t calculate_serialized_size( eprosima::fastcdr::CdrSizeCalculator& calculator, @@ -207,7 +131,7 @@ void serialize_key( { static_cast(scdr); static_cast(data); - scdr << data.client_id(); + scdr << data.client_id(); @@ -296,7 +220,7 @@ void serialize_key( { static_cast(scdr); static_cast(data); - scdr << data.client_id(); + scdr << data.client_id(); } diff --git a/examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx b/examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx index c4ed9303fe9..28b085a472b 100644 --- a/examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx +++ b/examples/cpp/request_reply/types/CalculatorPubSubTypes.cxx @@ -31,199 +31,6 @@ using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; -ClientIDPubSubType::ClientIDPubSubType() -{ - setName("ClientID"); - uint32_t type_size = -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(ClientID::getMaxCdrSerializedSize()); -#else - ClientID_max_cdr_typesize; -#endif - type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ - m_typeSize = type_size + 4; /*encapsulation*/ - m_isGetKeyDefined = false; - uint32_t keyLength = ClientID_max_key_cdr_typesize > 16 ? ClientID_max_key_cdr_typesize : 16; - m_keyBuffer = reinterpret_cast(malloc(keyLength)); - memset(m_keyBuffer, 0, keyLength); -} - -ClientIDPubSubType::~ClientIDPubSubType() -{ - if (m_keyBuffer != nullptr) - { - free(m_keyBuffer); - } -} - -bool ClientIDPubSubType::serialize( - const void* const data, - SerializedPayload_t* payload, - DataRepresentationId_t data_representation) -{ - const ClientID* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); - payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; -#if FASTCDR_VERSION_MAJOR > 1 - ser.set_encoding_flag( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); -#endif // FASTCDR_VERSION_MAJOR > 1 - - try - { - // Serialize encapsulation - ser.serialize_encapsulation(); - // Serialize the object. - ser << *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - // Get the serialized length -#if FASTCDR_VERSION_MAJOR == 1 - payload->length = static_cast(ser.getSerializedDataLength()); -#else - payload->length = static_cast(ser.get_serialized_data_length()); -#endif // FASTCDR_VERSION_MAJOR == 1 - return true; -} - -bool ClientIDPubSubType::deserialize( - SerializedPayload_t* payload, - void* data) -{ - try - { - // Convert DATA to pointer of your type - ClientID* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); - - // Object that deserializes the data. - eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN -#if FASTCDR_VERSION_MAJOR == 1 - , eprosima::fastcdr::Cdr::CdrType::DDS_CDR -#endif // FASTCDR_VERSION_MAJOR == 1 - ); - - // Deserialize encapsulation. - deser.read_encapsulation(); - payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - - // Deserialize the object. - deser >> *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - return true; -} - -std::function ClientIDPubSubType::getSerializedSizeProvider( - const void* const data, - DataRepresentationId_t data_representation) -{ - return [data, data_representation]() -> uint32_t - { -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(data_representation); - return static_cast(type::getCdrSerializedSize(*static_cast(data))) + - 4u /*encapsulation*/; -#else - try - { - eprosima::fastcdr::CdrSizeCalculator calculator( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); - size_t current_alignment {0}; - return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return 0; - } -#endif // FASTCDR_VERSION_MAJOR == 1 - }; -} - -void* ClientIDPubSubType::createData() -{ - return reinterpret_cast(new ClientID()); -} - -void ClientIDPubSubType::deleteData( - void* data) -{ - delete(reinterpret_cast(data)); -} - -bool ClientIDPubSubType::getKey( - const void* const data, - InstanceHandle_t* handle, - bool force_md5) -{ - if (!m_isGetKeyDefined) - { - return false; - } - - const ClientID* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), - ClientID_max_key_cdr_typesize); - - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); -#if FASTCDR_VERSION_MAJOR == 1 - p_type->serializeKey(ser); -#else - eprosima::fastcdr::serialize_key(ser, *p_type); -#endif // FASTCDR_VERSION_MAJOR == 1 - if (force_md5 || ClientID_max_key_cdr_typesize > 16) - { - m_md5.init(); -#if FASTCDR_VERSION_MAJOR == 1 - m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); -#else - m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); -#endif // FASTCDR_VERSION_MAJOR == 1 - m_md5.finalize(); - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_md5.digest[i]; - } - } - else - { - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_keyBuffer[i]; - } - } - return true; -} - -void ClientIDPubSubType::register_type_object_representation() -{ - register_ClientID_type_identifier(type_identifiers_); -} - CalculatorRequestTypePubSubType::CalculatorRequestTypePubSubType() { setName("CalculatorRequestType"); diff --git a/examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp b/examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp index 5b7c9fed89f..946ca0be8a8 100644 --- a/examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp +++ b/examples/cpp/request_reply/types/CalculatorPubSubTypes.hpp @@ -38,97 +38,6 @@ #endif // GEN_API_VER -/*! - * @brief This class represents the TopicDataType of the type ClientID defined by the user in the IDL file. - * @ingroup Calculator - */ -class ClientIDPubSubType : public eprosima::fastdds::dds::TopicDataType -{ -public: - - typedef ClientID type; - - eProsima_user_DllExport ClientIDPubSubType(); - - eProsima_user_DllExport ~ClientIDPubSubType() override; - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload) override - { - return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool deserialize( - eprosima::fastdds::rtps::SerializedPayload_t* payload, - void* data) override; - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data) override - { - return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool getKey( - const void* const data, - eprosima::fastdds::rtps::InstanceHandle_t* ihandle, - bool force_md5 = false) override; - - eProsima_user_DllExport void* createData() override; - - eProsima_user_DllExport void deleteData( - void* data) override; - - //Register TypeObject representation in Fast DDS TypeObjectRegistry - eProsima_user_DllExport void register_type_object_representation() override; - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - eProsima_user_DllExport inline bool is_bounded() const override - { - return true; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - eProsima_user_DllExport inline bool is_plain() const override - { - return false; - } - - eProsima_user_DllExport inline bool is_plain( - eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override - { - static_cast(data_representation); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - -#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - eProsima_user_DllExport inline bool construct_sample( - void* memory) const override - { - static_cast(memory); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - - eprosima::fastdds::MD5 m_md5; - unsigned char* m_keyBuffer; - -}; - /*! * @brief This class represents the TopicDataType of the type CalculatorRequestType defined by the user in the IDL file. * @ingroup Calculator @@ -185,7 +94,7 @@ class CalculatorRequestTypePubSubType : public eprosima::fastdds::dds::TopicData #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED eProsima_user_DllExport inline bool is_bounded() const override { - return true; + return false; } #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED @@ -276,7 +185,7 @@ class CalculatorReplyTypePubSubType : public eprosima::fastdds::dds::TopicDataTy #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED eProsima_user_DllExport inline bool is_bounded() const override { - return true; + return false; } #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED diff --git a/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx index 9ab9f99fa45..737382899f1 100644 --- a/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx +++ b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.cxx @@ -113,106 +113,6 @@ void register_CalculatorOperationType_type_identifier( } } }// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method -void register_ClientID_type_identifier( - TypeIdentifierPair& type_ids_ClientID) -{ - - ReturnCode_t return_code_ClientID {eprosima::fastdds::dds::RETCODE_OK}; - return_code_ClientID = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "ClientID", type_ids_ClientID); - if (eprosima::fastdds::dds::RETCODE_OK != return_code_ClientID) - { - StructTypeFlag struct_flags_ClientID = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); - QualifiedTypeName type_name_ClientID = "ClientID"; - eprosima::fastcdr::optional type_ann_builtin_ClientID; - eprosima::fastcdr::optional ann_custom_ClientID; - AppliedAnnotationSeq tmp_ann_custom_ClientID; - eprosima::fastcdr::optional verbatim_ClientID; - if (!tmp_ann_custom_ClientID.empty()) - { - ann_custom_ClientID = tmp_ann_custom_ClientID; - } - - CompleteTypeDetail detail_ClientID = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ClientID, ann_custom_ClientID, type_name_ClientID.to_string()); - CompleteStructHeader header_ClientID; - header_ClientID = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ClientID); - CompleteStructMemberSeq member_seq_ClientID; - { - TypeIdentifierPair type_ids_value; - ReturnCode_t return_code_value {eprosima::fastdds::dds::RETCODE_OK}; - return_code_value = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "anonymous_array_uint8_t_12", type_ids_value); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_value) - { - return_code_value = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_byte", type_ids_value); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_value) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "Array element TypeIdentifier unknown to TypeObjectRegistry."); - return; - } - bool element_identifier_anonymous_array_uint8_t_12_ec {false}; - TypeIdentifier* element_identifier_anonymous_array_uint8_t_12 {new TypeIdentifier(TypeObjectUtils::retrieve_complete_type_identifier(type_ids_value, element_identifier_anonymous_array_uint8_t_12_ec))}; - if (!element_identifier_anonymous_array_uint8_t_12_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Array element TypeIdentifier inconsistent."); - return; - } - EquivalenceKind equiv_kind_anonymous_array_uint8_t_12 = EK_COMPLETE; - if (TK_NONE == type_ids_value.type_identifier2()._d()) - { - equiv_kind_anonymous_array_uint8_t_12 = EK_BOTH; - } - CollectionElementFlag element_flags_anonymous_array_uint8_t_12 = 0; - PlainCollectionHeader header_anonymous_array_uint8_t_12 = TypeObjectUtils::build_plain_collection_header(equiv_kind_anonymous_array_uint8_t_12, element_flags_anonymous_array_uint8_t_12); - { - SBoundSeq array_bound_seq; - TypeObjectUtils::add_array_dimension(array_bound_seq, static_cast(12)); - - PlainArraySElemDefn array_sdefn = TypeObjectUtils::build_plain_array_s_elem_defn(header_anonymous_array_uint8_t_12, array_bound_seq, - eprosima::fastcdr::external(element_identifier_anonymous_array_uint8_t_12)); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_s_array_type_identifier(array_sdefn, "anonymous_array_uint8_t_12", type_ids_value)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "anonymous_array_uint8_t_12 already registered in TypeObjectRegistry for a different type."); - } - } - } - StructMemberFlag member_flags_value = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_value = 0x00000000; - bool common_value_ec {false}; - CommonStructMember common_value {TypeObjectUtils::build_common_struct_member(member_id_value, member_flags_value, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_value, common_value_ec))}; - if (!common_value_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure value member TypeIdentifier inconsistent."); - return; - } - MemberName name_value = "value"; - eprosima::fastcdr::optional member_ann_builtin_value; - ann_custom_ClientID.reset(); - CompleteMemberDetail detail_value = TypeObjectUtils::build_complete_member_detail(name_value, member_ann_builtin_value, ann_custom_ClientID); - CompleteStructMember member_value = TypeObjectUtils::build_complete_struct_member(common_value, detail_value); - TypeObjectUtils::add_complete_struct_member(member_seq_ClientID, member_value); - } - CompleteStructType struct_type_ClientID = TypeObjectUtils::build_complete_struct_type(struct_flags_ClientID, header_ClientID, member_seq_ClientID); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_ClientID, type_name_ClientID.to_string(), type_ids_ClientID)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "ClientID already registered in TypeObjectRegistry for a different type."); - } - } -} -// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method void register_CalculatorRequestType_type_identifier( TypeIdentifierPair& type_ids_CalculatorRequestType) { @@ -244,11 +144,21 @@ void register_CalculatorRequestType_type_identifier( ReturnCode_t return_code_client_id {eprosima::fastdds::dds::RETCODE_OK}; return_code_client_id = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "ClientID", type_ids_client_id); + "anonymous_string_unbounded", type_ids_client_id); if (eprosima::fastdds::dds::RETCODE_OK != return_code_client_id) { - ::register_ClientID_type_identifier(type_ids_client_id); + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_client_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } } StructMemberFlag member_flags_client_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, false, false, true, false); @@ -409,11 +319,21 @@ void register_CalculatorReplyType_type_identifier( ReturnCode_t return_code_client_id {eprosima::fastdds::dds::RETCODE_OK}; return_code_client_id = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "ClientID", type_ids_client_id); + "anonymous_string_unbounded", type_ids_client_id); if (eprosima::fastdds::dds::RETCODE_OK != return_code_client_id) { - ::register_ClientID_type_identifier(type_ids_client_id); + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_client_id)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } } StructMemberFlag member_flags_client_id = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, false, false, true, false); diff --git a/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp index 5ca967afb91..1fb9bccf445 100644 --- a/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp +++ b/examples/cpp/request_reply/types/CalculatorTypeObjectSupport.hpp @@ -49,18 +49,6 @@ */ eProsima_user_DllExport void register_CalculatorOperationType_type_identifier( eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); -/** - * @brief Register ClientID related TypeIdentifier. - * Fully-descriptive TypeIdentifiers are directly registered. - * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is - * indirectly registered as well. - * - * @param[out] TypeIdentifier of the registered type. - * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. - * Invalid TypeIdentifier is returned in case of error. - */ -eProsima_user_DllExport void register_ClientID_type_identifier( - eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); /** * @brief Register CalculatorRequestType related TypeIdentifier. * Fully-descriptive TypeIdentifiers are directly registered. From 86e84c266c6aec839410a6077a373dde40c09582 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 15:15:40 +0200 Subject: [PATCH 19/46] Refs #21188: Client waits before sending request Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 30fb328f891..e822682366a 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -19,9 +19,11 @@ #include "ClientApp.hpp" +#include #include #include #include +#include #include #include @@ -106,6 +108,9 @@ void ClientApp::run() }); } + // Give some time for all connections to be matched on both ends + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (!send_request()) { throw std::runtime_error("Failed to send request"); From 1250a3289f603916d0ef993ad881308c09477111 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 15:57:05 +0200 Subject: [PATCH 20/46] Refs #21188: Add logging utils Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 25 +++++++------- examples/cpp/request_reply/ServerApp.cpp | 37 ++++++++++----------- examples/cpp/request_reply/app_utils.hpp | 42 ++++++++++++++++++++++++ examples/cpp/request_reply/main.cpp | 14 ++++---- 4 files changed, 79 insertions(+), 39 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index e822682366a..de1474a649c 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -80,7 +80,7 @@ ClientApp::ClientApp( create_request_entities(service_name); create_reply_entities(service_name); - std::cout << "Client initialized with ID: " << participant_->guid().guidPrefix << std::endl; + request_reply_info("Client initialized with ID: " << participant_->guid().guidPrefix); } ClientApp::~ClientApp() @@ -135,19 +135,19 @@ void ClientApp::on_publication_matched( if (info.current_count_change == 1) { - std::cout << "Remote request reader matched." << std::endl; + request_reply_info("Remote request reader matched."); server_matched_status_.match_request_reader(server_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote request reader unmatched." << std::endl; + request_reply_info("Remote request reader unmatched."); server_matched_status_.match_request_reader(server_guid_prefix, false); } else { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + request_reply_error(info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change"); } cv_.notify_all(); } @@ -162,19 +162,19 @@ void ClientApp::on_subscription_matched( if (info.current_count_change == 1) { - std::cout << "Remote reply writer matched." << std::endl; + request_reply_info("Remote reply writer matched."); server_matched_status_.match_reply_writer(server_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote reply writer unmatched." << std::endl; + request_reply_info("Remote reply writer unmatched."); server_matched_status_.match_reply_writer(server_guid_prefix, false); } else { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + request_reply_error(info.current_count_change + << " is not a valid value for SubscriptionMatchedStatus current count change"); } cv_.notify_all(); } @@ -190,8 +190,9 @@ void ClientApp::on_data_available( if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; - std::cout << "Reply received from server " << server_guid_prefix - << " with result: " << reply.result() << std::endl; + request_reply_info( + "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); + stop(); break; } @@ -327,7 +328,7 @@ bool ClientApp::send_request() request.x(request_input_.x); request.y(request_input_.y); - std::cout << "Sending request" << std::endl; + request_reply_info("Sending request"); return request_writer_->write(&request); } diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 924999b3690..a0c84a35dcf 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -81,7 +81,7 @@ ServerApp::ServerApp( create_request_entities(service_name); create_reply_entities(service_name); - std::cout << "Server initialized with ID: " << participant_->guid().guidPrefix << std::endl; + request_reply_info("Server initialized with ID: " << participant_->guid().guidPrefix); } ServerApp::~ServerApp() @@ -135,12 +135,12 @@ void ServerApp::on_publication_matched( if (info.current_count_change == 1) { - std::cout << "Remote reply reader matched with client " << client_guid_prefix << std::endl; + request_reply_info("Remote reply reader matched with client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote reply reader unmatched from client " << client_guid_prefix << std::endl; + request_reply_info("Remote reply reader unmatched from client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -152,8 +152,8 @@ void ServerApp::on_publication_matched( } else { - std::cout << info.current_count_change - << " is not a valid value for PublicationMatchedStatus current count change" << std::endl; + request_reply_error(info.current_count_change + << " is not a valid value for PublicationMatchedStatus current count change"); } } @@ -167,13 +167,13 @@ void ServerApp::on_subscription_matched( if (info.current_count_change == 1) { - std::cout << "Remote request writer matched with client " << client_guid_prefix << std::endl; + request_reply_info("Remote request writer matched with client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, true); } else if (info.current_count_change == -1) { - std::cout << "Remote request writer unmatched from client " << client_guid_prefix << std::endl; + request_reply_info("Remote request writer unmatched from client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -185,8 +185,8 @@ void ServerApp::on_subscription_matched( } else { - std::cout << info.current_count_change - << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl; + request_reply_error( + info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change"); } } @@ -201,7 +201,7 @@ void ServerApp::on_data_available( if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; - std::cout << "Request received from client " << client_guid_prefix << std::endl; + request_reply_info("Request received from client " << client_guid_prefix); { // Only lock to push the request into the queue so that the consumer thread gets @@ -344,20 +344,19 @@ void ServerApp::reply_routine() requests_.pop(); rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(request.info.publication_handle).guidPrefix; - std::cout << "Processing request from client " << client_guid_prefix << std::endl; + request_reply_info("Processing request from client " << client_guid_prefix); // If none to the client's endpoints are matched, ignore the request as the client is gone if (!client_matched_status_.is_fully_unmatched(client_guid_prefix)) { - std::cout << "Ignoring request from already gone client " << client_guid_prefix << std::endl; + request_reply_info("Ignoring request from already gone client " << client_guid_prefix); continue; } // If the request's client is not fully matched, save it for later if (!client_matched_status_.is_matched(client_guid_prefix)) { - std::cout << "Client " << client_guid_prefix << " not fully matched, saving request for later" << - std::endl; + request_reply_info("Client " << client_guid_prefix << " not fully matched, saving request for later"); requests_.push(request); } @@ -367,7 +366,7 @@ void ServerApp::reply_routine() // If the calculation fails, ignore the request, as the failure cause is a malformed request if (!calculate(*request.request, result)) { - std::cerr << "Failed to calculate result for request from client " << client_guid_prefix << std::endl; + request_reply_error("Failed to calculate result for request from client " << client_guid_prefix); continue; } @@ -385,12 +384,12 @@ void ServerApp::reply_routine() if (!reply_writer_->write(&reply, write_params)) { // In case of failure, save the request for a later retry - std::cerr << "Failed to send reply to client " << client_guid_prefix << std::endl; + request_reply_error("Failed to send reply to client " << client_guid_prefix); requests_.push(request); } else { - std::cout << "Reply sent to client " << client_guid_prefix << std::endl; + request_reply_info("Reply sent to client " << client_guid_prefix); } } } @@ -423,7 +422,7 @@ bool ServerApp::calculate( { if (0 == request.y()) { - std::cerr << "Division by zero request received" << std::endl; + request_reply_error("Division by zero request received"); success = false; } else @@ -434,7 +433,7 @@ bool ServerApp::calculate( } default: { - std::cerr << "Unknown operation received" << std::endl; + request_reply_error("Unknown operation received"); success = false; break; } diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index d7209ccc2d0..b3221087550 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -23,11 +23,16 @@ #include #include #include +#include #include #include +#include +#include +#include #include #include +#include #include #include "CLIParser.hpp" @@ -233,6 +238,43 @@ struct TypeConverter }; +struct Timestamp +{ + static std::string now() + { + // Get current time + auto now = std::chrono::system_clock::now(); + auto time_t_now = std::chrono::system_clock::to_time_t(now); + + // Convert to tm struct for local time + std::tm tm_now; +#if defined(_WIN32) || defined(_WIN64) + localtime_s(&tm_now, &time_t_now); +#else + localtime_r(&time_t_now, &tm_now); +#endif // if defined(_WIN32) || defined(_WIN64) + + // Format date and time + std::ostringstream oss; + oss << std::put_time(&tm_now, "%Y-%m-%dT%H:%M:%S"); + + // Add milliseconds + auto duration = now.time_since_epoch(); + auto milliseconds = std::chrono::duration_cast(duration).count() % 1000; + oss << '.' << std::setfill('0') << std::setw(3) << milliseconds; + + return oss.str(); + } +}; + +#define request_reply_info(message) \ + std::cout << C_B_WHITE << Timestamp::now() << C_B_GREEN << " [INFO] " << C_DEF \ + << C_WHITE << message << C_DEF << std::endl + +#define request_reply_error(message) \ + std::cerr << C_B_WHITE << Timestamp::now() << C_B_RED << " [ERROR] " << C_DEF \ + << C_WHITE << message << C_DEF << std::endl + } // namespace request_reply } // namespace examples } // namespace fastdds diff --git a/examples/cpp/request_reply/main.cpp b/examples/cpp/request_reply/main.cpp index 792570dae5d..c0d01e3e400 100644 --- a/examples/cpp/request_reply/main.cpp +++ b/examples/cpp/request_reply/main.cpp @@ -25,8 +25,7 @@ #include #include -#include - +#include "app_utils.hpp" #include "Application.hpp" #include "CLIParser.hpp" @@ -59,7 +58,7 @@ int main( } catch (const std::runtime_error& e) { - EPROSIMA_LOG_ERROR(app_name, e.what()); + request_reply_error(e.what()); ret = EXIT_FAILURE; } @@ -69,8 +68,9 @@ int main( stop_app_handler = [&](int signum) { - std::cout << "\n" << CLIParser::parse_signal(signum) << " received, stopping " << app_name - << " execution." << std::endl; + request_reply_info( + CLIParser::parse_signal(signum) << " received, stopping " << app_name << " execution."); + app->stop(); }; @@ -81,12 +81,10 @@ int main( signal(SIGHUP, signal_handler); #endif // _WIN32 - std::cout << app_name << " running. Please press Ctrl+C to stop the " - << app_name << " at any time." << std::endl; + request_reply_info(app_name << " running. Please press Ctrl+C to stop the " << app_name << " at any time."); thread.join(); } - Log::Reset(); return ret; } From ed7ac4102111db15019378c9152cc9d534699bd5 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 16:01:34 +0200 Subject: [PATCH 21/46] Refs #21188: Client SIGINT exit before any server has matched Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 25 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index de1474a649c..f49c724d9d9 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -104,19 +103,29 @@ void ClientApp::run() std::unique_lock lock(mtx_); cv_.wait(lock, [&]() { - return server_matched_status_.is_any_server_matched(); + return server_matched_status_.is_any_server_matched() || is_stopped(); }); } - // Give some time for all connections to be matched on both ends - std::this_thread::sleep_for(std::chrono::seconds(1)); - - if (!send_request()) + if (!is_stopped()) { - throw std::runtime_error("Failed to send request"); + // Give some time for all connections to be matched on both ends + std::unique_lock lock(mtx_); + cv_.wait_for(lock, std::chrono::seconds(1), [&]() + { + return is_stopped(); + }); } - wait_for_reply(); + if (!is_stopped()) + { + if (!send_request()) + { + throw std::runtime_error("Failed to send request"); + } + + wait_for_reply(); + } } void ClientApp::stop() From 4089d7630b91f2454695580182752d76e107812f Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 16:24:14 +0200 Subject: [PATCH 22/46] Refs #21188: Add debug logging Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 18 +++++++----- examples/cpp/request_reply/ServerApp.cpp | 12 ++++---- examples/cpp/request_reply/app_utils.hpp | 37 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index f49c724d9d9..3331aaa33d4 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -99,6 +99,7 @@ ClientApp::~ClientApp() void ClientApp::run() { + request_reply_debug("Waiting for a server to be available"); { std::unique_lock lock(mtx_); cv_.wait(lock, [&]() @@ -109,7 +110,8 @@ void ClientApp::run() if (!is_stopped()) { - // Give some time for all connections to be matched on both ends + request_reply_debug("One server is available. Waiting for some time to ensure matching on the server side"); + std::unique_lock lock(mtx_); cv_.wait_for(lock, std::chrono::seconds(1), [&]() { @@ -144,13 +146,13 @@ void ClientApp::on_publication_matched( if (info.current_count_change == 1) { - request_reply_info("Remote request reader matched."); + request_reply_debug("Remote request reader matched."); server_matched_status_.match_request_reader(server_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_info("Remote request reader unmatched."); + request_reply_debug("Remote request reader unmatched."); server_matched_status_.match_request_reader(server_guid_prefix, false); } else @@ -171,13 +173,13 @@ void ClientApp::on_subscription_matched( if (info.current_count_change == 1) { - request_reply_info("Remote reply writer matched."); + request_reply_debug("Remote reply writer matched."); server_matched_status_.match_reply_writer(server_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_info("Remote reply writer unmatched."); + request_reply_debug("Remote reply writer unmatched."); server_matched_status_.match_reply_writer(server_guid_prefix, false); } else @@ -337,9 +339,11 @@ bool ClientApp::send_request() request.x(request_input_.x); request.y(request_input_.y); - request_reply_info("Sending request"); + bool ret = request_writer_->write(&request); + + request_reply_info("Request sent: '" << request_input_.str() << "'"); - return request_writer_->write(&request); + return ret; } bool ClientApp::is_stopped() diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index a0c84a35dcf..bf7a45de2e6 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -135,12 +135,12 @@ void ServerApp::on_publication_matched( if (info.current_count_change == 1) { - request_reply_info("Remote reply reader matched with client " << client_guid_prefix); + request_reply_debug("Remote reply reader matched with client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_info("Remote reply reader unmatched from client " << client_guid_prefix); + request_reply_debug("Remote reply reader unmatched from client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -167,13 +167,13 @@ void ServerApp::on_subscription_matched( if (info.current_count_change == 1) { - request_reply_info("Remote request writer matched with client " << client_guid_prefix); + request_reply_debug("Remote request writer matched with client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_info("Remote request writer unmatched from client " << client_guid_prefix); + request_reply_debug("Remote request writer unmatched from client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -344,7 +344,7 @@ void ServerApp::reply_routine() requests_.pop(); rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(request.info.publication_handle).guidPrefix; - request_reply_info("Processing request from client " << client_guid_prefix); + request_reply_debug("Processing request from client " << client_guid_prefix); // If none to the client's endpoints are matched, ignore the request as the client is gone if (!client_matched_status_.is_fully_unmatched(client_guid_prefix)) @@ -356,7 +356,7 @@ void ServerApp::reply_routine() // If the request's client is not fully matched, save it for later if (!client_matched_status_.is_matched(client_guid_prefix)) { - request_reply_info("Client " << client_guid_prefix << " not fully matched, saving request for later"); + request_reply_debug("Client " << client_guid_prefix << " not fully matched, saving request for later"); requests_.push(request); } diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index b3221087550..d022e2a3de5 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -53,6 +53,34 @@ struct RequestInput { } + std::string str() + { + std::string result = std::to_string(x); + + switch (operation) + { + case CLIParser::Operation::ADDITION: + result += " + "; + break; + case CLIParser::Operation::SUBTRACTION: + result += " - "; + break; + case CLIParser::Operation::MULTIPLICATION: + result += " x "; + break; + case CLIParser::Operation::DIVISION: + result += " / "; + break; + default: + result += " UNDEFINED "; + break; + } + + result += std::to_string(y); + + return result; + } + CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; std::int16_t x = 0; @@ -265,8 +293,17 @@ struct Timestamp return oss.str(); } + }; +#ifndef NDEGUB +#define request_reply_debug(message) \ + std::cout << C_B_WHITE << Timestamp::now() << C_B_BLUE << " [DEBUG] " << C_DEF \ + << C_WHITE << message << C_DEF << std::endl +#else +#define request_reply_debug(message) +#endif // ifdef NDEGUB + #define request_reply_info(message) \ std::cout << C_B_WHITE << Timestamp::now() << C_B_GREEN << " [INFO] " << C_DEF \ << C_WHITE << message << C_DEF << std::endl From a412a17c2048ba98c515f1058d02d99295c09c13 Mon Sep 17 00:00:00 2001 From: eduponz Date: Sat, 29 Jun 2024 16:38:08 +0200 Subject: [PATCH 23/46] Refs #21188: Add request ID to log messages Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 8 ++++++-- examples/cpp/request_reply/ServerApp.cpp | 14 ++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 3331aaa33d4..5dfe3363342 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "types/Calculator.hpp" #include "types/CalculatorPubSubTypes.hpp" @@ -339,9 +340,12 @@ bool ClientApp::send_request() request.x(request_input_.x); request.y(request_input_.y); - bool ret = request_writer_->write(&request); - request_reply_info("Request sent: '" << request_input_.str() << "'"); + rtps::WriteParams wparams; + bool ret = request_writer_->write(&request, wparams); + + request_reply_info( + "Request sent with ID '" << wparams.sample_identity().sequence_number() << "': '" << request_input_.str()); return ret; } diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index bf7a45de2e6..57e383b2478 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "types/Calculator.hpp" @@ -201,7 +202,9 @@ void ServerApp::on_data_available( if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; - request_reply_info("Request received from client " << client_guid_prefix); + rtps::SequenceNumber_t request_id = info.sample_identity.sequence_number(); + + request_reply_info("Request with ID '" << request_id << "' received from client " << client_guid_prefix); { // Only lock to push the request into the queue so that the consumer thread gets @@ -377,19 +380,22 @@ void ServerApp::reply_routine() // Prepare the WriteParams to link the reply to the request rtps::WriteParams write_params; + rtps::SequenceNumber_t request_id = request.info.sample_identity.sequence_number(); write_params.related_sample_identity().writer_guid(request.info.sample_identity.writer_guid()); - write_params.related_sample_identity().sequence_number(request.info.sample_identity.sequence_number()); + write_params.related_sample_identity().sequence_number(request_id); // Send the reply if (!reply_writer_->write(&reply, write_params)) { // In case of failure, save the request for a later retry - request_reply_error("Failed to send reply to client " << client_guid_prefix); + request_reply_error( + "Failed to send reply to request with ID '" << request_id << "' to client " << client_guid_prefix); requests_.push(request); } else { - request_reply_info("Reply sent to client " << client_guid_prefix); + request_reply_info( + "Reply to request with ID '" << request_id << "' sent to client " << client_guid_prefix); } } } From c799e6c2f01a8c227aa5ee4a9ba038dfc4b0adcf Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 14:46:08 +0200 Subject: [PATCH 24/46] Refs #21188: Add small TODO for follow-up PR to fulfil Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 5dfe3363342..3c22a47ba77 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -113,6 +113,7 @@ void ClientApp::run() { request_reply_debug("One server is available. Waiting for some time to ensure matching on the server side"); + // TODO(eduponz): This wait should be conditioned to upcoming fully-matched API on the endpoints std::unique_lock lock(mtx_); cv_.wait_for(lock, std::chrono::seconds(1), [&]() { From d82825571148a465bcf19d0a341a672191afbd6a Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 15:01:07 +0200 Subject: [PATCH 25/46] Refs #21188: Add context to log messages Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 27 ++++++++------- examples/cpp/request_reply/ServerApp.cpp | 43 +++++++++++++----------- examples/cpp/request_reply/app_utils.hpp | 20 +++++------ examples/cpp/request_reply/main.cpp | 9 ++--- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 3c22a47ba77..c09ef94c379 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -80,7 +80,7 @@ ClientApp::ClientApp( create_request_entities(service_name); create_reply_entities(service_name); - request_reply_info("Client initialized with ID: " << participant_->guid().guidPrefix); + request_reply_info("ClientApp", "Client initialized with ID: " << participant_->guid().guidPrefix); } ClientApp::~ClientApp() @@ -100,7 +100,7 @@ ClientApp::~ClientApp() void ClientApp::run() { - request_reply_debug("Waiting for a server to be available"); + request_reply_debug("ClientApp", "Waiting for a server to be available"); { std::unique_lock lock(mtx_); cv_.wait(lock, [&]() @@ -111,7 +111,8 @@ void ClientApp::run() if (!is_stopped()) { - request_reply_debug("One server is available. Waiting for some time to ensure matching on the server side"); + request_reply_debug("ClientApp", + "One server is available. Waiting for some time to ensure matching on the server side"); // TODO(eduponz): This wait should be conditioned to upcoming fully-matched API on the endpoints std::unique_lock lock(mtx_); @@ -148,18 +149,18 @@ void ClientApp::on_publication_matched( if (info.current_count_change == 1) { - request_reply_debug("Remote request reader matched."); + request_reply_debug("ClientApp", "Remote request reader matched."); server_matched_status_.match_request_reader(server_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_debug("Remote request reader unmatched."); + request_reply_debug("ClientApp", "Remote request reader unmatched."); server_matched_status_.match_request_reader(server_guid_prefix, false); } else { - request_reply_error(info.current_count_change + request_reply_error("ClientApp", info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change"); } cv_.notify_all(); @@ -175,18 +176,18 @@ void ClientApp::on_subscription_matched( if (info.current_count_change == 1) { - request_reply_debug("Remote reply writer matched."); + request_reply_debug("ClientApp", "Remote reply writer matched."); server_matched_status_.match_reply_writer(server_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_debug("Remote reply writer unmatched."); + request_reply_debug("ClientApp", "Remote reply writer unmatched."); server_matched_status_.match_reply_writer(server_guid_prefix, false); } else { - request_reply_error(info.current_count_change + request_reply_error("ClientApp", info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change"); } cv_.notify_all(); @@ -203,8 +204,8 @@ void ClientApp::on_data_available( if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; - request_reply_info( - "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); + request_reply_info("ClientApp", + "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); stop(); break; @@ -345,8 +346,8 @@ bool ClientApp::send_request() rtps::WriteParams wparams; bool ret = request_writer_->write(&request, wparams); - request_reply_info( - "Request sent with ID '" << wparams.sample_identity().sequence_number() << "': '" << request_input_.str()); + request_reply_info("ClientApp", + "Request sent with ID '" << wparams.sample_identity().sequence_number() << "': '" << request_input_.str()); return ret; } diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 57e383b2478..a944473449c 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -82,7 +82,7 @@ ServerApp::ServerApp( create_request_entities(service_name); create_reply_entities(service_name); - request_reply_info("Server initialized with ID: " << participant_->guid().guidPrefix); + request_reply_info("ServerApp", "Server initialized with ID: " << participant_->guid().guidPrefix); } ServerApp::~ServerApp() @@ -136,12 +136,12 @@ void ServerApp::on_publication_matched( if (info.current_count_change == 1) { - request_reply_debug("Remote reply reader matched with client " << client_guid_prefix); + request_reply_debug("ServerApp", "Remote reply reader matched with client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_debug("Remote reply reader unmatched from client " << client_guid_prefix); + request_reply_debug("ServerApp", "Remote reply reader unmatched from client " << client_guid_prefix); client_matched_status_.match_reply_reader(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -153,7 +153,7 @@ void ServerApp::on_publication_matched( } else { - request_reply_error(info.current_count_change + request_reply_error("ServerApp", info.current_count_change << " is not a valid value for PublicationMatchedStatus current count change"); } } @@ -168,13 +168,13 @@ void ServerApp::on_subscription_matched( if (info.current_count_change == 1) { - request_reply_debug("Remote request writer matched with client " << client_guid_prefix); + request_reply_debug("ServerApp", "Remote request writer matched with client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, true); } else if (info.current_count_change == -1) { - request_reply_debug("Remote request writer unmatched from client " << client_guid_prefix); + request_reply_debug("ServerApp", "Remote request writer unmatched from client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, false); // Remove old replies since no one is waiting for them @@ -186,8 +186,9 @@ void ServerApp::on_subscription_matched( } else { - request_reply_error( - info.current_count_change << " is not a valid value for SubscriptionMatchedStatus current count change"); + request_reply_error("ServerApp", + info.current_count_change << + " is not a valid value for SubscriptionMatchedStatus current count change"); } } @@ -204,7 +205,8 @@ void ServerApp::on_data_available( rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; rtps::SequenceNumber_t request_id = info.sample_identity.sequence_number(); - request_reply_info("Request with ID '" << request_id << "' received from client " << client_guid_prefix); + request_reply_info("ServerApp", + "Request with ID '" << request_id << "' received from client " << client_guid_prefix); { // Only lock to push the request into the queue so that the consumer thread gets @@ -347,19 +349,20 @@ void ServerApp::reply_routine() requests_.pop(); rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(request.info.publication_handle).guidPrefix; - request_reply_debug("Processing request from client " << client_guid_prefix); + request_reply_debug("ServerApp", "Processing request from client " << client_guid_prefix); // If none to the client's endpoints are matched, ignore the request as the client is gone if (!client_matched_status_.is_fully_unmatched(client_guid_prefix)) { - request_reply_info("Ignoring request from already gone client " << client_guid_prefix); + request_reply_info("ServerApp", "Ignoring request from already gone client " << client_guid_prefix); continue; } // If the request's client is not fully matched, save it for later if (!client_matched_status_.is_matched(client_guid_prefix)) { - request_reply_debug("Client " << client_guid_prefix << " not fully matched, saving request for later"); + request_reply_debug("ServerApp", + "Client " << client_guid_prefix << " not fully matched, saving request for later"); requests_.push(request); } @@ -369,7 +372,8 @@ void ServerApp::reply_routine() // If the calculation fails, ignore the request, as the failure cause is a malformed request if (!calculate(*request.request, result)) { - request_reply_error("Failed to calculate result for request from client " << client_guid_prefix); + request_reply_error("ServerApp", + "Failed to calculate result for request from client " << client_guid_prefix); continue; } @@ -388,14 +392,15 @@ void ServerApp::reply_routine() if (!reply_writer_->write(&reply, write_params)) { // In case of failure, save the request for a later retry - request_reply_error( - "Failed to send reply to request with ID '" << request_id << "' to client " << client_guid_prefix); + request_reply_error("ServerApp", + "Failed to send reply to request with ID '" << request_id << "' to client " << + client_guid_prefix); requests_.push(request); } else { - request_reply_info( - "Reply to request with ID '" << request_id << "' sent to client " << client_guid_prefix); + request_reply_info("ServerApp", + "Reply to request with ID '" << request_id << "' sent to client " << client_guid_prefix); } } } @@ -428,7 +433,7 @@ bool ServerApp::calculate( { if (0 == request.y()) { - request_reply_error("Division by zero request received"); + request_reply_error("ServerApp", "Division by zero request received"); success = false; } else @@ -439,7 +444,7 @@ bool ServerApp::calculate( } default: { - request_reply_error("Unknown operation received"); + request_reply_error("ServerApp", "Unknown operation received"); success = false; break; } diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index d022e2a3de5..276d85b93fc 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -297,20 +297,20 @@ struct Timestamp }; #ifndef NDEGUB -#define request_reply_debug(message) \ - std::cout << C_B_WHITE << Timestamp::now() << C_B_BLUE << " [DEBUG] " << C_DEF \ - << C_WHITE << message << C_DEF << std::endl +#define request_reply_debug(context, message) \ + std::cout << C_B_WHITE << Timestamp::now() << C_B_BLUE << " [DEBUG] " << C_B_WHITE \ + << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl #else -#define request_reply_debug(message) +#define request_reply_debug(context, message) #endif // ifdef NDEGUB -#define request_reply_info(message) \ - std::cout << C_B_WHITE << Timestamp::now() << C_B_GREEN << " [INFO] " << C_DEF \ - << C_WHITE << message << C_DEF << std::endl +#define request_reply_info(context, message) \ + std::cout << C_B_WHITE << Timestamp::now() << C_B_GREEN << " [INFO] " << C_B_WHITE \ + << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl -#define request_reply_error(message) \ - std::cerr << C_B_WHITE << Timestamp::now() << C_B_RED << " [ERROR] " << C_DEF \ - << C_WHITE << message << C_DEF << std::endl +#define request_reply_error(context, message) \ + std::cerr << C_B_WHITE << Timestamp::now() << C_B_RED << " [ERROR] " << C_B_WHITE \ + << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl } // namespace request_reply } // namespace examples diff --git a/examples/cpp/request_reply/main.cpp b/examples/cpp/request_reply/main.cpp index c0d01e3e400..f17b7b70fb1 100644 --- a/examples/cpp/request_reply/main.cpp +++ b/examples/cpp/request_reply/main.cpp @@ -58,7 +58,7 @@ int main( } catch (const std::runtime_error& e) { - request_reply_error(e.what()); + request_reply_error("main", e.what()); ret = EXIT_FAILURE; } @@ -68,8 +68,8 @@ int main( stop_app_handler = [&](int signum) { - request_reply_info( - CLIParser::parse_signal(signum) << " received, stopping " << app_name << " execution."); + request_reply_info("main", + CLIParser::parse_signal(signum) << " received, stopping " << app_name << " execution."); app->stop(); }; @@ -81,7 +81,8 @@ int main( signal(SIGHUP, signal_handler); #endif // _WIN32 - request_reply_info(app_name << " running. Please press Ctrl+C to stop the " << app_name << " at any time."); + request_reply_info("main", + app_name << " running. Please press Ctrl+C to stop the " << app_name << " at any time."); thread.join(); } From e8b09f87799e90bb71b3244af36b21061194d7a2 Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 15:59:40 +0200 Subject: [PATCH 26/46] Refs #21188: Add tests Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 3 +- examples/cpp/request_reply/app_utils.hpp | 6 +- ...st_reply.xml => request_reply_profile.xml} | 0 test/examples/request_reply.compose.yml | 41 +++++++ .../request_reply_isolated.compose.yml | 105 ++++++++++++++++++ test/examples/test_request_reply.py | 58 ++++++++++ test/examples/test_request_reply_isolated.py | 62 +++++++++++ 7 files changed, 271 insertions(+), 4 deletions(-) rename examples/cpp/request_reply/{request_reply.xml => request_reply_profile.xml} (100%) create mode 100644 test/examples/request_reply.compose.yml create mode 100644 test/examples/request_reply_isolated.compose.yml create mode 100644 test/examples/test_request_reply.py create mode 100644 test/examples/test_request_reply_isolated.py diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index c09ef94c379..0f67f2182c9 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -347,7 +347,8 @@ bool ClientApp::send_request() bool ret = request_writer_->write(&request, wparams); request_reply_info("ClientApp", - "Request sent with ID '" << wparams.sample_identity().sequence_number() << "': '" << request_input_.str()); + "Request sent with ID '" << wparams.sample_identity().sequence_number() << + "': '" << request_input_.str() << "'"); return ret; } diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index 276d85b93fc..d655299e489 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -299,18 +299,18 @@ struct Timestamp #ifndef NDEGUB #define request_reply_debug(context, message) \ std::cout << C_B_WHITE << Timestamp::now() << C_B_BLUE << " [DEBUG] " << C_B_WHITE \ - << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl + << "[" << context << "] " << C_DEF << message << std::endl #else #define request_reply_debug(context, message) #endif // ifdef NDEGUB #define request_reply_info(context, message) \ std::cout << C_B_WHITE << Timestamp::now() << C_B_GREEN << " [INFO] " << C_B_WHITE \ - << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl + << "[" << context << "] " << C_DEF << message << std::endl #define request_reply_error(context, message) \ std::cerr << C_B_WHITE << Timestamp::now() << C_B_RED << " [ERROR] " << C_B_WHITE \ - << "[" << context << "] " << C_DEF << C_WHITE << message << C_DEF << std::endl + << "[" << context << "] " << C_DEF << message << std::endl } // namespace request_reply } // namespace examples diff --git a/examples/cpp/request_reply/request_reply.xml b/examples/cpp/request_reply/request_reply_profile.xml similarity index 100% rename from examples/cpp/request_reply/request_reply.xml rename to examples/cpp/request_reply/request_reply_profile.xml diff --git a/test/examples/request_reply.compose.yml b/test/examples/request_reply.compose.yml new file mode 100644 index 00000000000..3f006d43c92 --- /dev/null +++ b/test/examples/request_reply.compose.yml @@ -0,0 +1,41 @@ +# Copyright 2024 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. +version: "3" + +services: + server-client: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 1 + 1 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + + client: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 x 3" diff --git a/test/examples/request_reply_isolated.compose.yml b/test/examples/request_reply_isolated.compose.yml new file mode 100644 index 00000000000..43418933cd8 --- /dev/null +++ b/test/examples/request_reply_isolated.compose.yml @@ -0,0 +1,105 @@ +# Copyright 2024 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. +version: "3" + +services: + server-1: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + + server-2: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + + client-1: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 + 3" + depends_on: + - server-1 + - server-2 + + client-2: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 3 - 2" + depends_on: + - server-1 + - server-2 + + client-3: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 3 x 2" + depends_on: + - server-1 + - server-2 + + client-4: + image: @DOCKER_IMAGE_NAME@ + volumes: + - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ + - @fastcdr_LIB_DIR@:@fastcdr_LIB_DIR@ + @TINYXML2_LIB_DIR_COMPOSE_VOLUME@ + environment: + # TODO(eduponz): LD_LIBRARY_PATH is not the correct variable for Windows + LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ + EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ + FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 20 / 5" + depends_on: + - server-1 + - server-2 diff --git a/test/examples/test_request_reply.py b/test/examples/test_request_reply.py new file mode 100644 index 00000000000..362a38b2cc9 --- /dev/null +++ b/test/examples/test_request_reply.py @@ -0,0 +1,58 @@ +# Copyright 2024 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. + +import subprocess + +def test_request_reply(): + """.""" + expected_responses = { + 'request_reply-server-client-1': 2, + 'request_reply-client-1': 6 + } + + responses = { + 'request_reply-server-client-1': None, + 'request_reply-client-1': None, + } + + ret = True + out = '' + + try: + out = subprocess.check_output( + '/usr/bin/docker compose -f request_reply.compose.yml up', + stderr=subprocess.STDOUT, + shell=True, + timeout=30 + ).decode().split('\n') + + for line in out: + for client in expected_responses: + if client in line and 'Reply received from server' in line: + responses[client] = int(line.rstrip().split(' ')[-1]) + + for client in responses: + if responses[client] != expected_responses[client]: + ret = False + print('ERROR: ' + client + ' expected "' + expected_responses[client] + '" but received "' + responses[client] + '"') + raise subprocess.CalledProcessError(1, '') + + except subprocess.CalledProcessError: + for l in out: + print(l) + except subprocess.TimeoutExpired: + print('TIMEOUT') + print(out) + + assert(ret) diff --git a/test/examples/test_request_reply_isolated.py b/test/examples/test_request_reply_isolated.py new file mode 100644 index 00000000000..c706c819583 --- /dev/null +++ b/test/examples/test_request_reply_isolated.py @@ -0,0 +1,62 @@ +# Copyright 2024 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. + +import subprocess + +def test_request_reply_isolated(): + """.""" + expected_responses = { + 'request_reply_isolated-client-1-1': 5, + 'request_reply_isolated-client-2-1': 1, + 'request_reply_isolated-client-3-1': 6, + 'request_reply_isolated-client-4-1': 4 + } + + responses = { + 'request_reply_isolated-client-1-1': None, + 'request_reply_isolated-client-2-1': None, + 'request_reply_isolated-client-3-1': None, + 'request_reply_isolated-client-4-1': None + } + + ret = True + out = '' + + try: + out = subprocess.check_output( + '/usr/bin/docker compose -f request_reply_isolated.compose.yml up', + stderr=subprocess.STDOUT, + shell=True, + timeout=30 + ).decode().split('\n') + + for line in out: + for client in expected_responses: + if client in line and 'Reply received from server' in line: + responses[client] = int(line.rstrip().split(' ')[-1]) + + for client in responses: + if responses[client] != expected_responses[client]: + ret = False + print('ERROR: ' + client + ' expected "' + expected_responses[client] + '" but received "' + responses[client] + '"') + raise subprocess.CalledProcessError(1, '') + + except subprocess.CalledProcessError: + for l in out: + print(l) + except subprocess.TimeoutExpired: + print('TIMEOUT') + print(out) + + assert(ret) From 7a3f1cc12813f6f5b9e8f860866041bb3a37e46a Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 16:30:50 +0200 Subject: [PATCH 27/46] Refs #21188: Add README.md Signed-off-by: eduponz --- examples/cpp/request_reply/README.md | 105 +++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/examples/cpp/request_reply/README.md b/examples/cpp/request_reply/README.md index 47d94118beb..3ddb1b8d355 100644 --- a/examples/cpp/request_reply/README.md +++ b/examples/cpp/request_reply/README.md @@ -1 +1,106 @@ # Request-Reply example + +The *eProsima Fast DDS Request-Reply* example shows how to create a service oriented architecture using the *Request-Reply* communication pattern over Fast DDS. + +This example is part of the suite of examples designed by eProsima that aims to illustrate the features and possible configurations of DDS deployments through *eProsima Fast DDS*. + +This *request_reply* example shows a simple approach for a multi-server multi-client architecture, where servers are both prepared to reply to several clients, and also to be run alongside other server instances (to provide redundancy). +In this example, the clients take one "calculator" operation as input, and exit as soon as any of the servers has provided a response for their request. + +* [Description of the example](#description-of-the-example) +* [Run the example](#run-the-example) +* [XML profile playground](#xml-profile-playground) + +## Description of the example + +The RPC like communication pattern is implemented using a pair of related topics, one for the request and one for the reply. +The approach creates the following data flow for a request-reply operation: + +```mermaid +sequenceDiagram +participant Client +participant Client Request Writer +participant Client Reply Reader +participant Server +participant Server Request Reader +participant Server Reply Writer + +Client->>Client: Wait for server availability +Client->>Client Request Writer: request +Client Request Writer->>Server Request Reader: request +Server Request Reader->>Server: calculate response +Server->>Server Reply Writer: response +Server Reply Writer->>Client Reply Reader: response +Client Reply Reader->>Client: response +``` + +## Run the example + +To launch this example, two different terminals are required. +One of them will run the server application, and the other will run the client application. +Mind that it is possible to run multiple server instances and client instances simultaneously. + +### Server + +* Ubuntu ( / MacOS ) + + ```shell + user@machine:example_path$ ./request_reply server + 2024-07-01T16:26:45.314 [INFO] [ServerApp] Server initialized with ID: 01.0f.cc.6d.01.3d.fd.74.00.00.00.00 + 2024-07-01T16:26:45.315 [INFO] [main] Server running. Please press Ctrl+C to stop the Server at any time. + ``` + +* Windows + + ```powershell + example_path> request_reply.exe server + 2024-07-01T16:26:45.314 [INFO] [ServerApp] Server initialized with ID: 01.0f.cc.6d.01.3d.fd.74.00.00.00.00 + 2024-07-01T16:26:45.315 [INFO] [main] Server running. Please press Ctrl+C to stop the Server at any time. + ``` + +### Client + +* Ubuntu ( / MacOS ) + + ```shell + user@machine:example_path$ ./request_reply client 2 x 5 + 2024-07-01T16:08:28.296 [INFO] [ClientApp] Client initialized with ID: 01.0f.cc.6d.21.0f.f0.6b.00.00.00.00 + 2024-07-01T16:08:28.296 [INFO] [main] Client running. Please press Ctrl+C to stop the Client at any time. + 2024-07-01T16:08:29.296 [INFO] [ClientApp] Request sent with ID '1': '2 x 5' + 2024-07-01T16:08:29.297 [INFO] [ClientApp] Reply received from server 01.0f.cc.6d.92.0e.de.f0.00.00.00.00 with result: 10 + ``` + +* Windows + + ```powershell + example_path> request_reply.exe client 2 x 5 + 2024-07-01T16:08:28.296 [INFO] [ClientApp] Client initialized with ID: 01.0f.cc.6d.21.0f.f0.6b.00.00.00.00 + 2024-07-01T16:08:28.296 [INFO] [main] Client running. Please press Ctrl+C to stop the Client at any time. + 2024-07-01T16:08:29.296 [INFO] [ClientApp] Request sent with ID '1': '2 x 5' + 2024-07-01T16:08:29.297 [INFO] [ClientApp] Reply received from server 01.0f.cc.6d.92.0e.de.f0.00.00.00.00 with result: 10 + ``` + +## XML profile playground + +The *eProsima Fast DDS* entities can be configured through an XML profile from the environment. +This is accomplished by setting the environment variable ``FASTDDS_DEFAULT_PROFILES_FILE`` to path to the XML profiles file: + +* Ubuntu ( / MacOS ) + + ```shell + user@machine:example_path$ export FASTDDS_DEFAULT_PROFILES_FILE=request_reply_profile.xml + ``` + +* Windows + + ```powershell + example_path> set FASTDDS_DEFAULT_PROFILES_FILE=request_reply_profile.xml + ``` + +The example provides with an XML profiles files with certain QoS to ensure correct reception of the requests and replies. + +- Reliable reliability: avoid sample loss. +- Transient local durability: enable late-join subscriber applications to receive previous samples. +- Keep-last history with high depth: ensure certain amount of previous samples for late-joiners. + +Applying different configurations to the entities will change to a greater or lesser extent how the application behaves in relation to sample management. From e3baa96e29aae04a6e65d6e290ef53aed90938ce Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 16:31:39 +0200 Subject: [PATCH 28/46] Refs #21188: Add versions Signed-off-by: eduponz --- versions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/versions.md b/versions.md index ce47dc7df7c..997cec7f404 100644 --- a/versions.md +++ b/versions.md @@ -55,6 +55,7 @@ Forthcoming * Custom Content filter example * Delivery mechanisms example with SHM, UDP, TCP, data-sharing and intra-process mechanisms. * Discovery server example. + * Request-reply example to showcase RPC paradigms over Fast DDS. * Removed `TypeConsistencyQos` from DataReader, and included `TypeConsistencyEnforcementQosPolicy` and `DataRepresentationQosPolicy` * Added new `flow_controller_descriptor_list` XML configuration, remove `ThroughtputController`. * Migrate `#define`s within `BuiltinEndpoints.hpp` to namespaced `constexpr` variables. From 412dfe50a1c2de404dd7b64c465054171b9f87d4 Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 1 Jul 2024 16:32:06 +0200 Subject: [PATCH 29/46] Refs #21188: Remove old example Signed-off-by: eduponz --- .../dds/RequestReplyExample/CMakeLists.txt | 71 --- .../dds/RequestReplyExample/Calculator.hpp | 386 ---------------- .../dds/RequestReplyExample/Calculator.idl | 19 - .../RequestReplyExample/CalculatorCdrAux.hpp | 53 --- .../RequestReplyExample/CalculatorCdrAux.ipp | 210 --------- .../RequestReplyExample/CalculatorClient.cpp | 267 ----------- .../CalculatorPubSubTypes.cxx | 422 ------------------ .../CalculatorPubSubTypes.hpp | 224 ---------- .../RequestReplyExample/CalculatorServer.cpp | 203 --------- .../CalculatorTypeObjectSupport.cxx | 284 ------------ .../CalculatorTypeObjectSupport.hpp | 80 ---- .../cpp/dds/RequestReplyExample/README.md | 10 - 12 files changed, 2229 deletions(-) delete mode 100644 examples/cpp/dds/RequestReplyExample/CMakeLists.txt delete mode 100644 examples/cpp/dds/RequestReplyExample/Calculator.hpp delete mode 100644 examples/cpp/dds/RequestReplyExample/Calculator.idl delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.hpp delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.ipp delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorClient.cpp delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.cxx delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.hpp delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorServer.cpp delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.cxx delete mode 100644 examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.hpp delete mode 100644 examples/cpp/dds/RequestReplyExample/README.md diff --git a/examples/cpp/dds/RequestReplyExample/CMakeLists.txt b/examples/cpp/dds/RequestReplyExample/CMakeLists.txt deleted file mode 100644 index a3efdf02707..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2022 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. - -cmake_minimum_required(VERSION 3.20) - -project(RequestReplyExample VERSION 1 LANGUAGES CXX) - -# Find requirements -if(NOT fastcdr_FOUND) - find_package(fastcdr 2 REQUIRED) -endif() - -if(NOT fastdds_FOUND) - find_package(fastdds 3 REQUIRED) -endif() - -#Check C++11 -include(CheckCXXCompilerFlag) -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11) - if(NOT SUPPORTS_CXX11) - message(FATAL_ERROR "Compiler doesn't support C++11") - endif() -endif() - -message(STATUS "Configuring Request-Reply example...") -set(DDS_REQUEST_REPLY_EXAMPLE_COMMON_SOURCES - CalculatorPubSubTypes.cxx - CalculatorTypeObjectSupport.cxx - ) -set( DDS_REQUEST_REPLY_EXAMPLE_CLIENT_SOURCES - CalculatorClient.cpp - ) -set( DDS_REQUEST_REPLY_EXAMPLE_SERVER_SOURCES - CalculatorServer.cpp - ) - -add_executable(DDSCalculatorClient - ${DDS_REQUEST_REPLY_EXAMPLE_COMMON_SOURCES} - ${DDS_REQUEST_REPLY_EXAMPLE_CLIENT_SOURCES} - ) -target_compile_definitions(DDSCalculatorClient PRIVATE - $<$>,$>:__DEBUG> - $<$:__INTERNALDEBUG> # Internal debug activated. -) -target_link_libraries(DDSCalculatorClient fastdds fastcdr) -install(TARGETS DDSCalculatorClient - RUNTIME DESTINATION examples/cpp/dds/RequestReplyExample/${BIN_INSTALL_DIR}) - -add_executable(DDSCalculatorServer - ${DDS_REQUEST_REPLY_EXAMPLE_COMMON_SOURCES} - ${DDS_REQUEST_REPLY_EXAMPLE_SERVER_SOURCES} - ) -target_compile_definitions(DDSCalculatorServer PRIVATE - $<$>,$>:__DEBUG> - $<$:__INTERNALDEBUG> # Internal debug activated. -) -target_link_libraries(DDSCalculatorServer fastdds fastcdr) -install(TARGETS DDSCalculatorServer - RUNTIME DESTINATION examples/cpp/dds/RequestReplyExample/${BIN_INSTALL_DIR}) diff --git a/examples/cpp/dds/RequestReplyExample/Calculator.hpp b/examples/cpp/dds/RequestReplyExample/Calculator.hpp deleted file mode 100644 index 96e6c550547..00000000000 --- a/examples/cpp/dds/RequestReplyExample/Calculator.hpp +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file Calculator.hpp - * This header file contains the declaration of the described types in the IDL file. - * - * This file was generated by the tool fastddsgen. - */ - -#ifndef FAST_DDS_GENERATED__CALCULATOR_HPP -#define FAST_DDS_GENERATED__CALCULATOR_HPP - -#include -#include - -#if defined(_WIN32) -#if defined(EPROSIMA_USER_DLL_EXPORT) -#define eProsima_user_DllExport __declspec( dllexport ) -#else -#define eProsima_user_DllExport -#endif // EPROSIMA_USER_DLL_EXPORT -#else -#define eProsima_user_DllExport -#endif // _WIN32 - -#if defined(_WIN32) -#if defined(EPROSIMA_USER_DLL_EXPORT) -#if defined(CALCULATOR_SOURCE) -#define CALCULATOR_DllAPI __declspec( dllexport ) -#else -#define CALCULATOR_DllAPI __declspec( dllimport ) -#endif // CALCULATOR_SOURCE -#else -#define CALCULATOR_DllAPI -#endif // EPROSIMA_USER_DLL_EXPORT -#else -#define CALCULATOR_DllAPI -#endif // _WIN32 - -/*! - * @brief This class represents the enumeration OperationType defined by the user in the IDL file. - * @ingroup Calculator - */ -enum class OperationType : int32_t -{ - ADDITION, - SUBTRACTION, - MULTIPLICATION, - DIVISION -}; -/*! - * @brief This class represents the structure RequestType defined by the user in the IDL file. - * @ingroup Calculator - */ -class RequestType -{ -public: - - /*! - * @brief Default constructor. - */ - eProsima_user_DllExport RequestType() - { - } - - /*! - * @brief Default destructor. - */ - eProsima_user_DllExport ~RequestType() - { - } - - /*! - * @brief Copy constructor. - * @param x Reference to the object RequestType that will be copied. - */ - eProsima_user_DllExport RequestType( - const RequestType& x) - { - m_operation = x.m_operation; - - m_x = x.m_x; - - m_y = x.m_y; - - } - - /*! - * @brief Move constructor. - * @param x Reference to the object RequestType that will be copied. - */ - eProsima_user_DllExport RequestType( - RequestType&& x) noexcept - { - m_operation = x.m_operation; - m_x = x.m_x; - m_y = x.m_y; - } - - /*! - * @brief Copy assignment. - * @param x Reference to the object RequestType that will be copied. - */ - eProsima_user_DllExport RequestType& operator =( - const RequestType& x) - { - - m_operation = x.m_operation; - - m_x = x.m_x; - - m_y = x.m_y; - - return *this; - } - - /*! - * @brief Move assignment. - * @param x Reference to the object RequestType that will be copied. - */ - eProsima_user_DllExport RequestType& operator =( - RequestType&& x) noexcept - { - - m_operation = x.m_operation; - m_x = x.m_x; - m_y = x.m_y; - return *this; - } - - /*! - * @brief Comparison operator. - * @param x RequestType object to compare. - */ - eProsima_user_DllExport bool operator ==( - const RequestType& x) const - { - return (m_operation == x.m_operation && - m_x == x.m_x && - m_y == x.m_y); - } - - /*! - * @brief Comparison operator. - * @param x RequestType object to compare. - */ - eProsima_user_DllExport bool operator !=( - const RequestType& x) const - { - return !(*this == x); - } - - /*! - * @brief This function sets a value in member operation - * @param _operation New value for member operation - */ - eProsima_user_DllExport void operation( - OperationType _operation) - { - m_operation = _operation; - } - - /*! - * @brief This function returns the value of member operation - * @return Value of member operation - */ - eProsima_user_DllExport OperationType operation() const - { - return m_operation; - } - - /*! - * @brief This function returns a reference to member operation - * @return Reference to member operation - */ - eProsima_user_DllExport OperationType& operation() - { - return m_operation; - } - - - /*! - * @brief This function sets a value in member x - * @param _x New value for member x - */ - eProsima_user_DllExport void x( - int32_t _x) - { - m_x = _x; - } - - /*! - * @brief This function returns the value of member x - * @return Value of member x - */ - eProsima_user_DllExport int32_t x() const - { - return m_x; - } - - /*! - * @brief This function returns a reference to member x - * @return Reference to member x - */ - eProsima_user_DllExport int32_t& x() - { - return m_x; - } - - - /*! - * @brief This function sets a value in member y - * @param _y New value for member y - */ - eProsima_user_DllExport void y( - int32_t _y) - { - m_y = _y; - } - - /*! - * @brief This function returns the value of member y - * @return Value of member y - */ - eProsima_user_DllExport int32_t y() const - { - return m_y; - } - - /*! - * @brief This function returns a reference to member y - * @return Reference to member y - */ - eProsima_user_DllExport int32_t& y() - { - return m_y; - } - - - -private: - - OperationType m_operation{OperationType::ADDITION}; - int32_t m_x{0}; - int32_t m_y{0}; - -}; -/*! - * @brief This class represents the structure ReplyType defined by the user in the IDL file. - * @ingroup Calculator - */ -class ReplyType -{ -public: - - /*! - * @brief Default constructor. - */ - eProsima_user_DllExport ReplyType() - { - } - - /*! - * @brief Default destructor. - */ - eProsima_user_DllExport ~ReplyType() - { - } - - /*! - * @brief Copy constructor. - * @param x Reference to the object ReplyType that will be copied. - */ - eProsima_user_DllExport ReplyType( - const ReplyType& x) - { - m_z = x.m_z; - - } - - /*! - * @brief Move constructor. - * @param x Reference to the object ReplyType that will be copied. - */ - eProsima_user_DllExport ReplyType( - ReplyType&& x) noexcept - { - m_z = x.m_z; - } - - /*! - * @brief Copy assignment. - * @param x Reference to the object ReplyType that will be copied. - */ - eProsima_user_DllExport ReplyType& operator =( - const ReplyType& x) - { - - m_z = x.m_z; - - return *this; - } - - /*! - * @brief Move assignment. - * @param x Reference to the object ReplyType that will be copied. - */ - eProsima_user_DllExport ReplyType& operator =( - ReplyType&& x) noexcept - { - - m_z = x.m_z; - return *this; - } - - /*! - * @brief Comparison operator. - * @param x ReplyType object to compare. - */ - eProsima_user_DllExport bool operator ==( - const ReplyType& x) const - { - return (m_z == x.m_z); - } - - /*! - * @brief Comparison operator. - * @param x ReplyType object to compare. - */ - eProsima_user_DllExport bool operator !=( - const ReplyType& x) const - { - return !(*this == x); - } - - /*! - * @brief This function sets a value in member z - * @param _z New value for member z - */ - eProsima_user_DllExport void z( - int64_t _z) - { - m_z = _z; - } - - /*! - * @brief This function returns the value of member z - * @return Value of member z - */ - eProsima_user_DllExport int64_t z() const - { - return m_z; - } - - /*! - * @brief This function returns a reference to member z - * @return Reference to member z - */ - eProsima_user_DllExport int64_t& z() - { - return m_z; - } - - - -private: - - int64_t m_z{0}; - -}; - -#endif // _FAST_DDS_GENERATED_CALCULATOR_HPP_ - - diff --git a/examples/cpp/dds/RequestReplyExample/Calculator.idl b/examples/cpp/dds/RequestReplyExample/Calculator.idl deleted file mode 100644 index a998fb63bbc..00000000000 --- a/examples/cpp/dds/RequestReplyExample/Calculator.idl +++ /dev/null @@ -1,19 +0,0 @@ -enum OperationType -{ - ADDITION, - SUBTRACTION, - MULTIPLICATION, - DIVISION -}; - -struct RequestType -{ - OperationType operation; - long x; - long y; -}; - -struct ReplyType -{ - long long z; -}; diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.hpp b/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.hpp deleted file mode 100644 index a9afaef8f47..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorCdrAux.hpp - * This source file contains some definitions of CDR related functions. - * - * This file was generated by the tool fastddsgen. - */ - -#ifndef FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP -#define FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP - -#include "Calculator.hpp" - -constexpr uint32_t ReplyType_max_cdr_typesize {16UL}; -constexpr uint32_t ReplyType_max_key_cdr_typesize {0UL}; - -constexpr uint32_t RequestType_max_cdr_typesize {16UL}; -constexpr uint32_t RequestType_max_key_cdr_typesize {0UL}; - - -namespace eprosima { -namespace fastcdr { - -class Cdr; -class CdrSizeCalculator; - -eProsima_user_DllExport void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const RequestType& data); - -eProsima_user_DllExport void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const ReplyType& data); - - -} // namespace fastcdr -} // namespace eprosima - -#endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_HPP - diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.ipp b/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.ipp deleted file mode 100644 index d46633a3c92..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorCdrAux.ipp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorCdrAux.ipp - * This source file contains some declarations of CDR related functions. - * - * This file was generated by the tool fastddsgen. - */ - -#ifndef FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP -#define FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP - -#include "CalculatorCdrAux.hpp" - -#include -#include - - -#include -using namespace eprosima::fastcdr::exception; - -namespace eprosima { -namespace fastcdr { - -template<> -eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const RequestType& data, - size_t& current_alignment) -{ - static_cast(data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size {calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment)}; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.operation(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), - data.x(), current_alignment); - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), - data.y(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; -} - -template<> -eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const RequestType& data) -{ - eprosima::fastcdr::Cdr::state current_state(scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.operation() - << eprosima::fastcdr::MemberId(1) << data.x() - << eprosima::fastcdr::MemberId(2) << data.y() -; - scdr.end_serialize_type(current_state); -} - -template<> -eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - RequestType& data) -{ - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool - { - bool ret_value = true; - switch (mid.id) - { - case 0: - dcdr >> data.operation(); - break; - - case 1: - dcdr >> data.x(); - break; - - case 2: - dcdr >> data.y(); - break; - - default: - ret_value = false; - break; - } - return ret_value; - }); -} - -void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const RequestType& data) -{ - static_cast(scdr); - static_cast(data); -} - - -template<> -eProsima_user_DllExport size_t calculate_serialized_size( - eprosima::fastcdr::CdrSizeCalculator& calculator, - const ReplyType& data, - size_t& current_alignment) -{ - static_cast(data); - - eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); - size_t calculated_size {calculator.begin_calculate_type_serialized_size( - eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - current_alignment)}; - - - calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), - data.z(), current_alignment); - - - calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); - - return calculated_size; -} - -template<> -eProsima_user_DllExport void serialize( - eprosima::fastcdr::Cdr& scdr, - const ReplyType& data) -{ - eprosima::fastcdr::Cdr::state current_state(scdr); - scdr.begin_serialize_type(current_state, - eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); - - scdr - << eprosima::fastcdr::MemberId(0) << data.z() -; - scdr.end_serialize_type(current_state); -} - -template<> -eProsima_user_DllExport void deserialize( - eprosima::fastcdr::Cdr& cdr, - ReplyType& data) -{ - cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, - [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool - { - bool ret_value = true; - switch (mid.id) - { - case 0: - dcdr >> data.z(); - break; - - default: - ret_value = false; - break; - } - return ret_value; - }); -} - -void serialize_key( - eprosima::fastcdr::Cdr& scdr, - const ReplyType& data) -{ - static_cast(scdr); - static_cast(data); -} - - - -} // namespace fastcdr -} // namespace eprosima - -#endif // FAST_DDS_GENERATED__CALCULATORCDRAUX_IPP - diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorClient.cpp b/examples/cpp/dds/RequestReplyExample/CalculatorClient.cpp deleted file mode 100644 index 84d4334d519..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorClient.cpp +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright 2022 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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CalculatorPubSubTypes.hpp" - -class CalculatorClient -{ - class Listener : public eprosima::fastdds::dds::DataReaderListener - { - public: - - void on_data_available( - eprosima::fastdds::dds::DataReader* reader) override - { - ReplyType reply; - eprosima::fastdds::dds::SampleInfo sample_info; - - reader->take_next_sample(&reply, &sample_info); - - if (eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == sample_info.instance_state) - { - if (sample_info.related_sample_identity == write_params.sample_identity()) - { - { - std::unique_lock lock(reception_mutex); - received_reply = true; - z = reply.z(); - } - reception_cv.notify_one(); - } - } - } - - eprosima::fastdds::rtps::WriteParams write_params; - - // Structures for waiting reply - std::mutex reception_mutex; - std::condition_variable reception_cv; - bool received_reply = false; - int64_t z = 0; - - } - listener_; - -public: - - bool init() - { - participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, - eprosima::fastdds::dds::PARTICIPANT_QOS_DEFAULT); - - if (nullptr == participant_) - { - return false; - } - - request_type_ = eprosima::fastdds::dds::TypeSupport(new RequestTypePubSubType()); - reply_type_ = eprosima::fastdds::dds::TypeSupport(new ReplyTypePubSubType()); - - participant_->register_type(request_type_); - participant_->register_type(reply_type_); - - publisher_ = participant_->create_publisher(eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT); - - if (nullptr == publisher_) - { - return false; - } - - subscriber_ = participant_->create_subscriber(eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT); - - if (nullptr == subscriber_) - { - return false; - } - - request_topic_ = participant_->create_topic("CalculatorRequest", - request_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); - - if (nullptr == request_topic_) - { - return false; - } - - reply_topic_ = participant_->create_topic("CalculatorReply", - reply_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); - - if (nullptr == reply_topic_) - { - return false; - } - - request_writer_ = publisher_->create_datawriter(request_topic_, eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT); - - if (nullptr == request_writer_) - { - return false; - } - - eprosima::fastdds::dds::DataReaderQos reader_qos; - reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; - reader_qos.history().kind = eprosima::fastdds::dds::KEEP_ALL_HISTORY_QOS; - reply_reader_ = subscriber_->create_datareader(reply_topic_, reader_qos, &listener_); - - if (nullptr == reply_reader_) - { - return false; - } - - return true; - } - - void deinit() - { - if (nullptr != participant_) - { - participant_->delete_contained_entities(); - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(participant_); - } - } - - int64_t request( - OperationType operation, - int32_t x, - int32_t y) - { - int64_t z = 0; - RequestType request; - request.operation(operation); - request.x(x); - request.y(y); - - if (eprosima::fastdds::dds::RETCODE_OK == - request_writer_->write(static_cast(&request), listener_.write_params)) - { - std::unique_lock lock(listener_.reception_mutex); - listener_.reception_cv.wait(lock, [&]() - { - return listener_.received_reply; - }); - z = listener_.z; - } - else - { - std::cerr << "Error writing the request" << std::endl; - } - - return z; - } - -private: - - eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; - - eprosima::fastdds::dds::Publisher* publisher_ = nullptr; - - eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; - - eprosima::fastdds::dds::Topic* request_topic_ = nullptr; - - eprosima::fastdds::dds::Topic* reply_topic_ = nullptr; - - eprosima::fastdds::dds::DataWriter* request_writer_ = nullptr; - - eprosima::fastdds::dds::DataReader* reply_reader_ = nullptr; - - eprosima::fastdds::dds::TypeSupport request_type_; - - eprosima::fastdds::dds::TypeSupport reply_type_; -}; - -void print_help() -{ - std::cout << "Usage: CalculatorClient <+|-|x|/> " << std::endl; -} - -int main( - int argc, - char** argv) -{ - argc -= (argc > 0); - argv += (argc > 0); // skip program name argv[0] if present - - if (3 != argc) - { - print_help(); - return -1; - } - - int32_t x; - int32_t y; - OperationType operation; - char* endptr = 0; - - x = strtol(argv[0], &endptr, 10); - if (endptr == argv[0] || *endptr != 0) - { - std::cerr << "Error reading numeric argument x." << std::endl; - print_help(); - return -1; - } - - if (0 == strcmp(argv[1], "+")) - { - operation = OperationType::ADDITION; - } - else if (0 == strcmp(argv[1], "-")) - { - operation = OperationType::SUBTRACTION; - } - else if (0 == strcmp(argv[1], "x")) - { - operation = OperationType::MULTIPLICATION; - } - else if (0 == strcmp(argv[1], "/")) - { - operation = OperationType::DIVISION; - } - else - { - std::cerr << "Error reading operation argument. Valid values: <+|-|x|/>" << std::endl; - print_help(); - return -1; - } - - y = strtol(argv[2], &endptr, 10); - if (endptr == argv[2] || *endptr != 0) - { - std::cerr << "Error reading numeric argument y." << std::endl; - print_help(); - return -1; - } - - CalculatorClient client; - client.init(); - int64_t z = client.request(operation, x, y); - - std::cout << "Result: " << argv[0] << " " << argv[1] << " " << argv[2] << " = " << z << std::endl; - - client.deinit(); - - return 0; -} diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.cxx b/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.cxx deleted file mode 100644 index 754dcb694bf..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.cxx +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorPubSubTypes.cpp - * This header file contains the implementation of the serialization functions. - * - * This file was generated by the tool fastddsgen. - */ - -#include "CalculatorPubSubTypes.hpp" - -#include -#include - -#include "CalculatorCdrAux.hpp" -#include "CalculatorTypeObjectSupport.hpp" - -using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; -using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; -using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; - -RequestTypePubSubType::RequestTypePubSubType() -{ - setName("RequestType"); - uint32_t type_size = -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(RequestType::getMaxCdrSerializedSize()); -#else - RequestType_max_cdr_typesize; -#endif - type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ - m_typeSize = type_size + 4; /*encapsulation*/ - m_isGetKeyDefined = false; - uint32_t keyLength = RequestType_max_key_cdr_typesize > 16 ? RequestType_max_key_cdr_typesize : 16; - m_keyBuffer = reinterpret_cast(malloc(keyLength)); - memset(m_keyBuffer, 0, keyLength); -} - -RequestTypePubSubType::~RequestTypePubSubType() -{ - if (m_keyBuffer != nullptr) - { - free(m_keyBuffer); - } -} - -bool RequestTypePubSubType::serialize( - const void* const data, - SerializedPayload_t* payload, - DataRepresentationId_t data_representation) -{ - const RequestType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); - payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; -#if FASTCDR_VERSION_MAJOR > 1 - ser.set_encoding_flag( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); -#endif // FASTCDR_VERSION_MAJOR > 1 - - try - { - // Serialize encapsulation - ser.serialize_encapsulation(); - // Serialize the object. - ser << *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - // Get the serialized length -#if FASTCDR_VERSION_MAJOR == 1 - payload->length = static_cast(ser.getSerializedDataLength()); -#else - payload->length = static_cast(ser.get_serialized_data_length()); -#endif // FASTCDR_VERSION_MAJOR == 1 - return true; -} - -bool RequestTypePubSubType::deserialize( - SerializedPayload_t* payload, - void* data) -{ - try - { - // Convert DATA to pointer of your type - RequestType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); - - // Object that deserializes the data. - eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN -#if FASTCDR_VERSION_MAJOR == 1 - , eprosima::fastcdr::Cdr::CdrType::DDS_CDR -#endif // FASTCDR_VERSION_MAJOR == 1 - ); - - // Deserialize encapsulation. - deser.read_encapsulation(); - payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - - // Deserialize the object. - deser >> *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - return true; -} - -std::function RequestTypePubSubType::getSerializedSizeProvider( - const void* const data, - DataRepresentationId_t data_representation) -{ - return [data, data_representation]() -> uint32_t - { -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(data_representation); - return static_cast(type::getCdrSerializedSize(*static_cast(data))) + - 4u /*encapsulation*/; -#else - try - { - eprosima::fastcdr::CdrSizeCalculator calculator( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); - size_t current_alignment {0}; - return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return 0; - } -#endif // FASTCDR_VERSION_MAJOR == 1 - }; -} - -void* RequestTypePubSubType::createData() -{ - return reinterpret_cast(new RequestType()); -} - -void RequestTypePubSubType::deleteData( - void* data) -{ - delete(reinterpret_cast(data)); -} - -bool RequestTypePubSubType::getKey( - const void* const data, - InstanceHandle_t* handle, - bool force_md5) -{ - if (!m_isGetKeyDefined) - { - return false; - } - - const RequestType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), - RequestType_max_key_cdr_typesize); - - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); -#if FASTCDR_VERSION_MAJOR == 1 - p_type->serializeKey(ser); -#else - eprosima::fastcdr::serialize_key(ser, *p_type); -#endif // FASTCDR_VERSION_MAJOR == 1 - if (force_md5 || RequestType_max_key_cdr_typesize > 16) - { - m_md5.init(); -#if FASTCDR_VERSION_MAJOR == 1 - m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); -#else - m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); -#endif // FASTCDR_VERSION_MAJOR == 1 - m_md5.finalize(); - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_md5.digest[i]; - } - } - else - { - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_keyBuffer[i]; - } - } - return true; -} - -void RequestTypePubSubType::register_type_object_representation() -{ - register_RequestType_type_identifier(type_identifiers_); -} - -ReplyTypePubSubType::ReplyTypePubSubType() -{ - setName("ReplyType"); - uint32_t type_size = -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(ReplyType::getMaxCdrSerializedSize()); -#else - ReplyType_max_cdr_typesize; -#endif - type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ - m_typeSize = type_size + 4; /*encapsulation*/ - m_isGetKeyDefined = false; - uint32_t keyLength = ReplyType_max_key_cdr_typesize > 16 ? ReplyType_max_key_cdr_typesize : 16; - m_keyBuffer = reinterpret_cast(malloc(keyLength)); - memset(m_keyBuffer, 0, keyLength); -} - -ReplyTypePubSubType::~ReplyTypePubSubType() -{ - if (m_keyBuffer != nullptr) - { - free(m_keyBuffer); - } -} - -bool ReplyTypePubSubType::serialize( - const void* const data, - SerializedPayload_t* payload, - DataRepresentationId_t data_representation) -{ - const ReplyType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->max_size); - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); - payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; -#if FASTCDR_VERSION_MAJOR > 1 - ser.set_encoding_flag( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : - eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); -#endif // FASTCDR_VERSION_MAJOR > 1 - - try - { - // Serialize encapsulation - ser.serialize_encapsulation(); - // Serialize the object. - ser << *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - // Get the serialized length -#if FASTCDR_VERSION_MAJOR == 1 - payload->length = static_cast(ser.getSerializedDataLength()); -#else - payload->length = static_cast(ser.get_serialized_data_length()); -#endif // FASTCDR_VERSION_MAJOR == 1 - return true; -} - -bool ReplyTypePubSubType::deserialize( - SerializedPayload_t* payload, - void* data) -{ - try - { - // Convert DATA to pointer of your type - ReplyType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload->data), payload->length); - - // Object that deserializes the data. - eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN -#if FASTCDR_VERSION_MAJOR == 1 - , eprosima::fastcdr::Cdr::CdrType::DDS_CDR -#endif // FASTCDR_VERSION_MAJOR == 1 - ); - - // Deserialize encapsulation. - deser.read_encapsulation(); - payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; - - // Deserialize the object. - deser >> *p_type; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return false; - } - - return true; -} - -std::function ReplyTypePubSubType::getSerializedSizeProvider( - const void* const data, - DataRepresentationId_t data_representation) -{ - return [data, data_representation]() -> uint32_t - { -#if FASTCDR_VERSION_MAJOR == 1 - static_cast(data_representation); - return static_cast(type::getCdrSerializedSize(*static_cast(data))) + - 4u /*encapsulation*/; -#else - try - { - eprosima::fastcdr::CdrSizeCalculator calculator( - data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? - eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); - size_t current_alignment {0}; - return static_cast(calculator.calculate_serialized_size( - *static_cast(data), current_alignment)) + - 4u /*encapsulation*/; - } - catch (eprosima::fastcdr::exception::Exception& /*exception*/) - { - return 0; - } -#endif // FASTCDR_VERSION_MAJOR == 1 - }; -} - -void* ReplyTypePubSubType::createData() -{ - return reinterpret_cast(new ReplyType()); -} - -void ReplyTypePubSubType::deleteData( - void* data) -{ - delete(reinterpret_cast(data)); -} - -bool ReplyTypePubSubType::getKey( - const void* const data, - InstanceHandle_t* handle, - bool force_md5) -{ - if (!m_isGetKeyDefined) - { - return false; - } - - const ReplyType* p_type = static_cast(data); - - // Object that manages the raw buffer. - eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(m_keyBuffer), - ReplyType_max_key_cdr_typesize); - - // Object that serializes the data. - eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv1); -#if FASTCDR_VERSION_MAJOR == 1 - p_type->serializeKey(ser); -#else - eprosima::fastcdr::serialize_key(ser, *p_type); -#endif // FASTCDR_VERSION_MAJOR == 1 - if (force_md5 || ReplyType_max_key_cdr_typesize > 16) - { - m_md5.init(); -#if FASTCDR_VERSION_MAJOR == 1 - m_md5.update(m_keyBuffer, static_cast(ser.getSerializedDataLength())); -#else - m_md5.update(m_keyBuffer, static_cast(ser.get_serialized_data_length())); -#endif // FASTCDR_VERSION_MAJOR == 1 - m_md5.finalize(); - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_md5.digest[i]; - } - } - else - { - for (uint8_t i = 0; i < 16; ++i) - { - handle->value[i] = m_keyBuffer[i]; - } - } - return true; -} - -void ReplyTypePubSubType::register_type_object_representation() -{ - register_ReplyType_type_identifier(type_identifiers_); -} - - -// Include auxiliary functions like for serializing/deserializing. -#include "CalculatorCdrAux.ipp" diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.hpp b/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.hpp deleted file mode 100644 index 99aaac7df59..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorPubSubTypes.hpp +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorPubSubTypes.hpp - * This header file contains the declaration of the serialization functions. - * - * This file was generated by the tool fastddsgen. - */ - - -#ifndef FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP -#define FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP - -#include -#include -#include -#include -#include - -#include "Calculator.hpp" - - -#if !defined(GEN_API_VER) || (GEN_API_VER != 2) -#error \ - Generated Calculator is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. -#endif // GEN_API_VER - - -/*! - * @brief This class represents the TopicDataType of the type RequestType defined by the user in the IDL file. - * @ingroup Calculator - */ -class RequestTypePubSubType : public eprosima::fastdds::dds::TopicDataType -{ -public: - - typedef RequestType type; - - eProsima_user_DllExport RequestTypePubSubType(); - - eProsima_user_DllExport ~RequestTypePubSubType() override; - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload) override - { - return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool deserialize( - eprosima::fastdds::rtps::SerializedPayload_t* payload, - void* data) override; - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data) override - { - return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool getKey( - const void* const data, - eprosima::fastdds::rtps::InstanceHandle_t* ihandle, - bool force_md5 = false) override; - - eProsima_user_DllExport void* createData() override; - - eProsima_user_DllExport void deleteData( - void* data) override; - - //Register TypeObject representation in Fast DDS TypeObjectRegistry - eProsima_user_DllExport void register_type_object_representation() override; - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - eProsima_user_DllExport inline bool is_bounded() const override - { - return true; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - eProsima_user_DllExport inline bool is_plain() const override - { - return false; - } - - eProsima_user_DllExport inline bool is_plain( - eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override - { - static_cast(data_representation); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - -#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - eProsima_user_DllExport inline bool construct_sample( - void* memory) const override - { - static_cast(memory); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - - eprosima::fastdds::MD5 m_md5; - unsigned char* m_keyBuffer; - -}; - -/*! - * @brief This class represents the TopicDataType of the type ReplyType defined by the user in the IDL file. - * @ingroup Calculator - */ -class ReplyTypePubSubType : public eprosima::fastdds::dds::TopicDataType -{ -public: - - typedef ReplyType type; - - eProsima_user_DllExport ReplyTypePubSubType(); - - eProsima_user_DllExport ~ReplyTypePubSubType() override; - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload) override - { - return serialize(data, payload, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport bool serialize( - const void* const data, - eprosima::fastdds::rtps::SerializedPayload_t* payload, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool deserialize( - eprosima::fastdds::rtps::SerializedPayload_t* payload, - void* data) override; - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data) override - { - return getSerializedSizeProvider(data, eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION); - } - - eProsima_user_DllExport std::function getSerializedSizeProvider( - const void* const data, - eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; - - eProsima_user_DllExport bool getKey( - const void* const data, - eprosima::fastdds::rtps::InstanceHandle_t* ihandle, - bool force_md5 = false) override; - - eProsima_user_DllExport void* createData() override; - - eProsima_user_DllExport void deleteData( - void* data) override; - - //Register TypeObject representation in Fast DDS TypeObjectRegistry - eProsima_user_DllExport void register_type_object_representation() override; - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - eProsima_user_DllExport inline bool is_bounded() const override - { - return true; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED - -#ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - eProsima_user_DllExport inline bool is_plain() const override - { - return false; - } - - eProsima_user_DllExport inline bool is_plain( - eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override - { - static_cast(data_representation); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN - -#ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - eProsima_user_DllExport inline bool construct_sample( - void* memory) const override - { - static_cast(memory); - return false; - } - -#endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE - - eprosima::fastdds::MD5 m_md5; - unsigned char* m_keyBuffer; - -}; - -#endif // FAST_DDS_GENERATED__CALCULATOR_PUBSUBTYPES_HPP - diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorServer.cpp b/examples/cpp/dds/RequestReplyExample/CalculatorServer.cpp deleted file mode 100644 index a7ee65d9e5e..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorServer.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2022 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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CalculatorPubSubTypes.hpp" - -class CalculatorServer -{ - class Listener : public eprosima::fastdds::dds::DataReaderListener - { - public: - - Listener( - eprosima::fastdds::dds::DataWriter* writer) - : writer_(writer) - { - } - - void on_data_available( - eprosima::fastdds::dds::DataReader* reader) override - { - RequestType request; - eprosima::fastdds::dds::SampleInfo sample_info; - - reader->take_next_sample(&request, &sample_info); - - if (eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == sample_info.instance_state) - { - ReplyType reply; - - if (OperationType::ADDITION == request.operation()) - { - reply.z(request.x() + request.y()); - } - else if (OperationType::SUBTRACTION == request.operation()) - { - reply.z(request.x() - request.y()); - } - else if (OperationType::MULTIPLICATION == request.operation()) - { - reply.z(request.x() * request.y()); - } - else if (OperationType::DIVISION == request.operation()) - { - if (0 != request.y()) - { - reply.z(request.x() / request.y()); - } - } - eprosima::fastdds::rtps::WriteParams write_params; - write_params.related_sample_identity().writer_guid(sample_info.sample_identity.writer_guid()); - write_params.related_sample_identity().sequence_number(sample_info.sample_identity.sequence_number()); - writer_->write(reinterpret_cast(&reply), write_params); - } - } - - private: - - eprosima::fastdds::dds::DataWriter* writer_ = nullptr; - - }; - -public: - - bool init() - { - participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, - eprosima::fastdds::dds::PARTICIPANT_QOS_DEFAULT); - - if (nullptr == participant_) - { - return false; - } - - request_type_ = eprosima::fastdds::dds::TypeSupport(new RequestTypePubSubType()); - reply_type_ = eprosima::fastdds::dds::TypeSupport(new ReplyTypePubSubType()); - - participant_->register_type(request_type_); - participant_->register_type(reply_type_); - - publisher_ = participant_->create_publisher(eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT); - - if (nullptr == publisher_) - { - return false; - } - - subscriber_ = participant_->create_subscriber(eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT); - - if (nullptr == subscriber_) - { - return false; - } - - request_topic_ = participant_->create_topic("CalculatorRequest", - request_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); - - if (nullptr == request_topic_) - { - return false; - } - - reply_topic_ = participant_->create_topic("CalculatorReply", - reply_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT); - - if (nullptr == reply_topic_) - { - return false; - } - - eprosima::fastdds::dds::DataWriterQos writer_qos; - writer_qos.history().kind = eprosima::fastdds::dds::KEEP_ALL_HISTORY_QOS; - reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos); - - if (nullptr == reply_writer_) - { - return false; - } - - listener_ = { reply_writer_}; - - eprosima::fastdds::dds::DataReaderQos reader_qos; - reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS; - reader_qos.durability().kind = eprosima::fastdds::dds::TRANSIENT_LOCAL_DURABILITY_QOS; - reader_qos.history().kind = eprosima::fastdds::dds::KEEP_ALL_HISTORY_QOS; - request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos, &listener_); - - if (nullptr == request_reader_) - { - return false; - } - - return true; - } - - void deinit() - { - if (nullptr != participant_) - { - participant_->delete_contained_entities(); - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(participant_); - } - } - -private: - - eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr; - - eprosima::fastdds::dds::Publisher* publisher_ = nullptr; - - eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr; - - eprosima::fastdds::dds::Topic* request_topic_ = nullptr; - - eprosima::fastdds::dds::Topic* reply_topic_ = nullptr; - - eprosima::fastdds::dds::DataWriter* reply_writer_ = nullptr; - - eprosima::fastdds::dds::DataReader* request_reader_ = nullptr; - - eprosima::fastdds::dds::TypeSupport request_type_; - - eprosima::fastdds::dds::TypeSupport reply_type_; - - Listener listener_ = {nullptr}; -}; - -int main() -{ - CalculatorServer server; - server.init(); - - std::cout << "Press a key + ENTER to close the server" << std::endl; - char c; - std::cin >> c; - - server.deinit(); - - return 0; -} diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.cxx b/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.cxx deleted file mode 100644 index 574938928b7..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.cxx +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorTypeObjectSupport.cxx - * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file - * - * This file was generated by the tool fastddsgen. - */ - -#include "CalculatorTypeObjectSupport.hpp" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Calculator.hpp" - - -using namespace eprosima::fastdds::dds::xtypes; - -void register_OperationType_type_identifier( - TypeIdentifierPair& type_ids_OperationType) -{ - ReturnCode_t return_code_OperationType {eprosima::fastdds::dds::RETCODE_OK}; - return_code_OperationType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "OperationType", type_ids_OperationType); - if (eprosima::fastdds::dds::RETCODE_OK != return_code_OperationType) - { - EnumTypeFlag enum_flags_OperationType = 0; - BitBound bit_bound_OperationType = 32; - CommonEnumeratedHeader common_OperationType = TypeObjectUtils::build_common_enumerated_header(bit_bound_OperationType); - QualifiedTypeName type_name_OperationType = "OperationType"; - eprosima::fastcdr::optional type_ann_builtin_OperationType; - eprosima::fastcdr::optional ann_custom_OperationType; - CompleteTypeDetail detail_OperationType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_OperationType, ann_custom_OperationType, type_name_OperationType.to_string()); - CompleteEnumeratedHeader header_OperationType = TypeObjectUtils::build_complete_enumerated_header(common_OperationType, detail_OperationType); - CompleteEnumeratedLiteralSeq literal_seq_OperationType; - { - EnumeratedLiteralFlag flags_ADDITION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_ADDITION = TypeObjectUtils::build_common_enumerated_literal(0, flags_ADDITION); - eprosima::fastcdr::optional member_ann_builtin_ADDITION; - ann_custom_OperationType.reset(); - MemberName name_ADDITION = "ADDITION"; - CompleteMemberDetail detail_ADDITION = TypeObjectUtils::build_complete_member_detail(name_ADDITION, member_ann_builtin_ADDITION, ann_custom_OperationType); - CompleteEnumeratedLiteral literal_ADDITION = TypeObjectUtils::build_complete_enumerated_literal(common_ADDITION, detail_ADDITION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_OperationType, literal_ADDITION); - } - { - EnumeratedLiteralFlag flags_SUBTRACTION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_SUBTRACTION = TypeObjectUtils::build_common_enumerated_literal(1, flags_SUBTRACTION); - eprosima::fastcdr::optional member_ann_builtin_SUBTRACTION; - ann_custom_OperationType.reset(); - MemberName name_SUBTRACTION = "SUBTRACTION"; - CompleteMemberDetail detail_SUBTRACTION = TypeObjectUtils::build_complete_member_detail(name_SUBTRACTION, member_ann_builtin_SUBTRACTION, ann_custom_OperationType); - CompleteEnumeratedLiteral literal_SUBTRACTION = TypeObjectUtils::build_complete_enumerated_literal(common_SUBTRACTION, detail_SUBTRACTION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_OperationType, literal_SUBTRACTION); - } - { - EnumeratedLiteralFlag flags_MULTIPLICATION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_MULTIPLICATION = TypeObjectUtils::build_common_enumerated_literal(2, flags_MULTIPLICATION); - eprosima::fastcdr::optional member_ann_builtin_MULTIPLICATION; - ann_custom_OperationType.reset(); - MemberName name_MULTIPLICATION = "MULTIPLICATION"; - CompleteMemberDetail detail_MULTIPLICATION = TypeObjectUtils::build_complete_member_detail(name_MULTIPLICATION, member_ann_builtin_MULTIPLICATION, ann_custom_OperationType); - CompleteEnumeratedLiteral literal_MULTIPLICATION = TypeObjectUtils::build_complete_enumerated_literal(common_MULTIPLICATION, detail_MULTIPLICATION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_OperationType, literal_MULTIPLICATION); - } - { - EnumeratedLiteralFlag flags_DIVISION = TypeObjectUtils::build_enumerated_literal_flag(false); - CommonEnumeratedLiteral common_DIVISION = TypeObjectUtils::build_common_enumerated_literal(3, flags_DIVISION); - eprosima::fastcdr::optional member_ann_builtin_DIVISION; - ann_custom_OperationType.reset(); - MemberName name_DIVISION = "DIVISION"; - CompleteMemberDetail detail_DIVISION = TypeObjectUtils::build_complete_member_detail(name_DIVISION, member_ann_builtin_DIVISION, ann_custom_OperationType); - CompleteEnumeratedLiteral literal_DIVISION = TypeObjectUtils::build_complete_enumerated_literal(common_DIVISION, detail_DIVISION); - TypeObjectUtils::add_complete_enumerated_literal(literal_seq_OperationType, literal_DIVISION); - } - CompleteEnumeratedType enumerated_type_OperationType = TypeObjectUtils::build_complete_enumerated_type(enum_flags_OperationType, header_OperationType, - literal_seq_OperationType); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_enumerated_type_object(enumerated_type_OperationType, type_name_OperationType.to_string(), type_ids_OperationType)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "OperationType already registered in TypeObjectRegistry for a different type."); - } - } -}// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method -void register_RequestType_type_identifier( - TypeIdentifierPair& type_ids_RequestType) -{ - - ReturnCode_t return_code_RequestType {eprosima::fastdds::dds::RETCODE_OK}; - return_code_RequestType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "RequestType", type_ids_RequestType); - if (eprosima::fastdds::dds::RETCODE_OK != return_code_RequestType) - { - StructTypeFlag struct_flags_RequestType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); - QualifiedTypeName type_name_RequestType = "RequestType"; - eprosima::fastcdr::optional type_ann_builtin_RequestType; - eprosima::fastcdr::optional ann_custom_RequestType; - CompleteTypeDetail detail_RequestType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_RequestType, ann_custom_RequestType, type_name_RequestType.to_string()); - CompleteStructHeader header_RequestType; - header_RequestType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_RequestType); - CompleteStructMemberSeq member_seq_RequestType; - { - TypeIdentifierPair type_ids_operation; - ReturnCode_t return_code_operation {eprosima::fastdds::dds::RETCODE_OK}; - return_code_operation = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "OperationType", type_ids_operation); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_operation) - { - ::register_OperationType_type_identifier(type_ids_operation); - } - StructMemberFlag member_flags_operation = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_operation = 0x00000000; - bool common_operation_ec {false}; - CommonStructMember common_operation {TypeObjectUtils::build_common_struct_member(member_id_operation, member_flags_operation, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_operation, common_operation_ec))}; - if (!common_operation_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure operation member TypeIdentifier inconsistent."); - return; - } - MemberName name_operation = "operation"; - eprosima::fastcdr::optional member_ann_builtin_operation; - ann_custom_RequestType.reset(); - CompleteMemberDetail detail_operation = TypeObjectUtils::build_complete_member_detail(name_operation, member_ann_builtin_operation, ann_custom_RequestType); - CompleteStructMember member_operation = TypeObjectUtils::build_complete_struct_member(common_operation, detail_operation); - TypeObjectUtils::add_complete_struct_member(member_seq_RequestType, member_operation); - } - { - TypeIdentifierPair type_ids_x; - ReturnCode_t return_code_x {eprosima::fastdds::dds::RETCODE_OK}; - return_code_x = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_int32_t", type_ids_x); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_x) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "x Structure member TypeIdentifier unknown to TypeObjectRegistry."); - return; - } - StructMemberFlag member_flags_x = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_x = 0x00000001; - bool common_x_ec {false}; - CommonStructMember common_x {TypeObjectUtils::build_common_struct_member(member_id_x, member_flags_x, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_x, common_x_ec))}; - if (!common_x_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure x member TypeIdentifier inconsistent."); - return; - } - MemberName name_x = "x"; - eprosima::fastcdr::optional member_ann_builtin_x; - ann_custom_RequestType.reset(); - CompleteMemberDetail detail_x = TypeObjectUtils::build_complete_member_detail(name_x, member_ann_builtin_x, ann_custom_RequestType); - CompleteStructMember member_x = TypeObjectUtils::build_complete_struct_member(common_x, detail_x); - TypeObjectUtils::add_complete_struct_member(member_seq_RequestType, member_x); - } - { - TypeIdentifierPair type_ids_y; - ReturnCode_t return_code_y {eprosima::fastdds::dds::RETCODE_OK}; - return_code_y = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_int32_t", type_ids_y); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_y) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "y Structure member TypeIdentifier unknown to TypeObjectRegistry."); - return; - } - StructMemberFlag member_flags_y = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_y = 0x00000002; - bool common_y_ec {false}; - CommonStructMember common_y {TypeObjectUtils::build_common_struct_member(member_id_y, member_flags_y, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_y, common_y_ec))}; - if (!common_y_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure y member TypeIdentifier inconsistent."); - return; - } - MemberName name_y = "y"; - eprosima::fastcdr::optional member_ann_builtin_y; - ann_custom_RequestType.reset(); - CompleteMemberDetail detail_y = TypeObjectUtils::build_complete_member_detail(name_y, member_ann_builtin_y, ann_custom_RequestType); - CompleteStructMember member_y = TypeObjectUtils::build_complete_struct_member(common_y, detail_y); - TypeObjectUtils::add_complete_struct_member(member_seq_RequestType, member_y); - } - CompleteStructType struct_type_RequestType = TypeObjectUtils::build_complete_struct_type(struct_flags_RequestType, header_RequestType, member_seq_RequestType); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_RequestType, type_name_RequestType.to_string(), type_ids_RequestType)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "RequestType already registered in TypeObjectRegistry for a different type."); - } - } -} -// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method -void register_ReplyType_type_identifier( - TypeIdentifierPair& type_ids_ReplyType) -{ - - ReturnCode_t return_code_ReplyType {eprosima::fastdds::dds::RETCODE_OK}; - return_code_ReplyType = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "ReplyType", type_ids_ReplyType); - if (eprosima::fastdds::dds::RETCODE_OK != return_code_ReplyType) - { - StructTypeFlag struct_flags_ReplyType = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, - false, false); - QualifiedTypeName type_name_ReplyType = "ReplyType"; - eprosima::fastcdr::optional type_ann_builtin_ReplyType; - eprosima::fastcdr::optional ann_custom_ReplyType; - CompleteTypeDetail detail_ReplyType = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_ReplyType, ann_custom_ReplyType, type_name_ReplyType.to_string()); - CompleteStructHeader header_ReplyType; - header_ReplyType = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_ReplyType); - CompleteStructMemberSeq member_seq_ReplyType; - { - TypeIdentifierPair type_ids_z; - ReturnCode_t return_code_z {eprosima::fastdds::dds::RETCODE_OK}; - return_code_z = - eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( - "_int64_t", type_ids_z); - - if (eprosima::fastdds::dds::RETCODE_OK != return_code_z) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "z Structure member TypeIdentifier unknown to TypeObjectRegistry."); - return; - } - StructMemberFlag member_flags_z = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); - MemberId member_id_z = 0x00000000; - bool common_z_ec {false}; - CommonStructMember common_z {TypeObjectUtils::build_common_struct_member(member_id_z, member_flags_z, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_z, common_z_ec))}; - if (!common_z_ec) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure z member TypeIdentifier inconsistent."); - return; - } - MemberName name_z = "z"; - eprosima::fastcdr::optional member_ann_builtin_z; - ann_custom_ReplyType.reset(); - CompleteMemberDetail detail_z = TypeObjectUtils::build_complete_member_detail(name_z, member_ann_builtin_z, ann_custom_ReplyType); - CompleteStructMember member_z = TypeObjectUtils::build_complete_struct_member(common_z, detail_z); - TypeObjectUtils::add_complete_struct_member(member_seq_ReplyType, member_z); - } - CompleteStructType struct_type_ReplyType = TypeObjectUtils::build_complete_struct_type(struct_flags_ReplyType, header_ReplyType, member_seq_ReplyType); - if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == - TypeObjectUtils::build_and_register_struct_type_object(struct_type_ReplyType, type_name_ReplyType.to_string(), type_ids_ReplyType)) - { - EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, - "ReplyType already registered in TypeObjectRegistry for a different type."); - } - } -} - diff --git a/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.hpp b/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.hpp deleted file mode 100644 index d8bc006c6bf..00000000000 --- a/examples/cpp/dds/RequestReplyExample/CalculatorTypeObjectSupport.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2016 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. - -/*! - * @file CalculatorTypeObjectSupport.hpp - * Header file containing the API required to register the TypeObject representation of the described types in the IDL file - * - * This file was generated by the tool fastddsgen. - */ - -#ifndef FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP -#define FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP - -#include - - -#if defined(_WIN32) -#if defined(EPROSIMA_USER_DLL_EXPORT) -#define eProsima_user_DllExport __declspec( dllexport ) -#else -#define eProsima_user_DllExport -#endif // EPROSIMA_USER_DLL_EXPORT -#else -#define eProsima_user_DllExport -#endif // _WIN32 - -#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC - -/** - * @brief Register OperationType related TypeIdentifier. - * Fully-descriptive TypeIdentifiers are directly registered. - * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is - * indirectly registered as well. - * - * @param[out] TypeIdentifier of the registered type. - * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. - * Invalid TypeIdentifier is returned in case of error. - */ -eProsima_user_DllExport void register_OperationType_type_identifier( - eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); -/** - * @brief Register RequestType related TypeIdentifier. - * Fully-descriptive TypeIdentifiers are directly registered. - * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is - * indirectly registered as well. - * - * @param[out] TypeIdentifier of the registered type. - * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. - * Invalid TypeIdentifier is returned in case of error. - */ -eProsima_user_DllExport void register_RequestType_type_identifier( - eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); -/** - * @brief Register ReplyType related TypeIdentifier. - * Fully-descriptive TypeIdentifiers are directly registered. - * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is - * indirectly registered as well. - * - * @param[out] TypeIdentifier of the registered type. - * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. - * Invalid TypeIdentifier is returned in case of error. - */ -eProsima_user_DllExport void register_ReplyType_type_identifier( - eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); - - -#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC - -#endif // FAST_DDS_GENERATED__CALCULATOR_TYPE_OBJECT_SUPPORT_HPP diff --git a/examples/cpp/dds/RequestReplyExample/README.md b/examples/cpp/dds/RequestReplyExample/README.md deleted file mode 100644 index 15e1d1152df..00000000000 --- a/examples/cpp/dds/RequestReplyExample/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Request-Reply example - -This example illustrates how to achieve a Client/Server communication between two applications using the *Fast DDS* -request-reply mechanism. -More information in [Fast DDS documentation](https://fast-dds.docs.eprosima.com/en/latest/fastdds/use_cases/request_reply/request_reply.html). - -To launch this example open two different consoles: - -1. In the first one launch: `./DDSCalculatorServer` (or `DDSCalculatorServer.exe` on Windows). -1. In the second one: `./DDSCalculatorClient 3 + 3` (or `DDSCalculatorClient.exe 3 + 3` on windows). From f34ec0fde45eab027c07bd25c24924e20db38d71 Mon Sep 17 00:00:00 2001 From: eduponz Date: Tue, 9 Jul 2024 16:08:25 +0200 Subject: [PATCH 30/46] Refs #21188: Address minor Eliana's comments Signed-off-by: eduponz --- examples/cpp/dds/CMakeLists.txt | 1 - examples/cpp/request_reply/CLIParser.hpp | 5 +---- examples/cpp/request_reply/README.md | 1 + examples/cpp/request_reply/ServerApp.cpp | 3 ++- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/cpp/dds/CMakeLists.txt b/examples/cpp/dds/CMakeLists.txt index 19f83e1edea..99c38526dee 100644 --- a/examples/cpp/dds/CMakeLists.txt +++ b/examples/cpp/dds/CMakeLists.txt @@ -18,7 +18,6 @@ add_subdirectory(HelloWorldExampleDataSharing) add_subdirectory(HelloWorldExampleSharedMem) add_subdirectory(HelloWorldExampleTCP) add_subdirectory(Keys) -add_subdirectory(RequestReplyExample) add_subdirectory(StaticHelloWorldExample) add_subdirectory(WriterLoansExample) add_subdirectory(ZeroCopyExample) diff --git a/examples/cpp/request_reply/CLIParser.hpp b/examples/cpp/request_reply/CLIParser.hpp index 66655de48ed..8ef48465c08 100644 --- a/examples/cpp/request_reply/CLIParser.hpp +++ b/examples/cpp/request_reply/CLIParser.hpp @@ -149,7 +149,7 @@ class CLIParser print_help(EXIT_FAILURE); } - consume_client_arguments(argc, argv, config); + consume_client_arguments(argv, config); } return config; @@ -217,12 +217,9 @@ class CLIParser * @warning This method finishes the execution of the program if the input arguments are invalid */ static void consume_client_arguments( - const int argc, const char* const argv[], config& config) { - static_cast(argc); - assert(argc >= 5); config.x = consume_int16_argument(argv[2]); config.operation = consume_operation_argument(argv[3]); config.y = consume_int16_argument(argv[4]); diff --git a/examples/cpp/request_reply/README.md b/examples/cpp/request_reply/README.md index 3ddb1b8d355..6e66dd2aa20 100644 --- a/examples/cpp/request_reply/README.md +++ b/examples/cpp/request_reply/README.md @@ -21,6 +21,7 @@ sequenceDiagram participant Client participant Client Request Writer participant Client Reply Reader + participant Server participant Server Request Reader participant Server Reply Writer diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index a944473449c..d50897d608e 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -351,7 +351,7 @@ void ServerApp::reply_routine() rtps::GuidPrefix_t client_guid_prefix = rtps::iHandle2GUID(request.info.publication_handle).guidPrefix; request_reply_debug("ServerApp", "Processing request from client " << client_guid_prefix); - // If none to the client's endpoints are matched, ignore the request as the client is gone + // If none of the client's endpoints are matched, ignore the request as the client is gone if (!client_matched_status_.is_fully_unmatched(client_guid_prefix)) { request_reply_info("ServerApp", "Ignoring request from already gone client " << client_guid_prefix); @@ -364,6 +364,7 @@ void ServerApp::reply_routine() request_reply_debug("ServerApp", "Client " << client_guid_prefix << " not fully matched, saving request for later"); requests_.push(request); + continue; } // Calculate the result From d9cf2f5972cd9d067c3d755013174da0dddcb06e Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 10:36:23 +0200 Subject: [PATCH 31/46] Refs #21188: Remove operation param from CLI. Client always requests + Signed-off-by: eduponz --- examples/cpp/request_reply/CLIParser.hpp | 71 ++++----------------- examples/cpp/request_reply/ClientApp.cpp | 14 ++-- examples/cpp/request_reply/ClientApp.hpp | 3 +- examples/cpp/request_reply/app_utils.hpp | 81 ++++++------------------ 4 files changed, 43 insertions(+), 126 deletions(-) diff --git a/examples/cpp/request_reply/CLIParser.hpp b/examples/cpp/request_reply/CLIParser.hpp index 8ef48465c08..a5011ce0c4a 100644 --- a/examples/cpp/request_reply/CLIParser.hpp +++ b/examples/cpp/request_reply/CLIParser.hpp @@ -47,21 +47,10 @@ class CLIParser UNDEFINED }; - //! Operation enumeration - enum class Operation : std::uint8_t - { - ADDITION, - SUBTRACTION, - MULTIPLICATION, - DIVISION, - UNDEFINED - }; - //! Configuration structure for the application struct config { CLIParser::EntityKind entity = CLIParser::EntityKind::UNDEFINED; - CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; std::int16_t x = 0; std::int16_t y = 0; }; @@ -76,9 +65,16 @@ class CLIParser static void print_help( const std::uint8_t return_code) { - std::cout << "Service to perform an operation on two 16-bit integers" << std::endl; + std::cout << "Service to perform several operations (addition, " << std::endl; + std::cout << "subtraction, multiplication, and division) on two 16-bit" << std::endl; + std::cout << "integers" << std::endl; + std::cout << "" << std::endl; std::cout << "Usage: request_reply [options] [arguments]" << std::endl; std::cout << "" << std::endl; + std::cout << "Example:" << std::endl; + std::cout << " - request_reply server" << std::endl; + std::cout << " - request_reply client 4 5" << std::endl; + std::cout << "" << std::endl; std::cout << "Entities:" << std::endl; std::cout << " server Run a server entity" << std::endl; std::cout << " client Run a client entity" << std::endl; @@ -87,7 +83,8 @@ class CLIParser std::cout << " -h, --help Print this help message" << std::endl; std::cout << "" << std::endl; std::cout << "Client arguments:" << std::endl; - std::cout << " [NUMBER] <+|-|x|/> [NUMBER] Operation to be performed" << std::endl; + std::cout << " [NUMBER] [NUMBER] The numbers of which the" << std::endl; + std::cout << " operations are performed" << std::endl; std::exit(return_code); } @@ -143,7 +140,7 @@ class CLIParser if (CLIParser::EntityKind::CLIENT == config.entity) { - if (argc != 5) + if (argc != 4) { EPROSIMA_LOG_ERROR(CLI_PARSER, "Incorrect number of arguments for client entity"); print_help(EXIT_FAILURE); @@ -209,9 +206,9 @@ class CLIParser /** * @brief Consume the client arguments and store them in the config object * - * @param[in] argc number of arguments - * @param[in] argv array of arguments + * @pre argc == 4 * + * @param[in] argv array of arguments * @param[in,out] config config object to store the arguments * * @warning This method finishes the execution of the program if the input arguments are invalid @@ -221,8 +218,7 @@ class CLIParser config& config) { config.x = consume_int16_argument(argv[2]); - config.operation = consume_operation_argument(argv[3]); - config.y = consume_int16_argument(argv[4]); + config.y = consume_int16_argument(argv[3]); } /** @@ -265,45 +261,6 @@ class CLIParser return value; } - /** - * @brief Consume an operation argument and return it - * - * @param[in] arg string argument to consume - * - * @return Operation operation argument - * - * @warning This method finishes the execution of the program if the input arguments are invalid - */ - static Operation consume_operation_argument( - const std::string& arg) - { - Operation operation = Operation::UNDEFINED; - - if (arg == "+") - { - operation = Operation::ADDITION; - } - else if (arg == "-") - { - operation = Operation::SUBTRACTION; - } - else if (arg == "x") - { - operation = Operation::MULTIPLICATION; - } - else if (arg == "/") - { - operation = Operation::DIVISION; - } - else - { - EPROSIMA_LOG_ERROR(CLI_PARSER, "invalid operation argument: " + arg); - print_help(EXIT_FAILURE); - } - - return operation; - } - }; } // namespace request_reply diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 0f67f2182c9..2fa9408c7d9 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -62,7 +62,7 @@ Topic* create_topic( ClientApp::ClientApp( const CLIParser::config& config, const std::string& service_name) - : request_input_(config) + : request_input_({config.x, config.y}) , participant_(nullptr) , request_type_(nullptr) , request_topic_(nullptr) @@ -291,7 +291,7 @@ void ClientApp::create_reply_entities( reply_topic_ = create_topic("rr/" + service_name, reply_type_); reply_topic_filter_expression_ = "client_id = '" + - TypeConverter::to_calculator_type(participant_->guid().guidPrefix) + "'"; + TypeConverter::to_string(participant_->guid().guidPrefix) + "'"; reply_cf_topic_ = participant_->create_contentfilteredtopic("rr/" + service_name + "_cft", reply_topic_, reply_topic_filter_expression_, @@ -337,10 +337,10 @@ bool ClientApp::send_request() { CalculatorRequestType request; - request.client_id(TypeConverter::to_calculator_type(participant_->guid().guidPrefix)); - request.operation(TypeConverter::to_calculator_type(request_input_.operation)); - request.x(request_input_.x); - request.y(request_input_.y); + request.client_id(TypeConverter::to_string(participant_->guid().guidPrefix)); + request.operation(CalculatorOperationType::ADDITION); + request.x(request_input_.first); + request.y(request_input_.second); rtps::WriteParams wparams; @@ -348,7 +348,7 @@ bool ClientApp::send_request() request_reply_info("ClientApp", "Request sent with ID '" << wparams.sample_identity().sequence_number() << - "': '" << request_input_.str() << "'"); + "': '" << request_input_.first << " + " << request_input_.second << "'"); return ret; } diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index 7ba38042e33..d0f436afe77 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -100,7 +101,7 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit void wait_for_reply(); - RequestInput request_input_; + std::pair request_input_; DomainParticipant* participant_; diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index d655299e489..9f4a3501c15 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -35,7 +35,6 @@ #include #include -#include "CLIParser.hpp" #include "types/Calculator.hpp" namespace eprosima { @@ -43,51 +42,6 @@ namespace fastdds { namespace examples { namespace request_reply { -struct RequestInput -{ - RequestInput( - const CLIParser::config& config) - : operation(config.operation) - , x(config.x) - , y(config.y) - { - } - - std::string str() - { - std::string result = std::to_string(x); - - switch (operation) - { - case CLIParser::Operation::ADDITION: - result += " + "; - break; - case CLIParser::Operation::SUBTRACTION: - result += " - "; - break; - case CLIParser::Operation::MULTIPLICATION: - result += " x "; - break; - case CLIParser::Operation::DIVISION: - result += " / "; - break; - default: - result += " UNDEFINED "; - break; - } - - result += std::to_string(y); - - return result; - } - - CLIParser::Operation operation = CLIParser::Operation::UNDEFINED; - - std::int16_t x = 0; - - std::int16_t y = 0; -}; - class RemoteServerMatchedStatus { public: @@ -229,34 +183,39 @@ class RemoteClientMatchedStatus struct TypeConverter { - static CalculatorOperationType to_calculator_type( - const CLIParser::Operation& operation) + static std::string to_string( + const CalculatorRequestType& request) { - CalculatorOperationType calculator_operation; + std::ostringstream request_ss; + request_ss << request.x() << " " << to_string(request.operation()) << " " << request.y(); + return request_ss.str(); + } + static std::string to_string( + const CalculatorOperationType& operation) + { + std::string operation_str = "Unknown"; switch (operation) { - case CLIParser::Operation::ADDITION: - calculator_operation = CalculatorOperationType::ADDITION; + case CalculatorOperationType::ADDITION: + operation_str = "+"; break; - case CLIParser::Operation::SUBTRACTION: - calculator_operation = CalculatorOperationType::SUBTRACTION; + case CalculatorOperationType::SUBTRACTION: + operation_str = "-"; break; - case CLIParser::Operation::MULTIPLICATION: - calculator_operation = CalculatorOperationType::MULTIPLICATION; + case CalculatorOperationType::MULTIPLICATION: + operation_str = "*"; break; - case CLIParser::Operation::DIVISION: - calculator_operation = CalculatorOperationType::DIVISION; + case CalculatorOperationType::DIVISION: + operation_str = "/"; break; default: - throw std::invalid_argument("Invalid operation"); break; } - - return calculator_operation; + return operation_str; } - static std::string to_calculator_type( + static std::string to_string( const rtps::GuidPrefix_t& guid_prefix) { std::ostringstream client_id; From f27a9d849784167828c6696e407dfc040f37d694 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 10:37:28 +0200 Subject: [PATCH 32/46] Refs #21188: Add space between doxygen @param and direction specifier Signed-off-by: eduponz --- examples/cpp/request_reply/CLIParser.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/cpp/request_reply/CLIParser.hpp b/examples/cpp/request_reply/CLIParser.hpp index a5011ce0c4a..3a4e1940224 100644 --- a/examples/cpp/request_reply/CLIParser.hpp +++ b/examples/cpp/request_reply/CLIParser.hpp @@ -58,7 +58,7 @@ class CLIParser /** * @brief Print usage help message and exit with the given return code * - * @param[in] return_code return code to exit with + * @param [in] return_code return code to exit with * * @warning This method finishes the execution of the program with the input return code */ @@ -91,8 +91,8 @@ class CLIParser /** * @brief Parse the command line options and return the config object * - * @param[in] argc number of arguments - * @param[in] argv array of arguments + * @param [in] argc number of arguments + * @param [in] argv array of arguments * * @return config object with the parsed options * @@ -155,7 +155,7 @@ class CLIParser /** * @brief Parse the signal number into the signal name * - * @param[in] signum signal number + * @param [in] signum signal number * * @return std::string signal name */ @@ -182,7 +182,7 @@ class CLIParser /** * @brief Parse the entity kind into std::string * - * @param[in] entity entity kind + * @param [in] entity entity kind * * @return std::string entity kind */ @@ -208,8 +208,8 @@ class CLIParser * * @pre argc == 4 * - * @param[in] argv array of arguments - * @param[in,out] config config object to store the arguments + * @param [in] argv array of arguments + * @param [in,out] config config object to store the arguments * * @warning This method finishes the execution of the program if the input arguments are invalid */ @@ -224,7 +224,7 @@ class CLIParser /** * @brief Consume an int16 argument and return it * - * @param[in] arg string argument to consume + * @param [in] arg string argument to consume * * @return std::int16_t int16 argument * From 83f2faf8ca93015ffacef2a36953f4b624fe6163 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 11:29:48 +0200 Subject: [PATCH 33/46] Refs #21188: Client sends 1 request per operation and waits for all replies Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 88 +++++++++++++++++++++--- examples/cpp/request_reply/ClientApp.hpp | 12 +++- 2 files changed, 88 insertions(+), 12 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 2fa9408c7d9..02d86123ef5 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -124,12 +124,12 @@ void ClientApp::run() if (!is_stopped()) { - if (!send_request()) + if (!send_requests()) { throw std::runtime_error("Failed to send request"); } - wait_for_reply(); + wait_for_replies(); } } @@ -203,12 +203,52 @@ void ClientApp::on_data_available( { if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { + std::lock_guard lock(mtx_); + rtps::GuidPrefix_t server_guid_prefix = rtps::iHandle2GUID(info.publication_handle).guidPrefix; - request_reply_info("ClientApp", - "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); - stop(); - break; + auto request_status = requests_status_.find(info.related_sample_identity); + + if (requests_status_.end() != request_status) + { + if (!request_status->second) + { + request_status->second = true; + request_reply_info("ClientApp", + "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); + } + else + { + request_reply_debug("ClientApp", + "Duplicate reply received from server " << server_guid_prefix << " with result: " + << reply.result()); + continue; + } + } + else + { + request_reply_error("ClientApp", + "Reply received from server " << server_guid_prefix << " with unknown request ID '" + << info.related_sample_identity.sequence_number() << "'"); + continue; + } + + // Check if all responses have been received + if (requests_status_.size() == 4) + { + bool all_responses_received = true; + + for (auto status : requests_status_) + { + all_responses_received &= status.second; + } + + if (all_responses_received) + { + stop(); + break; + } + } } } } @@ -333,22 +373,50 @@ void ClientApp::create_reply_entities( } } -bool ClientApp::send_request() +bool ClientApp::send_requests() { CalculatorRequestType request; request.client_id(TypeConverter::to_string(participant_->guid().guidPrefix)); - request.operation(CalculatorOperationType::ADDITION); request.x(request_input_.first); request.y(request_input_.second); + request.operation(CalculatorOperationType::ADDITION); + bool ret = send_request(request); + + if (ret) + { + request.operation(CalculatorOperationType::SUBTRACTION); + ret = send_request(request); + } + + if (ret) + { + request.operation(CalculatorOperationType::MULTIPLICATION); + ret = send_request(request); + } + + if (ret) + { + request.operation(CalculatorOperationType::DIVISION); + ret = send_request(request); + } + + return ret; +} +bool ClientApp::send_request( + const CalculatorRequestType& request) +{ rtps::WriteParams wparams; bool ret = request_writer_->write(&request, wparams); request_reply_info("ClientApp", "Request sent with ID '" << wparams.sample_identity().sequence_number() << - "': '" << request_input_.first << " + " << request_input_.second << "'"); + "': '" << TypeConverter::to_string(request) << "'"); + + std::lock_guard lock(mtx_); + requests_status_[wparams.sample_identity()] = false; return ret; } @@ -358,7 +426,7 @@ bool ClientApp::is_stopped() return stop_.load(); } -void ClientApp::wait_for_reply() +void ClientApp::wait_for_replies() { std::unique_lock lock(mtx_); cv_.wait(lock, [&]() diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index d0f436afe77..fb4f7be8a45 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -37,10 +38,12 @@ #include #include #include +#include #include "app_utils.hpp" #include "Application.hpp" #include "CLIParser.hpp" +#include "types/Calculator.hpp" #include "types/CalculatorPubSubTypes.hpp" namespace eprosima { @@ -95,11 +98,14 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit void create_reply_entities( const std::string& service_name); - bool send_request(); + bool send_requests(); + + bool send_request( + const CalculatorRequestType& request); bool is_stopped(); - void wait_for_reply(); + void wait_for_replies(); std::pair request_input_; @@ -134,6 +140,8 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit RemoteServerMatchedStatus server_matched_status_; std::atomic stop_; + + std::map requests_status_; }; template<> From d13e20fd96061863b7a4372ce0fed9c08000fdfd Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 12:17:28 +0200 Subject: [PATCH 34/46] Refs #21188: Fix data race on reader filter removal Signed-off-by: eduponz --- src/cpp/fastdds/publisher/DataWriterImpl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpp/fastdds/publisher/DataWriterImpl.cpp b/src/cpp/fastdds/publisher/DataWriterImpl.cpp index 5b28f70402e..2eedc826720 100644 --- a/src/cpp/fastdds/publisher/DataWriterImpl.cpp +++ b/src/cpp/fastdds/publisher/DataWriterImpl.cpp @@ -2225,6 +2225,8 @@ void DataWriterImpl::remove_reader_filter( { if (reader_filters_) { + assert(writer_); + std::lock_guard guard(writer_->getMutex()); reader_filters_->remove_reader(reader_guid); } } From e327ed7603cb66d52b90fb793ce18e7bab08bec6 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 12:20:33 +0200 Subject: [PATCH 35/46] Refs #21188: Unmatch participant on participant removed Signed-off-by: eduponz --- examples/cpp/request_reply/ServerApp.cpp | 37 +++++++++++++++++++++--- examples/cpp/request_reply/ServerApp.hpp | 11 +++++-- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index d50897d608e..9f9fa532e05 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include "types/Calculator.hpp" #include "types/CalculatorPubSubTypes.hpp" @@ -126,6 +127,30 @@ void ServerApp::stop() cv_.notify_all(); } +void ServerApp::on_participant_discovery( + DomainParticipant* /* participant */, + rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) +{ + std::lock_guard lock(mtx_); + + should_be_ignored = false; + + rtps::GuidPrefix_t remote_participant_guid_prefix = info.info.m_guid.guidPrefix; + + if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT) + { + request_reply_debug("ServerApp", "Participant discovered: " << remote_participant_guid_prefix); + } + else if (info.status == rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT) + { + client_matched_status_.match_reply_reader(remote_participant_guid_prefix, false); + client_matched_status_.match_request_writer(remote_participant_guid_prefix, false); + + request_reply_debug("ServerApp", "Participant removed: " << remote_participant_guid_prefix); + } +} + void ServerApp::on_publication_matched( DataWriter* /* writer */, const PublicationMatchedStatus& info) @@ -170,7 +195,6 @@ void ServerApp::on_subscription_matched( { request_reply_debug("ServerApp", "Remote request writer matched with client " << client_guid_prefix); client_matched_status_.match_request_writer(client_guid_prefix, true); - } else if (info.current_count_change == -1) { @@ -229,7 +253,12 @@ void ServerApp::create_participant() throw std::runtime_error("Failed to get participant factory instance"); } - participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); + StatusMask participant_mask = StatusMask::none(); + participant_mask << StatusMask::publication_matched(); + participant_mask << StatusMask::subscription_matched(); + participant_mask << StatusMask::data_available(); + + participant_ = factory->create_participant_with_default_profile(this, participant_mask); if (nullptr == participant_) { @@ -281,7 +310,7 @@ void ServerApp::create_request_entities( throw std::runtime_error("Failed to get default datareader qos"); } - request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos, this, StatusMask::all()); + request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos); if (nullptr == request_reader_) { @@ -317,7 +346,7 @@ void ServerApp::create_reply_entities( throw std::runtime_error("Failed to get default datawriter qos"); } - reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos, this, StatusMask::all()); + reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos); if (nullptr == reply_writer_) { diff --git a/examples/cpp/request_reply/ServerApp.hpp b/examples/cpp/request_reply/ServerApp.hpp index 0e0a64ea917..a195b8164ff 100644 --- a/examples/cpp/request_reply/ServerApp.hpp +++ b/examples/cpp/request_reply/ServerApp.hpp @@ -30,11 +30,10 @@ #include #include +#include #include -#include #include #include -#include #include #include #include @@ -51,7 +50,7 @@ namespace request_reply { using namespace eprosima::fastdds::dds; -class ServerApp : public Application, public DataWriterListener, public DataReaderListener +class ServerApp : public Application, public DomainParticipantListener { public: @@ -66,6 +65,12 @@ class ServerApp : public Application, public DataWriterListener, public DataRead //! Stop server void stop() override; + //! Participant discovery method + void on_participant_discovery( + DomainParticipant* participant, + rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) override; + //! Publication matched method void on_publication_matched( DataWriter* writer, From 6165d9f7d517db13e467193fa5e8f5ac47b51b86 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 13:43:16 +0200 Subject: [PATCH 36/46] Refs #21188: Add DomainParticipantFactory::get_participant_extended_qos_from_default_profile Signed-off-by: eduponz --- .../dds/domain/DomainParticipantFactory.hpp | 9 +++++++++ .../fastdds/domain/DomainParticipantFactory.cpp | 9 +++++++++ .../dds/participant/ParticipantTests.cpp | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/include/fastdds/dds/domain/DomainParticipantFactory.hpp b/include/fastdds/dds/domain/DomainParticipantFactory.hpp index 29bca773014..a492fce1e09 100644 --- a/include/fastdds/dds/domain/DomainParticipantFactory.hpp +++ b/include/fastdds/dds/domain/DomainParticipantFactory.hpp @@ -240,6 +240,15 @@ class DomainParticipantFactory const std::string& profile_name, DomainParticipantExtendedQos& extended_qos) const; + /** + * Fills the DomainParticipantExtendedQos with the values of the default XML profile. + * + * @param extended_qos DomainParticipantExtendedQos object where the domain and qos are returned. + * @return RETCODE_OK + */ + FASTDDS_EXPORTED_API ReturnCode_t get_participant_extended_qos_from_default_profile( + DomainParticipantExtendedQos& extended_qos) const; + /** * Remove a Participant and all associated publishers and subscribers. * diff --git a/src/cpp/fastdds/domain/DomainParticipantFactory.cpp b/src/cpp/fastdds/domain/DomainParticipantFactory.cpp index 4d59024d6a7..eb6f9b65ffe 100644 --- a/src/cpp/fastdds/domain/DomainParticipantFactory.cpp +++ b/src/cpp/fastdds/domain/DomainParticipantFactory.cpp @@ -356,6 +356,15 @@ ReturnCode_t DomainParticipantFactory::get_participant_extended_qos_from_profile return RETCODE_BAD_PARAMETER; } +ReturnCode_t DomainParticipantFactory::get_participant_extended_qos_from_default_profile( + DomainParticipantExtendedQos& extended_qos) const +{ + ParticipantAttributes attr; + XMLProfileManager::getDefaultParticipantAttributes(attr); + utils::set_extended_qos_from_attributes(extended_qos, attr); + return RETCODE_OK; +} + ReturnCode_t DomainParticipantFactory::load_profiles() { // NOTE: This could be done with a bool atomic to avoid taking the mutex in most cases, however the use of diff --git a/test/unittest/dds/participant/ParticipantTests.cpp b/test/unittest/dds/participant/ParticipantTests.cpp index d13768accb7..9aacba03bec 100644 --- a/test/unittest/dds/participant/ParticipantTests.cpp +++ b/test/unittest/dds/participant/ParticipantTests.cpp @@ -648,6 +648,22 @@ TEST(ParticipantTests, CreateDomainParticipantWithExtendedQosFromProfile) ASSERT_TRUE(DomainParticipantFactory::get_instance()->delete_participant(new_participant) == RETCODE_OK); } +/** + * This test checks that get_participant_extended_qos_from_default_profile holds the correct domain ID. + */ +TEST(ParticipantTests, get_participant_extended_qos_from_default_profile) +{ + DomainParticipantFactory::get_instance()->load_XML_profiles_file("test_xml_profile.xml"); + + uint32_t domain_id = 123u; // This is the domain ID set in the default profile above + + DomainParticipantExtendedQos extended_qos; + ASSERT_TRUE(DomainParticipantFactory::get_instance()->get_participant_extended_qos_from_default_profile( + extended_qos) == RETCODE_OK); + + ASSERT_EQ(extended_qos.domainId(), domain_id); +} + TEST(ParticipantTests, CreateDomainParticipantWithDefaultProfile) { uint32_t domain_id = 123u; // This is the domain ID set in the default profile above From ec7d22445b863595bb5e199495cd66a37bc42c3d Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 13:37:10 +0200 Subject: [PATCH 37/46] Refs #21188: Server ignores non-client participants Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 9 ++++- examples/cpp/request_reply/ServerApp.cpp | 50 +++++++++++++++++++----- examples/cpp/request_reply/app_utils.hpp | 30 ++++++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 02d86123ef5..659aa405196 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -20,6 +20,7 @@ #include "ClientApp.hpp" #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include +#include "CLIParser.hpp" #include "types/Calculator.hpp" #include "types/CalculatorPubSubTypes.hpp" @@ -263,7 +265,12 @@ void ClientApp::create_participant() throw std::runtime_error("Failed to get participant factory instance"); } - participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); + DomainParticipantExtendedQos participant_qos; + factory->get_participant_extended_qos_from_default_profile(participant_qos); + + participant_qos.user_data().data_vec().push_back(static_cast(CLIParser::EntityKind::CLIENT)); + + participant_ = factory->create_participant(participant_qos.domainId(), participant_qos); if (nullptr == participant_) { diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 9f9fa532e05..753d677976b 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -42,6 +42,7 @@ #include #include +#include "CLIParser.hpp" #include "types/Calculator.hpp" #include "types/CalculatorPubSubTypes.hpp" @@ -137,17 +138,43 @@ void ServerApp::on_participant_discovery( should_be_ignored = false; rtps::GuidPrefix_t remote_participant_guid_prefix = info.info.m_guid.guidPrefix; + std::string status_str = TypeConverter::to_string(info.status); - if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT) + if (info.info.m_userData.data_vec().size() != 1) { - request_reply_debug("ServerApp", "Participant discovered: " << remote_participant_guid_prefix); + should_be_ignored = true; + request_reply_debug("ServerApp", "Ignoring participant with invalid user data: " + << remote_participant_guid_prefix); } - else if (info.status == rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT) + + if (!should_be_ignored) { - client_matched_status_.match_reply_reader(remote_participant_guid_prefix, false); - client_matched_status_.match_request_writer(remote_participant_guid_prefix, false); + CLIParser::EntityKind entity_kind = static_cast(info.info.m_userData.data_vec()[0]); + if (CLIParser::EntityKind::CLIENT != entity_kind) + { + should_be_ignored = true; + request_reply_debug("ServerApp", "Ignoring " << status_str << " " + << CLIParser::parse_entity_kind(entity_kind) + << ": " << remote_participant_guid_prefix); + } + } - request_reply_debug("ServerApp", "Participant removed: " << remote_participant_guid_prefix); + if (!should_be_ignored) + { + std::string client_str = CLIParser::parse_entity_kind(CLIParser::EntityKind::CLIENT); + + if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DISCOVERED_PARTICIPANT) + { + request_reply_debug("ServerApp", client_str << " " << status_str << ": " << remote_participant_guid_prefix); + } + else if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::REMOVED_PARTICIPANT || + info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DROPPED_PARTICIPANT) + { + client_matched_status_.match_reply_reader(remote_participant_guid_prefix, false); + client_matched_status_.match_request_writer(remote_participant_guid_prefix, false); + + request_reply_debug("ServerApp", client_str << " " << status_str << ": " << remote_participant_guid_prefix); + } } } @@ -258,7 +285,12 @@ void ServerApp::create_participant() participant_mask << StatusMask::subscription_matched(); participant_mask << StatusMask::data_available(); - participant_ = factory->create_participant_with_default_profile(this, participant_mask); + DomainParticipantExtendedQos participant_qos; + factory->get_participant_extended_qos_from_default_profile(participant_qos); + + participant_qos.user_data().data_vec().push_back(static_cast(CLIParser::EntityKind::SERVER)); + + participant_ = factory->create_participant(participant_qos.domainId(), participant_qos, this, participant_mask); if (nullptr == participant_) { @@ -310,7 +342,7 @@ void ServerApp::create_request_entities( throw std::runtime_error("Failed to get default datareader qos"); } - request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos); + request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos, nullptr, StatusMask::none()); if (nullptr == request_reader_) { @@ -346,7 +378,7 @@ void ServerApp::create_reply_entities( throw std::runtime_error("Failed to get default datawriter qos"); } - reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos); + reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos, nullptr, StatusMask::none()); if (nullptr == reply_writer_) { diff --git a/examples/cpp/request_reply/app_utils.hpp b/examples/cpp/request_reply/app_utils.hpp index 9f4a3501c15..65633406cbb 100644 --- a/examples/cpp/request_reply/app_utils.hpp +++ b/examples/cpp/request_reply/app_utils.hpp @@ -34,6 +34,7 @@ #include #include +#include #include "types/Calculator.hpp" @@ -223,6 +224,35 @@ struct TypeConverter return client_id.str(); } + static std::string to_string( + const rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS& info) + { + std::string info_str = "Unknown"; + + switch (info) + { + case rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DISCOVERED_PARTICIPANT: + info_str = "discovered"; + break; + case rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::CHANGED_QOS_PARTICIPANT: + info_str = "changed QoS"; + break; + case rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::REMOVED_PARTICIPANT: + info_str = "removed"; + break; + case rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DROPPED_PARTICIPANT: + info_str = "dropped"; + break; + case rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::IGNORED_PARTICIPANT: + info_str = "ignored"; + break; + default: + break; + } + + return info_str; + } + }; struct Timestamp From 61869f6236bf41bc5e801fb56cebb038f50517d2 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 14:17:44 +0200 Subject: [PATCH 38/46] Refs #21188: Client ignores non-server participants Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 58 ++++++++++++++++++++++-- examples/cpp/request_reply/ClientApp.hpp | 11 +++-- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 659aa405196..4248dd96299 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -141,6 +141,53 @@ void ClientApp::stop() cv_.notify_all(); } +void ClientApp::on_participant_discovery( + DomainParticipant* /* participant */, + rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) +{ + std::lock_guard lock(mtx_); + + should_be_ignored = false; + + rtps::GuidPrefix_t remote_participant_guid_prefix = info.info.m_guid.guidPrefix; + std::string status_str = TypeConverter::to_string(info.status); + + if (info.info.m_userData.data_vec().size() != 1) + { + should_be_ignored = true; + request_reply_debug("ClientApp", "Ignoring participant with invalid user data: " + << remote_participant_guid_prefix); + } + + if (!should_be_ignored) + { + CLIParser::EntityKind entity_kind = static_cast(info.info.m_userData.data_vec()[0]); + if (CLIParser::EntityKind::SERVER != entity_kind) + { + should_be_ignored = true; + request_reply_debug("ClientApp", "Ignoring " << status_str << " " + << CLIParser::parse_entity_kind(entity_kind) + << ": " << remote_participant_guid_prefix); + } + } + + if (!should_be_ignored) + { + std::string server_str = CLIParser::parse_entity_kind(CLIParser::EntityKind::SERVER); + + if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DISCOVERED_PARTICIPANT) + { + request_reply_debug("ClientApp", server_str << " " << status_str << ": " << remote_participant_guid_prefix); + } + else if (info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::REMOVED_PARTICIPANT || + info.status == rtps::ParticipantDiscoveryInfo::DISCOVERY_STATUS::DROPPED_PARTICIPANT) + { + request_reply_debug("ClientApp", server_str << " " << status_str << ": " << remote_participant_guid_prefix); + } + } +} + void ClientApp::on_publication_matched( DataWriter* /* writer */, const PublicationMatchedStatus& info) @@ -265,12 +312,17 @@ void ClientApp::create_participant() throw std::runtime_error("Failed to get participant factory instance"); } + StatusMask participant_mask = StatusMask::none(); + participant_mask << StatusMask::publication_matched(); + participant_mask << StatusMask::subscription_matched(); + participant_mask << StatusMask::data_available(); + DomainParticipantExtendedQos participant_qos; factory->get_participant_extended_qos_from_default_profile(participant_qos); participant_qos.user_data().data_vec().push_back(static_cast(CLIParser::EntityKind::CLIENT)); - participant_ = factory->create_participant(participant_qos.domainId(), participant_qos); + participant_ = factory->create_participant(participant_qos.domainId(), participant_qos, this, participant_mask); if (nullptr == participant_) { @@ -323,7 +375,7 @@ void ClientApp::create_request_entities( throw std::runtime_error("Failed to get default datawriter qos"); } - request_writer_ = publisher_->create_datawriter(request_topic_, writer_qos, this, StatusMask::all()); + request_writer_ = publisher_->create_datawriter(request_topic_, writer_qos, nullptr, StatusMask::none()); if (nullptr == request_writer_) { @@ -372,7 +424,7 @@ void ClientApp::create_reply_entities( throw std::runtime_error("Failed to get default datareader qos"); } - reply_reader_ = subscriber_->create_datareader(reply_cf_topic_, reader_qos, this, StatusMask::all()); + reply_reader_ = subscriber_->create_datareader(reply_cf_topic_, reader_qos, nullptr, StatusMask::none()); if (nullptr == reply_reader_) { diff --git a/examples/cpp/request_reply/ClientApp.hpp b/examples/cpp/request_reply/ClientApp.hpp index fb4f7be8a45..84624520800 100644 --- a/examples/cpp/request_reply/ClientApp.hpp +++ b/examples/cpp/request_reply/ClientApp.hpp @@ -29,11 +29,10 @@ #include #include +#include #include -#include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ namespace request_reply { using namespace eprosima::fastdds::dds; -class ClientApp : public Application, public DataReaderListener, public DataWriterListener +class ClientApp : public Application, public DomainParticipantListener { public: @@ -69,6 +68,12 @@ class ClientApp : public Application, public DataReaderListener, public DataWrit //! Trigger the end of execution void stop() override; + //! Participant discovery method + void on_participant_discovery( + DomainParticipant* participant, + rtps::ParticipantDiscoveryInfo&& info, + bool& should_be_ignored) override; + //! Publication matched method void on_publication_matched( DataWriter* writer, From 3b769aae6d592c57431f623d6eb7553f8e11bfc2 Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 14:21:47 +0200 Subject: [PATCH 39/46] Refs #21188: Improve client log Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index 4248dd96299..f2abcf89b92 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -263,14 +263,15 @@ void ClientApp::on_data_available( if (!request_status->second) { request_status->second = true; - request_reply_info("ClientApp", - "Reply received from server " << server_guid_prefix << " with result: " << reply.result()); + request_reply_info("ClientApp", "Reply received from server " + << server_guid_prefix << " to request with ID '" << request_status->first.sequence_number() + << "' with result: '" << reply.result() << "'"); } else { - request_reply_debug("ClientApp", - "Duplicate reply received from server " << server_guid_prefix << " with result: " - << reply.result()); + request_reply_debug("ClientApp", "Duplicate reply received from server " + << server_guid_prefix << " to request with ID '" << request_status->first.sequence_number() + << "' with result: '" << reply.result() << "'"); continue; } } From a82bcccbf3efc8fd130d8e36119a12ede3b644fa Mon Sep 17 00:00:00 2001 From: eduponz Date: Wed, 10 Jul 2024 14:58:54 +0200 Subject: [PATCH 40/46] Refs #21188: Update tests Signed-off-by: eduponz --- test/examples/request_reply.compose.yml | 4 +- .../request_reply_isolated.compose.yml | 8 +-- test/examples/test_request_reply.py | 38 +++++++++++-- test/examples/test_request_reply_isolated.py | 56 ++++++++++++++++--- 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/test/examples/request_reply.compose.yml b/test/examples/request_reply.compose.yml index 3f006d43c92..1cb8b1e1da5 100644 --- a/test/examples/request_reply.compose.yml +++ b/test/examples/request_reply.compose.yml @@ -25,7 +25,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 1 + 1 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" client: image: @DOCKER_IMAGE_NAME@ @@ -38,4 +38,4 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 x 3" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 67 24" diff --git a/test/examples/request_reply_isolated.compose.yml b/test/examples/request_reply_isolated.compose.yml index 43418933cd8..2e35faf7657 100644 --- a/test/examples/request_reply_isolated.compose.yml +++ b/test/examples/request_reply_isolated.compose.yml @@ -51,7 +51,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 + 3" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5" depends_on: - server-1 - server-2 @@ -67,7 +67,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 3 - 2" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 67 24" depends_on: - server-1 - server-2 @@ -83,7 +83,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 3 x 2" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 3 2" depends_on: - server-1 - server-2 @@ -99,7 +99,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 20 / 5" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 20 5" depends_on: - server-1 - server-2 diff --git a/test/examples/test_request_reply.py b/test/examples/test_request_reply.py index 362a38b2cc9..1ea34e1b1f4 100644 --- a/test/examples/test_request_reply.py +++ b/test/examples/test_request_reply.py @@ -12,18 +12,46 @@ # See the License for the specific language governing permissions and # limitations under the License. +import re import subprocess +def parse_response(client_responses: dict, response: str): + """.""" + # Define the regex pattern with two capturing groups + pattern = r"ID '(\d+)' with result: '(-?\d+)'" + + # Use re.search to find the first match + match = re.search(pattern, response) + + if match: + id_str = match.group(1) # First capturing group + result_int = int(match.group(2)) # Second capturing group, convert to int + + client_responses[id_str] = result_int + + return client_responses + + def test_request_reply(): """.""" expected_responses = { - 'request_reply-server-client-1': 2, - 'request_reply-client-1': 6 + 'request_reply-server-client-1': { + '1': 7, + '2': -3, + '3': 10, + '4': 0 + }, + 'request_reply-client-1': { + '1': 91, + '2': 43, + '3': 1608, + '4': 2 + }, } responses = { - 'request_reply-server-client-1': None, - 'request_reply-client-1': None, + 'request_reply-server-client-1': {}, + 'request_reply-client-1': {}, } ret = True @@ -40,7 +68,7 @@ def test_request_reply(): for line in out: for client in expected_responses: if client in line and 'Reply received from server' in line: - responses[client] = int(line.rstrip().split(' ')[-1]) + responses[client] = parse_response(responses[client], line) for client in responses: if responses[client] != expected_responses[client]: diff --git a/test/examples/test_request_reply_isolated.py b/test/examples/test_request_reply_isolated.py index c706c819583..3a24794bccd 100644 --- a/test/examples/test_request_reply_isolated.py +++ b/test/examples/test_request_reply_isolated.py @@ -12,22 +12,60 @@ # See the License for the specific language governing permissions and # limitations under the License. +import re import subprocess +def parse_response(client_responses: dict, response: str): + """.""" + # Define the regex pattern with two capturing groups + pattern = r"ID '(\d+)' with result: '(-?\d+)'" + + # Use re.search to find the first match + match = re.search(pattern, response) + + if match: + id_str = match.group(1) # First capturing group + result_int = int(match.group(2)) # Second capturing group, convert to int + + client_responses[id_str] = result_int + + return client_responses + + def test_request_reply_isolated(): """.""" expected_responses = { - 'request_reply_isolated-client-1-1': 5, - 'request_reply_isolated-client-2-1': 1, - 'request_reply_isolated-client-3-1': 6, - 'request_reply_isolated-client-4-1': 4 + 'request_reply_isolated-client-1-1': { + '1': 7, + '2': -3, + '3': 10, + '4': 0 + }, + 'request_reply_isolated-client-2-1': { + '1': 91, + '2': 43, + '3': 1608, + '4': 2 + }, + 'request_reply_isolated-client-3-1': { + '1': 5, + '2': 1, + '3': 6, + '4': 1 + }, + 'request_reply_isolated-client-4-1': { + '1': 25, + '2': 15, + '3': 100, + '4': 4 + } } responses = { - 'request_reply_isolated-client-1-1': None, - 'request_reply_isolated-client-2-1': None, - 'request_reply_isolated-client-3-1': None, - 'request_reply_isolated-client-4-1': None + 'request_reply_isolated-client-1-1': {}, + 'request_reply_isolated-client-2-1': {}, + 'request_reply_isolated-client-3-1': {}, + 'request_reply_isolated-client-4-1': {} } ret = True @@ -44,7 +82,7 @@ def test_request_reply_isolated(): for line in out: for client in expected_responses: if client in line and 'Reply received from server' in line: - responses[client] = int(line.rstrip().split(' ')[-1]) + responses[client] = parse_response(responses[client], line) for client in responses: if responses[client] != expected_responses[client]: From 24923754a3938ce2643dfb2d16aa026c9d070161 Mon Sep 17 00:00:00 2001 From: eduponz Date: Thu, 11 Jul 2024 07:02:45 +0200 Subject: [PATCH 41/46] Refs #21188: Increase timeouts for CI testing Signed-off-by: eduponz --- test/examples/request_reply.compose.yml | 2 +- test/examples/request_reply_isolated.compose.yml | 4 ++-- test/examples/test_request_reply.py | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/examples/request_reply.compose.yml b/test/examples/request_reply.compose.yml index 1cb8b1e1da5..c84f9eaff9b 100644 --- a/test/examples/request_reply.compose.yml +++ b/test/examples/request_reply.compose.yml @@ -25,7 +25,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" client: image: @DOCKER_IMAGE_NAME@ diff --git a/test/examples/request_reply_isolated.compose.yml b/test/examples/request_reply_isolated.compose.yml index 2e35faf7657..d0625082fce 100644 --- a/test/examples/request_reply_isolated.compose.yml +++ b/test/examples/request_reply_isolated.compose.yml @@ -25,7 +25,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" server-2: image: @DOCKER_IMAGE_NAME@ @@ -38,7 +38,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" client-1: image: @DOCKER_IMAGE_NAME@ diff --git a/test/examples/test_request_reply.py b/test/examples/test_request_reply.py index 1ea34e1b1f4..0f394042574 100644 --- a/test/examples/test_request_reply.py +++ b/test/examples/test_request_reply.py @@ -73,13 +73,15 @@ def test_request_reply(): for client in responses: if responses[client] != expected_responses[client]: ret = False - print('ERROR: ' + client + ' expected "' + expected_responses[client] + '" but received "' + responses[client] + '"') + print(f'ERROR: {client} expected "{expected_responses[client]}" but received "{responses[client]}"') raise subprocess.CalledProcessError(1, '') except subprocess.CalledProcessError: for l in out: + ret = False print(l) except subprocess.TimeoutExpired: + ret = False print('TIMEOUT') print(out) From c0f6687764fc30e7d649242ffcc1470107f1ebc1 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 12 Jul 2024 08:31:28 +0200 Subject: [PATCH 42/46] Refs #21188: Adjust for change in write return type Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 4 ++-- examples/cpp/request_reply/ServerApp.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index f2abcf89b92..af0fea42851 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -469,7 +469,7 @@ bool ClientApp::send_request( const CalculatorRequestType& request) { rtps::WriteParams wparams; - bool ret = request_writer_->write(&request, wparams); + ReturnCode_t ret = request_writer_->write(&request, wparams); request_reply_info("ClientApp", "Request sent with ID '" << wparams.sample_identity().sequence_number() << @@ -478,7 +478,7 @@ bool ClientApp::send_request( std::lock_guard lock(mtx_); requests_status_[wparams.sample_identity()] = false; - return ret; + return (RETCODE_OK == ret); } bool ClientApp::is_stopped() diff --git a/examples/cpp/request_reply/ServerApp.cpp b/examples/cpp/request_reply/ServerApp.cpp index 753d677976b..b3ee98b9f08 100644 --- a/examples/cpp/request_reply/ServerApp.cpp +++ b/examples/cpp/request_reply/ServerApp.cpp @@ -451,7 +451,7 @@ void ServerApp::reply_routine() write_params.related_sample_identity().sequence_number(request_id); // Send the reply - if (!reply_writer_->write(&reply, write_params)) + if (RETCODE_OK != reply_writer_->write(&reply, write_params)) { // In case of failure, save the request for a later retry request_reply_error("ServerApp", From a5898aaff56a44205413f6085f7e8af2ef66a379 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 12 Jul 2024 10:32:05 +0200 Subject: [PATCH 43/46] Refs #21188: Fix data race between requests_status_ init and update Signed-off-by: eduponz --- examples/cpp/request_reply/ClientApp.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/cpp/request_reply/ClientApp.cpp b/examples/cpp/request_reply/ClientApp.cpp index af0fea42851..aa17ec00021 100644 --- a/examples/cpp/request_reply/ClientApp.cpp +++ b/examples/cpp/request_reply/ClientApp.cpp @@ -468,16 +468,19 @@ bool ClientApp::send_requests() bool ClientApp::send_request( const CalculatorRequestType& request) { + // Taking the mutex here to avoid taking a reply on the on_data_available callback + // coming from a very fast server who replied before the request_status_ entry was set + std::lock_guard lock(mtx_); + rtps::WriteParams wparams; ReturnCode_t ret = request_writer_->write(&request, wparams); + requests_status_[wparams.sample_identity()] = false; + request_reply_info("ClientApp", "Request sent with ID '" << wparams.sample_identity().sequence_number() << "': '" << TypeConverter::to_string(request) << "'"); - std::lock_guard lock(mtx_); - requests_status_[wparams.sample_identity()] = false; - return (RETCODE_OK == ret); } From 6a51220273b31cbc5f35a1ab13ed63927e8c82c6 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 12 Jul 2024 10:35:32 +0200 Subject: [PATCH 44/46] Refs #21188: Take timeouts back to 3s Signed-off-by: eduponz --- test/examples/request_reply.compose.yml | 2 +- test/examples/request_reply_isolated.compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/examples/request_reply.compose.yml b/test/examples/request_reply.compose.yml index c84f9eaff9b..1cb8b1e1da5 100644 --- a/test/examples/request_reply.compose.yml +++ b/test/examples/request_reply.compose.yml @@ -25,7 +25,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" client: image: @DOCKER_IMAGE_NAME@ diff --git a/test/examples/request_reply_isolated.compose.yml b/test/examples/request_reply_isolated.compose.yml index d0625082fce..2e35faf7657 100644 --- a/test/examples/request_reply_isolated.compose.yml +++ b/test/examples/request_reply_isolated.compose.yml @@ -25,7 +25,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" server-2: image: @DOCKER_IMAGE_NAME@ @@ -38,7 +38,7 @@ services: LD_LIBRARY_PATH: @PROJECT_BINARY_DIR@/src/cpp:@fastcdr_LIB_DIR@@TINYXML2_LIB_DIR_COMPOSE_LD_LIBRARY_PATH@ EXAMPLE_DIR: @PROJECT_BINARY_DIR@/examples/cpp/request_reply@FILE_EXTENSION@ FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml - command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 10 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" + command: @SHELL_EXECUTABLE@ -c "timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" client-1: image: @DOCKER_IMAGE_NAME@ From a39e04135e2eab02e17e1340212ee61cd625a156 Mon Sep 17 00:00:00 2001 From: eduponz Date: Fri, 12 Jul 2024 11:16:58 +0200 Subject: [PATCH 45/46] Refs #21188: Remove compose name from clients to cope with different docker compose versions Signed-off-by: eduponz --- test/examples/test_request_reply.py | 8 ++++---- test/examples/test_request_reply_isolated.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/examples/test_request_reply.py b/test/examples/test_request_reply.py index 0f394042574..3864bb29730 100644 --- a/test/examples/test_request_reply.py +++ b/test/examples/test_request_reply.py @@ -35,13 +35,13 @@ def parse_response(client_responses: dict, response: str): def test_request_reply(): """.""" expected_responses = { - 'request_reply-server-client-1': { + 'server-client-1': { '1': 7, '2': -3, '3': 10, '4': 0 }, - 'request_reply-client-1': { + 'client-1': { '1': 91, '2': 43, '3': 1608, @@ -50,8 +50,8 @@ def test_request_reply(): } responses = { - 'request_reply-server-client-1': {}, - 'request_reply-client-1': {}, + 'server-client-1': {}, + 'client-1': {}, } ret = True diff --git a/test/examples/test_request_reply_isolated.py b/test/examples/test_request_reply_isolated.py index 3a24794bccd..cba2c1a5d9e 100644 --- a/test/examples/test_request_reply_isolated.py +++ b/test/examples/test_request_reply_isolated.py @@ -35,25 +35,25 @@ def parse_response(client_responses: dict, response: str): def test_request_reply_isolated(): """.""" expected_responses = { - 'request_reply_isolated-client-1-1': { + 'client-1-1': { '1': 7, '2': -3, '3': 10, '4': 0 }, - 'request_reply_isolated-client-2-1': { + 'client-2-1': { '1': 91, '2': 43, '3': 1608, '4': 2 }, - 'request_reply_isolated-client-3-1': { + 'client-3-1': { '1': 5, '2': 1, '3': 6, '4': 1 }, - 'request_reply_isolated-client-4-1': { + 'client-4-1': { '1': 25, '2': 15, '3': 100, @@ -62,10 +62,10 @@ def test_request_reply_isolated(): } responses = { - 'request_reply_isolated-client-1-1': {}, - 'request_reply_isolated-client-2-1': {}, - 'request_reply_isolated-client-3-1': {}, - 'request_reply_isolated-client-4-1': {} + 'client-1-1': {}, + 'client-2-1': {}, + 'client-3-1': {}, + 'client-4-1': {} } ret = True From 130a91139bd477d892b97065a4efd2658d995522 Mon Sep 17 00:00:00 2001 From: eduponz Date: Mon, 15 Jul 2024 16:19:06 +0200 Subject: [PATCH 46/46] Refs #21188: Apply Eliana's suggestions Signed-off-by: eduponz --- test/examples/request_reply.compose.yml | 2 +- test/examples/test_request_reply.py | 4 ++-- test/examples/test_request_reply_isolated.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/examples/request_reply.compose.yml b/test/examples/request_reply.compose.yml index 1cb8b1e1da5..d5399d18cc8 100644 --- a/test/examples/request_reply.compose.yml +++ b/test/examples/request_reply.compose.yml @@ -27,7 +27,7 @@ services: FASTDDS_DEFAULT_PROFILES_FILE: @PROJECT_BINARY_DIR@/examples/cpp/request_reply/request_reply_profile.xml command: @SHELL_EXECUTABLE@ -c "$${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ client 2 5 & timeout --preserve-status 3 $${EXAMPLE_DIR}/request_reply@FILE_EXTENSION@ server" - client: + alone-client: image: @DOCKER_IMAGE_NAME@ volumes: - @PROJECT_BINARY_DIR@:@PROJECT_BINARY_DIR@ diff --git a/test/examples/test_request_reply.py b/test/examples/test_request_reply.py index 3864bb29730..b0941099093 100644 --- a/test/examples/test_request_reply.py +++ b/test/examples/test_request_reply.py @@ -41,7 +41,7 @@ def test_request_reply(): '3': 10, '4': 0 }, - 'client-1': { + 'alone-client-1': { '1': 91, '2': 43, '3': 1608, @@ -51,7 +51,7 @@ def test_request_reply(): responses = { 'server-client-1': {}, - 'client-1': {}, + 'alone-client-1': {}, } ret = True diff --git a/test/examples/test_request_reply_isolated.py b/test/examples/test_request_reply_isolated.py index cba2c1a5d9e..4a504a2cc00 100644 --- a/test/examples/test_request_reply_isolated.py +++ b/test/examples/test_request_reply_isolated.py @@ -87,7 +87,7 @@ def test_request_reply_isolated(): for client in responses: if responses[client] != expected_responses[client]: ret = False - print('ERROR: ' + client + ' expected "' + expected_responses[client] + '" but received "' + responses[client] + '"') + print(f'ERROR: {client} expected "{expected_responses[client]} but received "{responses[client]}') raise subprocess.CalledProcessError(1, '') except subprocess.CalledProcessError: