From 5acae62bbe1e4e6e651e9dbb4842fb8ad0547c92 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Mon, 10 Dec 2018 13:32:16 +0100 Subject: [PATCH 01/34] Create Environment Variable for default XML file (#334) * Refs #3937. Create the management to check if exists an environment variable to load the DEFAULT_FASTRTPS_PROFILES.xml * Refs #3941 Update GETENV management in Windows to avoid mallocs * Refs #3937. Update the code with some suggestions from the pull request --- include/fastrtps/xmlparser/XMLParserCommon.h | 1 + .../fastrtps/xmlparser/XMLProfileManager.h | 2 +- src/cpp/xmlparser/XMLParserCommon.cpp | 1 + src/cpp/xmlparser/XMLProfileManager.cpp | 25 ++++++++++++++++--- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/fastrtps/xmlparser/XMLParserCommon.h b/include/fastrtps/xmlparser/XMLParserCommon.h index 742457ea8a3..90e4335fea4 100644 --- a/include/fastrtps/xmlparser/XMLParserCommon.h +++ b/include/fastrtps/xmlparser/XMLParserCommon.h @@ -33,6 +33,7 @@ enum class XMLP_ret }; +extern const char* DEFAULT_FASTRTPS_ENV_VARIABLE; extern const char* DEFAULT_FASTRTPS_PROFILES; extern const char* ROOT; diff --git a/include/fastrtps/xmlparser/XMLProfileManager.h b/include/fastrtps/xmlparser/XMLProfileManager.h index 9623045676a..6ddca1f7bfa 100644 --- a/include/fastrtps/xmlparser/XMLProfileManager.h +++ b/include/fastrtps/xmlparser/XMLProfileManager.h @@ -57,7 +57,7 @@ class XMLProfileManager * Load the default profiles XML file. * @return XMLP_ret::XML_OK on success, XMLP_ret::XML_ERROR in other case. */ - RTPS_DllAPI static XMLP_ret loadDefaultXMLFile(); + RTPS_DllAPI static void loadDefaultXMLFile(); /** * Load a profiles XML file. diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index 407a09835f9..c8af1a02e49 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -18,6 +18,7 @@ namespace eprosima { namespace fastrtps { namespace xmlparser { +const char* DEFAULT_FASTRTPS_ENV_VARIABLE = "FASTRTPS_DEFAULT_PROFILES_FILE"; const char* DEFAULT_FASTRTPS_PROFILES = "DEFAULT_FASTRTPS_PROFILES.xml"; const char* ROOT = "dds"; diff --git a/src/cpp/xmlparser/XMLProfileManager.cpp b/src/cpp/xmlparser/XMLProfileManager.cpp index 5470fda4543..17668d1dbe0 100644 --- a/src/cpp/xmlparser/XMLProfileManager.cpp +++ b/src/cpp/xmlparser/XMLProfileManager.cpp @@ -15,7 +15,10 @@ #include #include #include - +#include +#ifdef _WIN32 +#include +#endif namespace eprosima { namespace fastrtps { namespace xmlparser { @@ -102,9 +105,25 @@ void XMLProfileManager::getDefaultTopicAttributes(TopicAttributes& topic_attribu topic_attributes = default_topic_attributes; } -XMLP_ret XMLProfileManager::loadDefaultXMLFile() +void XMLProfileManager::loadDefaultXMLFile() { - return loadXMLFile(DEFAULT_FASTRTPS_PROFILES); + // Try to load the default XML file set with an environment variable. +#ifdef _WIN32 + char file_path[MAX_PATH]; + size_t size = MAX_PATH; + if (getenv_s(&size, file_path, size, DEFAULT_FASTRTPS_ENV_VARIABLE) == 0 && size > 0) + { + loadXMLFile(file_path); + } +#else + if (const char* file_path = std::getenv(DEFAULT_FASTRTPS_ENV_VARIABLE)) + { + loadXMLFile(file_path); + } +#endif + + // Try to load the default XML file. + loadXMLFile(DEFAULT_FASTRTPS_PROFILES); } XMLP_ret XMLProfileManager::loadXMLProfiles(tinyxml2::XMLElement& profiles) From 3d714b9a49fa35c90bddc2936a6c1546142b4471 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Tue, 11 Dec 2018 07:19:03 +0100 Subject: [PATCH 02/34] Refs #3794. Fix compilation issues using Codeblocks for Windows (#317) --- include/fastrtps/utils/eClock.h | 16 ++++++++-------- src/cpp/CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/fastrtps/utils/eClock.h b/include/fastrtps/utils/eClock.h index d2be5c5a275..1cab2adc04f 100644 --- a/include/fastrtps/utils/eClock.h +++ b/include/fastrtps/utils/eClock.h @@ -22,19 +22,19 @@ #if defined(_WIN32) #include -#include +#include #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 + +struct timezone +{ + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; #else #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif - -struct timezone -{ - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - + #else #include diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 379d7c9a49c..2f72ac6587d 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -194,7 +194,7 @@ else() set(HAVE_SECURITY 0) endif() -if(WIN32) +if(WIN32 AND (MSVC OR MSVC_IDE)) list(APPEND ${PROJECT_NAME}_source_files ${PROJECT_SOURCE_DIR}/src/cpp/fastrtps.rc ) From dc5eb23edfc4d4678fd1916c3171fe490a687efc Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Tue, 18 Dec 2018 16:30:18 +0100 Subject: [PATCH 03/34] Log FileConsumer [3709] (#298) * Refs #3697 Implementation of FileConsumer and XML parsing of Log configuration. * Refs #3697 PR requested changes (doxygen) * Refs #3709 Update the loggers and the xmlparser with the suggestions on GitHub * Refs #4021 Refactor logging and XMLProfiles tests to split the tests of logs into logs management and parsing. * Refs #3709 Improved timestamp and common methods. * Refs #3709 WIP Adding mocked Log * Refs #3709 WIP some fixes. * Refs #3709 XML log tests no longer test behavior, only configuration parsed. * Refs #3709. Added gmock to xmlparser tests. * Refs #3709 RegisterConsumer signature changed to use r-value, to make clear the unique_ptr ownership will be transferred. * Refs #3709 Trying to fix compilation warnings. * Refs #3709 Trying to fix compilation warnings in windows and mac. * Refs #3709 Fixed leak in mocked class. * Refs #3709 Fixed clearing consumers while messages pending. * Refs #3709 Removed too many mutex. --- examples/C++/Benchmark/BenchmarkPublisher.cpp | 2 + examples/C++/Benchmark/BenchmarkPublisher.h | 3 + .../HelloWorldPublisher.cpp | 2 + .../HelloWorldExample/HelloWorldPublisher.cpp | 2 + .../HelloWorldPublisher.cpp | 2 + .../attributes/ParticipantAttributes.h | 4 - .../fastrtps/attributes/PublisherAttributes.h | 2 - include/fastrtps/attributes/TopicAttributes.h | 45 +-- include/fastrtps/fastrtps_all.h | 1 - include/fastrtps/log/FileConsumer.h | 66 ++++ include/fastrtps/log/Log.h | 247 ++++++++------- include/fastrtps/log/StdoutConsumer.h | 1 + include/fastrtps/rtps/rtps_all.h | 1 - include/fastrtps/utils/DBQueue.h | 20 +- include/fastrtps/xmlparser/XMLParser.h | 13 + include/fastrtps/xmlparser/XMLParserCommon.h | 5 + .../fastrtps/xmlparser/XMLProfileManager.h | 5 +- include/fastrtps/xmlparser/XMLTree.h | 3 +- resources/xsd/fastRTPS_profiles.xsd | 16 + src/cpp/CMakeLists.txt | 2 + src/cpp/attributes/TopicAttributes.cpp | 62 ++++ src/cpp/log/FileConsumer.cpp | 52 ++++ src/cpp/log/Log.cpp | 293 ++++++++++++------ src/cpp/log/StdoutConsumer.cpp | 43 +-- src/cpp/xmlparser/XMLElementParser.cpp | 3 +- src/cpp/xmlparser/XMLParser.cpp | 173 ++++++++++- src/cpp/xmlparser/XMLParserCommon.cpp | 5 + src/cpp/xmlparser/XMLProfileManager.cpp | 16 +- .../mock/rtps/Log/fastrtps/log/FileConsumer.h | 49 +++ test/mock/rtps/Log/fastrtps/log/Log.h | 83 +++++ .../rtps/Log/fastrtps/log/StdoutConsumer.h | 28 ++ test/unittest/dynamic_types/CMakeLists.txt | 1 + test/unittest/logging/CMakeLists.txt | 46 ++- test/unittest/logging/LogFileTests.cpp | 117 +++++++ test/unittest/logging/LogTests.cpp | 171 +++++----- test/unittest/xmlparser/CMakeLists.txt | 61 ++-- .../xmlparser/XMLProfileParserTests.cpp | 39 ++- test/unittest/xmlparser/log_def_file.xml | 9 + test/unittest/xmlparser/log_inactive.xml | 6 + .../xmlparser/log_node_file_append.xml | 17 + 40 files changed, 1270 insertions(+), 446 deletions(-) create mode 100644 include/fastrtps/log/FileConsumer.h create mode 100644 src/cpp/attributes/TopicAttributes.cpp create mode 100644 src/cpp/log/FileConsumer.cpp create mode 100644 test/mock/rtps/Log/fastrtps/log/FileConsumer.h create mode 100644 test/mock/rtps/Log/fastrtps/log/Log.h create mode 100644 test/mock/rtps/Log/fastrtps/log/StdoutConsumer.h create mode 100644 test/unittest/logging/LogFileTests.cpp create mode 100644 test/unittest/xmlparser/log_def_file.xml create mode 100644 test/unittest/xmlparser/log_inactive.xml create mode 100644 test/unittest/xmlparser/log_node_file_append.xml diff --git a/examples/C++/Benchmark/BenchmarkPublisher.cpp b/examples/C++/Benchmark/BenchmarkPublisher.cpp index bd5b04bc6da..8b59986640f 100644 --- a/examples/C++/Benchmark/BenchmarkPublisher.cpp +++ b/examples/C++/Benchmark/BenchmarkPublisher.cpp @@ -32,6 +32,8 @@ #include #include +#include + using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; diff --git a/examples/C++/Benchmark/BenchmarkPublisher.h b/examples/C++/Benchmark/BenchmarkPublisher.h index 3503589fb8b..46bc24d85a4 100644 --- a/examples/C++/Benchmark/BenchmarkPublisher.h +++ b/examples/C++/Benchmark/BenchmarkPublisher.h @@ -37,6 +37,9 @@ #include "Benchmark_medium.h" #include "Benchmark_big.h" +#include +#include + class BenchMarkPublisher { public: BenchMarkPublisher(); diff --git a/examples/C++/DynamicHelloWorldExample/HelloWorldPublisher.cpp b/examples/C++/DynamicHelloWorldExample/HelloWorldPublisher.cpp index a65ca5da787..b80896d7e1d 100644 --- a/examples/C++/DynamicHelloWorldExample/HelloWorldPublisher.cpp +++ b/examples/C++/DynamicHelloWorldExample/HelloWorldPublisher.cpp @@ -31,6 +31,8 @@ #include #include +#include + using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; diff --git a/examples/C++/HelloWorldExample/HelloWorldPublisher.cpp b/examples/C++/HelloWorldExample/HelloWorldPublisher.cpp index e5b89076336..cbe6b7c433e 100644 --- a/examples/C++/HelloWorldExample/HelloWorldPublisher.cpp +++ b/examples/C++/HelloWorldExample/HelloWorldPublisher.cpp @@ -25,6 +25,8 @@ #include #include +#include + using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; diff --git a/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp b/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp index 6eac662836d..c3964089210 100644 --- a/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp +++ b/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp @@ -28,6 +28,8 @@ #include #include +#include + using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; diff --git a/include/fastrtps/attributes/ParticipantAttributes.h b/include/fastrtps/attributes/ParticipantAttributes.h index ff468ba27ca..e43e8516380 100644 --- a/include/fastrtps/attributes/ParticipantAttributes.h +++ b/include/fastrtps/attributes/ParticipantAttributes.h @@ -22,8 +22,6 @@ #include "../rtps/attributes/RTPSParticipantAttributes.h" - - namespace eprosima{ namespace fastrtps{ @@ -51,6 +49,4 @@ class ParticipantAttributes } } - - #endif /* PARTICIPANTATTRIBUTES_H_ */ diff --git a/include/fastrtps/attributes/PublisherAttributes.h b/include/fastrtps/attributes/PublisherAttributes.h index d1a971b61ad..012c6d1564e 100644 --- a/include/fastrtps/attributes/PublisherAttributes.h +++ b/include/fastrtps/attributes/PublisherAttributes.h @@ -29,8 +29,6 @@ #include "../qos/WriterQos.h" #include "../rtps/attributes/PropertyPolicy.h" - - namespace eprosima { namespace fastrtps{ diff --git a/include/fastrtps/attributes/TopicAttributes.h b/include/fastrtps/attributes/TopicAttributes.h index 63905d31b2d..e3a3ceb55f3 100644 --- a/include/fastrtps/attributes/TopicAttributes.h +++ b/include/fastrtps/attributes/TopicAttributes.h @@ -22,10 +22,7 @@ #include #include "../rtps/common/Types.h" - #include "../qos/QosPolicies.h" -#include "../log/Log.h" - namespace eprosima { @@ -68,7 +65,7 @@ class TopicAttributes (this->topicDataType == b.topicDataType) && (this->historyQos == b.historyQos); } - + /** * Get the topic data type * @return Topic data type @@ -127,45 +124,7 @@ class TopicAttributes * Method to check whether the defined QOS are correct. * @return True if they are valid. */ - bool checkQos() const - { - if(resourceLimitsQos.max_samples_per_instance > resourceLimitsQos.max_samples && topicKind == rtps::WITH_KEY) - { - logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"):max_samples_per_instance must be <= than max_samples"); - return false; - } - - if (resourceLimitsQos.max_samples_per_instance*resourceLimitsQos.max_instances > resourceLimitsQos.max_samples && topicKind == rtps::WITH_KEY) - { - logWarning(RTPS_QOS_CHECK, "TOPIC QOS: max_samples < max_samples_per_instance*max_instances"); - } - - if(historyQos.kind == KEEP_LAST_HISTORY_QOS) - { - if(historyQos.depth > resourceLimitsQos.max_samples) - { - logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be <= max_samples"); - return false; - } - if(historyQos.depth > resourceLimitsQos.max_samples_per_instance && topicKind == rtps::WITH_KEY) - { - logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be <= max_samples_per_instance"); - return false; - } - if(historyQos.depth <=0 ) - { - logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be > 0"); - return false; - } - } - - if(resourceLimitsQos.max_samples != 0 && resourceLimitsQos.allocated_samples > resourceLimitsQos.max_samples) - { - logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): max_samples < allocated_samples"); - return false; - } - return true; - } + bool checkQos() const; }; #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC diff --git a/include/fastrtps/fastrtps_all.h b/include/fastrtps/fastrtps_all.h index 37657418fad..c0a7302ead7 100644 --- a/include/fastrtps/fastrtps_all.h +++ b/include/fastrtps/fastrtps_all.h @@ -44,7 +44,6 @@ #include "TopicDataType.h" #include "utils/IPFinder.h" -#include "log/Log.h" #include "utils/eClock.h" #include "utils/TimeConversion.h" diff --git a/include/fastrtps/log/FileConsumer.h b/include/fastrtps/log/FileConsumer.h new file mode 100644 index 00000000000..ab12a311571 --- /dev/null +++ b/include/fastrtps/log/FileConsumer.h @@ -0,0 +1,66 @@ +// 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 FileConsumer.h + * + */ + +#ifndef FILE_CONSUMER_H +#define FILE_CONSUMER_H + +#include + +#include + +namespace eprosima { +namespace fastrtps { + +/** + * Log consumer that writes the log events to a file. + * + * @file FileConsumer.h + */ +class FileConsumer : public LogConsumer { +public: + //! Default constructor: filename = "output.log", append = false. + RTPS_DllAPI FileConsumer(); + + /** Constructor with parameters. + * @param filename path of the output file where the log will be wrote. + * @param append indicates if the consumer must append the content in the filename. + */ + RTPS_DllAPI FileConsumer(const std::string &filename, bool append = false); + + /** \internal + * Called by Log to ask us to consume the Entry. + * @param Log::Entry to consume. + */ + RTPS_DllAPI virtual void Consume(const Log::Entry&); + + virtual ~FileConsumer(); + +private: + void PrintHeader(const Log::Entry&); + void PrintContext(const Log::Entry&); + + std::string mOutputFile; + std::ofstream mFile; + bool mAppend; +}; + +} // namespace fastrtps +} // namespace eprosima + +#endif // FILE_CONSUMER_H diff --git a/include/fastrtps/log/Log.h b/include/fastrtps/log/Log.h index 4ed77579d6b..a9ad6580791 100644 --- a/include/fastrtps/log/Log.h +++ b/include/fastrtps/log/Log.h @@ -24,8 +24,8 @@ #include /** - * eProsima log layer. Logging categories and verbosities can be specified dynamically at runtime. However, even on a category - * not covered by the current verbosity level, there is some overhead on calling a log macro. For maximum performance, you can + * eProsima log layer. Logging categories and verbosities can be specified dynamically at runtime. However, even on a category + * not covered by the current verbosity level, there is some overhead on calling a log macro. For maximum performance, you can * opt out of logging any particular level by defining the following symbols: * * * #define LOG_NO_ERROR @@ -38,11 +38,11 @@ // Logging API: //! Logs an info message. Disable it through Log::SetVerbosity, #define LOG_NO_INFO, or being in a release branch -#define logInfo(cat,msg) logInfo_(cat,msg) +#define logInfo(cat, msg) logInfo_(cat, msg) //! Logs a warning. Disable reporting through Log::SetVerbosity or #define LOG_NO_WARNING -#define logWarning(cat,msg) logWarning_(cat,msg) +#define logWarning(cat, msg) logWarning_(cat, msg) //! Logs an error. Disable reporting through #define LOG_NO_ERROR -#define logError(cat,msg) logError_(cat,msg) +#define logError(cat, msg) logError_(cat, msg) namespace eprosima { namespace fastrtps { @@ -52,142 +52,177 @@ class LogConsumer; /** * Logging utilities. * Logging is accessed through the three macros above, and configuration on the log output - * can be achieved through static methods on the class. Logging at various levels can be + * can be achieved through static methods on the class. Logging at various levels can be * disabled dynamically (through the Verbosity level) or statically (through the LOG_NO_[VERB] * macros) for maximum performance. * @ingroup COMMON_MODULE */ class Log { -public: - /** + public: + /** * Types of log entry. * * Error: Maximum priority. Can only be disabled statically through #define LOG_NO_ERROR. * * Warning: Medium priority. Can be disabled statically and dynamically. * * Info: Low priority. Useful for debugging. Disabled by default on release branches. */ - enum Kind { - Error, - Warning, - Info, - }; - - /** - * Registers an user defined consumer to route log output. There is a default - * stdout consumer active at all times. + enum Kind + { + Error, + Warning, + Info, + }; + + /** + * Registers an user defined consumer to route log output. + * There is a default stdout consumer active as default. + * @param consumer r-value to a consumer unique_ptr. It will be invalidated after the call. */ - RTPS_DllAPI static void RegisterConsumer(std::unique_ptr); - //! Enables the reporting of filenames in log entries. Disabled by default. - RTPS_DllAPI static void ReportFilenames(bool); - //! Enables the reporting of function names in log entries. Enabled by default when supported. - RTPS_DllAPI static void ReportFunctions(bool); - //! Sets the verbosity level, allowing for messages equal or under that priority to be logged. - RTPS_DllAPI static void SetVerbosity(Log::Kind); - //! Returns the current verbosity level. - RTPS_DllAPI static Log::Kind GetVerbosity(); - //! Sets a filter that will pattern-match against log categories, dropping any unmatched categories. - RTPS_DllAPI static void SetCategoryFilter (const std::regex&); - //! Sets a filter that will pattern-match against filenames, dropping any unmatched categories. - RTPS_DllAPI static void SetFilenameFilter (const std::regex&); - //! Sets a filter that will pattern-match against the provided error string, dropping any unmatched categories. - RTPS_DllAPI static void SetErrorStringFilter (const std::regex&); - //! Returns the logging engine to configuration defaults. - RTPS_DllAPI static void Reset(); - //! Stops the logging thread. It will re-launch on the next call to a successful log macro. - RTPS_DllAPI static void KillThread(); - // Note: In VS2013, if you're linking this class statically, you will have to call KillThread before leaving - // main, due to an unsolved MSVC bug. - - struct Context { - const char* filename; - int line; - const char* function; - const char* category; - }; - - struct Entry - { - std::string message; - Log::Context context; - Log::Kind kind; - }; - - /** + RTPS_DllAPI static void RegisterConsumer(std::unique_ptr &&); + //! Removes all registered consumers, including the default stdout. + RTPS_DllAPI static void ClearConsumers(); + //! Enables the reporting of filenames in log entries. Disabled by default. + RTPS_DllAPI static void ReportFilenames(bool); + //! Enables the reporting of function names in log entries. Enabled by default when supported. + RTPS_DllAPI static void ReportFunctions(bool); + //! Sets the verbosity level, allowing for messages equal or under that priority to be logged. + RTPS_DllAPI static void SetVerbosity(Log::Kind); + //! Returns the current verbosity level. + RTPS_DllAPI static Log::Kind GetVerbosity(); + //! Sets a filter that will pattern-match against log categories, dropping any unmatched categories. + RTPS_DllAPI static void SetCategoryFilter(const std::regex &); + //! Sets a filter that will pattern-match against filenames, dropping any unmatched categories. + RTPS_DllAPI static void SetFilenameFilter(const std::regex &); + //! Sets a filter that will pattern-match against the provided error string, dropping any unmatched categories. + RTPS_DllAPI static void SetErrorStringFilter(const std::regex &); + //! Returns the logging engine to configuration defaults. + RTPS_DllAPI static void Reset(); + //! Stops the logging thread. It will re-launch on the next call to a successful log macro. + RTPS_DllAPI static void KillThread(); + // Note: In VS2013, if you're linking this class statically, you will have to call KillThread before leaving + // main, due to an unsolved MSVC bug. + + struct Context + { + const char *filename; + int line; + const char *function; + const char *category; + }; + + struct Entry + { + std::string message; + Log::Context context; + Log::Kind kind; + std::string timestamp; + }; + + /** * Not recommended to call this method directly! Use the following macros: * * logInfo(cat, msg); * * logWarning(cat, msg); * * logError(cat, msg); */ - RTPS_DllAPI static void QueueLog(const std::string& message, const Log::Context&, Log::Kind); - -private: - struct Resources - { - DBQueue mLogs; - std::vector > mConsumers; - std::unique_ptr mDefaultConsumer; - - std::unique_ptr mLoggingThread; - - // Condition variable segment. - std::condition_variable mCv; - std::mutex mCvMutex; - bool mLogging; - bool mWork; - - // Context configuration. - std::mutex mConfigMutex; - bool mFilenames; - bool mFunctions; - std::unique_ptr mCategoryFilter; - std::unique_ptr mFilenameFilter; - std::unique_ptr mErrorStringFilter; - - std::atomic mVerbosity; - - Resources(); - ~Resources(); - }; - - static struct Resources mResources; - - // Applies transformations to the entries compliant with the options selected (such as - // erasure of certain context information, or filtering by category. Returns false - // if the log entry is blacklisted. - static bool Preprocess(Entry&); - static void LaunchThread(); - static void Run(); + RTPS_DllAPI static void QueueLog(const std::string &message, const Log::Context &, Log::Kind); + + private: + struct Resources + { + DBQueue mLogs; + std::vector> mConsumers; + + std::unique_ptr mLoggingThread; + + // Condition variable segment. + std::condition_variable mCv; + std::mutex mCvMutex; + bool mLogging; + bool mWork; + + // Context configuration. + std::mutex mConfigMutex; + bool mFilenames; + bool mFunctions; + std::unique_ptr mCategoryFilter; + std::unique_ptr mFilenameFilter; + std::unique_ptr mErrorStringFilter; + + std::atomic mVerbosity; + + Resources(); + ~Resources(); + }; + + static struct Resources mResources; + + // Applies transformations to the entries compliant with the options selected (such as + // erasure of certain context information, or filtering by category. Returns false + // if the log entry is blacklisted. + static bool Preprocess(Entry &); + static void LaunchThread(); + static void Run(); + static void GetTimestamp(std::string &); }; /** * Consumes a log entry to output it somewhere. */ -class LogConsumer { -public: - virtual ~LogConsumer(){}; - virtual void Consume(const Log::Entry&) = 0; +class LogConsumer +{ + public: + virtual ~LogConsumer(){}; + virtual void Consume(const Log::Entry &) = 0; + + protected: + void PrintTimestamp(std::ostream &stream, const Log::Entry &, bool color) const; + void PrintHeader(std::ostream &stream, const Log::Entry &, bool color) const; + void PrintContext(std::ostream &stream, const Log::Entry &, bool color) const; + void PrintMessage(std::ostream &stream, const Log::Entry &, bool color) const; + void PrintNewLine(std::ostream &stream, bool color) const; }; -#if defined ( WIN32 ) - #define __func__ __FUNCTION__ +#if defined(WIN32) +#define __func__ __FUNCTION__ #endif #ifndef LOG_NO_ERROR - #define logError_(cat, msg) {std::stringstream ss; ss << msg; Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Error); } +#define logError_(cat, msg) \ + { \ + std::stringstream ss; \ + ss << msg; \ + Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Error); \ + } #else - #define logError_(cat, msg) +#define logError_(cat, msg) #endif #ifndef LOG_NO_WARNING - #define logWarning_(cat, msg) { if (Log::GetVerbosity() >= Log::Kind::Warning) { std::stringstream ss; ss << msg; Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Warning); } } -#else - #define logWarning_(cat, msg) +#define logWarning_(cat, msg) \ + { \ + if (Log::GetVerbosity() >= Log::Kind::Warning) \ + { \ + std::stringstream ss; \ + ss << msg; \ + Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Warning); \ + } \ + } +#else +#define logWarning_(cat, msg) #endif #if (defined(__INTERNALDEBUG) || defined(_INTERNALDEBUG)) && (defined(_DEBUG) || defined(__DEBUG)) && (!defined(LOG_NO_INFO)) - #define logInfo_(cat, msg) { if (Log::GetVerbosity() >= Log::Kind::Info) { std::stringstream ss; ss << msg; Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Info); } } +#define logInfo_(cat, msg) \ + { \ + if (Log::GetVerbosity() >= Log::Kind::Info) \ + { \ + std::stringstream ss; \ + ss << msg; \ + Log::QueueLog(ss.str(), Log::Context{__FILE__, __LINE__, __func__, #cat}, Log::Kind::Info); \ + } \ + } #else - #define logInfo_(cat, msg) +#define logInfo_(cat, msg) #endif } // namespace fastrtps diff --git a/include/fastrtps/log/StdoutConsumer.h b/include/fastrtps/log/StdoutConsumer.h index c9fd3c60844..3fb43043936 100644 --- a/include/fastrtps/log/StdoutConsumer.h +++ b/include/fastrtps/log/StdoutConsumer.h @@ -22,6 +22,7 @@ namespace fastrtps { class StdoutConsumer: public LogConsumer { public: + virtual ~StdoutConsumer() {}; RTPS_DllAPI virtual void Consume(const Log::Entry&); private: diff --git a/include/fastrtps/rtps/rtps_all.h b/include/fastrtps/rtps/rtps_all.h index e2fedbafa14..dabb99114b9 100644 --- a/include/fastrtps/rtps/rtps_all.h +++ b/include/fastrtps/rtps/rtps_all.h @@ -39,7 +39,6 @@ #include "history/ReaderHistory.h" #include "../utils/IPFinder.h" -#include "../log/Log.h" #include "../utils/eClock.h" #include "../utils/TimeConversion.h" diff --git a/include/fastrtps/utils/DBQueue.h b/include/fastrtps/utils/DBQueue.h index 7ff8024cd6f..dfa30240aa7 100644 --- a/include/fastrtps/utils/DBQueue.h +++ b/include/fastrtps/utils/DBQueue.h @@ -26,7 +26,7 @@ namespace fastrtps{ /** * Double buffered, threadsafe queue for MPSC (multi-producer, single-consumer) comms. */ -template +template class DBQueue { public: @@ -34,9 +34,9 @@ class DBQueue { mForegroundQueue(&mQueueAlpha), mBackgroundQueue(&mQueueBeta) {} - + //! Clears foreground queue and swaps queues. - void Swap() + void Swap() { std::unique_lock fgGuard(mForegroundMutex); std::unique_lock bgGuard(mBackgroundMutex); @@ -44,13 +44,13 @@ class DBQueue { // Clear the foreground queue. std::queue().swap(*mForegroundQueue); - auto* swap = mBackgroundQueue; + auto* swap = mBackgroundQueue; mBackgroundQueue = mForegroundQueue; mForegroundQueue = swap; } //! Pushes to the background queue. - void Push(const T& item) + void Push(const T& item) { std::unique_lock guard(mBackgroundMutex); mBackgroundQueue->push(item); @@ -71,7 +71,7 @@ class DBQueue { } //! Pops from the foreground queue. - void Pop() + void Pop() { std::unique_lock guard(mForegroundMutex); mForegroundQueue->pop(); @@ -84,6 +84,14 @@ class DBQueue { return mForegroundQueue->empty(); } + //! Reports whether the both queues are empty. + bool BothEmpty() const + { + std::unique_lock guard(mForegroundMutex); + std::unique_lock bgGuard(mBackgroundMutex); + return mForegroundQueue->empty() && mBackgroundQueue->empty(); + } + //! Reports the size of the foreground queue. size_t Size() const { diff --git a/include/fastrtps/xmlparser/XMLParser.h b/include/fastrtps/xmlparser/XMLParser.h index 7d6afef14d5..a371585d8ee 100644 --- a/include/fastrtps/xmlparser/XMLParser.h +++ b/include/fastrtps/xmlparser/XMLParser.h @@ -129,6 +129,12 @@ class XMLParser RTPS_DllAPI static XMLP_ret parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profilesNode); RTPS_DllAPI static XMLP_ret parseRoot(tinyxml2::XMLElement* p_root, BaseNode& rootNode); + /** + * Load a XML log node and parses it. It applies the configuration of the node directly. + * @param p_root Node to be loaded. + * @return XMLP_ret::XML_OK on success, XMLP_ret::XML_ERROR in other case. + */ + RTPS_DllAPI static XMLP_ret parseLogConfig(tinyxml2::XMLElement* p_root); RTPS_DllAPI static XMLP_ret parseXMLTransportsProf(tinyxml2::XMLElement* p_root); RTPS_DllAPI static XMLP_ret parseXMLParticipantProf(tinyxml2::XMLElement* p_root, BaseNode& rootNode); @@ -139,6 +145,13 @@ class XMLParser RTPS_DllAPI static XMLP_ret parseXMLCommonTransportData(tinyxml2::XMLElement* p_root, sp_transport_t p_transport); RTPS_DllAPI static XMLP_ret parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, sp_transport_t p_transport); + /** + * Load a XML consumer node and parses it. Adds the parsed consumer to Log directly. + * @param consumer Node to be loaded. + * @return XMLP_ret::XML_OK on success, XMLP_ret::XML_ERROR in other case. + */ + RTPS_DllAPI static XMLP_ret parseXMLConsumer(tinyxml2::XMLElement& consumer); + RTPS_DllAPI static XMLP_ret parseXMLDynamicTypes(tinyxml2::XMLElement& types); RTPS_DllAPI static XMLP_ret parseDynamicTypes(tinyxml2::XMLElement* p_root); RTPS_DllAPI static XMLP_ret parseXMLTypes(tinyxml2::XMLElement* p_root); diff --git a/include/fastrtps/xmlparser/XMLParserCommon.h b/include/fastrtps/xmlparser/XMLParserCommon.h index 90e4335fea4..777ebe4e6fa 100644 --- a/include/fastrtps/xmlparser/XMLParserCommon.h +++ b/include/fastrtps/xmlparser/XMLParserCommon.h @@ -46,6 +46,7 @@ extern const char* PUBLISHER; extern const char* SUBSCRIBER; extern const char* RTPS; extern const char* TYPES; +extern const char* LOG; extern const char* TRANSPORT_DESCRIPTOR; extern const char* TRANSPORT_ID; @@ -299,6 +300,10 @@ extern const char* VALUE_TYPE; extern const char* LENGHT; extern const char* MAXLENGTH; +// LOG +extern const char* USE_DEFAULT; +extern const char* CONSUMER; +extern const char* CLASS; } /* xmlparser */ } /* namespace */ diff --git a/include/fastrtps/xmlparser/XMLProfileManager.h b/include/fastrtps/xmlparser/XMLProfileManager.h index 6ddca1f7bfa..12e265effaf 100644 --- a/include/fastrtps/xmlparser/XMLProfileManager.h +++ b/include/fastrtps/xmlparser/XMLProfileManager.h @@ -15,8 +15,6 @@ #ifndef XML_PROFILE_MANAGER_H_ #define XML_PROFILE_MANAGER_H_ -#include "stdio.h" -#include #include #include #include @@ -25,6 +23,9 @@ #include #include #include + +#include +#include #include diff --git a/include/fastrtps/xmlparser/XMLTree.h b/include/fastrtps/xmlparser/XMLTree.h index b6b6d5ec644..63e998bc51a 100644 --- a/include/fastrtps/xmlparser/XMLTree.h +++ b/include/fastrtps/xmlparser/XMLTree.h @@ -23,7 +23,8 @@ enum class NodeType DATA_WRITER, DATA_READER, ROOT, - TYPES + TYPES, + LOG }; class BaseNode diff --git a/resources/xsd/fastRTPS_profiles.xsd b/resources/xsd/fastRTPS_profiles.xsd index 22247132982..80cbb5a706c 100644 --- a/resources/xsd/fastRTPS_profiles.xsd +++ b/resources/xsd/fastRTPS_profiles.xsd @@ -728,4 +728,20 @@ + + + + + + + + + + + + + + + + diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 2f72ac6587d..9dfcd990ad6 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -19,6 +19,7 @@ include(${PROJECT_SOURCE_DIR}/cmake/dev/generate_msvc_libraries.cmake) set(${PROJECT_NAME}_source_files log/Log.cpp log/StdoutConsumer.cpp + log/FileConsumer.cpp utils/eClock.cpp utils/IPFinder.cpp utils/md5.cpp @@ -112,6 +113,7 @@ set(${PROJECT_NAME}_source_files types/TypeNamesGenerator.cpp types/TypesBase.cpp + attributes/TopicAttributes.cpp qos/ParameterList.cpp qos/ParameterTypes.cpp qos/QosPolicies.cpp diff --git a/src/cpp/attributes/TopicAttributes.cpp b/src/cpp/attributes/TopicAttributes.cpp new file mode 100644 index 00000000000..d6ad63d6a38 --- /dev/null +++ b/src/cpp/attributes/TopicAttributes.cpp @@ -0,0 +1,62 @@ +// 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 TopicAttributes.cpp + */ + +#include +#include + +using namespace eprosima::fastrtps; + +bool TopicAttributes::checkQos() const +{ + if(resourceLimitsQos.max_samples_per_instance > resourceLimitsQos.max_samples && topicKind == rtps::WITH_KEY) + { + logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"):max_samples_per_instance must be <= than max_samples"); + return false; + } + + if (resourceLimitsQos.max_samples_per_instance*resourceLimitsQos.max_instances > resourceLimitsQos.max_samples && topicKind == rtps::WITH_KEY) + { + logWarning(RTPS_QOS_CHECK, "TOPIC QOS: max_samples < max_samples_per_instance*max_instances"); + } + + if(historyQos.kind == KEEP_LAST_HISTORY_QOS) + { + if(historyQos.depth > resourceLimitsQos.max_samples) + { + logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be <= max_samples"); + return false; + } + if(historyQos.depth > resourceLimitsQos.max_samples_per_instance && topicKind == rtps::WITH_KEY) + { + logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be <= max_samples_per_instance"); + return false; + } + if(historyQos.depth <=0 ) + { + logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): depth must be > 0"); + return false; + } + } + + if(resourceLimitsQos.max_samples != 0 && resourceLimitsQos.allocated_samples > resourceLimitsQos.max_samples) + { + logError(RTPS_QOS_CHECK,"INCORRECT TOPIC QOS ("<< topicName <<"): max_samples < allocated_samples"); + return false; + } + return true; +} diff --git a/src/cpp/log/FileConsumer.cpp b/src/cpp/log/FileConsumer.cpp new file mode 100644 index 00000000000..ee3ece65719 --- /dev/null +++ b/src/cpp/log/FileConsumer.cpp @@ -0,0 +1,52 @@ +#include +#include + +namespace eprosima { +namespace fastrtps { + +FileConsumer::FileConsumer() + : FileConsumer("output.log") +{ +} + +FileConsumer::FileConsumer(const std::string &filename, bool append) + : mOutputFile(filename) + , mAppend(append) +{ + if (mAppend) + { + mFile.open(mOutputFile, std::ios::out | std::ios::app); + } + else + { + mFile.open(mOutputFile, std::ios::out); + } +} + +FileConsumer::~FileConsumer() +{ + mFile.close(); +} + +void FileConsumer::Consume(const Log::Entry& entry) +{ + PrintHeader(entry); + PrintMessage(mFile, entry, false); + PrintContext(entry); + PrintNewLine(mFile, false); + mFile.flush(); +} + +void FileConsumer::PrintHeader(const Log::Entry& entry) +{ + PrintTimestamp(mFile, entry, false); + LogConsumer::PrintHeader(mFile, entry, false); +} + +void FileConsumer::PrintContext(const Log::Entry& entry) +{ + LogConsumer::PrintContext(mFile, entry, false); +} + +} // Namespace fastrtps +} // Namespace eprosima diff --git a/src/cpp/log/Log.cpp b/src/cpp/log/Log.cpp index 3d80776e627..ada5f837b21 100644 --- a/src/cpp/log/Log.cpp +++ b/src/cpp/log/Log.cpp @@ -4,6 +4,7 @@ #include #include +#include #include using namespace std; @@ -12,165 +13,255 @@ namespace fastrtps { struct Log::Resources Log::mResources; -Log::Resources::Resources(): - mDefaultConsumer(new StdoutConsumer), - mLogging(false), - mWork(false), - mFilenames(false), - mFunctions(true), - mVerbosity(Log::Error) +Log::Resources::Resources() : mLogging(false), + mWork(false), + mFilenames(false), + mFunctions(true), + mVerbosity(Log::Error) { + mResources.mConsumers.emplace_back(new StdoutConsumer); } Log::Resources::~Resources() { - Log::KillThread(); + Log::KillThread(); } -void Log::RegisterConsumer(std::unique_ptr consumer) +void Log::RegisterConsumer(std::unique_ptr &&consumer) { - std::unique_lock guard(mResources.mConfigMutex); - mResources.mConsumers.emplace_back(std::move(consumer)); + std::unique_lock guard(mResources.mConfigMutex); + mResources.mConsumers.emplace_back(std::move(consumer)); +} + +void Log::ClearConsumers() +{ + std::unique_lock working(mResources.mCvMutex); + mResources.mCv.wait(working, [&]() + { + return mResources.mLogs.BothEmpty(); + }); + std::unique_lock guard(mResources.mConfigMutex); + mResources.mConsumers.clear(); } void Log::Reset() { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mCategoryFilter.reset(); - mResources.mFilenameFilter.reset(); - mResources.mErrorStringFilter.reset(); - mResources.mFilenames = false; - mResources.mFunctions = true; - mResources.mVerbosity = Log::Error; - mResources.mConsumers.clear(); + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mCategoryFilter.reset(); + mResources.mFilenameFilter.reset(); + mResources.mErrorStringFilter.reset(); + mResources.mFilenames = false; + mResources.mFunctions = true; + mResources.mVerbosity = Log::Error; + mResources.mConsumers.clear(); + mResources.mConsumers.emplace_back(new StdoutConsumer); } void Log::Run() { - std::unique_lock guard(mResources.mCvMutex); - while (mResources.mLogging) - { - while (mResources.mWork) - { - mResources.mWork = false; - guard.unlock(); - - mResources.mLogs.Swap(); - while (!mResources.mLogs.Empty()) - { - std::unique_lock configGuard(mResources.mConfigMutex); - if (Preprocess(mResources.mLogs.Front())) + std::unique_lock guard(mResources.mCvMutex); + while (mResources.mLogging) + { + while (mResources.mWork) + { + mResources.mWork = false; + guard.unlock(); { - for (auto& consumer: mResources.mConsumers) - consumer->Consume(mResources.mLogs.Front()); + mResources.mLogs.Swap(); + while (!mResources.mLogs.Empty()) + { + std::unique_lock configGuard(mResources.mConfigMutex); + if (Preprocess(mResources.mLogs.Front())) + { + for (auto &consumer : mResources.mConsumers) + { + consumer->Consume(mResources.mLogs.Front()); + } + } - mResources.mDefaultConsumer->Consume(mResources.mLogs.Front()); + mResources.mLogs.Pop(); + } } - - mResources.mLogs.Pop(); - } - - guard.lock(); - } - if (mResources.mLogging) - mResources.mCv.wait(guard); - } + guard.lock(); + } + mResources.mCv.notify_one(); + if (mResources.mLogging) + mResources.mCv.wait(guard); + } } void Log::ReportFilenames(bool report) { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mFilenames = report; + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mFilenames = report; } void Log::ReportFunctions(bool report) { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mFunctions = report; + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mFunctions = report; } -bool Log::Preprocess(Log::Entry& entry) +bool Log::Preprocess(Log::Entry &entry) { - if (mResources.mCategoryFilter && !regex_search(entry.context.category, *mResources.mCategoryFilter)) - return false; - if (mResources.mFilenameFilter && !regex_search(entry.context.filename, *mResources.mFilenameFilter)) - return false; - if (mResources.mErrorStringFilter && !regex_search(entry.message, *mResources.mErrorStringFilter)) - return false; - if (!mResources.mFilenames) - entry.context.filename = nullptr; - if (!mResources.mFunctions) - entry.context.function = nullptr; + if (mResources.mCategoryFilter && !regex_search(entry.context.category, *mResources.mCategoryFilter)) + return false; + if (mResources.mFilenameFilter && !regex_search(entry.context.filename, *mResources.mFilenameFilter)) + return false; + if (mResources.mErrorStringFilter && !regex_search(entry.message, *mResources.mErrorStringFilter)) + return false; + if (!mResources.mFilenames) + entry.context.filename = nullptr; + if (!mResources.mFunctions) + entry.context.function = nullptr; - return true; + return true; } void Log::KillThread() { - { - std::unique_lock guard(mResources.mCvMutex); - mResources.mLogging = false; - mResources.mWork = false; - } - if (mResources.mLoggingThread) - { - // The #ifdef workaround here is due to an unsolved MSVC bug, which Microsoft has announced - // they have no intention of solving: https://connect.microsoft.com/VisualStudio/feedback/details/747145 - // Each VS version deals with post-main deallocation of threads in a very different way. + { + std::unique_lock guard(mResources.mCvMutex); + mResources.mLogging = false; + mResources.mWork = false; + } + + if (mResources.mLoggingThread) + { + mResources.mCv.notify_all(); + // The #ifdef workaround here is due to an unsolved MSVC bug, which Microsoft has announced + // they have no intention of solving: https://connect.microsoft.com/VisualStudio/feedback/details/747145 + // Each VS version deals with post-main deallocation of threads in a very different way. #if !defined(_WIN32) || defined(FASTRTPS_STATIC_LINK) || _MSC_VER >= 1800 - mResources.mCv.notify_all(); - mResources.mLoggingThread->join(); + mResources.mLoggingThread->join(); #endif - mResources.mLoggingThread.reset(); - } + mResources.mLoggingThread.reset(); + } } -void Log::QueueLog(const std::string& message, const Log::Context& context, Log::Kind kind) +void Log::QueueLog(const std::string &message, const Log::Context &context, Log::Kind kind) { - { - std::unique_lock guard(mResources.mCvMutex); - if (!mResources.mLogging && !mResources.mLoggingThread) - { - mResources.mLogging = true; - mResources.mLoggingThread.reset(new thread(Log::Run)); - } - } + { + std::unique_lock guard(mResources.mCvMutex); + if (!mResources.mLogging && !mResources.mLoggingThread) + { + mResources.mLogging = true; + mResources.mLoggingThread.reset(new thread(Log::Run)); + } + } - mResources.mLogs.Push(Log::Entry{message, context, kind}); - { - std::unique_lock guard(mResources.mCvMutex); - mResources.mWork = true; - } - mResources.mCv.notify_all(); + std::string timestamp; + GetTimestamp(timestamp); + mResources.mLogs.Push(Log::Entry{message, context, kind, timestamp}); + { + std::unique_lock guard(mResources.mCvMutex); + mResources.mWork = true; + } + mResources.mCv.notify_all(); } Log::Kind Log::GetVerbosity() { - return mResources.mVerbosity; + return mResources.mVerbosity; } void Log::SetVerbosity(Log::Kind kind) { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mVerbosity = kind; + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mVerbosity = kind; +} + +void Log::SetCategoryFilter(const std::regex &filter) +{ + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mCategoryFilter.reset(new std::regex(filter)); +} + +void Log::SetFilenameFilter(const std::regex &filter) +{ + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mFilenameFilter.reset(new std::regex(filter)); +} + +void Log::SetErrorStringFilter(const std::regex &filter) +{ + std::unique_lock configGuard(mResources.mConfigMutex); + mResources.mErrorStringFilter.reset(new std::regex(filter)); +} + +void Log::GetTimestamp(std::string ×tamp) +{ + std::stringstream stream; + auto now = std::chrono::system_clock::now(); + std::time_t now_c = std::chrono::system_clock::to_time_t(now); + std::chrono::system_clock::duration tp = now.time_since_epoch(); + tp -= std::chrono::duration_cast(tp); + auto ms = static_cast(tp / std::chrono::milliseconds(1)); + +#ifdef _WIN32 + struct tm timeinfo; + localtime_s(&timeinfo, &now_c); + stream << std::put_time(&timeinfo, "%F %T") << "." << std::setw(3) << std::setfill('0') << ms << " "; +#else + stream << std::put_time(localtime(&now_c), "%F %T") << "." << std::setw(3) << std::setfill('0') << ms << " "; +#endif + timestamp = stream.str(); +} + +void LogConsumer::PrintTimestamp(std::ostream &stream, const Log::Entry &entry, bool color) const +{ + std::string white = (color) ? C_B_WHITE : ""; + stream << white << entry.timestamp; +} + +void LogConsumer::PrintHeader(std::ostream &stream, const Log::Entry &entry, bool color) const +{ + std::string c_b_color = (!color) ? "" : + (entry.kind == Log::Kind::Error) ? C_B_RED : + (entry.kind == Log::Kind::Warning) ? C_B_YELLOW : + (entry.kind == Log::Kind::Info) ? C_B_GREEN : ""; + + std::string white = (color) ? C_B_WHITE : ""; + + std::string kind = (entry.kind == Log::Kind::Error) ? "Error" : + (entry.kind == Log::Kind::Warning) ? "Warning" : + (entry.kind == Log::Kind::Info) ? "Info" : ""; + + stream << c_b_color << "[" << white << entry.context.category << c_b_color << " " << kind << "] "; } -void Log::SetCategoryFilter(const std::regex& filter) +void LogConsumer::PrintContext(std::ostream &stream, const Log::Entry &entry, bool color) const { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mCategoryFilter.reset(new std::regex(filter)); + if (color) + { + stream << C_B_BLUE; + } + if (entry.context.filename) + { + stream << " (" << entry.context.filename; + stream << ":" << entry.context.line << ")"; + } + if (entry.context.function) + { + stream << " -> Function "; + if (color) + { + stream << C_CYAN; + } + stream << entry.context.function; + } } -void Log::SetFilenameFilter(const std::regex& filter) +void LogConsumer::PrintMessage(std::ostream &stream, const Log::Entry &entry, bool color) const { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mFilenameFilter.reset(new std::regex(filter)); + std::string white = (color) ? C_WHITE : ""; + stream << white << entry.message; } -void Log::SetErrorStringFilter(const std::regex& filter) +void LogConsumer::PrintNewLine(std::ostream &stream, bool color) const { - std::unique_lock configGuard(mResources.mConfigMutex); - mResources.mErrorStringFilter.reset(new std::regex(filter)); + std::string def = (color) ? C_DEF : ""; + stream << def << std::endl; } } //namespace fastrtps diff --git a/src/cpp/log/StdoutConsumer.cpp b/src/cpp/log/StdoutConsumer.cpp index e0c40967e90..ec646fb24d0 100644 --- a/src/cpp/log/StdoutConsumer.cpp +++ b/src/cpp/log/StdoutConsumer.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -9,52 +8,20 @@ namespace fastrtps { void StdoutConsumer::Consume(const Log::Entry& entry) { PrintHeader(entry); - std::cout << C_WHITE << entry.message; + PrintMessage(std::cout, entry, true); PrintContext(entry); - std::cout << C_DEF << std::endl; + PrintNewLine(std::cout, true); } void StdoutConsumer::PrintHeader(const Log::Entry& entry) const { - auto now = std::chrono::system_clock::now(); - std::time_t now_c = std::chrono::system_clock::to_time_t(now); - std::chrono::system_clock::duration tp = now.time_since_epoch(); - tp -= std::chrono::duration_cast(tp); - unsigned ms = static_cast(tp / std::chrono::milliseconds(1)); -#ifdef _WIN32 - std::tm ltime; - localtime_s(<ime, &now_c); - std::cout << C_B_WHITE << std::put_time(<ime, "%F %T") -#else - std::cout << C_B_WHITE << std::put_time(localtime(&now_c), "%F %T") -#endif - << "." << std::setw(3) << std::setfill('0') << ms << " "; - switch (entry.kind) - { - case Log::Kind::Error: - std::cout << C_B_RED << "[" << C_B_WHITE << entry.context.category << C_B_RED << " Error] "; - break; - case Log::Kind::Warning: - std::cout << C_B_YELLOW << "[" << C_B_WHITE << entry.context.category << C_B_YELLOW << " Warning] "; - break; - case Log::Kind::Info: - std::cout << C_B_GREEN << "[" << C_B_WHITE << entry.context.category << C_B_GREEN << " Info] "; - break; - } + PrintTimestamp(std::cout, entry, true); + LogConsumer::PrintHeader(std::cout, entry, true); } void StdoutConsumer::PrintContext(const Log::Entry& entry) const { - std::cout << C_B_BLUE; - if (entry.context.filename) - { - std::cout << " (" << entry.context.filename; - std::cout << ":" << entry.context.line << ")"; - } - if (entry.context.function) - { - std::cout << " -> Function " << C_CYAN << entry.context.function; - } + LogConsumer::PrintContext(std::cout, entry, true); } } // Namespace fastrtps diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index 847e73e4122..c227d234ab6 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -18,6 +18,7 @@ #include #include #include +#include using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; @@ -1627,6 +1628,7 @@ XMLP_ret XMLParser::getXMLPropertiesPolicy(tinyxml2::XMLElement *elem, PropertyP // TODO XMLP_ret XMLParser::getXMLOctetVector(tinyxml2::XMLElement *elem, std::vector &/*octetVector*/, uint8_t /*ident*/) { + (void)(elem); logError(XMLPARSER, "Tag '" << elem->Value() << "' octetVector do not supported for now"); return XMLP_ret::XML_OK; } @@ -1711,4 +1713,3 @@ XMLP_ret XMLParser::getXMLString(tinyxml2::XMLElement *elem, std::string *s, uin *s = text; return XMLP_ret::XML_OK; } - diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 8d188a12e55..8341bdfa41f 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -29,6 +29,9 @@ #include #include +#include +#include + #include #include #include @@ -54,8 +57,17 @@ XMLP_ret XMLParser::parseXML(tinyxml2::XMLDocument& xmlDoc, up_base_node_t& root // Just types in the XML. if (nullptr == (p_root = xmlDoc.FirstChildElement(TYPES))) { - logError(XMLPARSER, "Not found root tag"); - ret = XMLP_ret::XML_ERROR; + // Just log config in the XML. + if (nullptr == (p_root = xmlDoc.FirstChildElement(LOG))) + { + logError(XMLPARSER, "Not found root tag"); + ret = XMLP_ret::XML_ERROR; + } + else + { + root.reset(new BaseNode{NodeType::LOG}); + ret = parseLogConfig(p_root); + } } else { @@ -102,6 +114,15 @@ XMLP_ret XMLParser::parseXML(tinyxml2::XMLDocument& xmlDoc, up_base_node_t& root { ret = parseXMLTopicData(node, *root); } + else if (strcmp(tag, LOG) == 0) + { + ret = parseLogConfig(node); + } + else + { + logError(XMLPARSER, "Not expected tag: '" << tag << "'"); + ret = XMLP_ret::XML_ERROR; + } } node = node->NextSiblingElement(); @@ -1462,6 +1483,154 @@ XMLP_ret XMLParser::parseDynamicTypes(tinyxml2::XMLElement* p_root) return parseXMLTypes(p_root); } +XMLP_ret XMLParser::parseLogConfig(tinyxml2::XMLElement* p_root) +{ + /* + + + + + + + + + + + + + + + */ + + XMLP_ret ret = XMLP_ret::XML_OK; + tinyxml2::XMLElement *p_aux0 = p_root->FirstChildElement(LOG); + if (p_aux0 == nullptr) + { + p_aux0 = p_root; + } + + tinyxml2::XMLElement* p_element = p_aux0->FirstChildElement(); + const char* tag = nullptr; + while (nullptr != p_element) + { + if (nullptr != (tag = p_element->Value())) + { + if (strcmp(tag, USE_DEFAULT) == 0) + { + bool use_default = true; + std::string auxBool = p_element->GetText(); + if (std::strcmp(auxBool.c_str(), "FALSE") == 0) + { + use_default = false; + } + if (!use_default) + { + Log::ClearConsumers(); + } + } + else if (strcmp(tag, CONSUMER) == 0) + { + ret = parseXMLConsumer(*p_element); + if (ret != XMLP_ret::XML_OK) + { + return ret; + } + } + else + { + logError(XMLPARSER, "Not expected tag: '" << tag << "'"); + ret = XMLP_ret::XML_ERROR; + } + } + p_element = p_element->NextSiblingElement(CONSUMER); + } + return ret; +} + +XMLP_ret XMLParser::parseXMLConsumer(tinyxml2::XMLElement& consumer) +{ + XMLP_ret ret = XMLP_ret::XML_OK; + tinyxml2::XMLElement* p_element = consumer.FirstChildElement(CLASS); + + if (p_element != nullptr) + { + std::string classStr = p_element->GetText(); + + if (std::strcmp(classStr.c_str(), "StdoutConsumer") == 0) + { + Log::RegisterConsumer(std::unique_ptr(new StdoutConsumer)); + } + else if (std::strcmp(classStr.c_str(), "FileConsumer") == 0) + { + std::string outputFile = "output.log"; + bool append = false; + + tinyxml2::XMLElement* property = consumer.FirstChildElement(PROPERTY); + if (nullptr == property) + { + Log::RegisterConsumer(std::unique_ptr(new FileConsumer)); + } + else + { + tinyxml2::XMLElement* p_auxName = nullptr; + tinyxml2::XMLElement* p_auxValue = nullptr; + while (nullptr != property) + { + // name - stringType + if (nullptr != (p_auxName = property->FirstChildElement(NAME))) + { + std::string s = p_auxName->GetText(); + + if (std::strcmp(s.c_str(), "filename") == 0) + { + if (nullptr != (p_auxValue = property->FirstChildElement(VALUE))) + { + outputFile = p_auxValue->GetText(); + } + else + { + logError(XMLParser, "Filename value cannot be found for " << classStr + << " log consumer."); + } + } + else if (std::strcmp(s.c_str(), "append") == 0) + { + if (nullptr != (p_auxValue = property->FirstChildElement(VALUE))) + { + std::string auxBool = p_auxValue->GetText(); + if (std::strcmp(auxBool.c_str(), "TRUE") == 0) + { + append = true; + } + } + else + { + logError(XMLParser, "Append value cannot be found for " << classStr + << " log consumer."); + } + } + else + { + logError(XMLParser, "Unknown property " << s << " in " << classStr + << " log consumer."); + } + } + property = property->NextSiblingElement(PROPERTY); + } + + Log::RegisterConsumer(std::unique_ptr(new FileConsumer(outputFile, append))); + } + } + else + { + logError(XMLParser, "Unknown log consumer class: " << classStr); + ret = XMLP_ret::XML_ERROR; + } + } + + return ret; +} + XMLP_ret XMLParser::loadXML(const std::string& filename, up_base_node_t& root) { if (filename.empty()) diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index c8af1a02e49..e7a004c9c2f 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -31,6 +31,7 @@ const char* PUBLISHER = "publisher"; const char* SUBSCRIBER = "subscriber"; const char* RTPS = "rtps"; const char* TYPES = "types"; +const char* LOG = "log"; const char* TRANSPORT_DESCRIPTOR = "transport_descriptor"; const char* TRANSPORT_ID = "transport_id"; @@ -281,6 +282,10 @@ const char* VALUE_TYPE = "value_type"; const char* LENGHT = "length"; const char* MAXLENGTH = "maxLength"; +// LOG +const char* USE_DEFAULT = "use_default"; +const char* CONSUMER = "consumer"; +const char* CLASS = "class"; } /* xmlparser */ } /* namespace */ diff --git a/src/cpp/xmlparser/XMLProfileManager.cpp b/src/cpp/xmlparser/XMLProfileManager.cpp index 17668d1dbe0..26a78e010ba 100644 --- a/src/cpp/xmlparser/XMLProfileManager.cpp +++ b/src/cpp/xmlparser/XMLProfileManager.cpp @@ -15,13 +15,15 @@ #include #include #include +#include + #include #ifdef _WIN32 #include #endif -namespace eprosima { -namespace fastrtps { -namespace xmlparser { + +using namespace eprosima::fastrtps; +using namespace ::xmlparser; std::map XMLProfileManager::m_participant_profiles; ParticipantAttributes default_participant_attributes; @@ -346,6 +348,7 @@ XMLP_ret XMLProfileManager::extractProfiles(up_base_node_t profiles, const std:: XMLP_ret XMLProfileManager::extractParticipantProfile(up_base_node_t& profile, const std::string& filename) { + (void)(filename); std::string profile_name = ""; p_node_participant_t p_node_part = dynamic_cast(profile.get()); @@ -376,6 +379,7 @@ XMLP_ret XMLProfileManager::extractParticipantProfile(up_base_node_t& profile, c XMLP_ret XMLProfileManager::extractPublisherProfile(up_base_node_t& profile, const std::string& filename) { + (void)(filename); std::string profile_name = ""; p_node_publisher_t p_node_part = dynamic_cast(profile.get()); @@ -406,6 +410,7 @@ XMLP_ret XMLProfileManager::extractPublisherProfile(up_base_node_t& profile, con XMLP_ret XMLProfileManager::extractSubscriberProfile(up_base_node_t& profile, const std::string& filename) { + (void)(filename); std::string profile_name = ""; p_node_subscriber_t p_node_part = dynamic_cast(profile.get()); @@ -476,6 +481,7 @@ p_dynamictypebuilder_t XMLProfileManager::getDynamicTypeByName(const std::string XMLP_ret XMLProfileManager::extractTopicProfile(up_base_node_t& profile, const std::string& filename) { + (void)(filename); std::string profile_name = ""; p_node_topic_t p_node_topic = dynamic_cast(profile.get()); @@ -503,7 +509,3 @@ XMLP_ret XMLProfileManager::extractTopicProfile(up_base_node_t& profile, const s } return XMLP_ret::XML_OK; } - -} /* xmlparser */ -} /* namespace */ -} /* namespace eprosima */ diff --git a/test/mock/rtps/Log/fastrtps/log/FileConsumer.h b/test/mock/rtps/Log/fastrtps/log/FileConsumer.h new file mode 100644 index 00000000000..38d97545b7b --- /dev/null +++ b/test/mock/rtps/Log/fastrtps/log/FileConsumer.h @@ -0,0 +1,49 @@ +// 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 FileConsumer.h + * + */ + +#ifndef FILE_CONSUMER_H +#define FILE_CONSUMER_H + +#include +#include + +namespace eprosima { +namespace fastrtps { + +class FileConsumer : public LogConsumer +{ + public: + + FileConsumer() = default; + + FileConsumer(const std::string &, bool = false) {}; + + virtual ~FileConsumer() {} +}; + +MATCHER(IsFileConsumer, "Argument is a FileConsumer object?") +{ + *result_listener << (typeid(*arg.get()) == typeid(FileConsumer)); + return typeid(*arg.get()) == typeid(FileConsumer); +} + +} // namespace fastrtps +} // namespace eprosima + +#endif // FILE_CONSUMER_H diff --git a/test/mock/rtps/Log/fastrtps/log/Log.h b/test/mock/rtps/Log/fastrtps/log/Log.h new file mode 100644 index 00000000000..761ae1624bc --- /dev/null +++ b/test/mock/rtps/Log/fastrtps/log/Log.h @@ -0,0 +1,83 @@ + +// 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. +// +#ifndef _FASTRTPS_LOG_LOG_H_ +#define _FASTRTPS_LOG_LOG_H_ + +#include +#include +#include + +/** + * eProsima log mock. + */ + +#define logInfo(cat,msg) \ + { \ + NulStreambuf null_buffer; \ + std::ostream null_stream(&null_buffer); \ + null_stream << msg; \ + } + +#define logWarning(cat,msg) logInfo(cat,msg) +#define logError(cat,msg) logInfo(cat,msg) + +class NulStreambuf : public std::streambuf +{ +protected: + int overflow(int c) { return c; } +}; + +namespace eprosima { +namespace fastrtps { + +class LogConsumer +{ + public: + + virtual ~LogConsumer() {} +}; + +class Log +{ + public: + + static std::function&&)> RegisterConsumerFunc; + static void RegisterConsumer(std::unique_ptr&& c) { RegisterConsumerFunc(std::move(c)); } + + static std::function ClearConsumersFunc; + static void ClearConsumers() { ClearConsumersFunc(); } +}; + +using ::testing::_; +using ::testing::Invoke; +class LogMock +{ + public: + // r-value support for mocked function. + void RegisterConsumer(std::unique_ptr&& p) + { + RegisterConsumer(p); + } + + MOCK_METHOD1(RegisterConsumer, void(std::unique_ptr&)); + + MOCK_METHOD0(ClearConsumers, void()); +}; + +} // namespace fastrtps +} // namespace eprosima + +#endif diff --git a/test/mock/rtps/Log/fastrtps/log/StdoutConsumer.h b/test/mock/rtps/Log/fastrtps/log/StdoutConsumer.h new file mode 100644 index 00000000000..9e866520a7e --- /dev/null +++ b/test/mock/rtps/Log/fastrtps/log/StdoutConsumer.h @@ -0,0 +1,28 @@ +// 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. + +#ifndef STDOUT_CONSUMER_H +#define STDOUT_CONSUMER_H + +#include + +namespace eprosima { +namespace fastrtps { + +class StdoutConsumer : public LogConsumer {}; + +} // namespace fastrtps +} // namespace eprosima + +#endif diff --git a/test/unittest/dynamic_types/CMakeLists.txt b/test/unittest/dynamic_types/CMakeLists.txt index 9a06d6ae1c9..bf0812ffeba 100644 --- a/test/unittest/dynamic_types/CMakeLists.txt +++ b/test/unittest/dynamic_types/CMakeLists.txt @@ -53,6 +53,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPFinder.cpp ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/log/FileConsumer.cpp ) set(DYNAMIC_TYPES_TEST_SOURCE diff --git a/test/unittest/logging/CMakeLists.txt b/test/unittest/logging/CMakeLists.txt index 787b723f6e4..76f4930e1e4 100644 --- a/test/unittest/logging/CMakeLists.txt +++ b/test/unittest/logging/CMakeLists.txt @@ -21,10 +21,16 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) add_definitions(-D_WIN32_WINNT=0x0601) endif() - set(LOGTESTS_SOURCE + set(LOG_COMMON_SOURCE ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp - LogTests.cpp) + ) + + set(LOGTESTS_TEST_SOURCE LogTests.cpp) + + set(LOGTESTS_SOURCE + ${LOG_COMMON_SOURCE} + ${LOGTESTS_TEST_SOURCE}) include_directories(mock/) @@ -32,12 +38,38 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) target_compile_definitions(LogTests PRIVATE FASTRTPS_NO_LIB) target_include_directories(LogTests PRIVATE ${GTEST_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) - target_link_libraries(LogTests ${GTEST_LIBRARIES} ${MOCKS} ) - if(MSVC OR MSVC_IDE) - target_link_libraries(LogTests ${PRIVACY} - iphlpapi Shlwapi + target_link_libraries(LogTests ${GTEST_LIBRARIES} ${MOCKS} + $<$:iphlpapi$Shlwapi> + ) + add_gtest(LogTests SOURCES ${LOGTESTS_TEST_SOURCE}) + + set(LOGFILETESTS_TEST_SOURCE LogFileTests.cpp) + + set(LOGFILETESTS_SOURCE + ${LOG_COMMON_SOURCE} + ${PROJECT_SOURCE_DIR}/src/cpp/log/FileConsumer.cpp + ${LOGFILETESTS_TEST_SOURCE}) + + # External sources + if(TINYXML2_SOURCE_DIR) + list(APPEND LOGFILETESTS_SOURCE + ${TINYXML2_SOURCE_DIR}/tinyxml2.cpp ) endif() - add_gtest(LogTests SOURCES ${LOGTESTS_SOURCE}) + + include_directories(${TINYXML2_INCLUDE_DIR}) + + add_executable(LogFileTests ${LOGFILETESTS_SOURCE}) + target_compile_definitions(LogFileTests PRIVATE FASTRTPS_NO_LIB) + target_include_directories(LogFileTests PRIVATE ${GTEST_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) + target_link_libraries(LogFileTests ${GTEST_LIBRARIES} ${MOCKS} + $<$:iphlpapi$Shlwapi> + $<$:${TINYXML2_LIBRARY}> + fastcdr + ) + + add_gtest(LogFileTests SOURCES ${LOGFILETESTS_TEST_SOURCE}) + endif() endif() diff --git a/test/unittest/logging/LogFileTests.cpp b/test/unittest/logging/LogFileTests.cpp new file mode 100644 index 00000000000..e17946eea1b --- /dev/null +++ b/test/unittest/logging/LogFileTests.cpp @@ -0,0 +1,117 @@ +// 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. +// + +#include +#include +#include +#include +#include +#include +#include + +using namespace eprosima::fastrtps; +using namespace std; + +TEST(LogFileTests, file_consumer) +{ + // First remove previous executions file + std::remove("file_consumer.log"); + + Log::ClearConsumers(); + Log::RegisterConsumer(std::unique_ptr(new FileConsumer("file_consumer.log"))); + Log::SetVerbosity(Log::Info); + + vector> threads; + for (int i = 0; i != 5; i++) + { + threads.emplace_back(new thread([i]{ + logWarning(Multithread, "I'm thread " << std::to_string(i)); + })); + } + + for (auto& thread: threads) { + thread->join(); + } + + Log::ClearConsumers(); // Force close file + + std::ifstream ifs("file_consumer.log"); + std::string content((std::istreambuf_iterator(ifs)), + (std::istreambuf_iterator())); + + for (int i = 0; i != 5; ++i) + { + std::string str("I'm thread " + std::to_string(i)); + std::size_t found = content.find(str); + ASSERT_TRUE(found != std::string::npos); + } +} + +TEST(LogFileTests, file_consumer_append) +{ + // First remove previous executions file + std::remove("append.log"); + + Log::ClearConsumers(); + Log::RegisterConsumer(std::unique_ptr(new FileConsumer("append.log", true))); + Log::SetVerbosity(Log::Info); + + vector> threads; + for (int i = 0; i != 5; i++) + { + threads.emplace_back(new thread([i]{ + logWarning(Multithread, "I'm thread " << std::to_string(i)); + })); + } + + for (auto& thread: threads) { + thread->join(); + } + + Log::ClearConsumers(); // Force close file + + Log::RegisterConsumer(std::unique_ptr(new FileConsumer("append.log", true))); + + vector> threads2; + for (int i = 0; i != 5; i++) + { + threads2.emplace_back(new thread([i]{ + logWarning(Multithread, "I'm thread " << std::to_string(i+5)); + })); + } + + for (auto& thread: threads2) { + thread->join(); + } + + Log::ClearConsumers(); // Force close file + + std::ifstream ifs("append.log"); + std::string content((std::istreambuf_iterator(ifs)), + (std::istreambuf_iterator())); + + for (int i = 0; i != 10; ++i) + { + std::string str("I'm thread " + std::to_string(i)); + std::size_t found = content.find(str); + ASSERT_TRUE(found != std::string::npos); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/unittest/logging/LogTests.cpp b/test/unittest/logging/LogTests.cpp index a202aac336b..2a4d5aa679b 100644 --- a/test/unittest/logging/LogTests.cpp +++ b/test/unittest/logging/LogTests.cpp @@ -25,22 +25,21 @@ using namespace eprosima::fastrtps; using namespace std; -class LogTests: public ::testing::Test +class LogTests: public ::testing::Test { public: - LogTests() + LogTests() { - std::unique_ptr consumer(new MockConsumer); - std::unique_ptr defaultConsumer(new StdoutConsumer); - mockConsumer = consumer.get(); - Log::RegisterConsumer(std::move(consumer)); - Log::SetVerbosity(Log::Info); + mockConsumer = new MockConsumer(); + + Log::RegisterConsumer(std::unique_ptr(mockConsumer)); + Log::SetVerbosity(Log::Info); } ~LogTests() { - Log::Reset(); - Log::KillThread(); + Log::Reset(); + Log::KillThread(); } MockConsumer* mockConsumer; @@ -53,108 +52,108 @@ class LogTests: public ::testing::Test TEST_F(LogTests, asynchronous_logging) { - logError(SampleCategory, "Sample error message"); - logWarning(SampleCategory, "Sample warning message"); - logWarning(DifferentCategory, "Sample warning message in another category"); + logError(SampleCategory, "Sample error message"); + logWarning(SampleCategory, "Sample warning message"); + logWarning(DifferentCategory, "Sample warning message in another category"); - auto consumedEntries = HELPER_WaitForEntries(3); - ASSERT_EQ(3u, consumedEntries.size()); + auto consumedEntries = HELPER_WaitForEntries(3); + ASSERT_EQ(3u, consumedEntries.size()); } TEST_F(LogTests, reporting_options) { - // moving away from the defaults - Log::ReportFilenames(true); - Log::ReportFunctions(false); - - logError(Reporting, "Error with different reporting options"); - auto consumedEntries = HELPER_WaitForEntries(1); - ASSERT_EQ(1u, consumedEntries.size()); - - auto entry = consumedEntries.back(); - ASSERT_NE(entry.context.filename, nullptr); - ASSERT_EQ(entry.context.function, nullptr); + // moving away from the defaults + Log::ReportFilenames(true); + Log::ReportFunctions(false); + + logError(Reporting, "Error with different reporting options"); + auto consumedEntries = HELPER_WaitForEntries(1); + ASSERT_EQ(1u, consumedEntries.size()); + + auto entry = consumedEntries.back(); + ASSERT_NE(entry.context.filename, nullptr); + ASSERT_EQ(entry.context.function, nullptr); } TEST_F(LogTests, multithreaded_logging) { - vector> threads; - for (int i = 0; i != 5; i++) - { - threads.emplace_back(new thread([i]{ - logWarning(Multithread, "I'm thread " << i); - })); - } - - for (auto& thread: threads) { - thread->join(); - } - - auto consumedEntries = HELPER_WaitForEntries(5); - ASSERT_EQ(5u, consumedEntries.size()); + vector> threads; + for (int i = 0; i != 5; i++) + { + threads.emplace_back(new thread([i]{ + logWarning(Multithread, "I'm thread " << i); + })); + } + + for (auto& thread: threads) { + thread->join(); + } + + auto consumedEntries = HELPER_WaitForEntries(5); + ASSERT_EQ(5u, consumedEntries.size()); } TEST_F(LogTests, regex_category_filtering) { - Log::SetCategoryFilter(std::regex("(Good)")); - logError(GoodCategory, "This should be logged because my regex filter allows for it"); - logError(BadCategory, "If you're seeing this, something went wrong"); - logWarning(EvenMoreGoodCategory, "This should be logged too!"); - auto consumedEntries = HELPER_WaitForEntries(3); - ASSERT_EQ(2u, consumedEntries.size()); + Log::SetCategoryFilter(std::regex("(Good)")); + logError(GoodCategory, "This should be logged because my regex filter allows for it"); + logError(BadCategory, "If you're seeing this, something went wrong"); + logWarning(EvenMoreGoodCategory, "This should be logged too!"); + auto consumedEntries = HELPER_WaitForEntries(3); + ASSERT_EQ(2u, consumedEntries.size()); } TEST_F(LogTests, multi_criteria_filtering_with_regex) { - Log::SetCategoryFilter(std::regex("(Good)")); - Log::SetFilenameFilter(std::regex("(LogTests)", std::regex_constants::icase)); - Log::SetErrorStringFilter(std::regex("(Good)")); - Log::ReportFilenames(true); // For clarity, not necessary. - - logError(GoodCategory, "This should be logged because it contains the word \"Good\" in the "\ - "error string and the category, and is in the right filename"); - logError(BadCategory, "Despite the word \"Good\" being here, this shouldn't be logged"); - logError(GoodCategory, "And neither should this."); - auto consumedEntries = HELPER_WaitForEntries(3); - ASSERT_EQ(1u, consumedEntries.size()); - - Log::SetFilenameFilter(std::regex("(we shouldn't find this ever)")); - logError(GoodCategory, "Despite the word \"Good\" being here, this shouldn't be logged because "\ - "the filename is all wrong"); - - consumedEntries = HELPER_WaitForEntries(2); - ASSERT_EQ(1u, consumedEntries.size()); + Log::SetCategoryFilter(std::regex("(Good)")); + Log::SetFilenameFilter(std::regex("(LogTests)", std::regex_constants::icase)); + Log::SetErrorStringFilter(std::regex("(Good)")); + Log::ReportFilenames(true); // For clarity, not necessary. + + logError(GoodCategory, "This should be logged because it contains the word \"Good\" in the "\ + "error string and the category, and is in the right filename"); + logError(BadCategory, "Despite the word \"Good\" being here, this shouldn't be logged"); + logError(GoodCategory, "And neither should this."); + auto consumedEntries = HELPER_WaitForEntries(3); + ASSERT_EQ(1u, consumedEntries.size()); + + Log::SetFilenameFilter(std::regex("(we shouldn't find this ever)")); + logError(GoodCategory, "Despite the word \"Good\" being here, this shouldn't be logged because "\ + "the filename is all wrong"); + + consumedEntries = HELPER_WaitForEntries(2); + ASSERT_EQ(1u, consumedEntries.size()); } TEST_F(LogTests, multiple_verbosity_levels) { - Log::SetVerbosity(Log::Warning); - logError(VerbosityChecks, "This should be logged"); - logWarning(VerbosityChecks, "This should be logged too!"); - logInfo(VerbosityChecks, "If you're seeing this, something went wrong"); - auto consumedEntries = HELPER_WaitForEntries(3); - ASSERT_EQ(2u, consumedEntries.size()); - - Log::SetVerbosity(Log::Error); - logError(VerbosityChecks, "This should be logged"); - logWarning(VerbosityChecks, "If you're seeing this, something went wrong"); - logInfo(VerbosityChecks, "If you're seeing this, something went wrong"); - - consumedEntries = HELPER_WaitForEntries(5); - ASSERT_EQ(3u, consumedEntries.size()); + Log::SetVerbosity(Log::Warning); + logError(VerbosityChecks, "This should be logged"); + logWarning(VerbosityChecks, "This should be logged too!"); + logInfo(VerbosityChecks, "If you're seeing this, something went wrong"); + auto consumedEntries = HELPER_WaitForEntries(3); + ASSERT_EQ(2u, consumedEntries.size()); + + Log::SetVerbosity(Log::Error); + logError(VerbosityChecks, "This should be logged"); + logWarning(VerbosityChecks, "If you're seeing this, something went wrong"); + logInfo(VerbosityChecks, "If you're seeing this, something went wrong"); + + consumedEntries = HELPER_WaitForEntries(5); + ASSERT_EQ(3u, consumedEntries.size()); } std::vector LogTests::HELPER_WaitForEntries(uint32_t amount) { - size_t entries = 0; - for (uint32_t i = 0; i != AsyncTries; i++) - { - entries = mockConsumer->ConsumedEntries().size(); - if (entries == amount) break; - this_thread::sleep_for(chrono::milliseconds(AsyncWaitMs)); - } - - return mockConsumer->ConsumedEntries(); + size_t entries = 0; + for (uint32_t i = 0; i != AsyncTries; i++) + { + entries = mockConsumer->ConsumedEntries().size(); + if (entries == amount) break; + this_thread::sleep_for(chrono::milliseconds(AsyncWaitMs)); + } + + return mockConsumer->ConsumedEntries(); } int main(int argc, char **argv) diff --git a/test/unittest/xmlparser/CMakeLists.txt b/test/unittest/xmlparser/CMakeLists.txt index 1955bb21c6c..30062edb4d5 100644 --- a/test/unittest/xmlparser/CMakeLists.txt +++ b/test/unittest/xmlparser/CMakeLists.txt @@ -15,8 +15,9 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) include(${PROJECT_SOURCE_DIR}/cmake/common/gtest.cmake) check_gtest() + check_gmock() - if(GTEST_FOUND) + if(GTEST_FOUND AND GMOCK_FOUND) if(WIN32) add_definitions( -D_WIN32_WINNT=0x0601 @@ -33,6 +34,15 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_xml_profiles_rooted.xml ${CMAKE_CURRENT_BINARY_DIR}/test_xml_profiles_rooted.xml COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/log_def_file.xml + ${CMAKE_CURRENT_BINARY_DIR}/log_def_file.xml + COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/log_inactive.xml + ${CMAKE_CURRENT_BINARY_DIR}/log_inactive.xml + COPYONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/log_node_file_append.xml + ${CMAKE_CURRENT_BINARY_DIR}/log_node_file_append.xml + COPYONLY) set(XMLPROFILEPARSER_SOURCE XMLProfileParserTests.cpp @@ -45,11 +55,8 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/qos/WriterQos.cpp ${PROJECT_SOURCE_DIR}/src/cpp/qos/ReaderQos.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/ThroughputControllerDescriptor.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPFinder.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPLocator.cpp - ${PROJECT_SOURCE_DIR}/src/cpp/types/AnnotationDescriptor.cpp ${PROJECT_SOURCE_DIR}/src/cpp/types/DynamicData.cpp ${PROJECT_SOURCE_DIR}/src/cpp/types/DynamicDataFactory.cpp @@ -87,6 +94,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) target_compile_definitions(XMLProfileParserTests PRIVATE FASTRTPS_NO_LIB) target_include_directories(XMLProfileParserTests PRIVATE ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/test/mock/rtps/Log ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv6TransportDescriptor @@ -94,21 +102,12 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/test/mock/rtps/UDPv6TransportDescriptor ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) - if(MSVC OR MSVC_IDE) - target_link_libraries(XMLProfileParserTests ${PRIVACY} fastcdr) - else() - target_link_libraries(XMLProfileParserTests ${PRIVACY} fastcdr) - endif() - - target_link_libraries(XMLProfileParserTests ${GTEST_LIBRARIES}) - if(MSVC OR MSVC_IDE) - target_link_libraries(XMLProfileParserTests ${PRIVACY} iphlpapi Shlwapi ws2_32) - endif() - if(TINYXML2_LIBRARY) - target_link_libraries(XMLProfileParserTests ${PRIVACY} - ${TINYXML2_LIBRARY} - ) - endif() + target_link_libraries(XMLProfileParserTests ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} + $<$:iphlpapi$Shlwapi> + $<$:ws2_32> + $<$:${TINYXML2_LIBRARY}> + fastcdr + ) add_gtest(XMLProfileParserTests SOURCES XMLProfileParserTests.cpp) @@ -125,6 +124,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/ThroughputControllerDescriptor.cpp ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/log/FileConsumer.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPFinder.cpp ${PROJECT_SOURCE_DIR}/src/cpp/utils/IPLocator.cpp @@ -164,7 +164,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) add_executable(XMLParserTests ${XMLPARSER_SOURCE}) target_compile_definitions(XMLParserTests PRIVATE FASTRTPS_NO_LIB) target_include_directories(XMLParserTests PRIVATE - ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS} + ${GTEST_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPTransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv4TransportDescriptor ${PROJECT_SOURCE_DIR}/test/mock/rtps/TCPv6TransportDescriptor @@ -173,22 +173,13 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include ) - - if(MSVC OR MSVC_IDE) - target_link_libraries(XMLParserTests ${PRIVACY} iphlpapi Shlwapi ws2_32) - endif() - if(MSVC OR MSVC_IDE) - target_link_libraries(XMLParserTests ${PRIVACY} fastcdr) - else() - target_link_libraries(XMLParserTests ${PRIVACY} fastcdr) - endif() - - target_link_libraries(XMLParserTests ${GTEST_LIBRARIES} ) - if(TINYXML2_LIBRARY) - target_link_libraries(XMLParserTests ${PRIVACY} ${TINYXML2_LIBRARY} ) - endif() + target_link_libraries(XMLParserTests ${GTEST_LIBRARIES} + $<$:iphlpapi$Shlwapi> + $<$:ws2_32> + $<$:${TINYXML2_LIBRARY}> + fastcdr + ) add_gtest(XMLParserTests SOURCES XMLParserTests.cpp) endif() endif() - diff --git a/test/unittest/xmlparser/XMLProfileParserTests.cpp b/test/unittest/xmlparser/XMLProfileParserTests.cpp index d072b83a086..acf02f8c91e 100644 --- a/test/unittest/xmlparser/XMLProfileParserTests.cpp +++ b/test/unittest/xmlparser/XMLProfileParserTests.cpp @@ -12,23 +12,39 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include #include #include +#include +#include +#include +#include +#include using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; +using namespace ::testing; + +// Initialize Log mock +LogMock *log_mock; +std::function&&)> Log::RegisterConsumerFunc = + [](std::unique_ptr&& c) { log_mock->RegisterConsumer(std::move(c)); }; +std::function Log::ClearConsumersFunc = []() { log_mock->ClearConsumers(); }; class XMLProfileParserTests: public ::testing::Test { public: + XMLProfileParserTests() { + log_mock = new LogMock(); } ~XMLProfileParserTests() { - Log::KillThread(); + delete log_mock; } }; @@ -523,10 +539,27 @@ TEST_F(XMLProfileParserTests, XMLParserSecurity) #endif +TEST_F(XMLProfileParserTests, file_xml_consumer_append) +{ + EXPECT_CALL(*log_mock, ClearConsumers()).Times(1); + EXPECT_CALL(*log_mock, RegisterConsumer(IsFileConsumer())).Times(1); + xmlparser::XMLProfileManager::loadXMLFile("log_node_file_append.xml"); +} + +TEST_F(XMLProfileParserTests, log_inactive) +{ + EXPECT_CALL(*log_mock, ClearConsumers()).Times(1); + xmlparser::XMLProfileManager::loadXMLFile("log_inactive.xml"); +} + +TEST_F(XMLProfileParserTests, file_and_default) +{ + EXPECT_CALL(*log_mock, RegisterConsumer(IsFileConsumer())).Times(1); + xmlparser::XMLProfileManager::loadXMLFile("log_def_file.xml"); +} + int main(int argc, char **argv) { - Log::SetVerbosity(Log::Info); - Log::SetCategoryFilter(std::regex("(XMLPARSER)")); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/unittest/xmlparser/log_def_file.xml b/test/unittest/xmlparser/log_def_file.xml new file mode 100644 index 00000000000..96249262e92 --- /dev/null +++ b/test/unittest/xmlparser/log_def_file.xml @@ -0,0 +1,9 @@ + + + + TRUE + + FileConsumer + + + \ No newline at end of file diff --git a/test/unittest/xmlparser/log_inactive.xml b/test/unittest/xmlparser/log_inactive.xml new file mode 100644 index 00000000000..85421a35732 --- /dev/null +++ b/test/unittest/xmlparser/log_inactive.xml @@ -0,0 +1,6 @@ + + + + FALSE + + \ No newline at end of file diff --git a/test/unittest/xmlparser/log_node_file_append.xml b/test/unittest/xmlparser/log_node_file_append.xml new file mode 100644 index 00000000000..3afaffcb637 --- /dev/null +++ b/test/unittest/xmlparser/log_node_file_append.xml @@ -0,0 +1,17 @@ + + + + FALSE + + FileConsumer + + filename + test1.log + + + append + TRUE + + + + \ No newline at end of file From a88e7ef2052897061c127ab826f63cb8b1e9f356 Mon Sep 17 00:00:00 2001 From: MiguelCompany Date: Wed, 19 Dec 2018 10:46:40 +0100 Subject: [PATCH 04/34] Forcing SO_REUSEPORT when defined. [4109] (#350) * Refs #4096. Forcing SO_REUSEPORT when defined. * Refs #4096. Leaving change for QNX only. --- src/cpp/transport/UDPv4Transport.cpp | 4 ++++ src/cpp/transport/UDPv6Transport.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/cpp/transport/UDPv4Transport.cpp b/src/cpp/transport/UDPv4Transport.cpp index 01128f06340..aa078653e44 100644 --- a/src/cpp/transport/UDPv4Transport.cpp +++ b/src/cpp/transport/UDPv4Transport.cpp @@ -253,6 +253,10 @@ eProsimaUDPSocket UDPv4Transport::OpenAndBindInputSocket(const std::string& sIp, if (is_multicast) { getSocketPtr(socket)->set_option(ip::udp::socket::reuse_address(true)); +#if defined(__QNX__) + getSocketPtr(socket)->set_option(asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), SO_REUSEPORT>(true)); +#endif } getSocketPtr(socket)->bind(GenerateEndpoint(sIp, port)); diff --git a/src/cpp/transport/UDPv6Transport.cpp b/src/cpp/transport/UDPv6Transport.cpp index 53b43fb48bf..2e22e82e9a6 100644 --- a/src/cpp/transport/UDPv6Transport.cpp +++ b/src/cpp/transport/UDPv6Transport.cpp @@ -254,6 +254,10 @@ eProsimaUDPSocket UDPv6Transport::OpenAndBindInputSocket(const std::string& sIp, if (is_multicast) { getSocketPtr(socket)->set_option(ip::udp::socket::reuse_address(true)); +#if defined(__QNX__) + getSocketPtr(socket)->set_option(asio::detail::socket_option::boolean< + ASIO_OS_DEF(SOL_SOCKET), SO_REUSEPORT>(true)); +#endif } getSocketPtr(socket)->bind(GenerateEndpoint(sIp, port)); From 846307b9baaaff49ad5d3aee68b9cb509851e4f3 Mon Sep 17 00:00:00 2001 From: coquisx <45318059+coquisx@users.noreply.github.com> Date: Tue, 8 Jan 2019 12:15:19 +0100 Subject: [PATCH 05/34] Feature/xml standard [4115] (#352) * Refs #4026 Adapted xmlparser to standard DDS-XTypes and added xml example * Refs #4026 Reformatted text * Refs #4026 Included key for datatypes * Refs #4026 Deleted old syntax allowed * Refs #4026 Fix mane of config file for dynamicTest * Refs #4026 Introduced cases to string and wstring in getDiscriminatorTypeBuilder * Refs #4026 Fix cases of bounded string and bounded wstring, in alias definitions and members definitions * Refs #4026 Added two new test for bounded string and bounded wstring * Refs #4026 Modified config file for dynamictype test * Refs #4127. Update XSD file and change part of the parser to be more restrictive * Refs #4127 Review the XML Parser to be more restrictive * Refs #4108 Update the parser of durations and locators with the new structures. * Refs #4127 Review the XMLParser class to make the parsing more restrictive. * Refs #4127 Review the tests and the resources to match with the new XML design. * Refs #4108 Create a new test to check recursive types * Refs #4115 Minor changes and better test comparision for dynamic types. --- .../C++/XMLProfiles/XMLProfilesExample.xml | 2 +- include/fastrtps/xmlparser/XMLParser.h | 5 + include/fastrtps/xmlparser/XMLParserCommon.h | 41 +- resources/xsd/fastRTPS_profiles.xsd | 537 ++-- src/cpp/types/DynamicData.cpp | 2 +- src/cpp/xmlparser/XMLElementParser.cpp | 2767 ++++++++++------- src/cpp/xmlparser/XMLParser.cpp | 1642 +++++----- src/cpp/xmlparser/XMLParserCommon.cpp | 63 +- test/unittest/dynamic_types/CMakeLists.txt | 4 +- .../dynamic_types/DynamicTypesTests.cpp | 137 +- test/unittest/dynamic_types/types.xml | 178 +- .../xmlparser/XMLProfileParserTests.cpp | 4 +- test/unittest/xmlparser/test_xml_profiles.xml | 186 +- .../xmlparser/test_xml_profiles_rooted.xml | 186 +- 14 files changed, 3294 insertions(+), 2460 deletions(-) diff --git a/examples/C++/XMLProfiles/XMLProfilesExample.xml b/examples/C++/XMLProfiles/XMLProfilesExample.xml index e44e8d12990..e91ee718007 100644 --- a/examples/C++/XMLProfiles/XMLProfilesExample.xml +++ b/examples/C++/XMLProfiles/XMLProfilesExample.xml @@ -6,7 +6,7 @@ 80 - INFINITE + DURATION_INFINITY diff --git a/include/fastrtps/xmlparser/XMLParser.h b/include/fastrtps/xmlparser/XMLParser.h index a371585d8ee..644f8f155cf 100644 --- a/include/fastrtps/xmlparser/XMLParser.h +++ b/include/fastrtps/xmlparser/XMLParser.h @@ -178,6 +178,11 @@ class XMLParser RTPS_DllAPI static XMLP_ret getXMLHistoryMemoryPolicy(tinyxml2::XMLElement* elem, rtps::MemoryManagementPolicy_t& historyMemoryPolicy, uint8_t ident); RTPS_DllAPI static XMLP_ret getXMLLocatorList(tinyxml2::XMLElement* elem, rtps::LocatorList_t& locatorList, uint8_t ident); + RTPS_DllAPI static XMLP_ret getXMLLocatorUDPv4(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident); + RTPS_DllAPI static XMLP_ret getXMLLocatorUDPv6(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident); + RTPS_DllAPI static XMLP_ret getXMLLocatorTCPv4(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident); + RTPS_DllAPI static XMLP_ret getXMLLocatorTCPv6(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident); + RTPS_DllAPI static XMLP_ret getXMLWriterTimes(tinyxml2::XMLElement* elem, rtps::WriterTimes& times, uint8_t ident); RTPS_DllAPI static XMLP_ret getXMLReaderTimes(tinyxml2::XMLElement* elem, rtps::ReaderTimes& times, uint8_t ident); RTPS_DllAPI static XMLP_ret getXMLDuration(tinyxml2::XMLElement* elem, rtps::Duration_t& duration, uint8_t ident); diff --git a/include/fastrtps/xmlparser/XMLParserCommon.h b/include/fastrtps/xmlparser/XMLParserCommon.h index 777ebe4e6fa..b1b7b9b1895 100644 --- a/include/fastrtps/xmlparser/XMLParserCommon.h +++ b/include/fastrtps/xmlparser/XMLParserCommon.h @@ -117,13 +117,14 @@ extern const char* PREALLOCATED; extern const char* PREALLOCATED_WITH_REALLOC; extern const char* DYNAMIC; extern const char* LOCATOR; +extern const char* UDPv4_LOCATOR; +extern const char* UDPv6_LOCATOR; +extern const char* TCPv4_LOCATOR; +extern const char* TCPv6_LOCATOR; extern const char* KIND; extern const char* ADDRESS; -extern const char* IPV6_ADDRESS; -extern const char* ADDRESSES; extern const char* UNIQUE_LAN_ID; extern const char* WAN_ADDRESS; -extern const char* IP_ADDRESS; extern const char* RESERVED; extern const char* UDPv4; extern const char* UDPv6; @@ -137,9 +138,9 @@ extern const char* NACK_RESP_DELAY; extern const char* NACK_SUPRESSION; extern const char* BY_NAME; extern const char* BY_VAL; -extern const char* _INFINITE; -extern const char* ZERO; -extern const char* INVALID; +extern const char* DURATION_INFINITY; +extern const char* DURATION_INFINITE_SEC; +extern const char* DURATION_INFINITE_NSEC; extern const char* SECONDS; extern const char* FRACTION; extern const char* SHARED; @@ -265,12 +266,10 @@ extern const char* _VOLATILE_DURABILITY_QOS; extern const char* STRENGTH; // TYPES parser -extern const char* STRUCT; -extern const char* UNION; extern const char* BOOLEAN; extern const char* CHAR; extern const char* WCHAR; -extern const char* OCTET; +extern const char* TBYTE; extern const char* SHORT; extern const char* LONG; extern const char* USHORT; @@ -282,23 +281,27 @@ extern const char* DOUBLE; extern const char* LONGDOUBLE; extern const char* STRING; extern const char* WSTRING; -extern const char* BOUNDEDSTRING; -extern const char* BOUNDEDWSTRING; +extern const char* LITERAL; +extern const char* STRUCT; +extern const char* UNION; +extern const char* SEQUENCE; extern const char* MAP; extern const char* TYPEDEF; extern const char* ENUM; -extern const char* LITERAL; -extern const char* SEQUENCE; extern const char* CASE; -extern const char* CASEVALUE; extern const char* DEFAULT; extern const char* DISCRIMINATOR; -extern const char* DIMENSIONS; +extern const char* CASE_DISCRIMINATOR; +extern const char* ARRAY_DIMENSIONS; +extern const char* STR_MAXLENGTH; +extern const char* SEQ_MAXLENGTH; +extern const char* MAP_MAXLENGTH; +extern const char* MAP_KEY_TYPE; +extern const char* ENUMERATOR; +extern const char* NON_BASIC_TYPE; +extern const char* NON_BASIC_TYPE_NAME; extern const char* KEY; -extern const char* KEY_TYPE; -extern const char* VALUE_TYPE; -extern const char* LENGHT; -extern const char* MAXLENGTH; +extern const char* MEMBER; // LOG extern const char* USE_DEFAULT; diff --git a/resources/xsd/fastRTPS_profiles.xsd b/resources/xsd/fastRTPS_profiles.xsd index 80cbb5a706c..fa8f0373b0d 100644 --- a/resources/xsd/fastRTPS_profiles.xsd +++ b/resources/xsd/fastRTPS_profiles.xsd @@ -9,6 +9,14 @@ + + + + + + + + @@ -33,16 +41,6 @@ - - - - - - - - - - @@ -83,86 +81,106 @@ - + - - - + + + + + + + - - - - - - - - - - - + + + + - - - - + + + + - - + + - - - - - - - + + + + + + + - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -185,35 +203,35 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - - - - + + + + @@ -226,8 +244,8 @@ - - + + @@ -240,11 +258,11 @@ - - - - - + + + + + @@ -265,12 +283,12 @@ - - - - - - + + + + + + @@ -296,9 +314,9 @@ - - - + + + @@ -311,8 +329,8 @@ - - + + @@ -376,9 +394,9 @@ - - - + + + @@ -421,50 +439,50 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -472,19 +490,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -497,92 +515,104 @@ - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + + + + + + + - + + + - + - + - + @@ -605,7 +635,7 @@ - + @@ -619,28 +649,26 @@ - + - + - + - + - + - + @@ -659,7 +687,7 @@ - + @@ -728,6 +756,19 @@ + + + + + + + + + + + + + @@ -744,4 +785,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cpp/types/DynamicData.cpp b/src/cpp/types/DynamicData.cpp index 9e1ce4d0945..0271ddd6759 100644 --- a/src/cpp/types/DynamicData.cpp +++ b/src/cpp/types/DynamicData.cpp @@ -4323,7 +4323,7 @@ ResponseCode DynamicData::InsertComplexValue(DynamicData_ptr value, MemberId& ou { #ifdef DYNAMIC_TYPES_CHECKING outId = static_cast(mComplexValues.size()); - mComplexValues.insert(std::make_pair(outId, DynamicDataFactory::GetInstance()->CreateCopy(value))); + mComplexValues.insert(std::make_pair(outId, DynamicDataFactory::GetInstance()->CreateCopy(value.get()))); return ResponseCode::RETCODE_OK; #else outId = static_cast(mValues.size()); diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index c227d234ab6..c7aa4bc47b9 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -26,209 +26,250 @@ using namespace eprosima::fastrtps::xmlparser; XMLP_ret XMLParser::getXMLBuiltinAttributes(tinyxml2::XMLElement *elem, BuiltinAttributes &builtin, uint8_t ident) { - /* - - - - - - - - - - - - - - - - */ + /* + + + + + + + + + + + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; - // use_SIMPLE_RTPS_PDP - boolType - if (nullptr != (p_aux0 = elem->FirstChildElement(SIMPLE_RTPS_PDP))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.use_SIMPLE_RTPSParticipantDiscoveryProtocol, ident)) - return XMLP_ret::XML_ERROR; - } - // use_WriterLivelinessProtocol - boolType - if (nullptr != (p_aux0 = elem->FirstChildElement(WRITER_LVESS_PROTOCOL))) - { - if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.use_WriterLivelinessProtocol, ident)) - return XMLP_ret::XML_ERROR; - } - // EDP - if (nullptr != (p_aux0 = elem->FirstChildElement(_EDP))) - { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, SIMPLE_RTPS_PDP) == 0) { - logError(XMLPARSER, "Node '" << _EDP << "' without content"); - return XMLP_ret::XML_ERROR; + // use_SIMPLE_RTPS_PDP - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.use_SIMPLE_RTPSParticipantDiscoveryProtocol, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, SIMPLE) == 0) + else if (strcmp(name, WRITER_LVESS_PROTOCOL) == 0) { - builtin.use_SIMPLE_EndpointDiscoveryProtocol = true; - builtin.use_STATIC_EndpointDiscoveryProtocol = false; + // use_WriterLivelinessProtocol - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &builtin.use_WriterLivelinessProtocol, ident)) + return XMLP_ret::XML_ERROR; } - else if (strcmp(text, STATIC) == 0) + else if (strcmp(name, _EDP) == 0) { - builtin.use_SIMPLE_EndpointDiscoveryProtocol = false; - builtin.use_STATIC_EndpointDiscoveryProtocol = true; + /* + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << _EDP << "' without content"); + return XMLP_ret::XML_ERROR; + } + else if (strcmp(text, SIMPLE) == 0) + { + builtin.use_SIMPLE_EndpointDiscoveryProtocol = true; + builtin.use_STATIC_EndpointDiscoveryProtocol = false; + } + else if (strcmp(text, STATIC) == 0) + { + builtin.use_SIMPLE_EndpointDiscoveryProtocol = false; + builtin.use_STATIC_EndpointDiscoveryProtocol = true; + } + else + { + logError(XMLPARSER, "Node '" << _EDP << "' with bad content"); + return XMLP_ret::XML_ERROR; + } } - else + else if (strcmp(name, DOMAIN_ID) == 0) { - logError(XMLPARSER, "Node '" << _EDP << "' with bad content"); - return XMLP_ret::XML_ERROR; + // domainId - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &builtin.domainId, ident)) + return XMLP_ret::XML_ERROR; } - } - // domainId - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(DOMAIN_ID))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &builtin.domainId, ident)) - return XMLP_ret::XML_ERROR; - } - // leaseDuration - durationType - if (nullptr != (p_aux0 = elem->FirstChildElement(LEASEDURATION))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, builtin.leaseDuration, ident)) - return XMLP_ret::XML_ERROR; - } - // leaseAnnouncement - durationType - if (nullptr != (p_aux0 = elem->FirstChildElement(LEASE_ANNOUNCE))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, builtin.leaseDuration_announcementperiod, ident)) - return XMLP_ret::XML_ERROR; - } - // simpleEDP - if (nullptr != (p_aux0 = elem->FirstChildElement(SIMPLE_EDP))) - { - // PUBWRITER_SUBREADER - boolType - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(PUBWRITER_SUBREADER))) + else if (strcmp(name, LEASEDURATION) == 0) { - if (XMLP_ret::XML_OK != getXMLBool(p_aux1, &builtin.m_simpleEDP.use_PublicationWriterANDSubscriptionReader, ident + 1)) + // leaseDuration - durationType + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, builtin.leaseDuration, ident)) return XMLP_ret::XML_ERROR; } - // PUBREADER_SUBWRITER - boolType - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(PUBREADER_SUBWRITER))) + else if (strcmp(name, LEASE_ANNOUNCE) == 0) { - if (XMLP_ret::XML_OK != getXMLBool(p_aux1, &builtin.m_simpleEDP.use_PublicationReaderANDSubscriptionWriter, ident + 1)) + // leaseAnnouncement - durationType + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, builtin.leaseDuration_announcementperiod, ident)) return XMLP_ret::XML_ERROR; } - } - // metatrafficUnicastLocatorList - if (nullptr != (p_aux0 = elem->FirstChildElement(META_UNI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficUnicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // metatrafficMulticastLocatorList - if (nullptr != (p_aux0 = elem->FirstChildElement(META_MULTI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficMulticastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // initialPeersList - if (nullptr != (p_aux0 = elem->FirstChildElement(INIT_PEERS_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.initialPeersList, ident)) - return XMLP_ret::XML_ERROR; - } - // staticEndpointXMLFilename - stringType - if (nullptr != (p_aux0 = elem->FirstChildElement(STATIC_ENDPOINT_XML))) - { - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) return XMLP_ret::XML_ERROR; - builtin.setStaticEndpointXMLFilename(s.c_str()); - } - // readerhistoryMemoryPolicy - if (nullptr != (p_aux0 = elem->FirstChildElement(READER_HIST_MEM_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.readerHistoryMemoryPolicy, ident)) - return XMLP_ret::XML_ERROR; - } - // writerhistoryMemoryPolicy - if (nullptr != (p_aux0 = elem->FirstChildElement(WRITER_HIST_MEM_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.writerHistoryMemoryPolicy, ident)) + else if (strcmp(name, SIMPLE_EDP) == 0) + { + // simpleEDP + for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != NULL; p_aux1 = p_aux1->NextSiblingElement()) + { + name = p_aux1->Name(); + if (strcmp(name, PUBWRITER_SUBREADER) == 0) + { + // PUBWRITER_SUBREADER - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux1, &builtin.m_simpleEDP.use_PublicationWriterANDSubscriptionReader, ident + 1)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PUBREADER_SUBWRITER) == 0) + { + // PUBREADER_SUBWRITER - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux1, &builtin.m_simpleEDP.use_PublicationReaderANDSubscriptionWriter, ident + 1)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'simpleEDP'. Name: " << name); + return XMLP_ret::XML_ERROR; + } + } + } + else if (strcmp(name, META_UNI_LOC_LIST) == 0) + { + // metatrafficUnicastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficUnicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, META_MULTI_LOC_LIST) == 0) + { + // metatrafficMulticastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.metatrafficMulticastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, INIT_PEERS_LIST) == 0) + { + // initialPeersList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, builtin.initialPeersList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, STATIC_ENDPOINT_XML) == 0) + { + // staticEndpointXMLFilename - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) + return XMLP_ret::XML_ERROR; + builtin.setStaticEndpointXMLFilename(s.c_str()); + } + else if (strcmp(name, READER_HIST_MEM_POLICY) == 0) + { + // readerhistoryMemoryPolicy + if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.readerHistoryMemoryPolicy, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, WRITER_HIST_MEM_POLICY) == 0) + { + // writerhistoryMemoryPolicy + if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, builtin.writerHistoryMemoryPolicy, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'builtinAttributesType'. Name: " << name); return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; - } XMLP_ret XMLParser::getXMLPortParameters(tinyxml2::XMLElement *elem, PortParameters &port, uint8_t ident) { - /* - - - - - - - - - - */ + /* + + + + + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - // portBase - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(PORT_BASE))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.portBase, ident)) return XMLP_ret::XML_ERROR; - } - // domainIDGain - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(DOMAIN_ID_GAIN))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.domainIDGain, ident)) return XMLP_ret::XML_ERROR; - } - // participantIDGain - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(PARTICIPANT_ID_GAIN))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.participantIDGain, ident)) return XMLP_ret::XML_ERROR; - } - // offsetd0 - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(OFFSETD0))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd0, ident)) return XMLP_ret::XML_ERROR; - } - // offsetd1 - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(OFFSETD1))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd1, ident)) return XMLP_ret::XML_ERROR; - } - // offsetd2 - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(OFFSETD2))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd2, ident)) return XMLP_ret::XML_ERROR; - } - // offsetd3 - uint16Type - if (nullptr != (p_aux0 = elem->FirstChildElement(OFFSETD3))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd3, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, PORT_BASE) == 0) + { + // portBase - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.portBase, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, DOMAIN_ID_GAIN) == 0) + { + // domainIDGain - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.domainIDGain, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PARTICIPANT_ID_GAIN) == 0) + { + // participantIDGain - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.participantIDGain, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, OFFSETD0) == 0) + { + // offsetd0 - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd0, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, OFFSETD1) == 0) + { + // offsetd1 - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd1, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, OFFSETD2) == 0) + { + // offsetd2 - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd2, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, OFFSETD3) == 0) + { + // offsetd3 - uint16Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port.offsetd3, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'portType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } XMLP_ret XMLParser::getXMLTransports(tinyxml2::XMLElement *elem, std::vector> &transports, uint8_t /*ident*/) { - /* - - - - */ - tinyxml2::XMLElement *p_aux0 = nullptr; + /* + + + + + + */ + tinyxml2::XMLElement *p_aux0 = nullptr; p_aux0 = elem->FirstChildElement(TRANSPORT_ID); if (nullptr == p_aux0) { @@ -267,1052 +308,1545 @@ XMLP_ret XMLParser::getXMLThroughputController(tinyxml2::XMLElement *elem, ThroughputControllerDescriptor &throughputController, uint8_t ident) { - /* - - - - - */ + /* + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // bytesPerPeriod - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(BYTES_PER_SECOND))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &throughputController.bytesPerPeriod, ident)) return XMLP_ret::XML_ERROR; - } - // periodMillisecs - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(PERIOD_MILLISECS))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &throughputController.periodMillisecs, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, BYTES_PER_SECOND) == 0) + { + // bytesPerPeriod - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &throughputController.bytesPerPeriod, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PERIOD_MILLISECS) == 0) + { + // periodMillisecs - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &throughputController.periodMillisecs, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'portType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } XMLP_ret XMLParser::getXMLTopicAttributes(tinyxml2::XMLElement *elem, TopicAttributes &topic, uint8_t ident) { - /* - - - - - - - - */ - + /* + + + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // kind - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + // kind + /* + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, _NO_KEY) == 0) + topic.topicKind = TopicKind_t::NO_KEY; + else if (strcmp(text, _WITH_KEY) == 0) + topic.topicKind = TopicKind_t::WITH_KEY; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, NAME) == 0) + { + // name - stringType + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &topic.topicName, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, DATA_TYPE) == 0) + { + // dataType - stringType + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &topic.topicDataType, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, HISTORY_QOS) == 0) + { + // historyQos + if (XMLP_ret::XML_OK != getXMLHistoryQosPolicy(p_aux0, topic.historyQos, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, RES_LIMITS_QOS) == 0) + { + // resourceLimitsQos + if (XMLP_ret::XML_OK != getXMLResourceLimitsQos(p_aux0, topic.resourceLimitsQos, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, _NO_KEY) == 0) topic.topicKind = TopicKind_t::NO_KEY; - else if (strcmp(text, _WITH_KEY) == 0) topic.topicKind = TopicKind_t::WITH_KEY; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'topicAttributesType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - // name - stringType - if (nullptr != (p_aux0 = elem->FirstChildElement(NAME))) - { - if (XMLP_ret::XML_OK != getXMLString(p_aux0, &topic.topicName, ident)) return XMLP_ret::XML_ERROR; - } - // dataType - stringType - if (nullptr != (p_aux0 = elem->FirstChildElement(DATA_TYPE))) - { - if (XMLP_ret::XML_OK != getXMLString(p_aux0, &topic.topicDataType, ident)) return XMLP_ret::XML_ERROR; - } - // historyQos - if (nullptr != (p_aux0 = elem->FirstChildElement(HISTORY_QOS))) + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::getXMLResourceLimitsQos(tinyxml2::XMLElement *elem, + ResourceLimitsQosPolicy &resourceLimitsQos, + uint8_t ident) +{ + /* + + + + + + + + + */ + + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLHistoryQosPolicy(p_aux0, topic.historyQos, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, MAX_SAMPLES) == 0) + { + // max_samples - int32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MAX_INSTANCES) == 0) + { + // max_instances - int32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_instances, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MAX_SAMPLES_INSTANCE) == 0) + { + // max_samples_per_instance - int32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples_per_instance, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, ALLOCATED_SAMPLES) == 0) + { + // allocated_samples - int32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.allocated_samples, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'resourceLimitsQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - // resourceLimitsQos - if (nullptr != (p_aux0 = elem->FirstChildElement(RES_LIMITS_QOS))) + + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::getXMLHistoryQosPolicy(tinyxml2::XMLElement *elem, HistoryQosPolicy &historyQos, uint8_t ident) +{ + /* + + + + + + + */ + + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLResourceLimitsQos(p_aux0, topic.resourceLimitsQos, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) + { + // kind + /* + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, KEEP_LAST) == 0) + historyQos.kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; + else if (strcmp(text, KEEP_ALL) == 0) + historyQos.kind = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, DEPTH) == 0) + { + // depth - uint32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &historyQos.depth, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'historyQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLResourceLimitsQos(tinyxml2::XMLElement *elem, - ResourceLimitsQosPolicy &resourceLimitsQos, - uint8_t ident) +XMLP_ret XMLParser::getXMLWriterQosPolicies(tinyxml2::XMLElement *elem, WriterQos &qos, uint8_t ident) { - /* - - - - - - - */ + /* + + + + + + + + + + + + + + + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // max_samples - int32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_SAMPLES))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples, ident)) + name = p_aux0->Name(); + if (strcmp(name, DURABILITY) == 0) + { + // durability + if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux0, qos.m_durability, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, LIVELINESS) == 0) + { + // liveliness + if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux0, qos.m_liveliness, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, RELIABILITY) == 0) + { + // reliability + if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux0, qos.m_reliability, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PARTITION) == 0) + { + // partition + if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux0, qos.m_partition, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PUB_MODE) == 0) + { + // publishMode + if (XMLP_ret::XML_OK != getXMLPublishModeQos(p_aux0, qos.m_publishMode, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, DEADLINE) == 0 || + strcmp(name, LATENCY_BUDGET) == 0 || strcmp(name, LIFESPAN) == 0 || + strcmp(name, USER_DATA) == 0 || strcmp(name, TIME_FILTER) == 0 || + strcmp(name, OWNERSHIP) == 0 || strcmp(name, OWNERSHIP_STRENGTH) == 0 || + strcmp(name, DEST_ORDER) == 0 || strcmp(name, PRESENTATION) == 0 || + strcmp(name, TOPIC_DATA) == 0 || strcmp(name, GROUP_DATA) == 0) + { + // TODO: Do not supported for now + //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER))) getXMLTimeBasedFilterQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP))) getXMLOwnershipQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement(OWNERSHIP_STRENGTH))) getXMLOwnershipStrengthQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER))) getXMLDestinationOrderQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( PRESENTATION))) getXMLPresentationQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA))) getXMLTopicDataQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) getXMLGroupDataQos(p_aux, ident); + logError(XMLPARSER, "Quality os Service '" << p_aux0->Value() << "' do not supported for now"); + } + else + { + logError(XMLPARSER, "Invalid element found into 'writerQosPoliciesType'. Name: " << name); return XMLP_ret::XML_ERROR; + } } - // max_instances - int32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_INSTANCES))) + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::getXMLReaderQosPolicies(tinyxml2::XMLElement *elem, ReaderQos &qos, uint8_t ident) +{ + /* + + + + + + + + + + + + + + + + + + + + */ + + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_instances, ident)) + name = p_aux0->Name(); + if (strcmp(name, DURABILITY) == 0) + { + // durability + if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux0, qos.m_durability, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, LIVELINESS) == 0) + { + // liveliness + if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux0, qos.m_liveliness, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, RELIABILITY) == 0) + { + // reliability + if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux0, qos.m_reliability, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PARTITION) == 0) + { + // partition + if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux0, qos.m_partition, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, DEADLINE) == 0 || + strcmp(name, LATENCY_BUDGET) == 0 || strcmp(name, LIFESPAN) == 0 || + strcmp(name, USER_DATA) == 0 || strcmp(name, TIME_FILTER) == 0 || + strcmp(name, OWNERSHIP) == 0 || strcmp(name, OWNERSHIP_STRENGTH) == 0 || + strcmp(name, DEST_ORDER) == 0 || strcmp(name, PRESENTATION) == 0 || + strcmp(name, TOPIC_DATA) == 0 || strcmp(name, GROUP_DATA) == 0) + { + // TODO: Do not supported for now + //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER))) getXMLTimeBasedFilterQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP))) getXMLOwnershipQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER))) getXMLDestinationOrderQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( PRESENTATION))) getXMLPresentationQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA))) getXMLTopicDataQos(p_aux, ident); + //if (nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) getXMLGroupDataQos(p_aux, ident); + logError(XMLPARSER, "Quality os Service '" << p_aux0->Value() << "' do not supported for now"); + } + else + { + logError(XMLPARSER, "Invalid element found into 'readerQosPoliciesType'. Name: " << name); return XMLP_ret::XML_ERROR; + } } - // max_samples_per_instance - int32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_SAMPLES_INSTANCE))) + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::getXMLDurabilityQos(tinyxml2::XMLElement *elem, DurabilityQosPolicy &durability, uint8_t /*ident*/) +{ + /* + + + + + + */ + + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + bool bKindDefined = false; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.max_samples_per_instance, ident)) + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) + { + // kind + /* + + + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + bKindDefined = true; + if (strcmp(text, _VOLATILE) == 0) + durability.kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS; + else if (strcmp(text, _TRANSIENT_LOCAL) == 0) + durability.kind = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS; + else if (strcmp(text, _TRANSIENT) == 0) + durability.kind = DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS; + else if (strcmp(text, _PERSISTENT) == 0) + durability.kind = DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else + { + logError(XMLPARSER, "Invalid element found into 'durabilityQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; + } } - // allocated_samples - int32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(ALLOCATED_SAMPLES))) + if (!bKindDefined) { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &resourceLimitsQos.allocated_samples, ident)) + logError(XMLPARSER, "Node 'durabilityQosPolicyType' without content"); + return XMLP_ret::XML_ERROR; + } + + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::getXMLDurabilityServiceQos(tinyxml2::XMLElement *elem, + DurabilityServiceQosPolicy &durabilityService, + uint8_t ident) +{ + /* + + + + + + + + + + + */ + + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) + { + name = p_aux0->Name(); + if (strcmp(name, SRV_CLEAN_DELAY) == 0) + { + // service_cleanup_delay - durationType + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, durabilityService.service_cleanup_delay, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, HISTORY_KIND) == 0) + { + // history_kind + /* + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << HISTORY_KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, KEEP_LAST) == 0) + durabilityService.history_kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; + else if (strcmp(text, KEEP_ALL) == 0) + durabilityService.history_kind = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS; + else + { + logError(XMLPARSER, "Node '" << HISTORY_KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, HISTORY_DEPTH) == 0) + { + // history_depth - uint32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.history_depth, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MAX_SAMPLES) == 0) + { + // max_samples - uint32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_samples, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MAX_INSTANCES) == 0) + { + // max_instances - uint32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_instances, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MAX_SAMPLES_INSTANCE) == 0) + { + // max_samples_per_instance - uint32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_samples_per_instance, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'durabilityServiceQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLHistoryQosPolicy(tinyxml2::XMLElement *elem, HistoryQosPolicy &historyQos, uint8_t ident) +XMLP_ret XMLParser::getXMLDeadlineQos(tinyxml2::XMLElement *elem, DeadlineQosPolicy &deadline, uint8_t ident) { - /* - - - - - */ - + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // kind - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + const char* name = nullptr; + bool bPeriodDefined = false; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, PERIOD) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + bPeriodDefined = true; + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, deadline.period, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, KEEP_LAST) == 0) historyQos.kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; - else if (strcmp(text, KEEP_ALL) == 0) historyQos.kind = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'deadlineQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - // depth - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(DEPTH))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &historyQos.depth, ident)) return XMLP_ret::XML_ERROR; - } - return XMLP_ret::XML_OK; -} - -XMLP_ret XMLParser::getXMLWriterQosPolicies(tinyxml2::XMLElement *elem, WriterQos &qos, uint8_t ident) -{ - /* - - - - - - - - - - - - - - - - - - - - */ - - tinyxml2::XMLElement *p_aux = nullptr; - - // durability - if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY))) - { - if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux, qos.m_durability, ident)) return XMLP_ret::XML_ERROR; - } - // liveliness - if (nullptr != (p_aux = elem->FirstChildElement( LIVELINESS))) - { - if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux, qos.m_liveliness, ident)) return XMLP_ret::XML_ERROR; - } - // reliability - if (nullptr != (p_aux = elem->FirstChildElement( RELIABILITY))) - { - if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux, qos.m_reliability, ident)) return XMLP_ret::XML_ERROR; - } - // partition - if (nullptr != (p_aux = elem->FirstChildElement( PARTITION))) - { - if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux, qos.m_partition, ident)) return XMLP_ret::XML_ERROR; - } - // publishMode - if (nullptr != (p_aux = elem->FirstChildElement( PUB_MODE))) - { - if (XMLP_ret::XML_OK != getXMLPublishModeQos(p_aux, qos.m_publishMode, ident)) return XMLP_ret::XML_ERROR; - } - - if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV)) || - nullptr != (p_aux = elem->FirstChildElement( DEADLINE)) || - nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET)) || - nullptr != (p_aux = elem->FirstChildElement( LIFESPAN)) || - nullptr != (p_aux = elem->FirstChildElement( USER_DATA)) || - nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER)) || - nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP)) || - nullptr != (p_aux = elem->FirstChildElement(OWNERSHIP_STRENGTH)) || - nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER)) || - nullptr != (p_aux = elem->FirstChildElement( PRESENTATION)) || - nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA)) || - nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) - - logError(XMLPARSER, "Quality os Service '" << p_aux->Value() << "' do not supported for now"); - - // TODO: Do not supported for now - //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER))) getXMLTimeBasedFilterQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP))) getXMLOwnershipQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement(OWNERSHIP_STRENGTH))) getXMLOwnershipStrengthQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER))) getXMLDestinationOrderQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( PRESENTATION))) getXMLPresentationQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA))) getXMLTopicDataQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) getXMLGroupDataQos(p_aux, ident); - return XMLP_ret::XML_OK; -} - -XMLP_ret XMLParser::getXMLReaderQosPolicies(tinyxml2::XMLElement *elem, ReaderQos &qos, uint8_t ident) -{ - /* - - - - - - - - - - - - - - - - - - */ - - tinyxml2::XMLElement *p_aux = nullptr; - - // durability - if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY))) - { - if (XMLP_ret::XML_OK != getXMLDurabilityQos(p_aux, qos.m_durability, ident)) return XMLP_ret::XML_ERROR; - } - // liveliness - if (nullptr != (p_aux = elem->FirstChildElement( LIVELINESS))) - { - if (XMLP_ret::XML_OK != getXMLLivelinessQos(p_aux, qos.m_liveliness, ident)) return XMLP_ret::XML_ERROR; - } - // reliability - if (nullptr != (p_aux = elem->FirstChildElement( RELIABILITY))) - { - if (XMLP_ret::XML_OK != getXMLReliabilityQos(p_aux, qos.m_reliability, ident)) return XMLP_ret::XML_ERROR; - } - // partition - if (nullptr != (p_aux = elem->FirstChildElement( PARTITION))) + if (!bPeriodDefined) { - if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux, qos.m_partition, ident)) return XMLP_ret::XML_ERROR; + logError(XMLPARSER, "Node 'deadlineQosPolicyType' without content"); + return XMLP_ret::XML_ERROR; } - if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV)) || - nullptr != (p_aux = elem->FirstChildElement( DEADLINE)) || - nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET)) || - nullptr != (p_aux = elem->FirstChildElement( LIFESPAN)) || - nullptr != (p_aux = elem->FirstChildElement( USER_DATA)) || - nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER)) || - nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP)) || - nullptr != (p_aux = elem->FirstChildElement(OWNERSHIP_STRENGTH)) || - nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER)) || - nullptr != (p_aux = elem->FirstChildElement( PRESENTATION)) || - nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA)) || - nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) - - logError(XMLPARSER, "Quality os Service '" << p_aux->Value() << "' do not supported for now"); - - // TODO: Do not supported for now - //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( TIME_FILTER))) getXMLTimeBasedFilterQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( OWNERSHIP))) getXMLOwnershipQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEST_ORDER))) getXMLDestinationOrderQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( PRESENTATION))) getXMLPresentationQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( TOPIC_DATA))) getXMLTopicDataQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( GROUP_DATA))) getXMLGroupDataQos(p_aux, ident); - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLDurabilityQos(tinyxml2::XMLElement *elem, DurabilityQosPolicy &durability, uint8_t /*ident*/) +XMLP_ret XMLParser::getXMLLatencyBudgetQos(tinyxml2::XMLElement *elem, LatencyBudgetQosPolicy &latencyBudget, uint8_t ident) { - /* - - - - */ + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // kind - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + const char* name = nullptr; + bool bDurationDefined = false; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, DURATION) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + bDurationDefined = true; + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, latencyBudget.duration, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, _VOLATILE) == 0) - durability.kind = DurabilityQosPolicyKind::VOLATILE_DURABILITY_QOS; - else if (strcmp(text, _TRANSIENT_LOCAL) == 0) - durability.kind = DurabilityQosPolicyKind::TRANSIENT_LOCAL_DURABILITY_QOS; - else if (strcmp(text, _TRANSIENT) == 0) - durability.kind = DurabilityQosPolicyKind::TRANSIENT_DURABILITY_QOS; - else if (strcmp(text, _PERSISTENT) == 0) - durability.kind = DurabilityQosPolicyKind::PERSISTENT_DURABILITY_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'latencyBudgetQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - else + + if (!bDurationDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'latencyBudgetQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLDurabilityServiceQos(tinyxml2::XMLElement *elem, - DurabilityServiceQosPolicy &durabilityService, - uint8_t ident) +XMLP_ret XMLParser::getXMLLivelinessQos(tinyxml2::XMLElement *elem, LivelinessQosPolicy &liveliness, uint8_t ident) { - /* - - - - - - - - - */ + /* + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - // service_cleanup_delay - durationType - if (nullptr != (p_aux0 = elem->FirstChildElement(SRV_CLEAN_DELAY))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, durabilityService.service_cleanup_delay, ident)) - return XMLP_ret::XML_ERROR; - } - // history_kind - if (nullptr != (p_aux0 = elem->FirstChildElement(HISTORY_KIND))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) { - logError(XMLPARSER, "Node '" << HISTORY_KIND << "' without content"); - return XMLP_ret::XML_ERROR; + // kind + /* + + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, AUTOMATIC) == 0) + liveliness.kind = LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS; + else if (strcmp(text, MANUAL_BY_PARTICIPANT) == 0) + liveliness.kind = LivelinessQosPolicyKind::MANUAL_BY_PARTICIPANT_LIVELINESS_QOS; + else if (strcmp(text, MANUAL_BY_TOPIC) == 0) + liveliness.kind = LivelinessQosPolicyKind::MANUAL_BY_TOPIC_LIVELINESS_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, LEASE_DURATION) == 0) + { + // lease_duration + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.lease_duration, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, ANNOUNCE_PERIOD) == 0) + { + // announcement_period + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.announcement_period, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, KEEP_LAST) == 0) - durabilityService.history_kind = HistoryQosPolicyKind::KEEP_LAST_HISTORY_QOS; - else if (strcmp(text, KEEP_ALL) == 0) - durabilityService.history_kind = HistoryQosPolicyKind::KEEP_ALL_HISTORY_QOS; else { - logError(XMLPARSER, "Node '" << HISTORY_KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'livelinessQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - // history_depth - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(HISTORY_DEPTH))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.history_depth, ident)) - return XMLP_ret::XML_ERROR; - } - // max_samples - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_SAMPLES))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_samples, ident)) - return XMLP_ret::XML_ERROR; - } - // max_instances - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_INSTANCES))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_instances, ident)) - return XMLP_ret::XML_ERROR; - } - // max_samples_per_instance - uint32Type - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_SAMPLES_INSTANCE))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &durabilityService.max_samples_per_instance, ident)) - return XMLP_ret::XML_ERROR; - } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLDeadlineQos(tinyxml2::XMLElement *elem, DeadlineQosPolicy &deadline, uint8_t ident) +XMLP_ret XMLParser::getXMLReliabilityQos(tinyxml2::XMLElement *elem, ReliabilityQosPolicy &reliability, uint8_t ident) { - /* - - - - */ + /* + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(PERIOD))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, deadline.period, ident)) return XMLP_ret::XML_ERROR; - } - else + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); - return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) + { + // kind + /* + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, _BEST_EFFORT) == 0) + reliability.kind = ReliabilityQosPolicyKind::BEST_EFFORT_RELIABILITY_QOS; + else if (strcmp(text, _RELIABLE) == 0) + reliability.kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, MAX_BLOCK_TIME) == 0) + { + // max_blocking_time + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, reliability.max_blocking_time, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'reliabilityQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLLatencyBudgetQos(tinyxml2::XMLElement *elem, LatencyBudgetQosPolicy &latencyBudget, uint8_t ident) +XMLP_ret XMLParser::getXMLLifespanQos(tinyxml2::XMLElement *elem, LifespanQosPolicy &lifespan, uint8_t ident) { - /* - - - - */ + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(DURATION))) + bool bDurationDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, latencyBudget.duration, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, DURATION) == 0) + { + bDurationDefined = true; + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, lifespan.duration, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'lifespanQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - else + + if (!bDurationDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'lifespanQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLLivelinessQos(tinyxml2::XMLElement *elem, LivelinessQosPolicy &liveliness, uint8_t ident) +XMLP_ret XMLParser::getXMLTimeBasedFilterQos(tinyxml2::XMLElement *elem, + TimeBasedFilterQosPolicy &timeBasedFilter, + uint8_t ident) { - /* - - - - - - */ - - bool haveSomeField = false; + /* + + + + + + */ + tinyxml2::XMLElement *p_aux0 = nullptr; - // kind - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + bool bSeparationDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, MIN_SEPARATION) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + bSeparationDefined = true; + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, timeBasedFilter.minimum_separation, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, AUTOMATIC) == 0) - liveliness.kind = LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS; - else if (strcmp(text, MANUAL_BY_PARTICIPANT) == 0) - liveliness.kind = LivelinessQosPolicyKind::MANUAL_BY_PARTICIPANT_LIVELINESS_QOS; - else if (strcmp(text, MANUAL_BY_TOPIC) == 0) - liveliness.kind = LivelinessQosPolicyKind::MANUAL_BY_TOPIC_LIVELINESS_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'timeBasedFilterQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } - haveSomeField = true; - } - // lease_duration - if (nullptr != (p_aux0 = elem->FirstChildElement(LEASE_DURATION))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.lease_duration, ident)) return XMLP_ret::XML_ERROR; - haveSomeField = true; - } - // announcement_period - if (nullptr != (p_aux0 = elem->FirstChildElement(ANNOUNCE_PERIOD))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, liveliness.announcement_period, ident)) return XMLP_ret::XML_ERROR; - haveSomeField = true; } - if (!haveSomeField) + + if (!bSeparationDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'timeBasedFilterQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLReliabilityQos(tinyxml2::XMLElement *elem, ReliabilityQosPolicy &reliability, uint8_t ident) +XMLP_ret XMLParser::getXMLOwnershipQos(tinyxml2::XMLElement *elem, OwnershipQosPolicy &ownership, uint8_t /*ident*/) { - /* - - - - - */ - - bool haveSomeField = false; + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - // kind - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + bool bKindDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + /* + + + + + + + */ + bKindDefined = true; + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, SHARED) == 0) + ownership.kind = OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS; + else if (strcmp(text, EXCLUSIVE) == 0) + ownership.kind = OwnershipQosPolicyKind::EXCLUSIVE_OWNERSHIP_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + return XMLP_ret::XML_ERROR; + } } - if (strcmp(text, _BEST_EFFORT) == 0) - reliability.kind = ReliabilityQosPolicyKind::BEST_EFFORT_RELIABILITY_QOS; - else if (strcmp(text, _RELIABLE) == 0) - reliability.kind = ReliabilityQosPolicyKind::RELIABLE_RELIABILITY_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'ownershipQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } - haveSomeField = true; } - // max_blocking_time - if (nullptr != (p_aux0 = elem->FirstChildElement(MAX_BLOCK_TIME))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, reliability.max_blocking_time, ident)) return XMLP_ret::XML_ERROR; - haveSomeField = true; - } - if (!haveSomeField) + + if (!bKindDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'ownershipQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } + return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLLifespanQos(tinyxml2::XMLElement *elem, LifespanQosPolicy &lifespan, uint8_t ident) +XMLP_ret XMLParser::getXMLOwnershipStrengthQos(tinyxml2::XMLElement *elem, + OwnershipStrengthQosPolicy &ownershipStrength, + uint8_t ident) { - /* - - - - */ - + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(DURATION))) + bool bValueDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, lifespan.duration, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, VALUE) == 0) + { + bValueDefined = true; + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &ownershipStrength.value, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'ownershipStrengthQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - else + + if (!bValueDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'ownershipStrengthQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLTimeBasedFilterQos(tinyxml2::XMLElement *elem, - TimeBasedFilterQosPolicy &timeBasedFilter, - uint8_t ident) +XMLP_ret XMLParser::getXMLDestinationOrderQos(tinyxml2::XMLElement *elem, + DestinationOrderQosPolicy &destinationOrder, + uint8_t /*ident*/) { - /* - - - - */ + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(MIN_SEPARATION))) + bool bKindDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, timeBasedFilter.minimum_separation, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) + { + /* + + + + + + + */ + bKindDefined = true; + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, BY_RECEPTION_TIMESTAMP) == 0) + destinationOrder.kind = DestinationOrderQosPolicyKind::BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS; + else if (strcmp(text, BY_SOURCE_TIMESTAMP) == 0) + destinationOrder.kind = DestinationOrderQosPolicyKind::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS; + else + { + logError(XMLPARSER, "Node '" << KIND << "' bad content"); + return XMLP_ret::XML_ERROR; + } + } + else + { + logError(XMLPARSER, "Invalid element found into 'destinationOrderQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - else + + if (!bKindDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'destinationOrderQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLOwnershipQos(tinyxml2::XMLElement *elem, OwnershipQosPolicy &ownership, uint8_t /*ident*/) +XMLP_ret XMLParser::getXMLPresentationQos(tinyxml2::XMLElement *elem, PresentationQosPolicy &presentation, uint8_t ident) { - /* - - - - */ + /* + + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, ACCESS_SCOPE) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + // access_scope + /* + + + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << ACCESS_SCOPE << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, INSTANCE) == 0) + presentation.access_scope = PresentationQosPolicyAccessScopeKind::INSTANCE_PRESENTATION_QOS; + else if (strcmp(text, TOPIC) == 0) + presentation.access_scope = PresentationQosPolicyAccessScopeKind::TOPIC_PRESENTATION_QOS; + else if (strcmp(text, GROUP) == 0) + presentation.access_scope = PresentationQosPolicyAccessScopeKind::GROUP_PRESENTATION_QOS; + else + { + logError(XMLPARSER, "Node '" << ACCESS_SCOPE << "' bad content"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, COHERENT_ACCESS) == 0) + { + // coherent_access - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &presentation.coherent_access, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, ORDERED_ACCESS) == 0) + { + // ordered_access - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &presentation.ordered_access, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, SHARED) == 0) - ownership.kind = OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS; - else if (strcmp(text, EXCLUSIVE) == 0) - ownership.kind = OwnershipQosPolicyKind::EXCLUSIVE_OWNERSHIP_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' with bad content"); + logError(XMLPARSER, "Invalid element found into 'presentationQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - else - { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); - return XMLP_ret::XML_ERROR; - } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLOwnershipStrengthQos(tinyxml2::XMLElement *elem, - OwnershipStrengthQosPolicy &ownershipStrength, - uint8_t ident) +XMLP_ret XMLParser::getXMLPartitionQos(tinyxml2::XMLElement *elem, PartitionQosPolicy &partition, uint8_t ident) { - /* - - - - */ + /* + + + + + + */ - tinyxml2::XMLElement *p_aux0 = nullptr; + tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; + bool bNamesDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) + { + name = p_aux0->Name(); + if (strcmp(name, NAMES) == 0) + { + bNamesDefined = true; + p_aux1 = p_aux0->FirstChildElement(NAME); + if (nullptr == p_aux1) + { + // Not even one + logError(XMLPARSER, "Node '" << NAMES << "' without content"); + return XMLP_ret::XML_ERROR; + } - if (nullptr != (p_aux0 = elem->FirstChildElement(VALUE))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &ownershipStrength.value, ident)) return XMLP_ret::XML_ERROR; + std::vector names; + while (nullptr != p_aux1) + { + std::string sName = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux1, &sName, ident)) return XMLP_ret::XML_ERROR; + names.push_back(sName); + p_aux1 = p_aux1->NextSiblingElement(NAME); + } + partition.setNames(names); + } + else + { + logError(XMLPARSER, "Invalid element found into 'partitionQosPolicyType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - else + + if (!bNamesDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'partitionQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLDestinationOrderQos(tinyxml2::XMLElement *elem, - DestinationOrderQosPolicy &destinationOrder, - uint8_t /*ident*/) +XMLP_ret XMLParser::getXMLPublishModeQos(tinyxml2::XMLElement *elem, PublishModeQosPolicy &publishMode, uint8_t /*ident*/) { - /* - - - - */ - + /* + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + bool bKindDefined = false; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, KIND) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + /* + + + + + + + */ + bKindDefined = true; + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node '" << KIND << "' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, SYNCHRONOUS) == 0) + publishMode.kind = PublishModeQosPolicyKind::SYNCHRONOUS_PUBLISH_MODE; + else if (strcmp(text, ASYNCHRONOUS) == 0) + publishMode.kind = PublishModeQosPolicyKind::ASYNCHRONOUS_PUBLISH_MODE; + else + { + logError(XMLPARSER, "Node '" << KIND << "' bad content"); + return XMLP_ret::XML_ERROR; + } } - if (strcmp(text, BY_RECEPTION_TIMESTAMP) == 0) - destinationOrder.kind = DestinationOrderQosPolicyKind::BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS; - else if (strcmp(text, BY_SOURCE_TIMESTAMP) == 0) - destinationOrder.kind = DestinationOrderQosPolicyKind::BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS; else { - logError(XMLPARSER, "Node '" << KIND << "' bad content"); + logError(XMLPARSER, "Invalid element found into 'publishModeQosPolicyType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - else + + if (!bKindDefined) { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); + logError(XMLPARSER, "Node 'publishModeQosPolicyType' without content"); return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLPresentationQos(tinyxml2::XMLElement *elem, PresentationQosPolicy &presentation, uint8_t ident) +XMLP_ret XMLParser::getXMLDuration(tinyxml2::XMLElement *elem, Duration_t &duration, uint8_t ident) { - /* - - - - - - */ + /* + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - // access_scope - if (nullptr != (p_aux0 = elem->FirstChildElement(ACCESS_SCOPE))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, SECONDS) == 0) { - logError(XMLPARSER, "Node '" << ACCESS_SCOPE << "' without content"); - return XMLP_ret::XML_ERROR; + /* + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node 'SECONDS' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, DURATION_INFINITY) == 0) + duration = c_TimeInfinite; + else if (strcmp(text, DURATION_INFINITE_SEC) == 0) + duration.seconds = c_TimeInfinite.seconds; + else if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &duration.seconds, ident)) + { + logError(XMLPARSER, "<" << elem->Value() << "> getXMLInt XML_ERROR!"); + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, FRACTION) == 0) + { + /* + + + + + + */ + const char* text = p_aux0->GetText(); + if (nullptr == text) + { + logError(XMLPARSER, "Node 'FRACTION' without content"); + return XMLP_ret::XML_ERROR; + } + if (strcmp(text, DURATION_INFINITY) == 0) + duration = c_TimeInfinite; + else if (strcmp(text, DURATION_INFINITE_NSEC) == 0) + duration.fraction = c_TimeInfinite.fraction; + else if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &duration.fraction, ident)) + { + logError(XMLPARSER, "<" << elem->Value() << "> getXMLInt XML_ERROR!"); + return XMLP_ret::XML_ERROR; + } } - if (strcmp(text, INSTANCE) == 0) - presentation.access_scope = PresentationQosPolicyAccessScopeKind::INSTANCE_PRESENTATION_QOS; - else if (strcmp(text, TOPIC) == 0) - presentation.access_scope = PresentationQosPolicyAccessScopeKind::TOPIC_PRESENTATION_QOS; - else if (strcmp(text, GROUP) == 0) - presentation.access_scope = PresentationQosPolicyAccessScopeKind::GROUP_PRESENTATION_QOS; else { - logError(XMLPARSER, "Node '" << ACCESS_SCOPE << "' bad content"); + logError(XMLPARSER, "Invalid element found into 'durationType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - // coherent_access - boolType - if (nullptr != (p_aux0 = elem->FirstChildElement(COHERENT_ACCESS))) - { - if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &presentation.coherent_access, ident)) return XMLP_ret::XML_ERROR; - } - // ordered_access - boolType - if (nullptr != (p_aux0 = elem->FirstChildElement(ORDERED_ACCESS))) - { - if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &presentation.ordered_access, ident)) return XMLP_ret::XML_ERROR; - } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLPartitionQos(tinyxml2::XMLElement *elem, PartitionQosPolicy &partition, uint8_t ident) +XMLP_ret XMLParser::getXMLWriterTimes(tinyxml2::XMLElement *elem, WriterTimes ×, uint8_t ident) { - /* - - - - */ - - tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(NAMES))) + /* + + + + + + + + + */ + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - p_aux1 = p_aux0->FirstChildElement(NAME); - if (nullptr == p_aux1) + name = p_aux0->Name(); + if (strcmp(name, INIT_HEARTB_DELAY) == 0) { - // Not even one - logError(XMLPARSER, "Node '" << NAMES << "' without content"); - return XMLP_ret::XML_ERROR; + // initialHeartbeatDelay + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialHeartbeatDelay, ident)) + return XMLP_ret::XML_ERROR; } - std::vector names; - while (nullptr != p_aux1) + else if (strcmp(name, HEARTB_PERIOD) == 0) { - std::string name = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux1, &name, ident)) return XMLP_ret::XML_ERROR; - names.push_back(name); - p_aux1 = p_aux1->NextSiblingElement(NAME); + // heartbeatPeriod + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatPeriod, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, NACK_RESP_DELAY) == 0) + { + // nackResponseDelay + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackResponseDelay, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, NACK_SUPRESSION) == 0) + { + // nackSupressionDuration + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackSupressionDuration, ident)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'writerTimesType'. Name: " << name); + return XMLP_ret::XML_ERROR; } - partition.setNames(names); - } - else - { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); - return XMLP_ret::XML_ERROR; } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLPublishModeQos(tinyxml2::XMLElement *elem, PublishModeQosPolicy &publishMode, uint8_t /*ident*/) +XMLP_ret XMLParser::getXMLReaderTimes(tinyxml2::XMLElement *elem, ReaderTimes ×, uint8_t ident) { - /* - - - - */ + /* + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(KIND))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, INIT_ACKNACK_DELAY) == 0) { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; + // initialAcknackDelay + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialAcknackDelay, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, HEARTB_RESP_DELAY) == 0) + { + // heartbeatResponseDelay + if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatResponseDelay, ident)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, SYNCHRONOUS) == 0) - publishMode.kind = PublishModeQosPolicyKind::SYNCHRONOUS_PUBLISH_MODE; - else if (strcmp(text, ASYNCHRONOUS) == 0) - publishMode.kind = PublishModeQosPolicyKind::ASYNCHRONOUS_PUBLISH_MODE; else { - logError(XMLPARSER, "Node '" << KIND << "' bad content"); + logError(XMLPARSER, "Invalid element found into 'readerTimesType'. Name: " << name); return XMLP_ret::XML_ERROR; } } - else - { - logError(XMLPARSER, "Node '" << elem->Value() << "' without content"); - return XMLP_ret::XML_ERROR; - } return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLDuration(tinyxml2::XMLElement *elem, Duration_t &duration, uint8_t ident) +XMLP_ret XMLParser::getXMLLocatorUDPv4(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident) { - /* - - - - - */ - - tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(BY_NAME))) + /* + + + + + + + */ + + locator.kind = LOCATOR_KIND_UDPv4; + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - - */ - const char* text = p_aux0->GetText(); - if (nullptr == text) + name = p_aux0->Name(); + if (strcmp(name, PORT) == 0) { - logError(XMLPARSER, "Node '" << BY_NAME << "' without content"); - return XMLP_ret::XML_ERROR; + // port - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + return XMLP_ret::XML_ERROR; } - if (strcmp(text, _INFINITE) == 0) duration = c_TimeInfinite; - else if (strcmp(text, ZERO) == 0) duration = c_TimeZero; - else if (strcmp(text, INVALID) == 0) duration = c_TimeInvalid; - else + else if (strcmp(name, ADDRESS) == 0) { - logError(XMLPARSER, "Node '" << BY_NAME << "' bad content"); - return XMLP_ret::XML_ERROR; + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setIPv4(locator, s); } - - // Both ways forbidden - if (nullptr != (p_aux0 = elem->FirstChildElement(BY_VAL))) + else { - logError(XMLPARSER, "Node '" << BY_NAME << "' with several definitions"); + logError(XMLPARSER, "Invalid element found into 'udpv4LocatorType'. Name: " << name); return XMLP_ret::XML_ERROR; } } + return XMLP_ret::XML_OK; +} - if (nullptr != (p_aux0 = elem->FirstChildElement(BY_VAL))) +XMLP_ret XMLParser::getXMLLocatorUDPv6(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident) +{ + /* + + + + + + + */ + + locator.kind = LOCATOR_KIND_UDPv6; + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - /* - - - - - */ - - // seconds - uint32Type - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(SECONDS))) + name = p_aux0->Name(); + if (strcmp(name, PORT) == 0) + { + // port - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, ADDRESS) == 0) { - if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &duration.seconds, ident)) return XMLP_ret::XML_ERROR; // TODO: getXMLUint + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setIPv6(locator, s); } - // fraction - uint32Type - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(FRACTION))) + else { - if (XMLP_ret::XML_OK != getXMLUint(p_aux1, &duration.fraction, ident)) return XMLP_ret::XML_ERROR; + logError(XMLPARSER, "Invalid element found into 'udpv6LocatorType'. Name: " << name); + return XMLP_ret::XML_ERROR; } } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLWriterTimes(tinyxml2::XMLElement *elem, WriterTimes ×, uint8_t ident) +XMLP_ret XMLParser::getXMLLocatorTCPv4(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident) { - /* - - - - - - - */ - + /* + + + + + + + + + + */ + + locator.kind = LOCATOR_KIND_TCPv4; tinyxml2::XMLElement *p_aux0 = nullptr; - // initialHeartbeatDelay - if (nullptr != (p_aux0 = elem->FirstChildElement(INIT_HEARTB_DELAY))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialHeartbeatDelay, ident)) return XMLP_ret::XML_ERROR; - } - // heartbeatPeriod - if (nullptr != (p_aux0 = elem->FirstChildElement(HEARTB_PERIOD))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatPeriod, ident)) return XMLP_ret::XML_ERROR; - } - // nackResponseDelay - if (nullptr != (p_aux0 = elem->FirstChildElement(NACK_RESP_DELAY))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackResponseDelay, ident)) return XMLP_ret::XML_ERROR; - } - // nackSupressionDuration - if (nullptr != (p_aux0 = elem->FirstChildElement(NACK_SUPRESSION))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.nackSupressionDuration, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, PORT) == 0) + { + // port - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PHYSICAL_PORT) == 0) + { + // port - uint32Type + uint16_t port(0); + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setPhysicalPort(locator, port); + } + else if (strcmp(name, ADDRESS) == 0) + { + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setIPv4(locator, s); + } + else if (strcmp(name, WAN_ADDRESS) == 0) + { + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setWan(locator, s); + } + else if (strcmp(name, UNIQUE_LAN_ID) == 0) + { + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setLanID(locator, s); + } + else + { + logError(XMLPARSER, "Invalid element found into 'tcpv4LocatorType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } -XMLP_ret XMLParser::getXMLReaderTimes(tinyxml2::XMLElement *elem, ReaderTimes ×, uint8_t ident) +XMLP_ret XMLParser::getXMLLocatorTCPv6(tinyxml2::XMLElement* elem, rtps::Locator_t& locator, uint8_t ident) { - /* - - - - - */ + /* + + + + + + + + */ + locator.kind = LOCATOR_KIND_TCPv6; tinyxml2::XMLElement *p_aux0 = nullptr; - // initialAcknackDelay - if (nullptr != (p_aux0 = elem->FirstChildElement(INIT_ACKNACK_DELAY))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.initialAcknackDelay, ident)) return XMLP_ret::XML_ERROR; - } - // heartbeatResponseDelay - if (nullptr != (p_aux0 = elem->FirstChildElement(HEARTB_RESP_DELAY))) - { - if (XMLP_ret::XML_OK != getXMLDuration(p_aux0, times.heartbeatResponseDelay, ident)) return XMLP_ret::XML_ERROR; + name = p_aux0->Name(); + if (strcmp(name, PORT) == 0) + { + // port - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PHYSICAL_PORT) == 0) + { + // port - uint32Type + uint16_t port(0); + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setPhysicalPort(locator, port); + } + else if (strcmp(name, ADDRESS) == 0) + { + // address - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident + 1)) + return XMLP_ret::XML_ERROR; + IPLocator::setIPv6(locator, s); + } + else + { + logError(XMLPARSER, "Invalid element found into 'tcpv6LocatorType'. Name: " << name); + return XMLP_ret::XML_ERROR; + } } - return XMLP_ret::XML_OK; } XMLP_ret XMLParser::getXMLLocatorList(tinyxml2::XMLElement *elem, LocatorList_t &locatorList, uint8_t ident) { - /* - - - - */ - - tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr, *p_aux2 = nullptr; - + /* + + + + + + */ + tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; p_aux0 = elem->FirstChildElement(LOCATOR); if (nullptr == p_aux0) { @@ -1322,162 +1856,41 @@ XMLP_ret XMLParser::getXMLLocatorList(tinyxml2::XMLElement *elem, LocatorList_t while (nullptr != p_aux0) { - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /* + + + + + + + + + */ Locator_t loc; - // kind - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(KIND))) - { - /* - - - - - - - - */ - const char* text = p_aux1->GetText(); - if (nullptr == text) - { - logError(XMLPARSER, "Node '" << KIND << "' without content"); - return XMLP_ret::XML_ERROR; - } - if (strcmp(text, RESERVED) == 0) - loc.kind = LOCATOR_KIND_RESERVED; - else if (strcmp(text, UDPv4) == 0) - loc.kind = LOCATOR_KIND_UDPv4; - else if (strcmp(text, UDPv6) == 0) - loc.kind = LOCATOR_KIND_UDPv6; - else if (strcmp(text, TCPv4) == 0) - loc.kind = LOCATOR_KIND_TCPv4; - else if (strcmp(text, TCPv6) == 0) - loc.kind = LOCATOR_KIND_TCPv6; - else - { - logError(XMLPARSER, "Node '" << KIND << "' bad content"); - return XMLP_ret::XML_ERROR; - } - } - - // port - uint32Type - bool bPortOption = false; - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(PORT))) + if (nullptr != (p_aux1 = p_aux0->FirstChildElement(UDPv4_LOCATOR))) { - if (XMLP_ret::XML_OK != getXMLUint(p_aux1, &loc.port, ident + 1)) + if (XMLP_ret::XML_OK != getXMLLocatorUDPv4(p_aux1, loc, ident + 1)) return XMLP_ret::XML_ERROR; - bPortOption = true; } - - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(PORTS))) + else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(UDPv6_LOCATOR))) { - if (bPortOption) - { - logError(XMLPARSER, "Incompatible ports configuration ( 'port' <-> 'ports (physical_port & logical port)'."); + if (XMLP_ret::XML_OK != getXMLLocatorUDPv6(p_aux1, loc, ident + 1)) return XMLP_ret::XML_ERROR; - } - - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(LOGICAL_PORT))) - { - uint16_t aux; - if (XMLP_ret::XML_OK != getXMLUint(p_aux2, &aux, ident + 1)) - return XMLP_ret::XML_ERROR; - IPLocator::setLogicalPort(loc, aux); - } - - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(PHYSICAL_PORT))) - { - uint16_t aux; - if (XMLP_ret::XML_OK != getXMLUint(p_aux2, &aux, ident + 1)) - return XMLP_ret::XML_ERROR; - IPLocator::setPhysicalPort(loc, aux); - } } - - /// address - stringType - bool bAddressOption = false; - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(ADDRESS))) + else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(TCPv4_LOCATOR))) { - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux1, &s, ident + 1)) + if (XMLP_ret::XML_OK != getXMLLocatorTCPv4(p_aux1, loc, ident + 1)) return XMLP_ret::XML_ERROR; - IPLocator::setIPv4(loc, s); - bAddressOption = true; } - - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(IPV6_ADDRESS))) + else if (nullptr != (p_aux1 = p_aux0->FirstChildElement(TCPv6_LOCATOR))) { - if (bAddressOption) - { - logError(XMLPARSER, "Incompatible address configuration ( 'address' <-> 'ipv6_address' <-> 'addresses_ (unique_lan_id & wan_address & ip_address)'."); - return XMLP_ret::XML_ERROR; - } - - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux1, &s, ident + 1)) + if (XMLP_ret::XML_OK != getXMLLocatorTCPv6(p_aux1, loc, ident + 1)) return XMLP_ret::XML_ERROR; - IPLocator::setIPv6(loc, s); - bAddressOption = true; } - - if (nullptr != (p_aux1 = p_aux0->FirstChildElement(ADDRESSES))) + else if (nullptr != (p_aux1 = p_aux0->FirstChildElement())) { - if (bAddressOption) - { - logError(XMLPARSER, "Incompatible address configuration ( 'address' <-> 'ipv6_address' <-> 'addresses_ (unique_lan_id & wan_address & ip_address)'."); - return XMLP_ret::XML_ERROR; - } - - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(UNIQUE_LAN_ID))) - { - std::string sUniqueLanId; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &sUniqueLanId, ident + 1)) - return XMLP_ret::XML_ERROR; - IPLocator::setLanID(loc, sUniqueLanId); - } - - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(WAN_ADDRESS))) - { - std::string sWanAddr; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &sWanAddr, ident + 1)) - return XMLP_ret::XML_ERROR; - IPLocator::setWan(loc, sWanAddr); - } - - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(IP_ADDRESS))) - { - std::string sIPddr; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &sIPddr, ident + 1)) - return XMLP_ret::XML_ERROR; - IPLocator::setIPv4(loc, sIPddr); - } + logError(XMLPARSER, "Invalid element found into 'locatorType'. Name: " << p_aux1->Name()); + return XMLP_ret::XML_ERROR; } locatorList.push_back(loc); @@ -1488,27 +1901,28 @@ XMLP_ret XMLParser::getXMLLocatorList(tinyxml2::XMLElement *elem, LocatorList_t } XMLP_ret XMLParser::getXMLHistoryMemoryPolicy(tinyxml2::XMLElement *elem, - MemoryManagementPolicy_t &historyMemoryPolicy, - uint8_t /*ident*/) + MemoryManagementPolicy_t &historyMemoryPolicy, uint8_t /*ident*/) { - /* - - - - - - */ + /* + + + + + + + + */ const char* text = elem->GetText(); if (nullptr == text) { logError(XMLPARSER, "Node '" << KIND << "' without content"); return XMLP_ret::XML_ERROR; } - if (strcmp(text, PREALLOCATED) == 0) + if (strcmp(text, PREALLOCATED) == 0) historyMemoryPolicy = MemoryManagementPolicy::PREALLOCATED_MEMORY_MODE; else if (strcmp(text, PREALLOCATED_WITH_REALLOC) == 0) historyMemoryPolicy = MemoryManagementPolicy::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; - else if (strcmp(text, DYNAMIC) == 0) + else if (strcmp(text, DYNAMIC) == 0) historyMemoryPolicy = MemoryManagementPolicy::DYNAMIC_RESERVE_MEMORY_MODE; else { @@ -1521,105 +1935,130 @@ XMLP_ret XMLParser::getXMLHistoryMemoryPolicy(tinyxml2::XMLElement *elem, XMLP_ret XMLParser::getXMLPropertiesPolicy(tinyxml2::XMLElement *elem, PropertyPolicy &propertiesPolicy, uint8_t ident) { - /* - - - - - */ + /* + + + + + + + */ tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr, *p_aux2 = nullptr; - - if (nullptr != (p_aux0 = elem->FirstChildElement(PROPERTIES))) + const char* name = nullptr; + for (p_aux0 = elem->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) { - p_aux1 = p_aux0->FirstChildElement(PROPERTY); - if (nullptr == p_aux1) - { - logError(XMLPARSER, "Node '" << PROPERTIES << "' without content"); - return XMLP_ret::XML_ERROR; - } - - while (nullptr != p_aux1) + name = p_aux0->Name(); + if (strcmp(name, PROPERTIES) == 0) { - /* - - - - - - */ - Property prop; - // name - stringType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(NAME))) + p_aux1 = p_aux0->FirstChildElement(PROPERTY); + if (nullptr == p_aux1) { - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return XMLP_ret::XML_ERROR; - prop.name(s); - } - // value - stringType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(VALUE))) - { - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return XMLP_ret::XML_ERROR; - prop.value(s); + logError(XMLPARSER, "Node '" << PROPERTIES << "' without content"); + return XMLP_ret::XML_ERROR; } - // propagate - boolType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(PROPAGATE))) + + while (nullptr != p_aux1) { - bool b = false; - if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) return XMLP_ret::XML_ERROR; - prop.propagate(b); + /* + + + + + + + + */ + + const char* sub_name = nullptr; + Property prop; + for (p_aux2 = p_aux1->FirstChildElement(); p_aux2 != NULL; p_aux2 = p_aux2->NextSiblingElement()) + { + sub_name = p_aux2->Name(); + if (strcmp(sub_name, NAME) == 0) + { + // name - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) + return XMLP_ret::XML_ERROR; + prop.name(s); + } + else if (strcmp(sub_name, VALUE) == 0) + { + // value - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) + return XMLP_ret::XML_ERROR; + prop.value(s); + } + else if (strcmp(sub_name, PROPAGATE) == 0) + { + // propagate - boolType + bool b = false; + if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) + return XMLP_ret::XML_ERROR; + prop.propagate(b); + } + } + propertiesPolicy.properties().push_back(prop); + p_aux1 = p_aux1->NextSiblingElement(PROPERTY); } - propertiesPolicy.properties().push_back(prop); - p_aux1 = p_aux1->NextSiblingElement(PROPERTY); - } - } - - // TODO: The value will be std::vector - if (nullptr != (p_aux0 = elem->FirstChildElement(BIN_PROPERTIES))) - { - p_aux1 = p_aux0->FirstChildElement(PROPERTY); - if (nullptr == p_aux1) - { - logError(XMLPARSER, "Node '" << BIN_PROPERTIES << "' without content"); - return XMLP_ret::XML_ERROR; } - - while (nullptr != p_aux1) + else if (strcmp(name, BIN_PROPERTIES) == 0) { - /* - - - - - - */ - BinaryProperty bin_prop; - // name - stringType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(NAME))) + // TODO: The value will be std::vector + p_aux1 = p_aux0->FirstChildElement(PROPERTY); + if (nullptr == p_aux1) { - std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return XMLP_ret::XML_ERROR; - bin_prop.name(s); - } - // TODO: - // value - stringType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(VALUE))) - { - logError(XMLPARSER, "Tag '" << p_aux2->Value() << "' do not supported for now"); - /*std::string s = ""; - if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return XMLP_ret::XML_ERROR; - bin_prop.value(s);*/ + logError(XMLPARSER, "Node '" << BIN_PROPERTIES << "' without content"); + return XMLP_ret::XML_ERROR; } - // propagate - boolType - if (nullptr != (p_aux2 = p_aux1->FirstChildElement(PROPAGATE))) + + while (nullptr != p_aux1) { - bool b = false; - if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) return XMLP_ret::XML_ERROR; - bin_prop.propagate(b); + /* + + + + + + + + */ + const char* sub_name = nullptr; + BinaryProperty bin_prop; + for (p_aux2 = p_aux1->FirstChildElement(); p_aux2 != NULL; p_aux2 = p_aux2->NextSiblingElement()) + { + sub_name = p_aux2->Name(); + if (strcmp(sub_name, NAME) == 0) + { + // name - stringType + std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) + return XMLP_ret::XML_ERROR; + bin_prop.name(s); + } + else if (strcmp(sub_name, VALUE) == 0) + { + // TODO: + // value - stringType + logError(XMLPARSER, "Tag '" << p_aux2->Value() << "' do not supported for now"); + /*std::string s = ""; + if (XMLP_ret::XML_OK != getXMLString(p_aux2, &s, ident + 2)) return XMLP_ret::XML_ERROR; + bin_prop.value(s);*/ + } + else if (strcmp(sub_name, PROPAGATE) == 0) + { + // propagate - boolType + bool b = false; + if (XMLP_ret::XML_OK != getXMLBool(p_aux2, &b, ident + 2)) + return XMLP_ret::XML_ERROR; + bin_prop.propagate(b); + } + } + propertiesPolicy.binary_properties().push_back(bin_prop); + p_aux1 = p_aux1->NextSiblingElement(PROPERTY); } - propertiesPolicy.binary_properties().push_back(bin_prop); - p_aux1 = p_aux1->NextSiblingElement(PROPERTY); } } return XMLP_ret::XML_OK; diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 8341bdfa41f..8c233298823 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -71,28 +71,28 @@ XMLP_ret XMLParser::parseXML(tinyxml2::XMLDocument& xmlDoc, up_base_node_t& root } else { - root.reset(new BaseNode{NodeType::TYPES}); - ret = parseDynamicTypes(p_root); + root.reset(new BaseNode{ NodeType::TYPES }); + ret = parseDynamicTypes(p_root); } } else { - root.reset(new BaseNode{NodeType::PROFILES}); - ret = parseProfiles(p_root, *root); + root.reset(new BaseNode{ NodeType::PROFILES }); + ret = parseProfiles(p_root, *root); } } else { - root.reset(new BaseNode{NodeType::ROOT}); + root.reset(new BaseNode{ NodeType::ROOT }); tinyxml2::XMLElement* node = p_root->FirstChildElement(); - const char* tag = nullptr; + const char* tag = nullptr; while (nullptr != node) { if (nullptr != (tag = node->Value())) { if (strcmp(tag, PROFILES) == 0) { - up_base_node_t profiles_node = up_base_node_t{new BaseNode{NodeType::PROFILES}}; + up_base_node_t profiles_node = up_base_node_t{ new BaseNode{NodeType::PROFILES} }; if (XMLP_ret::XML_OK == (ret = parseProfiles(node, *profiles_node))) { root->addChild(std::move(profiles_node)); @@ -163,6 +163,14 @@ XMLP_ret XMLParser::parseRoot(tinyxml2::XMLElement* p_root, BaseNode& rootNode) XMLP_ret XMLParser::parseXMLTransportsProf(tinyxml2::XMLElement* p_root) { + /* + + + + + + */ + XMLP_ret ret = XMLP_ret::XML_OK; tinyxml2::XMLElement* p_element = p_root->FirstChildElement(TRANSPORT_DESCRIPTOR); while(p_element != nullptr) @@ -180,41 +188,45 @@ XMLP_ret XMLParser::parseXMLTransportsProf(tinyxml2::XMLElement* p_root) XMLP_ret XMLParser::parseXMLTypes(tinyxml2::XMLElement* p_root) { /* - - - - - + + + + + */ XMLP_ret ret = XMLP_ret::XML_OK; - tinyxml2::XMLElement *p_aux0 = nullptr; + tinyxml2::XMLElement *p_aux0 = nullptr, *p_aux1 = nullptr; p_aux0 = p_root->FirstChildElement(TYPES); - if (p_aux0 != nullptr) { - tinyxml2::XMLElement* p_element = p_aux0->FirstChildElement(TYPE); - while(p_element != nullptr) + const char* name = nullptr; + for (p_aux1 = p_aux0->FirstChildElement(); p_aux1 != nullptr; p_aux1 = p_aux1->NextSiblingElement()) { - ret = parseXMLDynamicType(p_element); - if (ret != XMLP_ret::XML_OK) + name = p_aux1->Name(); + if (strcmp(name, TYPE) == 0) { - return ret; + if (XMLP_ret::XML_OK != parseXMLDynamicType(p_aux1)) + return XMLP_ret::XML_ERROR; + } + else + { + logError(XMLPARSER, "Invalid element found into 'types'. Name: " << name); + return XMLP_ret::XML_ERROR; } - p_element = p_element->NextSiblingElement(TYPE); } } else // Directly root is TYPES? { - tinyxml2::XMLElement* p_element = p_root->FirstChildElement(TYPE); - while(p_element != nullptr) + const char* name = nullptr; + for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) { - ret = parseXMLDynamicType(p_element); - if (ret != XMLP_ret::XML_OK) + name = p_aux0->Name(); + if (strcmp(name, TYPE) == 0) { - return ret; + if (XMLP_ret::XML_OK != parseXMLDynamicType(p_aux0)) + return XMLP_ret::XML_ERROR; } - p_element = p_element->NextSiblingElement(TYPE); } } return ret; @@ -222,33 +234,29 @@ XMLP_ret XMLParser::parseXMLTypes(tinyxml2::XMLElement* p_root) XMLP_ret XMLParser::parseXMLTransportData(tinyxml2::XMLElement* p_root) { - /* - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /* + + + + + + + + + + + + + + + + + + + + + + */ XMLP_ret ret = XMLP_ret::XML_OK; std::string sId = ""; @@ -336,6 +344,10 @@ XMLP_ret XMLParser::parseXMLTransportData(tinyxml2::XMLElement* p_root) return ret; } } + else + { + logError(XMLPARSER, "Invalid transport type: '" << sType << "'"); + } ret = parseXMLCommonTransportData(p_root, pDescriptor); if (ret != XMLP_ret::XML_OK) @@ -350,166 +362,202 @@ XMLP_ret XMLParser::parseXMLTransportData(tinyxml2::XMLElement* p_root) XMLP_ret XMLParser::parseXMLCommonTransportData(tinyxml2::XMLElement* p_root, sp_transport_t p_transport) { - /* - - - - - - - - - - - - */ - - tinyxml2::XMLElement* p_aux = nullptr; + /* + + + + + + + + + + + + + + + + + + + + + + */ std::shared_ptr pDesc = std::dynamic_pointer_cast(p_transport); - // sendBufferSize - int32Type - if (nullptr != (p_aux = p_root->FirstChildElement(SEND_BUFFER_SIZE))) - { - int iSize = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &iSize, 0) || iSize < 0) - return XMLP_ret::XML_ERROR; - pDesc->sendBufferSize = iSize; - } - - // receiveBufferSize - int32Type - if (nullptr != (p_aux = p_root->FirstChildElement(RECEIVE_BUFFER_SIZE))) - { - int iSize = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &iSize, 0) || iSize < 0) - return XMLP_ret::XML_ERROR; - pDesc->receiveBufferSize = iSize; - } - - // TTL - int8Type - if (nullptr != (p_aux = p_root->FirstChildElement(TTL))) - { - int iTTL = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &iTTL, 0) || iTTL < 0 || iTTL > 255) - return XMLP_ret::XML_ERROR; - pDesc->TTL = static_cast(iTTL); - } - - // maxMessageSize - uint32Type - if (nullptr != (p_aux = p_root->FirstChildElement(MAX_MESSAGE_SIZE))) - { - uint32_t uSize = 0; - if (XMLP_ret::XML_OK != getXMLUint(p_aux, &uSize, 0)) - return XMLP_ret::XML_ERROR; - pDesc->maxMessageSize = uSize; - } - - // maxInitialPeersRange - uint32Type - if (nullptr != (p_aux = p_root->FirstChildElement(MAX_INITIAL_PEERS_RANGE))) - { - uint32_t uRange = 0; - if (XMLP_ret::XML_OK != getXMLUint(p_aux, &uRange, 0)) - return XMLP_ret::XML_ERROR; - pDesc->maxInitialPeersRange = uRange; - } - - // InterfaceWhiteList stringListType - if (nullptr != (p_aux = p_root->FirstChildElement(WHITE_LIST))) + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = p_root->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - tinyxml2::XMLElement* p_aux1 = p_aux->FirstChildElement(ADDRESS); - while (nullptr != p_aux1) + name = p_aux0->Name(); + if (strcmp(name, SEND_BUFFER_SIZE) == 0) { - const char* text = p_aux1->GetText(); - if (nullptr != text) - { - pDesc->interfaceWhiteList.emplace_back(text); - } - p_aux1 = p_aux1->NextSiblingElement(ADDRESS); + // sendBufferSize - int32Type + int iSize = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iSize, 0) || iSize < 0) + return XMLP_ret::XML_ERROR; + pDesc->sendBufferSize = iSize; } - } - return XMLP_ret::XML_OK; -} - -XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, sp_transport_t p_transport) -{ - /* - - - - - - - - - - - - - */ - - XMLP_ret ret = XMLP_ret::XML_OK; - std::shared_ptr pTCPDesc = std::dynamic_pointer_cast(p_transport); - if (pTCPDesc != nullptr) - { - tinyxml2::XMLElement *p_aux0 = nullptr; - - // keep_alive_frequency_ms - uint32Type - if (nullptr != (p_aux0 = p_root->FirstChildElement(KEEP_ALIVE_FREQUENCY))) + else if (strcmp(name, RECEIVE_BUFFER_SIZE) == 0) { - int iFrequency(0); - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iFrequency, 0)) + // receiveBufferSize - int32Type + int iSize = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iSize, 0) || iSize < 0) return XMLP_ret::XML_ERROR; - pTCPDesc->keep_alive_frequency_ms = static_cast(iFrequency); + pDesc->receiveBufferSize = iSize; } - - // keep_alive_timeout_ms - uint32Type - if (nullptr != (p_aux0 = p_root->FirstChildElement(KEEP_ALIVE_TIMEOUT))) + else if (strcmp(name, TTL) == 0) { - int iTimeout(0); - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTimeout, 0)) + // TTL - int8Type + int iTTL = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTTL, 0) || iTTL < 0 || iTTL > 255) return XMLP_ret::XML_ERROR; - pTCPDesc->keep_alive_timeout_ms = static_cast(iTimeout); + pDesc->TTL = static_cast(iTTL); } - - // max_logical_port - uint16Type - if (nullptr != (p_aux0 = p_root->FirstChildElement(MAX_LOGICAL_PORT))) + else if (strcmp(name, MAX_MESSAGE_SIZE) == 0) { - int iPort(0); - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) + // maxMessageSize - uint32Type + uint32_t uSize = 0; + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uSize, 0)) return XMLP_ret::XML_ERROR; - pTCPDesc->max_logical_port = static_cast(iPort); + pDesc->maxMessageSize = uSize; } - - // logical_port_range - uint16Type - if (nullptr != (p_aux0 = p_root->FirstChildElement(LOGICAL_PORT_RANGE))) + else if (strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0) { - int iPort(0); - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) + // maxInitialPeersRange - uint32Type + uint32_t uRange = 0; + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &uRange, 0)) return XMLP_ret::XML_ERROR; - pTCPDesc->logical_port_range = static_cast(iPort); + pDesc->maxInitialPeersRange = uRange; } - - // logical_port_increment - uint16Type - if (nullptr != (p_aux0 = p_root->FirstChildElement(LOGICAL_PORT_INCREMENT))) + else if (strcmp(name, WHITE_LIST) == 0) { - int iPort(0); - if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) - return XMLP_ret::XML_ERROR; - pTCPDesc->logical_port_increment = static_cast(iPort); + // InterfaceWhiteList stringListType + tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(ADDRESS); + while (nullptr != p_aux1) + { + const char* text = p_aux1->GetText(); + if (nullptr != text) + { + pDesc->interfaceWhiteList.emplace_back(text); + } + p_aux1 = p_aux1->NextSiblingElement(ADDRESS); + } + } + else if (strcmp(name, TCP_WAN_ADDR) == 0 || strcmp(name, UDP_OUTPUT_PORT) == 0 || + strcmp(name, TRANSPORT_ID) == 0 || strcmp(name, TYPE) == 0 || + strcmp(name, KEEP_ALIVE_FREQUENCY) == 0 || strcmp(name, KEEP_ALIVE_TIMEOUT) == 0 || + strcmp(name, MAX_LOGICAL_PORT) == 0 || strcmp(name, LOGICAL_PORT_RANGE) == 0 || + strcmp(name, LOGICAL_PORT_INCREMENT) == 0 || strcmp(name, LISTENING_PORTS) == 0) + { + // Parsed outside of this method + } + else + { + logError(XMLPARSER, "Invalid element found into 'rtpsTransportDescriptorType'. Name: " << name); + return XMLP_ret::XML_ERROR; } + } + return XMLP_ret::XML_OK; +} + +XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, sp_transport_t p_transport) +{ + /* + + + + + + + + + + + + + + + */ - // ListeningPorts uint16ListType - if (nullptr != (p_aux0 = p_root->FirstChildElement(LISTENING_PORTS))) + XMLP_ret ret = XMLP_ret::XML_OK; + std::shared_ptr pTCPDesc = std::dynamic_pointer_cast(p_transport); + if (pTCPDesc != nullptr) + { + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = p_root->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(PORT); - while (nullptr != p_aux1) + name = p_aux0->Name(); + if (strcmp(name, KEEP_ALIVE_FREQUENCY) == 0) + { + // keep_alive_frequency_ms - uint32Type + int iFrequency(0); + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iFrequency, 0)) + return XMLP_ret::XML_ERROR; + pTCPDesc->keep_alive_frequency_ms = static_cast(iFrequency); + } + else if (strcmp(name, KEEP_ALIVE_TIMEOUT) == 0) + { + // keep_alive_timeout_ms - uint32Type + int iTimeout(0); + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iTimeout, 0)) + return XMLP_ret::XML_ERROR; + pTCPDesc->keep_alive_timeout_ms = static_cast(iTimeout); + } + else if (strcmp(name, MAX_LOGICAL_PORT) == 0) + { + // max_logical_port - uint16Type + int iPort(0); + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) + return XMLP_ret::XML_ERROR; + pTCPDesc->max_logical_port = static_cast(iPort); + } + else if (strcmp(name, LOGICAL_PORT_RANGE) == 0) + { + // logical_port_range - uint16Type + int iPort(0); + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) + return XMLP_ret::XML_ERROR; + pTCPDesc->logical_port_range = static_cast(iPort); + } + else if (strcmp(name, LOGICAL_PORT_INCREMENT) == 0) { - int iPort = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &iPort, 0) || iPort < 0 || iPort > 65535) + // logical_port_increment - uint16Type + int iPort(0); + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &iPort, 0) || iPort < 0 || iPort > 65535) return XMLP_ret::XML_ERROR; - pTCPDesc->add_listener_port(static_cast(iPort)); + pTCPDesc->logical_port_increment = static_cast(iPort); + } + else if (strcmp(name, LISTENING_PORTS) == 0) + { + // ListeningPorts uint16ListType + tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(PORT); + while (nullptr != p_aux1) + { + int iPort = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux1, &iPort, 0) || iPort < 0 || iPort > 65535) + return XMLP_ret::XML_ERROR; - p_aux1 = p_aux1->NextSiblingElement(PORT); + pTCPDesc->add_listener_port(static_cast(iPort)); + p_aux1 = p_aux1->NextSiblingElement(PORT); + } + } + else if (strcmp(name, TCP_WAN_ADDR) == 0 || strcmp(name, TRANSPORT_ID) == 0 || + strcmp(name, TYPE) == 0 || strcmp(name, SEND_BUFFER_SIZE) == 0 || + strcmp(name, RECEIVE_BUFFER_SIZE) == 0 || strcmp(name, TTL) == 0 || + strcmp(name, MAX_MESSAGE_SIZE) == 0 || strcmp(name, MAX_INITIAL_PEERS_RANGE) == 0 || + strcmp(name, WHITE_LIST) == 0) + { + // Parsed Outside of this method + } + else + { + logError(XMLPARSER, "Invalid element found into 'rtpsTransportDescriptorType'. Name: " << name); + return XMLP_ret::XML_ERROR; } } } @@ -525,38 +573,37 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, XMLP_ret XMLParser::parseXMLDynamicType(tinyxml2::XMLElement* p_root) { /* - - - - - - - - - + + + + + + + + + + */ XMLP_ret ret = XMLP_ret::XML_OK; - tinyxml2::XMLElement *p_element = nullptr; - - for (p_element = p_root->FirstChildElement(); - p_element != nullptr; p_element = p_element->NextSiblingElement()) + tinyxml2::XMLElement *p_aux0 = nullptr; + for (p_aux0 = p_root->FirstChildElement(); p_aux0 != nullptr; p_aux0 = p_aux0->NextSiblingElement()) { - const std::string type = p_element->Value(); + const std::string type = p_aux0->Value(); if (type.compare(STRUCT) == 0) { - ret = parseXMLStructDynamicType(p_element); + ret = parseXMLStructDynamicType(p_aux0); } else if (type.compare(UNION) == 0) { - ret = parseXMLUnionDynamicType(p_element); + ret = parseXMLUnionDynamicType(p_aux0); } else if (type.compare(ENUM) == 0) { - ret = parseXMLEnumDynamicType(p_element); + ret = parseXMLEnumDynamicType(p_aux0); } else if (type.compare(TYPEDEF) == 0) { - ret = parseXMLAliasDynamicType(p_element); + ret = parseXMLAliasDynamicType(p_aux0); } else { @@ -572,7 +619,9 @@ XMLP_ret XMLParser::parseXMLDynamicType(tinyxml2::XMLElement* p_root) return ret; } -static p_dynamictypebuilder_t getDiscriminatorTypeBuilder(const std::string &disc) +static p_dynamictypebuilder_t getDiscriminatorTypeBuilder(const std::string &disc, uint32_t bound = 0); + +static p_dynamictypebuilder_t getDiscriminatorTypeBuilder(const std::string &disc, uint32_t bound) { /* mKind == TK_BOOLEAN || mKind == TK_BYTE || mKind == TK_INT16 || mKind == TK_INT32 || @@ -585,7 +634,7 @@ static p_dynamictypebuilder_t getDiscriminatorTypeBuilder(const std::string &dis { return factory->CreateBoolBuilder(); } - else if (disc.compare(OCTET) == 0) + else if (disc.compare(TBYTE) == 0) { return factory->CreateByteBuilder(); } @@ -633,72 +682,115 @@ static p_dynamictypebuilder_t getDiscriminatorTypeBuilder(const std::string &dis { return factory->CreateChar16Builder(); } + else if (disc.compare(STRING) == 0) + { + return factory->CreateStringBuilder(bound); + } + else if (disc.compare(WSTRING) == 0) + { + return factory->CreateWstringBuilder(bound); + } + return XMLProfileManager::getDynamicTypeByName(disc); } XMLP_ret XMLParser::parseXMLAliasDynamicType(tinyxml2::XMLElement* p_root) { /* - - || - - - + + + */ XMLP_ret ret = XMLP_ret::XML_OK; - const char* name = p_root->Attribute(NAME); - const char* value = p_root->Attribute(VALUE); - p_dynamictypebuilder_t valueBuilder; - - if (value == nullptr) - { - valueBuilder = parseXMLMemberDynamicType(p_root->FirstChildElement(), nullptr, MEMBER_ID_INVALID); - } - else + const char* type = p_root->Attribute(TYPE); + if (type != nullptr) { - valueBuilder = getDiscriminatorTypeBuilder(value); - } + if (strcmp(type, NON_BASIC_TYPE) == 0) + { + const char* typeNonBasicName = p_root->Attribute(NON_BASIC_TYPE_NAME); + if (typeNonBasicName != nullptr) + { + type = typeNonBasicName; + } + else + { + logError(XMLPARSER, "Error parsing member type: Not found."); + ret = XMLP_ret::XML_ERROR; + } + } - if (valueBuilder == nullptr) - { - logError(XMLPARSER, "Error parsing alias type: Value not recognized."); - ret = XMLP_ret::XML_ERROR; + p_dynamictypebuilder_t valueBuilder; + if ((p_root->Attribute(ARRAY_DIMENSIONS) != nullptr) || + (p_root->Attribute(SEQ_MAXLENGTH) != nullptr) || + (p_root->Attribute(MAP_MAXLENGTH) != nullptr)) + { + valueBuilder = parseXMLMemberDynamicType(p_root , nullptr, MEMBER_ID_INVALID); + } + else + { + uint32_t bound = 0; + const char* boundStr = p_root->Attribute(STR_MAXLENGTH); + if (boundStr != nullptr) + { + bound = std::atoi(boundStr); + } + valueBuilder = getDiscriminatorTypeBuilder(type, bound); + } + + if (valueBuilder != nullptr) + { + const char* name = p_root->Attribute(NAME); + p_dynamictypebuilder_t typeBuilder = + types::DynamicTypeBuilderFactory::GetInstance()->CreateAliasBuilder(valueBuilder, name); + XMLProfileManager::insertDynamicTypeByName(name, typeBuilder); + } + else + { + logError(XMLPARSER, "Error parsing alias type: Value not recognized."); + ret = XMLP_ret::XML_ERROR; + } } else { - p_dynamictypebuilder_t typeBuilder = - types::DynamicTypeBuilderFactory::GetInstance()->CreateAliasBuilder(valueBuilder, name); - XMLProfileManager::insertDynamicTypeByName(name, typeBuilder); + logError(XMLPARSER, "Error parsing alias type: Type not defined."); + ret = XMLP_ret::XML_ERROR; } - return ret; } XMLP_ret XMLParser::parseXMLEnumDynamicType(tinyxml2::XMLElement* p_root) { /* - - - - - + + + + + + + + + + + + + //TODO: Enum bitbound to set the internal field */ XMLP_ret ret = XMLP_ret::XML_OK; const char* enumName = p_root->Attribute(NAME); p_dynamictypebuilder_t typeBuilder = types::DynamicTypeBuilderFactory::GetInstance()->CreateEnumBuilder(); - uint32_t currValue = 0; - for (tinyxml2::XMLElement* literal = p_root->FirstChildElement(LITERAL); - literal != nullptr; literal = literal->NextSiblingElement(LITERAL)) + for (tinyxml2::XMLElement* literal = p_root->FirstChildElement(ENUMERATOR); + literal != nullptr; literal = literal->NextSiblingElement(ENUMERATOR)) { const char* name = literal->Attribute(NAME); - const char* value = literal->Attribute(VALUE); if (name == nullptr) { logError(XMLPARSER, "Error parsing enum type: Literals must have name."); return XMLP_ret::XML_ERROR; } + + const char* value = literal->Attribute(VALUE); if (value != nullptr) { currValue = std::atoi(value); @@ -713,26 +805,36 @@ XMLP_ret XMLParser::parseXMLEnumDynamicType(tinyxml2::XMLElement* p_root) XMLP_ret XMLParser::parseXMLStructDynamicType(tinyxml2::XMLElement* p_root) { /* - - - - - - - - + + + + + + + + */ XMLP_ret ret = XMLP_ret::XML_OK; const char* name = p_root->Attribute(NAME); p_dynamictypebuilder_t typeBuilder = types::DynamicTypeBuilderFactory::GetInstance()->CreateStructBuilder(); typeBuilder->SetName(name); uint32_t mId = 0; + const char* element_name = nullptr; for (tinyxml2::XMLElement *p_element = p_root->FirstChildElement(); p_element != nullptr; p_element = p_element->NextSiblingElement()) { - p_dynamictypebuilder_t mType = parseXMLMemberDynamicType(p_element, typeBuilder, mId++); - if (mType == nullptr) + element_name = p_element->Name(); + if (strcmp(element_name, MEMBER) == 0) + { + p_dynamictypebuilder_t mType = parseXMLMemberDynamicType(p_element, typeBuilder, mId++); + if (mType == nullptr) + { + return XMLP_ret::XML_ERROR; + } + } + else { + logError(XMLPARSER, "Invalid element found into 'structDcl'. Name: " << element_name); return XMLP_ret::XML_ERROR; } } @@ -745,28 +847,28 @@ XMLP_ret XMLParser::parseXMLStructDynamicType(tinyxml2::XMLElement* p_root) XMLP_ret XMLParser::parseXMLUnionDynamicType(tinyxml2::XMLElement* p_root) { /* - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + */ + XMLP_ret ret = XMLP_ret::XML_OK; const char* name = p_root->Attribute(NAME); - tinyxml2::XMLElement *p_element = p_root->FirstChildElement(DISCRIMINATOR); if (p_element != nullptr) { @@ -788,10 +890,9 @@ XMLP_ret XMLParser::parseXMLUnionDynamicType(tinyxml2::XMLElement* p_root) p_element != nullptr; p_element = p_element->NextSiblingElement(CASE)) { std::string valuesStr = ""; - for (tinyxml2::XMLElement *caseValue = p_element->FirstChildElement(CASEVALUE); - caseValue != nullptr; caseValue = caseValue->NextSiblingElement(CASEVALUE)) + for (tinyxml2::XMLElement *caseValue = p_element->FirstChildElement(CASE_DISCRIMINATOR); + caseValue != nullptr; caseValue = caseValue->NextSiblingElement(CASE_DISCRIMINATOR)) { - //ret = parseXMLMemberDynamicType(p_element, typeBuilder); const char* values = caseValue->Attribute(VALUE); if (values == nullptr) { @@ -810,14 +911,14 @@ XMLP_ret XMLParser::parseXMLUnionDynamicType(tinyxml2::XMLElement* p_root) } tinyxml2::XMLElement *caseElement = p_element->FirstChildElement(); - while (caseElement != nullptr && strncmp(caseElement->Value(), CASEVALUE, 10) == 0) + while (caseElement != nullptr && strncmp(caseElement->Value(), CASE_DISCRIMINATOR, 10) == 0) { caseElement = caseElement->NextSiblingElement(); } if (caseElement != nullptr) { - p_dynamictypebuilder_t mType = parseXMLMemberDynamicType( - caseElement, typeBuilder, mId++, valuesStr); + p_dynamictypebuilder_t mType = parseXMLMemberDynamicType + (caseElement, typeBuilder, mId++, valuesStr); if (mType == nullptr) { return XMLP_ret::XML_ERROR; @@ -830,7 +931,7 @@ XMLP_ret XMLParser::parseXMLUnionDynamicType(tinyxml2::XMLElement* p_root) } } - XMLProfileManager::insertDynamicTypeByName(name, std::move(typeBuilder)); + XMLProfileManager::insertDynamicTypeByName(name, typeBuilder); } } else @@ -862,14 +963,12 @@ static bool dimensionsToLabels(const std::string& labelStr, std::vector + + + + + + + + + + + */ if (p_root == nullptr) { logError(XMLPARSER, "Error parsing member: Node not found."); return nullptr; } - const char* memberType = p_root->Value(); + const char* memberType = p_root->Attribute(TYPE); const char* memberName = p_root->Attribute(NAME); - const char* memberArray = p_root->Attribute(DIMENSIONS); - const char* memberKey = p_root->Attribute(KEY); bool isArray = false; if (memberName == nullptr && p_dynamictype != nullptr) @@ -902,407 +1012,384 @@ p_dynamictypebuilder_t XMLParser::parseXMLMemberDynamicType(tinyxml2::XMLElement return nullptr; } + if (memberType == nullptr) + { + logError(XMLPARSER, "Error parsing member type: Not found."); + return nullptr; + } + + const char* memberArray = p_root->Attribute(ARRAY_DIMENSIONS); if (memberArray != nullptr) { isArray = true; } - types::DynamicTypeBuilder* memberBuilder = nullptr; - types::DynamicTypeBuilderFactory* factory = types::DynamicTypeBuilderFactory::GetInstance(); - - if (strncmp(memberType, BOOLEAN, 8) == 0) + if (strcmp(memberType, NON_BASIC_TYPE) == 0) { - if (!isArray) + const char* memberNonBasicTypeName = p_root->Attribute(NON_BASIC_TYPE_NAME); + if (memberNonBasicTypeName != nullptr) { - memberBuilder = factory->CreateBoolBuilder(); + memberType = memberNonBasicTypeName; } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateBoolBuilder(); - std::vector bounds; - dimensionsToArrayBounds(memberArray, bounds); - memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); - //factory->DeleteBuilder(innerBuilder); + logError(XMLPARSER, "Error parsing member type: Not found."); + return nullptr; } } - else if (strncmp(memberType, CHAR, 5) == 0) + + types::DynamicTypeBuilder* memberBuilder = nullptr; + types::DynamicTypeBuilderFactory* factory = types::DynamicTypeBuilderFactory::GetInstance(); + + const char* memberSequence = p_root->Attribute(SEQ_MAXLENGTH); + if (memberSequence != nullptr) { - if (!isArray) + /* + In sequences allowed formats are (complex format includes the basic): + sequence,2> + + + + In this example, inner sequence's name is ignored and can be omited. + */ + p_dynamictypebuilder_t contentType = getDiscriminatorTypeBuilder(memberType); + if (contentType == nullptr) { - memberBuilder = factory->CreateChar8Builder(); + logError(XMLPARSER, "Error parsing sequence element type: Cannot be recognized."); + return nullptr; } - else + + const char* lengthStr = p_root->Attribute(SEQ_MAXLENGTH); + uint32_t length = MAX_ELEMENTS_COUNT; + if (lengthStr != nullptr) { - types::DynamicTypeBuilder* innerBuilder = factory->CreateChar8Builder(); - std::vector bounds; - dimensionsToArrayBounds(memberArray, bounds); - memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); - //factory->DeleteBuilder(innerBuilder); + length = std::stoi(lengthStr); } - } - else if (strncmp(memberType, WCHAR, 6) == 0) - { + if (!isArray) { - memberBuilder = factory->CreateChar16Builder(); + memberBuilder = factory->CreateSequenceBuilder(contentType, length); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateChar16Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateSequenceBuilder(contentType, length); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, OCTET, 6) == 0) + else if (p_root->Attribute(MAP_MAXLENGTH) != nullptr) { - if (!isArray) + /* + In maps allowed formats are (complex format includes the basic): + map, map,2> + + + + + + + + + + + + + In this example, inner maps names are ignored and can be omited. + */ + // Parse key + + //const char* keyType = p_root->Attribute(KEY); + p_dynamictypebuilder_t keyTypeBuilder = nullptr; + const char* memberMapKeyType = p_root->Attribute(MAP_KEY_TYPE); + if (memberMapKeyType != nullptr) { - memberBuilder = factory->CreateByteBuilder(); + keyTypeBuilder = getDiscriminatorTypeBuilder(memberMapKeyType); + if (keyTypeBuilder == nullptr) + { + logError(XMLPARSER, "Error parsing map's key element type: Cannot be recognized."); + return nullptr; + } } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateByteBuilder(); - std::vector bounds; - dimensionsToArrayBounds(memberArray, bounds); - memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); - //factory->DeleteBuilder(innerBuilder); + logError(XMLPARSER, "Error parsing key_type element: Not found."); + return nullptr; } - } - else if (strncmp(memberType, SHORT, 6) == 0) - { + + // Parse value + p_dynamictypebuilder_t valueTypeBuilder; + if (memberType != nullptr) + { + valueTypeBuilder = getDiscriminatorTypeBuilder(memberType); + if (valueTypeBuilder == nullptr) + { + logError(XMLPARSER, "Error parsing map's value element type: Cannot be recognized."); + return nullptr; + } + } + else + { + logError(XMLPARSER, "Error parsing value_value element: Not found."); + return nullptr; + } + + const char* lengthStr = p_root->Attribute(MAP_MAXLENGTH); + uint32_t length = MAX_ELEMENTS_COUNT; + if (lengthStr != nullptr) + { + length = std::stoi(lengthStr); + } + if (!isArray) { - memberBuilder = factory->CreateInt16Builder(); + memberBuilder = factory->CreateMapBuilder(keyTypeBuilder, valueTypeBuilder, length); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateInt16Builder(); + types::DynamicTypeBuilder* innerBuilder = + factory->CreateMapBuilder(keyTypeBuilder, valueTypeBuilder, length); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, LONG, 5) == 0) + else if (strncmp(memberType, BOOLEAN, 8) == 0) { if (!isArray) { - memberBuilder = factory->CreateInt32Builder(); + memberBuilder = factory->CreateBoolBuilder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateInt32Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateBoolBuilder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, ULONG, 13) == 0) + else if (strncmp(memberType, CHAR, 5) == 0) { if (!isArray) { - memberBuilder = factory->CreateUint32Builder(); + memberBuilder = factory->CreateChar8Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateUint32Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateChar8Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, USHORT, 14) == 0) + else if (strncmp(memberType, WCHAR, 6) == 0) { if (!isArray) { - memberBuilder = factory->CreateUint16Builder(); + memberBuilder = factory->CreateChar16Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateUint16Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateChar16Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, LONGLONG, 9) == 0) + else if (strncmp(memberType, TBYTE, 6) == 0) { if (!isArray) { - memberBuilder = factory->CreateInt64Builder(); + memberBuilder = factory->CreateByteBuilder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateInt64Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateByteBuilder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, ULONGLONG, 17) == 0) + else if (strncmp(memberType, SHORT, 6) == 0) { if (!isArray) { - memberBuilder = factory->CreateUint64Builder(); + memberBuilder = factory->CreateInt16Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateUint64Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateInt16Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, FLOAT, 6) == 0) + else if (strncmp(memberType, LONG, 5) == 0) { if (!isArray) { - memberBuilder = factory->CreateFloat32Builder(); + memberBuilder = factory->CreateInt32Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat32Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateInt32Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, DOUBLE, 7) == 0) + else if (strncmp(memberType, ULONG, 13) == 0) { if (!isArray) { - memberBuilder = factory->CreateFloat64Builder(); + memberBuilder = factory->CreateUint32Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat64Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateUint32Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, LONGDOUBLE, 11) == 0) + else if (strncmp(memberType, USHORT, 14) == 0) { if (!isArray) { - memberBuilder = factory->CreateFloat128Builder(); + memberBuilder = factory->CreateUint16Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat128Builder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateUint16Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, STRING, 7) == 0) + else if (strncmp(memberType, LONGLONG, 9) == 0) { if (!isArray) { - memberBuilder = factory->CreateStringBuilder(); + memberBuilder = factory->CreateInt64Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateStringBuilder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateInt64Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, WSTRING, 8) == 0) + else if (strncmp(memberType, ULONGLONG, 17) == 0) { if (!isArray) { - memberBuilder = factory->CreateWstringBuilder(); + memberBuilder = factory->CreateUint64Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateWstringBuilder(); + types::DynamicTypeBuilder* innerBuilder = factory->CreateUint64Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, BOUNDEDSTRING, 14) == 0) + else if (strncmp(memberType, FLOAT, 6) == 0) { - tinyxml2::XMLElement* maxLength = p_root->FirstChildElement(MAXLENGTH); - const char* boundStr = maxLength->Attribute(VALUE); - uint32_t bound = std::atoi(boundStr); if (!isArray) { - memberBuilder = factory->CreateStringBuilder(bound); + memberBuilder = factory->CreateFloat32Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateStringBuilder(bound); + types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat32Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, BOUNDEDWSTRING, 15) == 0) + else if (strncmp(memberType, DOUBLE, 7) == 0) { - tinyxml2::XMLElement* maxLength = p_root->FirstChildElement(MAXLENGTH); - const char* boundStr = maxLength->Attribute(VALUE); - uint32_t bound = std::atoi(boundStr); if (!isArray) { - memberBuilder = factory->CreateWstringBuilder(bound); + memberBuilder = factory->CreateFloat64Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateWstringBuilder(bound); + types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat64Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, SEQUENCE, 9) == 0) + else if (strncmp(memberType, LONGDOUBLE, 11) == 0) { - /* - In sequences allowed formats are (complex format includes the basic): - sequence,2> - - - - In this example, inner sequence's name is ignored and can be omited. - */ - const char* seqType = p_root->Attribute(TYPE); - p_dynamictypebuilder_t contentType; - if (seqType == nullptr) - { - contentType = parseXMLMemberDynamicType(p_root->FirstChildElement(), nullptr, MEMBER_ID_INVALID); - } - else - { - contentType = getDiscriminatorTypeBuilder(seqType); - } - - if (contentType == nullptr) - { - logError(XMLPARSER, "Error parsing sequence element type: Cannot be recognized."); - return nullptr; - } - - const char* lengthStr = p_root->Attribute(LENGHT); - uint32_t length = MAX_ELEMENTS_COUNT; - if (lengthStr != nullptr) - { - length = std::stoi(lengthStr); - } - if (!isArray) { - memberBuilder = factory->CreateSequenceBuilder(contentType, length); + memberBuilder = factory->CreateFloat128Builder(); } else { - types::DynamicTypeBuilder* innerBuilder = factory->CreateSequenceBuilder(contentType, length); + types::DynamicTypeBuilder* innerBuilder = factory->CreateFloat128Builder(); std::vector bounds; dimensionsToArrayBounds(memberArray, bounds); memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); //factory->DeleteBuilder(innerBuilder); } } - else if (strncmp(memberType, MAP, 4) == 0) + else if (strncmp(memberType, STRING, 7) == 0) { - /* - In maps allowed formats are (complex format includes the basic): - map, map,2> - - - - - - - - - - - - - In this example, inner maps names are ignored and can be omited. - */ - // Parse key - const char* keyType = p_root->Attribute(KEY_TYPE); - p_dynamictypebuilder_t keyTypeBuilder; - if (keyType == nullptr) - { - tinyxml2::XMLElement* keyElement = p_root->FirstChildElement(KEY_TYPE); - if (keyElement == nullptr) - { - logError(XMLPARSER, "Error parsing key_value element: Not found."); - return nullptr; - } - keyTypeBuilder = parseXMLMemberDynamicType(keyElement->FirstChildElement(), nullptr, MEMBER_ID_INVALID); - } - else + uint32_t bound = 0; + const char* boundStr = p_root->Attribute(STR_MAXLENGTH); + if (boundStr != nullptr) { - keyTypeBuilder = getDiscriminatorTypeBuilder(keyType); + bound = std::atoi(boundStr); } - - if (keyTypeBuilder == nullptr) - { - logError(XMLPARSER, "Error parsing map's key element type: Cannot be recognized."); - return nullptr; - } - - // Parse value - const char* valueType = p_root->Attribute(VALUE_TYPE); - p_dynamictypebuilder_t valueTypeBuilder; - if (valueType == nullptr) + if (!isArray) { - tinyxml2::XMLElement* valueElement = p_root->FirstChildElement(VALUE_TYPE); - if (valueElement == nullptr) - { - logError(XMLPARSER, "Error parsing value_value element: Not found."); - return nullptr; - } - valueTypeBuilder = parseXMLMemberDynamicType(valueElement->FirstChildElement(), nullptr, MEMBER_ID_INVALID); + memberBuilder = factory->CreateStringBuilder(bound); } else { - valueTypeBuilder = getDiscriminatorTypeBuilder(valueType); - } - - if (valueTypeBuilder == nullptr) - { - logError(XMLPARSER, "Error parsing map's value element type: Cannot be recognized."); - return nullptr; + types::DynamicTypeBuilder* innerBuilder = factory->CreateStringBuilder(bound); + std::vector boundsArray; + dimensionsToArrayBounds(memberArray, boundsArray); + memberBuilder = factory->CreateArrayBuilder(innerBuilder, boundsArray); + //factory->DeleteBuilder(innerBuilder); } - - const char* lengthStr = p_root->Attribute(LENGHT); - uint32_t length = MAX_ELEMENTS_COUNT; - if (lengthStr != nullptr) + } + else if (strncmp(memberType, WSTRING, 8) == 0) + { + uint32_t bound = 0; + const char* boundStr = p_root->Attribute(STR_MAXLENGTH); + if (boundStr != nullptr) { - length = std::stoi(lengthStr); + bound = std::atoi(boundStr); } - if (!isArray) { - memberBuilder = factory->CreateMapBuilder(keyTypeBuilder, valueTypeBuilder, length); + memberBuilder = factory->CreateWstringBuilder(bound); } else { - types::DynamicTypeBuilder* innerBuilder = - factory->CreateMapBuilder(keyTypeBuilder, valueTypeBuilder, length); - std::vector bounds; - dimensionsToArrayBounds(memberArray, bounds); - memberBuilder = factory->CreateArrayBuilder(innerBuilder, bounds); + types::DynamicTypeBuilder* innerBuilder = factory->CreateWstringBuilder(bound); + std::vector boundsArray; + dimensionsToArrayBounds(memberArray, boundsArray); + memberBuilder = factory->CreateArrayBuilder(innerBuilder, boundsArray); //factory->DeleteBuilder(innerBuilder); } } @@ -1323,10 +1410,10 @@ p_dynamictypebuilder_t XMLParser::parseXMLMemberDynamicType(tinyxml2::XMLElement } } - //memberBuilder->SetName(memberName); - if (memberKey != nullptr) + const char* memberTopicKey = p_root->Attribute(KEY); + if (memberTopicKey != nullptr) { - if (strncmp(memberKey, "true", 5) == 0) + if (strncmp(memberTopicKey, "true", 5) == 0) { memberBuilder->ApplyAnnotation("@Key", "true"); if (p_dynamictype != nullptr) @@ -1426,8 +1513,22 @@ XMLP_ret XMLParser::parseXMLTopicData(tinyxml2::XMLElement* p_root, BaseNode& ro XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profilesNode) { + /* + + + + + + + + + + + + */ + tinyxml2::XMLElement* p_profile = p_root->FirstChildElement(); - const char* tag = nullptr; + const char* tag = nullptr; while (nullptr != p_profile) { if (nullptr != (tag = p_profile->Value())) @@ -1453,20 +1554,17 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil { parseXMLTopicData(p_profile, profilesNode); } - else if (strcmp(tag, QOS_PROFILE)) - { - } - else if (strcmp(tag, APPLICATION)) + else if (strcmp(tag, QOS_PROFILE) == 0) { + logError(XMLPARSER, "Field 'QOS_PROFILE' do not supported for now"); } - else if (strcmp(tag, TYPE)) + else if (strcmp(tag, APPLICATION) == 0) { + logError(XMLPARSER, "Field 'APPLICATION' do not supported for now"); } - else if (strcmp(tag, DATA_WRITER)) - { - } - else if (strcmp(tag, DATA_READER)) + else if (strcmp(tag, TYPE) == 0) { + logError(XMLPARSER, "Field 'TYPE' do not supported for now"); } else { @@ -1698,10 +1796,10 @@ XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* node, DataNode& participant_node) { - /* - - - - - - - - - - - - - - - - */ + /* + + + + + + + + + + + + + + + + + + */ if (nullptr == p_profile) { @@ -1742,113 +1842,123 @@ XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* p_profile, DataNodeFirstChildElement(DEF_UNI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != - getXMLLocatorList(p_aux, participant_node.get()->rtps.defaultUnicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // defaultMulticastLocatorList - if (nullptr != (p_aux = p_element->FirstChildElement(DEF_MULTI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != - getXMLLocatorList(p_aux, participant_node.get()->rtps.defaultMulticastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // sendSocketBufferSize - uint32Type - if (nullptr != (p_aux = p_element->FirstChildElement(SEND_SOCK_BUF_SIZE))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux, &participant_node.get()->rtps.sendSocketBufferSize, ident)) - return XMLP_ret::XML_ERROR; - } - // listenSocketBufferSize - uint32Type - if (nullptr != (p_aux = p_element->FirstChildElement(LIST_SOCK_BUF_SIZE))) - { - if (XMLP_ret::XML_OK != getXMLUint(p_aux, &participant_node.get()->rtps.listenSocketBufferSize, ident)) - return XMLP_ret::XML_ERROR; - } - // builtin - if (nullptr != (p_aux = p_element->FirstChildElement(BUILTIN))) - { - if (XMLP_ret::XML_OK != getXMLBuiltinAttributes(p_aux, participant_node.get()->rtps.builtin, ident)) - return XMLP_ret::XML_ERROR; - } - // port - if (nullptr != (p_aux = p_element->FirstChildElement(PORT))) - { - if (XMLP_ret::XML_OK != getXMLPortParameters(p_aux, participant_node.get()->rtps.port, ident)) - return XMLP_ret::XML_ERROR; - } - // TODO: userData - if (nullptr != (p_aux = p_element->FirstChildElement(USER_DATA))) - { - if (XMLP_ret::XML_OK != getXMLOctetVector(p_aux, participant_node.get()->rtps.userData, ident)) - return XMLP_ret::XML_ERROR; - } - // participantID - int32Type - if (nullptr != (p_aux = p_element->FirstChildElement(PART_ID))) - { - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &participant_node.get()->rtps.participantID, ident)) - return XMLP_ret::XML_ERROR; - } - // throughputController - if (nullptr != (p_aux = p_element->FirstChildElement(THROUGHPUT_CONT))) - { - if (XMLP_ret::XML_OK != - getXMLThroughputController(p_aux, participant_node.get()->rtps.throughputController, ident)) - return XMLP_ret::XML_ERROR; - } - // userTransports - if (nullptr != (p_aux = p_element->FirstChildElement(USER_TRANS))) - { - if (XMLP_ret::XML_OK != getXMLTransports(p_aux, participant_node.get()->rtps.userTransports, ident)) - return XMLP_ret::XML_ERROR; - } - // useBuiltinTransports - boolType - if (nullptr != (p_aux = p_element->FirstChildElement(USE_BUILTIN_TRANS))) - { - if (XMLP_ret::XML_OK != getXMLBool(p_aux, &participant_node.get()->rtps.useBuiltinTransports, ident)) - return XMLP_ret::XML_ERROR; - } - // propertiesPolicy - if (nullptr != (p_aux = p_element->FirstChildElement(PROPERTIES_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux, participant_node.get()->rtps.properties, ident)) - return XMLP_ret::XML_ERROR; - } - // name - stringType - if (nullptr != (p_aux = p_element->FirstChildElement(NAME))) + uint8_t ident = 1; + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = p_element->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - std::string s; - if (XMLP_ret::XML_OK != getXMLString(p_aux, &s, ident)) + name = p_aux0->Name(); + if (strcmp(name, DEF_UNI_LOC_LIST) == 0) + { + // defaultUnicastLocatorList + if (XMLP_ret::XML_OK != + getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultUnicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, DEF_MULTI_LOC_LIST) == 0) + { + // defaultMulticastLocatorList + if (XMLP_ret::XML_OK != + getXMLLocatorList(p_aux0, participant_node.get()->rtps.defaultMulticastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, SEND_SOCK_BUF_SIZE) == 0) + { + // sendSocketBufferSize - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.sendSocketBufferSize, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, LIST_SOCK_BUF_SIZE) == 0) + { + // listenSocketBufferSize - uint32Type + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &participant_node.get()->rtps.listenSocketBufferSize, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, BUILTIN) == 0) + { + // builtin + if (XMLP_ret::XML_OK != getXMLBuiltinAttributes(p_aux0, participant_node.get()->rtps.builtin, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PORT) == 0) + { + // port + if (XMLP_ret::XML_OK != getXMLPortParameters(p_aux0, participant_node.get()->rtps.port, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, USER_DATA) == 0) + { + // TODO: userData + if (XMLP_ret::XML_OK != getXMLOctetVector(p_aux0, participant_node.get()->rtps.userData, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PART_ID) == 0) + { + // participantID - int32Type + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &participant_node.get()->rtps.participantID, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, THROUGHPUT_CONT) == 0) + { + // throughputController + if (XMLP_ret::XML_OK != + getXMLThroughputController(p_aux0, participant_node.get()->rtps.throughputController, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, USER_TRANS) == 0) + { + // userTransports + if (XMLP_ret::XML_OK != getXMLTransports(p_aux0, participant_node.get()->rtps.userTransports, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, USE_BUILTIN_TRANS) == 0) + { + // useBuiltinTransports - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &participant_node.get()->rtps.useBuiltinTransports, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PROPERTIES_POLICY) == 0) + { + // propertiesPolicy + if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, participant_node.get()->rtps.properties, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, NAME) == 0) + { + // name - stringType + std::string s; + if (XMLP_ret::XML_OK != getXMLString(p_aux0, &s, ident)) + return XMLP_ret::XML_ERROR; + participant_node.get()->rtps.setName(s.c_str()); + } + else + { + logError(XMLPARSER, "Invalid element found into 'rtpsParticipantAttributesType'. Name: " << name); return XMLP_ret::XML_ERROR; - participant_node.get()->rtps.setName(s.c_str()); + } } - return XMLP_ret::XML_OK; } XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* p_profile, DataNode& publisher_node) { - /* - - - - - - - - - - - - - - - */ + /* + + + + + + + + + + + + + + + + */ if (nullptr == p_profile) { @@ -1858,100 +1968,111 @@ XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* p_profile, DataNodeFirstChildElement(TOPIC))) - { - if (XMLP_ret::XML_OK != getXMLTopicAttributes(p_aux, publisher_node.get()->topic, ident)) - return XMLP_ret::XML_ERROR; - } - // qos - if (nullptr != (p_aux = p_profile->FirstChildElement(QOS))) - { - if (XMLP_ret::XML_OK != getXMLWriterQosPolicies(p_aux, publisher_node.get()->qos, ident)) - return XMLP_ret::XML_ERROR; - } - // times - if (nullptr != (p_aux = p_profile->FirstChildElement(TIMES))) - { - if (XMLP_ret::XML_OK != getXMLWriterTimes(p_aux, publisher_node.get()->times, ident)) - return XMLP_ret::XML_ERROR; - } - // unicastLocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(UNI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, publisher_node.get()->unicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // multicastLocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(MULTI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, publisher_node.get()->multicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // remoteLocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(REM_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, publisher_node.get()->remoteLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // throughputController - if (nullptr != (p_aux = p_profile->FirstChildElement(THROUGHPUT_CONT))) - { - if (XMLP_ret::XML_OK != - getXMLThroughputController(p_aux, publisher_node.get()->throughputController, ident)) - return XMLP_ret::XML_ERROR; - } - // historyMemoryPolicy - if (nullptr != (p_aux = p_profile->FirstChildElement(HIST_MEM_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux, publisher_node.get()->historyMemoryPolicy, ident)) - return XMLP_ret::XML_ERROR; - } - // propertiesPolicy - if (nullptr != (p_aux = p_profile->FirstChildElement(PROPERTIES_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux, publisher_node.get()->properties, ident)) - return XMLP_ret::XML_ERROR; - } - // userDefinedID - int16type - if (nullptr != (p_aux = p_profile->FirstChildElement(USER_DEF_ID))) - { - int i = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &i, ident) || i > 255) - return XMLP_ret::XML_ERROR; - publisher_node.get()->setUserDefinedID(static_cast(i)); - } - // entityID - int16Type - if (nullptr != (p_aux = p_profile->FirstChildElement(ENTITY_ID))) + uint8_t ident = 1; + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - int i = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &i, ident) || i > 255) + name = p_aux0->Name(); + if (strcmp(name, TOPIC) == 0) + { + // topic + if (XMLP_ret::XML_OK != getXMLTopicAttributes(p_aux0, publisher_node.get()->topic, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, QOS) == 0) + { + // qos + if (XMLP_ret::XML_OK != getXMLWriterQosPolicies(p_aux0, publisher_node.get()->qos, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, TIMES) == 0) + { + // times + if (XMLP_ret::XML_OK != getXMLWriterTimes(p_aux0, publisher_node.get()->times, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, UNI_LOC_LIST) == 0) + { + // unicastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher_node.get()->unicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MULTI_LOC_LIST) == 0) + { + // multicastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher_node.get()->multicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, REM_LOC_LIST) == 0) + { + // remoteLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, publisher_node.get()->remoteLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, THROUGHPUT_CONT) == 0) + { + // throughputController + if (XMLP_ret::XML_OK != + getXMLThroughputController(p_aux0, publisher_node.get()->throughputController, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, HIST_MEM_POLICY) == 0) + { + // historyMemoryPolicy + if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, publisher_node.get()->historyMemoryPolicy, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PROPERTIES_POLICY) == 0) + { + // propertiesPolicy + if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, publisher_node.get()->properties, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, USER_DEF_ID) == 0) + { + // userDefinedID - int16type + int i = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident) || i > 255) + return XMLP_ret::XML_ERROR; + publisher_node.get()->setUserDefinedID(static_cast(i)); + } + else if (strcmp(name, ENTITY_ID) == 0) + { + // entityID - int16Type + int i = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident) || i > 255) + return XMLP_ret::XML_ERROR; + publisher_node.get()->setEntityID(static_cast(i)); + } + else + { + logError(XMLPARSER, "Invalid element found into 'publisherProfileType'. Name: " << name); return XMLP_ret::XML_ERROR; - publisher_node.get()->setEntityID(static_cast(i)); + } } return XMLP_ret::XML_OK; } XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* p_profile, DataNode& subscriber_node) { - /* - - - - - - - - - - - - - - - */ + /* + + + + + + + + + + + + + + + + */ if (nullptr == p_profile) { @@ -1961,78 +2082,89 @@ XMLP_ret XMLParser::fillDataNode(tinyxml2::XMLElement* p_profile, DataNodeFirstChildElement(TOPIC))) - { - if (XMLP_ret::XML_OK != getXMLTopicAttributes(p_aux, subscriber_node.get()->topic, ident)) - return XMLP_ret::XML_ERROR; - } - // qos - if (nullptr != (p_aux = p_profile->FirstChildElement(QOS))) - { - if (XMLP_ret::XML_OK != getXMLReaderQosPolicies(p_aux, subscriber_node.get()->qos, ident)) - return XMLP_ret::XML_ERROR; - } - // times - if (nullptr != (p_aux = p_profile->FirstChildElement(TIMES))) - { - if (XMLP_ret::XML_OK != getXMLReaderTimes(p_aux, subscriber_node.get()->times, ident)) - return XMLP_ret::XML_ERROR; - } - // unicastLocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(UNI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, subscriber_node.get()->unicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // multicastLocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(MULTI_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, subscriber_node.get()->multicastLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // remote LocatorList - if (nullptr != (p_aux = p_profile->FirstChildElement(REM_LOC_LIST))) - { - if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux, subscriber_node.get()->remoteLocatorList, ident)) - return XMLP_ret::XML_ERROR; - } - // expectsInlineQos - boolType - if (nullptr != (p_aux = p_profile->FirstChildElement(EXP_INLINE_QOS))) - { - if (XMLP_ret::XML_OK != getXMLBool(p_aux, &subscriber_node.get()->expectsInlineQos, ident)) - return XMLP_ret::XML_ERROR; - } - // historyMemoryPolicy - if (nullptr != (p_aux = p_profile->FirstChildElement(HIST_MEM_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux, subscriber_node.get()->historyMemoryPolicy, ident)) - return XMLP_ret::XML_ERROR; - } - // propertiesPolicy - if (nullptr != (p_aux = p_profile->FirstChildElement(PROPERTIES_POLICY))) - { - if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux, subscriber_node.get()->properties, ident)) - return XMLP_ret::XML_ERROR; - } - // userDefinedID - int16Type - if (nullptr != (p_aux = p_profile->FirstChildElement(USER_DEF_ID))) - { - int i = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &i, ident) || i > 255) - return XMLP_ret::XML_ERROR; - subscriber_node.get()->setUserDefinedID(static_cast(i)); - } - // entityID - int16Type - if (nullptr != (p_aux = p_profile->FirstChildElement(ENTITY_ID))) + uint8_t ident = 1; + tinyxml2::XMLElement *p_aux0 = nullptr; + const char* name = nullptr; + for (p_aux0 = p_profile->FirstChildElement(); p_aux0 != NULL; p_aux0 = p_aux0->NextSiblingElement()) { - int i = 0; - if (XMLP_ret::XML_OK != getXMLInt(p_aux, &i, ident) || i > 255) + name = p_aux0->Name(); + if (strcmp(name, TOPIC) == 0) + { + // topic + if (XMLP_ret::XML_OK != getXMLTopicAttributes(p_aux0, subscriber_node.get()->topic, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, QOS) == 0) + { + // qos + if (XMLP_ret::XML_OK != getXMLReaderQosPolicies(p_aux0, subscriber_node.get()->qos, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, TIMES) == 0) + { + // times + if (XMLP_ret::XML_OK != getXMLReaderTimes(p_aux0, subscriber_node.get()->times, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, UNI_LOC_LIST) == 0) + { + // unicastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber_node.get()->unicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, MULTI_LOC_LIST) == 0) + { + // multicastLocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber_node.get()->multicastLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, REM_LOC_LIST) == 0) + { + // remote LocatorList + if (XMLP_ret::XML_OK != getXMLLocatorList(p_aux0, subscriber_node.get()->remoteLocatorList, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, EXP_INLINE_QOS) == 0) + { + // expectsInlineQos - boolType + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &subscriber_node.get()->expectsInlineQos, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, HIST_MEM_POLICY) == 0) + { + // historyMemoryPolicy + if (XMLP_ret::XML_OK != getXMLHistoryMemoryPolicy(p_aux0, subscriber_node.get()->historyMemoryPolicy, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, PROPERTIES_POLICY) == 0) + { + // propertiesPolicy + if (XMLP_ret::XML_OK != getXMLPropertiesPolicy(p_aux0, subscriber_node.get()->properties, ident)) + return XMLP_ret::XML_ERROR; + } + else if (strcmp(name, USER_DEF_ID) == 0) + { + // userDefinedID - int16Type + int i = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident) || i > 255) + return XMLP_ret::XML_ERROR; + subscriber_node.get()->setUserDefinedID(static_cast(i)); + } + else if (strcmp(name, ENTITY_ID) == 0) + { + // entityID - int16Type + int i = 0; + if (XMLP_ret::XML_OK != getXMLInt(p_aux0, &i, ident) || i > 255) + return XMLP_ret::XML_ERROR; + subscriber_node.get()->setEntityID(static_cast(i)); + } + else + { + logError(XMLPARSER, "Invalid element found into 'subscriberProfileType'. Name: " << name); return XMLP_ret::XML_ERROR; - subscriber_node.get()->setEntityID(static_cast(i)); + } } + return XMLP_ret::XML_OK; } diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index e7a004c9c2f..43ae0d0328c 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -100,13 +100,14 @@ const char* PREALLOCATED = "PREALLOCATED"; const char* PREALLOCATED_WITH_REALLOC = "PREALLOCATED_WITH_REALLOC"; const char* DYNAMIC = "DYNAMIC"; const char* LOCATOR = "locator"; +const char* UDPv4_LOCATOR = "udpv4"; +const char* UDPv6_LOCATOR = "udpv6"; +const char* TCPv4_LOCATOR = "tcpv4"; +const char* TCPv6_LOCATOR = "tcpv6"; const char* KIND = "kind"; const char* ADDRESS = "address"; -const char* IPV6_ADDRESS = "ipv6_address"; -const char* ADDRESSES = "addresses_"; const char* UNIQUE_LAN_ID = "unique_lan_id"; const char* WAN_ADDRESS = "wan_address"; -const char* IP_ADDRESS = "ip_address"; const char* RESERVED = "RESERVED"; const char* UDPv4 = "UDPv4"; const char* UDPv6 = "UDPv6"; @@ -120,10 +121,10 @@ const char* NACK_RESP_DELAY = "nackResponseDelay"; const char* NACK_SUPRESSION = "nackSupressionDuration"; const char* BY_NAME = "durationbyname"; const char* BY_VAL = "durationbyval"; -const char* _INFINITE = "INFINITE"; -const char* ZERO = "ZERO"; -const char* INVALID = "INVALID"; -const char* SECONDS = "seconds"; +const char* DURATION_INFINITY = "DURATION_INFINITY"; +const char* DURATION_INFINITE_SEC = "DURATION_INFINITE_SEC"; +const char* DURATION_INFINITE_NSEC = "DURATION_INFINITE_NSEC"; +const char* SECONDS = "sec"; const char* FRACTION = "fraction"; const char* SHARED = "SHARED"; const char* EXCLUSIVE = "EXCLUSIVE"; @@ -247,40 +248,42 @@ const char* _OWNERSHIP_KIND_NOT_PRESENT = "OWNERSHIP_KIND_NOT_PRESENT"; const char* STRENGTH = "strength"; // TYPES parser -const char* STRUCT = "struct"; -const char* UNION = "union"; const char* BOOLEAN = "boolean"; -const char* CHAR = "char"; -const char* WCHAR = "wchar"; -const char* OCTET = "octet"; -const char* SHORT = "short"; -const char* LONG = "long"; -const char* USHORT = "unsignedshort"; -const char* ULONG = "unsignedlong"; -const char* LONGLONG = "longlong"; -const char* ULONGLONG = "unsignedlonglong"; -const char* FLOAT = "float"; -const char* DOUBLE = "double"; -const char* LONGDOUBLE = "longdouble"; +const char* CHAR = "char8"; +const char* WCHAR = "char16"; +const char* TBYTE = "byte"; +const char* SHORT = "int16"; +const char* LONG = "int32"; +const char* USHORT = "uint16"; +const char* ULONG = "uint32"; +const char* LONGLONG = "int64"; +const char* ULONGLONG = "uint64"; +const char* FLOAT = "float32"; +const char* DOUBLE = "float64"; +const char* LONGDOUBLE = "float128"; const char* STRING = "string"; const char* WSTRING = "wstring"; -const char* BOUNDEDSTRING = "boundedString"; -const char* BOUNDEDWSTRING = "boundedWString"; +const char* LITERAL = "literal"; +const char* STRUCT = "struct"; +const char* UNION = "union"; const char* SEQUENCE = "sequence"; const char* MAP = "map"; const char* TYPEDEF = "typedef"; const char* ENUM = "enum"; -const char* LITERAL = "literal"; const char* CASE = "case"; -const char* CASEVALUE = "caseValue"; const char* DEFAULT = "default"; const char* DISCRIMINATOR = "discriminator"; -const char* DIMENSIONS = "dimensions"; +const char* CASE_DISCRIMINATOR = "caseDiscriminator"; +const char* ARRAY_DIMENSIONS = "arrayDimensions"; +const char* STR_MAXLENGTH = "stringMaxLength"; +const char* SEQ_MAXLENGTH = "sequenceMaxLength"; +const char* MAP_MAXLENGTH = "mapMaxLength"; +const char* MAP_KEY_TYPE = "key_type"; +const char* ENUMERATOR = "enumerator"; +const char* NON_BASIC_TYPE = "nonBasic"; +const char* NON_BASIC_TYPE_NAME = "nonBasicTypeName"; const char* KEY = "key"; -const char* KEY_TYPE = "key_type"; -const char* VALUE_TYPE = "value_type"; -const char* LENGHT = "length"; -const char* MAXLENGTH = "maxLength"; +const char* MEMBER = "member"; // LOG const char* USE_DEFAULT = "use_default"; diff --git a/test/unittest/dynamic_types/CMakeLists.txt b/test/unittest/dynamic_types/CMakeLists.txt index bf0812ffeba..38f338b9d0a 100644 --- a/test/unittest/dynamic_types/CMakeLists.txt +++ b/test/unittest/dynamic_types/CMakeLists.txt @@ -105,6 +105,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) endif() add_gtest(DynamicTypesTests SOURCES ${DYNAMIC_TYPES_TEST_SOURCE}) + add_executable(DynamicComplexTypesTests ${DYNAMIC_COMPLEX_TYPES_TEST_SOURCE}) target_compile_definitions(DynamicComplexTypesTests PRIVATE FASTRTPS_NO_LIB) target_include_directories(DynamicComplexTypesTests PRIVATE @@ -118,8 +119,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) endif() add_gtest(DynamicComplexTypesTests SOURCES ${DYNAMIC_COMPLEX_TYPES_TEST_SOURCE}) - endif() endif() -configure_file("types.xml" "types.xml" COPYONLY) \ No newline at end of file +configure_file("types.xml" "types.xml" COPYONLY) diff --git a/test/unittest/dynamic_types/DynamicTypesTests.cpp b/test/unittest/dynamic_types/DynamicTypesTests.cpp index 3ab11a22b22..8a2949a563d 100644 --- a/test/unittest/dynamic_types/DynamicTypesTests.cpp +++ b/test/unittest/dynamic_types/DynamicTypesTests.cpp @@ -3702,10 +3702,10 @@ TEST_F(DynamicTypesTests, DynamicType_XML_BoolStruct_test) { using namespace xmlparser; using namespace types; + const char* config_file = "types.xml"; tinyxml2::XMLDocument doc; - doc.LoadFile("types.xml"); - tinyxml2::XMLElement *element = doc.FirstChildElement("types"); - XMLP_ret ret = XMLProfileManager::loadXMLDynamicTypes(*element); + + XMLP_ret ret = XMLProfileManager::loadXMLFile(config_file); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("BoolStruct"); @@ -4624,6 +4624,71 @@ TEST_F(DynamicTypesTests, DynamicType_XML_ArrayArrayStruct_test) } } +TEST_F(DynamicTypesTests, DynamicType_XML_ArrayArrayArrayStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ArrayArrayArrayStruct"); + + // Manual comparision test + /* + typedef long MyArray[2][2]; + + struct ArrayArrayStruct + { + MyArray my_array_array[2][2]; + }; + + struct ArrayArrayArrayStruct + { + ArrayArrayStruct my_array_array_array[2][2]; + }; + + ====== + + + + + + + + + + + + + + + */ + // Typedef aka Alias + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr array_builder = m_factory->CreateArrayBuilder(int32_builder.get(), { 2, 2 }); + DynamicTypeBuilder_ptr myArray_builder = m_factory->CreateAliasBuilder(array_builder.get(), "MyArray"); + + // Struct ArrayArrayStruct + DynamicTypeBuilder_ptr aas_builder = m_factory->CreateStructBuilder(); + DynamicTypeBuilder_ptr aMyArray_builder = m_factory->CreateArrayBuilder(myArray_builder.get(), { 2, 2 }); + aas_builder->AddMember(0, "my_array_array", aMyArray_builder.get()); + aas_builder->SetName("ArrayArrayStruct"); + + // Struct ArrayArrayArrayStruct + DynamicTypeBuilder_ptr aaas_builder = m_factory->CreateStructBuilder(); + DynamicTypeBuilder_ptr aas_array_builder = m_factory->CreateArrayBuilder(aas_builder.get(), { 2, 2 }); + aaas_builder->AddMember(0, "my_array_array_array", aas_array_builder.get()); + aaas_builder->SetName("ArrayArrayArrayStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(aaas_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + TEST_F(DynamicTypesTests, DynamicType_XML_SequenceSequenceStruct_test) { using namespace xmlparser; @@ -4723,6 +4788,72 @@ TEST_F(DynamicTypesTests, DynamicType_XML_MapMapStruct_test) } } +TEST_F(DynamicTypesTests, DynamicType_bounded_string_unit_tests) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ShortStringStruct"); + DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + + // SERIALIZATION TEST + StringStruct refData; + StringStructPubSubType refDatapb; + + uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); + SerializedPayload_t payload(payloadSize); + SerializedPayload_t dynamic_payload(payloadSize); + ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); + ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + + uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); + SerializedPayload_t static_payload(static_payloadSize); + ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); + ASSERT_TRUE(static_payload.length == static_payloadSize); + ASSERT_FALSE(data->SetStringValue("TEST_OVER_LENGTH_LIMITS", MEMBER_ID_INVALID) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + +TEST_F(DynamicTypesTests, DynamicType_bounded_wstring_unit_tests) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ShortWStringStruct"); + DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + + // SERIALIZATION TEST + StringStruct refData; + StringStructPubSubType refDatapb; + + uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); + SerializedPayload_t payload(payloadSize); + SerializedPayload_t dynamic_payload(payloadSize); + ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); + ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + + uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); + SerializedPayload_t static_payload(static_payloadSize); + ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); + ASSERT_TRUE(static_payload.length == static_payloadSize); + ASSERT_FALSE(data->SetStringValue("TEST_OVER_LENGTH_LIMITS", MEMBER_ID_INVALID) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + int main(int argc, char **argv) { Log::SetVerbosity(Log::Info); diff --git a/test/unittest/dynamic_types/types.xml b/test/unittest/dynamic_types/types.xml index f1b7160ab7d..c7fe6aad7de 100644 --- a/test/unittest/dynamic_types/types.xml +++ b/test/unittest/dynamic_types/types.xml @@ -1,228 +1,254 @@ + + - - - - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + - + + + + + + - + + + + - - - + - + + + + - - - - - + - - + + - - + + - + - - + + - - + + - + - - + + - - + + - + - - + + - - + + - + - + - + - \ No newline at end of file + diff --git a/test/unittest/xmlparser/XMLProfileParserTests.cpp b/test/unittest/xmlparser/XMLProfileParserTests.cpp index acf02f8c91e..9a6ec25cf56 100644 --- a/test/unittest/xmlparser/XMLProfileParserTests.cpp +++ b/test/unittest/xmlparser/XMLProfileParserTests.cpp @@ -243,7 +243,7 @@ TEST_F(XMLProfileParserTests, XMLParserPublisher) EXPECT_EQ(pub_times.initialHeartbeatDelay, c_TimeZero); EXPECT_EQ(pub_times.heartbeatPeriod.seconds, 11); EXPECT_EQ(pub_times.heartbeatPeriod.fraction, 32u); - EXPECT_EQ(pub_times.nackResponseDelay, c_TimeInvalid); + EXPECT_EQ(pub_times.nackResponseDelay, c_TimeZero); EXPECT_EQ(pub_times.nackSupressionDuration.seconds, 121); EXPECT_EQ(pub_times.nackSupressionDuration.fraction, 332u); IPLocator::setIPv4(locator, 192, 168, 1, 3); @@ -310,7 +310,7 @@ TEST_F(XMLProfileParserTests, XMLParserDefaultPublisherProfile) EXPECT_EQ(pub_times.initialHeartbeatDelay, c_TimeZero); EXPECT_EQ(pub_times.heartbeatPeriod.seconds, 11); EXPECT_EQ(pub_times.heartbeatPeriod.fraction, 32u); - EXPECT_EQ(pub_times.nackResponseDelay, c_TimeInvalid); + EXPECT_EQ(pub_times.nackResponseDelay, c_TimeZero); EXPECT_EQ(pub_times.nackSupressionDuration.seconds, 121); EXPECT_EQ(pub_times.nackSupressionDuration.fraction, 332u); IPLocator::setIPv4(locator, 192, 168, 1, 3); diff --git a/test/unittest/xmlparser/test_xml_profiles.xml b/test/unittest/xmlparser/test_xml_profiles.xml index 8dcf4e14e7a..819d75bd993 100644 --- a/test/unittest/xmlparser/test_xml_profiles.xml +++ b/test/unittest/xmlparser/test_xml_profiles.xml @@ -5,26 +5,20 @@ - UDPv4 -
192.168.1.2
- 2019 + +
192.168.1.2
+ 2019 +
- UDPv4 -
239.255.0.1
- 2021 + +
239.255.0.1
+ 2021 +
- - - UDPv4 -
192.168.1.1
- 1979 -
-
- 80 32 1000 @@ -33,13 +27,11 @@ SIMPLE 2019102 - INFINITE + DURATION_INFINITY - - 10 - 333 - + 10 + 333 false @@ -47,32 +39,38 @@ - UDPv4 -
192.168.1.5
- 9999 + +
192.168.1.5
+ 9999 +
- UDPv4 -
192.168.1.6
- 6666 + +
192.168.1.6
+ 6666 +
- UDPv4 -
239.255.0.2
- 32 + +
239.255.0.2
+ 32 +
-
239.255.0.3
- 2112 + +
239.255.0.3
+ 2112 +
- UDPv4 -
239.255.0.1
- 21120 + +
239.255.0.1
+ 21120 +
PREALLOCATED @@ -88,8 +86,6 @@ 456 9898 - true - false 2048 45 @@ -122,19 +118,18 @@ MANUAL_BY_PARTICIPANT - - 1 - 2 - + 1 + 2 - INFINITE + DURATION_INFINITY BEST_EFFORT - ZERO + 0 + 0 @@ -149,54 +144,53 @@ - ZERO + 0 + 0 - - 11 - 32 - + 11 + 32 - INVALID + 0 + 0 - - 121 - 332 - + 121 + 332 -
192.168.1.3
- 197 + +
192.168.1.3
+ 197 +
- UDPv4 -
192.168.1.9
- 219 + +
192.168.1.9
+ 219 +
- UDPv4 -
239.255.0.1
- 2020 + +
239.255.0.1
+ 2020 +
- UDPv4 + + - 1989 + + 1989 +
- - - UDPv4 - 2021 - - 9236 234 @@ -229,19 +223,18 @@ MANUAL_BY_TOPIC - - 11 - 22 - + 11 + 22 - ZERO + 0 + 0 RELIABLE - INFINITE + DURATION_INFINITY @@ -255,50 +248,45 @@ - ZERO + 0 + 0 - - 18 - 81 - + 18 + 81 -
192.168.1.10
- 196 + +
192.168.1.10
+ 196 +
- UDPv4 - 212 + + 212 +
- UDPv4 -
239.255.0.10
- 220 + +
239.255.0.10
+ 220 +
- UDPv4 + + -
239.255.0.11
- 9891 + +
239.255.0.11
+ 9891 +
- - - UDPv4 -
192.168.1.2
- 2079 -
- -
true PREALLOCATED_WITH_REALLOC 13 diff --git a/test/unittest/xmlparser/test_xml_profiles_rooted.xml b/test/unittest/xmlparser/test_xml_profiles_rooted.xml index c524b37bd0a..a68f77ba50b 100644 --- a/test/unittest/xmlparser/test_xml_profiles_rooted.xml +++ b/test/unittest/xmlparser/test_xml_profiles_rooted.xml @@ -6,26 +6,20 @@ - UDPv4 -
192.168.1.2
- 2019 + +
192.168.1.2
+ 2019 +
- UDPv4 -
239.255.0.1
- 2021 + +
239.255.0.1
+ 2021 +
- - - UDPv4 -
192.168.1.1
- 1979 -
-
- 80 32 1000 @@ -34,13 +28,11 @@ SIMPLE 2019102 - INFINITE + DURATION_INFINITY - - 10 - 333 - + 10 + 333 false @@ -48,32 +40,38 @@ - UDPv4 -
192.168.1.5
- 9999 + +
192.168.1.5
+ 9999 +
- UDPv4 -
192.168.1.6
- 6666 + +
192.168.1.6
+ 6666 +
- UDPv4 -
239.255.0.2
- 32 + +
239.255.0.2
+ 32 +
-
239.255.0.3
- 2112 + +
239.255.0.3
+ 2112 +
- UDPv4 -
239.255.0.1
- 21120 + +
239.255.0.1
+ 21120 +
@@ -87,8 +85,6 @@ 456 9898 - true - false 2048 45 @@ -121,19 +117,18 @@ MANUAL_BY_PARTICIPANT - - 1 - 2 - + 1 + 2 - INFINITE + DURATION_INFINITY BEST_EFFORT - ZERO + 0 + 0 @@ -148,54 +143,53 @@ - ZERO + 0 + 0 - - 11 - 32 - + 11 + 32 - INVALID + 0 + 0 - - 121 - 332 - + 121 + 332 -
192.168.1.3
- 197 + +
192.168.1.3
+ 197 +
- UDPv4 -
192.168.1.9
- 219 + +
192.168.1.9
+ 219 +
- UDPv4 -
239.255.0.1
- 2020 + +
239.255.0.1
+ 2020 +
- UDPv4 + + - 1989 + + 1989 +
- - - UDPv4 - 2021 - - 9236 234 @@ -228,19 +222,18 @@ MANUAL_BY_TOPIC - - 11 - 22 - + 11 + 22 - ZERO + 0 + 0 RELIABLE - INFINITE + DURATION_INFINITY @@ -254,50 +247,45 @@ - ZERO + 0 + 0 - - 18 - 81 - + 18 + 81 -
192.168.1.10
- 196 + +
192.168.1.10
+ 196 +
- UDPv4 - 212 + + 212 +
- UDPv4 -
239.255.0.10
- 220 + +
239.255.0.10
+ 220 +
- UDPv4 + + -
239.255.0.11
- 9891 + +
239.255.0.11
+ 9891 +
- - - UDPv4 -
192.168.1.2
- 2079 -
- -
true PREALLOCATED_WITH_REALLOC 13 From d2718feb6a68e9d03b895b079a5c54fab3bb5320 Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Thu, 10 Jan 2019 12:47:07 +0100 Subject: [PATCH 06/34] Feature/xml standard [#4301] (#369) * Refs #4121 Fixing new XML model. * Refs #4121 Fixed new XML model. --- resources/xsd/fastRTPS_profiles.xsd | 40 ++++++++++++----------------- src/cpp/xmlparser/XMLParser.cpp | 26 ++++++++++++++++--- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/resources/xsd/fastRTPS_profiles.xsd b/resources/xsd/fastRTPS_profiles.xsd index fa8f0373b0d..215716ac46c 100644 --- a/resources/xsd/fastRTPS_profiles.xsd +++ b/resources/xsd/fastRTPS_profiles.xsd @@ -86,7 +86,7 @@
- + @@ -315,7 +315,7 @@ - + @@ -546,13 +546,13 @@ - + - + @@ -575,7 +575,7 @@ - + @@ -593,12 +593,13 @@ - + + @@ -739,23 +740,6 @@ - - - - - - - - - - - - - - - - - @@ -831,6 +815,16 @@ + + + + + + + + + + diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 8c233298823..63cc415fee9 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -114,6 +114,10 @@ XMLP_ret XMLParser::parseXML(tinyxml2::XMLDocument& xmlDoc, up_base_node_t& root { ret = parseXMLTopicData(node, *root); } + else if (strcmp(tag, TYPES) == 0) + { + ret = parseXMLTypes(node); + } else if (strcmp(tag, LOG) == 0) { ret = parseLogConfig(node); @@ -253,7 +257,7 @@ XMLP_ret XMLParser::parseXMLTransportData(tinyxml2::XMLElement* p_root) - + */ @@ -381,7 +385,7 @@ XMLP_ret XMLParser::parseXMLCommonTransportData(tinyxml2::XMLElement* p_root, sp - + */ @@ -475,7 +479,7 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, - + @@ -534,7 +538,7 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, } else if (strcmp(name, LISTENING_PORTS) == 0) { - // ListeningPorts uint16ListType + // listening_ports uint16ListType tinyxml2::XMLElement* p_aux1 = p_aux0->FirstChildElement(PORT); while (nullptr != p_aux1) { @@ -700,6 +704,16 @@ XMLP_ret XMLParser::parseXMLAliasDynamicType(tinyxml2::XMLElement* p_root) + + + + + + + + + + */ XMLP_ret ret = XMLP_ret::XML_OK; @@ -1554,6 +1568,10 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil { parseXMLTopicData(p_profile, profilesNode); } + else if (strcmp(tag, TYPES) == 0) + { + parseXMLTypes(p_profile); + } else if (strcmp(tag, QOS_PROFILE) == 0) { logError(XMLPARSER, "Field 'QOS_PROFILE' do not supported for now"); From 192161134b3698a92e80568e85ceb8bfc76b4d2a Mon Sep 17 00:00:00 2001 From: MiguelCompany Date: Mon, 14 Jan 2019 08:07:43 +0100 Subject: [PATCH 07/34] Refs #3091. Initial improvement on handling key-only data submessages. (#371) --- src/cpp/rtps/messages/MessageReceiver.cpp | 26 +++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/cpp/rtps/messages/MessageReceiver.cpp b/src/cpp/rtps/messages/MessageReceiver.cpp index 9cb36a5dee7..bd3932d2f7e 100644 --- a/src/cpp/rtps/messages/MessageReceiver.cpp +++ b/src/cpp/rtps/messages/MessageReceiver.cpp @@ -467,6 +467,7 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh //FOUND THE READER. //We ask the reader for a cachechange to store the information. CacheChange_t ch; + ch.kind = ALIVE; ch.serializedPayload.max_size = mMaxPayload_; ch.writerGUID.guidPrefix = sourceGuidPrefix; valid &= CDRMessage::readEntityId(msg,&ch.writerGUID.entityId); @@ -525,7 +526,6 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh ch.serializedPayload.data = &msg->buffer[msg->pos]; ch.serializedPayload.length = payload_size; msg->pos += payload_size; - ch.kind = ALIVE; } else { @@ -536,24 +536,22 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh } else if(keyFlag) { - Endianness_t previous_endian = msg->msg_endian; - if(ch.serializedPayload.encapsulation == PL_CDR_BE) - msg->msg_endian = BIGEND; - else if(ch.serializedPayload.encapsulation == PL_CDR_LE) - msg->msg_endian = LITTLEEND; - else + if (payload_size <= 0) { - logError(RTPS_MSG_IN,IDSTRING"Bad encapsulation for KeyHash and status parameter list"); + logWarning(RTPS_MSG_IN, IDSTRING"Serialized Payload value invalid (" << payload_size << ")"); return false; } - //uint32_t param_size; - ParameterList_t parameter_list; - if(ParameterList::readParameterListfromCDRMsg(msg, ¶meter_list, &ch, false) <= 0) + + if (payload_size <= 16) { - logInfo(RTPS_MSG_IN,IDSTRING"SubMessage Data ERROR, keyFlag ParameterList"); - return false; + memcpy(ch.instanceHandle.value, &msg->buffer[msg->pos], payload_size); } - msg->msg_endian = previous_endian; + else + { + logWarning(RTPS_MSG_IN, IDSTRING"Ignoring Serialized Payload for too large key-only data" + "(" << payload_size << ")"); + } + msg->pos += payload_size; } } //Is the final message? From f7068c08380c770214317bcef50fe13038aa6138 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Wed, 16 Jan 2019 10:40:04 +0100 Subject: [PATCH 08/34] Domain Thread Safe [4278] (#366) * Refs #4161 Create a new mutex on the Domain class to make it thread-safe * Refs #4161 Apply several changes from the suggestions on GitHub. * Refs #4278 Change a recursive mutex for a normal mutex * Refs #4278 Fix issue on destruction. * Refs #4278. Locks on remove methods after checking input parameter. --- include/fastrtps/Domain.h | 2 ++ src/cpp/Domain.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/fastrtps/Domain.h b/include/fastrtps/Domain.h index 6fae039d9dd..012cf89602e 100644 --- a/include/fastrtps/Domain.h +++ b/include/fastrtps/Domain.h @@ -21,6 +21,7 @@ #define DOMAIN_H_ #include "attributes/ParticipantAttributes.h" +#include namespace eprosima{ namespace fastrtps{ @@ -184,6 +185,7 @@ class Domain private: + static std::mutex m_mutex; static std::vector m_participants; static bool default_xml_profiles_loaded; diff --git a/src/cpp/Domain.cpp b/src/cpp/Domain.cpp index 5fd0cc2d67f..d406bbc666c 100644 --- a/src/cpp/Domain.cpp +++ b/src/cpp/Domain.cpp @@ -45,6 +45,7 @@ using namespace eprosima::fastrtps::xmlparser; namespace eprosima { namespace fastrtps { +std::mutex Domain::m_mutex; std::vector Domain::m_participants; bool Domain::default_xml_profiles_loaded = false; @@ -62,10 +63,15 @@ Domain::~Domain() void Domain::stopAll() { - while(m_participants.size()>0) { - Domain::removeParticipant(m_participants.begin()->first); + std::lock_guard guard(m_mutex); + while (m_participants.size() > 0) + { + delete(m_participants.back().second); + m_participants.pop_back(); + } } + // Deletes DynamicTypes and TypeObject factories DynamicTypeBuilderFactory::DeleteInstance(); DynamicDataFactory::DeleteInstance(); @@ -80,6 +86,8 @@ bool Domain::removeParticipant(Participant* part) { if(part!=nullptr) { + std::lock_guard guard(m_mutex); + for(auto it = m_participants.begin();it!= m_participants.end();++it) { if(it->second->getGuid() == part->getGuid()) @@ -98,6 +106,8 @@ bool Domain::removePublisher(Publisher* pub) { if(pub!=nullptr) { + std::lock_guard guard(m_mutex); + for(auto it = m_participants.begin();it!= m_participants.end();++it) { if(it->second->getGuid().guidPrefix == pub->getGuid().guidPrefix) @@ -114,6 +124,8 @@ bool Domain::removeSubscriber(Subscriber* sub) { if(sub!=nullptr) { + std::lock_guard guard(m_mutex); + for(auto it = m_participants.begin();it!= m_participants.end();++it) { if(it->second->getGuid().guidPrefix == sub->getGuid().guidPrefix) @@ -140,6 +152,7 @@ Participant* Domain::createParticipant(const std::string &participant_profile, P logError(PARTICIPANT, "Problem loading profile '" << participant_profile << "'"); return nullptr; } + return createParticipant(participant_att, listen); } @@ -161,7 +174,10 @@ Participant* Domain::createParticipant(ParticipantAttributes& att,ParticipantLis pubsubpair.first = pubsubpar; pubsubpair.second = pspartimpl; - m_participants.push_back(pubsubpair); + { + std::lock_guard guard(m_mutex); + m_participants.push_back(pubsubpair); + } return pubsubpar; } @@ -184,11 +200,13 @@ Publisher* Domain::createPublisher(Participant *part, const std::string &publish logError(PUBLISHER, "Problem loading profile '" << publisher_profile << "'"); return nullptr; } + return createPublisher(part, publisher_att, listen); } Publisher* Domain::createPublisher(Participant *part, PublisherAttributes &att, PublisherListener *listen) { + std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end(); ++it) { if(it->second->getGuid() == part->getGuid()) @@ -230,11 +248,13 @@ Subscriber* Domain::createSubscriber(Participant *part, const std::string &subsc logError(PUBLISHER, "Problem loading profile '" << subscriber_profile << "'"); return nullptr; } + return createSubscriber(part, subscriber_att, listen); } Subscriber* Domain::createSubscriber(Participant *part, SubscriberAttributes &att, SubscriberListener *listen) { + std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end(); ++it) { if(it->second->getGuid() == part->getGuid()) @@ -247,6 +267,7 @@ Subscriber* Domain::createSubscriber(Participant *part, SubscriberAttributes &at bool Domain::getRegisteredType(Participant* part, const char* typeName, TopicDataType** type) { + std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end();++it) { if(it->second->getGuid() == part->getGuid()) @@ -259,9 +280,9 @@ bool Domain::getRegisteredType(Participant* part, const char* typeName, TopicDat bool Domain::registerType(Participant* part, TopicDataType* type) { + std::lock_guard guard(m_mutex); //TODO El registro debería hacerse de manera que no tengamos un objeto del usuario sino que tengamos un objeto TopicDataTYpe propio para que no //haya problemas si el usuario lo destruye antes de tiempo. - for (auto it = m_participants.begin(); it != m_participants.end();++it) { if(it->second->getGuid() == part->getGuid()) @@ -316,6 +337,7 @@ bool Domain::unregisterType(Participant* part, const char* typeName) { //TODO El registro debería hacerse de manera que no tengamos un objeto del usuario sino que tengamos un objeto TopicDataTYpe propio para que no //haya problemas si el usuario lo destruye antes de tiempo. + std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end();++it) { if(it->second->getGuid() == part->getGuid()) From a3f66674519731eb690ece099804a4a1f0df9f16 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Wed, 16 Jan 2019 16:25:41 +0100 Subject: [PATCH 09/34] Create a TCP Release management [4221] (#362) * Refs #4021 Implement a new feature way to stop the retry system in TCP transports. * Update include/fastrtps/rtps/network/NetworkFactory.h Co-Authored-By: JuanCarlos-eProsima <40226503+JuanCarlos-eProsima@users.noreply.github.com> * Update include/fastrtps/transport/TransportInterface.h Co-Authored-By: JuanCarlos-eProsima <40226503+JuanCarlos-eProsima@users.noreply.github.com> * Update src/cpp/rtps/network/NetworkFactory.cpp Co-Authored-By: JuanCarlos-eProsima <40226503+JuanCarlos-eProsima@users.noreply.github.com> * Update include/fastrtps/transport/UDPTransportInterface.h Co-Authored-By: JuanCarlos-eProsima <40226503+JuanCarlos-eProsima@users.noreply.github.com> * Update include/fastrtps/transport/TCPTransportInterface.h Co-Authored-By: JuanCarlos-eProsima <40226503+JuanCarlos-eProsima@users.noreply.github.com> * Refs #4021 Change a bool to atomic bool following the suggestions from GitHub * Refs #4021 Fix compilation warning on Linux * Refs #4221 Change the setSendRetry method following the suggestions from GitHub * Refs #4221 Rename method from setSendRetry to Shutdown to make it more generic --- include/fastrtps/rtps/network/NetworkFactory.h | 5 +++++ .../fastrtps/transport/TCPTransportInterface.h | 6 ++++++ include/fastrtps/transport/TransportInterface.h | 5 +++++ .../fastrtps/transport/UDPTransportInterface.h | 1 + src/cpp/rtps/network/NetworkFactory.cpp | 8 ++++++++ src/cpp/rtps/participant/RTPSParticipantImpl.cpp | 3 +++ src/cpp/transport/TCPTransportInterface.cpp | 15 +++++++++++++-- 7 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/fastrtps/rtps/network/NetworkFactory.h b/include/fastrtps/rtps/network/NetworkFactory.h index 5839b18d48a..33d24f4e430 100644 --- a/include/fastrtps/rtps/network/NetworkFactory.h +++ b/include/fastrtps/rtps/network/NetworkFactory.h @@ -134,6 +134,11 @@ class NetworkFactory * */ bool fillDefaultUnicastLocator(Locator_t &locator, const RTPSParticipantAttributes& m_att) const; + /** + * Shutdown method to close the connections of the transports. + */ + void Shutdown(); + private: std::vector > mRegisteredTransports; diff --git a/include/fastrtps/transport/TCPTransportInterface.h b/include/fastrtps/transport/TCPTransportInterface.h index 5930d105245..ccf325be5d3 100644 --- a/include/fastrtps/transport/TCPTransportInterface.h +++ b/include/fastrtps/transport/TCPTransportInterface.h @@ -263,6 +263,7 @@ class TCPTransportInterface : public TransportInterface std::shared_ptr ioServiceThread; RTCPMessageManager* mRTCPMessageManager; mutable std::mutex mSocketsMapMutex; + std::atomic mSendRetryActive; std::map> mSocketAcceptors; // The Key is the "Physical Port" std::vector mDeletedAcceptors; @@ -338,6 +339,11 @@ class TCPTransportInterface : public TransportInterface void Clean(); // Must be called on childs destructors! virtual void EndpointToLocator(const asio::ip::tcp::endpoint& endpoint, Locator_t& locator) const = 0; + + /** + * Shutdown method to close the connections of the transports. + */ + virtual void Shutdown() override; }; } // namespace rtps diff --git a/include/fastrtps/transport/TransportInterface.h b/include/fastrtps/transport/TransportInterface.h index 0d78b4ddaf4..72233648c6e 100644 --- a/include/fastrtps/transport/TransportInterface.h +++ b/include/fastrtps/transport/TransportInterface.h @@ -147,6 +147,11 @@ class TransportInterface LocatorList_t& list) const = 0; virtual bool fillUnicastLocator(Locator_t &locator, uint32_t well_known_port) const = 0; + + /** + * Shutdown method to close the connections of the transports. + */ + virtual void Shutdown() {}; }; } // namespace rtps diff --git a/include/fastrtps/transport/UDPTransportInterface.h b/include/fastrtps/transport/UDPTransportInterface.h index 78d896f3562..6406000dd90 100644 --- a/include/fastrtps/transport/UDPTransportInterface.h +++ b/include/fastrtps/transport/UDPTransportInterface.h @@ -180,6 +180,7 @@ class UDPTransportInterface : public TransportInterface virtual void SetReceiveBufferSize(uint32_t size) = 0; virtual void SetSendBufferSize(uint32_t size) = 0; virtual void SetSocketOutbountInterface(eProsimaUDPSocket&, const std::string&) = 0; + /* struct LocatorCompare { bool operator()(const Locator_t& lhs, const Locator_t& rhs) const diff --git a/src/cpp/rtps/network/NetworkFactory.cpp b/src/cpp/rtps/network/NetworkFactory.cpp index 123e14b3591..001bddd990f 100644 --- a/src/cpp/rtps/network/NetworkFactory.cpp +++ b/src/cpp/rtps/network/NetworkFactory.cpp @@ -277,6 +277,14 @@ bool NetworkFactory::fillDefaultUnicastLocator(Locator_t &locator, const RTPSPar return result; } +void NetworkFactory::Shutdown() +{ + for (auto& transport : mRegisteredTransports) + { + transport->Shutdown(); + } +} + uint16_t NetworkFactory::calculateWellKnownPort(const RTPSParticipantAttributes& att) const { return static_cast(att.port.portBase + diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp index 1c751ad46b4..baaa80c7741 100644 --- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp +++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp @@ -242,6 +242,9 @@ const std::vector& RTPSParticipantImpl::getAllReaders() const RTPSParticipantImpl::~RTPSParticipantImpl() { + // Disable Retries on Transports + m_network_Factory.Shutdown(); + // Safely abort threads. for(auto& block : m_receiverResourcelist) { diff --git a/src/cpp/transport/TCPTransportInterface.cpp b/src/cpp/transport/TCPTransportInterface.cpp index deea321a9ad..5ad7a6f76dc 100644 --- a/src/cpp/transport/TCPTransportInterface.cpp +++ b/src/cpp/transport/TCPTransportInterface.cpp @@ -95,6 +95,7 @@ TCPTransportDescriptor::TCPTransportDescriptor(const TCPTransportDescriptor& t) TCPTransportInterface::TCPTransportInterface() : mRTCPMessageManager(nullptr) + , mSendRetryActive(true) , mCleanSocketsPoolTimer(nullptr) { } @@ -547,7 +548,7 @@ void TCPTransportInterface::CloseTCPSocket(TCPChannelResource *pChannelResource) return p.second == pChannelResource; }); - if (searchIt != mChannelResources.end() && pChannelResource->IsAlive()) + if (searchIt != mChannelResources.end() && pChannelResource->IsAlive() && mSendRetryActive) { TCPChannelResource *newChannel = nullptr; const Locator_t& physicalLocator = IPLocator::toPhysicalLocator(pChannelResource->GetLocator()); @@ -1011,13 +1012,18 @@ bool TCPTransportInterface::Send(const octet* sendBuffer, uint32_t sendBufferSiz return success; } - else + else if (mSendRetryActive) { logWarning(RTCP, " SEND [RTPS] Failed: Connection not established " \ << IPLocator::getLogicalPort(remoteLocator)); eClock::my_sleep(100); return false; } + else + { + // With the retry disabled, the messages are discarded + return true; + } } bool TCPTransportInterface::SendThroughSocket(const octet* sendBuffer, uint32_t sendBufferSize, @@ -1345,6 +1351,11 @@ bool TCPTransportInterface::fillUnicastLocator(Locator_t &locator, uint32_t well return true; } +void TCPTransportInterface::Shutdown() +{ + mSendRetryActive = false; +} + } // namespace rtps } // namespace fastrtps From 5447b30d222d1897d9f38f443cfb522a263e4402 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Fri, 18 Jan 2019 08:43:48 +0100 Subject: [PATCH 10/34] Refs #4315 Small fix on the XML Parser to check all the parsed file and return the result at the end. (#378) --- src/cpp/xmlparser/XMLParser.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 63cc415fee9..3495991ef79 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -182,6 +182,7 @@ XMLP_ret XMLParser::parseXMLTransportsProf(tinyxml2::XMLElement* p_root) ret = parseXMLTransportData(p_element); if (ret != XMLP_ret::XML_OK) { + logError(XMLPARSER, "Error parsing transports"); return ret; } p_element = p_element->NextSiblingElement(TRANSPORT_DESCRIPTOR); @@ -1543,6 +1544,7 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil tinyxml2::XMLElement* p_profile = p_root->FirstChildElement(); const char* tag = nullptr; + bool parseOk = true; while (nullptr != p_profile) { if (nullptr != (tag = p_profile->Value())) @@ -1550,27 +1552,27 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil // If profile parsing functions fails, log and continue. if (strcmp(tag, TRANSPORT_DESCRIPTORS) == 0) { - parseXMLTransportsProf(p_profile); + parseOk &= parseXMLTransportsProf(p_profile) == XMLP_ret::XML_OK; } else if (strcmp(tag, PARTICIPANT) == 0) { - parseXMLParticipantProf(p_profile, profilesNode); + parseOk &= parseXMLParticipantProf(p_profile, profilesNode) == XMLP_ret::XML_OK; } else if (strcmp(tag, PUBLISHER) == 0 || strcmp(tag, DATA_WRITER) == 0) { - parseXMLPublisherProf(p_profile, profilesNode); + parseOk &= parseXMLPublisherProf(p_profile, profilesNode) == XMLP_ret::XML_OK; } else if (strcmp(tag, SUBSCRIBER) == 0 || strcmp(tag, DATA_READER) == 0) { - parseXMLSubscriberProf(p_profile, profilesNode); + parseOk &= parseXMLSubscriberProf(p_profile, profilesNode) == XMLP_ret::XML_OK; } else if (strcmp(tag, TOPIC) == 0) { - parseXMLTopicData(p_profile, profilesNode); + parseOk &= parseXMLTopicData(p_profile, profilesNode) == XMLP_ret::XML_OK; } else if (strcmp(tag, TYPES) == 0) { - parseXMLTypes(p_profile); + parseOk &= parseXMLTypes(p_profile) == XMLP_ret::XML_OK; } else if (strcmp(tag, QOS_PROFILE) == 0) { @@ -1589,6 +1591,12 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil logError(XMLPARSER, "Not expected tag: '" << tag << "'"); } } + + if (!parseOk) + { + logError(XMLPARSER, "Error parsing profiles"); + return XMLP_ret::XML_ERROR; + } p_profile = p_profile->NextSiblingElement(); } return XMLP_ret::XML_OK; From d0fed2b6e94581ffddff57b43c21eb8d268ba91d Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Mon, 21 Jan 2019 09:47:22 +0100 Subject: [PATCH 11/34] Refs #4315 Added more error messages. (#380) --- src/cpp/xmlparser/XMLParser.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 3495991ef79..596d472f53c 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -618,6 +618,7 @@ XMLP_ret XMLParser::parseXMLDynamicType(tinyxml2::XMLElement* p_root) if (ret != XMLP_ret::XML_OK) { + logError(XMLPARSER, "Error parsing type " << type << "."); break; } } @@ -1070,7 +1071,7 @@ p_dynamictypebuilder_t XMLParser::parseXMLMemberDynamicType(tinyxml2::XMLElement p_dynamictypebuilder_t contentType = getDiscriminatorTypeBuilder(memberType); if (contentType == nullptr) { - logError(XMLPARSER, "Error parsing sequence element type: Cannot be recognized."); + logError(XMLPARSER, "Error parsing sequence element type: Cannot be recognized: " << memberType); return nullptr; } @@ -1425,6 +1426,19 @@ p_dynamictypebuilder_t XMLParser::parseXMLMemberDynamicType(tinyxml2::XMLElement } } + + if (memberBuilder == nullptr) + { + if (!isArray) + { + logError(XMLPARSER, "Failed creating " << memberType << ": " << memberName); + } + else + { + logError(XMLPARSER, "Failed creating " << memberType << " array: " << memberName); + } + } + const char* memberTopicKey = p_root->Attribute(KEY); if (memberTopicKey != nullptr) { @@ -1594,7 +1608,7 @@ XMLP_ret XMLParser::parseProfiles(tinyxml2::XMLElement* p_root, BaseNode& profil if (!parseOk) { - logError(XMLPARSER, "Error parsing profiles"); + logError(XMLPARSER, "Error parsing profile's tag " << tag); return XMLP_ret::XML_ERROR; } p_profile = p_profile->NextSiblingElement(); From 6ee8ef9d485b6051b9dc948bf51540ff5dae6bbe Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Tue, 22 Jan 2019 09:04:50 +0100 Subject: [PATCH 12/34] Feature/tcp performance tests [4281] (#367) * Refs #4018. Update the performance tests to support tcpv4 communication. * Refs #4018. Set command publishers as reliable * Refs #4018. Fix compilation error. * Refs #4018. Add a sleep before close the video test to wait until the subscriber receives the last message. * Refs #4018. Add log messages * Refs #4018. Add log messages to memory test * Refs #4018 TCP tests * Refs #4018 Create the new configuration attribute to manage the TCP delays. * Refs #4018 Auto-disable TCP delay for testing. * Refs #4018 Restore default value for TCP delay. * Refs #4331 Disabled CRC * Refs #4331 Create two new attributes to set if TCP is going to use CRC checking or not. * Refs #4331 Enable CRC Checking with the configuration variables * Refs #4331 Fix issue on parser to keep consistency with the standard * Refs #4281 Remove the configuration parameters to accelerate the discovery process because they could affect to the results of the tests * Refs #4331 Applied style. * Refs #4331 Comment sleep for testing purposes. * Refs #4331 Comment sleep for testing purposes. * Refs #4331 Fix issue with several locators on TCP connections. * Refs #4331 Fixing localhost * Refs #4331 Fixed localhost * Refs #4331 Recovered sleep, but with 0 ms. * Refs #4331 Fix issue connecting to localhost using the lan address. * Refs #4331 Create unit tests to check every combination for the shrink method * Refs #4331 Created unit tests to check every combination for the shrink method * Refs #4315 Create new configuration attributes to set the width, height and frame rate of the video streaming. * Refs #4315 Added more log messages on errors. * Refs #4315 Fix some logs and upgrade the information about drops. * Refs #4315 Update video test time to work on seconds. * Refs #4315 Fix shrink locator in tcpv4 * Refs #4315 Improve the explanation of the HelloWorldTCP example to show how publisher and subscriber work over TCP * Refs #4315 Fix a crash on the videotest if the subscriber hasn't results after the test * Refs #4281 Apply some changes suggested in the Pull Request * Refs #4281 Add braces to all the performance tests * Refs #4281 Rename the field "avoid_tcp_delay" to its new name "enable_tcp_nodelay" and add a new check for TCP with the whitelists * Refs #4281 Add a special case for TCP whitelist checking when there isn't any locator --- .../HelloWorldPublisher.cpp | 13 +- .../HelloWorldSubscriber.cpp | 8 +- .../HelloWorldExampleTCP/HelloWorld_main.cpp | 66 ++-- .../transport/TCPTransportDescriptor.h | 3 + include/fastrtps/transport/TCPv4Transport.h | 2 + include/fastrtps/xmlparser/XMLParserCommon.h | 3 + resources/xsd/fastRTPS_profiles.xsd | 3 + src/cpp/transport/TCPTransportInterface.cpp | 31 +- src/cpp/transport/TCPv4Transport.cpp | 130 +++++++- src/cpp/transport/tcp/RTCPMessageManager.cpp | 46 +-- src/cpp/xmlparser/XMLParser.cpp | 30 +- src/cpp/xmlparser/XMLParserCommon.cpp | 3 + .../transport/TCPTransportDescriptor.h | 3 + test/performance/CMakeLists.txt | 5 +- test/performance/LatencyTestPublisher.cpp | 67 +++- test/performance/LatencyTestSubscriber.cpp | 21 +- test/performance/ThroughputPublisher.cpp | 8 +- test/performance/ThroughputSubscriber.cpp | 15 +- test/performance/VideoTestPublisher.cpp | 97 ++++-- test/performance/VideoTestPublisher.h | 8 +- test/performance/VideoTestSubscriber.cpp | 297 +++++++++++------- test/performance/VideoTestSubscriber.h | 5 +- test/performance/main_LatencyTest.cpp | 7 +- test/performance/main_ThroughputTest.cpp | 22 +- test/performance/main_VideoTest.cpp | 52 ++- test/profiling/MemoryTestPublisher.cpp | 4 +- test/profiling/MemoryTestSubscriber.cpp | 4 + test/unittest/transport/TCPv4Tests.cpp | 254 ++++++++++++++- .../transport/mock/MockTCPv4Transport.h | 59 ++++ 29 files changed, 1001 insertions(+), 265 deletions(-) create mode 100644 test/unittest/transport/mock/MockTCPv4Transport.h diff --git a/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp b/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp index f1a36cf43b5..0d9e93b10c0 100644 --- a/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp +++ b/examples/C++/HelloWorldExampleTCP/HelloWorldPublisher.cpp @@ -33,11 +33,10 @@ using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -HelloWorldPublisher::HelloWorldPublisher():mp_participant(nullptr), -mp_publisher(nullptr) +HelloWorldPublisher::HelloWorldPublisher() + : mp_participant(nullptr) + , mp_publisher(nullptr) { - - } bool HelloWorldPublisher::init(const std::string &wan_ip, unsigned short port) @@ -70,7 +69,9 @@ bool HelloWorldPublisher::init(const std::string &wan_ip, unsigned short port) mp_participant = Domain::createParticipant(PParam); if (mp_participant == nullptr) + { return false; + } //REGISTER THE TYPE Domain::registerType(mp_participant, &m_type); @@ -89,7 +90,9 @@ bool HelloWorldPublisher::init(const std::string &wan_ip, unsigned short port) Wparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; mp_publisher = Domain::createPublisher(mp_participant, Wparam, (PublisherListener*)&m_listener); if (mp_publisher == nullptr) + { return false; + } return true; } @@ -134,7 +137,9 @@ void HelloWorldPublisher::runThread(uint32_t samples, long sleep_ms) for (uint32_t i = 0; i < samples; ++i) { if (!publish()) + { --i; + } else { std::cout << "[RTCP] Message: " << m_Hello.message() << " with index: " << m_Hello.index() << " SENT" << std::endl; diff --git a/examples/C++/HelloWorldExampleTCP/HelloWorldSubscriber.cpp b/examples/C++/HelloWorldExampleTCP/HelloWorldSubscriber.cpp index 522d920fdca..8570d5f4616 100644 --- a/examples/C++/HelloWorldExampleTCP/HelloWorldSubscriber.cpp +++ b/examples/C++/HelloWorldExampleTCP/HelloWorldSubscriber.cpp @@ -68,7 +68,9 @@ bool HelloWorldSubscriber::init(const std::string &wan_ip, unsigned short port) mp_participant = Domain::createParticipant(PParam); if (mp_participant == nullptr) + { return false; + } //REGISTER THE TYPE Domain::registerType(mp_participant, &m_type); @@ -85,10 +87,10 @@ bool HelloWorldSubscriber::init(const std::string &wan_ip, unsigned short port) Rparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; Rparam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; mp_subscriber = Domain::createSubscriber(mp_participant, Rparam, (SubscriberListener*)&m_listener); - if (mp_subscriber == nullptr) + { return false; - + } return true; } @@ -138,5 +140,7 @@ void HelloWorldSubscriber::run(uint32_t number) { std::cout << "[RTCP] Subscriber running until " << number << "samples have been received" << std::endl; while (number < this->m_listener.n_samples) + { eClock::my_sleep(500); + } } diff --git a/examples/C++/HelloWorldExampleTCP/HelloWorld_main.cpp b/examples/C++/HelloWorldExampleTCP/HelloWorld_main.cpp index 71287183f87..5b89ab025f7 100644 --- a/examples/C++/HelloWorldExampleTCP/HelloWorld_main.cpp +++ b/examples/C++/HelloWorldExampleTCP/HelloWorld_main.cpp @@ -80,16 +80,26 @@ int main(int argc, char** argv) } else { - std::cout << "publisher OR subscriber argument needed" << std::endl; - std::cout << "publisher has optional arguments: publisher [times] [interval] [wan_ip] [port] " << std::endl; - std::cout << "\ttimes: Number of messages to send (default: unlimited = 0). " << std::endl; - std::cout << "\t\tIf times is set greater than 0, no messages will be sent until a subscriber matches. " << std::endl; - std::cout << "\tinterval: Milliseconds between messages (default: 100). " << std::endl; - std::cout << "\twap_ip: Public IP Address of the server. " << std::endl; - std::cout << "\tport: Physical Port of the server, this port must be allowed in the router of the server. " << std::endl; - std::cout << "\nsubscriber has optional arguments: subscriber [wan_ip] [port] " << std::endl; - std::cout << "\twap_ip: Public IP Address of the server. " << std::endl; - std::cout << "\tport: Physical Port of the server. " << std::endl; + std::cout << "There was an error with the input arguments." << std::endl << std::endl; + std::cout << "This example needs at least the argument to set if it is going to work" << std::endl; + std::cout << "as a 'publisher' or as a 'subscriber'." << std::endl << std::endl; + + std::cout << "The publisher is going to work as a TCP server and if the test" << std::endl; + std::cout << "is through a NAT it must have its public IP in the wan_ip argument." << std::endl << std::endl; + std::cout << "The optional arguments are: publisher [times] [interval] [wan_ip] [port] " << std::endl; + std::cout << "\t- times: Number of messages to send (default: unlimited = 0). " << std::endl; + std::cout << "\t\t If times is set greater than 0, no messages will be sent until a subscriber matches. " << std::endl; + std::cout << "\t- interval: Milliseconds between messages (default: 100). " << std::endl; + std::cout << "\t- wap_ip: Public IP Address of the publisher. " << std::endl; + std::cout << "\t- port: Physical Port to listening incoming connections, this port must be allowed in" << std::endl; + std::cout << "\t\tthe router of the publisher if the test is going to use WAN IP. " << std::endl << std::endl; + + std::cout << "The subscriber is going to work as a TCP client. If the test is through a NAT" << std::endl; + std::cout << "server_ip must have the WAN IP of the publisher and if the test is on LAN" << std::endl; + std::cout << "it must have the LAN IP of the publisher" << std::endl << std::endl; + std::cout << "The optional arguments are: subscriber [server_ip] [port] " << std::endl; + std::cout << "\t- server_ip: IP Address of the publisher. " << std::endl; + std::cout << "\t- port: Physical Port where the publisher is listening for connections." << std::endl << std::endl; Log::Reset(); return 0; @@ -98,24 +108,24 @@ int main(int argc, char** argv) switch (type) { - case 1: - { - HelloWorldPublisher mypub; - if (mypub.init(wan_ip, static_cast(port))) - { - mypub.run(count, sleep); - } - break; - } - case 2: - { - HelloWorldSubscriber mysub; - if (mysub.init(wan_ip, static_cast(port))) - { - mysub.run(); - } - break; - } + case 1: + { + HelloWorldPublisher mypub; + if (mypub.init(wan_ip, static_cast(port))) + { + mypub.run(count, sleep); + } + break; + } + case 2: + { + HelloWorldSubscriber mysub; + if (mysub.init(wan_ip, static_cast(port))) + { + mysub.run(); + } + break; + } } Domain::stopAll(); Log::Reset(); diff --git a/include/fastrtps/transport/TCPTransportDescriptor.h b/include/fastrtps/transport/TCPTransportDescriptor.h index 00a7742cd83..33698e2d895 100644 --- a/include/fastrtps/transport/TCPTransportDescriptor.h +++ b/include/fastrtps/transport/TCPTransportDescriptor.h @@ -35,7 +35,10 @@ typedef struct TCPTransportDescriptor : public SocketTransportDescriptor { uint16_t logical_port_range; uint16_t logical_port_increment; uint32_t tcp_negotiation_timeout; + bool enable_tcp_nodelay; bool wait_for_tcp_negotiation; + bool calculate_crc; + bool check_crc; void add_listener_port(uint16_t port) { diff --git a/include/fastrtps/transport/TCPv4Transport.h b/include/fastrtps/transport/TCPv4Transport.h index a49218f05ed..9e2a17c8b01 100644 --- a/include/fastrtps/transport/TCPv4Transport.h +++ b/include/fastrtps/transport/TCPv4Transport.h @@ -70,6 +70,8 @@ class TCPv4Transport : public TCPTransportInterface virtual bool fillUnicastLocator(Locator_t &locator, uint32_t well_known_port) const override; + virtual LocatorList_t ShrinkLocatorLists(const std::vector& locatorLists) override; + protected: TCPv4TransportDescriptor mConfiguration_; diff --git a/include/fastrtps/xmlparser/XMLParserCommon.h b/include/fastrtps/xmlparser/XMLParserCommon.h index b1b7b9b1895..647d4ece6c6 100644 --- a/include/fastrtps/xmlparser/XMLParserCommon.h +++ b/include/fastrtps/xmlparser/XMLParserCommon.h @@ -63,8 +63,11 @@ extern const char* KEEP_ALIVE_TIMEOUT; extern const char* MAX_LOGICAL_PORT; extern const char* LOGICAL_PORT_RANGE; extern const char* LOGICAL_PORT_INCREMENT; +extern const char* ENABLE_TCP_NODELAY; extern const char* METADATA_LOGICAL_PORT; extern const char* LISTENING_PORTS; +extern const char* CALCULATE_CRC; +extern const char* CHECK_CRC; extern const char* QOS_PROFILE; extern const char* APPLICATION; diff --git a/resources/xsd/fastRTPS_profiles.xsd b/resources/xsd/fastRTPS_profiles.xsd index 215716ac46c..d328cb1f0ae 100644 --- a/resources/xsd/fastRTPS_profiles.xsd +++ b/resources/xsd/fastRTPS_profiles.xsd @@ -576,6 +576,9 @@ + + + diff --git a/src/cpp/transport/TCPTransportInterface.cpp b/src/cpp/transport/TCPTransportInterface.cpp index 5ad7a6f76dc..80fdc9fcc5e 100644 --- a/src/cpp/transport/TCPTransportInterface.cpp +++ b/src/cpp/transport/TCPTransportInterface.cpp @@ -76,7 +76,10 @@ TCPTransportDescriptor::TCPTransportDescriptor() , logical_port_range(20) , logical_port_increment(2) , tcp_negotiation_timeout(s_default_tcp_negotitation_timeout) + , enable_tcp_nodelay(false) , wait_for_tcp_negotiation(false) + , calculate_crc(true) + , check_crc(true) { } @@ -89,7 +92,10 @@ TCPTransportDescriptor::TCPTransportDescriptor(const TCPTransportDescriptor& t) , logical_port_range(t.logical_port_range) , logical_port_increment(t.logical_port_increment) , tcp_negotiation_timeout(t.tcp_negotiation_timeout) + , enable_tcp_nodelay(t.enable_tcp_nodelay) , wait_for_tcp_negotiation(t.wait_for_tcp_negotiation) + , calculate_crc(t.calculate_crc) + , check_crc(t.check_crc) { } @@ -296,7 +302,13 @@ bool TCPTransportInterface::CreateAcceptorSocket(const Locator_t& locator) catch (asio::system_error const& e) { (void)e; - logInfo(RTCP_MSG_OUT, "TCPTransport Error binding at port: (" << IPLocator::getPhysicalPort(locator) << ")" << " with msg: " << e.what()); + logError(RTCP_MSG_OUT, "TCPTransport Error binding at port: (" << IPLocator::getPhysicalPort(locator) << ")" << " with msg: " << e.what()); + return false; + } + catch (const asio::error_code& code) + { + (void)code; + logError(RTCP, "TCPTransport Error binding at port: (" << IPLocator::getPhysicalPort(locator) << ")" << " with code: " << code); return false; } @@ -320,7 +332,10 @@ void TCPTransportInterface::FillTCPHeader(TCPHeader& header, const octet* sendBu { header.length = sendBufferSize + static_cast(TCPHeader::getSize()); header.logicalPort = logicalPort; - CalculateCRC(header, sendBuffer, sendBufferSize); + if (GetConfiguration()->calculate_crc) + { + CalculateCRC(header, sendBuffer, sendBufferSize); + } } @@ -809,7 +824,7 @@ bool TCPTransportInterface::Receive(TCPChannelResource *pChannelResource, octet* body_size); //logInfo(RTCP_MSG_IN, " Received [ReadBody]"); - if (!CheckCRC(tcp_header, receiveBuffer, receiveBufferSize)) + if (GetConfiguration()->check_crc && !CheckCRC(tcp_header, receiveBuffer, receiveBufferSize)) { logWarning(RTCP_MSG_IN, "Bad TCP header CRC"); } @@ -1016,7 +1031,6 @@ bool TCPTransportInterface::Send(const octet* sendBuffer, uint32_t sendBufferSiz { logWarning(RTCP, " SEND [RTPS] Failed: Connection not established " \ << IPLocator::getLogicalPort(remoteLocator)); - eClock::my_sleep(100); return false; } else @@ -1120,6 +1134,11 @@ void TCPTransportInterface::SocketAccepted(TCPAcceptor* acceptor, const asio::er eProsimaTCPSocket unicastSocket = eProsimaTCPSocket(acceptor->mSocket); acceptor->mSocket = nullptr; #endif + + getSocketPtr(unicastSocket)->set_option(socket_base::receive_buffer_size(GetConfiguration()->receiveBufferSize)); + getSocketPtr(unicastSocket)->set_option(socket_base::send_buffer_size(GetConfiguration()->sendBufferSize)); + getSocketPtr(unicastSocket)->set_option(ip::tcp::no_delay(GetConfiguration()->enable_tcp_nodelay)); + // Store the new connection. TCPChannelResource *pChannelResource = new TCPChannelResource(this, mRTCPMessageManager, mService, unicastSocket, GetConfiguration()->maxMessageSize); @@ -1184,6 +1203,10 @@ void TCPTransportInterface::SocketConnected(Locator_t locator, const asio::error { try { + outputSocket->getSocket()->set_option(socket_base::receive_buffer_size(GetConfiguration()->receiveBufferSize)); + outputSocket->getSocket()->set_option(socket_base::send_buffer_size(GetConfiguration()->sendBufferSize)); + outputSocket->getSocket()->set_option(ip::tcp::no_delay(GetConfiguration()->enable_tcp_nodelay)); + outputSocket->SetThread( new std::thread(&TCPTransportInterface::performListenOperation, this, outputSocket)); outputSocket->SetRTCPThread( diff --git a/src/cpp/transport/TCPv4Transport.cpp b/src/cpp/transport/TCPv4Transport.cpp index 56fd55e1bcf..78469079f8c 100644 --- a/src/cpp/transport/TCPv4Transport.cpp +++ b/src/cpp/transport/TCPv4Transport.cpp @@ -299,7 +299,7 @@ bool TCPv4Transport::fillMetatrafficUnicastLocator(Locator_t &locator, uint32_t { bool result = TCPTransportInterface::fillMetatrafficUnicastLocator(locator, metatraffic_unicast_port); - IPLocator::setWan(locator, + IPLocator::setWan(locator, mConfiguration_.wan_addr[0], mConfiguration_.wan_addr[1], mConfiguration_.wan_addr[2], mConfiguration_.wan_addr[3]); @@ -310,13 +310,137 @@ bool TCPv4Transport::fillUnicastLocator(Locator_t &locator, uint32_t well_known_ { bool result = TCPTransportInterface::fillUnicastLocator(locator, well_known_port); - IPLocator::setWan(locator, - mConfiguration_.wan_addr[0], mConfiguration_.wan_addr[1], + IPLocator::setWan(locator, + mConfiguration_.wan_addr[0], mConfiguration_.wan_addr[1], mConfiguration_.wan_addr[2], mConfiguration_.wan_addr[3]); return result; } +LocatorList_t TCPv4Transport::ShrinkLocatorLists(const std::vector& locatorLists) +{ + LocatorList_t unicastResult; + LocatorList_t connectedLocators; + for (auto it = mChannelResources.begin(); it != mChannelResources.end(); ++it) + { + connectedLocators.push_back(it->first); + } + + for (const LocatorList_t& locatorList : locatorLists) + { + LocatorListConstIterator it = locatorList.begin(); + LocatorList_t pendingUnicast; + + bool addLocator = true; + while (it != locatorList.end()) + { + assert((*it).kind == mTransportKind); + addLocator = true; + + // Check is local interface. + auto localInterface = mCurrentInterfaces.begin(); + for (; localInterface != mCurrentInterfaces.end(); ++localInterface) + { + if (CompareLocatorIP(localInterface->locator, *it)) + { + // Loopback locator + Locator_t loopbackLocator; + FillLocalIp(loopbackLocator); + IPLocator::setPhysicalPort(loopbackLocator, IPLocator::getPhysicalPort(*it)); + IPLocator::setLogicalPort(loopbackLocator, IPLocator::getLogicalPort(*it)); + pendingUnicast.push_back(loopbackLocator); + addLocator = false; + break; + } + } + + // Add localhost? + if (localInterface == mCurrentInterfaces.end() && IPLocator::isLocal(*it)) + { + pendingUnicast.push_back(*it); + ++it; + continue; + } + else if (!addLocator) + { + ++it; + continue; + } + + // Check Remote WAN locators. + if (memcmp(IPLocator::getWan(*it), mConfiguration_.wan_addr, 4) != 0) + { + // Only allow one locator with the same WAN and physical port. + for (auto unicastLocator = unicastResult.begin(); unicastLocator != unicastResult.end(); ++unicastLocator) + { + if (memcmp(IPLocator::getWan(*unicastLocator), IPLocator::getWan(*it), 4) == 0 && unicastLocator->port == it->port) + { + addLocator = false; + break; + } + } + } + else + { + // With the same wan than the server, only allow one locator with the same address and physical port. + for (auto unicastLocator = unicastResult.begin(); unicastLocator != unicastResult.end(); ++unicastLocator) + { + if (memcmp(IPLocator::getIPv4(*unicastLocator), IPLocator::getIPv4(*it), 4) == 0 && unicastLocator->port == it->port) + { + addLocator = false; + break; + } + } + } + + if (addLocator) + { + addLocator = false; + + // Only allow already connected locators. + for (auto locatorIt = connectedLocators.begin(); locatorIt != connectedLocators.end(); ++locatorIt) + { + if (((IPLocator::hasWan(*it) && memcmp(IPLocator::getWan(*it), IPLocator::getIPv4(*locatorIt), 4) == 0) || + (!IPLocator::hasWan(*it) && memcmp(IPLocator::getIPv4(*it), IPLocator::getIPv4(*locatorIt), 4) == 0)) && + IPLocator::getPhysicalPort(*locatorIt) == IPLocator::getPhysicalPort(*it)) + { + addLocator = true; + break; + } + } + + if (addLocator) + { + pendingUnicast.push_back(*it); + } + } + ++it; + } + + unicastResult.push_back(pendingUnicast); + } + + if (!IsInterfaceWhiteListEmpty() && unicastResult.size() > 0) + { + bool bValid = false; + for (Locator_t loc : unicastResult) + { + if (IsInterfaceAllowed(IPLocator::toIPv4string(loc))) + { + bValid = true; + } + } + + if (!bValid) + { + logError(RTCP, "There isn't any valid TCP Address on the whitelist"); + } + } + + LocatorList_t result(std::move(unicastResult)); + return result; +} + } // namespace rtps } // namespace fastrtps } // namespace eprosima diff --git a/src/cpp/transport/tcp/RTCPMessageManager.cpp b/src/cpp/transport/tcp/RTCPMessageManager.cpp index 2b6a4441e85..d59d84a31d8 100644 --- a/src/cpp/transport/tcp/RTCPMessageManager.cpp +++ b/src/cpp/transport/tcp/RTCPMessageManager.cpp @@ -153,35 +153,39 @@ void RTCPMessageManager::fillHeaders(TCPCPMKind kind, const TCPTransactionId &tr header.length = static_cast(retCtrlHeader.length + TCPHeader::getSize()); // Finally, calculate the CRC - octet* it = (octet*)&retCtrlHeader; + uint32_t crc = 0; - for (size_t i = 0; i < TCPControlMsgHeader::getSize(); ++i) + if (mTransport->GetConfiguration()->calculate_crc) { - crc = addToCRC(crc, it[i]); - } - if (respCode != nullptr) - { - it = (octet*)respCode; - for (int i = 0; i < 4; ++i) + octet* it = (octet*)&retCtrlHeader; + for (size_t i = 0; i < TCPControlMsgHeader::getSize(); ++i) { crc = addToCRC(crc, it[i]); } - } - if (payload != nullptr) - { - octet* pay = (octet*)&(payload->encapsulation); - for (uint32_t i = 0; i < 2; ++i) - { - crc = addToCRC(crc, pay[i]); - } - pay = (octet*)&(payload->length); - for (uint32_t i = 0; i < 4; ++i) + if (respCode != nullptr) { - crc = addToCRC(crc, pay[i]); + it = (octet*)respCode; + for (int i = 0; i < 4; ++i) + { + crc = addToCRC(crc, it[i]); + } } - for (uint32_t i = 0; i < payload->length; ++i) + if (payload != nullptr) { - crc = addToCRC(crc, payload->data[i]); + octet* pay = (octet*)&(payload->encapsulation); + for (uint32_t i = 0; i < 2; ++i) + { + crc = addToCRC(crc, pay[i]); + } + pay = (octet*)&(payload->length); + for (uint32_t i = 0; i < 4; ++i) + { + crc = addToCRC(crc, pay[i]); + } + for (uint32_t i = 0; i < payload->length; ++i) + { + crc = addToCRC(crc, payload->data[i]); + } } } header.crc = crc; diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 596d472f53c..32597a76651 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -259,6 +259,8 @@ XMLP_ret XMLParser::parseXMLTransportData(tinyxml2::XMLElement* p_root) + + */ @@ -456,7 +458,9 @@ XMLP_ret XMLParser::parseXMLCommonTransportData(tinyxml2::XMLElement* p_root, sp strcmp(name, TRANSPORT_ID) == 0 || strcmp(name, TYPE) == 0 || strcmp(name, KEEP_ALIVE_FREQUENCY) == 0 || strcmp(name, KEEP_ALIVE_TIMEOUT) == 0 || strcmp(name, MAX_LOGICAL_PORT) == 0 || strcmp(name, LOGICAL_PORT_RANGE) == 0 || - strcmp(name, LOGICAL_PORT_INCREMENT) == 0 || strcmp(name, LISTENING_PORTS) == 0) + strcmp(name, LOGICAL_PORT_INCREMENT) == 0 || strcmp(name, LISTENING_PORTS) == 0 || + strcmp(name, CALCULATE_CRC) == 0 || strcmp(name, CHECK_CRC) == 0 || + strcmp(name, ENABLE_TCP_NODELAY) == 0) { // Parsed outside of this method } @@ -484,6 +488,8 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, + + */ @@ -537,6 +543,14 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, return XMLP_ret::XML_ERROR; pTCPDesc->logical_port_increment = static_cast(iPort); } + // enable_tcp_nodelay - boolType + else if (strcmp(name, ENABLE_TCP_NODELAY) == 0) + { + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->enable_tcp_nodelay, 0)) + { + return XMLP_ret::XML_ERROR; + } + } else if (strcmp(name, LISTENING_PORTS) == 0) { // listening_ports uint16ListType @@ -551,6 +565,20 @@ XMLP_ret XMLParser::parseXMLCommonTCPTransportData(tinyxml2::XMLElement* p_root, p_aux1 = p_aux1->NextSiblingElement(PORT); } } + else if (strcmp(name, CALCULATE_CRC) == 0) + { + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->calculate_crc, 0)) + { + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, CHECK_CRC) == 0) + { + if (XMLP_ret::XML_OK != getXMLBool(p_aux0, &pTCPDesc->check_crc, 0)) + { + return XMLP_ret::XML_ERROR; + } + } else if (strcmp(name, TCP_WAN_ADDR) == 0 || strcmp(name, TRANSPORT_ID) == 0 || strcmp(name, TYPE) == 0 || strcmp(name, SEND_BUFFER_SIZE) == 0 || strcmp(name, RECEIVE_BUFFER_SIZE) == 0 || strcmp(name, TTL) == 0 || diff --git a/src/cpp/xmlparser/XMLParserCommon.cpp b/src/cpp/xmlparser/XMLParserCommon.cpp index 43ae0d0328c..d38f6b36e62 100644 --- a/src/cpp/xmlparser/XMLParserCommon.cpp +++ b/src/cpp/xmlparser/XMLParserCommon.cpp @@ -48,8 +48,11 @@ const char* KEEP_ALIVE_TIMEOUT = "keep_alive_timeout_ms"; const char* MAX_LOGICAL_PORT = "max_logical_port"; const char* LOGICAL_PORT_RANGE = "logical_port_range"; const char* LOGICAL_PORT_INCREMENT = "logical_port_increment"; +const char* ENABLE_TCP_NODELAY = "enable_tcp_nodelay"; const char* METADATA_LOGICAL_PORT = "metadata_logical_port"; const char* LISTENING_PORTS = "listening_ports"; +const char* CALCULATE_CRC = "calculate_crc"; +const char* CHECK_CRC = "check_crc"; const char* QOS_PROFILE = "qos_profile"; const char* APPLICATION = "application"; diff --git a/test/mock/rtps/TCPTransportDescriptor/fastrtps/transport/TCPTransportDescriptor.h b/test/mock/rtps/TCPTransportDescriptor/fastrtps/transport/TCPTransportDescriptor.h index dadd5247483..52bdf7a9dc7 100644 --- a/test/mock/rtps/TCPTransportDescriptor/fastrtps/transport/TCPTransportDescriptor.h +++ b/test/mock/rtps/TCPTransportDescriptor/fastrtps/transport/TCPTransportDescriptor.h @@ -36,7 +36,10 @@ typedef struct TCPTransportDescriptor : public SocketTransportDescriptor { uint16_t logical_port_increment; uint16_t metadata_logical_port; uint32_t tcp_negotiation_timeout; + bool enable_tcp_nodelay; bool wait_for_tcp_negotiation; + bool calculate_crc; + bool check_crc; void add_listener_port(uint16_t port) { diff --git a/test/performance/CMakeLists.txt b/test/performance/CMakeLists.txt index 82c3053b299..d2ef00ac530 100644 --- a/test/performance/CMakeLists.txt +++ b/test/performance/CMakeLists.txt @@ -77,10 +77,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER) AND fastcdr_FOUND) endif() else() find_package(PkgConfig) - pkg_check_modules(GST REQUIRED gstreamer-1.0>=1.4) - # gstreamer-sdp-1.0>=1.4 - # gstreamer-video-1.0>=1.4 - # gstreamer-app-1.0>=1.4) + pkg_check_modules(GST gstreamer-1.0>=1.4) endif() if(GST_FOUND) diff --git a/test/performance/LatencyTestPublisher.cpp b/test/performance/LatencyTestPublisher.cpp index b734dec4b54..97078ba03b4 100644 --- a/test/performance/LatencyTestPublisher.cpp +++ b/test/performance/LatencyTestPublisher.cpp @@ -75,7 +75,6 @@ LatencyTestPublisher::~LatencyTestPublisher() Domain::removeParticipant(mp_participant); } - bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, bool hostname, bool export_csv, const std::string& export_prefix, const PropertyPolicy& part_property_policy, const PropertyPolicy& property_policy, bool large_data, const std::string& sXMLConfigFile, bool dynamic_types, @@ -265,11 +264,14 @@ bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pi std::ostringstream pt; pt << "LatencyTest_"; if (hostname) + { pt << asio::ip::host_name() << "_"; + } pt << pid << "_PUB2SUB"; PubDataparam.topic.topicName = pt.str(); PubDataparam.times.heartbeatPeriod.seconds = 0; PubDataparam.times.heartbeatPeriod.fraction = 4294967 * 100; + if (!reliable) { PubDataparam.qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS; @@ -303,7 +305,9 @@ bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pi std::ostringstream st; st << "LatencyTest_"; if (hostname) + { st << asio::ip::host_name() << "_"; + } st << pid << "_SUB2PUB"; SubDataparam.topic.topicName = st.str(); if (reliable) @@ -337,14 +341,17 @@ bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pi std::ostringstream pct; pct << "LatencyTest_Command_"; if (hostname) + { pct << asio::ip::host_name() << "_"; + } pct << pid << "_PUB2SUB"; PubCommandParam.topic.topicName = pct.str(); PubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; PubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + PubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; + PubCommandParam.qos.m_publishMode.kind = eprosima::fastrtps::SYNCHRONOUS_PUBLISH_MODE; mp_commandpub = Domain::createPublisher(mp_participant, PubCommandParam, &this->m_commandpublistener); - if (mp_commandpub == nullptr) { return false; @@ -356,15 +363,17 @@ bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pi std::ostringstream sct; sct << "LatencyTest_Command_"; if (hostname) + { sct << asio::ip::host_name() << "_"; + } sct << pid << "_SUB2PUB"; SubCommandParam.topic.topicName = sct.str(); SubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; SubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; SubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + PubCommandParam.qos.m_publishMode.kind = eprosima::fastrtps::SYNCHRONOUS_PUBLISH_MODE; mp_commandsub = Domain::createSubscriber(mp_participant, SubCommandParam, &this->m_commandsublistener); - if (mp_commandsub == nullptr) { return false; @@ -373,7 +382,9 @@ bool LatencyTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pi // Calculate overhead t_start_ = std::chrono::steady_clock::now(); for (int i = 0; i < 1000; ++i) + { t_end_ = std::chrono::steady_clock::now(); + } t_overhead_ = std::chrono::duration(t_end_ - t_start_) / 1001; cout << "Overhead " << t_overhead_.count() << " ns" << endl; @@ -505,7 +516,9 @@ void LatencyTestPublisher::CommandSubListener::onNewDataMessage(Subscriber* subs } } else - cout<< "Problem reading"<dynamic_data) { subscriber->takeNextData((void*)mp_up->m_DynData_in,&mp_up->m_sampleinfo); - if (mp_up->m_DynData_in->GetUint32Value(0) == mp_up->m_DynData_out->GetUint32Value(0)) { mp_up->t_end_ = std::chrono::steady_clock::now(); @@ -535,7 +547,6 @@ void LatencyTestPublisher::DataSubListener::onNewDataMessage(Subscriber* subscri else { subscriber->takeNextData((void*)mp_up->mp_latency_in,&mp_up->m_sampleinfo); - if(mp_up->mp_latency_in->seqnum == mp_up->mp_latency_out->seqnum) { mp_up->t_end_ = std::chrono::steady_clock::now(); @@ -561,7 +572,10 @@ void LatencyTestPublisher::run() //WAIT FOR THE DISCOVERY PROCESS FO FINISH: //EACH SUBSCRIBER NEEDS 4 Matchings (2 publishers and 2 subscribers) std::unique_lock disc_lock(mutex_); - while(disc_count_ != (n_subscribers * 4)) disc_cond_.wait(disc_lock); + while (disc_count_ != (n_subscribers * 4)) + { + disc_cond_.wait(disc_lock); + } disc_lock.unlock(); cout << C_B_MAGENTA << "DISCOVERY COMPLETE "<::iterator ndata = data_size_pub.begin(); ndata != data_size_pub.end(); ++ndata) { - if(!this->test(*ndata)) + if (!this->test(*ndata)) + { break; + } eClock::my_sleep(100); if (ndata != data_size_pub.end() - 1) { @@ -586,8 +602,10 @@ void LatencyTestPublisher::run() Domain::removeSubscriber(mp_commandsub); std::string str_reliable = "besteffort"; - if(reliable_) + if (reliable_) + { str_reliable = "reliable"; + } if (n_export_csv) { @@ -739,14 +757,14 @@ bool LatencyTestPublisher::test(uint32_t datasize) void LatencyTestPublisher::analyzeTimes(uint32_t datasize) { TimeStats TS; - TS.nbytes = datasize+4; + TS.nbytes = datasize + 4; TS.received = n_received; TS.m_min = *std::min_element(times_.begin(), times_.end()); TS.m_max = *std::max_element(times_.begin(), times_.end()); TS.mean = std::accumulate(times_.begin(), times_.end(), std::chrono::duration(0)).count() / times_.size(); - double auxstdev=0; - for(std::vector>::iterator tit = times_.begin(); tit != times_.end(); ++tit) + double auxstdev = 0; + for (std::vector>::iterator tit = times_.begin(); tit != times_.end(); ++tit) { auxstdev += pow(((*tit).count() - TS.mean), 2); } @@ -757,33 +775,48 @@ void LatencyTestPublisher::analyzeTimes(uint32_t datasize) size_t elem = 0; elem = static_cast(times_.size() * 0.5); - if(elem > 0 && elem <= times_.size()) + if (elem > 0 && elem <= times_.size()) + { TS.p50 = times_.at(--elem).count(); + } else + { TS.p50 = NAN; + } elem = static_cast(times_.size() * 0.9); - if(elem > 0 && elem <= times_.size()) + if (elem > 0 && elem <= times_.size()) + { TS.p90 = times_.at(--elem).count(); + } else + { TS.p90 = NAN; + } elem = static_cast(times_.size() * 0.99); - if(elem > 0 && elem <= times_.size()) + if (elem > 0 && elem <= times_.size()) + { TS.p99 = times_.at(--elem).count(); + } else + { TS.p99 = NAN; + } elem = static_cast(times_.size() * 0.9999); - if(elem > 0 && elem <= times_.size()) + if (elem > 0 && elem <= times_.size()) + { TS.p9999 = times_.at(--elem).count(); + } else + { TS.p9999 = NAN; + } m_stats.push_back(TS); } - void LatencyTestPublisher::printStat(TimeStats& TS) { output_file_minimum << "\"" << TS.m_min.count() << "\""; diff --git a/test/performance/LatencyTestSubscriber.cpp b/test/performance/LatencyTestSubscriber.cpp index 76d346d6dfa..301bcc4b3e1 100644 --- a/test/performance/LatencyTestSubscriber.cpp +++ b/test/performance/LatencyTestSubscriber.cpp @@ -160,11 +160,14 @@ bool LatencyTestSubscriber::init(bool echo, int nsam, bool reliable, uint32_t pi std::ostringstream pt; pt << "LatencyTest_"; if (hostname) + { pt << asio::ip::host_name() << "_"; + } pt << pid << "_SUB2PUB"; PubDataparam.topic.topicName = pt.str(); PubDataparam.times.heartbeatPeriod.seconds = 0; PubDataparam.times.heartbeatPeriod.fraction = 4294967 * 100; + if (!reliable) { PubDataparam.qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS; @@ -198,9 +201,12 @@ bool LatencyTestSubscriber::init(bool echo, int nsam, bool reliable, uint32_t pi std::ostringstream st; st << "LatencyTest_"; if (hostname) + { st << asio::ip::host_name() << "_"; + } st << pid << "_PUB2SUB"; SubDataparam.topic.topicName = st.str(); + if (reliable) { SubDataparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; @@ -231,14 +237,17 @@ bool LatencyTestSubscriber::init(bool echo, int nsam, bool reliable, uint32_t pi std::ostringstream pct; pct << "LatencyTest_Command_"; if (hostname) + { pct << asio::ip::host_name() << "_"; + } pct << pid << "_SUB2PUB"; PubCommandParam.topic.topicName = pct.str(); PubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; PubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + PubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; + PubCommandParam.qos.m_publishMode.kind = eprosima::fastrtps::SYNCHRONOUS_PUBLISH_MODE; mp_commandpub = Domain::createPublisher(mp_participant, PubCommandParam, &this->m_commandpublistener); - if (mp_commandpub == nullptr) { return false; @@ -250,7 +259,9 @@ bool LatencyTestSubscriber::init(bool echo, int nsam, bool reliable, uint32_t pi std::ostringstream sct; sct << "LatencyTest_Command_"; if (hostname) + { sct << asio::ip::host_name() << "_"; + } sct << pid << "_PUB2SUB"; SubCommandParam.topic.topicName = sct.str(); SubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; @@ -258,12 +269,10 @@ bool LatencyTestSubscriber::init(bool echo, int nsam, bool reliable, uint32_t pi SubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; mp_commandsub = Domain::createSubscriber(mp_participant, SubCommandParam, &this->m_commandsublistener); - if (mp_commandsub == nullptr) { return false; } - return true; } @@ -359,6 +368,7 @@ void LatencyTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* sub } else if(command.m_command == STOP) { + cout << "Publisher has stopped the test" << endl; mp_up->mutex_.lock(); ++mp_up->data_count_; mp_up->mutex_.unlock(); @@ -366,6 +376,7 @@ void LatencyTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* sub } else if(command.m_command == STOP_ERROR) { + cout << "Publisher has canceled the test" << endl; mp_up->m_status = -1; mp_up->mutex_.lock(); ++mp_up->data_count_; @@ -416,8 +427,10 @@ void LatencyTestSubscriber::run() for(std::vector::iterator ndata = data_size_sub.begin();ndata!=data_size_sub.end();++ndata) { - if(!this->test(*ndata)) + if (!this->test(*ndata)) + { break; + } } } diff --git a/test/performance/ThroughputPublisher.cpp b/test/performance/ThroughputPublisher.cpp index 25f37b1b3bf..513063830c8 100644 --- a/test/performance/ThroughputPublisher.cpp +++ b/test/performance/ThroughputPublisher.cpp @@ -43,7 +43,6 @@ ThroughputPublisher::DataPubListener::~DataPubListener(){} void ThroughputPublisher::DataPubListener::onPublicationMatched(Publisher* /*pub*/, MatchingInfo& info) { std::unique_lock lock(m_up.dataMutex_); - if (info.status == MATCHED_MATCHING) { //std::cout << C_RED << "DATA Pub Matched" << C_DEF << std::endl; @@ -64,7 +63,6 @@ ThroughputPublisher::CommandSubListener::~CommandSubListener(){} void ThroughputPublisher::CommandSubListener::onSubscriptionMatched(Subscriber* /*sub*/, MatchingInfo& info) { std::unique_lock lock(m_up.mutex_); - if (info.status == MATCHED_MATCHING) { std::cout << C_RED << "COMMAND Sub Matched" << C_DEF << std::endl; @@ -87,7 +85,6 @@ void ThroughputPublisher::CommandPubListener::onPublicationMatched(Publisher* /* MatchingInfo& info) { std::unique_lock lock(m_up.mutex_); - if (info.status == MATCHED_MATCHING) { std::cout << C_RED << "COMMAND Pub Matched" << C_DEF << std::endl; @@ -272,6 +269,7 @@ ThroughputPublisher::ThroughputPublisher(bool reliable, uint32_t pid, bool hostn Wparam2.topic.topicName = pct.str(); Wparam2.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; Wparam2.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + Wparam2.qos.m_publishMode.kind = SYNCHRONOUS_PUBLISH_MODE; mp_commandpub = Domain::createPublisher(mp_par, Wparam2, (PublisherListener*)&this->m_CommandPubListener); @@ -309,6 +307,7 @@ void ThroughputPublisher::run(uint32_t test_time, uint32_t recovery_time_ms, int { return; } + if (demand == 0 || msg_size == 0) { if (!this->loadDemandsPayload()) @@ -421,9 +420,7 @@ bool ThroughputPublisher::test(uint32_t test_time, uint32_t recovery_time_ms, ui m_DynType.SetDynamicType(m_pDynType); Domain::registerType(mp_par, &m_DynType); - mp_datapub = Domain::createPublisher(mp_par, pubAttr, &m_DataPubListener); - m_DynData = DynamicDataFactory::GetInstance()->CreateData(m_pDynType); MemberId id; @@ -562,7 +559,6 @@ bool ThroughputPublisher::test(uint32_t test_time, uint32_t recovery_time_ms, ui std::cout << "PROBLEM READING RESULTS;" << std::endl; return false; - } bool ThroughputPublisher::loadDemandsPayload() diff --git a/test/performance/ThroughputSubscriber.cpp b/test/performance/ThroughputSubscriber.cpp index 6c7fdb17b05..ad705caa2a0 100644 --- a/test/performance/ThroughputSubscriber.cpp +++ b/test/performance/ThroughputSubscriber.cpp @@ -395,7 +395,9 @@ ThroughputSubscriber::ThroughputSubscriber(bool reliable, uint32_t pid, bool hos std::ostringstream st; st << "ThroughputTest_"; if (hostname) + { st << asio::ip::host_name() << "_"; + } st << pid << "_UP"; Sparam.topic.topicName = st.str(); if (reliable) @@ -429,11 +431,14 @@ ThroughputSubscriber::ThroughputSubscriber(bool reliable, uint32_t pid, bool hos std::ostringstream pct; pct << "ThroughputTest_Command_"; if (hostname) + { pct << asio::ip::host_name() << "_"; + } pct << pid << "_SUB2PUB"; Wparam.topic.topicName = pct.str(); Wparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; Wparam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + Wparam.qos.m_publishMode.kind = SYNCHRONOUS_PUBLISH_MODE; mp_commandpubli = Domain::createPublisher(mp_par, Wparam, (PublisherListener*)&this->m_CommandPubListener); @@ -444,7 +449,9 @@ ThroughputSubscriber::ThroughputSubscriber(bool reliable, uint32_t pid, bool hos std::ostringstream sct; sct << "ThroughputTest_Command_"; if (hostname) + { sct << asio::ip::host_name() << "_"; + } sct << pid << "_PUB2SUB"; Rparam.topic.topicName = sct.str(); Rparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; @@ -455,12 +462,16 @@ ThroughputSubscriber::ThroughputSubscriber(bool reliable, uint32_t pid, bool hos t_start_ = std::chrono::steady_clock::now(); for (int i = 0; i < 1000; ++i) + { t_end_ = std::chrono::steady_clock::now(); + } t_overhead_ = std::chrono::duration(t_end_ - t_start_) / 1001; std::cout << "Overhead " << t_overhead_.count() << std::endl; if (mp_datasub == nullptr || mp_commandsub == nullptr || mp_commandpubli == nullptr) + { ready = false; + } eClock::my_sleep(1000); @@ -476,7 +487,9 @@ ThroughputSubscriber::ThroughputSubscriber(bool reliable, uint32_t pid, bool hos void ThroughputSubscriber::run() { if (!ready) + { return; + } std::cout << "Waiting for command discovery" << std::endl; std::unique_lock lock(mutex_); disc_cond_.wait(lock, [&](){ @@ -487,7 +500,6 @@ void ThroughputSubscriber::run() while (stop_count_ != 2) { stop_cond_.wait(lock); - if (stop_count_ == 1) { std::cout << "Waiting clean state" << std::endl; @@ -534,5 +546,4 @@ void ThroughputSubscriber::run() } } return; - } diff --git a/test/performance/VideoTestPublisher.cpp b/test/performance/VideoTestPublisher.cpp index b735545136b..9b8aa62a75e 100644 --- a/test/performance/VideoTestPublisher.cpp +++ b/test/performance/VideoTestPublisher.cpp @@ -50,6 +50,9 @@ VideoTestPublisher::VideoTestPublisher() , m_dropRate(0) , m_sendSleepTime(0) , m_forcedDomain(-1) + , m_videoWidth(1024) + , m_videoHeight(720) + , m_videoFrameRate(30) { m_datapublistener.mp_up = this; m_commandpublistener.mp_up = this; @@ -58,10 +61,29 @@ VideoTestPublisher::VideoTestPublisher() VideoTestPublisher::~VideoTestPublisher() { - if (sink) gst_object_unref(GST_OBJECT(sink)), sink = nullptr; - if (videorate) gst_object_unref(GST_OBJECT(videorate)), videorate = nullptr; - if (filesrc) gst_object_unref(GST_OBJECT(filesrc)), filesrc = nullptr; - if (pipeline) gst_object_unref(GST_OBJECT(pipeline)), pipeline = nullptr; + if (sink) + { + gst_object_unref(GST_OBJECT(sink)); + sink = nullptr; + } + + if (videorate) + { + gst_object_unref(GST_OBJECT(videorate)); + videorate = nullptr; + } + + if (filesrc) + { + gst_object_unref(GST_OBJECT(filesrc)); + filesrc = nullptr; + } + + if (pipeline) + { + gst_object_unref(GST_OBJECT(pipeline)); + pipeline = nullptr; + } Domain::removeParticipant(mp_participant); } @@ -69,7 +91,8 @@ VideoTestPublisher::~VideoTestPublisher() bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, bool hostname, const PropertyPolicy& part_property_policy, const PropertyPolicy& property_policy, bool large_data, - const std::string& sXMLConfigFile, int test_time, int drop_rate, int max_sleep_time, int forced_domain) + const std::string& sXMLConfigFile, int test_time, int drop_rate, int max_sleep_time, + int forced_domain, int videoWidth, int videoHeight, int videoFrameRate) { large_data = true; m_testTime = test_time; @@ -80,6 +103,9 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, n_subscribers = n_sub; reliable_ = reliable; m_forcedDomain = forced_domain; + m_videoWidth = videoWidth; + m_videoHeight = videoHeight; + m_videoFrameRate = videoFrameRate; // GSTREAMER PIPELINE INITIALIZATION. InitGStreamer(); @@ -134,16 +160,7 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, // Create Data Publisher std::string profile_name = "publisher_profile"; PublisherAttributes PubDataparam; - PubDataparam.topic.topicDataType = "VideoType"; - PubDataparam.topic.topicKind = NO_KEY; - std::ostringstream pt; - pt << "VideoTest_"; - if (hostname) - pt << asio::ip::host_name() << "_"; - pt << pid << "_PUB2SUB"; - PubDataparam.topic.topicName = pt.str(); - PubDataparam.times.heartbeatPeriod.seconds = 0; - PubDataparam.times.heartbeatPeriod.fraction = 4294967 * 100; + if (!reliable) { PubDataparam.qos.m_reliability.kind = BEST_EFFORT_RELIABILITY_QOS; @@ -157,13 +174,23 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, if(m_sXMLConfigFile.length() > 0) { - mp_datapub = Domain::createPublisher(mp_participant, profile_name, (PublisherListener*)&this->m_datapublistener); + eprosima::fastrtps::xmlparser::XMLProfileManager::fillPublisherAttributes(profile_name, PubDataparam); } - else + + PubDataparam.topic.topicDataType = "VideoType"; + PubDataparam.topic.topicKind = NO_KEY; + std::ostringstream pt; + pt << "VideoTest_"; + if (hostname) { - mp_datapub = Domain::createPublisher(mp_participant, PubDataparam, (PublisherListener*)&this->m_datapublistener); + pt << asio::ip::host_name() << "_"; } + pt << pid << "_PUB2SUB"; + PubDataparam.topic.topicName = pt.str(); + PubDataparam.times.heartbeatPeriod.seconds = 0; + PubDataparam.times.heartbeatPeriod.fraction = 4294967 * 100; + mp_datapub = Domain::createPublisher(mp_participant, PubDataparam, (PublisherListener*)&this->m_datapublistener); if (mp_datapub == nullptr) { return false; @@ -176,12 +203,15 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, std::ostringstream pct; pct << "VideoTest_Command_"; if (hostname) + { pct << asio::ip::host_name() << "_"; + } pct << pid << "_PUB2SUB"; PubCommandParam.topic.topicName = pct.str(); PubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; + PubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; PubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; - + PubCommandParam.qos.m_publishMode.kind = eprosima::fastrtps::SYNCHRONOUS_PUBLISH_MODE; mp_commandpub = Domain::createPublisher(mp_participant, PubCommandParam, &this->m_commandpublistener); if (mp_commandpub == nullptr) @@ -195,7 +225,9 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, std::ostringstream sct; sct << "VideoTest_Command_"; if (hostname) + { sct << asio::ip::host_name() << "_"; + } sct << pid << "_SUB2PUB"; SubCommandParam.topic.topicName = sct.str(); SubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; @@ -203,7 +235,6 @@ bool VideoTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid, SubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; mp_commandsub = Domain::createSubscriber(mp_participant, SubCommandParam, &this->m_commandsublistener); - if (mp_commandsub == nullptr) { return false; @@ -267,7 +298,6 @@ void VideoTestPublisher::CommandPubListener::onPublicationMatched(Publisher* /*p void VideoTestPublisher::CommandSubListener::onSubscriptionMatched(Subscriber* /*sub*/,MatchingInfo& info) { std::unique_lock lock(mp_up->mutex_); - if(info.status == MATCHED_MATCHING) { cout << C_MAGENTA << "Command Sub Matched "<write(&command); + eClock::my_sleep(500); + if(m_status !=0) { cout << "Error in test "<mp_video_out != nullptr) { if (sub->m_sendSleepTime != 0) @@ -460,7 +490,10 @@ GstFlowReturn VideoTestPublisher::new_sample(GstElement *sink, VideoTestPublishe if (rand() % 100 > sub->m_dropRate) { - sub->mp_datapub->write((void*)sub->mp_video_out); + if (!sub->mp_datapub->write((void*)sub->mp_video_out)) + { + std::cout << "VideoPublication::run -> Cannot write video" << std::endl; + } } gst_buffer_unmap(buffer, &map); } @@ -473,15 +506,23 @@ GstFlowReturn VideoTestPublisher::new_sample(GstElement *sink, VideoTestPublishe gst_sample_unref(sample); returned_value = GST_FLOW_OK; } + else + { + std::cout << "VideoPublication::run -> Sample is nullptr" << std::endl; + } returned_value = GST_FLOW_ERROR; } + else + { + std::cout << "VideoPublication::run -> Sample is nullptr" << std::endl; + } returned_value = GST_FLOW_OK; std::chrono::steady_clock::time_point send_end = std::chrono::steady_clock::now(); std::unique_lock lock(sub->mutex_); - if(std::chrono::duration(send_end - sub->send_start_).count() >= sub->m_testTime) + if(std::chrono::duration>(send_end - sub->send_start_).count() >= sub->m_testTime) { sub->timer_on_ = true; sub->timer_cond_.notify_one(); diff --git a/test/performance/VideoTestPublisher.h b/test/performance/VideoTestPublisher.h index cce5a6d61ca..44ed8e56243 100644 --- a/test/performance/VideoTestPublisher.h +++ b/test/performance/VideoTestPublisher.h @@ -59,7 +59,7 @@ class VideoTestPublisher const eprosima::fastrtps::rtps::PropertyPolicy& part_property_policy, const eprosima::fastrtps::rtps::PropertyPolicy& property_policy, bool large_data, const std::string& sXMLConfigFile, int test_time, int drop_rate, int max_sleep_time, - int forced_domain); + int forced_domain, int video_width, int video_height, int frame_rate); void run(); bool test(uint32_t datasize); @@ -110,8 +110,10 @@ class VideoTestPublisher int m_dropRate; int m_sendSleepTime; int m_forcedDomain; - - protected: + int m_videoWidth; + int m_videoHeight; + int m_videoFrameRate; +protected: void InitGStreamer(); static GstFlowReturn new_sample(GstElement *sink, VideoTestPublisher *sub); diff --git a/test/performance/VideoTestSubscriber.cpp b/test/performance/VideoTestSubscriber.cpp index 3b6c05ff483..94ad1ba1964 100644 --- a/test/performance/VideoTestSubscriber.cpp +++ b/test/performance/VideoTestSubscriber.cpp @@ -46,6 +46,9 @@ VideoTestSubscriber::VideoTestSubscriber() , g_servertimestamp(0) , g_clienttimestamp(0) , g_framesDropped(0) + , m_videoWidth(1024) + , m_videoHeight(720) + , m_videoFrameRate(30) { m_datasublistener.mp_up = this; m_commandpublistener.mp_up = this; @@ -81,7 +84,8 @@ VideoTestSubscriber::~VideoTestSubscriber() bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostname, const PropertyPolicy& part_property_policy, const PropertyPolicy& property_policy, bool large_data, - const std::string& sXMLConfigFile, bool export_csv, const std::string& export_prefix, int forced_domain) + const std::string& sXMLConfigFile, bool export_csv, const std::string& export_prefix, + int forced_domain, int video_width, int video_height, int frame_rate) { large_data = true; m_sXMLConfigFile = sXMLConfigFile; @@ -90,6 +94,9 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn m_bExportCsv = export_csv; m_sExportPrefix = export_prefix; m_forcedDomain = forced_domain; + m_videoWidth = video_width; + m_videoHeight = video_height; + m_videoFrameRate = frame_rate; InitGStreamer(); @@ -142,14 +149,7 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn // Create Data subscriber std::string profile_name = "subscriber_profile"; SubscriberAttributes SubDataparam; - SubDataparam.topic.topicDataType = "VideoType"; - SubDataparam.topic.topicKind = NO_KEY; - std::ostringstream st; - st << "VideoTest_"; - if (hostname) - st << asio::ip::host_name() << "_"; - st << pid << "_PUB2SUB"; - SubDataparam.topic.topicName = st.str(); + if (reliable) { SubDataparam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; @@ -162,15 +162,24 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn if (m_sXMLConfigFile.length() > 0) { - mp_datasub = Domain::createSubscriber(mp_participant, profile_name, &this->m_datasublistener); + eprosima::fastrtps::xmlparser::XMLProfileManager::fillSubscriberAttributes(profile_name, SubDataparam); } - else + + SubDataparam.topic.topicDataType = "VideoType"; + SubDataparam.topic.topicKind = NO_KEY; + std::ostringstream st; + st << "VideoTest_"; + if (hostname) { - mp_datasub = Domain::createSubscriber(mp_participant, SubDataparam, &this->m_datasublistener); + st << asio::ip::host_name() << "_"; } + st << pid << "_PUB2SUB"; + SubDataparam.topic.topicName = st.str(); + mp_datasub = Domain::createSubscriber(mp_participant, SubDataparam, &this->m_datasublistener); if (mp_datasub == nullptr) { + std::cout << "Cannot create data subscriber" << std::endl; return false; } @@ -181,14 +190,16 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn std::ostringstream pct; pct << "VideoTest_Command_"; if (hostname) + { pct << asio::ip::host_name() << "_"; + } pct << pid << "_SUB2PUB"; PubCommandParam.topic.topicName = pct.str(); PubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; + PubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; PubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; mp_commandpub = Domain::createPublisher(mp_participant, PubCommandParam, &this->m_commandpublistener); - if (mp_commandpub == nullptr) { return false; @@ -200,7 +211,9 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn std::ostringstream sct; sct << "VideoTest_Command_"; if (hostname) + { sct << asio::ip::host_name() << "_"; + } sct << pid << "_PUB2SUB"; SubCommandParam.topic.topicName = sct.str(); SubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; @@ -208,22 +221,20 @@ bool VideoTestSubscriber::init(int nsam, bool reliable, uint32_t pid, bool hostn SubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; mp_commandsub = Domain::createSubscriber(mp_participant, SubCommandParam, &this->m_commandsublistener); - if (mp_commandsub == nullptr) { return false; } - return true; } void VideoTestSubscriber::DataSubListener::onSubscriptionMatched(Subscriber* /*sub*/,MatchingInfo& info) { std::unique_lock lock(mp_up->mutex_); - if(info.status == MATCHED_MATCHING) { logInfo(VideoTest,"Data Sub Matched "); + std::cout << "Data Sub Matched " << std::endl; ++mp_up->disc_count_; } else @@ -244,6 +255,7 @@ void VideoTestSubscriber::CommandPubListener::onPublicationMatched(Publisher* /* if(info.status == MATCHED_MATCHING) { logInfo(VideoTest, "Command Pub Matched "); + std::cout << "Command Pub Matched " << std::endl; ++mp_up->disc_count_; } else @@ -260,10 +272,10 @@ void VideoTestSubscriber::CommandPubListener::onPublicationMatched(Publisher* /* void VideoTestSubscriber::CommandSubListener::onSubscriptionMatched(Subscriber* /*sub*/,MatchingInfo& info) { std::unique_lock lock(mp_up->mutex_); - if(info.status == MATCHED_MATCHING) { logInfo(VideoTest, "Command Sub Matched "); + std::cout << "Command Sub Matched " << std::endl; ++mp_up->disc_count_; } else @@ -293,6 +305,7 @@ void VideoTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* subsc } else if(command.m_command == STOP) { + cout << "Publisher has stopped the test" << endl; mp_up->mutex_.lock(); ++mp_up->data_count_; mp_up->mutex_.unlock(); @@ -301,6 +314,7 @@ void VideoTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* subsc } else if(command.m_command == STOP_ERROR) { + cout << "Publisher has canceled the test" << endl; mp_up->m_status = -1; mp_up->mutex_.lock(); ++mp_up->data_count_; @@ -362,6 +376,8 @@ bool VideoTestSubscriber::test() --comm_count_; lock.unlock(); + cout << "TEST STARTED" << endl; + t_start_ = std::chrono::steady_clock::now(); t_drop_start_ = t_start_; m_status = 0; @@ -435,7 +451,8 @@ void VideoTestSubscriber::InitGStreamer() g_signal_connect(appsrc, "need-data", G_CALLBACK(start_feed_cb), this); g_signal_connect(appsrc, "enough-data", G_CALLBACK(stop_feed_cb), this); GstCaps *caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "I420", - "width", G_TYPE_INT, 1024, "height", G_TYPE_INT, 720, NULL); + "width", G_TYPE_INT, m_videoWidth, "height", G_TYPE_INT, m_videoHeight, + "framerate", GST_TYPE_FRACTION, m_videoFrameRate, 1, NULL); gst_app_src_set_caps(GST_APP_SRC(appsrc), caps); gst_caps_unref(caps); @@ -540,6 +557,7 @@ gboolean VideoTestSubscriber::push_data_cb(VideoTestSubscriber* sub) if (ret != GST_FLOW_OK) { // We got some error, stop sending data + std::cout << "Error on received frame" << std::endl; return FALSE; } } @@ -567,8 +585,14 @@ void VideoTestSubscriber::message_cb(GstBus* /*bus*/, GstMessage* message, gpoin printf("# GST INTERNAL # Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); - if (err) g_error_free(err); - if (debug_info) g_free(debug_info); + if (err) + { + g_error_free(err); + } + if (debug_info) + { + g_free(debug_info); + } //if (loop) g_main_loop_quit(loop); } @@ -581,8 +605,14 @@ void VideoTestSubscriber::message_cb(GstBus* /*bus*/, GstMessage* message, gpoin printf("# GST INTERNAL # Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error(&err); - if (err) g_error_free(err); - if (debug_info) g_free(debug_info); + if (err) + { + g_error_free(err); + } + if (debug_info) + { + g_free(debug_info); + } } break; case GST_MESSAGE_INFO: @@ -612,89 +642,139 @@ void VideoTestSubscriber::analyzeTimes() { if (samples_.size() > 0) { + for (uint32_t i = 0; i < drops_.size(); ++i) + { + drops_[i] -= drops_[0]; + } + + if (drops_.size() > 1) + { + drops_.pop_back(); + } + TimeStats TS; TS.received = static_cast(samples_.size()); { - // AVG - TS.m_minAvg = *std::min_element(avgs_.begin(), avgs_.end()); - TS.m_maxAvg = *std::max_element(avgs_.begin(), avgs_.end()); - - TS.pAvgMean = std::accumulate(avgs_.begin(), avgs_.end(), double(0)) / avgs_.size(); - double auxstdev = 0; - for (std::vector::iterator tit = avgs_.begin(); tit != avgs_.end(); ++tit) + if (avgs_.size() > 0) { - auxstdev += pow(((*tit) - TS.pAvgMean), 2); + // AVG + TS.m_minAvg = *std::min_element(avgs_.begin(), avgs_.end()); + TS.m_maxAvg = *std::max_element(avgs_.begin(), avgs_.end()); + + TS.pAvgMean = std::accumulate(avgs_.begin(), avgs_.end(), double(0)) / avgs_.size(); + double auxstdev = 0; + for (std::vector::iterator tit = avgs_.begin(); tit != avgs_.end(); ++tit) + { + auxstdev += pow(((*tit) - TS.pAvgMean), 2); + } + auxstdev = sqrt(auxstdev / avgs_.size()); + TS.pAvgStdev = auxstdev; + //TS.pAvgStdev = static_cast(round(auxstdev)); + + std::sort(avgs_.begin(), avgs_.end()); + size_t elem = 0; + + elem = static_cast(avgs_.size() * 0.5); + if (elem > 0 && elem <= avgs_.size()) + { + TS.pAvg50 = avgs_.at(--elem); + } + else + { + TS.pAvg50 = NAN; + } + + elem = static_cast(avgs_.size() * 0.9); + if (elem > 0 && elem <= avgs_.size()) + { + TS.pAvg90 = avgs_.at(--elem); + } + else + { + TS.pAvg90 = NAN; + } + + elem = static_cast(avgs_.size() * 0.99); + if (elem > 0 && elem <= avgs_.size()) + { + TS.pAvg99 = avgs_.at(--elem); + } + else + { + TS.pAvg99 = NAN; + } + + elem = static_cast(avgs_.size() * 0.9999); + if (elem > 0 && elem <= avgs_.size()) + { + TS.pAvg9999 = avgs_.at(--elem); + } + else + { + TS.pAvg9999 = NAN; + } } - auxstdev = sqrt(auxstdev / avgs_.size()); - TS.pAvgStdev = static_cast(round(auxstdev)); - - std::sort(avgs_.begin(), avgs_.end()); - size_t elem = 0; - - elem = static_cast(avgs_.size() * 0.5); - if (elem > 0 && elem <= avgs_.size()) - TS.pAvg50 = avgs_.at(--elem); - else - TS.pAvg50 = NAN; - - elem = static_cast(avgs_.size() * 0.9); - if (elem > 0 && elem <= avgs_.size()) - TS.pAvg90 = avgs_.at(--elem); - else - TS.pAvg90 = NAN; - - elem = static_cast(avgs_.size() * 0.99); - if (elem > 0 && elem <= avgs_.size()) - TS.pAvg99 = avgs_.at(--elem); - else - TS.pAvg99 = NAN; - - elem = static_cast(avgs_.size() * 0.9999); - if (elem > 0 && elem <= avgs_.size()) - TS.pAvg9999 = avgs_.at(--elem); - else - TS.pAvg9999 = NAN; } { - // DROP - TS.m_minDrop = *std::min_element(drops_.begin(), drops_.end()); - TS.m_maxDrop = *std::max_element(drops_.begin(), drops_.end()); - - TS.pDropMean = std::accumulate(drops_.begin(), drops_.end(), double(0)) / drops_.size(); - double auxstdev = 0; - for (std::vector::iterator tit = drops_.begin(); tit != drops_.end(); ++tit) + if (drops_.size() > 0) { - auxstdev += pow(((*tit) - TS.pDropMean), 2); + // DROP + TS.m_minDrop = *std::min_element(drops_.begin(), drops_.end()); + TS.m_maxDrop = *std::max_element(drops_.begin(), drops_.end()); + + TS.pDropMean = std::accumulate(drops_.begin(), drops_.end(), double(0)) / drops_.size(); + double auxstdev = 0; + for (std::vector::iterator tit = drops_.begin(); tit != drops_.end(); ++tit) + { + auxstdev += pow(((*tit) - TS.pDropMean), 2); + } + auxstdev = sqrt(auxstdev / drops_.size()); + //TS.pDropStdev = static_cast(round(auxstdev)); + TS.pDropStdev = auxstdev; + + std::sort(drops_.begin(), drops_.end()); + size_t elem = 0; + + elem = static_cast(drops_.size() * 0.5); + if (elem > 0 && elem <= drops_.size()) + { + TS.pDrop50 = drops_.at(--elem); + } + else + { + TS.pDrop50 = NAN; + } + + elem = static_cast(drops_.size() * 0.9); + if (elem > 0 && elem <= drops_.size()) + { + TS.pDrop90 = drops_.at(--elem); + } + else + { + TS.pDrop90 = NAN; + } + + elem = static_cast(drops_.size() * 0.99); + if (elem > 0 && elem <= drops_.size()) + { + TS.pDrop99 = drops_.at(--elem); + } + else + { + TS.pDrop99 = NAN; + } + + elem = static_cast(drops_.size() * 0.9999); + if (elem > 0 && elem <= drops_.size()) + { + TS.pDrop9999 = drops_.at(--elem); + } + else + { + TS.pDrop9999 = NAN; + } } - auxstdev = sqrt(auxstdev / drops_.size()); - TS.pDropStdev = static_cast(round(auxstdev)); - - std::sort(drops_.begin(), drops_.end()); - size_t elem = 0; - - elem = static_cast(drops_.size() * 0.5); - if (elem > 0 && elem <= drops_.size()) - TS.pDrop50 = drops_.at(--elem); - else - TS.pDrop50 = NAN; - - elem = static_cast(drops_.size() * 0.9); - if (elem > 0 && elem <= drops_.size()) - TS.pDrop90 = drops_.at(--elem); - else - TS.pDrop90 = NAN; - - elem = static_cast(drops_.size() * 0.99); - if (elem > 0 && elem <= drops_.size()) - TS.pDrop99 = drops_.at(--elem); - else - TS.pDrop99 = NAN; - - elem = static_cast(drops_.size() * 0.9999); - if (elem > 0 && elem <= drops_.size()) - TS.pDrop9999 = drops_.at(--elem); - else - TS.pDrop9999 = NAN; } m_stats.push_back(TS); @@ -717,22 +797,21 @@ void VideoTestSubscriber::printStat(TimeStats& TS) Drop 99.99%%, Drop max" << std::endl; printf("Statistics for video test \n"); - printf(" Samples, Avg stdev, Avg Mean, min Avg, Avg 50%%, Avg 90%%, Avg 99%%,\ - Avg 99.99%%, Avg max, Drop stdev, Drop Mean, min Drop, Drop 50%%, Drop 90%%, Drop 99%%,\ - Drop 99.99%%, Drop max\n"); - printf("------------,------------,------------,------------,------------,------------,------------,\ -------------,------------,------------,------------,------------,------------,------------,------------,\ -------------,------------\n"); - - output_file_csv << TS.received << "," << TS.pAvgMean << "," << TS.m_minAvg << "," << TS.m_minAvg << "," << + printf(" Samples, Avg stdev, Avg Mean, min Avg, Avg 50%%, Avg 90%%, Avg 99%%, Avg 99.99%%, Avg max\n"); + printf("-----------,-----------,-----------,-----------,-----------,-----------,-----------,-------------,-----------\n"); + printf("%11u,%11.2f,%11.2f,%11.2f,%11.2f,%11.2f,%11.2f,%13.2f,%11.2f \n\n\n", + TS.received, TS.pAvgStdev, TS.pAvgMean, TS.m_minAvg, TS.pAvg50, TS.pAvg90, TS.pAvg99, TS.pAvg9999, TS.m_maxAvg); + + printf(" Samples, FameDrop stdev, FameDrop Mean, min FameDrop, FameDrop 50%%, FameDrop 90%%, FameDrop 99%%, FameDrop 99.99%%, FameDrop max\n"); + printf("-----------,---------------,--------------,-------------,--------------,--------------,--------------,----------------,--------------\n"); + printf("%11u,%15.2f,%14.2f,%13.2f,%14.2f,%14.2f,%14.2f,%16.2f,%14.2f \n", + TS.received, TS.pDropStdev, TS.pDropMean, TS.m_minDrop, TS.pDrop50, TS.pDrop90, TS.pDrop99, TS.pDrop9999, TS.m_maxDrop); + + output_file_csv << TS.received << "," << TS.pAvgStdev << "," << TS.pAvgMean << "," << TS.m_minAvg << TS.pAvg50 << "," << TS.pAvg90 << "," << TS.pAvg99 << "," << TS.pAvg9999 << "," << TS.m_maxAvg << "," << - TS.pDropMean << "," << TS.m_minDrop << "," << TS.m_minDrop << "," << TS.pDrop50 << "," << TS.pDrop90 << + TS.pDropStdev << "," << TS.pDropMean << "," << TS.m_minDrop << "," << TS.pDrop50 << "," << TS.pDrop90 << "," << TS.pDrop99 << "," << TS.pDrop9999 << "," << TS.m_maxDrop << "," << std::endl; - printf("%12u,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f,%12.2f \n", - TS.received, TS.pAvgMean, TS.m_minAvg, TS.m_minAvg, TS.pAvg50, TS.pAvg90, TS.pAvg99, TS.pAvg9999, TS.m_maxAvg, - TS.pDropMean, TS.m_minDrop, TS.m_minDrop, TS.pDrop50, TS.pDrop90, TS.pDrop99, TS.pDrop9999, TS.m_maxDrop); - if (m_bExportCsv) { if (m_sExportPrefix.length() > 0) diff --git a/test/performance/VideoTestSubscriber.h b/test/performance/VideoTestSubscriber.h index 713fb714660..0ca618a06e4 100644 --- a/test/performance/VideoTestSubscriber.h +++ b/test/performance/VideoTestSubscriber.h @@ -70,7 +70,7 @@ class VideoTestSubscriber const eprosima::fastrtps::rtps::PropertyPolicy& part_property_policy, const eprosima::fastrtps::rtps::PropertyPolicy& property_policy, bool large_data, const std::string& sXMLConfigFile, bool export_csv, const std::string& export_file, - int forced_domain); + int forced_domain, int video_width, int video_height, int frame_rate); void run(); bool test(); @@ -124,6 +124,9 @@ class VideoTestSubscriber bool m_bExportCsv; std::string m_sExportPrefix; int m_forcedDomain; + int m_videoWidth; + int m_videoHeight; + int m_videoFrameRate; std::thread thread_; std::deque packet_deque_; diff --git a/test/performance/main_LatencyTest.cpp b/test/performance/main_LatencyTest.cpp index f27a06486ec..2902fd0d3f9 100644 --- a/test/performance/main_LatencyTest.cpp +++ b/test/performance/main_LatencyTest.cpp @@ -85,7 +85,10 @@ struct Arg: public option::Arg return option::ARG_OK; } - if (msg) printError("Option '", option, "' requires a numeric argument\n"); + if (msg) + { + printError("Option '", option, "' requires a numeric argument\n"); + } return option::ARG_ILLEGAL; } @@ -218,7 +221,9 @@ int main(int argc, char** argv) option::Parser parse(usage, argc, argv, &options[0], &buffer[0]); if (parse.error()) + { return 1; + } if (options[HELP]) { diff --git a/test/performance/main_ThroughputTest.cpp b/test/performance/main_ThroughputTest.cpp index 47fb04f6ab8..ea1b8a7cf90 100644 --- a/test/performance/main_ThroughputTest.cpp +++ b/test/performance/main_ThroughputTest.cpp @@ -63,16 +63,24 @@ struct Arg : public option::Arg static option::ArgStatus Unknown(const option::Option& option, bool msg) { - if (msg) printError("Unknown option '", option, "'\n"); + if (msg) + { + printError("Unknown option '", option, "'\n"); + } return option::ARG_ILLEGAL; } static option::ArgStatus Required(const option::Option& option, bool msg) { if (option.arg != 0 && option.arg[0] != 0) + { return option::ARG_OK; + } - if (msg) printError("Option '", option, "' requires an argument\n"); + if (msg) + { + printError("Option '", option, "' requires an argument\n"); + } return option::ARG_ILLEGAL; } @@ -83,9 +91,14 @@ struct Arg : public option::Arg { }; if (endptr != option.arg && *endptr == 0) + { return option::ARG_OK; + } - if (msg) printError("Option '", option, "' requires a numeric argument\n"); + if (msg) + { + printError("Option '", option, "' requires a numeric argument\n"); + } return option::ARG_ILLEGAL; } @@ -152,7 +165,6 @@ const option::Descriptor usage[] = { int main(int argc, char** argv) { - int columns; #if defined(_WIN32) @@ -219,7 +231,9 @@ int main(int argc, char** argv) option::Parser parse(usage, argc, argv, &options[0], &buffer[0]); if (parse.error()) + { return 1; + } if (options[HELP]) { diff --git a/test/performance/main_VideoTest.cpp b/test/performance/main_VideoTest.cpp index e7d121a92a1..a018e52d1b0 100644 --- a/test/performance/main_VideoTest.cpp +++ b/test/performance/main_VideoTest.cpp @@ -62,16 +62,24 @@ struct Arg: public option::Arg static option::ArgStatus Unknown(const option::Option& option, bool msg) { - if (msg) printError("Unknown option '", option, "'\n"); + if (msg) + { + printError("Unknown option '", option, "'\n"); + } return option::ARG_ILLEGAL; } static option::ArgStatus Required(const option::Option& option, bool msg) { if (option.arg != 0 && option.arg[0] != 0) - return option::ARG_OK; + { + return option::ARG_OK; + } - if (msg) printError("Option '", option, "' requires an argument\n"); + if (msg) + { + printError("Option '", option, "' requires an argument\n"); + } return option::ARG_ILLEGAL; } @@ -86,7 +94,10 @@ struct Arg: public option::Arg return option::ARG_OK; } - if (msg) printError("Option '", option, "' requires a numeric argument\n"); + if (msg) + { + printError("Option '", option, "' requires a numeric argument\n"); + } return option::ARG_ILLEGAL; } @@ -121,7 +132,10 @@ enum optionIndex { TEST_TIME, DROP_RATE, SEND_SLEEP_TIME, - FORCED_DOMAIN + FORCED_DOMAIN, + WIDTH, + HEIGHT, + FRAMERATE }; const option::Descriptor usage[] = { @@ -142,10 +156,13 @@ const option::Descriptor usage[] = { #endif { LARGE_DATA, 0, "l", "large", Arg::None, " -l \t--large\tTest large data." }, { XML_FILE, 0, "", "xml", Arg::String, "\t--xml \tXML Configuration file." }, - { TEST_TIME, 0, "", "testtime", Arg::Numeric, "\t--testtime \tTest duration time." }, + { TEST_TIME, 0, "", "testtime", Arg::Numeric, "\t--testtime \tTest duration time in seconds." }, { DROP_RATE, 0, "", "droprate", Arg::Numeric, "\t--droprate \tSending drop percentage ( 0 - 100 )." }, { SEND_SLEEP_TIME, 0, "", "sleeptime", Arg::Numeric, "\t--sleeptime \tMaximum sleep time before shipments (milliseconds)." }, { FORCED_DOMAIN, 0, "", "domain", Arg::Numeric, "\t--domain \tRTPS Domain." }, + { WIDTH, 0, "", "width", Arg::Numeric, "\t--width \tWidth of the video." }, + { HEIGHT, 0, "", "height", Arg::Numeric, "\t--height \tHeight of the video." }, + { FRAMERATE, 0, "", "rate", Arg::Numeric, "\t--rate \tFrame rate of the video." }, { 0, 0, 0, 0, 0, 0 } }; @@ -156,6 +173,8 @@ int main(int argc, char** argv) { int columns; + Log::SetVerbosity(Log::Warning); + #if defined(_WIN32) char* buf = nullptr; size_t sz = 0; @@ -174,10 +193,13 @@ int main(int argc, char** argv) bool pub_sub = false; int sub_number = 1; - int test_time = 100; + int test_time = 10; int drop_rate = 0; int max_sleep_time = 0; int forced_domain = -1; + int video_width = 1024; + int video_height = 720; + int frame_rate = 30; int n_samples = c_n_samples; #if HAVE_SECURITY bool use_security = false; @@ -222,7 +244,9 @@ int main(int argc, char** argv) option::Parser parse(usage, argc, argv, &options[0], &buffer[0]); if (parse.error()) + { return 1; + } if (options[HELP]) { @@ -312,6 +336,16 @@ int main(int argc, char** argv) forced_domain = strtol(opt.arg, nullptr, 10); break; + case WIDTH: + video_width = strtol(opt.arg, nullptr, 10); + break; + case HEIGHT: + video_height = strtol(opt.arg, nullptr, 10); + break; + case FRAMERATE: + frame_rate = strtol(opt.arg, nullptr, 10); + break; + #if HAVE_SECURITY case USE_SECURITY: if (strcmp(opt.arg, "true") == 0) @@ -397,14 +431,14 @@ int main(int argc, char** argv) cout << "Performing video test" << endl; VideoTestPublisher pub; pub.init(sub_number, n_samples, reliable, seed, hostname, pub_part_property_policy, - pub_property_policy, large_data, sXMLConfigFile, test_time, drop_rate, max_sleep_time, forced_domain); + pub_property_policy, large_data, sXMLConfigFile, test_time, drop_rate, max_sleep_time, forced_domain, video_width, video_height, frame_rate); pub.run(); } else { VideoTestSubscriber sub; sub.init(n_samples, reliable, seed, hostname, sub_part_property_policy, sub_property_policy, - large_data, sXMLConfigFile, export_csv, export_prefix, forced_domain); + large_data, sXMLConfigFile, export_csv, export_prefix, forced_domain, video_width, video_height, frame_rate); sub.run(); } diff --git a/test/profiling/MemoryTestPublisher.cpp b/test/profiling/MemoryTestPublisher.cpp index dc50090927b..e1ea6b54a25 100644 --- a/test/profiling/MemoryTestPublisher.cpp +++ b/test/profiling/MemoryTestPublisher.cpp @@ -179,6 +179,8 @@ bool MemoryTestPublisher::init(int n_sub, int n_sam, bool reliable, uint32_t pid PubCommandParam.topic.topicName = pct.str(); PubCommandParam.topic.historyQos.kind = KEEP_ALL_HISTORY_QOS; PubCommandParam.qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; + PubCommandParam.qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; + PubCommandParam.qos.m_publishMode.kind = eprosima::fastrtps::SYNCHRONOUS_PUBLISH_MODE; mp_commandpub = Domain::createPublisher(mp_participant, PubCommandParam, &this->m_commandpublistener); @@ -431,7 +433,7 @@ bool MemoryTestPublisher::test(uint32_t test_time, uint32_t datasize) command.m_command = STOP; mp_commandpub->write(&command); - + if(m_status !=0) { cout << "Error in test "<m_commandpublistener); @@ -272,6 +274,7 @@ void MemoryTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* subs } else if(command.m_command == STOP) { + cout << "Publisher has stopped the test" << endl; mp_up->mutex_.lock(); ++mp_up->data_count_; mp_up->mutex_.unlock(); @@ -279,6 +282,7 @@ void MemoryTestSubscriber::CommandSubListener::onNewDataMessage(Subscriber* subs } else if(command.m_command == STOP_ERROR) { + cout << "Publisher has canceled the test" << endl; mp_up->m_status = -1; mp_up->mutex_.lock(); ++mp_up->data_count_; diff --git a/test/unittest/transport/TCPv4Tests.cpp b/test/unittest/transport/TCPv4Tests.cpp index 5853086ed16..fc504a5aa60 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -14,6 +14,7 @@ #include #include +#include "mock/MockTCPv4Transport.h" #include #include #include @@ -40,6 +41,7 @@ const uint32_t ReceiveBufferCapacity = 65536; static uint16_t g_default_port = 0; static uint16_t g_output_port = 0; static uint16_t g_input_port = 0; +static std::string g_test_wan_address = "88.88.88.88"; uint16_t get_port(uint16_t offset) { @@ -53,6 +55,19 @@ uint16_t get_port(uint16_t offset) return port; } +static void GetIP4s(std::vector& locNames, bool return_loopback = false) +{ + IPFinder::getIPs(&locNames, return_loopback); + auto new_end = remove_if(locNames.begin(), + locNames.end(), + [](IPFinder::info_IP ip) {return ip.type != IPFinder::IP4 && ip.type != IPFinder::IP4_LOCAL; }); + locNames.erase(new_end, locNames.end()); + std::for_each(locNames.begin(), locNames.end(), [](auto&& loc) + { + loc.locator.kind = LOCATOR_KIND_TCPv4; + }); +} + class TCPv4Tests: public ::testing::Test { public: @@ -566,38 +581,251 @@ TEST_F(TCPv4Tests, send_and_receive_between_blocked_interfaces_ports) TEST_F(TCPv4Tests, shrink_locator_lists) { - TCPv4Transport transportUnderTest(descriptor); + std::vector localInterfaces; + GetIP4s(localInterfaces, false); + + MockTCPv4Transport transportUnderTest(descriptor); transportUnderTest.init(); - LocatorList_t result, list1, list2, list3; - Locator_t locator, locResult1, locResult2, locResult3; + LocatorList_t result, list1; + Locator_t locator, locator2, locator3; + Locator_t openConn1, openConn2; locator.kind = LOCATOR_KIND_TCPv4; locator.port = g_default_port; - locResult1.kind = LOCATOR_KIND_TCPv4; - locResult1.port = g_default_port; - locResult2.kind = LOCATOR_KIND_TCPv4; - locResult2.port = g_default_port; - locResult3.kind = LOCATOR_KIND_TCPv4; - locResult3.port = g_default_port; + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + locator3.kind = LOCATOR_KIND_TCPv4; + locator3.port = g_default_port; // Check shrink of only one locator list unicast. IPLocator::setIPv4(locator, 192,168,1,4); - IPLocator::setIPv4(locResult1, 192,168,1,4); + IPLocator::setIPv4(locator2, 192,168,1,4); list1.push_back(locator); IPLocator::setIPv4(locator, 192,168,2,5); - IPLocator::setIPv4(locResult2, 192,168,2,5); + IPLocator::setIPv4(locator3, 192,168,2,5); list1.push_back(locator); + // Open connections (fake) + openConn1 = locator2; + openConn2 = locator3; + transportUnderTest.OpenOutputChannel(openConn1); + transportUnderTest.OpenOutputChannel(openConn2); + result = transportUnderTest.ShrinkLocatorLists({list1}); ASSERT_EQ(result.size(), 2u); - for(auto it = result.begin(); it != result.end(); ++it) - ASSERT_TRUE(*it == locResult1 || *it == locResult2); + for (auto it = result.begin(); it != result.end(); ++it) + { + ASSERT_TRUE(*it == locator2 || *it == locator3); + } + list1.clear(); + + // Shrink Two Localhosts and return localhost. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 127, 0, 0, 1); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 127, 0, 0, 1); + list1.push_back(locator2); + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 1u); + ASSERT_TRUE(*result.begin() == locator); + list1.clear(); + + transportUnderTest.CloseOutputChannel(openConn1); + transportUnderTest.CloseOutputChannel(openConn2); + + // Shrink Several Local addresses and return localhost. + if (localInterfaces.size() > 0) + { + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 127, 0, 0, 1); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, localInterfaces.begin()->locator); + list1.push_back(locator2); + if (localInterfaces.size() > 1) + { + IPLocator::setIPv4(locator2, localInterfaces[1].locator); + list1.push_back(locator2); + } + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 1u); + ASSERT_TRUE(*result.begin() == locator); + list1.clear(); + } + + // Shrink two WAN Adresses ( Same as mine ) With same LAN Address and same Logical Port and Same Physical Port and return only one. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, g_test_wan_address); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 192, 168, 0, 1); + IPLocator::setWan(locator2, g_test_wan_address); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + IPLocator::setIPv4(openConn1, g_test_wan_address); + transportUnderTest.OpenOutputChannel(openConn1); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 1u); + ASSERT_TRUE(*result.begin() == locator); + + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + + // Shrink two WAN Adresses ( Same as mine ) With same LAN Address and same Logical Port and Different Physical Port and return both. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, g_test_wan_address); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port + 1; + IPLocator::setIPv4(locator2, 192, 168, 0, 1); + IPLocator::setWan(locator2, g_test_wan_address); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + openConn2.port = g_default_port + 1; + IPLocator::setIPv4(openConn1, g_test_wan_address); + IPLocator::setIPv4(openConn2, g_test_wan_address); + transportUnderTest.OpenOutputChannel(openConn1); + transportUnderTest.OpenOutputChannel(openConn2); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 2u); + for (auto it = result.begin(); it != result.end(); ++it) + { + ASSERT_TRUE(*it == locator || *it == locator2); + } + + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + transportUnderTest.CloseOutputChannel(openConn2); + + //Shrink two WAN Adresses ( Same as mine ) With different LAN Address and same Logical Port and same Physical Port and return both. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, g_test_wan_address); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 192, 168, 0, 2); + IPLocator::setWan(locator2, g_test_wan_address); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + IPLocator::setIPv4(openConn1, g_test_wan_address); + transportUnderTest.OpenOutputChannel(openConn1); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 2u); + for (auto it = result.begin(); it != result.end(); ++it) + { + ASSERT_TRUE(*it == locator || *it == locator2); + } + + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + + //Shrink two WAN Adresses ( different than mine ) With different LAN Address and same Logical Port and same Physical Port and return both. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, "88.88.88.90"); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 192, 168, 0, 2); + IPLocator::setWan(locator2, "88.88.88.90"); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + IPLocator::setIPv4(openConn1, "88.88.88.90"); + transportUnderTest.OpenOutputChannel(openConn1); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 2u); + for (auto it = result.begin(); it != result.end(); ++it) + { + ASSERT_TRUE(*it == locator || *it == locator2); + } + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + + //Shrink two WAN Adresses ( different than mine ) With same LAN Address and same Logical Port and same Physical Port and return only one. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, "88.88.88.90"); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 192, 168, 0, 1); + IPLocator::setWan(locator2, "88.88.88.90"); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + IPLocator::setIPv4(openConn1, "88.88.88.90"); + transportUnderTest.OpenOutputChannel(openConn1); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 1u); + ASSERT_TRUE(*result.begin() == locator); + + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + + //Shrink two WAN Adresses ( different than mine ) With same LAN Address and different Logical Port and same Physical Port and return both. + locator.kind = LOCATOR_KIND_TCPv4; + locator.port = g_default_port; + IPLocator::setIPv4(locator, 192, 168, 0, 1); + IPLocator::setWan(locator, "88.88.88.90"); + IPLocator::setLogicalPort(locator, 3333); + list1.push_back(locator); + locator2.kind = LOCATOR_KIND_TCPv4; + locator2.port = g_default_port; + IPLocator::setIPv4(locator2, 192, 168, 0, 1); + IPLocator::setWan(locator2, "88.88.88.90"); + IPLocator::setLogicalPort(locator2, 4444); + list1.push_back(locator2); + + // Open connections (fake) + openConn1.port = g_default_port; + IPLocator::setIPv4(openConn1, "88.88.88.90"); + transportUnderTest.OpenOutputChannel(openConn1); + + result = transportUnderTest.ShrinkLocatorLists({ list1 }); + ASSERT_EQ(result.size(), 2u); + for (auto it = result.begin(); it != result.end(); ++it) + { + ASSERT_TRUE(*it == locator || *it == locator2); + } + + list1.clear(); + transportUnderTest.CloseOutputChannel(openConn1); + } void TCPv4Tests::HELPER_SetDescriptorDefaults() { descriptor.add_listener_port(g_default_port); + descriptor.set_WAN_address(g_test_wan_address); } int main(int argc, char **argv) diff --git a/test/unittest/transport/mock/MockTCPv4Transport.h b/test/unittest/transport/mock/MockTCPv4Transport.h new file mode 100644 index 00000000000..e30eb53e1df --- /dev/null +++ b/test/unittest/transport/mock/MockTCPv4Transport.h @@ -0,0 +1,59 @@ +// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MOCK_TRANSPORT_TCP4_STUFF_H +#define MOCK_TRANSPORT_TCP4_STUFF_H + +#include +#include + +namespace eprosima{ +namespace fastrtps{ +namespace rtps{ + +class MockTCPv4Transport : public TCPv4Transport +{ + public: + + MockTCPv4Transport(const TCPv4TransportDescriptor& descriptor) + { + mConfiguration_ = descriptor; + } + + virtual bool OpenOutputChannel(const Locator_t& locator) override + { + const Locator_t& physicalLocator = IPLocator::toPhysicalLocator(locator); + TCPChannelResource *channel = new TCPChannelResource(this, nullptr, mService, physicalLocator, 0); + mChannelResources[physicalLocator] = channel; + return true; + } + + virtual bool CloseOutputChannel(const Locator_t& locator) override + { + const Locator_t& physicalLocator = IPLocator::toPhysicalLocator(locator); + auto it = mChannelResources.find(physicalLocator); + if (it != mChannelResources.end()) + { + delete it->second; + mChannelResources.erase(it); + } + return true; + } +}; + +} // namespace rtps +} // namespace fastrtps +} // namespace eprosima + +#endif //MOCK_TRANSPORT_TCP4_STUFF_H \ No newline at end of file From 7e280ae1c7598b2e98a63cd47c3c0d72588ca227 Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Tue, 22 Jan 2019 16:35:42 +0100 Subject: [PATCH 13/34] Refs #4415 Fix small issue with the XML Parser (#385) --- src/cpp/xmlparser/XMLElementParser.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index c7aa4bc47b9..47e6068a395 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -1743,13 +1743,15 @@ XMLP_ret XMLParser::getXMLLocatorTCPv4(tinyxml2::XMLElement* elem, rtps::Locator name = p_aux0->Name(); if (strcmp(name, PORT) == 0) { - // port - uint32Type - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + // port - uint16Type + uint16_t port(0); + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) return XMLP_ret::XML_ERROR; + IPLocator::setLogicalPort(locator, port); } else if (strcmp(name, PHYSICAL_PORT) == 0) { - // port - uint32Type + // physical_port - uint16Type uint16_t port(0); if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) return XMLP_ret::XML_ERROR; @@ -1808,13 +1810,15 @@ XMLP_ret XMLParser::getXMLLocatorTCPv6(tinyxml2::XMLElement* elem, rtps::Locator name = p_aux0->Name(); if (strcmp(name, PORT) == 0) { - // port - uint32Type - if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &locator.port, ident + 1)) + // port - uint16Type + uint16_t port(0); + if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) return XMLP_ret::XML_ERROR; + IPLocator::setLogicalPort(locator, port); } else if (strcmp(name, PHYSICAL_PORT) == 0) { - // port - uint32Type + // physical_port - uint16Type uint16_t port(0); if (XMLP_ret::XML_OK != getXMLUint(p_aux0, &port, ident + 1)) return XMLP_ret::XML_ERROR; From 559d7e12800cdad23db7eedbbcc390a60203bdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Wed, 23 Jan 2019 14:01:08 +0100 Subject: [PATCH 14/34] Fix compilation error on windows with external tinyxml2 [4430] (#388) * Refs #4403. Fixed error in windows with external tinyxml2. * Refs #4403. Fixed error with gradle. --- fastrtpsgen/build.gradle | 2 +- test/unittest/dynamic_types/CMakeLists.txt | 32 +++++++++++++--------- test/unittest/logging/CMakeLists.txt | 2 +- test/unittest/xmlparser/CMakeLists.txt | 4 +-- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/fastrtpsgen/build.gradle b/fastrtpsgen/build.gradle index 18dc6465d1b..25aa367f39c 100644 --- a/fastrtpsgen/build.gradle +++ b/fastrtpsgen/build.gradle @@ -73,7 +73,7 @@ jar { } } -compileJava.dependsOn buildIDLParser +compileJava.dependsOn buildIDLParser,copyResources compileJava { sourceCompatibility = 1.6 targetCompatibility = 1.6 diff --git a/test/unittest/dynamic_types/CMakeLists.txt b/test/unittest/dynamic_types/CMakeLists.txt index 38f338b9d0a..a073011cc25 100644 --- a/test/unittest/dynamic_types/CMakeLists.txt +++ b/test/unittest/dynamic_types/CMakeLists.txt @@ -56,6 +56,13 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/log/FileConsumer.cpp ) + # External sources + if(TINYXML2_SOURCE_DIR) + list(APPEND DYNAMIC_TYPES_SOURCE + ${TINYXML2_SOURCE_DIR}/tinyxml2.cpp + ) + endif() + set(DYNAMIC_TYPES_TEST_SOURCE DynamicTypesTests.cpp idl/Basic.cxx @@ -72,7 +79,6 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/qos/WriterQos.cpp ${PROJECT_SOURCE_DIR}/src/cpp/qos/ReaderQos.cpp ${PROJECT_SOURCE_DIR}/src/cpp/rtps/flowcontrol/ThroughputControllerDescriptor.cpp - ${TINYXML2_SOURCE_DIR}/tinyxml2.cpp ) set(DYNAMIC_COMPLEX_TYPES_TEST_SOURCE @@ -97,12 +103,12 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${TINYXML2_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include ) - target_link_libraries(DynamicTypesTests ${GTEST_LIBRARIES} ${MOCKS}) - if(MSVC OR MSVC_IDE) - target_link_libraries(DynamicTypesTests ${PRIVACY} fastcdr iphlpapi Shlwapi ws2_32) - else() - target_link_libraries(DynamicTypesTests ${PRIVACY} fastcdr) - endif() + target_link_libraries(DynamicTypesTests ${GTEST_LIBRARIES} + $<$:iphlpapi$Shlwapi> + $<$:ws2_32> + ${TINYXML2_LIBRARY} + fastcdr + ) add_gtest(DynamicTypesTests SOURCES ${DYNAMIC_TYPES_TEST_SOURCE}) @@ -111,12 +117,12 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) target_include_directories(DynamicComplexTypesTests PRIVATE ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) - target_link_libraries(DynamicComplexTypesTests ${GTEST_LIBRARIES} ${MOCKS}) - if(MSVC OR MSVC_IDE) - target_link_libraries(DynamicComplexTypesTests ${PRIVACY} fastcdr iphlpapi Shlwapi ws2_32) - else() - target_link_libraries(DynamicComplexTypesTests ${PRIVACY} fastcdr) - endif() + target_link_libraries(DynamicComplexTypesTests ${GTEST_LIBRARIES} + $<$:iphlpapi$Shlwapi> + $<$:ws2_32> + ${TINYXML2_LIBRARY} + fastcdr + ) add_gtest(DynamicComplexTypesTests SOURCES ${DYNAMIC_COMPLEX_TYPES_TEST_SOURCE}) endif() diff --git a/test/unittest/logging/CMakeLists.txt b/test/unittest/logging/CMakeLists.txt index 76f4930e1e4..465973ad0d4 100644 --- a/test/unittest/logging/CMakeLists.txt +++ b/test/unittest/logging/CMakeLists.txt @@ -65,7 +65,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) target_link_libraries(LogFileTests ${GTEST_LIBRARIES} ${MOCKS} $<$:iphlpapi$Shlwapi> - $<$:${TINYXML2_LIBRARY}> + ${TINYXML2_LIBRARY} fastcdr ) diff --git a/test/unittest/xmlparser/CMakeLists.txt b/test/unittest/xmlparser/CMakeLists.txt index 30062edb4d5..1424442373a 100644 --- a/test/unittest/xmlparser/CMakeLists.txt +++ b/test/unittest/xmlparser/CMakeLists.txt @@ -105,7 +105,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) target_link_libraries(XMLProfileParserTests ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} $<$:iphlpapi$Shlwapi> $<$:ws2_32> - $<$:${TINYXML2_LIBRARY}> + ${TINYXML2_LIBRARY} fastcdr ) add_gtest(XMLProfileParserTests SOURCES XMLProfileParserTests.cpp) @@ -177,7 +177,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) target_link_libraries(XMLParserTests ${GTEST_LIBRARIES} $<$:iphlpapi$Shlwapi> $<$:ws2_32> - $<$:${TINYXML2_LIBRARY}> + ${TINYXML2_LIBRARY} fastcdr ) add_gtest(XMLParserTests SOURCES XMLParserTests.cpp) From 92386bdaaa3852e7966e29819cde329a8a9babcb Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Thu, 24 Jan 2019 15:38:53 +0100 Subject: [PATCH 15/34] Hotfix/udp closing with whitelist [4427] (#387) * Refs #4276 Added blackbox tests to test discovery using only multicast. * Refs #4420 Added thread to retry closing input channels. * Refs #4420 Removed thread and disabling all related channels before releasing them. * Refs #4420 Avoiding access already closed endpoints on Windows. * Refs #4420 Improved comments. --- .../transport/UDPTransportInterface.h | 2 +- src/cpp/transport/UDPTransportInterface.cpp | 55 ++++++--- test/blackbox/BlackboxTests.cpp | 109 ++++++++++++++++++ test/blackbox/PubSubReader.hpp | 46 ++++++++ test/blackbox/PubSubWriter.hpp | 46 ++++++++ 5 files changed, 238 insertions(+), 20 deletions(-) diff --git a/include/fastrtps/transport/UDPTransportInterface.h b/include/fastrtps/transport/UDPTransportInterface.h index 6406000dd90..7d4d9435bba 100644 --- a/include/fastrtps/transport/UDPTransportInterface.h +++ b/include/fastrtps/transport/UDPTransportInterface.h @@ -80,7 +80,7 @@ class UDPTransportInterface : public TransportInterface uint32_t receiveBufferCapacity, uint32_t& receiveBufferSize, Locator_t& remoteLocator); //! Release the listening socket for the specified port. - bool ReleaseInputChannel(const Locator_t& locator, UDPChannelResource* channel); + bool ReleaseInputChannel(const Locator_t& locator, const asio::ip::address& interface_address); /** * Converts a given remote locator (that is, a locator referring to a remote diff --git a/src/cpp/transport/UDPTransportInterface.cpp b/src/cpp/transport/UDPTransportInterface.cpp index fbaf208a0e2..fa96c2d9b31 100644 --- a/src/cpp/transport/UDPTransportInterface.cpp +++ b/src/cpp/transport/UDPTransportInterface.cpp @@ -71,23 +71,42 @@ void UDPTransportInterface::Clean() bool UDPTransportInterface::CloseInputChannel(const Locator_t& locator) { - std::vector pChannelResources; + std::vector channel_resources; { std::unique_lock scopedLock(mInputMapMutex); if (!IsInputChannelOpen(locator)) return false; - pChannelResources = std::move(mInputSockets.at(IPLocator::getPhysicalPort(locator))); + channel_resources = std::move(mInputSockets.at(IPLocator::getPhysicalPort(locator))); mInputSockets.erase(IPLocator::getPhysicalPort(locator)); } - for (auto* channelResource : pChannelResources) + std::map addresses; + // It may sound redundant, but we must mark all the related channel to be killed first. + // Mostly in Windows, but in Linux can happen too, if we access to the endpoint + // of an already closed socket we get an exception. So we store the interface address to + // be used in the ReleaseInputChannel call later. + for (UDPChannelResource* channel_resource : channel_resources) { - ReleaseInputChannel(locator, channelResource); - channelResource->getSocket()->cancel(); - channelResource->getSocket()->close(); - delete channelResource; + if (channel_resource->IsAlive()) + { + addresses[channel_resource] = channel_resource->getSocket()->local_endpoint().address(); + } + else + { + addresses[channel_resource] = asio::ip::address(); + } + channel_resource->Disable(); + } + + // Then we release the channels + for (UDPChannelResource* channel : channel_resources) + { + ReleaseInputChannel(locator, addresses[channel]); + channel->getSocket()->cancel(); + channel->getSocket()->close(); + delete channel; } return true; @@ -210,7 +229,7 @@ bool UDPTransportInterface::OpenAndBindInputSockets(const Locator_t& locator, Tr std::vector vInterfaces = GetBindingInterfacesList(); for (std::string sInterface : vInterfaces) { - UDPChannelResource* pChannelResource; + UDPChannelResource* pChannelResource; pChannelResource = CreateInputChannelResource(sInterface, locator, is_multicast, maxMsgSize, receiver); mInputSockets[IPLocator::getPhysicalPort(locator)].push_back(pChannelResource); } @@ -227,7 +246,7 @@ bool UDPTransportInterface::OpenAndBindInputSockets(const Locator_t& locator, Tr return true; } -UDPChannelResource* UDPTransportInterface::CreateInputChannelResource(const std::string& sInterface, const Locator_t& locator, +UDPChannelResource* UDPTransportInterface::CreateInputChannelResource(const std::string& sInterface, const Locator_t& locator, bool is_multicast, uint32_t maxMsgSize, TransportReceiverInterface* receiver) { eProsimaUDPSocket unicastSocket = OpenAndBindInputSocket(sInterface, IPLocator::getPhysicalPort(locator), is_multicast); @@ -363,7 +382,9 @@ void UDPTransportInterface::performListenOperation(UDPChannelResource* pChannelR // Blocking receive. auto& msg = pChannelResource->GetMessageBuffer(); if (!Receive(pChannelResource, msg.buffer, msg.max_size, msg.length, remoteLocator)) + { continue; + } // Processes the data through the CDR Message interface. auto receiver = pChannelResource->GetMessageReceiver(); @@ -405,17 +426,10 @@ bool UDPTransportInterface::Receive(UDPChannelResource* pChannelResource, octet* } } -bool UDPTransportInterface::ReleaseInputChannel(const Locator_t& locator, UDPChannelResource* channel) +bool UDPTransportInterface::ReleaseInputChannel(const Locator_t& locator, const asio::ip::address& interface_address) { - if (!channel->IsAlive()) - { - return false; - } - try { - channel->Disable(); - uint16_t port = IPLocator::getPhysicalPort(locator); if(IsInterfaceWhiteListEmpty()) @@ -435,10 +449,11 @@ bool UDPTransportInterface::ReleaseInputChannel(const Locator_t& locator, UDPCha // We then send to the address of the input locator auto destinationEndpoint = GenerateLocalEndpoint(locator, port); socket.send_to(asio::buffer("EPRORTPSCLOSE", 13), destinationEndpoint); + + socket.close(); } else { - auto interface_address = channel->getSocket()->local_endpoint().address(); ip::udp::socket socket(mService); socket.open(GenerateProtocol()); socket.bind(asio::ip::udp::endpoint(interface_address, 0)); @@ -449,11 +464,13 @@ bool UDPTransportInterface::ReleaseInputChannel(const Locator_t& locator, UDPCha // We then send to the address of the input locator auto destinationEndpoint = GenerateLocalEndpoint(locator, port); socket.send_to(asio::buffer("EPRORTPSCLOSE", 13), destinationEndpoint); + + socket.close(); } } catch (const std::exception& error) { - logWarning(RTPS_MSG_OUT, "Error: " << error.what()); + logError(RTPS_MSG_OUT, "Error: " << error.what()); return false; } diff --git a/test/blackbox/BlackboxTests.cpp b/test/blackbox/BlackboxTests.cpp index 0d4e860f575..fdaa8b366bf 100644 --- a/test/blackbox/BlackboxTests.cpp +++ b/test/blackbox/BlackboxTests.cpp @@ -5660,6 +5660,115 @@ BLACKBOXTEST(BlackBox, UDPMaxInitialPeer_P5_6_P4) ASSERT_TRUE(reader.is_matched()); } +// Used to reproduce VPN environment issue with multicast. +BLACKBOXTEST(BlackBox, MulticastCommunicationBadReader) +{ + PubSubWriter writer(TEST_TOPIC_NAME); + + auto transport = std::make_shared(); + std::string ip0("127.0.0.1"); + std::string ip1("239.255.1.4"); + std::string ip2("239.255.1.5"); + + transport->interfaceWhiteList.push_back(ip0); + + writer.disable_builtin_transport().add_user_transport_to_pparams(transport); + writer.add_to_metatraffic_multicast_locator_list(ip2, global_port); + writer.init(); + + ASSERT_TRUE(writer.isInitialized()); + + PubSubReader readerMultiBad(TEST_TOPIC_NAME); + readerMultiBad.disable_builtin_transport().add_user_transport_to_pparams(transport); + readerMultiBad.add_to_metatraffic_multicast_locator_list(ip1, global_port); + readerMultiBad.init(); + + ASSERT_TRUE(readerMultiBad.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(std::chrono::seconds(3)); + readerMultiBad.wait_discovery(std::chrono::seconds(3)); + ASSERT_FALSE(writer.is_matched()); + ASSERT_FALSE(readerMultiBad.is_matched()); +} + +// Used to reproduce VPN environment issue with multicast. +BLACKBOXTEST(BlackBox, MulticastCommunicationOkReader) +{ + PubSubWriter writer(TEST_TOPIC_NAME); + + auto transport = std::make_shared(); + std::string ip0("127.0.0.1"); + std::string ip2("239.255.1.5"); + + transport->interfaceWhiteList.push_back(ip0); + + writer.disable_builtin_transport().add_user_transport_to_pparams(transport); + writer.add_to_metatraffic_multicast_locator_list(ip2, global_port); + writer.init(); + + ASSERT_TRUE(writer.isInitialized()); + + PubSubReader readerMultiOk(TEST_TOPIC_NAME); + readerMultiOk.disable_builtin_transport().add_user_transport_to_pparams(transport); + readerMultiOk.add_to_metatraffic_multicast_locator_list(ip2, global_port); + readerMultiOk.init(); + + ASSERT_TRUE(readerMultiOk.isInitialized()); + + writer.wait_discovery(std::chrono::seconds(3)); + readerMultiOk.wait_discovery(std::chrono::seconds(3)); + ASSERT_TRUE(writer.is_matched()); + ASSERT_TRUE(readerMultiOk.is_matched()); +} + +// #4420 Using whitelists in localhost sometimes UDP doesn't receive the release input channel message. +BLACKBOXTEST(BlackBox, whitelisting_udp_localhost_multi) +{ + PubSubWriter writer(TEST_TOPIC_NAME); + + auto transport = std::make_shared(); + std::string ip0("127.0.0.1"); + + transport->interfaceWhiteList.push_back(ip0); + + writer.disable_builtin_transport().add_user_transport_to_pparams(transport); + writer.init(); + + ASSERT_TRUE(writer.isInitialized()); + + for (int i = 0; i < 200; ++i) + { + PubSubReader readerMultiOk(TEST_TOPIC_NAME); + readerMultiOk.disable_builtin_transport().add_user_transport_to_pparams(transport); + readerMultiOk.init(); + + ASSERT_TRUE(readerMultiOk.isInitialized()); + + writer.wait_discovery(std::chrono::seconds(3)); + readerMultiOk.wait_discovery(std::chrono::seconds(3)); + ASSERT_TRUE(writer.is_matched()); + ASSERT_TRUE(readerMultiOk.is_matched()); + } +} + +// #4420 Using whitelists in localhost sometimes UDP doesn't receive the release input channel message. +BLACKBOXTEST(BlackBox, whitelisting_udp_localhost_alone) +{ + auto transport = std::make_shared(); + std::string ip0("127.0.0.1"); + + transport->interfaceWhiteList.push_back(ip0); + + for (int i = 0; i < 200; ++i) + { + PubSubWriter writer(TEST_TOPIC_NAME); + writer.disable_builtin_transport().add_user_transport_to_pparams(transport); + writer.init(); + ASSERT_TRUE(writer.isInitialized()); + } +} + int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index c14d66864c8..165d2929304 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -403,18 +403,64 @@ class PubSubReader return *this; } + PubSubReader& add_to_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + subscriber_attr_.unicastLocatorList.push_back(loc); + + return *this; + } + PubSubReader& multicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t multicastLocators) { subscriber_attr_.multicastLocatorList = multicastLocators; return *this; } + PubSubReader& add_to_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + subscriber_attr_.multicastLocatorList.push_back(loc); + + return *this; + } + PubSubReader& metatraffic_unicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) { participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = unicastLocators; return *this; } + PubSubReader& add_to_metatraffic_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficUnicastLocatorList.push_back(loc); + + return *this; + } + + PubSubReader& metatraffic_multicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + { + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList = unicastLocators; + return *this; + } + + PubSubReader& add_to_metatraffic_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList.push_back(loc); + + return *this; + } + PubSubReader& initial_peers(eprosima::fastrtps::rtps::LocatorList_t initial_peers) { participant_attr_.rtps.builtin.initialPeersList = initial_peers; diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index 3aecf413a6d..69eac608210 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -446,18 +446,64 @@ class PubSubWriter return *this; } + PubSubWriter& add_to_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + publisher_attr_.unicastLocatorList.push_back(loc); + + return *this; + } + PubSubWriter& multicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t multicastLocators) { publisher_attr_.multicastLocatorList = multicastLocators; return *this; } + PubSubWriter& add_to_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + publisher_attr_.multicastLocatorList.push_back(loc); + + return *this; + } + PubSubWriter& metatraffic_unicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) { participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = unicastLocators; return *this; } + PubSubWriter& add_to_metatraffic_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficUnicastLocatorList.push_back(loc); + + return *this; + } + + PubSubWriter& metatraffic_multicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + { + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList = unicastLocators; + return *this; + } + + PubSubWriter& add_to_metatraffic_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList.push_back(loc); + + return *this; + } + PubSubWriter& initial_peers(eprosima::fastrtps::rtps::LocatorList_t initial_peers) { participant_attr_.rtps.builtin.initialPeersList = initial_peers; From c77124a9e53c63bb81ebea4b9e3747b4aa7cb9d1 Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Thu, 24 Jan 2019 16:15:42 +0100 Subject: [PATCH 16/34] Fixed xml liveliness assertion (#389) --- test/communication/liveliness_assertion.xml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/communication/liveliness_assertion.xml b/test/communication/liveliness_assertion.xml index 825bc918608..ed80c8e2e0e 100644 --- a/test/communication/liveliness_assertion.xml +++ b/test/communication/liveliness_assertion.xml @@ -5,14 +5,10 @@ - - 3 - + 3 - - 1 - + 1 From a8ae680752f971a2195ffbde28ed9e9eb8c0fdfd Mon Sep 17 00:00:00 2001 From: Juan Carlos <40226503+JuanCarlos-eProsima@users.noreply.github.com> Date: Tue, 29 Jan 2019 09:53:26 +0100 Subject: [PATCH 17/34] Improve reports of performance tests [4454] (#391) * Refs #4422 Update the video test to write an auxiliar file only with the mean of the test ( For Jenkins ) * Refs #4422 Update the memory test to set the name of the transport on the output file * Refs #4422 Update the script of the memory tests to add the name of the transport as a suffix * Refs #4422 Update the video test to manage the statistics in a different way if there is only one register --- test/performance/VideoTestSubscriber.cpp | 82 +++++++++++++++++++++--- test/profiling/memory_tests.py | 21 +++--- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/test/performance/VideoTestSubscriber.cpp b/test/performance/VideoTestSubscriber.cpp index 94ad1ba1964..9f8bf1019b5 100644 --- a/test/performance/VideoTestSubscriber.cpp +++ b/test/performance/VideoTestSubscriber.cpp @@ -681,7 +681,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pAvg50 = NAN; + if (avgs_.size() == 1) + { + TS.pAvg50 = *avgs_.begin(); + } + else + { + TS.pAvg50 = NAN; + } } elem = static_cast(avgs_.size() * 0.9); @@ -691,7 +698,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pAvg90 = NAN; + if (avgs_.size() == 1) + { + TS.pAvg90 = *avgs_.begin(); + } + else + { + TS.pAvg90 = NAN; + } } elem = static_cast(avgs_.size() * 0.99); @@ -701,7 +715,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pAvg99 = NAN; + if (avgs_.size() == 1) + { + TS.pAvg99 = *avgs_.begin(); + } + else + { + TS.pAvg99 = NAN; + } } elem = static_cast(avgs_.size() * 0.9999); @@ -711,7 +732,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pAvg9999 = NAN; + if (avgs_.size() == 1) + { + TS.pAvg9999 = *avgs_.begin(); + } + else + { + TS.pAvg9999 = NAN; + } } } } @@ -742,7 +770,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pDrop50 = NAN; + if (drops_.size() == 1) + { + TS.pDrop50 = *drops_.begin(); + } + else + { + TS.pDrop50 = NAN; + } } elem = static_cast(drops_.size() * 0.9); @@ -752,7 +787,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pDrop90 = NAN; + if (drops_.size() == 1) + { + TS.pDrop90 = *drops_.begin(); + } + else + { + TS.pDrop90 = NAN; + } } elem = static_cast(drops_.size() * 0.99); @@ -762,7 +804,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pDrop99 = NAN; + if (drops_.size() == 1) + { + TS.pDrop99 = *drops_.begin(); + } + else + { + TS.pDrop99 = NAN; + } } elem = static_cast(drops_.size() * 0.9999); @@ -772,7 +821,14 @@ void VideoTestSubscriber::analyzeTimes() } else { - TS.pDrop9999 = NAN; + if (drops_.size() == 1) + { + TS.pDrop9999 = *drops_.begin(); + } + else + { + TS.pDrop9999 = NAN; + } } } } @@ -785,7 +841,9 @@ void VideoTestSubscriber::analyzeTimes() void VideoTestSubscriber::printStat(TimeStats& TS) { std::ofstream outFile; + std::ofstream outMeanFile; std::stringstream output_file_csv; + std::stringstream output_mean_csv; std::string str_reliable = "besteffort"; if (m_bReliable) { @@ -796,6 +854,8 @@ void VideoTestSubscriber::printStat(TimeStats& TS) Avg 99.99%%, Avg max, Drop stdev, Drop Mean, min Drop, Drop 50 %%, Drop 90 %%, Drop 99 %%, \ Drop 99.99%%, Drop max" << std::endl; + output_mean_csv << "Avg Mean" << std::endl; + printf("Statistics for video test \n"); printf(" Samples, Avg stdev, Avg Mean, min Avg, Avg 50%%, Avg 90%%, Avg 99%%, Avg 99.99%%, Avg max\n"); printf("-----------,-----------,-----------,-----------,-----------,-----------,-----------,-------------,-----------\n"); @@ -807,16 +867,20 @@ void VideoTestSubscriber::printStat(TimeStats& TS) printf("%11u,%15.2f,%14.2f,%13.2f,%14.2f,%14.2f,%14.2f,%16.2f,%14.2f \n", TS.received, TS.pDropStdev, TS.pDropMean, TS.m_minDrop, TS.pDrop50, TS.pDrop90, TS.pDrop99, TS.pDrop9999, TS.m_maxDrop); - output_file_csv << TS.received << "," << TS.pAvgStdev << "," << TS.pAvgMean << "," << TS.m_minAvg << + output_file_csv << TS.received << "," << TS.pAvgStdev << "," << TS.pAvgMean << "," << TS.m_minAvg << "," << TS.pAvg50 << "," << TS.pAvg90 << "," << TS.pAvg99 << "," << TS.pAvg9999 << "," << TS.m_maxAvg << "," << TS.pDropStdev << "," << TS.pDropMean << "," << TS.m_minDrop << "," << TS.pDrop50 << "," << TS.pDrop90 << "," << TS.pDrop99 << "," << TS.pDrop9999 << "," << TS.m_maxDrop << "," << std::endl; + output_mean_csv << TS.pAvgMean << "," << std::endl; + if (m_bExportCsv) { if (m_sExportPrefix.length() > 0) { outFile.open(m_sExportPrefix + ".csv"); + outMeanFile.open(m_sExportPrefix + "_Mean.csv"); + outMeanFile << output_mean_csv.str(); } else { diff --git a/test/profiling/memory_tests.py b/test/profiling/memory_tests.py index 13ae4ac7180..5d49728b913 100644 --- a/test/profiling/memory_tests.py +++ b/test/profiling/memory_tests.py @@ -24,11 +24,11 @@ if not valgrind: valgrind = "valgrind" -def start_test(command, pubsub, time): +def start_test(command, pubsub, time, transport): os.system("mkdir -p output") - valgrind_command_rel = [valgrind, "--tool=massif", "--stacks=yes", "--detailed-freq=1", "--max-snapshots=1000", "--massif-out-file=./output/consumption_" + pubsub + "_rel.out"] - valgrind_command_be = [valgrind, "--tool=massif", "--stacks=yes", "--detailed-freq=1", "--max-snapshots=1000", "--massif-out-file=./output/consumption_" + pubsub + "_be.out"] + valgrind_command_rel = [valgrind, "--tool=massif", "--stacks=yes", "--detailed-freq=1", "--max-snapshots=1000", "--massif-out-file=./output/consumption_" + pubsub + "_" + transport + "_rel.out"] + valgrind_command_be = [valgrind, "--tool=massif", "--stacks=yes", "--detailed-freq=1", "--max-snapshots=1000", "--massif-out-file=./output/consumption_" + pubsub + "_" + transport + "_be.out"] options = ["--time=" + time] @@ -45,7 +45,7 @@ def start_test(command, pubsub, time): proc.communicate() - py_command = "python3 ./memory_analysis.py ./output/consumption_" + pubsub + "_be.out ./output/MemoryTest_" + pubsub + "_be.csv" + py_command = "python3 ./memory_analysis.py ./output/consumption_" + pubsub + "_" + transport + "_be.out ./output/MemoryTest_" + pubsub + "_" + transport + "_be.csv" p = subprocess.Popen(py_command, shell=True) # Reliable @@ -55,10 +55,15 @@ def start_test(command, pubsub, time): proc.communicate() - py_command = "python3 ./memory_analysis.py ./output/consumption_" + pubsub + "_rel.out ./output/MemoryTest_" + pubsub + "_rel.csv" + py_command = "python3 ./memory_analysis.py ./output/consumption_" + pubsub + "_" + transport + "_rel.out ./output/MemoryTest_" + pubsub + "_" + transport + "_rel.csv" # print("Command: " + py_command) p = subprocess.Popen(py_command, shell=True) +transport = "" + +if len(sys.argv) >= 5: + transport = sys.argv[4] + if len(sys.argv) >= 4: test_time = sys.argv[3] @@ -68,11 +73,11 @@ def start_test(command, pubsub, time): for command in binaries: if len(sys.argv) >= 2: pubsub = sys.argv[1] - start_test(command, pubsub, test_time) + start_test(command, pubsub, test_time, transport) else: - tpub = threading.Thread(target=start_test, args=(command, "publisher", test_time)) + tpub = threading.Thread(target=start_test, args=(command, "publisher", test_time, transport)) tpub.start() - tsub = threading.Thread(target=start_test, args=(command, "subscriber", test_time)) + tsub = threading.Thread(target=start_test, args=(command, "subscriber", test_time, transport)) tsub.start() quit() From f6ebf154a97089136c4906de11f535969708f2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Berm=C3=BAdez=20Ortega?= <34604561+julianbermudez@users.noreply.github.com> Date: Tue, 29 Jan 2019 11:50:05 +0100 Subject: [PATCH 18/34] Add const qualifier [4397] (#381) * Refs #4372. Add const qualifier to Attributes in createSubscriber and createPublisher. * Refs #4372. Add const qualifier to Attributes in createParticipant. * Refs #4372. Modify changes to new style. * Refs #4372. Modify code style in ParticipantImpl. * Refs #4372. Modify member initializer list to new code style. --- include/fastrtps/Domain.h | 54 ++++++++++++------- include/fastrtps/publisher/PublisherHistory.h | 8 ++- include/fastrtps/rtps/RTPSDomain.h | 18 +++++-- include/fastrtps/rtps/common/Locator.h | 10 ++-- .../fastrtps/subscriber/SubscriberHistory.h | 13 +++-- src/cpp/Domain.cpp | 50 ++++++++++++----- src/cpp/participant/ParticipantImpl.cpp | 49 +++++++++++------ src/cpp/participant/ParticipantImpl.h | 31 +++++++---- src/cpp/publisher/PublisherHistory.cpp | 18 ++++--- src/cpp/publisher/PublisherImpl.cpp | 46 ++++++++++------ src/cpp/publisher/PublisherImpl.h | 16 ++++-- src/cpp/rtps/RTPSDomain.cpp | 36 ++++++++----- src/cpp/subscriber/SubscriberHistory.cpp | 27 ++++++---- src/cpp/subscriber/SubscriberImpl.cpp | 25 +++++---- src/cpp/subscriber/SubscriberImpl.h | 8 ++- 15 files changed, 273 insertions(+), 136 deletions(-) diff --git a/include/fastrtps/Domain.h b/include/fastrtps/Domain.h index 012cf89602e..b3b9066c450 100644 --- a/include/fastrtps/Domain.h +++ b/include/fastrtps/Domain.h @@ -59,16 +59,18 @@ class Domain * @param listen ParticipantListener Pointer. * @return Participant pointer. (nullptr if not created.) */ - RTPS_DllAPI static Participant* createParticipant(const std::string &participant_profile, - ParticipantListener *listen = nullptr); + RTPS_DllAPI static Participant* createParticipant( + const std::string& participant_profile, + ParticipantListener* listen = nullptr); /** * Create a Participant. * @param att Participant Attributes. * @param listen ParticipantListener Pointer. * @return Participant pointer. (nullptr if not created.) */ - RTPS_DllAPI static Participant* createParticipant(ParticipantAttributes &att, - ParticipantListener *listen = nullptr); + RTPS_DllAPI static Participant* createParticipant( + const ParticipantAttributes& att, + ParticipantListener* listen = nullptr); RTPS_DllAPI static void getDefaultParticipantAttributes(ParticipantAttributes& participant_attributes); @@ -79,9 +81,10 @@ class Domain * @param listen Pointer to the PublisherListener. * @return Pointer to the created Publisher (nullptr if not created). */ - RTPS_DllAPI static Publisher* createPublisher(Participant *part, - const std::string &publisher_profile, - PublisherListener *listen = nullptr); + RTPS_DllAPI static Publisher* createPublisher( + Participant* part, + const std::string& publisher_profile, + PublisherListener* listen = nullptr); /** * Create a Publisher in a Participant. @@ -90,9 +93,10 @@ class Domain * @param listen Pointer to the PublisherListener. * @return Pointer to the created Publisher (nullptr if not created). */ - RTPS_DllAPI static Publisher* createPublisher(Participant *part, - PublisherAttributes &att, - PublisherListener *listen = nullptr); + RTPS_DllAPI static Publisher* createPublisher( + Participant* part, + const PublisherAttributes& att, + PublisherListener* listen = nullptr); RTPS_DllAPI static void getDefaultPublisherAttributes(PublisherAttributes& publisher_attributes); @@ -103,9 +107,11 @@ class Domain * @param listen Pointer to the SubscriberListener. * @return Pointer to the created Subscriber (nullptr if not created). */ - RTPS_DllAPI static Subscriber* createSubscriber(Participant *part, - const std::string &subscriber_profile, - SubscriberListener *listen = nullptr); + RTPS_DllAPI static Subscriber* createSubscriber( + Participant* part, + const std::string& subscriber_profile, + SubscriberListener* listen = nullptr); + /** * Create a Subscriber in a Participant. * @param part Pointer to the participant where you want to create the Publisher. @@ -113,9 +119,10 @@ class Domain * @param listen Pointer to the SubscriberListener. * @return Pointer to the created Subscriber (nullptr if not created). */ - RTPS_DllAPI static Subscriber* createSubscriber(Participant *part, - SubscriberAttributes &att, - SubscriberListener *listen = nullptr); + RTPS_DllAPI static Subscriber* createSubscriber( + Participant* part, + const SubscriberAttributes& att, + SubscriberListener* listen = nullptr); RTPS_DllAPI static void getDefaultSubscriberAttributes(SubscriberAttributes& subscriber_attributes); @@ -145,7 +152,10 @@ class Domain * @param type Returned type. * @return True if type was found. */ - RTPS_DllAPI static bool getRegisteredType(Participant* part, const char* typeName, TopicDataType** type); + RTPS_DllAPI static bool getRegisteredType( + Participant* part, + const char* typeName, + TopicDataType** type); /** * Register a type in a participant. @@ -161,7 +171,9 @@ class Domain * @param type Pointer to the Type. * @return True if correctly registered. */ - RTPS_DllAPI static bool registerDynamicType(Participant* part, types::DynamicPubSubType* type); + RTPS_DllAPI static bool registerDynamicType( + Participant* part, + types::DynamicPubSubType* type); /** * Unregister a type in a participant. @@ -169,7 +181,9 @@ class Domain * @param typeName Name of the type. * @return True if correctly unregistered. */ - RTPS_DllAPI static bool unregisterType(Participant* part, const char* typeName); + RTPS_DllAPI static bool unregisterType( + Participant* part, + const char* typeName); /** * Stop and remove all participants, publishers and subscribers in this Domain. @@ -181,7 +195,7 @@ class Domain * @param xml_profile_file XML profile file. * @return True if correctly loaded. */ - RTPS_DllAPI static bool loadXMLProfilesFile(const std::string &xml_profile_file); + RTPS_DllAPI static bool loadXMLProfilesFile(const std::string& xml_profile_file); private: diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index af471650421..a541809e793 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -51,8 +51,12 @@ class PublisherHistory:public rtps::WriterHistory * @param history QOS of the associated History. * @param resource ResourceLimits for the History. */ - PublisherHistory(PublisherImpl* pimpl,uint32_t payloadMax, - HistoryQosPolicy& history,ResourceLimitsQosPolicy& resource, rtps::MemoryManagementPolicy_t mempolicy); + PublisherHistory( + PublisherImpl* pimpl, + uint32_t payloadMax, + const HistoryQosPolicy& history, + const ResourceLimitsQosPolicy& resource, + rtps::MemoryManagementPolicy_t mempolicy); virtual ~PublisherHistory(); diff --git a/include/fastrtps/rtps/RTPSDomain.h b/include/fastrtps/rtps/RTPSDomain.h index 3f1dab1d89f..c2aa5913b0e 100644 --- a/include/fastrtps/rtps/RTPSDomain.h +++ b/include/fastrtps/rtps/RTPSDomain.h @@ -79,7 +79,9 @@ class RTPSDomain * @param plisten Pointer to the ParticipantListener. * @return Pointer to the RTPSParticipant. */ - RTPS_DllAPI static RTPSParticipant* createParticipant(RTPSParticipantAttributes& PParam, RTPSParticipantListener* plisten = nullptr); + RTPS_DllAPI static RTPSParticipant* createParticipant( + const RTPSParticipantAttributes& attrs, + RTPSParticipantListener* plisten = nullptr); /** * Create a RTPSWriter in a participant. @@ -89,7 +91,12 @@ class RTPSDomain * @param listen Pointer to the WriterListener. * @return Pointer to the created RTPSWriter. */ - RTPS_DllAPI static RTPSWriter* createRTPSWriter(RTPSParticipant* p, WriterAttributes& watt, WriterHistory* hist, WriterListener* listen = nullptr); + RTPS_DllAPI static RTPSWriter* createRTPSWriter( + RTPSParticipant* p, + WriterAttributes& watt, + WriterHistory* hist, + WriterListener* listen = nullptr); + /** * Remove a RTPSWriter. * @param writer Pointer to the writer you want to remove. @@ -105,7 +112,12 @@ class RTPSDomain * @param listen Pointer to the ReaderListener. * @return Pointer to the created RTPSReader. */ - RTPS_DllAPI static RTPSReader* createRTPSReader(RTPSParticipant* p, ReaderAttributes& ratt, ReaderHistory* hist, ReaderListener* listen = nullptr); + RTPS_DllAPI static RTPSReader* createRTPSReader( + RTPSParticipant* p, + ReaderAttributes& ratt, + ReaderHistory* hist, + ReaderListener* listen = nullptr); + /** * Remove a RTPSReader. * @param reader Pointer to the reader you want to remove. diff --git a/include/fastrtps/rtps/common/Locator.h b/include/fastrtps/rtps/common/Locator.h index 835b7a05a51..f3d4d3b006b 100644 --- a/include/fastrtps/rtps/common/Locator.h +++ b/include/fastrtps/rtps/common/Locator.h @@ -149,9 +149,7 @@ inline bool IsAddressDefined(const Locator_t& loc) inline bool IsLocatorValid(const Locator_t&loc) { - if (loc.kind < 0) - return false; - return true; + return (0 <= loc.kind); } inline bool operator<(const Locator_t &loc1, const Locator_t &loc2) @@ -306,7 +304,7 @@ class LocatorList_t } } - RTPS_DllAPI bool empty() { + RTPS_DllAPI bool empty() const { return m_locators.empty(); } @@ -338,9 +336,9 @@ class LocatorList_t return false; } - RTPS_DllAPI bool isValid() + RTPS_DllAPI bool isValid() const { - for (LocatorListIterator it = this->begin(); it != this->end(); ++it) + for (LocatorListConstIterator it = this->begin(); it != this->end(); ++it) { if (!IsLocatorValid(*it)) return false; diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 2c8480c2153..a6ad6cc8c75 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -56,8 +56,13 @@ class SubscriberHistory: public rtps::ReaderHistory * @param history History QoS policy for the reader * @param resource Resource Limit QoS policy for the reader */ - SubscriberHistory(SubscriberImpl* pimpl,uint32_t payloadMax, - HistoryQosPolicy& history,ResourceLimitsQosPolicy& resource, rtps::MemoryManagementPolicy_t mempolicy); + SubscriberHistory( + SubscriberImpl* pimpl, + uint32_t payloadMax, + const HistoryQosPolicy& history, + const ResourceLimitsQosPolicy& resource, + rtps::MemoryManagementPolicy_t mempolicy); + virtual ~SubscriberHistory(); /** @@ -67,7 +72,9 @@ class SubscriberHistory: public rtps::ReaderHistory * @param unknown_missing_changes_up_to Number of missing changes before this one * @return */ - bool received_change(rtps::CacheChange_t* change, size_t unknown_missing_changes_up_to); + bool received_change( + rtps::CacheChange_t* change, + size_t unknown_missing_changes_up_to); /** @name Read or take data methods. * Methods to read or take data from the History. diff --git a/src/cpp/Domain.cpp b/src/cpp/Domain.cpp index d406bbc666c..3c85d64c87d 100644 --- a/src/cpp/Domain.cpp +++ b/src/cpp/Domain.cpp @@ -53,7 +53,6 @@ bool Domain::default_xml_profiles_loaded = false; Domain::Domain() { // TODO Auto-generated constructor stub - } Domain::~Domain() @@ -138,7 +137,9 @@ bool Domain::removeSubscriber(Subscriber* sub) return false; } -Participant* Domain::createParticipant(const std::string &participant_profile, ParticipantListener* listen) +Participant* Domain::createParticipant( + const std::string& participant_profile, + ParticipantListener* listen) { if (false == default_xml_profiles_loaded) { @@ -156,11 +157,13 @@ Participant* Domain::createParticipant(const std::string &participant_profile, P return createParticipant(participant_att, listen); } -Participant* Domain::createParticipant(ParticipantAttributes& att,ParticipantListener* listen) +Participant* Domain::createParticipant( + const eprosima::fastrtps::ParticipantAttributes& att, + ParticipantListener* listen) { Participant* pubsubpar = new Participant(); ParticipantImpl* pspartimpl = new ParticipantImpl(att,pubsubpar,listen); - RTPSParticipant* part = RTPSDomain::createParticipant(att.rtps,&pspartimpl->m_rtps_listener); + RTPSParticipant* part = RTPSDomain::createParticipant(att.rtps, &pspartimpl->m_rtps_listener); if(part == nullptr) { @@ -192,7 +195,10 @@ void Domain::getDefaultParticipantAttributes(ParticipantAttributes& participant_ return XMLProfileManager::getDefaultParticipantAttributes(participant_attributes); } -Publisher* Domain::createPublisher(Participant *part, const std::string &publisher_profile, PublisherListener *listen) +Publisher* Domain::createPublisher( + Participant* part, + const std::string& publisher_profile, + PublisherListener* listen) { PublisherAttributes publisher_att; if ( XMLP_ret::XML_ERROR == XMLProfileManager::fillPublisherAttributes(publisher_profile, publisher_att)) @@ -204,7 +210,10 @@ Publisher* Domain::createPublisher(Participant *part, const std::string &publish return createPublisher(part, publisher_att, listen); } -Publisher* Domain::createPublisher(Participant *part, PublisherAttributes &att, PublisherListener *listen) +Publisher* Domain::createPublisher( + Participant* part, + const PublisherAttributes& att, + PublisherListener* listen) { std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end(); ++it) @@ -240,7 +249,10 @@ void Domain::getDefaultSubscriberAttributes(SubscriberAttributes& subscriber_att return XMLProfileManager::getDefaultSubscriberAttributes(subscriber_attributes); } -Subscriber* Domain::createSubscriber(Participant *part, const std::string &subscriber_profile, SubscriberListener *listen) +Subscriber* Domain::createSubscriber( + Participant* part, + const std::string& subscriber_profile, + SubscriberListener* listen) { SubscriberAttributes subscriber_att; if ( XMLP_ret::XML_ERROR == XMLProfileManager::fillSubscriberAttributes(subscriber_profile, subscriber_att)) @@ -252,7 +264,10 @@ Subscriber* Domain::createSubscriber(Participant *part, const std::string &subsc return createSubscriber(part, subscriber_att, listen); } -Subscriber* Domain::createSubscriber(Participant *part, SubscriberAttributes &att, SubscriberListener *listen) +Subscriber* Domain::createSubscriber( + Participant* part, + const SubscriberAttributes& att, + SubscriberListener* listen) { std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end(); ++it) @@ -265,7 +280,10 @@ Subscriber* Domain::createSubscriber(Participant *part, SubscriberAttributes &at return nullptr; } -bool Domain::getRegisteredType(Participant* part, const char* typeName, TopicDataType** type) +bool Domain::getRegisteredType( + Participant* part, + const char* typeName, + TopicDataType** type) { std::lock_guard guard(m_mutex); for (auto it = m_participants.begin(); it != m_participants.end();++it) @@ -278,7 +296,9 @@ bool Domain::getRegisteredType(Participant* part, const char* typeName, TopicDat return false; } -bool Domain::registerType(Participant* part, TopicDataType* type) +bool Domain::registerType( + Participant* part, + TopicDataType* type) { std::lock_guard guard(m_mutex); //TODO El registro debería hacerse de manera que no tengamos un objeto del usuario sino que tengamos un objeto TopicDataTYpe propio para que no @@ -293,7 +313,9 @@ bool Domain::registerType(Participant* part, TopicDataType* type) return false; } -bool Domain::registerDynamicType(Participant* part, types::DynamicPubSubType* type) +bool Domain::registerDynamicType( + Participant* part, + types::DynamicPubSubType* type) { using namespace eprosima::fastrtps::types; TypeObjectFactory *typeFactory = TypeObjectFactory::GetInstance(); @@ -333,7 +355,9 @@ bool Domain::registerDynamicType(Participant* part, types::DynamicPubSubType* ty return registerType(part, type); } -bool Domain::unregisterType(Participant* part, const char* typeName) +bool Domain::unregisterType( + Participant* part, + const char* typeName) { //TODO El registro debería hacerse de manera que no tengamos un objeto del usuario sino que tengamos un objeto TopicDataTYpe propio para que no //haya problemas si el usuario lo destruye antes de tiempo. @@ -348,7 +372,7 @@ bool Domain::unregisterType(Participant* part, const char* typeName) return true; } -bool Domain::loadXMLProfilesFile(const std::string &xml_profile_file) +bool Domain::loadXMLProfilesFile(const std::string& xml_profile_file) { if (false == default_xml_profiles_loaded) { diff --git a/src/cpp/participant/ParticipantImpl.cpp b/src/cpp/participant/ParticipantImpl.cpp index 64adf7c1a18..10b0d0350b8 100644 --- a/src/cpp/participant/ParticipantImpl.cpp +++ b/src/cpp/participant/ParticipantImpl.cpp @@ -47,13 +47,16 @@ using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -ParticipantImpl::ParticipantImpl(ParticipantAttributes& patt,Participant* pspart,ParticipantListener* listen): - m_att(patt), - mp_rtpsParticipant(nullptr), - mp_participant(pspart), - mp_listener(listen), +ParticipantImpl::ParticipantImpl( + const ParticipantAttributes& patt, + Participant* pspart, + ParticipantListener* listen) + : m_att(patt) + , mp_rtpsParticipant(nullptr) + , mp_participant(pspart) + , mp_listener(listen) #pragma warning (disable : 4355 ) - m_rtps_listener(this) + , m_rtps_listener(this) { mp_participant->mp_impl = this; } @@ -111,7 +114,8 @@ const GUID_t& ParticipantImpl::getGuid() const return this->mp_rtpsParticipant->getGuid(); } -Publisher* ParticipantImpl::createPublisher(PublisherAttributes& att, +Publisher* ParticipantImpl::createPublisher( + const PublisherAttributes& att, PublisherListener* listen) { logInfo(PARTICIPANT,"CREATING PUBLISHER IN TOPIC: "< ParticipantImpl::getParticipantNames() const { return mp_rtpsParticipant->getParticipantNames(); } -Subscriber* ParticipantImpl::createSubscriber(SubscriberAttributes& att, +Subscriber* ParticipantImpl::createSubscriber( + const SubscriberAttributes& att, SubscriberListener* listen) { logInfo(PARTICIPANT,"CREATING SUBSCRIBER IN TOPIC: "<::iterator it=m_types.begin(); it!=m_types.end();++it) @@ -422,7 +429,8 @@ bool ParticipantImpl::unregisterType(const char* typeName) -void ParticipantImpl::MyRTPSParticipantListener::onParticipantDiscovery(RTPSParticipant*, +void ParticipantImpl::MyRTPSParticipantListener::onParticipantDiscovery( + RTPSParticipant*, rtps::ParticipantDiscoveryInfo&& info) { if(this->mp_participantimpl->mp_listener!=nullptr) @@ -432,7 +440,8 @@ void ParticipantImpl::MyRTPSParticipantListener::onParticipantDiscovery(RTPSPart } #if HAVE_SECURITY -void ParticipantImpl::MyRTPSParticipantListener::onParticipantAuthentication(RTPSParticipant*, +void ParticipantImpl::MyRTPSParticipantListener::onParticipantAuthentication( + RTPSParticipant*, ParticipantAuthenticationInfo&& info) { if(this->mp_participantimpl->mp_listener != nullptr) @@ -442,7 +451,8 @@ void ParticipantImpl::MyRTPSParticipantListener::onParticipantAuthentication(RTP } #endif -void ParticipantImpl::MyRTPSParticipantListener::onReaderDiscovery(RTPSParticipant*, +void ParticipantImpl::MyRTPSParticipantListener::onReaderDiscovery( + RTPSParticipant*, rtps::ReaderDiscoveryInfo&& info) { if(this->mp_participantimpl->mp_listener!=nullptr) @@ -451,7 +461,8 @@ void ParticipantImpl::MyRTPSParticipantListener::onReaderDiscovery(RTPSParticipa } } -void ParticipantImpl::MyRTPSParticipantListener::onWriterDiscovery(RTPSParticipant*, +void ParticipantImpl::MyRTPSParticipantListener::onWriterDiscovery( + RTPSParticipant*, rtps::WriterDiscoveryInfo&& info) { if(this->mp_participantimpl->mp_listener!=nullptr) @@ -460,7 +471,9 @@ void ParticipantImpl::MyRTPSParticipantListener::onWriterDiscovery(RTPSParticipa } } -bool ParticipantImpl::newRemoteEndpointDiscovered(const GUID_t& partguid, uint16_t endpointId, +bool ParticipantImpl::newRemoteEndpointDiscovered( + const GUID_t& partguid, + uint16_t endpointId, EndpointKind_t kind) { if (kind == WRITER) @@ -469,12 +482,16 @@ bool ParticipantImpl::newRemoteEndpointDiscovered(const GUID_t& partguid, uint16 return this->mp_rtpsParticipant->newRemoteReaderDiscovered(partguid, endpointId); } -bool ParticipantImpl::get_remote_writer_info(const GUID_t& writerGuid, WriterProxyData& returnedInfo) +bool ParticipantImpl::get_remote_writer_info( + const GUID_t& writerGuid, + WriterProxyData& returnedInfo) { return mp_rtpsParticipant->get_remote_writer_info(writerGuid, returnedInfo); } -bool ParticipantImpl::get_remote_reader_info(const GUID_t& readerGuid, ReaderProxyData& returnedInfo) +bool ParticipantImpl::get_remote_reader_info( + const GUID_t& readerGuid, + ReaderProxyData& returnedInfo) { return mp_rtpsParticipant->get_remote_reader_info(readerGuid, returnedInfo); } diff --git a/src/cpp/participant/ParticipantImpl.h b/src/cpp/participant/ParticipantImpl.h index e21f9c21ba1..8324f5185f6 100644 --- a/src/cpp/participant/ParticipantImpl.h +++ b/src/cpp/participant/ParticipantImpl.h @@ -63,7 +63,10 @@ class ParticipantImpl typedef std::vector t_v_SubscriberPairs; private: - ParticipantImpl(ParticipantAttributes& patt,Participant* pspart,ParticipantListener* listen = nullptr); + ParticipantImpl( + const ParticipantAttributes& patt, + Participant* pspart, + ParticipantListener* listen = nullptr); virtual ~ParticipantImpl(); public: @@ -88,7 +91,9 @@ class ParticipantImpl * @param listen Pointer to the listener. * @return Pointer to the created Publisher. */ - Publisher* createPublisher(PublisherAttributes& att, PublisherListener* listen=nullptr); + Publisher* createPublisher( + const PublisherAttributes& att, + PublisherListener* listen=nullptr); /** * Create a Subscriber in this Participant. @@ -96,7 +101,9 @@ class ParticipantImpl * @param listen Pointer to the listener. * @return Pointer to the created Subscriber. */ - Subscriber* createSubscriber(SubscriberAttributes& att, SubscriberListener* listen=nullptr); + Subscriber* createSubscriber( + const SubscriberAttributes& att, + SubscriberListener* listen=nullptr); /** * Remove a Publisher from this participant. @@ -138,12 +145,18 @@ class ParticipantImpl * @param kind EndpointKind (WRITER or READER) * @return True if correctly found and activated. */ - bool newRemoteEndpointDiscovered(const rtps::GUID_t& partguid, uint16_t userId, - rtps::EndpointKind_t kind); - - bool get_remote_writer_info(const rtps::GUID_t& writerGuid, rtps::WriterProxyData& returnedInfo); - - bool get_remote_reader_info(const rtps::GUID_t& readerGuid, rtps::ReaderProxyData& returnedInfo); + bool newRemoteEndpointDiscovered( + const rtps::GUID_t& partguid, + uint16_t userId, + rtps::EndpointKind_t kind); + + bool get_remote_writer_info( + const rtps::GUID_t& writerGuid, + rtps::WriterProxyData& returnedInfo); + + bool get_remote_reader_info( + const rtps::GUID_t& readerGuid, + rtps::ReaderProxyData& returnedInfo); private: //!Participant Attributes diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 4386ca99868..c9a40f5a051 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -34,9 +34,13 @@ extern eprosima::fastrtps::rtps::WriteParams WRITE_PARAM_DEFAULT; using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -PublisherHistory::PublisherHistory(PublisherImpl* pimpl, uint32_t payloadMaxSize, HistoryQosPolicy& history, - ResourceLimitsQosPolicy& resource, MemoryManagementPolicy_t mempolicy): - WriterHistory(HistoryAttributes(mempolicy, payloadMaxSize, +PublisherHistory::PublisherHistory( + PublisherImpl* pimpl, + uint32_t payloadMaxSize, + const HistoryQosPolicy& history, + const ResourceLimitsQosPolicy& resource, + MemoryManagementPolicy_t mempolicy) + : WriterHistory(HistoryAttributes(mempolicy, payloadMaxSize, history.kind == KEEP_ALL_HISTORY_QOS ? resource.allocated_samples : pimpl->getAttributes().topic.getTopicKind() == NO_KEY ? @@ -46,10 +50,10 @@ PublisherHistory::PublisherHistory(PublisherImpl* pimpl, uint32_t payloadMaxSize resource.max_samples : pimpl->getAttributes().topic.getTopicKind() == NO_KEY ? history.depth : - history.depth * resource.max_instances)), - m_historyQos(history), - m_resourceLimitsQos(resource), - mp_pubImpl(pimpl) + history.depth * resource.max_instances)) + , m_historyQos(history) + , m_resourceLimitsQos(resource) + , mp_pubImpl(pimpl) { // TODO Auto-generated constructor stub diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 7a794f326a6..477c83a7bec 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -35,26 +35,29 @@ using namespace eprosima::fastrtps; using namespace ::rtps; -PublisherImpl::PublisherImpl(ParticipantImpl* p,TopicDataType*pdatatype, - PublisherAttributes& att,PublisherListener* listen ): - mp_participant(p), - mp_writer(nullptr), - mp_type(pdatatype), - m_att(att), +PublisherImpl::PublisherImpl( + ParticipantImpl* p, + TopicDataType* pdatatype, + const PublisherAttributes& att, + PublisherListener* listen ) + : mp_participant(p) + , mp_writer(nullptr) + , mp_type(pdatatype) + , m_att(att) #pragma warning (disable : 4355 ) - m_history(this, pdatatype->m_typeSize + , m_history(this, pdatatype->m_typeSize #if HAVE_SECURITY // In future v2 changepool is in writer, and writer set this value to cachechagepool. + 20 /*SecureDataHeader*/ + 4 + ((2* 16) /*EVP_MAX_IV_LENGTH max block size*/ - 1 ) /* SecureDataBodey*/ + 16 + 4 /*SecureDataTag*/ #endif - , att.topic.historyQos, att.topic.resourceLimitsQos, att.historyMemoryPolicy), - mp_listener(listen), + , att.topic.historyQos, att.topic.resourceLimitsQos, att.historyMemoryPolicy) + , mp_listener(listen) #pragma warning (disable : 4355 ) - m_writerListener(this), - mp_userPublisher(nullptr), - mp_rtpsParticipant(nullptr), - high_mark_for_frag_(0) + , m_writerListener(this) + , mp_userPublisher(nullptr) + , mp_rtpsParticipant(nullptr) + , high_mark_for_frag_(0) { } @@ -71,12 +74,17 @@ PublisherImpl::~PublisherImpl() -bool PublisherImpl::create_new_change(ChangeKind_t changeKind, void* data) +bool PublisherImpl::create_new_change( + ChangeKind_t changeKind, + void* data) { return create_new_change_with_params(changeKind, data, WriteParams::WRITE_PARAM_DEFAULT); } -bool PublisherImpl::create_new_change_with_params(ChangeKind_t changeKind, void* data, WriteParams &wparams) +bool PublisherImpl::create_new_change_with_params( + ChangeKind_t changeKind, + void* data, + WriteParams& wparams) { /// Preconditions @@ -280,13 +288,17 @@ bool PublisherImpl::updateAttributes(const PublisherAttributes& att) return updated; } -void PublisherImpl::PublisherWriterListener::onWriterMatched(RTPSWriter* /*writer*/,MatchingInfo& info) +void PublisherImpl::PublisherWriterListener::onWriterMatched( + RTPSWriter* /*writer*/, + MatchingInfo& info) { if(mp_publisherImpl->mp_listener!=nullptr) mp_publisherImpl->mp_listener->onPublicationMatched(mp_publisherImpl->mp_userPublisher,info); } -void PublisherImpl::PublisherWriterListener::onWriterChangeReceivedByAll(RTPSWriter* /*writer*/, CacheChange_t* ch) +void PublisherImpl::PublisherWriterListener::onWriterChangeReceivedByAll( + RTPSWriter* /*writer*/, + CacheChange_t* ch) { if (mp_publisherImpl->m_att.qos.m_durability.kind == VOLATILE_DURABILITY_QOS) { diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 2db77576ec5..17f8d661e87 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -60,8 +60,11 @@ class PublisherImpl * Create a publisher, assigning its pointer to the associated writer. * Don't use directly, create Publisher using DomainRTPSParticipant static function. */ - PublisherImpl(ParticipantImpl* p,TopicDataType* ptype, - PublisherAttributes& att,PublisherListener* p_listen = nullptr); + PublisherImpl( + ParticipantImpl* p, + TopicDataType* ptype, + const PublisherAttributes& att, + PublisherListener* p_listen = nullptr); virtual ~PublisherImpl(); @@ -71,7 +74,9 @@ class PublisherImpl * @param Data * @return */ - bool create_new_change(rtps::ChangeKind_t kind, void* Data); + bool create_new_change( + rtps::ChangeKind_t kind, + void* Data); /** * @@ -80,7 +85,10 @@ class PublisherImpl * @param wparams * @return */ - bool create_new_change_with_params(rtps::ChangeKind_t kind, void* Data, rtps::WriteParams &wparams); + bool create_new_change_with_params( + rtps::ChangeKind_t kind, + void* Data, + rtps::WriteParams& wparams); /** * Removes the cache change with the minimum sequence number diff --git a/src/cpp/rtps/RTPSDomain.cpp b/src/cpp/rtps/RTPSDomain.cpp index 42a5183722e..492f43d2b8c 100644 --- a/src/cpp/rtps/RTPSDomain.cpp +++ b/src/cpp/rtps/RTPSDomain.cpp @@ -58,12 +58,15 @@ void RTPSDomain::stopAll() eClock::my_sleep(100); } -RTPSParticipant* RTPSDomain::createParticipant(RTPSParticipantAttributes& PParam, +RTPSParticipant* RTPSDomain::createParticipant( + const RTPSParticipantAttributes& attrs, RTPSParticipantListener* listen) { std::lock_guard guard(m_mutex); logInfo(RTPS_PARTICIPANT,""); + RTPSParticipantAttributes PParam = attrs; + if(PParam.builtin.leaseDuration < c_TimeInfinite && PParam.builtin.leaseDuration <= PParam.builtin.leaseDuration_announcementperiod) //TODO CHeckear si puedo ser infinito { logError(RTPS_PARTICIPANT,"RTPSParticipant Attributes: LeaseDuration should be >= leaseDuration announcement period"); @@ -74,7 +77,9 @@ RTPSParticipant* RTPSDomain::createParticipant(RTPSParticipantAttributes& PParam { ID = getNewId(); while(m_RTPSParticipantIDs.insert(ID).second == false) + { ID = getNewId(); + } } else { @@ -122,14 +127,14 @@ RTPSParticipant* RTPSDomain::createParticipant(RTPSParticipantAttributes& PParam PParam.builtin.initialPeersList.push_back(local); } } - guidP.value[4] = ((octet*)&pid)[0]; - guidP.value[5] = ((octet*)&pid)[1]; - guidP.value[6] = ((octet*)&pid)[2]; - guidP.value[7] = ((octet*)&pid)[3]; - guidP.value[8] = ((octet*)&ID)[0]; - guidP.value[9] = ((octet*)&ID)[1]; - guidP.value[10] = ((octet*)&ID)[2]; - guidP.value[11] = ((octet*)&ID)[3]; + guidP.value[4] = octet(pid); + guidP.value[5] = octet(pid >> 8); + guidP.value[6] = octet(pid >> 16); + guidP.value[7] = octet(pid >> 24); + guidP.value[8] = octet(ID); + guidP.value[9] = octet(ID >> 8); + guidP.value[10] = octet(ID >> 16); + guidP.value[11] = octet(ID >> 24); RTPSParticipant* p = new RTPSParticipant(nullptr); RTPSParticipantImpl* pimpl = new RTPSParticipantImpl(PParam,guidP,p,listen); @@ -181,7 +186,11 @@ void RTPSDomain::removeRTPSParticipant_nts(std::vector guard(m_mutex); for(auto it= m_RTPSParticipants.begin();it!=m_RTPSParticipants.end();++it) @@ -215,8 +224,11 @@ bool RTPSDomain::removeRTPSWriter(RTPSWriter* writer) return false; } -RTPSReader* RTPSDomain::createRTPSReader(RTPSParticipant* p, ReaderAttributes& ratt, - ReaderHistory* rhist, ReaderListener* rlisten) +RTPSReader* RTPSDomain::createRTPSReader( + RTPSParticipant* p, + ReaderAttributes& ratt, + ReaderHistory* rhist, + ReaderListener* rlisten) { std::lock_guard guard(m_mutex); for(auto it= m_RTPSParticipants.begin();it!=m_RTPSParticipants.end();++it) diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index a65aa5efbcf..55c7ee3089c 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -36,15 +36,18 @@ inline bool sort_ReaderHistoryCache(CacheChange_t*c1,CacheChange_t*c2) return c1->sequenceNumber < c2->sequenceNumber; } -SubscriberHistory::SubscriberHistory(SubscriberImpl* simpl,uint32_t payloadMaxSize, - HistoryQosPolicy& history, - ResourceLimitsQosPolicy& resource,MemoryManagementPolicy_t mempolicy): - ReaderHistory(HistoryAttributes(mempolicy, payloadMaxSize,resource.allocated_samples,resource.max_samples + 1)), - m_unreadCacheCount(0), - m_historyQos(history), - m_resourceLimitsQos(resource), - mp_subImpl(simpl), - mp_getKeyObject(nullptr) +SubscriberHistory::SubscriberHistory( + SubscriberImpl* simpl, + uint32_t payloadMaxSize, + const HistoryQosPolicy& history, + const ResourceLimitsQosPolicy& resource, + MemoryManagementPolicy_t mempolicy) + : ReaderHistory(HistoryAttributes(mempolicy, payloadMaxSize,resource.allocated_samples,resource.max_samples + 1)) + , m_unreadCacheCount(0) + , m_historyQos(history) + , m_resourceLimitsQos(resource) + , mp_subImpl(simpl) + , mp_getKeyObject(nullptr) { if (mp_subImpl->getType()->m_isGetKeyDefined) { @@ -60,7 +63,9 @@ SubscriberHistory::~SubscriberHistory() } } -bool SubscriberHistory::received_change(CacheChange_t* a_change, size_t unknown_missing_changes_up_to) +bool SubscriberHistory::received_change( + CacheChange_t* a_change, + size_t unknown_missing_changes_up_to) { if (mp_reader == nullptr || mp_mutex == nullptr) @@ -549,4 +554,4 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change, t_v_Inst_Caches logError(SUBSCRIBER, "Change not found, something is wrong"); } return false; -} \ No newline at end of file +} diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index daa1fd0fa2d..1ba58e83ccc 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -36,18 +36,21 @@ namespace eprosima { namespace fastrtps { -SubscriberImpl::SubscriberImpl(ParticipantImpl* p,TopicDataType* ptype, - SubscriberAttributes& att,SubscriberListener* listen): - mp_participant(p), - mp_reader(nullptr), - mp_type(ptype), - m_att(att), +SubscriberImpl::SubscriberImpl( + ParticipantImpl* p, + TopicDataType* ptype, + const SubscriberAttributes& att, + SubscriberListener* listen) + : mp_participant(p) + , mp_reader(nullptr) + , mp_type(ptype) + , m_att(att) #pragma warning (disable : 4355 ) - m_history(this,ptype->m_typeSize + 3/*Possible alignment*/, att.topic.historyQos, att.topic.resourceLimitsQos,att.historyMemoryPolicy), - mp_listener(listen), - m_readerListener(this), - mp_userSubscriber(nullptr), - mp_rtpsParticipant(nullptr) + , m_history(this,ptype->m_typeSize + 3/*Possible alignment*/, att.topic.historyQos, att.topic.resourceLimitsQos,att.historyMemoryPolicy) + , mp_listener(listen) + , m_readerListener(this) + , mp_userSubscriber(nullptr) + , mp_rtpsParticipant(nullptr) { } diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 6dc9bf1d435..6608bb5c739 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -56,8 +56,12 @@ class SubscriberImpl { * @param attr * @param listen */ - SubscriberImpl(ParticipantImpl* p,TopicDataType* ptype, - SubscriberAttributes& attr,SubscriberListener* listen = nullptr); + SubscriberImpl( + ParticipantImpl* p, + TopicDataType* ptype, + const SubscriberAttributes& attr, + SubscriberListener* listen = nullptr); + virtual ~SubscriberImpl(); /** From f7989aaf39c3ca298ae2245dfb445cb37048d15c Mon Sep 17 00:00:00 2001 From: JBurgos-eProsima <46781586+JBurgos-eProsima@users.noreply.github.com> Date: Tue, 29 Jan 2019 11:55:33 +0100 Subject: [PATCH 19/34] Improve XML test for dynamic types [4452] (#390) * Refs #4194 XML test for dynamic types Some of the XML test were not checking correctly that the parsed types contained the expected structure. That issue has been fixed. * Name of the XML file moved to a class variable * Refs #4452. Return const reference --- .../dynamic_types/DynamicTypesTests.cpp | 1149 +++++++++-------- test/unittest/dynamic_types/types.xml | 2 +- 2 files changed, 576 insertions(+), 575 deletions(-) diff --git a/test/unittest/dynamic_types/DynamicTypesTests.cpp b/test/unittest/dynamic_types/DynamicTypesTests.cpp index 8a2949a563d..4b8beb62c66 100644 --- a/test/unittest/dynamic_types/DynamicTypesTests.cpp +++ b/test/unittest/dynamic_types/DynamicTypesTests.cpp @@ -35,6 +35,8 @@ using namespace eprosima::fastrtps::types; class DynamicTypesTests: public ::testing::Test { + const std::string config_file_ = "types.xml"; + public: DynamicTypesTests() { @@ -50,6 +52,11 @@ class DynamicTypesTests: public ::testing::Test DynamicDataFactory::DeleteInstance(); DynamicTypeBuilderFactory::DeleteInstance(); } + + const std::string& config_file() + { + return config_file_; + } }; TEST_F(DynamicTypesTests, TypeDescriptors_unit_tests) @@ -3698,893 +3705,703 @@ TEST_F(DynamicTypesTests, DynamicType_union_with_unions_unit_tests) ASSERT_TRUE(DynamicDataFactory::GetInstance()->IsEmpty()); } -TEST_F(DynamicTypesTests, DynamicType_XML_BoolStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_EnumStruct_test) { using namespace xmlparser; using namespace types; - const char* config_file = "types.xml"; - tinyxml2::XMLDocument doc; - XMLP_ret ret = XMLProfileManager::loadXMLFile(config_file); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("BoolStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - BoolStruct wbool; - BoolStructPubSubType wboolpb; + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("EnumStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(wboolpb.deserialize(&dynamic_payload, &wbool)); + // Enum + DynamicTypeBuilder_ptr enum_builder = m_factory->CreateEnumBuilder(); + enum_builder->AddEmptyMember(0, "A"); + enum_builder->AddEmptyMember(1, "B"); + enum_builder->AddEmptyMember(2, "C"); + enum_builder->SetName("MyEnum"); - uint32_t static_payloadSize = static_cast(wboolpb.getSerializedSizeProvider(&wbool)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(wboolpb.serialize(&wbool, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct EnumStruct + DynamicTypeBuilder_ptr es_builder = m_factory->CreateStructBuilder(); + es_builder->AddMember(0, "my_enum", enum_builder.get()); + es_builder->SetName("EnumStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(es_builder->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_OctetStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_AliasStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("OctetStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("AliasStruct"); - // SERIALIZATION TEST - OctetStruct refData; - OctetStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Enum + DynamicTypeBuilder_ptr enum_builder = m_factory->CreateEnumBuilder(); + enum_builder->AddEmptyMember(0, "A"); + enum_builder->AddEmptyMember(1, "B"); + enum_builder->AddEmptyMember(2, "C"); + enum_builder->SetName("MyEnum"); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Alias + DynamicTypeBuilder_ptr alias_builder = m_factory->CreateAliasBuilder(enum_builder.get(), "MyAliasEnum"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + // Struct AliasStruct + DynamicTypeBuilder_ptr aliass_builder_ptr = m_factory->CreateStructBuilder(); + aliass_builder_ptr->AddMember(0, "my_alias", alias_builder.get()); + aliass_builder_ptr->SetName("AliasStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(aliass_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_ShortStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_AliasAliasStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ShortStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("AliasAliasStruct"); - // SERIALIZATION TEST - ShortStruct refData; - ShortStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Enum + DynamicTypeBuilder_ptr enum_builder = m_factory->CreateEnumBuilder(); + enum_builder->AddEmptyMember(0, "A"); + enum_builder->AddEmptyMember(1, "B"); + enum_builder->AddEmptyMember(2, "C"); + enum_builder->SetName("MyEnum"); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Alias and aliasalias + DynamicTypeBuilder_ptr alias_builder = m_factory->CreateAliasBuilder(enum_builder.get(), "MyAliasEnum"); + DynamicTypeBuilder_ptr alias_alias_builder = m_factory->CreateAliasBuilder(alias_builder.get(), "MyAliasAliasEnum"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + // Struct AliasAliasStruct + DynamicTypeBuilder_ptr aliasAliasS_builder_ptr = m_factory->CreateStructBuilder(); + aliasAliasS_builder_ptr->AddMember(0, "my_alias_alias", alias_alias_builder.get()); + aliasAliasS_builder_ptr->SetName("AliasAliasStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(aliasAliasS_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_LongStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_BoolStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("LongStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - LongStruct refData; - LongStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("BoolStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Boolean + DynamicTypeBuilder_ptr boolean_builder = m_factory->CreateBoolBuilder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct BoolStruct + DynamicTypeBuilder_ptr bool_builder_ptr = m_factory->CreateStructBuilder(); + bool_builder_ptr->AddMember(0, "my_bool", boolean_builder.get()); + bool_builder_ptr->SetName("BoolStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(bool_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_LongLongStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_OctetStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("LongLongStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - LongLongStruct refData; - LongLongStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("OctetStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Byte + DynamicTypeBuilder_ptr byte_builder = m_factory->CreateByteBuilder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct OctetStruct + DynamicTypeBuilder_ptr octet_builder_ptr = m_factory->CreateStructBuilder(); + octet_builder_ptr->AddMember(0, "my_octet", byte_builder.get()); + octet_builder_ptr->SetName("OctetStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(octet_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_UShortStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ShortStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("UShortStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - UShortStruct refData; - UShortStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ShortStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Int16 + DynamicTypeBuilder_ptr int16_builder = m_factory->CreateInt16Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ShortStruct + DynamicTypeBuilder_ptr int16_builder_ptr = m_factory->CreateStructBuilder(); + int16_builder_ptr->AddMember(0, "my_int16", int16_builder.get()); + int16_builder_ptr->SetName("ShortStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(int16_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_ULongStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_LongStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ULongStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - ULongStruct refData; - ULongStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("LongStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Int32 + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct LongStruct + DynamicTypeBuilder_ptr int32_builder_ptr = m_factory->CreateStructBuilder(); + int32_builder_ptr->AddMember(0, "my_int32", int32_builder.get()); + int32_builder_ptr->SetName("LongStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(int32_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_ULongLongStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_LongLongStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ULongLongStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - ULongLongStruct refData; - ULongLongStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("LongLongStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Int64 + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct LongLongStruct + DynamicTypeBuilder_ptr int64_builder_ptr = m_factory->CreateStructBuilder(); + int64_builder_ptr->AddMember(0, "my_int64", int64_builder.get()); + int64_builder_ptr->SetName("LongLongStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(int64_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_FloatStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_UShortStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("FloatStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - FloatStruct refData; - FloatStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("UShortStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // uint16 + DynamicTypeBuilder_ptr uint16_builder = m_factory->CreateUint16Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct UShortStruct + DynamicTypeBuilder_ptr uint16_builder_ptr = m_factory->CreateStructBuilder(); + uint16_builder_ptr->AddMember(0, "my_uint16", uint16_builder.get()); + uint16_builder_ptr->SetName("UShortStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(uint16_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_DoubleStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ULongStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("DoubleStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - DoubleStruct refData; - DoubleStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ULongStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // uint32 + DynamicTypeBuilder_ptr uint32_builder = m_factory->CreateUint32Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ULongStruct + DynamicTypeBuilder_ptr uint32_builder_ptr = m_factory->CreateStructBuilder(); + uint32_builder_ptr->AddMember(0, "my_uint32", uint32_builder.get()); + uint32_builder_ptr->SetName("ULongStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(uint32_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_CharStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ULongLongStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("CharStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - CharStruct refData; - CharStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ULongLongStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // uint64 + DynamicTypeBuilder_ptr uint64_builder = m_factory->CreateUint64Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ULongLongStruct + DynamicTypeBuilder_ptr uint64_builder_ptr = m_factory->CreateStructBuilder(); + uint64_builder_ptr->AddMember(0, "my_uint64", uint64_builder.get()); + uint64_builder_ptr->SetName("ULongLongStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(uint64_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_WCharStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_FloatStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("WCharStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - WCharStruct refData; - WCharStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("FloatStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // float32 + DynamicTypeBuilder_ptr float32_builder = m_factory->CreateFloat32Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct FloatStruct + DynamicTypeBuilder_ptr float32_builder_ptr = m_factory->CreateStructBuilder(); + float32_builder_ptr->AddMember(0, "my_float32", float32_builder.get()); + float32_builder_ptr->SetName("FloatStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(float32_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_StringStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_DoubleStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("StringStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - StringStruct refData; - StringStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("DoubleStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // float64 + DynamicTypeBuilder_ptr float64_builder = m_factory->CreateFloat64Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct DoubleStruct + DynamicTypeBuilder_ptr float64_builder_ptr = m_factory->CreateStructBuilder(); + float64_builder_ptr->AddMember(0, "my_float64", float64_builder.get()); + float64_builder_ptr->SetName("DoubleStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(float64_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_WStringStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_LongDoubleStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("WStringStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("LongDoubleStruct"); - // SERIALIZATION TEST - WStringStruct refData; - WStringStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // float128 + DynamicTypeBuilder_ptr float128_builder = m_factory->CreateFloat128Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct LongDoubleStruct + DynamicTypeBuilder_ptr float128_builder_ptr = m_factory->CreateStructBuilder(); + float128_builder_ptr->AddMember(0, "my_float128", float128_builder.get()); + float128_builder_ptr->SetName("LongDoubleStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(float128_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_LargeStringStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_CharStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("LargeStringStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("CharStruct"); - // SERIALIZATION TEST - LargeStringStruct refData; - LargeStringStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // char + DynamicTypeBuilder_ptr char8_builder = m_factory->CreateChar8Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct CharStruct + DynamicTypeBuilder_ptr char_builder_ptr = m_factory->CreateStructBuilder(); + char_builder_ptr->AddMember(0, "my_char", char8_builder.get()); + char_builder_ptr->SetName("CharStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(char_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_ArraytStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_WCharStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ArraytStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("WCharStruct"); - // SERIALIZATION TEST - ArraytStruct refData; - ArraytStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // wchar + DynamicTypeBuilder_ptr char16_builder = m_factory->CreateChar16Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct WCharStruct + DynamicTypeBuilder_ptr wchar_builder_ptr = m_factory->CreateStructBuilder(); + wchar_builder_ptr->AddMember(0, "my_wchar", char16_builder.get()); + wchar_builder_ptr->SetName("WCharStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(wchar_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_SequenceStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_StringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("SequenceStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - SequenceStruct refData; - SequenceStructPubSubType refDatapb; + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("StringStruct"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // string + DynamicTypeBuilder_ptr string_builder = m_factory->CreateStringBuilder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct StringStruct + DynamicTypeBuilder_ptr string_builder_ptr = m_factory->CreateStructBuilder(); + string_builder_ptr->AddMember(0, "my_string", string_builder.get()); + string_builder_ptr->SetName("StringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(string_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_StructStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_WStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("StructStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("WStringStruct"); - // SERIALIZATION TEST - StructStruct refData; - StructStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // wstring + DynamicTypeBuilder_ptr wstring_builder = m_factory->CreateWstringBuilder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct WStringStruct + DynamicTypeBuilder_ptr wstring_builder_ptr = m_factory->CreateStructBuilder(); + wstring_builder_ptr->AddMember(0, "my_wstring", wstring_builder.get()); + wstring_builder_ptr->SetName("WStringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(wstring_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_StructStructStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_LargeStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("StructStructStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("LargeStringStruct"); - // SERIALIZATION TEST - StructStructStruct refData; - StructStructStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // large string + DynamicTypeBuilder_ptr string_builder = m_factory->CreateStringBuilder(41925); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct LargeStringStruct + DynamicTypeBuilder_ptr large_string_builder_ptr = m_factory->CreateStructBuilder(); + large_string_builder_ptr->AddMember(0, "my_large_string", string_builder.get()); + large_string_builder_ptr->SetName("LargeStringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(large_string_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_SimpleUnionStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_LargeWStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("SimpleUnionStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("LargeWStringStruct"); - // SERIALIZATION TEST - SimpleUnionStruct refData; - SimpleUnionStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // large wstring + DynamicTypeBuilder_ptr wstring_builder = m_factory->CreateWstringBuilder(41925); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct LargeWStringStruct + DynamicTypeBuilder_ptr large_wstring_builder_ptr = m_factory->CreateStructBuilder(); + large_wstring_builder_ptr->AddMember(0, "my_large_wstring", wstring_builder.get()); + large_wstring_builder_ptr->SetName("LargeWStringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(large_wstring_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_UnionUnionUnionStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ShortStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("UnionUnionUnionStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ShortStringStruct"); - // SERIALIZATION TEST - UnionUnionUnionStruct refData; - UnionUnionUnionStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + // Short string + DynamicTypeBuilder_ptr string_builder = m_factory->CreateStringBuilder(15); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ShortStringStruct + DynamicTypeBuilder_ptr short_string_builder_ptr = m_factory->CreateStructBuilder(); + short_string_builder_ptr->AddMember(0, "my_short_string", string_builder.get()); + short_string_builder_ptr->SetName("ShortStringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(short_string_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_WCharUnionStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ShortWStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("WCharUnionStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ShortWStringStruct"); - // SERIALIZATION TEST - WCharUnionStruct refData; - WCharUnionStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Short wstring + DynamicTypeBuilder_ptr wstring_builder = m_factory->CreateWstringBuilder(15); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ShortWStringStruct + DynamicTypeBuilder_ptr short_wstring_builder_ptr = m_factory->CreateStructBuilder(); + short_wstring_builder_ptr->AddMember(0, "my_short_wstring", wstring_builder.get()); + short_wstring_builder_ptr->SetName("ShortWStringStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(short_wstring_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_EnumStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_AliasStringStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("EnumStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - EnumStruct refData; - EnumStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); - - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("StructAliasString"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); - - delete(pbType); - XMLProfileManager::DeleteInstance(); - } -} - -TEST_F(DynamicTypesTests, DynamicType_XML_AliasStruct_test) -{ - using namespace xmlparser; - using namespace types; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); - ASSERT_EQ(ret, XMLP_ret::XML_OK); - { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("AliasStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + // String + DynamicTypeBuilder_ptr string_builder = m_factory->CreateStringBuilder(); - // SERIALIZATION TEST - AliasStruct refData; - AliasStructPubSubType refDatapb; + // Alias + DynamicTypeBuilder_ptr myAlias_builder = m_factory->CreateAliasBuilder(string_builder.get(), "MyAliasString"); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Struct StructAliasString + DynamicTypeBuilder_ptr alias_string_builder_ptr = m_factory->CreateStructBuilder(); + alias_string_builder_ptr->AddMember(0, "my_alias_string", myAlias_builder.get()); + alias_string_builder_ptr->SetName("StructAliasString"); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); - - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(alias_string_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_AliasAliasStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_StructAliasWString_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("AliasAliasStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - AliasAliasStruct refData; - AliasAliasStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); - - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("StructAliasWString"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - delete(pbType); - XMLProfileManager::DeleteInstance(); - } -} + // wstring + DynamicTypeBuilder_ptr wstring_builder = m_factory->CreateWstringBuilder(); -TEST_F(DynamicTypesTests, DynamicType_XML_LongDoubleStruct_test) -{ - using namespace xmlparser; - using namespace types; + // Alias + DynamicTypeBuilder_ptr myAlias_builder = m_factory->CreateAliasBuilder(wstring_builder.get(), "MyAliasWString"); - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); - ASSERT_EQ(ret, XMLP_ret::XML_OK); - { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("LongDoubleStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + // Struct StructAliasWString + DynamicTypeBuilder_ptr alias_wstring_builder_ptr = m_factory->CreateStructBuilder(); + alias_wstring_builder_ptr->AddMember(0, "my_alias_wstring", myAlias_builder.get()); + alias_wstring_builder_ptr->SetName("StructAliasWString"); - // SERIALIZATION TEST - LongDoubleStruct refData; - LongDoubleStructPubSubType refDatapb; - - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); - - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); - - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(alias_wstring_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } -TEST_F(DynamicTypesTests, DynamicType_XML_LargeWStringStruct_test) +TEST_F(DynamicTypesTests, DynamicType_XML_ArraytStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("LargeWStringStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ArraytStruct"); - // SERIALIZATION TEST - LargeWStringStruct refData; - LargeWStringStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Int32 + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Array + DynamicTypeBuilder_ptr array_builder = m_factory->CreateArrayBuilder(int32_builder.get(), { 2, 2, 2 }); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + // Struct ShortWStringStruct + DynamicTypeBuilder_ptr array_int32_builder_ptr = m_factory->CreateStructBuilder(); + array_int32_builder_ptr->AddMember(0, "my_array", array_builder.get()); + array_int32_builder_ptr->SetName("ArraytStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(array_int32_builder_ptr->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); @@ -4596,28 +4413,25 @@ TEST_F(DynamicTypesTests, DynamicType_XML_ArrayArrayStruct_test) using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ArrayArrayStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ArrayArrayStruct"); - // SERIALIZATION TEST - ArrayArrayStruct refData; - ArrayArrayStructPubSubType refDatapb; + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + // Typedef aka Alias + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr array_builder = m_factory->CreateArrayBuilder(int32_builder.get(), { 2, 2 }); + DynamicTypeBuilder_ptr myArray_builder = m_factory->CreateAliasBuilder(array_builder.get(), "MyArray"); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + // Struct ArrayArrayStruct + DynamicTypeBuilder_ptr aas_builder = m_factory->CreateStructBuilder(); + DynamicTypeBuilder_ptr aMyArray_builder = m_factory->CreateArrayBuilder(myArray_builder.get(), { 2, 2 }); + aas_builder->AddMember(0, "my_array_array", aMyArray_builder.get()); + aas_builder->SetName("ArrayArrayStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(aas_builder->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); @@ -4629,12 +4443,12 @@ TEST_F(DynamicTypesTests, DynamicType_XML_ArrayArrayArrayStruct_test) using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { - DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ArrayArrayArrayStruct"); + DynamicPubSubType* pbType = XMLProfileManager::CreateDynamicPubSubType("ArrayArrayArrayStruct"); + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); // Manual comparision test /* typedef long MyArray[2][2]; @@ -4689,33 +4503,54 @@ TEST_F(DynamicTypesTests, DynamicType_XML_ArrayArrayArrayStruct_test) } } +TEST_F(DynamicTypesTests, DynamicType_XML_SequenceStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("SequenceStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr seq_builder = m_factory->CreateSequenceBuilder(int32_builder.get(), 2); + + DynamicTypeBuilder_ptr seqs_builder = m_factory->CreateStructBuilder(); + seqs_builder->AddMember(0, "my_sequence", seq_builder.get()); + seqs_builder->SetName("SequenceStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(seqs_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + TEST_F(DynamicTypesTests, DynamicType_XML_SequenceSequenceStruct_test) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("SequenceSequenceStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - SequenceSequenceStruct refData; - SequenceSequenceStructPubSubType refDatapb; + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr seq_builder = m_factory->CreateSequenceBuilder(int32_builder.get(), 2); + DynamicTypeBuilder_ptr alias_builder = m_factory->CreateAliasBuilder(seq_builder.get(), "my_sequence_sequence_inner"); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + DynamicTypeBuilder_ptr sss_builder = m_factory->CreateStructBuilder(); + DynamicTypeBuilder_ptr seq_seq_builder = m_factory->CreateSequenceBuilder(alias_builder.get(), 2); + sss_builder->AddMember(0, "my_sequence_sequence", seq_seq_builder.get()); + sss_builder->SetName("SequenceSequenceStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(sss_builder->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); @@ -4727,28 +4562,21 @@ TEST_F(DynamicTypesTests, DynamicType_XML_MapStruct_test) using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("MapStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); - - // SERIALIZATION TEST - MapStruct refData; - MapStructPubSubType refDatapb; + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr map_builder = m_factory->CreateMapBuilder(int32_builder.get(), int32_builder.get(), 7); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + DynamicTypeBuilder_ptr maps_builder = m_factory->CreateStructBuilder(); + maps_builder->AddMember(0, "my_map", map_builder.get()); + maps_builder->SetName("MapStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(maps_builder->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); @@ -4760,40 +4588,213 @@ TEST_F(DynamicTypesTests, DynamicType_XML_MapMapStruct_test) using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("MapMapStruct"); - DynamicData* data = DynamicDataFactory::GetInstance()->CreateData(pbType->GetDynamicType()); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); - // SERIALIZATION TEST - MapMapStruct refData; - MapMapStructPubSubType refDatapb; + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr map_builder = m_factory->CreateMapBuilder(int32_builder.get(), int32_builder.get(), 7); + DynamicTypeBuilder_ptr alias_builder = m_factory->CreateAliasBuilder(map_builder.get(), "my_map_map_inner"); + DynamicTypeBuilder_ptr map_map_builder = m_factory->CreateMapBuilder(alias_builder.get(), int32_builder.get(), 2); - uint32_t payloadSize = static_cast(pbType->getSerializedSizeProvider(data)()); - SerializedPayload_t payload(payloadSize); - SerializedPayload_t dynamic_payload(payloadSize); - ASSERT_TRUE(pbType->serialize(data, &dynamic_payload)); - ASSERT_TRUE(refDatapb.deserialize(&dynamic_payload, &refData)); - uint32_t static_payloadSize = static_cast(refDatapb.getSerializedSizeProvider(&refData)()); - SerializedPayload_t static_payload(static_payloadSize); - ASSERT_TRUE(refDatapb.serialize(&refData, &static_payload)); - ASSERT_TRUE(static_payload.length == static_payloadSize); + DynamicTypeBuilder_ptr maps_builder = m_factory->CreateStructBuilder(); + maps_builder->AddMember(0, "my_map_map", map_map_builder.get()); + maps_builder->SetName("MapMapStruct"); - ASSERT_TRUE(DynamicDataFactory::GetInstance()->DeleteData(data) == ResponseCode::RETCODE_OK); + ASSERT_TRUE(pbType->GetDynamicType()->Equals(maps_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + +TEST_F(DynamicTypesTests, DynamicType_XML_StructStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("StructStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); + + DynamicTypeBuilder_ptr structs_builder = m_factory->CreateStructBuilder(); + structs_builder->AddMember(0, "a", int32_builder.get()); + structs_builder->AddMember(1, "b", int64_builder.get()); + structs_builder->SetName("StructStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(structs_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + +TEST_F(DynamicTypesTests, DynamicType_XML_StructStructStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("StructStructStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); + + DynamicTypeBuilder_ptr structs_builder = m_factory->CreateStructBuilder(); + structs_builder->AddMember(0, "a", int32_builder.get()); + structs_builder->AddMember(1, "b", int64_builder.get()); + structs_builder->SetName("StructStruct"); + + DynamicTypeBuilder_ptr sss_builder = m_factory->CreateStructBuilder(); + sss_builder->AddMember(0, "child_struct", structs_builder.get()); + sss_builder->AddMember(1, "child_int64", int64_builder.get()); + sss_builder->SetName("StructStructStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(sss_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + +TEST_F(DynamicTypesTests, DynamicType_XML_SimpleUnionStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("SimpleUnionStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); + + DynamicTypeBuilder_ptr union_builder = m_factory->CreateUnionBuilder(int32_builder.get()); + union_builder->AddMember(0, "first", int32_builder.get(), "", { 0 }, true); + union_builder->AddMember(1, "second", int64_builder.get(), "", { 1 }, false); + union_builder->SetName("SimpleUnion"); + + + DynamicTypeBuilder_ptr us_builder = m_factory->CreateStructBuilder(); + us_builder->AddMember(0, "my_union", union_builder.get()); + us_builder->SetName("SimpleUnionStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(us_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + +TEST_F(DynamicTypesTests, DynamicType_XML_UnionUnionStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("UnionUnionStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); + + DynamicTypeBuilder_ptr union_builder = m_factory->CreateUnionBuilder(int32_builder.get()); + union_builder->AddMember(0, "first", int32_builder.get(), "", { 0 }, true); + union_builder->AddMember(1, "second", int64_builder.get(), "", { 1 }, false); + union_builder->SetName("SimpleUnion"); + + DynamicTypeBuilder_ptr union_union_builder = m_factory->CreateUnionBuilder(int32_builder.get()); + union_union_builder->AddMember(0, "first", int32_builder.get(), "", { 0 }, true); + union_union_builder->AddMember(1, "second", union_builder.get(), "", { 1 }, false); + union_union_builder->SetName("UnionUnion"); + + + DynamicTypeBuilder_ptr uus_builder = m_factory->CreateStructBuilder(); + uus_builder->AddMember(0, "my_union", union_union_builder.get()); + uus_builder->SetName("UnionUnionStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(uus_builder->Build().get())); delete(pbType); XMLProfileManager::DeleteInstance(); } } +TEST_F(DynamicTypesTests, DynamicType_XML_WCharUnionStruct_test) +{ + using namespace xmlparser; + using namespace types; + + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); + ASSERT_EQ(ret, XMLP_ret::XML_OK); + { + DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("WCharUnionStruct"); + + DynamicTypeBuilderFactory* m_factory = DynamicTypeBuilderFactory::GetInstance(); + + DynamicTypeBuilder_ptr wchar_builder = m_factory->CreateChar16Builder(); + DynamicTypeBuilder_ptr int32_builder = m_factory->CreateInt32Builder(); + DynamicTypeBuilder_ptr int64_builder = m_factory->CreateInt64Builder(); + + DynamicTypeBuilder_ptr union_builder = m_factory->CreateUnionBuilder(wchar_builder.get()); + union_builder->AddMember(0, "first", int32_builder.get(), "", { 0 }, true); + union_builder->AddMember(1, "second", int64_builder.get(), "", { 1 }, false); + union_builder->SetName("WCharUnion"); + + + DynamicTypeBuilder_ptr us_builder = m_factory->CreateStructBuilder(); + us_builder->AddMember(0, "my_union", union_builder.get()); + us_builder->SetName("WCharUnionStruct"); + + ASSERT_TRUE(pbType->GetDynamicType()->Equals(us_builder->Build().get())); + + delete(pbType); + XMLProfileManager::DeleteInstance(); + } +} + + + + + + + + + + + + + + + + + TEST_F(DynamicTypesTests, DynamicType_bounded_string_unit_tests) { using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ShortStringStruct"); @@ -4826,7 +4827,7 @@ TEST_F(DynamicTypesTests, DynamicType_bounded_wstring_unit_tests) using namespace xmlparser; using namespace types; - XMLP_ret ret = XMLProfileManager::loadXMLFile("types.xml"); + XMLP_ret ret = XMLProfileManager::loadXMLFile(DynamicTypesTests::config_file()); ASSERT_EQ(ret, XMLP_ret::XML_OK); { DynamicPubSubType *pbType = XMLProfileManager::CreateDynamicPubSubType("ShortWStringStruct"); diff --git a/test/unittest/dynamic_types/types.xml b/test/unittest/dynamic_types/types.xml index c7fe6aad7de..b2951575b01 100644 --- a/test/unittest/dynamic_types/types.xml +++ b/test/unittest/dynamic_types/types.xml @@ -242,7 +242,7 @@ - + From a70e31530d3a9e804f68b3eb0585ff3cd0945265 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Tue, 29 Jan 2019 12:36:03 +0100 Subject: [PATCH 20/34] Refs #4458. v1.7.1 --- CMakeLists.txt | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48ff2c524a9..358bb2c1039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,7 +92,7 @@ set(${PROJECT_NAME}_DESCRIPTION "eProsima ${PROJECT_NAME_LARGE} library provides message(STATUS "Configuring ${PROJECT_NAME_LARGE}") message(STATUS "Version: ${PROJECT_VERSION}") -message(STATUS "To change de version modify the file configure.ac") +message(STATUS "To change the version modify the file configure.ac") ############################################################################### # Generation of windows installers. diff --git a/configure.ac b/configure.ac index 13efac25e83..44aacfbab0c 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ # m4_define([version_major],[1]) m4_define([version_minor],[7]) -m4_define([version_micro],[0]) +m4_define([version_micro],[1]) AC_INIT([fastrtps], [version_major.version_minor.version_micro], [support@eprosima.com], [eProsima FastRTPS], [http://eprosima.com/]) CONFIG_ARGS="$*" From e5e7658ac85c7ba3b29048bca27f9a8a20bf82f5 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Tue, 29 Jan 2019 12:45:48 +0100 Subject: [PATCH 21/34] Refs #4458. Updating submodules. --- thirdparty/fastcdr | 2 +- thirdparty/idl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/fastcdr b/thirdparty/fastcdr index b395f44e896..ae56c2f1cfe 160000 --- a/thirdparty/fastcdr +++ b/thirdparty/fastcdr @@ -1 +1 @@ -Subproject commit b395f44e896c8621ec754d91bcb9c561de41d9d6 +Subproject commit ae56c2f1cfe980cb309d7fe98d0589c73e32bf04 diff --git a/thirdparty/idl b/thirdparty/idl index 04930f7926f..bbeaad35d97 160000 --- a/thirdparty/idl +++ b/thirdparty/idl @@ -1 +1 @@ -Subproject commit 04930f7926f972142811dd0dbdc0019356385e74 +Subproject commit bbeaad35d971f798b5318a4cd9793b245ed2e608 From 29e40906d7167665689cab664d0a82518fe61807 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Tue, 29 Jan 2019 15:57:09 +0100 Subject: [PATCH 22/34] Refs #4458. Updating asio. --- thirdparty/asio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/asio b/thirdparty/asio index b3d2ab7255f..22afb86087a 160000 --- a/thirdparty/asio +++ b/thirdparty/asio @@ -1 +1 @@ -Subproject commit b3d2ab7255fabe46a49b24a584c9fd797c8248e5 +Subproject commit 22afb86087a77037cd296d27134756c9b0d2cb75 From d2ec94e7a665d689b24e8ae71c9b83c9efec45db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Thu, 31 Jan 2019 17:04:12 +0100 Subject: [PATCH 23/34] Fixed error sending multicast on Windows in some scenarios. [4542] (#394) * Fixed error sending multicast on Windows in only one interface. * Fixed filtering interfaces mechanism on Windows --- src/cpp/transport/UDPTransportInterface.cpp | 9 ++++++--- src/cpp/utils/IPFinder.cpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cpp/transport/UDPTransportInterface.cpp b/src/cpp/transport/UDPTransportInterface.cpp index fa96c2d9b31..0ddf3ead38a 100644 --- a/src/cpp/transport/UDPTransportInterface.cpp +++ b/src/cpp/transport/UDPTransportInterface.cpp @@ -276,13 +276,16 @@ bool UDPTransportInterface::OpenAndBindOutputSockets(const Locator_t& locator) eProsimaUDPSocket unicastSocket = OpenAndBindUnicastOutputSocket(GenerateAnyAddressEndpoint(port), port); getSocketPtr(unicastSocket)->set_option(ip::multicast::enable_loopback(true)); + // Outbounding first interface with already created socket. + if(!locNames.empty()) + { + SetSocketOutbountInterface(unicastSocket, (*locNames.begin()).name); + } + // If more than one interface, then create sockets for outbounding multicast. if (locNames.size() > 1) { auto locIt = locNames.begin(); - - // Outbounding first interface with already created socket. - SetSocketOutbountInterface(unicastSocket, (*locIt).name); mOutputSockets.push_back(new UDPChannelResource(unicastSocket)); // Create other socket for outbounding rest of interfaces. diff --git a/src/cpp/utils/IPFinder.cpp b/src/cpp/utils/IPFinder.cpp index f792a679e28..23cfe4ca928 100644 --- a/src/cpp/utils/IPFinder.cpp +++ b/src/cpp/utils/IPFinder.cpp @@ -90,6 +90,7 @@ bool IPFinder::getIPs(std::vector* vec_name, bool return_loopback) info_IP info; info.type = family == AF_INET ? IP4 : IP6; info.name = std::string(buf); + info.dev = std::string(aa->AdapterName); // Currently not supported interfaces that not support multicast. if(aa->Flags & 0x0010) From 74cd8bf55cb1c4cd9f93e3cc5d7bea23b7632161 Mon Sep 17 00:00:00 2001 From: MiguelBarro <45819833+MiguelBarro@users.noreply.github.com> Date: Mon, 4 Feb 2019 12:30:17 +0100 Subject: [PATCH 24/34] Modify Windows version of UDPTransportInterface [4546] (#398) * Modified UDPTransportInterface to prevent closing sockets error logs over Windows * MAC fails in the same fashion that Windows. An agreement was reach to ignore the error in all platforms. --- include/fastrtps/transport/UDPTransportInterface.h | 2 +- include/fastrtps/transport/UDPv4Transport.h | 2 +- include/fastrtps/transport/UDPv6Transport.h | 2 +- src/cpp/transport/UDPTransportInterface.cpp | 13 +++++++++---- src/cpp/transport/UDPv4Transport.cpp | 2 +- src/cpp/transport/UDPv6Transport.cpp | 2 +- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/fastrtps/transport/UDPTransportInterface.h b/include/fastrtps/transport/UDPTransportInterface.h index 7d4d9435bba..ee6e4afd961 100644 --- a/include/fastrtps/transport/UDPTransportInterface.h +++ b/include/fastrtps/transport/UDPTransportInterface.h @@ -179,7 +179,7 @@ class UDPTransportInterface : public TransportInterface virtual void SetReceiveBufferSize(uint32_t size) = 0; virtual void SetSendBufferSize(uint32_t size) = 0; - virtual void SetSocketOutbountInterface(eProsimaUDPSocket&, const std::string&) = 0; + virtual void SetSocketOutboundInterface(eProsimaUDPSocket&, const std::string&) = 0; /* struct LocatorCompare { diff --git a/include/fastrtps/transport/UDPv4Transport.h b/include/fastrtps/transport/UDPv4Transport.h index c84241a64bc..4ddaf54ddda 100644 --- a/include/fastrtps/transport/UDPv4Transport.h +++ b/include/fastrtps/transport/UDPv4Transport.h @@ -114,7 +114,7 @@ class UDPv4Transport : public UDPTransportInterface virtual void SetReceiveBufferSize(uint32_t size) override; virtual void SetSendBufferSize(uint32_t size) override; - virtual void SetSocketOutbountInterface(eProsimaUDPSocket&, const std::string&) override; + virtual void SetSocketOutboundInterface(eProsimaUDPSocket&, const std::string&) override; }; } // namespace rtps diff --git a/include/fastrtps/transport/UDPv6Transport.h b/include/fastrtps/transport/UDPv6Transport.h index 72dd49ffdec..f645cbf8962 100644 --- a/include/fastrtps/transport/UDPv6Transport.h +++ b/include/fastrtps/transport/UDPv6Transport.h @@ -114,7 +114,7 @@ class UDPv6Transport : public UDPTransportInterface virtual void SetReceiveBufferSize(uint32_t size) override; virtual void SetSendBufferSize(uint32_t size) override; - virtual void SetSocketOutbountInterface(eProsimaUDPSocket&, const std::string&) override; + virtual void SetSocketOutboundInterface(eProsimaUDPSocket&, const std::string&) override; }; } // namespace rtps diff --git a/src/cpp/transport/UDPTransportInterface.cpp b/src/cpp/transport/UDPTransportInterface.cpp index 0ddf3ead38a..616432c77b6 100644 --- a/src/cpp/transport/UDPTransportInterface.cpp +++ b/src/cpp/transport/UDPTransportInterface.cpp @@ -279,7 +279,7 @@ bool UDPTransportInterface::OpenAndBindOutputSockets(const Locator_t& locator) // Outbounding first interface with already created socket. if(!locNames.empty()) { - SetSocketOutbountInterface(unicastSocket, (*locNames.begin()).name); + SetSocketOutboundInterface(unicastSocket, (*locNames.begin()).name); } // If more than one interface, then create sockets for outbounding multicast. @@ -293,7 +293,7 @@ bool UDPTransportInterface::OpenAndBindOutputSockets(const Locator_t& locator) { uint16_t new_port = 0; eProsimaUDPSocket multicastSocket = OpenAndBindUnicastOutputSocket(GenerateEndpoint((*locIt).name, new_port), new_port); - SetSocketOutbountInterface(multicastSocket, (*locIt).name); + SetSocketOutboundInterface(multicastSocket, (*locIt).name); UDPChannelResource* mSocket = new UDPChannelResource(multicastSocket); mSocket->only_multicast_purpose(true); @@ -318,7 +318,7 @@ bool UDPTransportInterface::OpenAndBindOutputSockets(const Locator_t& locator) if (IsInterfaceAllowed(infoIP.name)) { eProsimaUDPSocket unicastSocket = OpenAndBindUnicastOutputSocket(GenerateEndpoint(infoIP.name, port), port); - SetSocketOutbountInterface(unicastSocket, infoIP.name); + SetSocketOutboundInterface(unicastSocket, infoIP.name); if (!firstInterface) { getSocketPtr(unicastSocket)->set_option(ip::multicast::enable_loopback(true)); @@ -451,8 +451,13 @@ bool UDPTransportInterface::ReleaseInputChannel(const Locator_t& locator, const // We then send to the address of the input locator auto destinationEndpoint = GenerateLocalEndpoint(locator, port); - socket.send_to(asio::buffer("EPRORTPSCLOSE", 13), destinationEndpoint); + asio::error_code ec; + socket_base::message_flags flags = 0; + + // We ignore the error message because some OS don't allow this functionality like Windows (WSAENETUNREACH) or Mac (EADDRNOTAVAIL) + socket.send_to(asio::buffer("EPRORTPSCLOSE", 13), destinationEndpoint,flags, ec); + socket.close(); } else diff --git a/src/cpp/transport/UDPv4Transport.cpp b/src/cpp/transport/UDPv4Transport.cpp index d230597d9de..2f7ceb9bd64 100644 --- a/src/cpp/transport/UDPv4Transport.cpp +++ b/src/cpp/transport/UDPv4Transport.cpp @@ -478,7 +478,7 @@ void UDPv4Transport::SetSendBufferSize(uint32_t size) mConfiguration_.sendBufferSize = size; } -void UDPv4Transport::SetSocketOutbountInterface(eProsimaUDPSocket& socket, const std::string& sIp) +void UDPv4Transport::SetSocketOutboundInterface(eProsimaUDPSocket& socket, const std::string& sIp) { getSocketPtr(socket)->set_option(ip::multicast::outbound_interface(asio::ip::address_v4::from_string(sIp))); } diff --git a/src/cpp/transport/UDPv6Transport.cpp b/src/cpp/transport/UDPv6Transport.cpp index bf325ae719d..79d5a219863 100644 --- a/src/cpp/transport/UDPv6Transport.cpp +++ b/src/cpp/transport/UDPv6Transport.cpp @@ -432,7 +432,7 @@ void UDPv6Transport::SetSendBufferSize(uint32_t size) mConfiguration_.sendBufferSize = size; } -void UDPv6Transport::SetSocketOutbountInterface(eProsimaUDPSocket& socket, const std::string& sIp) +void UDPv6Transport::SetSocketOutboundInterface(eProsimaUDPSocket& socket, const std::string& sIp) { getSocketPtr(socket)->set_option(ip::multicast::outbound_interface(asio::ip::address_v6::from_string(sIp).scope_id())); } From 83a71669b50cfe0c7e4926cb035028a5c6cb8e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Mon, 4 Feb 2019 14:25:14 +0100 Subject: [PATCH 25/34] Activate asserts in RelWithDebInfo. (#399) --- CMakeLists.txt | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 358bb2c1039..338fe43cbc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,15 @@ message(STATUS "To change the version modify the file configure.ac") ############################################################################### option(EPROSIMA_INSTALLER "Activate the creation of a build to create windows installers" OFF) +############################################################################### +# eProsima build options +############################################################################### +option(EPROSIMA_BUILD "Activate internal building" OFF) + +if(EPROSIMA_INSTALLER) + set(EPROSIMA_BUILD ON) +endif() + ############################################################################### # Warning level ############################################################################### @@ -112,6 +121,10 @@ if(MSVC OR MSVC_IDE) if(EPROSIMA_EXTRA_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EPROSIMA_EXTRA_CMAKE_CXX_FLAGS}") endif() + + if(EPROSIMA_BUILD) + string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + endif() else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wextra -Wno-unknown-pragmas") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -119,6 +132,10 @@ else() elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error") endif() + + if(EPROSIMA_BUILD) + string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + endif() endif() ############################################################################### @@ -164,16 +181,6 @@ else() set(LICENSE_INSTALL_DIR ${DATA_INSTALL_DIR}/${PROJECT_NAME} CACHE PATH "Installation directory for licenses") endif() -############################################################################### -# eProsima build options -############################################################################### -option(EPROSIMA_BUILD "Activate internal building" OFF) - -if(EPROSIMA_INSTALLER) - set(EPROSIMA_BUILD ON) -endif() - - ############################################################################### # Internal debug messages ############################################################################### From 73accbf8bea7c7d7b85d0f42edf666fdf58c41c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Mon, 4 Feb 2019 15:52:44 +0100 Subject: [PATCH 26/34] Refs #4543. Fixed error notifying changes. (#400) This error occurs when the user unlock the reader mutex in the callback onNewCacheChangeAdded(). --- src/cpp/rtps/reader/StatefulReader.cpp | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 29c0048f128..02b6619c73d 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -498,30 +498,27 @@ bool StatefulReader::change_received(CacheChange_t* a_change, WriterProxy* prox) void StatefulReader::NotifyChanges(WriterProxy* prox) { GUID_t proxGUID = prox->m_att.guid; - SequenceNumber_t last_notified = update_last_notified(proxGUID, prox->available_changes_max()); + update_last_notified(proxGUID, prox->available_changes_max()); SequenceNumber_t nextChangeToNotify = prox->nextCacheChangeToBeNotified(); while (nextChangeToNotify != SequenceNumber_t::unknown()) { - if (nextChangeToNotify > last_notified) + mp_history->postSemaphore(); + + if (getListener() != nullptr) { - mp_history->postSemaphore(); + CacheChange_t* ch_to_give = nullptr; - if (getListener() != nullptr) + if (mp_history->get_change(nextChangeToNotify, proxGUID, &ch_to_give)) { - CacheChange_t* ch_to_give = nullptr; - - if (mp_history->get_change(nextChangeToNotify, proxGUID, &ch_to_give)) + if (!ch_to_give->isRead) { - if (!ch_to_give->isRead) - { - getListener()->onNewCacheChangeAdded((RTPSReader*)this, ch_to_give); - } + getListener()->onNewCacheChangeAdded((RTPSReader*)this, ch_to_give); } - - // Search again the WriterProxy because could be removed after the unlock. - if (!findWriterProxy(proxGUID, &prox)) - break; } + + // Search again the WriterProxy because could be removed after the unlock. + if (!findWriterProxy(proxGUID, &prox)) + break; } nextChangeToNotify = prox->nextCacheChangeToBeNotified(); From 4009e5e37cbb2483b48826a9b64651361697e371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Tue, 5 Feb 2019 11:54:26 +0100 Subject: [PATCH 27/34] Refs #4576. Forced c++11. (#401) --- CMakeLists.txt | 1 + cmake/common/check_configuration.cmake | 16 ++++++++++++---- include/fastrtps/config.h.in | 10 ++++++++++ test/blackbox/NetworkConf.cpp | 2 +- test/unittest/transport/TCPv4Tests.cpp | 2 +- test/unittest/transport/UDPv4Tests.cpp | 2 +- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 338fe43cbc6..cc3c339f222 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,7 @@ endif() # Test system configuration ############################################################################### include(${PROJECT_SOURCE_DIR}/cmake/common/check_configuration.cmake) +set(FORCE_CXX "11") check_stdcxx() check_compile_feature() check_endianness() diff --git a/cmake/common/check_configuration.cmake b/cmake/common/check_configuration.cmake index 884d4f67544..7f98cb8fec6 100644 --- a/cmake/common/check_configuration.cmake +++ b/cmake/common/check_configuration.cmake @@ -22,30 +22,38 @@ macro(check_stdcxx) set(HAVE_CXX1Y 0) set(HAVE_CXX11 0) set(HAVE_CXX0X 0) - if(SUPPORTS_CXX14) + if(SUPPORTS_CXX14 AND (NOT FORCE_CXX OR "${FORCE_CXX}" STREQUAL "14")) add_compile_options($<$:-std=c++14>) set(HAVE_CXX14 1) set(HAVE_CXX1Y 1) set(HAVE_CXX11 1) set(HAVE_CXX0X 1) + elseif(NOT SUPPORTS_CXX14 AND FORCE_CXX AND "${FORCE_CXX}" STREQUAL "14") + message(FATAL_ERROR "Force to support stdc++14 but not supported by the compiler") else() check_cxx_compiler_flag(-std=c++1y SUPPORTS_CXX1Y) - if(SUPPORTS_CXX1Y) + if(SUPPORTS_CXX1Y AND (NOT FORCE_CXX OR "${FORCE_CXX}" STREQUAL "1Y")) add_compile_options($<$:-std=c++1y>) set(HAVE_CXX1Y 1) set(HAVE_CXX11 1) set(HAVE_CXX0X 1) + elseif(NOT SUPPORTS_CXX1Y AND FORCE_CXX AND "${FORCE_CXX}" STREQUAL "1Y") + message(FATAL_ERROR "Force to support stdc++1y but not supported by the compiler") else() check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11) - if(SUPPORTS_CXX11) + if(SUPPORTS_CXX11 AND (NOT FORCE_CXX OR "${FORCE_CXX}" STREQUAL "11")) add_compile_options($<$:-std=c++11>) set(HAVE_CXX11 1) set(HAVE_CXX0X 1) + elseif(NOT SUPPORTS_CXX11 AND FORCE_CXX AND "${FORCE_CXX}" STREQUAL "11") + message(FATAL_ERROR "Force to support stdc++11 but not supported by the compiler") else() check_cxx_compiler_flag(-std=c++0x SUPPORTS_CXX0X) - if(SUPPORTS_CXX0X) + if(SUPPORTS_CXX0X AND (NOT FORCE_CXX OR "${FORCE_CXX}" STREQUAL "0X")) add_compile_options($<$:-std=c++0x>) set(HAVE_CXX0X 1) + elseif(NOT SUPPORTS_CXX0X AND FORCE_CXX AND "${FORCE_CXX}" STREQUAL "0X") + message(FATAL_ERROR "Force to support stdc++0x but not supported by the compiler") else() set(HAVE_CXX0X 0) endif() diff --git a/include/fastrtps/config.h.in b/include/fastrtps/config.h.in index e973a83565d..4745cea4ae5 100644 --- a/include/fastrtps/config.h.in +++ b/include/fastrtps/config.h.in @@ -22,6 +22,16 @@ #define GEN_API_VER 1 +// C++14 support defines +#ifndef HAVE_CXX14 +#define HAVE_CXX14 @HAVE_CXX14@ +#endif + +// C++1Y support defines +#ifndef HAVE_CXX1Y +#define HAVE_CXX1Y @HAVE_CXX1Y@ +#endif + // C++11 support defines #ifndef HAVE_CXX11 #define HAVE_CXX11 @HAVE_CXX11@ diff --git a/test/blackbox/NetworkConf.cpp b/test/blackbox/NetworkConf.cpp index d5a6d8129d1..e2a6f315d5a 100644 --- a/test/blackbox/NetworkConf.cpp +++ b/test/blackbox/NetworkConf.cpp @@ -32,7 +32,7 @@ static void GetIP4s(std::vector& interfaces) interfaces.end(), [](IPFinder::info_IP ip){return ip.type != IPFinder::IP4 && ip.type != IPFinder::IP4_LOCAL;}); interfaces.erase(new_end, interfaces.end()); - std::for_each(interfaces.begin(), interfaces.end(), [](auto&& loc) + std::for_each(interfaces.begin(), interfaces.end(), [](IPFinder::info_IP& loc) { loc.locator.kind = LOCATOR_KIND_UDPv4; }); diff --git a/test/unittest/transport/TCPv4Tests.cpp b/test/unittest/transport/TCPv4Tests.cpp index fc504a5aa60..6eaaf46a123 100644 --- a/test/unittest/transport/TCPv4Tests.cpp +++ b/test/unittest/transport/TCPv4Tests.cpp @@ -62,7 +62,7 @@ static void GetIP4s(std::vector& locNames, bool return_loopba locNames.end(), [](IPFinder::info_IP ip) {return ip.type != IPFinder::IP4 && ip.type != IPFinder::IP4_LOCAL; }); locNames.erase(new_end, locNames.end()); - std::for_each(locNames.begin(), locNames.end(), [](auto&& loc) + std::for_each(locNames.begin(), locNames.end(), [](IPFinder::info_IP& loc) { loc.locator.kind = LOCATOR_KIND_TCPv4; }); diff --git a/test/unittest/transport/UDPv4Tests.cpp b/test/unittest/transport/UDPv4Tests.cpp index 76f2fcdbfd2..94caed34d91 100644 --- a/test/unittest/transport/UDPv4Tests.cpp +++ b/test/unittest/transport/UDPv4Tests.cpp @@ -366,7 +366,7 @@ static void GetIP4s(std::vector& interfaces) return ip.type != IPFinder::IP4 && ip.type != IPFinder::IP4_LOCAL; }); interfaces.erase(new_end, interfaces.end()); - std::for_each(interfaces.begin(), interfaces.end(), [](auto&& loc) + std::for_each(interfaces.begin(), interfaces.end(), [](IPFinder::info_IP& loc) { loc.locator.kind = LOCATOR_KIND_UDPv4; }); From 35d00b5fd5df2e6aff2262bcfad64efb30e53514 Mon Sep 17 00:00:00 2001 From: MiguelCompany Date: Thu, 7 Feb 2019 16:22:10 +0100 Subject: [PATCH 28/34] Refs #4594. Fixed error return on parseXML (#403) --- src/cpp/xmlparser/XMLParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/xmlparser/XMLParser.cpp b/src/cpp/xmlparser/XMLParser.cpp index 32597a76651..4434b0cae4e 100644 --- a/src/cpp/xmlparser/XMLParser.cpp +++ b/src/cpp/xmlparser/XMLParser.cpp @@ -86,7 +86,7 @@ XMLP_ret XMLParser::parseXML(tinyxml2::XMLDocument& xmlDoc, up_base_node_t& root root.reset(new BaseNode{ NodeType::ROOT }); tinyxml2::XMLElement* node = p_root->FirstChildElement(); const char* tag = nullptr; - while (nullptr != node) + while ( (nullptr != node) && (ret == XMLP_ret::XML_OK)) { if (nullptr != (tag = node->Value())) { From d85f1517594929b20fe3541eb55ec0e9cd555db4 Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Tue, 12 Feb 2019 12:27:38 +0100 Subject: [PATCH 29/34] Refs #4642 Too old configuration method [#395] (#408) * Refs #4642 Too old configuration method. * Refs #4642 Removed unused WAN setting. --- examples/C++/Benchmark/BenchmarkPublisher.cpp | 32 ---------------- .../C++/Benchmark/BenchmarkSubscriber.cpp | 38 +------------------ 2 files changed, 2 insertions(+), 68 deletions(-) diff --git a/examples/C++/Benchmark/BenchmarkPublisher.cpp b/examples/C++/Benchmark/BenchmarkPublisher.cpp index 8b59986640f..f8faaa010cd 100644 --- a/examples/C++/Benchmark/BenchmarkPublisher.cpp +++ b/examples/C++/Benchmark/BenchmarkPublisher.cpp @@ -95,27 +95,11 @@ bool BenchMarkPublisher::init(int transport, ReliabilityQosPolicyKind reliabilit } else if (transport == 2) { - uint32_t kind = LOCATOR_KIND_TCPv4; PParam.rtps.useBuiltinTransports = false; - Locator_t unicast_locator; - unicast_locator.kind = kind; - IPLocator::setIPv4(unicast_locator, "127.0.0.1"); - unicast_locator.port = 5100; - IPLocator::setLogicalPort(unicast_locator, 7410); - PParam.rtps.defaultUnicastLocatorList.push_back(unicast_locator); // Publisher's data channel - - Locator_t meta_locator; - meta_locator.kind = kind; - IPLocator::setIPv4(meta_locator, "127.0.0.1"); - meta_locator.port = 5100; - IPLocator::setLogicalPort(meta_locator, 7402); - PParam.rtps.builtin.metatrafficUnicastLocatorList.push_back(meta_locator); // Publisher's meta channel - std::shared_ptr descriptor = std::make_shared(); descriptor->sendBufferSize = 8912896; // 8.5Mb descriptor->receiveBufferSize = 8912896; // 8.5Mb - descriptor->set_WAN_address("127.0.0.1"); descriptor->add_listener_port(5100); PParam.rtps.userTransports.push_back(descriptor); } @@ -125,27 +109,11 @@ bool BenchMarkPublisher::init(int transport, ReliabilityQosPolicyKind reliabilit } else if (transport == 4) { - uint32_t kind = LOCATOR_KIND_TCPv6; PParam.rtps.useBuiltinTransports = false; - Locator_t unicast_locator; - unicast_locator.kind = kind; - IPLocator::setIPv6(unicast_locator, "::1"); - unicast_locator.port = 5100; - IPLocator::setLogicalPort(unicast_locator, 7410); - PParam.rtps.defaultUnicastLocatorList.push_back(unicast_locator); // Publisher's data channel - - Locator_t meta_locator; - meta_locator.kind = kind; - IPLocator::setIPv6(meta_locator, "::1"); - meta_locator.port = 5100; - IPLocator::setLogicalPort(meta_locator, 7402); - PParam.rtps.builtin.metatrafficUnicastLocatorList.push_back(meta_locator); // Publisher's meta channel - std::shared_ptr descriptor = std::make_shared(); descriptor->sendBufferSize = 8912896; // 8.5Mb descriptor->receiveBufferSize = 8912896; // 8.5Mb - //descriptor->set_WAN_address("127.0.0.1"); descriptor->add_listener_port(5100); PParam.rtps.userTransports.push_back(descriptor); } diff --git a/examples/C++/Benchmark/BenchmarkSubscriber.cpp b/examples/C++/Benchmark/BenchmarkSubscriber.cpp index 640cf20b3aa..440b08cda03 100644 --- a/examples/C++/Benchmark/BenchmarkSubscriber.cpp +++ b/examples/C++/Benchmark/BenchmarkSubscriber.cpp @@ -73,24 +73,7 @@ bool BenchMarkSubscriber::init(int transport, ReliabilityQosPolicyKind reliabili initial_peer_locator.kind = kind; IPLocator::setIPv4(initial_peer_locator, "127.0.0.1"); initial_peer_locator.port = 5100; - IPLocator::setLogicalPort(initial_peer_locator, 7402); - PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's meta channel - IPLocator::setLogicalPort(initial_peer_locator, 7410); - PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's meta channel - - Locator_t unicast_locator; - unicast_locator.kind = kind; - IPLocator::setIPv4(unicast_locator, "127.0.0.1"); - unicast_locator.port = 5100; - IPLocator::setLogicalPort(unicast_locator, 7411); - PParam.rtps.defaultUnicastLocatorList.push_back(unicast_locator); // Subscriber's data channel - - Locator_t meta_locator; - meta_locator.kind = kind; - IPLocator::setIPv4(meta_locator, "127.0.0.1"); - meta_locator.port = 5100; - IPLocator::setLogicalPort(meta_locator, 7403); - PParam.rtps.builtin.metatrafficUnicastLocatorList.push_back(meta_locator); // Subscriber's meta channel + PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's channel PParam.rtps.useBuiltinTransports = false; std::shared_ptr descriptor = std::make_shared(); @@ -111,24 +94,7 @@ bool BenchMarkSubscriber::init(int transport, ReliabilityQosPolicyKind reliabili initial_peer_locator.kind = kind; IPLocator::setIPv6(initial_peer_locator, "::1"); initial_peer_locator.port = 5100; - IPLocator::setLogicalPort(initial_peer_locator, 7402); - PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's meta channel - IPLocator::setLogicalPort(initial_peer_locator, 7410); - PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's meta channel - - Locator_t unicast_locator; - unicast_locator.kind = kind; - IPLocator::setIPv6(unicast_locator, "::1"); - unicast_locator.port = 5100; - IPLocator::setLogicalPort(unicast_locator, 7411); - PParam.rtps.defaultUnicastLocatorList.push_back(unicast_locator); // Subscriber's data channel - - Locator_t meta_locator; - meta_locator.kind = kind; - IPLocator::setIPv6(meta_locator, "::1"); - meta_locator.port = 5100; - IPLocator::setLogicalPort(meta_locator, 7403); - PParam.rtps.builtin.metatrafficUnicastLocatorList.push_back(meta_locator); // Subscriber's meta channel + PParam.rtps.builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's channel PParam.rtps.useBuiltinTransports = false; std::shared_ptr descriptor = std::make_shared(); From bc61fa3fab63ced48416db86ebb8df4e0f0cebdf Mon Sep 17 00:00:00 2001 From: Luis Gasco Date: Wed, 13 Feb 2019 13:52:54 +0100 Subject: [PATCH 30/34] Refs #4642 Updating IDL-Parser submodule. (#415) --- thirdparty/idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/idl b/thirdparty/idl index bbeaad35d97..11e24c84771 160000 --- a/thirdparty/idl +++ b/thirdparty/idl @@ -1 +1 @@ -Subproject commit bbeaad35d971f798b5318a4cd9793b245ed2e608 +Subproject commit 11e24c84771855b64c6b2dc6fc6d63000ed71f11 From cb0a6e237eee4985ef8b1ffe6afbebd8e4116d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Thu, 14 Feb 2019 07:12:22 +0100 Subject: [PATCH 31/34] Refs #4661. Improved discovery time (#411) * Refs #4190. Improved discovery times. * Refs #4190. Applying conding style. --- .../rtps/attributes/ReaderAttributes.h | 2 +- .../rtps/attributes/WriterAttributes.h | 2 +- include/fastrtps/rtps/common/CacheChange.h | 4 +- .../timedevent/HeartbeatResponseDelay.h | 8 +- .../rtps/reader/timedevent/InitialAckNack.h | 10 +- include/fastrtps/rtps/writer/ReaderProxy.h | 3 - include/fastrtps/rtps/writer/StatefulWriter.h | 14 ++- .../writer/timedevent/NackResponseDelay.h | 49 ++++---- .../writer/timedevent/PeriodicHeartbeat.h | 9 +- .../builtin/discovery/endpoint/EDPSimple.cpp | 54 ++++----- .../participant/PDPSimpleListener.cpp | 2 +- src/cpp/rtps/messages/MessageReceiver.cpp | 2 +- src/cpp/rtps/reader/StatefulReader.cpp | 3 + .../timedevent/HeartbeatResponseDelay.cpp | 36 ++++-- .../rtps/reader/timedevent/InitialAckNack.cpp | 27 +++-- src/cpp/rtps/writer/ReaderProxy.cpp | 38 +++--- src/cpp/rtps/writer/StatefulWriter.cpp | 110 ++++++++++-------- src/cpp/rtps/writer/StatelessWriter.cpp | 2 +- .../writer/timedevent/NackResponseDelay.cpp | 27 +++-- .../writer/timedevent/PeriodicHeartbeat.cpp | 29 +++-- test/blackbox/BlackboxTests.cpp | 7 +- 21 files changed, 257 insertions(+), 181 deletions(-) diff --git a/include/fastrtps/rtps/attributes/ReaderAttributes.h b/include/fastrtps/rtps/attributes/ReaderAttributes.h index 82638e4184b..f8e637a9aa6 100644 --- a/include/fastrtps/rtps/attributes/ReaderAttributes.h +++ b/include/fastrtps/rtps/attributes/ReaderAttributes.h @@ -37,7 +37,7 @@ class ReaderTimes public: ReaderTimes() { - initialAcknackDelay.fraction = 200*1000*1000; + initialAcknackDelay.fraction = 300*1000*1000; heartbeatResponseDelay.fraction = 20*1000*1000; } diff --git a/include/fastrtps/rtps/attributes/WriterAttributes.h b/include/fastrtps/rtps/attributes/WriterAttributes.h index 82d0a280268..5ba2faf774a 100644 --- a/include/fastrtps/rtps/attributes/WriterAttributes.h +++ b/include/fastrtps/rtps/attributes/WriterAttributes.h @@ -45,7 +45,7 @@ class WriterTimes public: WriterTimes() { - initialHeartbeatDelay.fraction = 200*1000*1000; + initialHeartbeatDelay.fraction = 50*1000*1000; heartbeatPeriod.seconds = 3; nackResponseDelay.fraction = 20*1000*1000; } diff --git a/include/fastrtps/rtps/common/CacheChange.h b/include/fastrtps/rtps/common/CacheChange.h index b10fadb0255..9460e435736 100644 --- a/include/fastrtps/rtps/common/CacheChange.h +++ b/include/fastrtps/rtps/common/CacheChange.h @@ -201,8 +201,8 @@ namespace eprosima */ enum ChangeForReaderStatus_t{ UNSENT = 0, //!< UNSENT - UNACKNOWLEDGED = 1,//!< UNACKNOWLEDGED - REQUESTED = 2, //!< REQUESTED + REQUESTED = 1, //!< REQUESTED + UNACKNOWLEDGED = 2,//!< UNACKNOWLEDGED ACKNOWLEDGED = 3, //!< ACKNOWLEDGED UNDERWAY = 4 //!< UNDERWAY }; diff --git a/include/fastrtps/rtps/reader/timedevent/HeartbeatResponseDelay.h b/include/fastrtps/rtps/reader/timedevent/HeartbeatResponseDelay.h index 0bf717cccc5..862a35129ee 100644 --- a/include/fastrtps/rtps/reader/timedevent/HeartbeatResponseDelay.h +++ b/include/fastrtps/rtps/reader/timedevent/HeartbeatResponseDelay.h @@ -44,7 +44,9 @@ class HeartbeatResponseDelay:public TimedEvent * @param p_WP * @param interval */ - HeartbeatResponseDelay(WriterProxy* p_WP,double interval); + HeartbeatResponseDelay( + WriterProxy* p_WP, + double interval); /** * Method invoked when the event occurs @@ -52,7 +54,9 @@ class HeartbeatResponseDelay:public TimedEvent * @param code Code representing the status of the event * @param msg Message associated to the event */ - void event(EventCode code, const char* msg= nullptr); + void event( + EventCode code, + const char* msg= nullptr); //!Pointer to the WriterProxy associated with this specific event. WriterProxy* mp_WP; diff --git a/include/fastrtps/rtps/reader/timedevent/InitialAckNack.h b/include/fastrtps/rtps/reader/timedevent/InitialAckNack.h index 993a151b7c2..fae42ec7318 100644 --- a/include/fastrtps/rtps/reader/timedevent/InitialAckNack.h +++ b/include/fastrtps/rtps/reader/timedevent/InitialAckNack.h @@ -41,12 +41,16 @@ class WriterProxy; class InitialAckNack: public TimedEvent { public: + /** * * @param p_RP * @param interval */ - InitialAckNack(WriterProxy* wp, double interval); + InitialAckNack( + WriterProxy* wp, + double interval); + virtual ~InitialAckNack(); /** @@ -55,7 +59,9 @@ class InitialAckNack: public TimedEvent * @param code Code representing the status of the event * @param msg Message associated to the event */ - void event(EventCode code, const char* msg= nullptr); + void event( + EventCode code, + const char* msg= nullptr); //! RTPSMessageGroup_t m_cdrmessages; diff --git a/include/fastrtps/rtps/writer/ReaderProxy.h b/include/fastrtps/rtps/writer/ReaderProxy.h index 1c0541f6851..9d690045917 100644 --- a/include/fastrtps/rtps/writer/ReaderProxy.h +++ b/include/fastrtps/rtps/writer/ReaderProxy.h @@ -39,7 +39,6 @@ namespace eprosima { class StatefulWriter; - class NackResponseDelay; class NackSupressionDuration; @@ -161,8 +160,6 @@ namespace eprosima */ void setLastNackfragCount(uint32_t lastNackfragCount) { lastNackfragCount_ = lastNackfragCount; } - //! Timed Event to manage the Acknack response delay. - NackResponseDelay* mp_nackResponse; //! Timed Event to manage the delay to mark a change as UNACKED after sending it. NackSupressionDuration* mp_nackSupression; //! Last ack/nack count diff --git a/include/fastrtps/rtps/writer/StatefulWriter.h b/include/fastrtps/rtps/writer/StatefulWriter.h index 88309825d42..56fdad1b10e 100644 --- a/include/fastrtps/rtps/writer/StatefulWriter.h +++ b/include/fastrtps/rtps/writer/StatefulWriter.h @@ -33,6 +33,7 @@ namespace eprosima namespace rtps { class ReaderProxy; + class NackResponseDelay; /** * Class StatefulWriter, specialization of RTPSWriter that maintains information of each matched Reader. @@ -52,8 +53,15 @@ namespace eprosima PeriodicHeartbeat* mp_periodicHB; protected: + //!Constructor - StatefulWriter(RTPSParticipantImpl*,GUID_t& guid,WriterAttributes& att,WriterHistory* hist,WriterListener* listen=nullptr); + StatefulWriter( + RTPSParticipantImpl*, + GUID_t& guid, + WriterAttributes& att, + WriterHistory* hist, + WriterListener* listen=nullptr); + private: //!Count of the sent heartbeats. Count_t m_heartbeatCount; @@ -74,6 +82,10 @@ namespace eprosima unsigned int may_remove_change_; public: + + //! Timed Event to manage the Acknack response delay. + NackResponseDelay* nack_response_event_; + /** * Add a specific change to all ReaderLocators. * @param p Pointer to the change. diff --git a/include/fastrtps/rtps/writer/timedevent/NackResponseDelay.h b/include/fastrtps/rtps/writer/timedevent/NackResponseDelay.h index b7fe4cd1864..0e2303fb984 100644 --- a/include/fastrtps/rtps/writer/timedevent/NackResponseDelay.h +++ b/include/fastrtps/rtps/writer/timedevent/NackResponseDelay.h @@ -35,26 +35,35 @@ class ReaderProxy; * NackResponseDelay class use to delay the response to an NACK message. * @ingroup WRITER_MODULE */ -class NackResponseDelay:public TimedEvent { -public: - /** - * - * @param p_RP - * @param intervalmillisec - */ - NackResponseDelay(ReaderProxy* p_RP,double intervalmillisec); - virtual ~NackResponseDelay(); - - /** - * Method invoked when the event occurs - * - * @param code Code representing the status of the event - * @param msg Message associated to the event - */ - void event(EventCode code, const char* msg= nullptr); - - //!Associated reader proxy - ReaderProxy* mp_RP; +class NackResponseDelay:public TimedEvent +{ + public: + + /*! + * + * @param[in] writer Writer which creates this event. + * @param[in] interval_millisec Interval of the event in milliseconds. + */ + NackResponseDelay( + StatefulWriter* writer, + double interval_millisec); + + virtual ~NackResponseDelay(); + + /*! + * Method invoked when the event occurs + * + * @param code Code representing the status of the event + * @param msg Message associated to the event + */ + void event( + EventCode code, + const char* msg= nullptr); + + private: + + //!Associated writer + StatefulWriter* writer_; }; } } diff --git a/include/fastrtps/rtps/writer/timedevent/PeriodicHeartbeat.h b/include/fastrtps/rtps/writer/timedevent/PeriodicHeartbeat.h index e287ccb1157..9a7eb32b051 100644 --- a/include/fastrtps/rtps/writer/timedevent/PeriodicHeartbeat.h +++ b/include/fastrtps/rtps/writer/timedevent/PeriodicHeartbeat.h @@ -43,7 +43,10 @@ class PeriodicHeartbeat: public TimedEvent * @param p_RP * @param interval */ - PeriodicHeartbeat(StatefulWriter* p_RP,double interval); + PeriodicHeartbeat( + StatefulWriter* p_RP, + double interval); + virtual ~PeriodicHeartbeat(); /** @@ -52,7 +55,9 @@ class PeriodicHeartbeat: public TimedEvent * @param code Code representing the status of the event * @param msg Message associated to the event */ - void event(EventCode code, const char* msg= nullptr); + void event( + EventCode code, + const char* msg= nullptr); //! RTPSMessageGroup_t m_cdrmessages; diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp index e1ce1a6eb85..5148e449f24 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp @@ -42,6 +42,12 @@ namespace eprosima { namespace fastrtps{ namespace rtps { +// Default configuration values for EDP entities. +const Duration_t edp_heartbeat_period{1, 0}; // 1 second +const Duration_t edp_nack_response_delay{0, 400*1000*1000}; // ~93 milliseconds +const Duration_t edp_nack_supression_duration{0, 50*1000*1000}; // ~11 milliseconds +const Duration_t edp_heartbeat_response_delay{0, 50*1000*1000}; // ~11 milliseconds + EDPSimple::EDPSimple(PDPSimple* p,RTPSParticipantImpl* part): EDP(p,part), @@ -153,10 +159,9 @@ bool EDPSimple::createSEDPEndpoints() watt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - watt.times.nackResponseDelay.seconds = 0; - watt.times.nackResponseDelay.fraction = 0; - watt.times.initialHeartbeatDelay.seconds = 0; - watt.times.initialHeartbeatDelay.fraction = 0; + watt.times.heartbeatPeriod = edp_heartbeat_period; + watt.times.nackResponseDelay = edp_nack_response_delay; + watt.times.nackSupressionDuration = edp_nack_supression_duration; if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; @@ -184,10 +189,7 @@ bool EDPSimple::createSEDPEndpoints() ratt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; - ratt.times.heartbeatResponseDelay.seconds = 0; - ratt.times.heartbeatResponseDelay.fraction = 0; - ratt.times.initialAcknackDelay.seconds = 0; - ratt.times.initialAcknackDelay.fraction = 0; + ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; this->mp_subListen = new EDPSimpleSUBListener(this); created &=this->mp_RTPSParticipant->createReader(&raux,ratt,mp_SubReader.second,mp_subListen,c_EntityId_SEDPSubReader,true); if(created) @@ -218,10 +220,7 @@ bool EDPSimple::createSEDPEndpoints() ratt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; - ratt.times.heartbeatResponseDelay.seconds = 0; - ratt.times.heartbeatResponseDelay.fraction = 0; - ratt.times.initialAcknackDelay.seconds = 0; - ratt.times.initialAcknackDelay.fraction = 0; + ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; this->mp_pubListen = new EDPSimplePUBListener(this); created &=this->mp_RTPSParticipant->createReader(&raux,ratt,mp_PubReader.second,mp_pubListen,c_EntityId_SEDPPubReader,true); if(created) @@ -249,10 +248,9 @@ bool EDPSimple::createSEDPEndpoints() watt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - watt.times.nackResponseDelay.seconds = 0; - watt.times.nackResponseDelay.fraction = 0; - watt.times.initialHeartbeatDelay.seconds = 0; - watt.times.initialHeartbeatDelay.fraction = 0; + watt.times.heartbeatPeriod= edp_heartbeat_period; + watt.times.nackResponseDelay = edp_nack_response_delay; + watt.times.nackSupressionDuration = edp_nack_supression_duration; if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; @@ -301,10 +299,9 @@ bool EDPSimple::create_sedp_secure_endpoints() watt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - watt.times.nackResponseDelay.seconds = 0; - watt.times.nackResponseDelay.fraction = 0; - watt.times.initialHeartbeatDelay.seconds = 0; - watt.times.initialHeartbeatDelay.fraction = 0; + watt.times.heartbeatPeriod = edp_heartbeat_period; + watt.times.nackResponseDelay = edp_nack_response_delay; + watt.times.nackSupressionDuration = edp_nack_supression_duration; watt.endpoint.security_attributes().is_submessage_protected = part_attr.is_discovery_protected; watt.endpoint.security_attributes().plugin_endpoint_attributes = PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (part_attr.is_discovery_protected) @@ -343,10 +340,7 @@ bool EDPSimple::create_sedp_secure_endpoints() ratt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; - ratt.times.heartbeatResponseDelay.seconds = 0; - ratt.times.heartbeatResponseDelay.fraction = 0; - ratt.times.initialAcknackDelay.seconds = 0; - ratt.times.initialAcknackDelay.fraction = 0; + ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; ratt.endpoint.security_attributes().is_submessage_protected = part_attr.is_discovery_protected; ratt.endpoint.security_attributes().plugin_endpoint_attributes = PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (part_attr.is_discovery_protected) @@ -385,10 +379,7 @@ bool EDPSimple::create_sedp_secure_endpoints() ratt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; - ratt.times.heartbeatResponseDelay.seconds = 0; - ratt.times.heartbeatResponseDelay.fraction = 0; - ratt.times.initialAcknackDelay.seconds = 0; - ratt.times.initialAcknackDelay.fraction = 0; + ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; ratt.endpoint.security_attributes().is_submessage_protected = part_attr.is_discovery_protected; ratt.endpoint.security_attributes().plugin_endpoint_attributes = PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (part_attr.is_discovery_protected) @@ -423,10 +414,9 @@ bool EDPSimple::create_sedp_secure_endpoints() watt.endpoint.multicastLocatorList = this->mp_PDP->getLocalParticipantProxyData()->m_metatrafficMulticastLocatorList; //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - watt.times.nackResponseDelay.seconds = 0; - watt.times.nackResponseDelay.fraction = 0; - watt.times.initialHeartbeatDelay.seconds = 0; - watt.times.initialHeartbeatDelay.fraction = 0; + watt.times.heartbeatPeriod = edp_heartbeat_period; + watt.times.nackResponseDelay = edp_nack_response_delay; + watt.times.nackSupressionDuration = edp_nack_supression_duration; watt.endpoint.security_attributes().is_submessage_protected = part_attr.is_discovery_protected; watt.endpoint.security_attributes().plugin_endpoint_attributes = PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_VALID; if (part_attr.is_discovery_protected) diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPSimpleListener.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPSimpleListener.cpp index 50fd22c6d62..3747b651bcf 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPSimpleListener.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPSimpleListener.cpp @@ -105,8 +105,8 @@ void PDPSimpleListener::onNewCacheChangeAdded(RTPSReader* reader, const CacheCha this->mp_SPDP->m_participantProxies.push_back(pdata); lock.unlock(); - mp_SPDP->assignRemoteEndpoints(&participant_data); mp_SPDP->announceParticipantState(false); + mp_SPDP->assignRemoteEndpoints(&participant_data); } else { diff --git a/src/cpp/rtps/messages/MessageReceiver.cpp b/src/cpp/rtps/messages/MessageReceiver.cpp index bd3932d2f7e..9270ee7d1ba 100644 --- a/src/cpp/rtps/messages/MessageReceiver.cpp +++ b/src/cpp/rtps/messages/MessageReceiver.cpp @@ -1043,7 +1043,7 @@ bool MessageReceiver::proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* // TODO Not doing Acknowledged. if((*rit)->requested_fragment_set(writerSN, fnState)) { - (*rit)->mp_nackResponse->restart_timer(); + SF->nack_response_event_->restart_timer(); } } break; diff --git a/src/cpp/rtps/reader/StatefulReader.cpp b/src/cpp/rtps/reader/StatefulReader.cpp index 02b6619c73d..087c123a603 100644 --- a/src/cpp/rtps/reader/StatefulReader.cpp +++ b/src/cpp/rtps/reader/StatefulReader.cpp @@ -362,6 +362,9 @@ bool StatefulReader::processHeartbeatMsg(GUID_t &writerGUID, uint32_t hbCount, S if(pWP->m_lastHeartbeatCount < hbCount) { + // If it is the first heartbeat message, we can try to cancel initial ack. + pWP->mp_initialAcknack->cancel_timer(); + pWP->m_lastHeartbeatCount = hbCount; pWP->lost_changes_update(firstSN); fragmentedChangePitStop_->try_to_remove_until(firstSN, pWP->m_att.guid); diff --git a/src/cpp/rtps/reader/timedevent/HeartbeatResponseDelay.cpp b/src/cpp/rtps/reader/timedevent/HeartbeatResponseDelay.cpp index 343adac43f5..308e53b9243 100644 --- a/src/cpp/rtps/reader/timedevent/HeartbeatResponseDelay.cpp +++ b/src/cpp/rtps/reader/timedevent/HeartbeatResponseDelay.cpp @@ -40,18 +40,27 @@ HeartbeatResponseDelay::~HeartbeatResponseDelay() destroy(); } -HeartbeatResponseDelay::HeartbeatResponseDelay(WriterProxy* p_WP,double interval): - TimedEvent(p_WP->mp_SFR->getRTPSParticipant()->getEventResource().getIOService(), - p_WP->mp_SFR->getRTPSParticipant()->getEventResource().getThread(), interval), - mp_WP(p_WP), m_cdrmessages(p_WP->mp_SFR->getRTPSParticipant()->getMaxMessageSize(), - p_WP->mp_SFR->getRTPSParticipant()->getGuid().guidPrefix), - m_destination_locators(p_WP->m_att.endpoint.unicastLocatorList), - m_remote_endpoints(1, p_WP->m_att.guid) +HeartbeatResponseDelay::HeartbeatResponseDelay( + WriterProxy* p_WP, + double interval) + : TimedEvent(p_WP->mp_SFR->getRTPSParticipant()->getEventResource().getIOService(), + p_WP->mp_SFR->getRTPSParticipant()->getEventResource().getThread(), interval) + , mp_WP(p_WP) + , m_cdrmessages(p_WP->mp_SFR->getRTPSParticipant()->getMaxMessageSize(), + p_WP->mp_SFR->getRTPSParticipant()->getGuid().guidPrefix) + , m_destination_locators(mp_WP->mp_SFR->getRTPSParticipant()->network_factory(). + ShrinkLocatorLists({p_WP->m_att.endpoint.unicastLocatorList})) + , m_remote_endpoints(1, p_WP->m_att.guid) { - m_destination_locators.push_back(p_WP->m_att.endpoint.multicastLocatorList); + if(m_destination_locators.empty()) + { + m_destination_locators.push_back(p_WP->m_att.endpoint.multicastLocatorList); + } } -void HeartbeatResponseDelay::event(EventCode code, const char* msg) +void HeartbeatResponseDelay::event( + EventCode code, + const char* msg) { // Unused in release mode. @@ -68,8 +77,8 @@ void HeartbeatResponseDelay::event(EventCode code, const char* msg) // Stores missing changes but there is some fragments received. std::vector uncompleted_changes; - RTPSMessageGroup group(mp_WP->mp_SFR->getRTPSParticipant(), mp_WP->mp_SFR, RTPSMessageGroup::READER, m_cdrmessages, - m_destination_locators, m_remote_endpoints); + RTPSMessageGroup group(mp_WP->mp_SFR->getRTPSParticipant(), mp_WP->mp_SFR, RTPSMessageGroup::READER, + m_cdrmessages, m_destination_locators, m_remote_endpoints); if(!missing_changes.empty() || !mp_WP->m_heartbeatFinalFlag) { @@ -102,7 +111,9 @@ void HeartbeatResponseDelay::event(EventCode code, const char* msg) bool final = false; if(sns.isSetEmpty()) + { final = true; + } group.add_acknack(m_remote_endpoints, sns, mp_WP->mp_SFR->m_acknackCount, final, m_destination_locators); } @@ -143,7 +154,8 @@ void HeartbeatResponseDelay::event(EventCode code, const char* msg) ++mp_WP->mp_SFR->m_nackfragCount; logInfo(RTPS_READER,"Sending NACKFRAG for sample" << cit->sequenceNumber << ": "<< frag_sns;); - group.add_nackfrag(m_remote_endpoints, cit->sequenceNumber, frag_sns, mp_WP->mp_SFR->m_nackfragCount, m_destination_locators); + group.add_nackfrag(m_remote_endpoints, cit->sequenceNumber, frag_sns, mp_WP->mp_SFR->m_nackfragCount, + m_destination_locators); } } } diff --git a/src/cpp/rtps/reader/timedevent/InitialAckNack.cpp b/src/cpp/rtps/reader/timedevent/InitialAckNack.cpp index e8ef61a4004..70b8ab4bc9b 100644 --- a/src/cpp/rtps/reader/timedevent/InitialAckNack.cpp +++ b/src/cpp/rtps/reader/timedevent/InitialAckNack.cpp @@ -43,18 +43,27 @@ InitialAckNack::~InitialAckNack() destroy(); } -InitialAckNack::InitialAckNack(WriterProxy* wp, double interval): - TimedEvent(wp->mp_SFR->getRTPSParticipant()->getEventResource().getIOService(), - wp->mp_SFR->getRTPSParticipant()->getEventResource().getThread(), interval), - m_cdrmessages(wp->mp_SFR->getRTPSParticipant()->getMaxMessageSize(), - wp->mp_SFR->getRTPSParticipant()->getGuid().guidPrefix), wp_(wp), - m_destination_locators(wp->m_att.endpoint.unicastLocatorList), - m_remote_endpoints(1, wp->m_att.guid) +InitialAckNack::InitialAckNack( + WriterProxy* wp, + double interval) + : TimedEvent(wp->mp_SFR->getRTPSParticipant()->getEventResource().getIOService(), + wp->mp_SFR->getRTPSParticipant()->getEventResource().getThread(), interval) + , m_cdrmessages(wp->mp_SFR->getRTPSParticipant()->getMaxMessageSize(), + wp->mp_SFR->getRTPSParticipant()->getGuid().guidPrefix) + , wp_(wp) + , m_destination_locators(wp->mp_SFR->getRTPSParticipant()->network_factory(). + ShrinkLocatorLists({wp->m_att.endpoint.unicastLocatorList})) + , m_remote_endpoints(1, wp->m_att.guid) { - m_destination_locators.push_back(wp->m_att.endpoint.multicastLocatorList); + if(m_destination_locators.empty()) + { + m_destination_locators.push_back(wp->m_att.endpoint.multicastLocatorList); + } } -void InitialAckNack::event(EventCode code, const char* msg) +void InitialAckNack::event( + EventCode code, + const char* msg) { // Unused in release mode. diff --git a/src/cpp/rtps/writer/ReaderProxy.cpp b/src/cpp/rtps/writer/ReaderProxy.cpp index d2eafef567e..feeb6e48257 100644 --- a/src/cpp/rtps/writer/ReaderProxy.cpp +++ b/src/cpp/rtps/writer/ReaderProxy.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -34,14 +33,19 @@ using namespace eprosima::fastrtps::rtps; -ReaderProxy::ReaderProxy(const RemoteReaderAttributes& rdata,const WriterTimes& times,StatefulWriter* SW) : - m_att(rdata), mp_SFW(SW), - mp_nackResponse(nullptr), mp_nackSupression(nullptr), m_lastAcknackCount(0), - mp_mutex(new std::recursive_mutex()), lastNackfragCount_(0) +ReaderProxy::ReaderProxy( + const RemoteReaderAttributes& rdata, + const WriterTimes& times, + StatefulWriter* SW) + : m_att(rdata) + , mp_SFW(SW) + , mp_nackSupression(nullptr) + , m_lastAcknackCount(0) + , mp_mutex(new std::recursive_mutex()) + , lastNackfragCount_(0) { if(rdata.endpoint.reliabilityKind == RELIABLE) { - mp_nackResponse = new NackResponseDelay(this,TimeConv::Time_t2MilliSecondsDouble(times.nackResponseDelay)); mp_nackSupression = new NackSupressionDuration(this,TimeConv::Time_t2MilliSecondsDouble(times.nackSupressionDuration)); } @@ -61,12 +65,6 @@ ReaderProxy::~ReaderProxy() void ReaderProxy::destroy_timers() { - if(mp_nackResponse != nullptr) - { - delete(mp_nackResponse); - mp_nackResponse = nullptr; - } - if(mp_nackSupression != nullptr) { delete(mp_nackSupression); @@ -93,7 +91,9 @@ void ReaderProxy::addChange(const ChangeForReader_t& change) m_changesForReader.insert(change); //TODO (Ricardo) Remove this functionality from here. It is not his place. if (change.getStatus() == UNSENT) + { AsyncWriterThread::wakeUp(mp_SFW); + } } size_t ReaderProxy::countChangesForReader() const @@ -169,7 +169,7 @@ bool ReaderProxy::requested_changes_set(std::vector& seqNumSet { auto chit = m_changesForReader.find(ChangeForReader_t(*sit)); - if(chit != m_changesForReader.end()) + if(chit != m_changesForReader.end() && UNACKNOWLEDGED == chit->getStatus()) { ChangeForReader_t newch(*chit); newch.setStatus(REQUESTED); @@ -227,7 +227,9 @@ std::vector ReaderProxy::get_requested_changes() const void ReaderProxy::set_change_to_status(const SequenceNumber_t& seq_num, ChangeForReaderStatus_t status) { if(seq_num <= changesFromRLowMark_) + { return; + } auto it = m_changesForReader.find(ChangeForReader_t(seq_num)); bool mustWakeUpAsyncThread = false; @@ -278,13 +280,17 @@ bool ReaderProxy::mark_fragment_as_sent_for_change(const CacheChange_t* change, } if (mustWakeUpAsyncThread) + { AsyncWriterThread::wakeUp(mp_SFW); + } return allFragmentsSent; } void ReaderProxy::convert_status_on_all_changes(ChangeForReaderStatus_t previous, ChangeForReaderStatus_t next) { + assert(previous > next); + std::lock_guard guard(*mp_mutex); bool mustWakeUpAsyncThread = false; @@ -303,8 +309,10 @@ void ReaderProxy::convert_status_on_all_changes(ChangeForReaderStatus_t previous { // Note: we can perform this cast as we are not touching the sorting field (seq_num) const_cast(*it).setStatus(next); - if (next == UNSENT && previous != UNSENT) + if (next == UNSENT) + { mustWakeUpAsyncThread = true; + } } } @@ -312,7 +320,9 @@ void ReaderProxy::convert_status_on_all_changes(ChangeForReaderStatus_t previous } if (mustWakeUpAsyncThread) + { AsyncWriterThread::wakeUp(mp_SFW); + } } //TODO(Ricardo) diff --git a/src/cpp/rtps/writer/StatefulWriter.cpp b/src/cpp/rtps/writer/StatefulWriter.cpp index aa62254d2fc..9b052bf3506 100644 --- a/src/cpp/rtps/writer/StatefulWriter.cpp +++ b/src/cpp/rtps/writer/StatefulWriter.cpp @@ -46,14 +46,21 @@ using namespace eprosima::fastrtps::rtps; -StatefulWriter::StatefulWriter(RTPSParticipantImpl* pimpl,GUID_t& guid, - WriterAttributes& att,WriterHistory* hist,WriterListener* listen): - RTPSWriter(pimpl, guid, att, hist, listen), - mp_periodicHB(nullptr), m_times(att.times), - all_acked_(false), may_remove_change_(0), - disableHeartbeatPiggyback_(att.disableHeartbeatPiggyback), - sendBufferSize_(pimpl->get_min_network_send_buffer_size()), - currentUsageSendBufferSize_(static_cast(pimpl->get_min_network_send_buffer_size())) +StatefulWriter::StatefulWriter( + RTPSParticipantImpl* pimpl, + GUID_t& guid, + WriterAttributes& att, + WriterHistory* hist, + WriterListener* listen) + : RTPSWriter(pimpl, guid, att, hist, listen) + , mp_periodicHB(nullptr) + , m_times(att.times) + , all_acked_(false) + , may_remove_change_(0) + , nack_response_event_(nullptr) + , disableHeartbeatPiggyback_(att.disableHeartbeatPiggyback) + , sendBufferSize_(pimpl->get_min_network_send_buffer_size()) + , currentUsageSendBufferSize_(static_cast(pimpl->get_min_network_send_buffer_size())) { m_heartbeatCount = 0; if(guid.entityId == c_EntityId_SEDPPubWriter) @@ -65,6 +72,7 @@ StatefulWriter::StatefulWriter(RTPSParticipantImpl* pimpl,GUID_t& guid, else m_HBReaderEntityId = c_EntityId_Unknown; mp_periodicHB = new PeriodicHeartbeat(this,TimeConv::Time_t2MilliSecondsDouble(m_times.heartbeatPeriod)); + nack_response_event_ = new NackResponseDelay(this, TimeConv::Time_t2MilliSecondsDouble(m_times.nackResponseDelay)); } @@ -74,16 +82,26 @@ StatefulWriter::~StatefulWriter() logInfo(RTPS_WRITER,"StatefulWriter destructor"); - for(std::vector::iterator it = matched_readers.begin(); - it != matched_readers.end(); ++it) + for(std::vector::iterator it = matched_readers.begin(); it != matched_readers.end(); ++it) + { (*it)->destroy_timers(); + } + + if(nack_response_event_ != nullptr) + { + delete(nack_response_event_); + nack_response_event_ = nullptr; + } if(mp_periodicHB !=nullptr) + { delete(mp_periodicHB); + } - for(std::vector::iterator it = matched_readers.begin(); - it!=matched_readers.end();++it) + for(std::vector::iterator it = matched_readers.begin(); it!=matched_readers.end();++it) + { delete(*it); + } } /* @@ -142,13 +160,16 @@ void StatefulWriter::unsent_change_added_to_history(CacheChange_t* change) if (m_separateSendingEnabled) { guids.at(0) = (*it)->m_att.guid; - RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, - (*it)->m_att.endpoint.remoteLocatorList, guids); - if (!group.add_data(*change, guids, (*it)->m_att.endpoint.remoteLocatorList, (*it)->m_att.expectsInlineQos)) + LocatorList_t remote_locators_shrinked{mp_RTPSParticipant->network_factory().ShrinkLocatorLists( + {(*it)->m_att.endpoint.remoteLocatorList})}; + + RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, + remote_locators_shrinked, guids); + if (!group.add_data(*change, guids, remote_locators_shrinked, (*it)->m_att.expectsInlineQos)) { logError(RTPS_WRITER, "Error sending change " << change->sequenceNumber); } - send_heartbeat_piggyback_nts_(guids, (*it)->m_att.endpoint.remoteLocatorList, group); + send_heartbeat_piggyback_nts_(guids, remote_locators_shrinked, group); } } @@ -242,8 +263,10 @@ void StatefulWriter::send_any_unsent_changes() // Specific destination message group guids.at(0) = remoteReader->m_att.guid; - const LocatorList_t& locators = remoteReader->m_att.endpoint.remoteLocatorList; - RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, locators, guids); + const LocatorList_t remote_locators_shrinked{mp_RTPSParticipant->network_factory().ShrinkLocatorLists( + {remoteReader->m_att.endpoint.remoteLocatorList})}; + RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, + remote_locators_shrinked, guids); // Loop all changes bool is_reliable = (remoteReader->m_att.endpoint.reliabilityKind == RELIABLE); @@ -255,7 +278,8 @@ void StatefulWriter::send_any_unsent_changes() if (unsentChange->isRelevant() && unsentChange->isValid()) { // As we checked we are not async, we know we cannot have fragments - if (group.add_data(*(unsentChange->getChange()), guids, locators, remoteReader->m_att.expectsInlineQos)) + if (group.add_data(*(unsentChange->getChange()), guids, remote_locators_shrinked, + remoteReader->m_att.expectsInlineQos)) { if (is_reliable) { @@ -286,7 +310,7 @@ void StatefulWriter::send_any_unsent_changes() if (!irrelevant.empty()) { - group.add_gap(irrelevant, guids, locators); + group.add_gap(irrelevant, guids, remote_locators_shrinked); } } // Readers loop } @@ -558,16 +582,18 @@ bool StatefulWriter::matched_reader_add(RemoteReaderAttributes& rdata) assert(last_seq + 1 == current_seq); std::vector guids(1, rp->m_att.guid); - const LocatorList_t& locatorsList = rp->m_att.endpoint.remoteLocatorList; - RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, locatorsList, guids); + const LocatorList_t remote_locators_shrinked{mp_RTPSParticipant->network_factory().ShrinkLocatorLists( + {rp->m_att.endpoint.remoteLocatorList})}; + RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, + remote_locators_shrinked, guids); // Send initial heartbeat - send_heartbeat_nts_(guids, locatorsList, group, false); + send_heartbeat_nts_(guids, remote_locators_shrinked, group, false); // Send Gap if(!not_relevant_changes.empty()) { - group.add_gap(not_relevant_changes, guids, locatorsList); + group.add_gap(not_relevant_changes, guids, remote_locators_shrinked); } // Always activate heartbeat period. We need a confirmation of the reader. @@ -841,26 +867,9 @@ void StatefulWriter::updateTimes(const WriterTimes& times) } if(m_times.nackResponseDelay != times.nackResponseDelay) { - for(std::vector::iterator it = this->matched_readers.begin(); - it!=this->matched_readers.end();++it) - { - std::lock_guard rguard(*(*it)->mp_mutex); - - if((*it)->mp_nackResponse != nullptr) // It is reliable - (*it)->mp_nackResponse->update_interval(times.nackResponseDelay); - } - } - if(m_times.heartbeatPeriod != times.heartbeatPeriod) - { - this->mp_periodicHB->update_interval(times.heartbeatPeriod); - } - if(m_times.nackResponseDelay != times.nackResponseDelay) - { - for(std::vector::iterator it = this->matched_readers.begin(); - it!=this->matched_readers.end();++it) + if(nack_response_event_ != nullptr) // It is reliable { - std::lock_guard rguard(*(*it)->mp_mutex); - (*it)->mp_nackResponse->update_interval(times.nackResponseDelay); + nack_response_event_->update_interval(times.nackResponseDelay); } } if(m_times.nackSupressionDuration != times.nackSupressionDuration) @@ -890,11 +899,12 @@ SequenceNumber_t StatefulWriter::next_sequence_number() const void StatefulWriter::send_heartbeat_to_nts(ReaderProxy& remoteReaderProxy, bool final) { std::vector tmp_guids(1, remoteReaderProxy.m_att.guid); - const LocatorList_t& locators = remoteReaderProxy.m_att.endpoint.remoteLocatorList; + const LocatorList_t remote_locators_shrinked{mp_RTPSParticipant->network_factory().ShrinkLocatorLists( + {remoteReaderProxy.m_att.endpoint.remoteLocatorList})}; RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, - locators, tmp_guids); + remote_locators_shrinked, tmp_guids); - send_heartbeat_nts_(tmp_guids, locators, group, final); + send_heartbeat_nts_(tmp_guids, remote_locators_shrinked, group, final); } void StatefulWriter::send_heartbeat_nts_(const std::vector& remote_readers, const LocatorList_t &locators, @@ -974,21 +984,21 @@ void StatefulWriter::process_acknack(const GUID_t reader_guid, uint32_t ack_coun if(remote_reader->m_lastAcknackCount < ack_count) { remote_reader->m_lastAcknackCount = ack_count; - if(sn_set.base != SequenceNumber_t(0, 0)) + if(sn_set.base > SequenceNumber_t(0, 0)) { // Sequence numbers before Base are set as Acknowledged. remote_reader->acked_changes_set(sn_set.base); std::vector set_vec = sn_set.get_set(); - if (remote_reader->requested_changes_set(set_vec) && remote_reader->mp_nackResponse != nullptr) + if (remote_reader->requested_changes_set(set_vec) && nack_response_event_ != nullptr) { - remote_reader->mp_nackResponse->restart_timer(); + nack_response_event_->restart_timer(); } else if(!final_flag) { mp_periodicHB->restart_timer(); } } - else if(sn_set.isSetEmpty() && !final_flag) + else if(SequenceNumber_t{0, 0} == remote_reader->get_low_mark() && sn_set.isSetEmpty() && !final_flag) { send_heartbeat_to_nts(*remote_reader, true); } diff --git a/src/cpp/rtps/writer/StatelessWriter.cpp b/src/cpp/rtps/writer/StatelessWriter.cpp index 6d3715f2ff6..003ebdf5fba 100644 --- a/src/cpp/rtps/writer/StatelessWriter.cpp +++ b/src/cpp/rtps/writer/StatelessWriter.cpp @@ -89,7 +89,7 @@ void StatelessWriter::unsent_change_added_to_history(CacheChange_t* cptr) guids.at(0) = it->guid; RTPSMessageGroup group(mp_RTPSParticipant, this, RTPSMessageGroup::WRITER, m_cdrmessages, it->endpoint.unicastLocatorList, guids); - + if (!group.add_data(*cptr, guids, it->endpoint.unicastLocatorList, false)) { logError(RTPS_WRITER, "Error sending change " << cptr->sequenceNumber); diff --git a/src/cpp/rtps/writer/timedevent/NackResponseDelay.cpp b/src/cpp/rtps/writer/timedevent/NackResponseDelay.cpp index 0784202ac71..3af1afd1fe7 100644 --- a/src/cpp/rtps/writer/timedevent/NackResponseDelay.cpp +++ b/src/cpp/rtps/writer/timedevent/NackResponseDelay.cpp @@ -40,24 +40,31 @@ NackResponseDelay::~NackResponseDelay() destroy(); } -NackResponseDelay::NackResponseDelay(ReaderProxy* p_RP,double millisec): - TimedEvent(p_RP->mp_SFW->getRTPSParticipant()->getEventResource().getIOService(), - p_RP->mp_SFW->getRTPSParticipant()->getEventResource().getThread(), millisec), - mp_RP(p_RP) +NackResponseDelay::NackResponseDelay( + StatefulWriter* writer, + double millisec) + : TimedEvent(writer->getRTPSParticipant()->getEventResource().getIOService(), + writer->getRTPSParticipant()->getEventResource().getThread(), millisec) + , writer_(writer) { } -void NackResponseDelay::event(EventCode code, const char* msg) +void NackResponseDelay::event( + EventCode code, + const char* msg) { - // Unused in release mode. (void)msg; - if(code == EVENT_SUCCESS) + if (code == EVENT_SUCCESS) { logInfo(RTPS_WRITER,"Responding to Acknack msg";); - std::lock_guard guardW(*mp_RP->mp_SFW->getMutex()); - std::lock_guard guard(*mp_RP->mp_mutex); - mp_RP->convert_status_on_all_changes(REQUESTED, UNSENT); + std::lock_guard guardW(*writer_->getMutex()); + for (auto reader_proxy = writer_->matchedReadersBegin(); reader_proxy != writer_->matchedReadersEnd(); + ++reader_proxy) + { + std::lock_guard guardR(*(*reader_proxy)->mp_mutex); + (*reader_proxy)->convert_status_on_all_changes(REQUESTED, UNSENT); + } } } diff --git a/src/cpp/rtps/writer/timedevent/PeriodicHeartbeat.cpp b/src/cpp/rtps/writer/timedevent/PeriodicHeartbeat.cpp index b1c5205bb67..68ae00d0d58 100644 --- a/src/cpp/rtps/writer/timedevent/PeriodicHeartbeat.cpp +++ b/src/cpp/rtps/writer/timedevent/PeriodicHeartbeat.cpp @@ -42,16 +42,21 @@ PeriodicHeartbeat::~PeriodicHeartbeat() destroy(); } -PeriodicHeartbeat::PeriodicHeartbeat(StatefulWriter* p_SFW, double interval): - TimedEvent(p_SFW->getRTPSParticipant()->getEventResource().getIOService(), - p_SFW->getRTPSParticipant()->getEventResource().getThread(), interval), - m_cdrmessages(p_SFW->getRTPSParticipant()->getMaxMessageSize(), - p_SFW->getRTPSParticipant()->getGuid().guidPrefix), mp_SFW(p_SFW) +PeriodicHeartbeat::PeriodicHeartbeat( + StatefulWriter* p_SFW, + double interval) + : TimedEvent(p_SFW->getRTPSParticipant()->getEventResource().getIOService(), + p_SFW->getRTPSParticipant()->getEventResource().getThread(), interval) + , m_cdrmessages(p_SFW->getRTPSParticipant()->getMaxMessageSize(), + p_SFW->getRTPSParticipant()->getGuid().guidPrefix) + , mp_SFW(p_SFW) { } -void PeriodicHeartbeat::event(EventCode code, const char* msg) +void PeriodicHeartbeat::event( + EventCode code, + const char* msg) { // Unused in release mode. @@ -79,7 +84,7 @@ void PeriodicHeartbeat::event(EventCode code, const char* msg) else { Count_t heartbeatCount = 0; - LocatorList_t locList; + std::vector locList; std::vector remote_readers; {//BEGIN PROTECTION @@ -94,8 +99,7 @@ void PeriodicHeartbeat::event(EventCode code, const char* msg) unacked_changes = true; } } - locList.push_back((*it)->m_att.endpoint.unicastLocatorList); - locList.push_back((*it)->m_att.endpoint.multicastLocatorList); + locList.push_back((*it)->m_att.endpoint.remoteLocatorList); remote_readers.push_back((*it)->m_att.guid); } @@ -126,9 +130,10 @@ void PeriodicHeartbeat::event(EventCode code, const char* msg) RTPSMessageGroup group(mp_SFW->getRTPSParticipant(), mp_SFW, RTPSMessageGroup::WRITER, m_cdrmessages); // FinalFlag is always false because this class is used only by StatefulWriter in Reliable. - group.add_heartbeat(remote_readers, - firstSeq, lastSeq, heartbeatCount, false, false, locList); - logInfo(RTPS_WRITER, mp_SFW->getGuid().entityId << " Sending Heartbeat (" << firstSeq << " - " << lastSeq << ")"); + group.add_heartbeat(remote_readers, firstSeq, lastSeq, heartbeatCount, false, false, + mp_SFW->getRTPSParticipant()->network_factory().ShrinkLocatorLists(locList)); + logInfo(RTPS_WRITER, mp_SFW->getGuid().entityId << " Sending Heartbeat (" << firstSeq + << " - " << lastSeq << ")"); } } diff --git a/test/blackbox/BlackboxTests.cpp b/test/blackbox/BlackboxTests.cpp index fdaa8b366bf..44245c7ba74 100644 --- a/test/blackbox/BlackboxTests.cpp +++ b/test/blackbox/BlackboxTests.cpp @@ -2055,9 +2055,6 @@ BLACKBOXTEST(BlackBox, EndpointRediscovery) writer.wait_discovery(); reader.wait_discovery(); - // Wait heartbeat period of builtin endpoints - std::this_thread::sleep_for(std::chrono::seconds(4)); - test_UDPv4Transport::test_UDPv4Transport_ShutdownAllNetwork = true; writer.wait_reader_undiscovery(); @@ -5716,8 +5713,8 @@ BLACKBOXTEST(BlackBox, MulticastCommunicationOkReader) ASSERT_TRUE(readerMultiOk.isInitialized()); - writer.wait_discovery(std::chrono::seconds(3)); - readerMultiOk.wait_discovery(std::chrono::seconds(3)); + writer.wait_discovery(); + readerMultiOk.wait_discovery(); ASSERT_TRUE(writer.is_matched()); ASSERT_TRUE(readerMultiOk.is_matched()); } From 5827bb94408f3d5d2284d2e77b482ff84738ef3f Mon Sep 17 00:00:00 2001 From: MiguelCompany Date: Thu, 14 Feb 2019 12:38:12 +0100 Subject: [PATCH 32/34] Correctly handling octetsToNextHeader value zero [4665] (#414) * Refs #4339. Fix #375 by correctly handling octetsToNextHeader value cero. * Refs #4665. Removed submsgLengthLarger and turned submessageLength into uint32_t * Refs #4661. Fixed documentation lines about endpoint times. --- .../rtps/attributes/ReaderAttributes.h | 4 +- .../rtps/attributes/WriterAttributes.h | 4 +- .../fastrtps/rtps/messages/MessageReceiver.h | 25 ++-- .../fastrtps/rtps/messages/RTPS_messages.h | 17 +-- src/cpp/rtps/messages/MessageReceiver.cpp | 119 +++++++----------- src/cpp/transport/test_TCPv4Transport.cpp | 22 +++- src/cpp/transport/test_UDPv4Transport.cpp | 22 +++- 7 files changed, 110 insertions(+), 103 deletions(-) diff --git a/include/fastrtps/rtps/attributes/ReaderAttributes.h b/include/fastrtps/rtps/attributes/ReaderAttributes.h index f8e637a9aa6..c9d7983e298 100644 --- a/include/fastrtps/rtps/attributes/ReaderAttributes.h +++ b/include/fastrtps/rtps/attributes/ReaderAttributes.h @@ -49,9 +49,9 @@ class ReaderTimes (this->heartbeatResponseDelay == b.heartbeatResponseDelay); } - //!Initial AckNack delay. Default value ~45ms. + //!Initial AckNack delay. Default value ~70ms. Duration_t initialAcknackDelay; - //!Delay to be applied when a hearbeat message is received, default value ~4.5ms. + //!Delay to be applied when a hearbeat message is received, default value ~5ms. Duration_t heartbeatResponseDelay; }; diff --git a/include/fastrtps/rtps/attributes/WriterAttributes.h b/include/fastrtps/rtps/attributes/WriterAttributes.h index 5ba2faf774a..d44c688d1a5 100644 --- a/include/fastrtps/rtps/attributes/WriterAttributes.h +++ b/include/fastrtps/rtps/attributes/WriterAttributes.h @@ -60,11 +60,11 @@ class WriterTimes (this->nackSupressionDuration == b.nackSupressionDuration); } - //! Initial heartbeat delay. Default value ~45ms. + //! Initial heartbeat delay. Default value ~11ms. Duration_t initialHeartbeatDelay; //! Periodic HB period, default value 3s. Duration_t heartbeatPeriod; - //!Delay to apply to the response of a ACKNACK message, default value ~45ms. + //!Delay to apply to the response of a ACKNACK message, default value ~5ms. Duration_t nackResponseDelay; //!This time allows the RTPSWriter to ignore nack messages too soon after the data as sent, default value 0s. Duration_t nackSupressionDuration; diff --git a/include/fastrtps/rtps/messages/MessageReceiver.h b/include/fastrtps/rtps/messages/MessageReceiver.h index acc4cafb6e8..fc8a4686995 100644 --- a/include/fastrtps/rtps/messages/MessageReceiver.h +++ b/include/fastrtps/rtps/messages/MessageReceiver.h @@ -127,21 +127,20 @@ class MessageReceiver * * @param msg * @param smh - * @param last * @return */ - bool proc_Submsg_Data(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_DataFrag(CDRMessage_t*msg, SubmessageHeader_t* smh, bool*last); - bool proc_Submsg_Acknack(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_Heartbeat(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_Gap(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_InfoTS(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_InfoDST(CDRMessage_t*msg,SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_InfoSRC(CDRMessage_t*msg,SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* smh, bool*last); - bool proc_Submsg_HeartbeatFrag(CDRMessage_t*msg, SubmessageHeader_t* smh, bool*last); - bool proc_Submsg_SecureMessage(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); - bool proc_Submsg_SecureSubMessage(CDRMessage_t*msg, SubmessageHeader_t* smh,bool*last); + bool proc_Submsg_Data(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_DataFrag(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_Acknack(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_Heartbeat(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_Gap(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_InfoTS(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_InfoDST(CDRMessage_t*msg,SubmessageHeader_t* smh); + bool proc_Submsg_InfoSRC(CDRMessage_t*msg,SubmessageHeader_t* smh); + bool proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_HeartbeatFrag(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_SecureMessage(CDRMessage_t*msg, SubmessageHeader_t* smh); + bool proc_Submsg_SecureSubMessage(CDRMessage_t*msg, SubmessageHeader_t* smh); RTPSParticipantImpl* participant_; }; diff --git a/include/fastrtps/rtps/messages/RTPS_messages.h b/include/fastrtps/rtps/messages/RTPS_messages.h index 77bb294b669..e5672e5f342 100644 --- a/include/fastrtps/rtps/messages/RTPS_messages.h +++ b/include/fastrtps/rtps/messages/RTPS_messages.h @@ -77,17 +77,18 @@ enum SubmessageId : uint8_t } //!@brief Structure SubmessageHeader_t, used to contain the header information of a submessage. - struct SubmessageHeader_t{ + struct SubmessageHeader_t + { octet submessageId; - uint16_t submessageLength; - uint32_t submsgLengthLarger; + uint32_t submessageLength; SubmessageFlag flags; + bool is_last; - SubmessageHeader_t(): - submessageId(0), - submessageLength(0), - submsgLengthLarger(0), - flags(0) + SubmessageHeader_t() + : submessageId(0) + , submessageLength(0) + , flags(0) + , is_last(false) {} }; diff --git a/src/cpp/rtps/messages/MessageReceiver.cpp b/src/cpp/rtps/messages/MessageReceiver.cpp index 9270ee7d1ba..f1b62011071 100644 --- a/src/cpp/rtps/messages/MessageReceiver.cpp +++ b/src/cpp/rtps/messages/MessageReceiver.cpp @@ -181,7 +181,6 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) #endif // Loop until there are no more submessages - bool last_submsg = false; bool valid; int count = 0; SubmessageHeader_t submsgh; //Current submessage header @@ -209,16 +208,6 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) if(!readSubmessageHeader(submessage, &submsgh)) return; - if(submessage->pos + submsgh.submessageLength > submessage->length) - { - logWarning(RTPS_MSG_IN,IDSTRING"SubMsg of invalid length ("<pos << "/" << submessage->length << ")"); - return; - } - if(submsgh.submessageLength == 0) //THIS IS THE LAST SUBMESSAGE - { - submsgh.submsgLengthLarger = submessage->length - submessage->pos; - } valid = true; count++; switch(submsgh.submessageId) @@ -233,7 +222,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN,IDSTRING"Data Submsg received, processing."); - valid = proc_Submsg_Data(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_Data(submessage, &submsgh); } break; } @@ -246,7 +235,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN, IDSTRING"DataFrag Submsg received, processing."); - valid = proc_Submsg_DataFrag(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_DataFrag(submessage, &submsgh); } break; case GAP: @@ -259,7 +248,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN,IDSTRING"Gap Submsg received, processing..."); - valid = proc_Submsg_Gap(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_Gap(submessage, &submsgh); } break; } @@ -273,7 +262,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN,IDSTRING"Acknack Submsg received, processing..."); - valid = proc_Submsg_Acknack(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_Acknack(submessage, &submsgh); } break; } @@ -287,7 +276,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN, IDSTRING"NackFrag Submsg received, processing..."); - valid = proc_Submsg_NackFrag(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_NackFrag(submessage, &submsgh); } break; } @@ -301,7 +290,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN,IDSTRING"Heartbeat Submsg received, processing..."); - valid = proc_Submsg_Heartbeat(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_Heartbeat(submessage, &submsgh); } break; } @@ -315,7 +304,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) else { logInfo(RTPS_MSG_IN, IDSTRING"HeartbeatFrag Submsg received, processing..."); - valid = proc_Submsg_HeartbeatFrag(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_HeartbeatFrag(submessage, &submsgh); } break; } @@ -325,16 +314,16 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) break; case INFO_DST: logInfo(RTPS_MSG_IN,IDSTRING"InfoDST message received, processing..."); - valid = proc_Submsg_InfoDST(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_InfoDST(submessage, &submsgh); break; case INFO_SRC: logInfo(RTPS_MSG_IN,IDSTRING"InfoSRC message received, processing..."); - valid = proc_Submsg_InfoSRC(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_InfoSRC(submessage, &submsgh); break; case INFO_TS: { logInfo(RTPS_MSG_IN,IDSTRING"InfoTS Submsg received, processing..."); - valid = proc_Submsg_InfoTS(submessage, &submsgh, &last_submsg); + valid = proc_Submsg_InfoTS(submessage, &submsgh); break; } case INFO_REPLY: @@ -346,7 +335,7 @@ void MessageReceiver::processCDRMsg(const Locator_t& loc, CDRMessage_t*msg) break; } - if(!valid || last_submsg) + if(!valid || submsgh.is_last) { break; } @@ -399,11 +388,31 @@ bool MessageReceiver::readSubmessageHeader(CDRMessage_t* msg, SubmessageHeader_t smh->flags = msg->buffer[msg->pos];msg->pos++; //Set endianness of message msg->msg_endian = smh->flags & BIT(0) ? LITTLEEND : BIGEND; - CDRMessage::readUInt16(msg,&smh->submessageLength); + uint16_t length = 0; + CDRMessage::readUInt16(msg,&length); + if (msg->pos + length > msg->length) + { + logWarning(RTPS_MSG_IN, IDSTRING"SubMsg of invalid length (" << length + << ") with current msg position/length (" << msg->pos << "/" << msg->length << ")"); + return false; + } + + if ( (length == 0) && (smh->submessageId != INFO_TS) && (smh->submessageId != PAD) ) + { + // THIS IS THE LAST SUBMESSAGE + smh->submessageLength = msg->length - msg->pos; + smh->is_last = true; + } + else + { + smh->submessageLength = length; + smh->is_last = false; + } + return true; } -bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh) { std::lock_guard guard(mtx); @@ -514,10 +523,7 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh if(dataFlag || keyFlag) { uint32_t payload_size; - if(smh->submessageLength>0) - payload_size = smh->submessageLength - (RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE+octetsToInlineQos+inlineQosSize); - else - payload_size = smh->submsgLengthLarger; + payload_size = smh->submessageLength - (RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE+octetsToInlineQos+inlineQosSize); if(dataFlag) { @@ -554,9 +560,6 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh msg->pos += payload_size; } } - //Is the final message? - if(smh->submessageLength == 0) - *last = true; // Set sourcetimestamp if(haveTimestamp) @@ -584,7 +587,7 @@ bool MessageReceiver::proc_Submsg_Data(CDRMessage_t* msg,SubmessageHeader_t* smh return true; } -bool MessageReceiver::proc_Submsg_DataFrag(CDRMessage_t* msg, SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_DataFrag(CDRMessage_t* msg, SubmessageHeader_t* smh) { std::lock_guard guard(mtx); @@ -703,10 +706,7 @@ bool MessageReceiver::proc_Submsg_DataFrag(CDRMessage_t* msg, SubmessageHeader_t } uint32_t payload_size; - if (smh->submessageLength>0) - payload_size = smh->submessageLength - (RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE + octetsToInlineQos + inlineQosSize); - else - payload_size = smh->submsgLengthLarger; + payload_size = smh->submessageLength - (RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE + octetsToInlineQos + inlineQosSize); // Validations??? XXX TODO @@ -757,10 +757,6 @@ bool MessageReceiver::proc_Submsg_DataFrag(CDRMessage_t* msg, SubmessageHeader_t */ } - //Is the final message? - if (smh->submessageLength == 0) - *last = true; - // Set sourcetimestamp if (haveTimestamp) ch.sourceTimestamp = this->timestamp; @@ -785,7 +781,7 @@ bool MessageReceiver::proc_Submsg_DataFrag(CDRMessage_t* msg, SubmessageHeader_t } -bool MessageReceiver::proc_Submsg_Heartbeat(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_Heartbeat(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; bool finalFlag = smh->flags & BIT(1) ? true : false; @@ -823,14 +819,11 @@ bool MessageReceiver::proc_Submsg_Heartbeat(CDRMessage_t* msg,SubmessageHeader_t (*it)->processHeartbeatMsg(writerGUID, HBCount, firstSN, lastSN, finalFlag, livelinessFlag); } } - //Is the final message? - if(smh->submessageLength == 0) - *last = true; return true; } -bool MessageReceiver::proc_Submsg_Acknack(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_Acknack(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; bool finalFlag = smh->flags & BIT(1) ? true: false; @@ -850,9 +843,6 @@ bool MessageReceiver::proc_Submsg_Acknack(CDRMessage_t* msg,SubmessageHeader_t* CDRMessage::readSequenceNumberSet(msg,&SNSet); uint32_t Ackcount; CDRMessage::readUInt32(msg,&Ackcount); - //Is the final message? - if(smh->submessageLength == 0) - *last = true; std::lock_guard guard(mtx); //Look for the correct writer to use the acknack @@ -881,7 +871,7 @@ bool MessageReceiver::proc_Submsg_Acknack(CDRMessage_t* msg,SubmessageHeader_t* -bool MessageReceiver::proc_Submsg_Gap(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_Gap(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; //Assign message endianness @@ -890,10 +880,6 @@ bool MessageReceiver::proc_Submsg_Gap(CDRMessage_t* msg,SubmessageHeader_t* smh, else msg->msg_endian = BIGEND; - //Is the final message? - if(smh->submessageLength == 0) - *last = true; - GUID_t writerGUID,readerGUID; readerGUID.guidPrefix = destGuidPrefix; CDRMessage::readEntityId(msg,&readerGUID.entityId); @@ -919,7 +905,7 @@ bool MessageReceiver::proc_Submsg_Gap(CDRMessage_t* msg,SubmessageHeader_t* smh, return true; } -bool MessageReceiver::proc_Submsg_InfoTS(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_InfoTS(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; bool timeFlag = smh->flags & BIT(1) ? true : false; @@ -928,9 +914,6 @@ bool MessageReceiver::proc_Submsg_InfoTS(CDRMessage_t* msg,SubmessageHeader_t* s msg->msg_endian = LITTLEEND; else msg->msg_endian = BIGEND; - //Is the final message? - if(smh->submessageLength == 0) - *last = true; if(!timeFlag) { haveTimestamp = true; @@ -942,7 +925,7 @@ bool MessageReceiver::proc_Submsg_InfoTS(CDRMessage_t* msg,SubmessageHeader_t* s return true; } -bool MessageReceiver::proc_Submsg_InfoDST(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_InfoDST(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; //bool timeFlag = smh->flags & BIT(1) ? true : false; @@ -958,13 +941,10 @@ bool MessageReceiver::proc_Submsg_InfoDST(CDRMessage_t* msg,SubmessageHeader_t* this->destGuidPrefix = guidP; logInfo(RTPS_MSG_IN,IDSTRING"DST RTPSParticipant is now: "<< this->destGuidPrefix); } - //Is the final message? - if(smh->submessageLength == 0) - *last = true; return true; } -bool MessageReceiver::proc_Submsg_InfoSRC(CDRMessage_t* msg,SubmessageHeader_t* smh, bool* last) +bool MessageReceiver::proc_Submsg_InfoSRC(CDRMessage_t* msg,SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; //bool timeFlag = smh->flags & BIT(1) ? true : false; @@ -973,7 +953,7 @@ bool MessageReceiver::proc_Submsg_InfoSRC(CDRMessage_t* msg,SubmessageHeader_t* msg->msg_endian = LITTLEEND; else msg->msg_endian = BIGEND; - if(smh->submessageLength == 20 || smh->submessageLength==0) + if(smh->submessageLength == 20) { //AVOID FIRST 4 BYTES: msg->pos+=4; @@ -981,16 +961,13 @@ bool MessageReceiver::proc_Submsg_InfoSRC(CDRMessage_t* msg,SubmessageHeader_t* CDRMessage::readOctet(msg,&this->sourceVersion.m_minor); CDRMessage::readData(msg,&this->sourceVendorId[0],2); CDRMessage::readData(msg,this->sourceGuidPrefix.value,12); - //Is the final message? - if(smh->submessageLength == 0) - *last = true; logInfo(RTPS_MSG_IN,IDSTRING"SRC RTPSParticipant is now: "<sourceGuidPrefix); return true; } return false; } -bool MessageReceiver::proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* smh, bool*last) { +bool MessageReceiver::proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; @@ -1015,9 +992,6 @@ bool MessageReceiver::proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* uint32_t Ackcount; CDRMessage::readUInt32(msg, &Ackcount); - if (smh->submessageLength == 0) - *last = true; - std::lock_guard guard(mtx); //Look for the correct writer to use the acknack for (std::vector::iterator it = AssociatedWriters.begin(); @@ -1063,7 +1037,7 @@ bool MessageReceiver::proc_Submsg_NackFrag(CDRMessage_t*msg, SubmessageHeader_t* return false; } -bool MessageReceiver::proc_Submsg_HeartbeatFrag(CDRMessage_t*msg, SubmessageHeader_t* smh, bool*last) { +bool MessageReceiver::proc_Submsg_HeartbeatFrag(CDRMessage_t*msg, SubmessageHeader_t* smh) { bool endiannessFlag = smh->flags & BIT(0) ? true : false; //Assign message endianness @@ -1102,9 +1076,6 @@ bool MessageReceiver::proc_Submsg_HeartbeatFrag(CDRMessage_t*msg, SubmessageHead */ } - //Is the final message? - if (smh->submessageLength == 0) - *last = true; return true; } diff --git a/src/cpp/transport/test_TCPv4Transport.cpp b/src/cpp/transport/test_TCPv4Transport.cpp index 709537b8b76..0e7beca9e45 100644 --- a/src/cpp/transport/test_TCPv4Transport.cpp +++ b/src/cpp/transport/test_TCPv4Transport.cpp @@ -178,13 +178,31 @@ void test_TCPv4Transport::CalculateCRC(TCPHeader &header, const octet *data, uin static bool ReadSubmessageHeader(CDRMessage_t& msg, SubmessageHeader_t& smh) { - if(msg.length - msg.pos < 4) + if (msg.length - msg.pos < 4) return false; smh.submessageId = msg.buffer[msg.pos]; msg.pos++; smh.flags = msg.buffer[msg.pos]; msg.pos++; msg.msg_endian = smh.flags & BIT(0) ? LITTLEEND : BIGEND; - CDRMessage::readUInt16(&msg, &smh.submessageLength); + uint16_t length = 0; + CDRMessage::readUInt16(&msg, &length); + + if (msg.pos + length > msg.length) + { + return false; + } + + if (length == 0) + { + // THIS IS THE LAST SUBMESSAGE + smh.submessageLength = msg.length - msg.pos; + smh.is_last = true; + } + else + { + smh.submessageLength = length; + smh.is_last = false; + } return true; } diff --git a/src/cpp/transport/test_UDPv4Transport.cpp b/src/cpp/transport/test_UDPv4Transport.cpp index c61ae7a4d2a..f8bbb57af2d 100644 --- a/src/cpp/transport/test_UDPv4Transport.cpp +++ b/src/cpp/transport/test_UDPv4Transport.cpp @@ -93,13 +93,31 @@ bool test_UDPv4Transport::Send(const octet* sendBuffer, uint32_t sendBufferSize, static bool ReadSubmessageHeader(CDRMessage_t& msg, SubmessageHeader_t& smh) { - if(msg.length - msg.pos < 4) + if (msg.length - msg.pos < 4) return false; smh.submessageId = msg.buffer[msg.pos]; msg.pos++; smh.flags = msg.buffer[msg.pos]; msg.pos++; msg.msg_endian = smh.flags & BIT(0) ? LITTLEEND : BIGEND; - CDRMessage::readUInt16(&msg, &smh.submessageLength); + uint16_t length = 0; + CDRMessage::readUInt16(&msg, &length); + + if (msg.pos + length > msg.length) + { + return false; + } + + if ( (length == 0) && (smh.submessageId != INFO_TS) && (smh.submessageId != PAD) ) + { + // THIS IS THE LAST SUBMESSAGE + smh.submessageLength = msg.length - msg.pos; + smh.is_last = true; + } + else + { + smh.submessageLength = length; + smh.is_last = false; + } return true; } From 92f2e37ef682988e5cfc4f320de4712630893009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Mon, 18 Feb 2019 16:24:00 +0100 Subject: [PATCH 33/34] Added SEDP mechanism to remove unregistered entities info. [4687] (#422) --- .../builtin/discovery/endpoint/EDPSimple.h | 25 +- include/fastrtps/rtps/reader/ReaderListener.h | 54 ++- include/fastrtps/rtps/writer/WriterListener.h | 56 +-- .../builtin/discovery/endpoint/EDPSimple.cpp | 341 +++++++++--------- .../discovery/endpoint/EDPSimpleListeners.cpp | 78 +++- .../discovery/endpoint/EDPSimpleListeners.h | 74 +++- .../discovery/participant/PDPSimple.cpp | 4 +- 7 files changed, 382 insertions(+), 250 deletions(-) diff --git a/include/fastrtps/rtps/builtin/discovery/endpoint/EDPSimple.h b/include/fastrtps/rtps/builtin/discovery/endpoint/EDPSimple.h index db4b49d18c4..9fda5419dd7 100644 --- a/include/fastrtps/rtps/builtin/discovery/endpoint/EDPSimple.h +++ b/include/fastrtps/rtps/builtin/discovery/endpoint/EDPSimple.h @@ -59,28 +59,29 @@ class EDPSimple : public EDP //!Discovery attributes. BuiltinAttributes m_discovery; //!Pointer to the Publications Writer (only created if indicated in the DiscoveryAtributes). - t_p_StatefulWriter mp_PubWriter; + t_p_StatefulWriter publications_writer_; //!Pointer to the Subscriptions Writer (only created if indicated in the DiscoveryAtributes). - t_p_StatefulWriter mp_SubWriter; + t_p_StatefulWriter subscriptions_writer_; //!Pointer to the Publications Reader (only created if indicated in the DiscoveryAtributes). - t_p_StatefulReader mp_PubReader; + t_p_StatefulReader publications_reader_; //!Pointer to the Subscriptions Reader (only created if indicated in the DiscoveryAtributes). - t_p_StatefulReader mp_SubReader; + t_p_StatefulReader subscriptions_reader_; #if HAVE_SECURITY - t_p_StatefulWriter sedp_builtin_publications_secure_writer_; + t_p_StatefulWriter publications_secure_writer_; - t_p_StatefulReader sedp_builtin_publications_secure_reader_; + t_p_StatefulReader publications_secure_reader_; - t_p_StatefulWriter sedp_builtin_subscriptions_secure_writer_; + t_p_StatefulWriter subscriptions_secure_writer_; - t_p_StatefulReader sedp_builtin_subscriptions_secure_reader_; + t_p_StatefulReader subscriptions_secure_reader_; #endif - //!Pointer to the ReaderListener associated with PubReader - EDPSimplePUBListener* mp_pubListen; - //!Pointer to the ReaderListener associated with SubReader - EDPSimpleSUBListener* mp_subListen; + //!Pointer to the listener associated with PubReader and PubWriter. + EDPSimplePUBListener* publications_listener_; + + //!Pointer to the listener associated with SubReader and SubWriter. + EDPSimpleSUBListener* subscriptions_listener_; /** * Initialization method. diff --git a/include/fastrtps/rtps/reader/ReaderListener.h b/include/fastrtps/rtps/reader/ReaderListener.h index 471cf1de904..2ce723ca107 100644 --- a/include/fastrtps/rtps/reader/ReaderListener.h +++ b/include/fastrtps/rtps/reader/ReaderListener.h @@ -35,26 +35,40 @@ struct CacheChange_t; */ class RTPS_DllAPI ReaderListener { -public: - ReaderListener(){}; - virtual ~ReaderListener(){}; - - /** - * This method is invoked when a new reader matches - * @param reader Matching reader - * @param info Matching information of the reader - */ - virtual void onReaderMatched(RTPSReader* reader, MatchingInfo& info){(void)reader; (void)info;}; - - /** - * This method is called when a new CacheChange_t is added to the ReaderHistory. - * @param reader Pointer to the reader. - * @param change Pointer to the CacheChange_t. This is a const pointer to const data - * to indicate that the user should not dispose of this data himself. - * To remove the data call the remove_change method of the ReaderHistory. - * reader->getHistory()->remove_change((CacheChange_t*)change). - */ - virtual void onNewCacheChangeAdded(RTPSReader* reader, const CacheChange_t* const change){(void)reader; (void)change;}; + public: + + ReaderListener() = default; + + virtual ~ReaderListener() = default; + + /** + * This method is invoked when a new reader matches + * @param reader Matching reader + * @param info Matching information of the reader + */ + virtual void onReaderMatched( + RTPSReader* reader, + MatchingInfo& info) + { + (void)reader; + (void)info; + } + + /** + * This method is called when a new CacheChange_t is added to the ReaderHistory. + * @param reader Pointer to the reader. + * @param change Pointer to the CacheChange_t. This is a const pointer to const data + * to indicate that the user should not dispose of this data himself. + * To remove the data call the remove_change method of the ReaderHistory. + * reader->getHistory()->remove_change((CacheChange_t*)change). + */ + virtual void onNewCacheChangeAdded( + RTPSReader* reader, + const CacheChange_t* const change) + { + (void)reader; + (void)change; + } }; //Namespace enders diff --git a/include/fastrtps/rtps/writer/WriterListener.h b/include/fastrtps/rtps/writer/WriterListener.h index 78f5f2efed9..97fdb8f9123 100644 --- a/include/fastrtps/rtps/writer/WriterListener.h +++ b/include/fastrtps/rtps/writer/WriterListener.h @@ -35,28 +35,42 @@ struct CacheChange_t; */ class RTPS_DllAPI WriterListener { -public: - WriterListener(){}; - virtual ~WriterListener(){}; - - /** - * This method is called when a new Reader is matched with this Writer by hte builtin protocols - * @param writer Pointer to the RTPSWriter. - * @param info Matching Information. - */ - virtual void onWriterMatched(RTPSWriter* writer,MatchingInfo& info){(void)writer; (void)info;} - - /** - * This method is called when all the readers matched with this Writer acknowledge that a cache - * change has been received. - * @param writer Pointer to the RTPSWriter. - * @param change Pointer to the affected CacheChange_t. - */ - virtual void onWriterChangeReceivedByAll(RTPSWriter* writer, CacheChange_t* change) { (void)writer; (void)change; } + public: + WriterListener() = default; + + virtual ~WriterListener() = default; + + /** + * This method is called when a new Reader is matched with this Writer by hte builtin protocols + * @param writer Pointer to the RTPSWriter. + * @param info Matching Information. + */ + virtual void onWriterMatched( + RTPSWriter* writer, + MatchingInfo& info) + { + (void)writer; + (void)info; + } + + /** + * This method is called when all the readers matched with this Writer acknowledge that a cache + * change has been received. + * @param writer Pointer to the RTPSWriter. + * @param change Pointer to the affected CacheChange_t. + */ + virtual void onWriterChangeReceivedByAll( + RTPSWriter* writer, + CacheChange_t* change) + { + (void)writer; + (void)change; + } }; -} -} -} + +} /* namespace rtps */ +} /* namespace fastrtps */ +} /* namespace eprosima */ diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp index 5148e449f24..6a23c59e2b9 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimple.cpp @@ -48,69 +48,76 @@ const Duration_t edp_nack_response_delay{0, 400*1000*1000}; // ~93 milliseconds const Duration_t edp_nack_supression_duration{0, 50*1000*1000}; // ~11 milliseconds const Duration_t edp_heartbeat_response_delay{0, 50*1000*1000}; // ~11 milliseconds +const int32_t edp_initial_reserved_caches = 20; -EDPSimple::EDPSimple(PDPSimple* p,RTPSParticipantImpl* part): - EDP(p,part), - mp_pubListen(nullptr), - mp_subListen(nullptr) - { - // TODO Auto-generated constructor stub - - } +EDPSimple::EDPSimple( + PDPSimple* p, + RTPSParticipantImpl* part) + : EDP(p,part) + , publications_listener_(nullptr) + , subscriptions_listener_(nullptr) +{ +} EDPSimple::~EDPSimple() { #if HAVE_SECURITY - if(this->sedp_builtin_publications_secure_writer_.first !=nullptr) + if(this->publications_secure_writer_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(sedp_builtin_publications_secure_writer_.first); - delete(sedp_builtin_publications_secure_writer_.second); + this->mp_RTPSParticipant->deleteUserEndpoint(publications_secure_writer_.first); + delete(publications_secure_writer_.second); } - if(this->sedp_builtin_publications_secure_reader_.first !=nullptr) + if(this->publications_secure_reader_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(sedp_builtin_publications_secure_reader_.first); - delete(sedp_builtin_publications_secure_reader_.second); + this->mp_RTPSParticipant->deleteUserEndpoint(publications_secure_reader_.first); + delete(publications_secure_reader_.second); } - if(this->sedp_builtin_subscriptions_secure_writer_.first !=nullptr) + if(this->subscriptions_secure_writer_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(sedp_builtin_subscriptions_secure_writer_.first); - delete(sedp_builtin_subscriptions_secure_writer_.second); + this->mp_RTPSParticipant->deleteUserEndpoint(subscriptions_secure_writer_.first); + delete(subscriptions_secure_writer_.second); } - if(this->sedp_builtin_subscriptions_secure_reader_.first !=nullptr) + if(this->subscriptions_secure_reader_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(sedp_builtin_subscriptions_secure_reader_.first); - delete(sedp_builtin_subscriptions_secure_reader_.second); + this->mp_RTPSParticipant->deleteUserEndpoint(subscriptions_secure_reader_.first); + delete(subscriptions_secure_reader_.second); } #endif - if(this->mp_PubReader.first !=nullptr) + if(this->publications_reader_.first !=nullptr) + { + this->mp_RTPSParticipant->deleteUserEndpoint(publications_reader_.first); + delete(publications_reader_.second); + } + if(this->subscriptions_reader_.first !=nullptr) + { + this->mp_RTPSParticipant->deleteUserEndpoint(subscriptions_reader_.first); + delete(subscriptions_reader_.second); + } + if(this->publications_writer_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(mp_PubReader.first); - delete(mp_PubReader.second); + this->mp_RTPSParticipant->deleteUserEndpoint(publications_writer_.first); + delete(publications_writer_.second); } - if(this->mp_SubReader.first !=nullptr) + if(this->subscriptions_writer_.first !=nullptr) { - this->mp_RTPSParticipant->deleteUserEndpoint(mp_SubReader.first); - delete(mp_SubReader.second); + this->mp_RTPSParticipant->deleteUserEndpoint(subscriptions_writer_.first); + delete(subscriptions_writer_.second); } - if(this->mp_PubWriter.first !=nullptr) + + if(nullptr != publications_listener_) { - this->mp_RTPSParticipant->deleteUserEndpoint(mp_PubWriter.first); - delete(mp_PubWriter.second); + delete(publications_listener_); } - if(this->mp_SubWriter.first !=nullptr) + + if(nullptr != subscriptions_listener_) { - this->mp_RTPSParticipant->deleteUserEndpoint(mp_SubWriter.first); - delete(mp_SubWriter.second); + delete(subscriptions_listener_); } - if(mp_pubListen!=nullptr) - delete(mp_pubListen); - if(mp_subListen !=nullptr) - delete(mp_subListen); } @@ -145,13 +152,16 @@ bool EDPSimple::createSEDPEndpoints() bool created = true; RTPSReader* raux = nullptr; RTPSWriter* waux = nullptr; + + publications_listener_ = new EDPSimplePUBListener(this); + subscriptions_listener_ = new EDPSimpleSUBListener(this); + if(m_discovery.m_simpleEDP.use_PublicationWriterANDSubscriptionReader) { - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 5000; + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_PUBLICATION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.writerHistoryMemoryPolicy; - mp_PubWriter.second = new WriterHistory(hatt); + publications_writer_.second = new WriterHistory(hatt); //Wparam.pushMode = true; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.topicKind = WITH_KEY; @@ -165,23 +175,25 @@ bool EDPSimple::createSEDPEndpoints() if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; - created &=this->mp_RTPSParticipant->createWriter(&waux,watt,mp_PubWriter.second,nullptr,c_EntityId_SEDPPubWriter,true); + + created &=this->mp_RTPSParticipant->createWriter(&waux, watt, publications_writer_.second, + publications_listener_, c_EntityId_SEDPPubWriter, true); + if(created) { - mp_PubWriter.first = dynamic_cast(waux); + publications_writer_.first = dynamic_cast(waux); logInfo(RTPS_EDP,"SEDP Publication Writer created"); } else { - delete(mp_PubWriter.second); - mp_PubWriter.second = nullptr; + delete(publications_writer_.second); + publications_writer_.second = nullptr; } - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 1000000; + + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_SUBSCRIPTION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.readerHistoryMemoryPolicy; - mp_SubReader.second = new ReaderHistory(hatt); - //Rparam.historyMaxSize = 100; + subscriptions_reader_.second = new ReaderHistory(hatt); ratt.expectsInlineQos = false; ratt.endpoint.reliabilityKind = RELIABLE; ratt.endpoint.topicKind = WITH_KEY; @@ -190,29 +202,27 @@ bool EDPSimple::createSEDPEndpoints() //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; - this->mp_subListen = new EDPSimpleSUBListener(this); - created &=this->mp_RTPSParticipant->createReader(&raux,ratt,mp_SubReader.second,mp_subListen,c_EntityId_SEDPSubReader,true); + + created &=this->mp_RTPSParticipant->createReader(&raux, ratt, subscriptions_reader_.second, + subscriptions_listener_, c_EntityId_SEDPSubReader, true); + if(created) { - mp_SubReader.first = dynamic_cast(raux); + subscriptions_reader_.first = dynamic_cast(raux); logInfo(RTPS_EDP,"SEDP Subscription Reader created"); } else { - delete(mp_SubReader.second); - mp_SubReader.second = nullptr; - delete(mp_subListen); - mp_subListen = nullptr; + delete(subscriptions_reader_.second); + subscriptions_reader_.second = nullptr; } } if(m_discovery.m_simpleEDP.use_PublicationReaderANDSubscriptionWriter) { - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 1000000; + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_PUBLICATION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.readerHistoryMemoryPolicy; - mp_PubReader.second = new ReaderHistory(hatt); - //Rparam.historyMaxSize = 100; + publications_reader_.second = new ReaderHistory(hatt); ratt.expectsInlineQos = false; ratt.endpoint.reliabilityKind = RELIABLE; ratt.endpoint.topicKind = WITH_KEY; @@ -221,26 +231,26 @@ bool EDPSimple::createSEDPEndpoints() //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.times.heartbeatResponseDelay = edp_heartbeat_response_delay; - this->mp_pubListen = new EDPSimplePUBListener(this); - created &=this->mp_RTPSParticipant->createReader(&raux,ratt,mp_PubReader.second,mp_pubListen,c_EntityId_SEDPPubReader,true); + + created &=this->mp_RTPSParticipant->createReader(&raux, ratt, publications_reader_.second, + publications_listener_, c_EntityId_SEDPPubReader, true); + if(created) { - mp_PubReader.first = dynamic_cast(raux); + publications_reader_.first = dynamic_cast(raux); logInfo(RTPS_EDP,"SEDP Publication Reader created"); } else { - delete(mp_PubReader.second); - mp_PubReader.second = nullptr; - delete(mp_pubListen); - mp_pubListen = nullptr; + delete(publications_reader_.second); + publications_reader_.second = nullptr; } - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 5000; + + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_SUBSCRIPTION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.writerHistoryMemoryPolicy; - mp_SubWriter.second = new WriterHistory(hatt); + subscriptions_writer_.second = new WriterHistory(hatt); //Wparam.pushMode = true; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.topicKind = WITH_KEY; @@ -254,18 +264,20 @@ bool EDPSimple::createSEDPEndpoints() if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; - created &=this->mp_RTPSParticipant->createWriter(&waux, watt, mp_SubWriter.second, nullptr, - c_EntityId_SEDPSubWriter, true); + + created &=this->mp_RTPSParticipant->createWriter(&waux, watt, subscriptions_writer_.second, + subscriptions_listener_, c_EntityId_SEDPSubWriter, true); + if(created) { - mp_SubWriter.first = dynamic_cast(waux); + subscriptions_writer_.first = dynamic_cast(waux); logInfo(RTPS_EDP,"SEDP Subscription Writer created"); } else { - delete(mp_SubWriter.second); - mp_SubWriter.second = nullptr; + delete(subscriptions_writer_.second); + subscriptions_writer_.second = nullptr; } } logInfo(RTPS_EDP,"Creation finished"); @@ -287,11 +299,10 @@ bool EDPSimple::create_sedp_secure_endpoints() if(m_discovery.m_simpleEDP.enable_builtin_secure_publications_writer_and_subscriptions_reader) { - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 5000; + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_PUBLICATION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.writerHistoryMemoryPolicy; - sedp_builtin_publications_secure_writer_.second = new WriterHistory(hatt); + publications_secure_writer_.second = new WriterHistory(hatt); //Wparam.pushMode = true; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.topicKind = WITH_KEY; @@ -315,24 +326,24 @@ bool EDPSimple::create_sedp_secure_endpoints() if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; - created &=this->mp_RTPSParticipant->createWriter(&waux, watt, sedp_builtin_publications_secure_writer_.second, - nullptr, sedp_builtin_publications_secure_writer, true); + + created &=this->mp_RTPSParticipant->createWriter(&waux, watt, publications_secure_writer_.second, + publications_listener_, sedp_builtin_publications_secure_writer, true); + if(created) { - sedp_builtin_publications_secure_writer_.first = dynamic_cast(waux); + publications_secure_writer_.first = dynamic_cast(waux); logInfo(RTPS_EDP,"SEDP Publication Writer created"); } else { - delete(sedp_builtin_publications_secure_writer_.second); - sedp_builtin_publications_secure_writer_.second = nullptr; + delete(publications_secure_writer_.second); + publications_secure_writer_.second = nullptr; } - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 1000000; + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_SUBSCRIPTION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.readerHistoryMemoryPolicy; - sedp_builtin_subscriptions_secure_reader_.second = new ReaderHistory(hatt); - //Rparam.historyMaxSize = 100; + subscriptions_secure_reader_.second = new ReaderHistory(hatt); ratt.expectsInlineQos = false; ratt.endpoint.reliabilityKind = RELIABLE; ratt.endpoint.topicKind = WITH_KEY; @@ -350,28 +361,28 @@ bool EDPSimple::create_sedp_secure_endpoints() if (plugin_part_attr.is_discovery_origin_authenticated) ratt.endpoint.security_attributes().plugin_endpoint_attributes |= PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED; } - created &=this->mp_RTPSParticipant->createReader(&raux, ratt, sedp_builtin_subscriptions_secure_reader_.second, - mp_subListen, sedp_builtin_subscriptions_secure_reader, true); + + created &=this->mp_RTPSParticipant->createReader(&raux, ratt, subscriptions_secure_reader_.second, + subscriptions_listener_, sedp_builtin_subscriptions_secure_reader, true); + if(created) { - sedp_builtin_subscriptions_secure_reader_.first = dynamic_cast(raux); + subscriptions_secure_reader_.first = dynamic_cast(raux); logInfo(RTPS_EDP,"SEDP Subscription Reader created"); } else { - delete(sedp_builtin_subscriptions_secure_reader_.second); - sedp_builtin_subscriptions_secure_reader_.second = nullptr; + delete(subscriptions_secure_reader_.second); + subscriptions_secure_reader_.second = nullptr; } } if(m_discovery.m_simpleEDP.enable_builtin_secure_subscriptions_writer_and_publications_reader) { - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 1000000; + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_PUBLICATION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.readerHistoryMemoryPolicy; - sedp_builtin_publications_secure_reader_.second = new ReaderHistory(hatt); - //Rparam.historyMaxSize = 100; + publications_secure_reader_.second = new ReaderHistory(hatt); ratt.expectsInlineQos = false; ratt.endpoint.reliabilityKind = RELIABLE; ratt.endpoint.topicKind = WITH_KEY; @@ -389,24 +400,26 @@ bool EDPSimple::create_sedp_secure_endpoints() if (plugin_part_attr.is_discovery_origin_authenticated) ratt.endpoint.security_attributes().plugin_endpoint_attributes |= PLUGIN_ENDPOINT_SECURITY_ATTRIBUTES_FLAG_IS_SUBMESSAGE_ORIGIN_AUTHENTICATED; } - created &=this->mp_RTPSParticipant->createReader(&raux, ratt, sedp_builtin_publications_secure_reader_.second, - mp_pubListen, sedp_builtin_publications_secure_reader, true); + + created &=this->mp_RTPSParticipant->createReader(&raux, ratt, publications_secure_reader_.second, + publications_listener_, sedp_builtin_publications_secure_reader, true); + if(created) { - sedp_builtin_publications_secure_reader_.first = dynamic_cast(raux); + publications_secure_reader_.first = dynamic_cast(raux); logInfo(RTPS_EDP,"SEDP Publication Reader created"); } else { - delete(sedp_builtin_publications_secure_reader_.second); - sedp_builtin_publications_secure_reader_.second = nullptr; + delete(publications_secure_reader_.second); + publications_secure_reader_.second = nullptr; } - hatt.initialReservedCaches = 100; - hatt.maximumReservedCaches = 5000; + + hatt.initialReservedCaches = edp_initial_reserved_caches; hatt.payloadMaxSize = DISCOVERY_SUBSCRIPTION_DATA_MAX_SIZE; hatt.memoryPolicy = mp_PDP->mp_builtin->m_att.writerHistoryMemoryPolicy; - sedp_builtin_subscriptions_secure_writer_.second = new WriterHistory(hatt); + subscriptions_secure_writer_.second = new WriterHistory(hatt); //Wparam.pushMode = true; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.topicKind = WITH_KEY; @@ -429,18 +442,20 @@ bool EDPSimple::create_sedp_secure_endpoints() if(mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX && mp_RTPSParticipant->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0) watt.mode = ASYNCHRONOUS_WRITER; - created &=this->mp_RTPSParticipant->createWriter(&waux, watt, sedp_builtin_subscriptions_secure_writer_.second, - nullptr, sedp_builtin_subscriptions_secure_writer, true); + + created &=this->mp_RTPSParticipant->createWriter(&waux, watt, subscriptions_secure_writer_.second, + subscriptions_listener_, sedp_builtin_subscriptions_secure_writer, true); + if(created) { - sedp_builtin_subscriptions_secure_writer_.first = dynamic_cast(waux); + subscriptions_secure_writer_.first = dynamic_cast(waux); logInfo(RTPS_EDP,"SEDP Subscription Writer created"); } else { - delete(sedp_builtin_subscriptions_secure_writer_.second); - sedp_builtin_subscriptions_secure_writer_.second = nullptr; + delete(subscriptions_secure_writer_.second); + subscriptions_secure_writer_.second = nullptr; } } logInfo(RTPS_EDP,"Creation finished"); @@ -453,12 +468,12 @@ bool EDPSimple::processLocalReaderProxyData(RTPSReader* local_reader, ReaderProx logInfo(RTPS_EDP,rdata->guid().entityId); (void)local_reader; - auto* writer = &mp_SubWriter; + auto* writer = &subscriptions_writer_; #if HAVE_SECURITY if(local_reader->getAttributes().security_attributes().is_discovery_protected) { - writer = &sedp_builtin_subscriptions_secure_writer_; + writer = &subscriptions_secure_writer_; } #endif @@ -513,12 +528,12 @@ bool EDPSimple::processLocalWriterProxyData(RTPSWriter* local_writer, WriterProx logInfo(RTPS_EDP, wdata->guid().entityId); (void)local_writer; - auto* writer = &mp_PubWriter; + auto* writer = &publications_writer_; #if HAVE_SECURITY if(local_writer->getAttributes().security_attributes().is_discovery_protected) { - writer = &sedp_builtin_publications_secure_writer_; + writer = &publications_secure_writer_; } #endif @@ -569,12 +584,12 @@ bool EDPSimple::removeLocalWriter(RTPSWriter* W) { logInfo(RTPS_EDP,W->getGuid().entityId); - auto* writer = &mp_PubWriter; + auto* writer = &publications_writer_; #if HAVE_SECURITY if(W->getAttributes().security_attributes().is_discovery_protected) { - writer = &sedp_builtin_publications_secure_writer_; + writer = &publications_secure_writer_; } #endif @@ -609,12 +624,12 @@ bool EDPSimple::removeLocalReader(RTPSReader* R) { logInfo(RTPS_EDP,R->getGuid().entityId); - auto* writer = &mp_SubWriter; + auto* writer = &subscriptions_writer_; #if HAVE_SECURITY if(R->getAttributes().security_attributes().is_discovery_protected) { - writer = &sedp_builtin_subscriptions_secure_writer_; + writer = &subscriptions_secure_writer_; } #endif @@ -654,7 +669,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) auxendp &=DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_PubReader.first!=nullptr) //Exist Pub Writer and i have pub reader + if(auxendp!=0 && publications_reader_.first!=nullptr) //Exist Pub Writer and i have pub reader { logInfo(RTPS_EDP,"Adding SEDP Pub Writer to my Pub Reader"); RemoteWriterAttributes watt(pdata.m_VendorId); @@ -666,13 +681,13 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - mp_PubReader.first->matched_writer_add(watt); + publications_reader_.first->matched_writer_add(watt); } auxendp = endp; auxendp &=DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_PubWriter.first!=nullptr) //Exist Pub Detector + if(auxendp!=0 && publications_writer_.first!=nullptr) //Exist Pub Detector { logInfo(RTPS_EDP,"Adding SEDP Pub Reader to my Pub Writer"); RemoteReaderAttributes ratt(pdata.m_VendorId); @@ -684,13 +699,13 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - mp_PubWriter.first->matched_reader_add(ratt); + publications_writer_.first->matched_reader_add(ratt); } auxendp = endp; auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_SubReader.first!=nullptr) //Exist Pub Announcer + if(auxendp!=0 && subscriptions_reader_.first!=nullptr) //Exist Pub Announcer { logInfo(RTPS_EDP,"Adding SEDP Sub Writer to my Sub Reader"); RemoteWriterAttributes watt(pdata.m_VendorId); @@ -702,13 +717,13 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - mp_SubReader.first->matched_writer_add(watt); + subscriptions_reader_.first->matched_writer_add(watt); } auxendp = endp; auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_SubWriter.first!=nullptr) //Exist Pub Announcer + if(auxendp!=0 && subscriptions_writer_.first!=nullptr) //Exist Pub Announcer { logInfo(RTPS_EDP,"Adding SEDP Sub Reader to my Sub Writer"); RemoteReaderAttributes ratt(pdata.m_VendorId); @@ -720,7 +735,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - mp_SubWriter.first->matched_reader_add(ratt); + subscriptions_writer_.first->matched_reader_add(ratt); } #if HAVE_SECURITY @@ -728,7 +743,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) auxendp &= DISC_BUILTIN_ENDPOINT_PUBLICATION_SECURE_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_publications_secure_reader_.first != nullptr) + if(auxendp != 0 && publications_secure_reader_.first != nullptr) { WriterProxyData watt; watt.guid().guidPrefix = pdata.m_guid.guidPrefix; @@ -739,11 +754,11 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) watt.m_qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; watt.m_qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; if(!mp_RTPSParticipant->security_manager().discovered_builtin_writer( - sedp_builtin_publications_secure_reader_.first->getGuid(), pdata.m_guid, watt, - sedp_builtin_publications_secure_reader_.first->getAttributes().security_attributes())) + publications_secure_reader_.first->getGuid(), pdata.m_guid, watt, + publications_secure_reader_.first->getAttributes().security_attributes())) { logError(RTPS_EDP, "Security manager returns an error for writer " << - sedp_builtin_publications_secure_reader_.first->getGuid()); + publications_secure_reader_.first->getGuid()); } } @@ -751,7 +766,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) auxendp &= DISC_BUILTIN_ENDPOINT_PUBLICATION_SECURE_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_publications_secure_writer_.first!=nullptr) + if(auxendp != 0 && publications_secure_writer_.first!=nullptr) { ReaderProxyData ratt; ratt.m_expectsInlineQos = false; @@ -762,11 +777,11 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) ratt.m_qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; ratt.m_qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; if(!mp_RTPSParticipant->security_manager().discovered_builtin_reader( - sedp_builtin_publications_secure_writer_.first->getGuid(), pdata.m_guid, ratt, - sedp_builtin_publications_secure_writer_.first->getAttributes().security_attributes())) + publications_secure_writer_.first->getGuid(), pdata.m_guid, ratt, + publications_secure_writer_.first->getAttributes().security_attributes())) { logError(RTPS_EDP, "Security manager returns an error for writer " << - sedp_builtin_publications_secure_writer_.first->getGuid()); + publications_secure_writer_.first->getGuid()); } } @@ -774,7 +789,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_SECURE_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_subscriptions_secure_reader_.first != nullptr) + if(auxendp != 0 && subscriptions_secure_reader_.first != nullptr) { WriterProxyData watt; watt.guid().guidPrefix = pdata.m_guid.guidPrefix; @@ -785,11 +800,11 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) watt.m_qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; watt.m_qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; if(!mp_RTPSParticipant->security_manager().discovered_builtin_writer( - sedp_builtin_subscriptions_secure_reader_.first->getGuid(), pdata.m_guid, watt, - sedp_builtin_subscriptions_secure_reader_.first->getAttributes().security_attributes())) + subscriptions_secure_reader_.first->getGuid(), pdata.m_guid, watt, + subscriptions_secure_reader_.first->getAttributes().security_attributes())) { logError(RTPS_EDP, "Security manager returns an error for writer " << - sedp_builtin_subscriptions_secure_reader_.first->getGuid()); + subscriptions_secure_reader_.first->getGuid()); } } @@ -797,7 +812,7 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_SECURE_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_subscriptions_secure_writer_.first!=nullptr) + if(auxendp != 0 && subscriptions_secure_writer_.first!=nullptr) { logInfo(RTPS_EDP,"Adding SEDP Sub Reader to my Sub Writer"); ReaderProxyData ratt; @@ -809,11 +824,11 @@ void EDPSimple::assignRemoteEndpoints(const ParticipantProxyData& pdata) ratt.m_qos.m_durability.kind = TRANSIENT_LOCAL_DURABILITY_QOS; ratt.m_qos.m_reliability.kind = RELIABLE_RELIABILITY_QOS; if(!mp_RTPSParticipant->security_manager().discovered_builtin_reader( - sedp_builtin_subscriptions_secure_writer_.first->getGuid(), pdata.m_guid, ratt, - sedp_builtin_subscriptions_secure_writer_.first->getAttributes().security_attributes())) + subscriptions_secure_writer_.first->getGuid(), pdata.m_guid, ratt, + subscriptions_secure_writer_.first->getAttributes().security_attributes())) { logError(RTPS_EDP, "Security manager returns an error for writer " << - sedp_builtin_subscriptions_secure_writer_.first->getGuid()); + subscriptions_secure_writer_.first->getGuid()); } } #endif @@ -829,7 +844,7 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) auxendp &=DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_PubReader.first!=nullptr) //Exist Pub Writer and i have pub reader + if(auxendp!=0 && publications_reader_.first!=nullptr) //Exist Pub Writer and i have pub reader { RemoteWriterAttributes watt; watt.guid.guidPrefix = pdata->m_guid.guidPrefix; @@ -840,13 +855,13 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - mp_PubReader.first->matched_writer_remove(watt); + publications_reader_.first->matched_writer_remove(watt); } auxendp = endp; auxendp &=DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_PubWriter.first!=nullptr) //Exist Pub Detector + if(auxendp!=0 && publications_writer_.first!=nullptr) //Exist Pub Detector { RemoteReaderAttributes ratt; ratt.expectsInlineQos = false; @@ -857,13 +872,13 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - mp_PubWriter.first->matched_reader_remove(ratt); + publications_writer_.first->matched_reader_remove(ratt); } auxendp = endp; auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_SubReader.first!=nullptr) //Exist Pub Announcer + if(auxendp!=0 && subscriptions_reader_.first!=nullptr) //Exist Pub Announcer { logInfo(RTPS_EDP,"Adding SEDP Sub Writer to my Sub Reader"); RemoteWriterAttributes watt; @@ -875,13 +890,13 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - mp_SubReader.first->matched_writer_remove(watt); + subscriptions_reader_.first->matched_writer_remove(watt); } auxendp = endp; auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp!=0 && mp_SubWriter.first!=nullptr) //Exist Pub Announcer + if(auxendp!=0 && subscriptions_writer_.first!=nullptr) //Exist Pub Announcer { logInfo(RTPS_EDP,"Adding SEDP Sub Reader to my Sub Writer"); RemoteReaderAttributes ratt; @@ -893,7 +908,7 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - mp_SubWriter.first->matched_reader_remove(ratt); + subscriptions_writer_.first->matched_reader_remove(ratt); } #if HAVE_SECURITY @@ -901,7 +916,7 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) auxendp &= DISC_BUILTIN_ENDPOINT_PUBLICATION_SECURE_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_publications_secure_reader_.first != nullptr) + if(auxendp != 0 && publications_secure_reader_.first != nullptr) { RemoteWriterAttributes watt; watt.guid.guidPrefix = pdata->m_guid.guidPrefix; @@ -912,10 +927,10 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - if(sedp_builtin_publications_secure_reader_.first->matched_writer_remove(watt)) + if(publications_secure_reader_.first->matched_writer_remove(watt)) { mp_RTPSParticipant->security_manager().remove_writer( - sedp_builtin_publications_secure_reader_.first->getGuid(), pdata->m_guid, watt.guid); + publications_secure_reader_.first->getGuid(), pdata->m_guid, watt.guid); } } @@ -923,7 +938,7 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) auxendp &= DISC_BUILTIN_ENDPOINT_PUBLICATION_SECURE_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_publications_secure_writer_.first != nullptr) + if(auxendp != 0 && publications_secure_writer_.first != nullptr) { RemoteReaderAttributes ratt; ratt.guid.guidPrefix = pdata->m_guid.guidPrefix; @@ -933,10 +948,10 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - if(sedp_builtin_publications_secure_writer_.first->matched_reader_remove(ratt)) + if(publications_secure_writer_.first->matched_reader_remove(ratt)) { mp_RTPSParticipant->security_manager().remove_reader( - sedp_builtin_publications_secure_writer_.first->getGuid(), pdata->m_guid, ratt.guid); + publications_secure_writer_.first->getGuid(), pdata->m_guid, ratt.guid); } } @@ -944,7 +959,7 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_SECURE_ANNOUNCER; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_subscriptions_secure_reader_.first != nullptr) + if(auxendp != 0 && subscriptions_secure_reader_.first != nullptr) { logInfo(RTPS_EDP,"Adding SEDP Sub Writer to my Sub Reader"); RemoteWriterAttributes watt; @@ -956,17 +971,17 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //watt.endpoint.remoteLocatorList = m_discovery.initialPeersList; watt.endpoint.reliabilityKind = RELIABLE; watt.endpoint.durabilityKind = TRANSIENT_LOCAL; - if(sedp_builtin_subscriptions_secure_reader_.first->matched_writer_remove(watt)) + if(subscriptions_secure_reader_.first->matched_writer_remove(watt)) { mp_RTPSParticipant->security_manager().remove_writer( - sedp_builtin_subscriptions_secure_reader_.first->getGuid(), pdata->m_guid, watt.guid); + subscriptions_secure_reader_.first->getGuid(), pdata->m_guid, watt.guid); } } auxendp = endp; auxendp &= DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_SECURE_DETECTOR; //FIXME: FIX TO NOT FAIL WITH BAD BUILTIN ENDPOINT SET //auxendp = 1; - if(auxendp != 0 && sedp_builtin_subscriptions_secure_writer_.first!=nullptr) + if(auxendp != 0 && subscriptions_secure_writer_.first!=nullptr) { logInfo(RTPS_EDP,"Adding SEDP Sub Reader to my Sub Writer"); RemoteReaderAttributes ratt; @@ -977,10 +992,10 @@ void EDPSimple::removeRemoteEndpoints(ParticipantProxyData* pdata) //ratt.endpoint.remoteLocatorList = m_discovery.initialPeersList; ratt.endpoint.durabilityKind = TRANSIENT_LOCAL; ratt.endpoint.reliabilityKind = RELIABLE; - if(sedp_builtin_subscriptions_secure_writer_.first->matched_reader_remove(ratt)) + if(subscriptions_secure_writer_.first->matched_reader_remove(ratt)) { mp_RTPSParticipant->security_manager().remove_reader( - sedp_builtin_subscriptions_secure_writer_.first->getGuid(), pdata->m_guid, ratt.guid); + subscriptions_secure_writer_.first->getGuid(), pdata->m_guid, ratt.guid); } } #endif @@ -995,13 +1010,13 @@ bool EDPSimple::pairing_remote_writer_with_local_builtin_reader_after_security(c if(local_reader.entityId == sedp_builtin_publications_secure_reader) { RemoteWriterAttributes attrs = remote_writer_data.toRemoteWriterAttributes(); - sedp_builtin_publications_secure_reader_.first->matched_writer_add(attrs); + publications_secure_reader_.first->matched_writer_add(attrs); returned_value = true; } else if(local_reader.entityId == sedp_builtin_subscriptions_secure_reader) { RemoteWriterAttributes attrs = remote_writer_data.toRemoteWriterAttributes(); - sedp_builtin_subscriptions_secure_reader_.first->matched_writer_add(attrs); + subscriptions_secure_reader_.first->matched_writer_add(attrs); returned_value = true; } @@ -1016,13 +1031,13 @@ bool EDPSimple::pairing_remote_reader_with_local_builtin_writer_after_security(c if(local_writer.entityId == sedp_builtin_publications_secure_writer) { RemoteReaderAttributes attrs = remote_reader_data.toRemoteReaderAttributes(); - sedp_builtin_publications_secure_writer_.first->matched_reader_add(attrs); + publications_secure_writer_.first->matched_reader_add(attrs); returned_value = true; } else if(local_writer.entityId == sedp_builtin_subscriptions_secure_writer) { RemoteReaderAttributes attrs = remote_reader_data.toRemoteReaderAttributes(); - sedp_builtin_subscriptions_secure_writer_.first->matched_reader_add(attrs); + subscriptions_secure_writer_.first->matched_reader_add(attrs); returned_value = true; } diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp index c97a5f36183..88ffc633b12 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.cpp @@ -27,6 +27,7 @@ #include #include +#include #include @@ -43,13 +44,20 @@ namespace rtps { void EDPSimplePUBListener::onNewCacheChangeAdded(RTPSReader* reader, const CacheChange_t* const change_in) { CacheChange_t* change = (CacheChange_t*)change_in; - //std::lock_guard guard(*this->mp_SEDP->mp_PubReader.first->getMutex()); + //std::lock_guard guard(*this->sedp_->publications_reader_.first->getMutex()); logInfo(RTPS_EDP,""); if(!computeKey(change)) { logWarning(RTPS_EDP,"Received change with no Key"); } + ReaderHistory* reader_history = +#if HAVE_SECURITY + reader == sedp_->publications_secure_reader_.first ? + sedp_->publications_secure_reader_.second : +#endif + sedp_->publications_reader_.second; + if(change->kind == ALIVE) { //LOAD INFORMATION IN TEMPORAL WRITER PROXY DATA @@ -59,21 +67,21 @@ void EDPSimplePUBListener::onNewCacheChangeAdded(RTPSReader* reader, const Cache if(writerProxyData.readFromCDRMessage(&tempMsg)) { change->instanceHandle = writerProxyData.key(); - if(writerProxyData.guid().guidPrefix == mp_SEDP->mp_RTPSParticipant->getGuid().guidPrefix) + if(writerProxyData.guid().guidPrefix == sedp_->mp_RTPSParticipant->getGuid().guidPrefix) { logInfo(RTPS_EDP,"Message from own RTPSParticipant, ignoring"); - mp_SEDP->mp_PubReader.second->remove_change(change); + reader_history->remove_change(change); return; } //LOOK IF IS AN UPDATED INFORMATION ParticipantProxyData pdata; - if(this->mp_SEDP->mp_PDP->addWriterProxyData(&writerProxyData, pdata)) //ADDED NEW DATA + if(this->sedp_->mp_PDP->addWriterProxyData(&writerProxyData, pdata)) //ADDED NEW DATA { // At this point we can release reader lock, cause change is not used reader->getMutex()->unlock(); - mp_SEDP->pairing_writer_proxy_with_any_local_reader(&pdata, &writerProxyData); + sedp_->pairing_writer_proxy_with_any_local_reader(&pdata, &writerProxyData); // Take again the reader lock. reader->getMutex()->lock(); @@ -90,11 +98,11 @@ void EDPSimplePUBListener::onNewCacheChangeAdded(RTPSReader* reader, const Cache logInfo(RTPS_EDP,"Disposed Remote Writer, removing..."); GUID_t auxGUID = iHandle2GUID(change->instanceHandle); - this->mp_SEDP->mp_PDP->removeWriterProxyData(auxGUID); + this->sedp_->mp_PDP->removeWriterProxyData(auxGUID); } //Removing change from history - this->mp_SEDP->mp_PubReader.second->remove_change(change); + reader_history->remove_change(change); return; } @@ -112,13 +120,20 @@ bool EDPSimpleSUBListener::computeKey(CacheChange_t* change) void EDPSimpleSUBListener::onNewCacheChangeAdded(RTPSReader* reader, const CacheChange_t* const change_in) { CacheChange_t* change = (CacheChange_t*)change_in; - //std::lock_guard guard(*this->mp_SEDP->mp_SubReader.first->getMutex()); + //std::lock_guard guard(*this->sedp_->subscriptions_reader_.first->getMutex()); logInfo(RTPS_EDP,""); if(!computeKey(change)) { logWarning(RTPS_EDP,"Received change with no Key"); } + ReaderHistory* reader_history = +#if HAVE_SECURITY + reader == sedp_->subscriptions_secure_reader_.first ? + sedp_->subscriptions_secure_reader_.second : +#endif + sedp_->subscriptions_reader_.second; + if(change->kind == ALIVE) { //LOAD INFORMATION IN TEMPORAL WRITER PROXY DATA @@ -128,21 +143,21 @@ void EDPSimpleSUBListener::onNewCacheChangeAdded(RTPSReader* reader, const Cache if(readerProxyData.readFromCDRMessage(&tempMsg)) { change->instanceHandle = readerProxyData.key(); - if(readerProxyData.guid().guidPrefix == mp_SEDP->mp_RTPSParticipant->getGuid().guidPrefix) + if(readerProxyData.guid().guidPrefix == sedp_->mp_RTPSParticipant->getGuid().guidPrefix) { logInfo(RTPS_EDP,"From own RTPSParticipant, ignoring"); - mp_SEDP->mp_SubReader.second->remove_change(change); + reader_history->remove_change(change); return; } //LOOK IF IS AN UPDATED INFORMATION ParticipantProxyData pdata; - if(this->mp_SEDP->mp_PDP->addReaderProxyData(&readerProxyData, pdata)) //ADDED NEW DATA + if(this->sedp_->mp_PDP->addReaderProxyData(&readerProxyData, pdata)) //ADDED NEW DATA { // At this point we can release reader lock, cause change is not used reader->getMutex()->unlock(); - mp_SEDP->pairing_reader_proxy_with_any_local_writer(&pdata, &readerProxyData); + sedp_->pairing_reader_proxy_with_any_local_writer(&pdata, &readerProxyData); // Take again the reader lock. reader->getMutex()->lock(); @@ -159,15 +174,50 @@ void EDPSimpleSUBListener::onNewCacheChangeAdded(RTPSReader* reader, const Cache logInfo(RTPS_EDP,"Disposed Remote Reader, removing..."); GUID_t auxGUID = iHandle2GUID(change->instanceHandle); - this->mp_SEDP->mp_PDP->removeReaderProxyData(auxGUID); + this->sedp_->mp_PDP->removeReaderProxyData(auxGUID); } // Remove change from history. - this->mp_SEDP->mp_SubReader.second->remove_change(change); + reader_history->remove_change(change); return; } +void EDPSimplePUBListener::onWriterChangeReceivedByAll(RTPSWriter* writer, CacheChange_t* change) +{ + (void)writer; + + if(ChangeKind_t::NOT_ALIVE_DISPOSED_UNREGISTERED == change->kind) + { + WriterHistory* writer_history = +#if HAVE_SECURITY + writer == sedp_->publications_secure_writer_.first ? + sedp_->publications_secure_writer_.second : +#endif + sedp_->publications_writer_.second; + + writer_history->remove_change(change); + } +} + +void EDPSimpleSUBListener::onWriterChangeReceivedByAll(RTPSWriter* writer, CacheChange_t* change) +{ + (void)writer; + + if(ChangeKind_t::NOT_ALIVE_DISPOSED_UNREGISTERED == change->kind) + { + WriterHistory* writer_history = +#if HAVE_SECURITY + writer == sedp_->subscriptions_secure_writer_.first ? + sedp_->subscriptions_secure_writer_.second : +#endif + sedp_->subscriptions_writer_.second; + + writer_history->remove_change(change); + } + +} + } /* namespace rtps */ } } /* namespace eprosima */ diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h index 1c595e0863b..8820ecce7d1 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDPSimpleListeners.h @@ -22,6 +22,7 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC #include +#include namespace eprosima { namespace fastrtps { @@ -31,57 +32,96 @@ class EDPSimple; class RTPSReader; struct CacheChange_t; -/** +/*! * Class EDPSimplePUBReaderListener, used to define the behavior when a new WriterProxyData is received. - *@ingroup DISCOVERY_MODULE + * @ingroup DISCOVERY_MODULE */ -class EDPSimplePUBListener : public ReaderListener +class EDPSimplePUBListener : public ReaderListener, public WriterListener { public: - /** + + /*! Constructor - * @param p Pointer to the EDPSimple associated with this listener. + * @param sedp Pointer to the EDPSimple associated with this listener. */ - EDPSimplePUBListener(EDPSimple* p):mp_SEDP(p){}; - virtual ~EDPSimplePUBListener(){}; + EDPSimplePUBListener(EDPSimple* sedp) : sedp_(sedp) {} + + virtual ~EDPSimplePUBListener() {} + /** * Virtual method, * @param reader * @param change */ - void onNewCacheChangeAdded(RTPSReader* reader,const CacheChange_t* const change); + void onNewCacheChangeAdded( + RTPSReader* reader, + const CacheChange_t* const change) override; + + + /*! + * This method is called when all the readers matched with this Writer acknowledge that a cache + * change has been received. + * @param writer Pointer to the RTPSWriter. + * @param change Pointer to the affected CacheChange_t. + */ + void onWriterChangeReceivedByAll( + RTPSWriter* writer, + CacheChange_t* change) override; + /** * Compute the Key from a CacheChange_t * @param change Pointer to the change. */ bool computeKey(CacheChange_t* change); + + private: + //!Pointer to the EDPSimple - EDPSimple* mp_SEDP; + EDPSimple* sedp_; }; -/** + +/*! * Class EDPSimpleSUBReaderListener, used to define the behavior when a new ReaderProxyData is received. - *@ingroup DISCOVERY_MODULE + * @ingroup DISCOVERY_MODULE */ -class EDPSimpleSUBListener : public ReaderListener +class EDPSimpleSUBListener : public ReaderListener, public WriterListener { public: - /** - * @param p + + /*! + Constructor + * @param sedp Pointer to the EDPSimple associated with this listener. */ - EDPSimpleSUBListener(EDPSimple* p):mp_SEDP(p){} + EDPSimpleSUBListener(EDPSimple* sedp) : sedp_(sedp){} virtual ~EDPSimpleSUBListener(){} /** * @param reader * @param change */ - void onNewCacheChangeAdded(RTPSReader* reader, const CacheChange_t* const change); + void onNewCacheChangeAdded( + RTPSReader* reader, + const CacheChange_t* const change) override; + + /*! + * This method is called when all the readers matched with this Writer acknowledge that a cache + * change has been received. + * @param writer Pointer to the RTPSWriter. + * @param change Pointer to the affected CacheChange_t. + */ + void onWriterChangeReceivedByAll( + RTPSWriter* writer, + CacheChange_t* change) override; + /** * @param change */ bool computeKey(CacheChange_t* change); + + private: + //!Pointer to the EDPSimple - EDPSimple* mp_SEDP; + EDPSimple* sedp_; }; } /* namespace rtps */ diff --git a/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp b/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp index 953d8714472..41fd3f3138d 100644 --- a/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp +++ b/src/cpp/rtps/builtin/discovery/participant/PDPSimple.cpp @@ -491,8 +491,7 @@ bool PDPSimple::createSPDPEndpoints() //SPDP BUILTIN RTPSParticipant WRITER HistoryAttributes hatt; hatt.payloadMaxSize = DISCOVERY_PARTICIPANT_DATA_MAX_SIZE; - hatt.initialReservedCaches = 250; - hatt.maximumReservedCaches = 5000; + hatt.initialReservedCaches = 25; hatt.memoryPolicy = mp_builtin->m_att.readerHistoryMemoryPolicy; mp_SPDPReaderHistory = new ReaderHistory(hatt); ReaderAttributes ratt; @@ -531,7 +530,6 @@ bool PDPSimple::createSPDPEndpoints() hatt.payloadMaxSize = DISCOVERY_PARTICIPANT_DATA_MAX_SIZE; hatt.initialReservedCaches = 20; - hatt.maximumReservedCaches = 100; hatt.memoryPolicy = mp_builtin->m_att.writerHistoryMemoryPolicy; mp_SPDPWriterHistory = new WriterHistory(hatt); WriterAttributes watt; From 10a80d60b84ed08ea3eb0458e2f30016a1e7ad9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Tue, 19 Feb 2019 16:15:15 +0100 Subject: [PATCH 34/34] Fixing wrong unlocking. (#424) --- src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp index 1d22b4a4e57..0df38b4f2aa 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp @@ -795,7 +795,7 @@ bool EDP::pairing_reader_proxy_with_local_writer(const GUID_t& local_writer, con { (*wit)->getMutex()->lock(); GUID_t writerGUID = (*wit)->getGuid(); - (*wit)->getMutex()->lock(); + (*wit)->getMutex()->unlock(); if(local_writer == writerGUID) {