summaryrefslogtreecommitdiff
path: root/implementation
diff options
context:
space:
mode:
Diffstat (limited to 'implementation')
-rw-r--r--implementation/compat/logging/include/logger.hpp28
-rw-r--r--implementation/compat/logging/include/logger_impl.hpp33
-rw-r--r--implementation/compat/logging/src/logger.cpp16
-rw-r--r--implementation/compat/logging/src/logger_impl.cpp30
-rw-r--r--implementation/compat/message/src/message_impl.cpp5
-rw-r--r--implementation/compat/message/src/payload_impl.cpp5
-rw-r--r--implementation/compat/runtime/src/application_impl.cpp5
-rw-r--r--implementation/configuration/include/configuration.hpp48
-rw-r--r--implementation/configuration/include/configuration_impl.hpp39
-rw-r--r--implementation/configuration/include/internal.hpp.in10
-rw-r--r--implementation/configuration/include/internal_android.hpp10
-rw-r--r--implementation/configuration/include/service.hpp4
-rw-r--r--implementation/configuration/src/configuration_impl.cpp412
-rw-r--r--implementation/endpoints/include/endpoint_manager_impl.hpp18
-rw-r--r--implementation/endpoints/include/tcp_client_endpoint_impl.hpp11
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp21
-rw-r--r--implementation/endpoints/src/endpoint_manager_impl.cpp287
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp70
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp9
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp186
-rw-r--r--implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp2
-rw-r--r--implementation/logger/include/logger_impl.hpp53
-rw-r--r--implementation/logger/src/logger_impl.cpp114
-rw-r--r--implementation/logger/src/message.cpp157
-rw-r--r--implementation/logging/include/android_sink_backend.hpp33
-rw-r--r--implementation/logging/include/defines.hpp12
-rw-r--r--implementation/logging/include/dlt_sink_backend.hpp45
-rw-r--r--implementation/logging/include/logger_impl.hpp77
-rw-r--r--implementation/logging/src/android_sink_backend.cpp66
-rw-r--r--implementation/logging/src/dlt_sink_backend.cpp70
-rw-r--r--implementation/logging/src/logger.cpp14
-rw-r--r--implementation/logging/src/logger_impl.cpp211
-rw-r--r--implementation/plugin/src/plugin_manager_impl.cpp1
-rw-r--r--implementation/routing/include/event.hpp2
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp5
-rw-r--r--implementation/routing/include/remote_subscription.hpp4
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp16
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp4
-rw-r--r--implementation/routing/src/event.cpp2
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp108
-rw-r--r--implementation/routing/src/remote_subscription.cpp3
-rw-r--r--implementation/routing/src/routing_manager_base.cpp12
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp250
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp102
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp4
-rw-r--r--implementation/runtime/include/application_impl.hpp5
-rw-r--r--implementation/runtime/src/application_impl.cpp182
-rw-r--r--implementation/security/include/policy.hpp12
-rw-r--r--implementation/security/src/security_impl.cpp141
-rw-r--r--implementation/service_discovery/include/selective_option_impl.hpp1
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp4
-rw-r--r--implementation/service_discovery/include/service_discovery_host.hpp10
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp50
-rw-r--r--implementation/service_discovery/include/subscription.hpp6
-rw-r--r--implementation/service_discovery/src/remote_subscription_ack.cpp5
-rwxr-xr-ximplementation/service_discovery/src/selective_option_impl.cpp5
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp676
-rw-r--r--implementation/service_discovery/src/subscription.cpp8
-rw-r--r--implementation/utility/src/utility.cpp27
59 files changed, 2228 insertions, 1518 deletions
diff --git a/implementation/compat/logging/include/logger.hpp b/implementation/compat/logging/include/logger.hpp
deleted file mode 100644
index 0f59502..0000000
--- a/implementation/compat/logging/include/logger.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_COMPAT_LOGGER_HPP_
-#define VSOMEIP_COMPAT_LOGGER_HPP_
-
-#include <memory>
-
-#include <boost/log/sources/severity_logger.hpp>
-#include <boost/log/trivial.hpp>
-
-namespace vsomeip {
-
-class logger {
-public:
- static std::shared_ptr<logger> get();
-
- virtual ~logger() {}
-
- virtual boost::log::sources::severity_logger_mt<
- boost::log::trivial::severity_level> & get_internal() = 0;
-};
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_COMPAT_LOGGER_HPP_
diff --git a/implementation/compat/logging/include/logger_impl.hpp b/implementation/compat/logging/include/logger_impl.hpp
deleted file mode 100644
index 8aed18e..0000000
--- a/implementation/compat/logging/include/logger_impl.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_COMPAT_LOGGER_IMPL_HPP_
-#define VSOMEIP_COMPAT_LOGGER_IMPL_HPP_
-
-#include "logger.hpp"
-
-namespace vsomeip_v3 {
-class logger;
-} // namespace vsomeip_v3
-
-namespace vsomeip {
-
-class logger_impl
- : public logger {
-public:
- static std::shared_ptr<logger> get();
-
- logger_impl();
-
- boost::log::sources::severity_logger_mt<
- boost::log::trivial::severity_level> & get_internal();
-
-private:
- std::shared_ptr<vsomeip_v3::logger> impl_;
-};
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_COMPAT_LOGGER_IMPL_HPP_
diff --git a/implementation/compat/logging/src/logger.cpp b/implementation/compat/logging/src/logger.cpp
deleted file mode 100644
index eb11707..0000000
--- a/implementation/compat/logging/src/logger.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include "../include/logger_impl.hpp"
-
-namespace vsomeip {
-
-std::shared_ptr<logger>
-logger::get() {
-
- return (logger_impl::get());
-}
-
-} // namespace vsomeip
diff --git a/implementation/compat/logging/src/logger_impl.cpp b/implementation/compat/logging/src/logger_impl.cpp
deleted file mode 100644
index 4ceaaa7..0000000
--- a/implementation/compat/logging/src/logger_impl.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include "../include/logger_impl.hpp"
-#include <vsomeip/internal/logger.hpp>
-
-namespace vsomeip {
-
-std::shared_ptr<logger>
-logger_impl::get() {
-
- static std::shared_ptr<logger_impl> the_logger(
- std::make_shared<logger_impl>()
- );
- return the_logger;
-}
-
-logger_impl::logger_impl()
- : impl_(vsomeip_v3::logger::get()) {
-}
-
-boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> &
-logger_impl::get_internal() {
-
- return impl_->get_internal();
-}
-
-} // namespace vsomeip
diff --git a/implementation/compat/message/src/message_impl.cpp b/implementation/compat/message/src/message_impl.cpp
index e7e7af1..3cccc79 100644
--- a/implementation/compat/message/src/message_impl.cpp
+++ b/implementation/compat/message/src/message_impl.cpp
@@ -7,6 +7,11 @@
#include "../include/message_impl.hpp"
#include "../include/payload_impl.hpp"
+#ifdef ANDROID
+# include "../../../configuration/include/internal_android.hpp"
+#else
+# include "../../../configuration/include/internal.hpp"
+#endif
#include "../../../message/include/message_impl.hpp"
namespace vsomeip {
diff --git a/implementation/compat/message/src/payload_impl.cpp b/implementation/compat/message/src/payload_impl.cpp
index 5d78304..e1233c2 100644
--- a/implementation/compat/message/src/payload_impl.cpp
+++ b/implementation/compat/message/src/payload_impl.cpp
@@ -8,6 +8,11 @@
#include <vsomeip/internal/logger.hpp>
#include "../include/payload_impl.hpp"
+#ifdef ANDROID
+# include "../../../configuration/include/internal_android.hpp"
+#else
+# include "../../../configuration/include/internal.hpp"
+#endif
namespace vsomeip {
diff --git a/implementation/compat/runtime/src/application_impl.cpp b/implementation/compat/runtime/src/application_impl.cpp
index 559eae3..f1934e4 100644
--- a/implementation/compat/runtime/src/application_impl.cpp
+++ b/implementation/compat/runtime/src/application_impl.cpp
@@ -10,6 +10,11 @@
#include <vsomeip/internal/logger.hpp>
#include "../include/application_impl.hpp"
+#ifdef ANDROID
+# include "../../../configuration/include/internal_android.hpp"
+#else
+# include "../../../configuration/include/internal.hpp"
+#endif
#include "../../message/include/message_impl.hpp"
#include "../../message/include/payload_impl.hpp"
diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp
index aac5422..b1dcf5b 100644
--- a/implementation/configuration/include/configuration.hpp
+++ b/implementation/configuration/include/configuration.hpp
@@ -13,7 +13,7 @@
#include <chrono>
#include <boost/asio/ip/address.hpp>
-#include <boost/log/trivial.hpp>
+#include <boost/icl/interval_set.hpp>
#include <vsomeip/export.hpp>
#include <vsomeip/defines.hpp>
@@ -77,7 +77,7 @@ public:
virtual bool has_file_log() const = 0;
virtual bool has_dlt_log() const = 0;
virtual const std::string & get_logfile() const = 0;
- virtual boost::log::trivial::severity_level get_loglevel() const = 0;
+ virtual logger::level_e get_loglevel() const = 0;
virtual const std::string & get_routing_host() const = 0;
@@ -90,6 +90,13 @@ public:
virtual uint16_t get_unreliable_port(service_t _service,
instance_t _instance) const = 0;
+ virtual major_version_t get_major_version(service_t _service,
+ instance_t _instance) const = 0;
+ virtual minor_version_t get_minor_version(service_t _service,
+ instance_t _instance) const = 0;
+ virtual ttl_t get_ttl(service_t _service,
+ instance_t _instance) const = 0;
+
virtual void get_configured_timing_requests(
service_t _service, std::string _ip_target,
std::uint16_t _port_target, method_t _method,
@@ -207,14 +214,37 @@ public:
virtual std::uint32_t get_max_tcp_restart_aborts() const = 0;
virtual std::uint32_t get_max_tcp_connect_time() const = 0;
- // SD acceptance
- virtual bool sd_acceptance_required(const boost::asio::ip::address& _address,
- std::uint16_t _port) const = 0;
- virtual void set_sd_acceptance_required(
+ // Acceptance handling
+ virtual bool is_protected_device(
+ const boost::asio::ip::address& _address) const = 0;
+ virtual bool is_protected_port(
const boost::asio::ip::address& _address, std::uint16_t _port,
- const std::string& _path, bool _enable) = 0;
- typedef std::map<std::pair<boost::asio::ip::address, std::uint16_t>, std::string> sd_acceptance_required_map_t;
- virtual sd_acceptance_required_map_t get_sd_acceptance_required() = 0;
+ bool _reliable) const = 0;
+
+ typedef std::pair<std::uint16_t, std::uint16_t> port_range_t;
+ virtual void set_sd_acceptance_rule(
+ const boost::asio::ip::address &_address,
+ port_range_t _port_range, port_type_e _type,
+ const std::string &_path, bool _reliable, bool _enable, bool _default) = 0;
+
+ typedef std::map<
+ boost::asio::ip::address,
+ std::pair<
+ std::string,
+ std::map<
+ bool,
+ std::pair<
+ boost::icl::interval_set<std::uint16_t>,
+ boost::icl::interval_set<std::uint16_t>
+ >
+ >
+ >
+ > sd_acceptance_rules_t;
+ virtual void set_sd_acceptance_rules(const sd_acceptance_rules_t& _rules,
+ bool _enable) = 0;
+ virtual sd_acceptance_rules_t get_sd_acceptance_rules() = 0;
+ virtual void set_sd_acceptance_rules_active(
+ const boost::asio::ip::address& _address, bool _enable) = 0;
virtual std::uint32_t get_udp_receive_buffer_size() const = 0;
diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp
index f43a97a..e3dc94b 100644
--- a/implementation/configuration/include/configuration_impl.hpp
+++ b/implementation/configuration/include/configuration_impl.hpp
@@ -72,7 +72,7 @@ public:
VSOMEIP_EXPORT bool has_file_log() const;
VSOMEIP_EXPORT bool has_dlt_log() const;
VSOMEIP_EXPORT const std::string & get_logfile() const;
- VSOMEIP_EXPORT boost::log::trivial::severity_level get_loglevel() const;
+ VSOMEIP_EXPORT vsomeip_v3::logger::level_e get_loglevel() const;
VSOMEIP_EXPORT std::string get_unicast_address(service_t _service, instance_t _instance) const;
@@ -81,6 +81,13 @@ public:
VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service,
instance_t _instance) const;
+ VSOMEIP_EXPORT major_version_t get_major_version(service_t _service,
+ instance_t _instance) const;
+ VSOMEIP_EXPORT minor_version_t get_minor_version(service_t _service,
+ instance_t _instance) const;
+ VSOMEIP_EXPORT ttl_t get_ttl(service_t _service,
+ instance_t _instance) const;
+
VSOMEIP_EXPORT void get_configured_timing_requests(
service_t _service, std::string _ip_target,
std::uint16_t _port_target, method_t _method,
@@ -191,13 +198,21 @@ public:
VSOMEIP_EXPORT std::uint32_t get_max_tcp_restart_aborts() const;
VSOMEIP_EXPORT std::uint32_t get_max_tcp_connect_time() const;
- VSOMEIP_EXPORT bool sd_acceptance_required(const boost::asio::ip::address& _address,
- std::uint16_t _port) const;
-
- VSOMEIP_EXPORT void set_sd_acceptance_required(
- const boost::asio::ip::address& _address, std::uint16_t _port,
- const std::string& _path, bool _enable);
- VSOMEIP_EXPORT sd_acceptance_required_map_t get_sd_acceptance_required();
+ VSOMEIP_EXPORT bool is_protected_device(
+ const boost::asio::ip::address& _address) const;
+ VSOMEIP_EXPORT bool is_protected_port(
+ const boost::asio::ip::address& _address,
+ std::uint16_t _port, bool _reliable) const;
+
+ VSOMEIP_EXPORT void set_sd_acceptance_rule(
+ const boost::asio::ip::address& _address,
+ port_range_t _port_range, port_type_e _type,
+ const std::string& _path, bool _reliable, bool _enable, bool _default);
+ VSOMEIP_EXPORT void set_sd_acceptance_rules(
+ const sd_acceptance_rules_t& _rules, bool _enable);
+ VSOMEIP_EXPORT sd_acceptance_rules_t get_sd_acceptance_rules();
+ VSOMEIP_EXPORT void set_sd_acceptance_rules_active(
+ const boost::asio::ip::address& _address, bool _enable);
VSOMEIP_EXPORT std::uint32_t get_udp_receive_buffer_size() const;
@@ -302,7 +317,8 @@ private:
std::map<event_t, std::shared_ptr<debounce>> &_debounces);
void load_event_debounce_ignore(const boost::property_tree::ptree &_tree,
std::map<std::size_t, byte_t> &_ignore);
- void load_sd_acceptance_required(const configuration_element &_element);
+ void load_acceptances(const configuration_element &_element);
+ void load_acceptance_data(const boost::property_tree::ptree &_tree);
void load_udp_receive_buffer_size(const configuration_element &_element);
bool load_npdu_debounce_times_configuration(
const std::shared_ptr<service>& _service,
@@ -370,7 +386,7 @@ protected:
bool has_file_log_;
bool has_dlt_log_;
std::string logfile_;
- boost::log::trivial::severity_level loglevel_;
+ vsomeip_v3::logger::level_e loglevel_;
std::map<std::string,
std::tuple<
@@ -512,7 +528,8 @@ protected:
uint32_t tcp_connect_time_max_;
mutable std::mutex sd_acceptance_required_ips_mutex_;
- sd_acceptance_required_map_t sd_acceptance_required_ips_;
+ sd_acceptance_rules_t sd_acceptance_rules_;
+ std::set<boost::asio::ip::address> sd_acceptance_rules_active_;
bool has_issued_methods_warning_;
bool has_issued_clients_warning_;
diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in
index 36a6355..94a6e66 100644
--- a/implementation/configuration/include/internal.hpp.in
+++ b/implementation/configuration/include/internal.hpp.in
@@ -68,6 +68,7 @@
#define VSOMEIP_MAX_TCP_CONNECT_TIME 5000
#define VSOMEIP_MAX_TCP_RESTART_ABORTS 5
+#define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000
#define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5
@@ -84,6 +85,8 @@
#define VSOMEIP_REQUEST_DEBOUNCE_TIME 10
+#define VSOMEIP_MAX_WAIT_SENT 5
+
#define VSOMEIP_COMMAND_HEADER_SIZE 7
#define VSOMEIP_COMMAND_TYPE_POS 0
@@ -219,6 +222,13 @@ const std::uint32_t ANY_GID = 0xFFFFFFFF;
typedef std::pair<std::uint32_t, std::uint32_t> credentials_t;
+enum class port_type_e {
+ PT_OPTIONAL,
+ PT_SECURE,
+ PT_UNSECURE,
+ PT_UNKNOWN
+};
+
} // namespace vsomeip_v3
#endif // VSOMEIP_V3_INTERNAL_HPP_
diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp
index 9f770ac..ddb4631 100644
--- a/implementation/configuration/include/internal_android.hpp
+++ b/implementation/configuration/include/internal_android.hpp
@@ -17,6 +17,7 @@
#define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES"
#define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS"
#define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING"
+#define VSOMEIP_ENV_BASE_PATH "VSOMEIP_BASE_PATH"
#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json"
#define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json"
@@ -28,11 +29,11 @@
#define VSOMEIP_BASE_PATH "/storage/"
-#define VSOMEIP_CFG_LIBRARY "libvsomeip_cfg.so"
+#define VSOMEIP_CFG_LIBRARY "libvsomeip3-cfg.so"
-#define VSOMEIP_SD_LIBRARY "libvsomeip_sd.so"
+#define VSOMEIP_SD_LIBRARY "libvsomeip3-sd.so"
-#define VSOMEIP_E2E_LIBRARY "libvsomeip-e2e.so.3"
+#define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so"
#define VSOMEIP_ROUTING_CLIENT 0
@@ -51,6 +52,7 @@
#define VSOMEIP_MAX_TCP_CONNECT_TIME 5000
#define VSOMEIP_MAX_TCP_RESTART_ABORTS 5
+#define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000
#define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5
@@ -69,6 +71,8 @@
#define VSOMEIP_REQUEST_DEBOUNCE_TIME 10
+#define VSOMEIP_MAX_WAIT_SENT 5
+
#define VSOMEIP_COMMAND_HEADER_SIZE 7
#define VSOMEIP_COMMAND_TYPE_POS 0
diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp
index e0e0c72..8077f8e 100644
--- a/implementation/configuration/include/service.hpp
+++ b/implementation/configuration/include/service.hpp
@@ -25,6 +25,10 @@ struct service {
uint16_t reliable_;
uint16_t unreliable_;
+ major_version_t major_;
+ minor_version_t minor_;
+ ttl_t ttl_;
+
std::string multicast_address_;
uint16_t multicast_port_;
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp
index 7c0cf6a..eb7b1ea 100644
--- a/implementation/configuration/src/configuration_impl.cpp
+++ b/implementation/configuration/src/configuration_impl.cpp
@@ -9,6 +9,7 @@
#include <set>
#include <sstream>
#include <limits>
+#include <utility>
#define WIN32_LEAN_AND_MEAN
@@ -20,13 +21,14 @@
#include <vsomeip/constants.hpp>
#include <vsomeip/plugins/application_plugin.hpp>
#include <vsomeip/plugins/pre_configuration_plugin.hpp>
+#include <vsomeip/internal/logger.hpp>
#include "../include/client.hpp"
#include "../include/configuration_impl.hpp"
#include "../include/event.hpp"
#include "../include/eventgroup.hpp"
#include "../include/service.hpp"
-#include "../../logging/include/logger_impl.hpp"
+#include "../../logger/include/logger_impl.hpp"
#include "../../routing/include/event.hpp"
#include "../../service_discovery/include/defines.hpp"
#include "../../utility/include/utility.hpp"
@@ -47,7 +49,7 @@ configuration_impl::configuration_impl()
has_file_log_(false),
has_dlt_log_(false),
logfile_("/tmp/vsomeip.log"),
- loglevel_(boost::log::trivial::severity_level::info),
+ loglevel_(vsomeip_v3::logger::level_e::LL_INFO),
is_sd_enabled_(VSOMEIP_SD_DEFAULT_ENABLED),
sd_protocol_(VSOMEIP_SD_DEFAULT_PROTOCOL),
sd_multicast_(VSOMEIP_SD_DEFAULT_MULTICAST),
@@ -184,7 +186,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other)
debounces_ = _other.debounces_;
endpoint_queue_limits_ = _other.endpoint_queue_limits_;
- sd_acceptance_required_ips_ = _other.sd_acceptance_required_ips_;
+ sd_acceptance_rules_ = _other.sd_acceptance_rules_;
has_issued_methods_warning_ = _other.has_issued_methods_warning_;
has_issued_clients_warning_ = _other.has_issued_clients_warning_;
@@ -258,7 +260,7 @@ bool configuration_impl::load(const std::string &_name) {
std::vector<configuration_element> its_optional_elements;
// Dummy initialization; maybe we'll find no logging configuration
- logger_impl::init(shared_from_this());
+ logger::logger_impl::init(shared_from_this());
// Look for the standard configuration file
read_data(its_input, its_mandatory_elements, its_failed, true);
@@ -450,13 +452,14 @@ bool configuration_impl::load_data(const std::vector<configuration_element> &_el
bool _load_mandatory, bool _load_optional) {
// Load logging configuration data
std::set<std::string> its_warnings;
+
if (!is_logging_loaded_) {
for (const auto& e : _elements)
is_logging_loaded_
= load_logging(e, its_warnings) || is_logging_loaded_;
if (is_logging_loaded_) {
- logger_impl::init(shared_from_this());
+ logger::logger_impl::init(shared_from_this());
for (auto w : its_warnings)
VSOMEIP_WARNING << w;
}
@@ -496,7 +499,7 @@ bool configuration_impl::load_data(const std::vector<configuration_element> &_el
load_selective_broadcasts_support(e);
load_e2e(e);
load_debounce(e);
- load_sd_acceptance_required(e);
+ load_acceptances(e);
}
}
@@ -551,18 +554,18 @@ bool configuration_impl::load_logging(
std::string its_value(i->second.data());
loglevel_
= (its_value == "trace" ?
- boost::log::trivial::severity_level::trace :
+ vsomeip_v3::logger::level_e::LL_VERBOSE :
(its_value == "debug" ?
- boost::log::trivial::severity_level::debug :
+ vsomeip_v3::logger::level_e::LL_DEBUG :
(its_value == "info" ?
- boost::log::trivial::severity_level::info :
+ vsomeip_v3::logger::level_e::LL_INFO :
(its_value == "warning" ?
- boost::log::trivial::severity_level::warning :
+ vsomeip_v3::logger::level_e::LL_WARNING :
(its_value == "error" ?
- boost::log::trivial::severity_level::error :
+ vsomeip_v3::logger::level_e::LL_ERROR :
(its_value == "fatal" ?
- boost::log::trivial::severity_level::fatal :
- boost::log::trivial::severity_level::info))))));
+ vsomeip_v3::logger::level_e::LL_FATAL :
+ vsomeip_v3::logger::level_e::LL_INFO))))));
is_configured_[ET_LOGGING_LEVEL] = true;
}
} else if (its_key == "version") {
@@ -1416,6 +1419,9 @@ void configuration_impl::load_service(
its_service->multicast_address_ = "";
its_service->multicast_port_ = ILLEGAL_PORT;
its_service->protocol_ = "someip";
+ its_service->major_ = DEFAULT_MAJOR;
+ its_service->minor_ = DEFAULT_MINOR;
+ its_service->ttl_ = DEFAULT_TTL;
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
@@ -1480,6 +1486,14 @@ void configuration_impl::load_service(
its_converter >> its_service->service_;
} else if (its_key == "instance") {
its_converter >> its_service->instance_;
+ } else if (its_key == "major") {
+ unsigned int temp;
+ its_converter >> temp;
+ its_service->major_ = static_cast<major_version_t>(temp);
+ } else if (its_key == "minor") {
+ its_converter >> its_service->minor_;
+ } else if (its_key == "ttl") {
+ its_converter >> its_service->ttl_;
}
}
}
@@ -1581,10 +1595,10 @@ void configuration_impl::load_event(
} else {
// If event reliability type was not configured,
if (its_reliability == reliability_type_e::RT_UNKNOWN) {
- if (_service->reliable_ != ILLEGAL_PORT) {
- its_reliability = reliability_type_e::RT_RELIABLE;
- } else if (_service->unreliable_ != ILLEGAL_PORT) {
+ if (_service->unreliable_ != ILLEGAL_PORT) {
its_reliability = reliability_type_e::RT_UNRELIABLE;
+ } else if (_service->reliable_ != ILLEGAL_PORT) {
+ its_reliability = reliability_type_e::RT_RELIABLE;
}
VSOMEIP_WARNING << "Reliability type for event ["
<< std::hex << _service->service_ << "."
@@ -2154,7 +2168,7 @@ const std::string & configuration_impl::get_logfile() const {
return logfile_;
}
-boost::log::trivial::severity_level configuration_impl::get_loglevel() const {
+vsomeip_v3::logger::level_e configuration_impl::get_loglevel() const {
return loglevel_;
}
@@ -2238,6 +2252,39 @@ void configuration_impl::get_configured_timing_responses(
*_max_retention_time = npdu_default_max_retention_resp_;
}
+major_version_t configuration_impl::get_major_version(service_t _service,
+ instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ major_version_t its_major = DEFAULT_MAJOR;
+ auto its_service = find_service_unlocked(_service, _instance);
+ if (its_service)
+ its_major = its_service->major_;
+
+ return its_major;
+}
+
+minor_version_t configuration_impl::get_minor_version(service_t _service,
+ instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ minor_version_t its_minor = DEFAULT_MINOR;
+ auto its_service = find_service_unlocked(_service, _instance);
+ if (its_service)
+ its_minor = its_service->minor_;
+
+ return its_minor;
+}
+
+ttl_t configuration_impl::get_ttl(service_t _service,
+ instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ ttl_t its_ttl = DEFAULT_TTL;
+ auto its_service = find_service_unlocked(_service, _instance);
+ if (its_service)
+ its_ttl = its_service->ttl_;
+
+ return its_ttl;
+}
+
bool configuration_impl::is_someip(service_t _service,
instance_t _instance) const {
auto its_service = find_service(_service, _instance);
@@ -3206,27 +3253,136 @@ void configuration_impl::load_event_debounce_ignore(
}
void
-configuration_impl::load_sd_acceptance_required(
+configuration_impl::load_acceptances(
const configuration_element &_element) {
- const std::string sar("sd_acceptance_required");
+
+ std::string its_acceptances_key("acceptances");
+
+ if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) {
+ VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key
+ << " Ignoring definition from " << _element.name_;
+ return;
+ }
+
+ try {
+ auto its_acceptances = _element.tree_.get_child(its_acceptances_key);
+ for (auto i = its_acceptances.begin(); i != its_acceptances.end(); ++i) {
+ load_acceptance_data(i->second);
+ }
+
+ is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true;
+ } catch (...) {
+ // Intentionally left empty
+ }
+}
+
+void
+configuration_impl::load_acceptance_data(
+ const boost::property_tree::ptree &_tree) {
+
+ std::stringstream its_converter;
try {
std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_);
- if (_element.tree_.get_child_optional(sar)) {
- if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) {
- VSOMEIP_WARNING << "Multiple definitions of " << sar
- << " Ignoring definition from " << _element.name_;
- } else {
- for (const auto& ipe : _element.tree_.get_child(sar)) {
- boost::system::error_code ec;
- boost::asio::ip::address its_address =
- boost::asio::ip::address::from_string(ipe.first.data(), ec);
- if (!its_address.is_unspecified()) {
- sd_acceptance_required_ips_[{its_address, ANY_PORT}] = ipe.second.data();
+
+ boost::asio::ip::address its_address;
+ std::string its_path;
+ std::map<bool,
+ std::pair<boost::icl::interval_set<std::uint16_t>,
+ boost::icl::interval_set<std::uint16_t>
+ >
+ > its_ports;
+ bool has_optional, has_secure, is_reliable;
+
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+
+ std::string its_key(i->first);
+ std::string its_value(i->second.data());
+
+ if (its_key == "address") {
+ boost::system::error_code ec;
+ its_address = boost::asio::ip::address::from_string(its_value);
+ } else if (its_key == "path") {
+ its_path = its_value;
+ } else if (its_key == "reliable" || its_key == "unreliable") {
+
+ is_reliable = (its_key == "reliable");
+ has_optional = has_secure = false;
+
+ for (const auto &p : i->second) {
+ if (p.second.size()) { // range
+ std::uint16_t its_first(0);
+ std::uint16_t its_last(0);
+ port_type_e its_type(port_type_e::PT_OPTIONAL);
+
+ for (const auto& range : p.second) {
+ const std::string its_key(range.first);
+ const std::string its_value(range.second.data());
+ if (its_key == "first" || its_key == "last" || its_key == "port") {
+ its_converter << std::dec << its_value;
+ std::uint16_t its_port_value(0);
+ its_converter >> its_port_value;
+ its_converter.str("");
+ its_converter.clear();
+ if (its_key == "first") {
+ its_first = its_port_value;
+ } else if (its_key == "last") {
+ its_last = its_port_value;
+ } else if (its_key == "port") {
+ its_first = its_last = its_port_value;
+ }
+ } else if (its_key == "type") {
+ if (its_value == "secure") {
+ its_type = port_type_e::PT_SECURE;
+ } else if (its_value == "optional") {
+ its_type = port_type_e::PT_OPTIONAL;
+ } else {
+ its_type = port_type_e::PT_UNKNOWN;
+ }
+ }
+ }
+ if (its_type != port_type_e::PT_UNKNOWN) {
+ if (its_type == port_type_e::PT_OPTIONAL) {
+ has_optional = true;
+ if (its_first != 0 && its_last != 0) {
+ its_ports.operator [](is_reliable).first.insert(
+ boost::icl::interval<std::uint16_t>::closed(its_first, its_last));
+ }
+ } else {
+ has_secure = true;
+ if (its_first != 0 && its_last != 0) {
+ its_ports.operator [](is_reliable).second.insert(
+ boost::icl::interval<std::uint16_t>::closed(its_first, its_last));
+ }
+ }
+ }
}
}
- is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true;
+
+ // If optional was not set, use default!
+ if (!has_optional) {
+ const auto its_optional_client = boost::icl::interval<std::uint16_t>::closed(30491, 30499);
+ const auto its_optional_server = boost::icl::interval<std::uint16_t>::closed(30501, 30599);
+
+ its_ports.operator [](is_reliable).first.insert(its_optional_client);
+ its_ports.operator [](is_reliable).first.insert(its_optional_server);
+ }
+
+ // If secure was not set, use default!
+ if (!has_secure) {
+ const auto its_secure_client = boost::icl::interval<std::uint16_t>::closed(32491, 32499);
+ const auto its_secure_server = boost::icl::interval<std::uint16_t>::closed(32501, 32599);
+
+ its_ports.operator [](is_reliable).second.insert(its_secure_client);
+ its_ports.operator [](is_reliable).second.insert(its_secure_server);
+ }
}
}
+
+ if (!its_address.is_unspecified()) {
+ sd_acceptance_rules_.insert(
+ std::make_pair(its_address,
+ std::make_pair(its_path, its_ports)));
+ }
} catch (...) {
// intentionally left empty
}
@@ -3448,37 +3604,189 @@ std::uint32_t configuration_impl::get_max_tcp_connect_time() const {
return tcp_connect_time_max_;
}
-bool configuration_impl::sd_acceptance_required(
- const boost::asio::ip::address& _address, std::uint16_t _port) const {
+bool configuration_impl::is_protected_device(
+ const boost::asio::ip::address& _address) const {
std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_);
- return sd_acceptance_required_ips_.find({_address, _port})
- != sd_acceptance_required_ips_.end();
+ return (sd_acceptance_rules_active_.find(_address)
+ != sd_acceptance_rules_active_.end());
}
-void configuration_impl::set_sd_acceptance_required(
+bool configuration_impl::is_protected_port(
const boost::asio::ip::address& _address, std::uint16_t _port,
- const std::string& _path, bool _enable) {
+ bool _reliable) const {
+
+ bool is_required(is_protected_device(_address));
+
std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_);
- if (_enable) {
- const auto found_address = sd_acceptance_required_ips_.find({_address, _port});
- if (found_address != sd_acceptance_required_ips_.end()) {
- boost::system::error_code ec;
- VSOMEIP_WARNING << __func__ << " configuration for: "
- << found_address->first.first.to_string(ec) << ":"
- << std::dec << _port << " -> "
- << found_address->first.second << " already configured."
- << " Won't update with: "<< _path;
- } else {
- sd_acceptance_required_ips_[{_address, _port}] = _path;
+ const auto found_address = sd_acceptance_rules_.find(_address);
+ if (found_address != sd_acceptance_rules_.end()) {
+ const auto found_reliability = found_address->second.second.find(_reliable);
+ if (found_reliability != found_address->second.second.end()) {
+ const auto its_range = boost::icl::interval<std::uint16_t>::closed(_port, _port);
+
+ bool is_optional
+ = (found_reliability->second.first.find(its_range)
+ != found_reliability->second.first.end());
+
+ bool is_secure
+ = (found_reliability->second.second.find(its_range)
+ != found_reliability->second.second.end());
+
+ is_required = ((is_required && is_optional) || is_secure);
}
- } else {
- sd_acceptance_required_ips_.erase({_address, _port});
}
+
+ return (is_required);
}
-configuration::sd_acceptance_required_map_t configuration_impl::get_sd_acceptance_required() {
+void configuration_impl::set_sd_acceptance_rule(
+ const boost::asio::ip::address &_address,
+ port_range_t _port_range, port_type_e _type,
+ const std::string &_path, bool _reliable, bool _enable, bool _default) {
+
+ (void)_port_range;
+ (void)_type;
+
std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_);
- return sd_acceptance_required_ips_;
+
+ const auto its_optional_client = boost::icl::interval<std::uint16_t>::closed(30491, 30499);
+ const auto its_optional_server = boost::icl::interval<std::uint16_t>::closed(30501, 30599);
+ const auto its_secure_client = boost::icl::interval<std::uint16_t>::closed(32491, 32499);
+ const auto its_secure_server = boost::icl::interval<std::uint16_t>::closed(32501, 32599);
+
+ const bool rules_active = (sd_acceptance_rules_active_.find(_address)
+ != sd_acceptance_rules_active_.end());
+
+ const auto found_address = sd_acceptance_rules_.find(_address);
+ if (found_address != sd_acceptance_rules_.end()) {
+ if (found_address->second.first.length() > 0
+ && found_address->second.first != _path) {
+ VSOMEIP_WARNING << __func__ << ": activation path for IP: "
+ << _address << " differ: "
+ << found_address->second.first << " vs. " << _path
+ << " will use: " << found_address->second.first;
+ } else {
+ found_address->second.first = _path;
+ }
+ const auto found_reliability = found_address->second.second.find(_reliable);
+ if (found_reliability != found_address->second.second.end()) {
+ if (_enable) {
+ // only insert full range interval if there are no other intervals
+ // configured
+ if (!_default ||
+ (found_reliability->second.first.empty()
+ && found_reliability->second.second.empty())) {
+ found_reliability->second.first.add(its_optional_client);
+ found_reliability->second.first.add(its_optional_server);
+ found_reliability->second.second.add(its_secure_client);
+ found_reliability->second.second.add(its_secure_server);
+ if (!rules_active) {
+ sd_acceptance_rules_active_.insert(_address);
+ }
+ VSOMEIP_INFO << "ipsec:acceptance:" << _address
+ << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges "
+ << found_reliability->second.first << " "
+ << found_reliability->second.second;
+ } else {
+ VSOMEIP_INFO << "ipsec:acceptance:" << _address
+ << ":" << (_reliable ? "tcp" : "udp") << ": using configured ranges "
+ << found_reliability->second.first << " "
+ << found_reliability->second.second;
+ }
+ } else {
+ found_reliability->second.first.erase(its_optional_client);
+ found_reliability->second.first.erase(its_optional_server);
+ found_reliability->second.second.erase(its_secure_client);
+ found_reliability->second.second.erase(its_secure_server);
+ if (found_reliability->second.first.empty()
+ && found_reliability->second.second.empty()) {
+ found_address->second.second.erase(found_reliability);
+ if (found_address->second.second.empty()) {
+ sd_acceptance_rules_.erase(found_address);
+ if (rules_active) {// no more rules for IP present
+ sd_acceptance_rules_active_.erase(_address);
+ }
+ }
+ }
+ }
+ } else if (_enable) {
+ boost::icl::interval_set<std::uint16_t> its_optional_default;
+ its_optional_default.add(its_optional_client);
+ its_optional_default.add(its_optional_server);
+ boost::icl::interval_set<std::uint16_t> its_secure_default;
+ its_secure_default.add(its_secure_client);
+ its_secure_default.add(its_secure_server);
+
+ found_address->second.second.emplace(
+ std::make_pair(_reliable,
+ std::make_pair(its_optional_default, its_secure_default)));
+ if (!rules_active) {
+ sd_acceptance_rules_active_.insert(_address);
+ }
+
+ const auto found_reliability = found_address->second.second.find(_reliable);
+ VSOMEIP_INFO << "ipsec:acceptance:" << _address
+ << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges "
+ << found_reliability->second.first << " "
+ << found_reliability->second.second;
+ }
+ } else if (_enable) {
+ boost::icl::interval_set<std::uint16_t> its_optional_default;
+ its_optional_default.add(its_optional_client);
+ its_optional_default.add(its_optional_server);
+ boost::icl::interval_set<std::uint16_t> its_secure_default;
+ its_secure_default.add(its_secure_client);
+ its_secure_default.add(its_secure_server);
+
+ sd_acceptance_rules_.emplace(std::make_pair(_address,
+ std::make_pair(
+ _path,
+ std::map<
+ bool,
+ std::pair<
+ boost::icl::interval_set<std::uint16_t>,
+ boost::icl::interval_set<std::uint16_t>
+ >
+ >({{
+ _reliable,
+ std::make_pair(its_optional_default, its_secure_default)
+ }}))));
+ if (!rules_active) {
+ sd_acceptance_rules_active_.insert(_address);
+ }
+
+ const auto found_address = sd_acceptance_rules_.find(_address);
+ if (found_address != sd_acceptance_rules_.end()) {
+ const auto found_reliability = found_address->second.second.find(_reliable);
+ if (found_reliability != found_address->second.second.end()) {
+ VSOMEIP_INFO << "ipsec:acceptance:" << _address
+ << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges "
+ << found_reliability->second.first << " "
+ << found_reliability->second.second;
+ }
+ }
+ }
+}
+
+void configuration_impl::set_sd_acceptance_rules(
+ const sd_acceptance_rules_t& _rules, bool _enable) {
+ // Unused, only still available to preserve compatibility
+ (void)_rules;
+ (void)_enable;
+}
+
+configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules() {
+ std::lock_guard<std::mutex> its_lock(sd_acceptance_required_ips_mutex_);
+ return sd_acceptance_rules_;
+}
+
+void configuration_impl::set_sd_acceptance_rules_active(
+ const boost::asio::ip::address& _address, bool _enable) {
+ if (_enable) {
+ sd_acceptance_rules_active_.insert(_address);
+ } else {
+ sd_acceptance_rules_active_.erase(_address);
+ }
}
std::uint32_t configuration_impl::get_udp_receive_buffer_size() const {
diff --git a/implementation/endpoints/include/endpoint_manager_impl.hpp b/implementation/endpoints/include/endpoint_manager_impl.hpp
index 3f61b7a..cdf41b8 100644
--- a/implementation/endpoints/include/endpoint_manager_impl.hpp
+++ b/implementation/endpoints/include/endpoint_manager_impl.hpp
@@ -21,11 +21,9 @@ public:
std::shared_ptr<endpoint> find_or_create_remote_client(service_t _service,
instance_t _instance,
- bool _reliable,
- client_t _client);
+ bool _reliable);
- void find_or_create_remote_client(service_t _service, instance_t _instance,
- client_t _client);
+ void find_or_create_remote_client(service_t _service, instance_t _instance);
void is_remote_service_known(
service_t _service, instance_t _instance, major_version_t _major,
minor_version_t _minor,
@@ -90,15 +88,13 @@ public:
private:
std::shared_ptr<endpoint> find_remote_client(service_t _service,
instance_t _instance,
- bool _reliable,
- client_t _client);
+ bool _reliable);
std::shared_ptr<endpoint> create_remote_client(service_t _service,
instance_t _instance,
- bool _reliable,
- client_t _client);
+ bool _reliable);
std::shared_ptr<endpoint> create_client_endpoint(
const boost::asio::ip::address &_address, uint16_t _local_port,
- uint16_t _remote_port, bool _reliable, client_t _client);
+ uint16_t _remote_port, bool _reliable);
private:
mutable std::recursive_mutex endpoint_mutex_;
@@ -106,8 +102,8 @@ private:
std::map<service_t, std::map<instance_t,
std::map<bool, std::shared_ptr<endpoint_definition>>>> remote_service_info_;
- typedef std::map<service_t, std::map<instance_t, std::map<client_t,
- std::map<bool, std::shared_ptr<endpoint>>>>> remote_services_t;
+ typedef std::map<service_t, std::map<instance_t,
+ std::map<bool, std::shared_ptr<endpoint>>>> remote_services_t;
remote_services_t remote_services_;
typedef std::map<boost::asio::ip::address, std::map<uint16_t,
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
index 4765bd8..e8c2c9a 100644
--- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
@@ -6,9 +6,11 @@
#ifndef VSOMEIP_V3_TCP_CLIENT_ENDPOINT_IMPL_HPP_
#define VSOMEIP_V3_TCP_CLIENT_ENDPOINT_IMPL_HPP_
-#include <boost/asio/ip/tcp.hpp>
#include <chrono>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/steady_timer.hpp>
+
#include <vsomeip/defines.hpp>
#include "client_endpoint_impl.hpp"
@@ -79,6 +81,8 @@ private:
std::uint32_t get_max_allowed_reconnects() const;
void max_allowed_reconnects_reached();
+ void wait_until_sent(const boost::system::error_code &_error);
+
const std::uint32_t recv_buffer_size_initial_;
message_buffer_ptr_t recv_buffer_;
std::uint32_t shrink_count_;
@@ -94,6 +98,11 @@ private:
std::uint32_t tcp_connect_time_max_;
std::atomic<uint32_t> aborted_restart_count_;
std::chrono::steady_clock::time_point connect_timepoint_;
+
+ std::mutex sent_mutex_;
+ bool is_sending_;
+ boost::asio::steady_timer sent_timer_;
+
};
} // namespace vsomeip_v3
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
index 1a6cef6..db936f3 100644
--- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
@@ -62,9 +62,10 @@ public:
bool is_reliable() const;
private:
+ void leave_unlocked(const std::string &_address);
void set_broadcast();
void receive_unicast();
- void receive_multicast();
+ void receive_multicast(uint8_t _id);
bool is_joined(const std::string &_address) const;
bool is_joined(const std::string &_address, bool* _received) const;
std::string get_remote_information(
@@ -80,7 +81,8 @@ private:
void on_multicast_received(boost::system::error_code const &_error,
std::size_t _bytes,
- boost::asio::ip::address const &_destination);
+ boost::asio::ip::address const &_destination,
+ uint8_t _multicast_id);
void on_message_received(boost::system::error_code const &_error,
std::size_t _bytes,
@@ -92,19 +94,20 @@ private:
socket_type unicast_socket_;
endpoint_type unicast_remote_;
message_buffer_t unicast_recv_buffer_;
- mutable std::mutex unicast_socket_mutex_;
+ mutable std::mutex unicast_mutex_;
std::unique_ptr<socket_type> multicast_socket_;
- std::unique_ptr<endpoint_type> multicast_ep_;
+ std::unique_ptr<endpoint_type> multicast_local_;
endpoint_type multicast_remote_;
- std::unique_ptr<message_buffer_t> multicast_recv_buffer_;
- mutable std::mutex multicast_socket_mutex_;
+ message_buffer_t multicast_recv_buffer_;
+ mutable std::mutex multicast_mutex_;
+ uint8_t multicast_id_;
+ std::map<std::string, bool> joined_;
+ std::atomic<bool> joined_group_;
mutable std::mutex default_targets_mutex_;
std::map<service_t, endpoint_type> default_targets_;
- mutable std::mutex joined_mutex_;
- std::map<std::string, bool> joined_;
- std::atomic<bool> joined_group_;
+
const std::uint16_t local_port_;
std::shared_ptr<tp::tp_reassembler> tp_reassembler_;
diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp
index 6d37509..d4fedd4 100644
--- a/implementation/endpoints/src/endpoint_manager_impl.cpp
+++ b/implementation/endpoints/src/endpoint_manager_impl.cpp
@@ -39,14 +39,14 @@ endpoint_manager_impl::endpoint_manager_impl(
}
std::shared_ptr<endpoint> endpoint_manager_impl::find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ service_t _service, instance_t _instance, bool _reliable) {
std::shared_ptr<endpoint> its_endpoint;
bool start_endpoint(false);
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- its_endpoint = find_remote_client(_service, _instance, _reliable, _client);
+ its_endpoint = find_remote_client(_service, _instance, _reliable);
if (!its_endpoint) {
- its_endpoint = create_remote_client(_service, _instance, _reliable, _client);
+ its_endpoint = create_remote_client(_service, _instance, _reliable);
start_endpoint = true;
}
}
@@ -58,22 +58,21 @@ std::shared_ptr<endpoint> endpoint_manager_impl::find_or_create_remote_client(
}
void endpoint_manager_impl::find_or_create_remote_client(
- service_t _service, instance_t _instance,
- client_t _client) {
+ service_t _service, instance_t _instance) {
std::shared_ptr<endpoint> its_reliable_endpoint;
std::shared_ptr<endpoint> its_unreliable_endpoint;
bool start_reliable_endpoint(false);
bool start_unreliable_endpoint(false);
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- its_reliable_endpoint = find_remote_client(_service, _instance, true, _client);
+ its_reliable_endpoint = find_remote_client(_service, _instance, true);
if (!its_reliable_endpoint) {
- its_reliable_endpoint = create_remote_client(_service, _instance, true, _client);
+ its_reliable_endpoint = create_remote_client(_service, _instance, true);
start_reliable_endpoint = true;
}
- its_unreliable_endpoint = find_remote_client(_service, _instance, false, _client);
+ its_unreliable_endpoint = find_remote_client(_service, _instance, false);
if (!its_unreliable_endpoint) {
- its_unreliable_endpoint = create_remote_client(_service, _instance, false, _client);
+ its_unreliable_endpoint = create_remote_client(_service, _instance, false);
start_unreliable_endpoint = true;
}
}
@@ -285,55 +284,40 @@ void endpoint_manager_impl::clear_client_endpoints(service_t _service, instance_
bool _reliable) {
std::shared_ptr<endpoint> endpoint_to_delete;
bool other_services_reachable_through_endpoint(false);
- std::vector<std::shared_ptr<endpoint>> its_specific_endpoints;
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
// Clear client endpoints for remote services (generic and specific ones)
- if (remote_services_.find(_service) != remote_services_.end()) {
- if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
- auto endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable];
- if (endpoint) {
- service_instances_[_service].erase(endpoint.get());
- endpoint_to_delete = endpoint;
- }
- remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].erase(_reliable);
- auto found_endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].find(
- !_reliable);
- if (found_endpoint == remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].end()) {
- remote_services_[_service][_instance].erase(VSOMEIP_ROUTING_CLIENT);
- }
- }
- }
- if (remote_services_.find(_service) != remote_services_.end()) {
- if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
- if (!remote_services_[_service][_instance].size()) {
- remote_services_[_service].erase(_instance);
- if (0 >= remote_services_[_service].size()) {
- remote_services_.erase(_service);
+ const auto found_service = remote_services_.find(_service);
+ if (found_service != remote_services_.end()) {
+ const auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ const auto found_reliability = found_instance->second.find(_reliable);
+ if (found_reliability != found_instance->second.end()) {
+ service_instances_[_service].erase(found_reliability->second.get());
+ endpoint_to_delete = found_reliability->second;
+
+ found_instance->second.erase(found_reliability);
+ if (found_instance->second.empty()) {
+ found_service->second.erase(found_instance);
+ if (found_service->second.empty()) {
+ remote_services_.erase(found_service);
+ }
}
}
}
}
- if (!service_instances_[_service].size()) {
- service_instances_.erase(_service);
- }
-
// Only stop and delete the endpoint if none of the services
// reachable through it is online anymore.
if (endpoint_to_delete) {
for (const auto& service : remote_services_) {
for (const auto& instance : service.second) {
- const auto& client = instance.second.find(VSOMEIP_ROUTING_CLIENT);
- if (client != instance.second.end()) {
- for (const auto& reliable : client->second) {
- if (reliable.second == endpoint_to_delete) {
- other_services_reachable_through_endpoint = true;
- break;
- }
- }
+ const auto found_reliability = instance.second.find(_reliable);
+ if (found_reliability != instance.second.end()
+ && found_reliability->second == endpoint_to_delete) {
+ other_services_reachable_through_endpoint = true;
+ break;
}
- if (other_services_reachable_through_endpoint) { break; }
}
if (other_services_reachable_through_endpoint) { break; }
}
@@ -381,9 +365,6 @@ void endpoint_manager_impl::clear_client_endpoints(service_t _service, instance_
if (!other_services_reachable_through_endpoint && endpoint_to_delete) {
endpoint_to_delete->stop();
}
- for (const auto &specific_endpoint : its_specific_endpoints) {
- specific_endpoint->stop();
- }
}
void endpoint_manager_impl::find_or_create_multicast_endpoint(
@@ -493,12 +474,10 @@ void endpoint_manager_impl::print_status() const {
// udp and tcp client endpoints
{
client_endpoints_by_ip_t client_endpoints_by_ip;
- remote_services_t remote_services;
server_endpoints_t server_endpoints;
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
client_endpoints_by_ip = client_endpoints_by_ip_;
- remote_services = remote_services_;
server_endpoints = server_endpoints_;
}
VSOMEIP_INFO << "status start remote client endpoints:";
@@ -515,24 +494,6 @@ void endpoint_manager_impl::print_status() const {
VSOMEIP_INFO << "status end remote client endpoints: " << std::dec
<< num_remote_client_endpoints;
- // selective client endpoints
- VSOMEIP_INFO << "status start selective remote client endpoints:";
- std::uint32_t num_remote_selectiv_client_endpoints(0);
- for (const auto& s : remote_services) {
- for (const auto& i : s.second) {
- for (const auto& c : i.second) {
- if (c.first != VSOMEIP_ROUTING_CLIENT) {
- for (const auto& ur : c.second) {
- ur.second->print_status();
- num_remote_selectiv_client_endpoints++;
- }
- }
- }
- }
- }
- VSOMEIP_INFO << "status end selective remote client endpoints: "
- << std::dec << num_remote_selectiv_client_endpoints;
-
VSOMEIP_INFO << "status start server endpoints:";
std::uint32_t num_server_endpoints(1);
// local server endpoints
@@ -677,36 +638,31 @@ void endpoint_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
for (auto &its_service : remote_services_) {
for (auto &its_instance : its_service.second) {
- for (auto &its_client : its_instance.second) {
- if (its_client.first == VSOMEIP_ROUTING_CLIENT ||
- its_client.first == get_client()) {
- auto found_endpoint = its_client.second.find(endpoint_is_reliable);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second == _endpoint) {
- std::shared_ptr<serviceinfo> its_info(
- rm_->find_service(its_service.first,
- its_instance.first));
- if (!its_info) {
- _endpoint->set_established(true);
- return;
- }
- // only report services offered via TCP+UDP when both
- // endpoints are connected
- const auto its_other_endpoint = its_info->get_endpoint(
- !endpoint_is_reliable);
-
- if (!its_other_endpoint || (its_other_endpoint
- && its_other_endpoint->is_established_or_connected())) {
- services_to_report_.push_front(
- { its_service.first,
- its_instance.first,
- its_info->get_major(),
- its_info->get_minor(),
- _endpoint,
- (!endpoint_is_reliable &&
- !its_other_endpoint)});
- }
- }
+ auto found_endpoint = its_instance.second.find(endpoint_is_reliable);
+ if (found_endpoint != its_instance.second.end()) {
+ if (found_endpoint->second == _endpoint) {
+ std::shared_ptr<serviceinfo> its_info(
+ rm_->find_service(its_service.first,
+ its_instance.first));
+ if (!its_info) {
+ _endpoint->set_established(true);
+ return;
+ }
+ // only report services offered via TCP+UDP when both
+ // endpoints are connected
+ const auto its_other_endpoint = its_info->get_endpoint(
+ !endpoint_is_reliable);
+
+ if (!its_other_endpoint || (its_other_endpoint
+ && its_other_endpoint->is_established_or_connected())) {
+ services_to_report_.push_front(
+ { its_service.first,
+ its_instance.first,
+ its_info->get_major(),
+ its_info->get_minor(),
+ _endpoint,
+ (!endpoint_is_reliable &&
+ !its_other_endpoint)});
}
}
}
@@ -728,31 +684,26 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
for (auto &its_service : remote_services_) {
for (auto &its_instance : its_service.second) {
- for (auto &its_client : its_instance.second) {
- if (its_client.first == VSOMEIP_ROUTING_CLIENT ||
- its_client.first == get_client()) {
- const bool is_reliable = _endpoint->is_reliable();
- auto found_endpoint = its_client.second.find(is_reliable);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second == _endpoint) {
- std::shared_ptr<serviceinfo> its_info(
- rm_->find_service(its_service.first,
- its_instance.first));
- if(!its_info){
- return;
- }
- if (!is_reliable) {
- static_cast<routing_manager_impl*>(rm_)->on_availability(
- its_service.first, its_instance.first,
- false, its_info->get_major(),
- its_info->get_minor());
- }
- static_cast<routing_manager_impl*>(rm_)->service_endpoint_disconnected(
- its_service.first, its_instance.first,
- its_info->get_major(),
- its_info->get_minor(), _endpoint);
- }
+ const bool is_reliable = _endpoint->is_reliable();
+ auto found_endpoint = its_instance.second.find(is_reliable);
+ if (found_endpoint != its_instance.second.end()) {
+ if (found_endpoint->second == _endpoint) {
+ std::shared_ptr<serviceinfo> its_info(
+ rm_->find_service(its_service.first,
+ its_instance.first));
+ if(!its_info){
+ return;
+ }
+ if (!is_reliable) {
+ static_cast<routing_manager_impl*>(rm_)->on_availability(
+ its_service.first, its_instance.first,
+ false, its_info->get_major(),
+ its_info->get_minor());
}
+ static_cast<routing_manager_impl*>(rm_)->service_endpoint_disconnected(
+ its_service.first, its_instance.first,
+ its_info->get_major(),
+ its_info->get_minor(), _endpoint);
}
}
}
@@ -780,22 +731,19 @@ void endpoint_manager_impl::release_port(uint16_t _port, bool _reliable) {
}
std::shared_ptr<endpoint> endpoint_manager_impl::find_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ service_t _service, instance_t _instance, bool _reliable) {
std::shared_ptr<endpoint> its_endpoint;
auto found_service = remote_services_.find(_service);
if (found_service != remote_services_.end()) {
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
- auto found_client = found_instance->second.find(_client);
- if (found_client != found_instance->second.end()) {
- auto found_reliability = found_client->second.find(_reliable);
- if (found_reliability != found_client->second.end()) {
- its_endpoint = found_reliability->second;
- }
+ auto found_reliability = found_instance->second.find(_reliable);
+ if (found_reliability != found_instance->second.end()) {
+ its_endpoint = found_reliability->second;
}
}
}
- if (its_endpoint || _client != VSOMEIP_ROUTING_CLIENT) {
+ if (its_endpoint) {
return its_endpoint;
}
@@ -821,7 +769,7 @@ std::shared_ptr<endpoint> endpoint_manager_impl::find_remote_client(
its_endpoint = found_reliable2->second;
// store the endpoint under this service/instance id
// as well - needed for later cleanup
- remote_services_[_service][_instance][_client][_reliable] =
+ remote_services_[_service][_instance][_reliable] =
its_endpoint;
service_instances_[_service][its_endpoint.get()] = _instance;
// add endpoint to serviceinfo object
@@ -839,7 +787,7 @@ std::shared_ptr<endpoint> endpoint_manager_impl::find_remote_client(
}
std::shared_ptr<endpoint> endpoint_manager_impl::create_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ service_t _service, instance_t _instance, bool _reliable) {
std::shared_ptr<endpoint> its_endpoint;
std::shared_ptr<endpoint_definition> its_endpoint_def;
uint16_t its_local_port;
@@ -868,24 +816,22 @@ std::shared_ptr<endpoint> endpoint_manager_impl::create_remote_client(
its_endpoint_def->get_address(),
its_local_port,
its_endpoint_def->get_port(),
- _reliable, _client
- );
+ _reliable);
}
if (its_endpoint) {
used_client_ports_[_reliable].insert(its_local_port);
its_lock.unlock();
service_instances_[_service][its_endpoint.get()] = _instance;
- remote_services_[_service][_instance][_client][_reliable] = its_endpoint;
- if (_client == VSOMEIP_ROUTING_CLIENT) {
- client_endpoints_by_ip_[its_endpoint_def->get_address()]
- [its_endpoint_def->get_port()]
- [_reliable] = its_endpoint;
- // Set the basic route to the service in the service info
- auto found_service_info = rm_->find_service(_service, _instance);
- if (found_service_info) {
- found_service_info->set_endpoint(its_endpoint, _reliable);
- }
+ remote_services_[_service][_instance][_reliable] = its_endpoint;
+
+ client_endpoints_by_ip_[its_endpoint_def->get_address()]
+ [its_endpoint_def->get_port()]
+ [_reliable] = its_endpoint;
+ // Set the basic route to the service in the service info
+ auto found_service_info = rm_->find_service(_service, _instance);
+ if (found_service_info) {
+ found_service_info->set_endpoint(its_endpoint, _reliable);
}
}
}
@@ -896,8 +842,7 @@ std::shared_ptr<endpoint> endpoint_manager_impl::create_remote_client(
std::shared_ptr<endpoint> endpoint_manager_impl::create_client_endpoint(
const boost::asio::ip::address &_address,
uint16_t _local_port, uint16_t _remote_port,
- bool _reliable, client_t _client) {
- (void)_client;
+ bool _reliable) {
std::shared_ptr<endpoint> its_endpoint;
boost::asio::ip::address its_unicast = configuration_->get_unicast_address();
@@ -935,6 +880,7 @@ std::shared_ptr<endpoint> endpoint_manager_impl::create_client_endpoint(
void
endpoint_manager_impl::log_client_states() const {
std::stringstream its_log;
+ client_endpoints_by_ip_t its_client_endpoints;
std::vector<
std::pair<
std::tuple<boost::asio::ip::address, uint16_t, bool>,
@@ -944,19 +890,21 @@ endpoint_manager_impl::log_client_states() const {
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- for (const auto its_address : client_endpoints_by_ip_) {
- for (const auto its_port : its_address.second) {
- for (const auto its_reliability : its_port.second) {
- size_t its_queue_size = its_reliability.second->get_queue_size();
- if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE)
- its_client_queue_sizes.push_back(
- std::make_pair(
- std::make_tuple(
- its_address.first,
- its_port.first,
- its_reliability.first),
- its_queue_size));
- }
+ its_client_endpoints = client_endpoints_by_ip_;
+ }
+
+ for (const auto its_address : its_client_endpoints) {
+ for (const auto its_port : its_address.second) {
+ for (const auto its_reliability : its_port.second) {
+ size_t its_queue_size = its_reliability.second->get_queue_size();
+ if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE)
+ its_client_queue_sizes.push_back(
+ std::make_pair(
+ std::make_tuple(
+ its_address.first,
+ its_port.first,
+ its_reliability.first),
+ its_queue_size));
}
}
}
@@ -989,6 +937,7 @@ endpoint_manager_impl::log_client_states() const {
void
endpoint_manager_impl::log_server_states() const {
std::stringstream its_log;
+ server_endpoints_t its_server_endpoints;
std::vector<
std::pair<
std::pair<uint16_t, bool>,
@@ -998,17 +947,19 @@ endpoint_manager_impl::log_server_states() const {
{
std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- for (const auto its_port : server_endpoints_) {
- for (const auto its_reliability : its_port.second) {
- size_t its_queue_size = its_reliability.second->get_queue_size();
- if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE)
- its_client_queue_sizes.push_back(
+ its_server_endpoints = server_endpoints_;
+ }
+
+ for (const auto its_port : its_server_endpoints) {
+ for (const auto its_reliability : its_port.second) {
+ size_t its_queue_size = its_reliability.second->get_queue_size();
+ if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE)
+ its_client_queue_sizes.push_back(
+ std::make_pair(
std::make_pair(
- std::make_pair(
- its_port.first,
- its_reliability.first),
- its_queue_size));
- }
+ its_port.first,
+ its_reliability.first),
+ its_queue_size));
}
}
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
index 2c56521..2a86244 100644
--- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
@@ -49,7 +49,9 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl(
send_timeout_warning_(send_timeout_ / 2),
tcp_restart_aborts_max_(configuration_->get_max_tcp_restart_aborts()),
tcp_connect_time_max_(configuration_->get_max_tcp_connect_time()),
- aborted_restart_count_(0) {
+ aborted_restart_count_(0),
+ sent_timer_(_io) {
+
is_supporting_magic_cookies_ = true;
}
@@ -320,6 +322,10 @@ void tcp_client_endpoint_impl::send_queued() {
{
std::lock_guard<std::mutex> its_lock(socket_mutex_);
if (socket_->is_open()) {
+ {
+ std::lock_guard<std::mutex> its_sent_lock(sent_mutex_);
+ is_sending_ = true;
+ }
boost::asio::async_write(
*socket_,
boost::asio::buffer(*its_buffer),
@@ -584,9 +590,10 @@ void tcp_client_endpoint_impl::receive_cbk(
state_ = cei_state_e::CONNECTING;
shutdown_and_close_socket_unlocked(false);
its_lock.unlock();
- std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
- its_ep_host->on_disconnect(shared_from_this());
- restart(true);
+
+ // wait_until_sent interprets "no error" as timeout.
+ // Therefore call it with an error.
+ wait_until_sent(boost::asio::error::operation_aborted);
return;
} else if (max_message_size_ != MESSAGE_SIZE_UNLIMITED &&
current_message_size > max_message_size_) {
@@ -612,9 +619,10 @@ void tcp_client_endpoint_impl::receive_cbk(
state_ = cei_state_e::CONNECTING;
shutdown_and_close_socket_unlocked(false);
its_lock.unlock();
- std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
- its_ep_host->on_disconnect(shared_from_this());
- restart(true);
+
+ // wait_until_sent interprets "no error" as timeout.
+ // Therefore call it with an error.
+ wait_until_sent(boost::asio::error::operation_aborted);
return;
}
} else if (current_message_size > _recv_buffer_size) {
@@ -649,9 +657,10 @@ void tcp_client_endpoint_impl::receive_cbk(
state_ = cei_state_e::CONNECTING;
shutdown_and_close_socket_unlocked(false);
its_lock.unlock();
- std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
- its_ep_host->on_disconnect(shared_from_this());
- restart(true);
+
+ // wait_until_sent interprets "no error" as timeout.
+ // Therefore call it with an error.
+ wait_until_sent(boost::asio::error::operation_aborted);
return;
}
}
@@ -686,9 +695,10 @@ void tcp_client_endpoint_impl::receive_cbk(
state_ = cei_state_e::CONNECTING;
shutdown_and_close_socket_unlocked(false);
its_lock.unlock();
- std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
- its_ep_host->on_disconnect(shared_from_this());
- restart(true);
+
+ // wait_until_sent interprets "no error" as timeout.
+ // Therefore call it with an error.
+ wait_until_sent(boost::asio::error::operation_aborted);
}
} else {
its_lock.unlock();
@@ -813,6 +823,18 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error,
std::size_t _bytes,
const message_buffer_ptr_t& _sent_msg) {
(void)_bytes;
+
+ {
+ // Signal that the current send operation has finished.
+ // Note: Waiting is always done after having closed the socket.
+ // Therefore, no new send operation will be scheduled.
+ std::lock_guard<std::mutex> its_sent_lock(sent_mutex_);
+ is_sending_ = false;
+
+ boost::system::error_code ec;
+ sent_timer_.cancel(ec);
+ }
+
if (!_error) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (queue_.size() > 0) {
@@ -886,4 +908,26 @@ void tcp_client_endpoint_impl::max_allowed_reconnects_reached() {
return;
}
+void tcp_client_endpoint_impl::wait_until_sent(const boost::system::error_code &_error) {
+
+ std::unique_lock<std::mutex> its_sent_lock(sent_mutex_);
+ if (!is_sending_ || !_error) {
+ its_sent_lock.unlock();
+ if (!_error)
+ VSOMEIP_WARNING << __func__
+ << ": Maximum wait time for send operation exceeded.";
+
+ std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
+ its_ep_host->on_disconnect(shared_from_this());
+ restart(true);
+ } else {
+ std::chrono::milliseconds its_timeout(VSOMEIP_MAX_TCP_SENT_WAIT_TIME);
+ boost::system::error_code ec;
+ sent_timer_.expires_from_now(its_timeout, ec);
+ sent_timer_.async_wait(std::bind(&tcp_client_endpoint_impl::wait_until_sent,
+ std::dynamic_pointer_cast<tcp_client_endpoint_impl>(shared_from_this()),
+ std::placeholders::_1));
+ }
+}
+
} // namespace vsomeip_v3
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
index ec8c991..6bbd337 100644
--- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
@@ -84,12 +84,17 @@ void udp_client_endpoint_impl::connect() {
}
}
+ if (local_.port() == ILLEGAL_PORT) {
+ // Let the OS assign the port
+ local_.port(0);
+ }
+
#ifndef _WIN32
// If specified, bind to device
std::string its_device(configuration_->get_device());
if (its_device != "") {
- if (setsockopt(socket_->native_handle(),
- SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (int)its_device.size()) == -1) {
+ if (!setsockopt(socket_->native_handle(),
+ SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (int)its_device.size())) {
VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\"";
}
}
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
index 0a65b2e..9d22d51 100644
--- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
@@ -37,6 +37,7 @@ udp_server_endpoint_impl::udp_server_endpoint_impl(
_configuration),
unicast_socket_(_io, _local.protocol()),
unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0),
+ multicast_id_(0),
joined_group_(false),
local_port_(_local.port()),
tp_reassembler_(std::make_shared<tp::tp_reassembler>(_configuration->get_max_message_size_unreliable(), _io)),
@@ -77,6 +78,7 @@ udp_server_endpoint_impl::udp_server_endpoint_impl(
boost::asio::socket_base::broadcast option(true);
unicast_socket_.set_option(option, ec);
boost::asio::detail::throw_error(ec, "broadcast option");
+
const std::uint32_t its_udp_recv_buffer_size =
configuration_->get_udp_receive_buffer_size();
unicast_socket_.set_option(boost::asio::socket_base::receive_buffer_size(
@@ -124,9 +126,8 @@ void udp_server_endpoint_impl::start() {
void udp_server_endpoint_impl::stop() {
server_endpoint_impl::stop();
-
{
- std::lock_guard<std::mutex> its_lock(unicast_socket_mutex_);
+ std::lock_guard<std::mutex> its_lock(unicast_mutex_);
if (unicast_socket_.is_open()) {
boost::system::error_code its_error;
@@ -136,7 +137,7 @@ void udp_server_endpoint_impl::stop() {
}
{
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
+ std::lock_guard<std::mutex> its_lock(multicast_mutex_);
if (multicast_socket_ && multicast_socket_->is_open()) {
boost::system::error_code its_error;
@@ -150,11 +151,11 @@ void udp_server_endpoint_impl::stop() {
void udp_server_endpoint_impl::receive() {
receive_unicast();
- receive_multicast();
}
void udp_server_endpoint_impl::receive_unicast() {
- std::lock_guard<std::mutex> its_lock(unicast_socket_mutex_);
+
+ std::lock_guard<std::mutex> its_lock(unicast_mutex_);
if(unicast_socket_.is_open()) {
unicast_socket_.async_receive_from(
@@ -172,12 +173,14 @@ void udp_server_endpoint_impl::receive_unicast() {
}
}
-void udp_server_endpoint_impl::receive_multicast() {
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
+//
+// receive_multicast is called with multicast_mutex_ being hold
+//
+void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) {
- if (multicast_socket_ && multicast_socket_->is_open()) {
+ if (_multicast_id == multicast_id_ && multicast_socket_ && multicast_socket_->is_open()) {
multicast_socket_->async_receive_from(
- boost::asio::buffer(&(*multicast_recv_buffer_)[0], max_message_size_),
+ boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_),
multicast_remote_,
std::bind(
&udp_server_endpoint_impl::on_multicast_received,
@@ -185,7 +188,8 @@ void udp_server_endpoint_impl::receive_multicast() {
udp_server_endpoint_impl >(shared_from_this()),
std::placeholders::_1,
std::placeholders::_2,
- std::placeholders::_3
+ std::placeholders::_3,
+ _multicast_id
)
);
}
@@ -194,6 +198,7 @@ void udp_server_endpoint_impl::receive_multicast() {
bool udp_server_endpoint_impl::send_to(
const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size) {
+
std::lock_guard<std::mutex> its_lock(mutex_);
endpoint_type its_target(_target->get_address(), _target->get_port());
return send_intern(its_target, _data, _size);
@@ -202,6 +207,7 @@ bool udp_server_endpoint_impl::send_to(
bool udp_server_endpoint_impl::send_error(
const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size) {
+
bool ret(false);
std::lock_guard<std::mutex> its_lock(mutex_);
const endpoint_type its_target(_target->get_address(), _target->get_port());
@@ -236,64 +242,72 @@ void udp_server_endpoint_impl::send_queued(
<< (int)(*its_buffer)[i] << " ";
VSOMEIP_INFO << msg.str();
#endif
- std::lock_guard<std::mutex> its_lock(unicast_socket_mutex_);
+ std::lock_guard<std::mutex> its_lock(unicast_mutex_);
unicast_socket_.async_send_to(
- boost::asio::buffer(*its_buffer),
- _queue_iterator->first,
- std::bind(
- &udp_server_endpoint_base_impl::send_cbk,
- shared_from_this(),
- _queue_iterator,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ boost::asio::buffer(*its_buffer),
+ _queue_iterator->first,
+ std::bind(
+ &udp_server_endpoint_base_impl::send_cbk,
+ shared_from_this(),
+ _queue_iterator,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void udp_server_endpoint_impl::get_configured_times_from_endpoint(
service_t _service, method_t _method,
std::chrono::nanoseconds *_debouncing,
std::chrono::nanoseconds *_maximum_retention) const {
+
configuration_->get_configured_timing_responses(_service,
udp_server_endpoint_base_impl::local_.address().to_string(),
udp_server_endpoint_base_impl::local_.port(), _method,
_debouncing, _maximum_retention);
}
+//
+// Both is_joined - methods must be called with multicast_mutex_ being hold!
+//
bool udp_server_endpoint_impl::is_joined(const std::string &_address) const {
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
+
return (joined_.find(_address) != joined_.end());
}
bool udp_server_endpoint_impl::is_joined(
const std::string &_address, bool* _received) const {
- *_received = false;
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
+
const auto found_address = joined_.find(_address);
if (found_address != joined_.end()) {
*_received = found_address->second;
+ } else {
+ *_received = false;
}
+
return (found_address != joined_.end());
}
void udp_server_endpoint_impl::join(const std::string &_address) {
+
bool has_received(false);
+ //
+ // join_func must be called with multicast_mutex_ being hold!
+ //
auto join_func = [this](const std::string &_address) {
try {
- VSOMEIP_TRACE << "Joining to multicast group " << _address
+ VSOMEIP_DEBUG << "Joining to multicast group " << _address
<< " from " << local_.address().to_string();
boost::system::error_code ec;
- if (!multicast_recv_buffer_) {
- multicast_recv_buffer_ = std::unique_ptr<message_buffer_t>(
- new message_buffer_t(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0));
- }
+ if (multicast_recv_buffer_.empty())
+ multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0);
- if (!multicast_ep_) {
- multicast_ep_ = std::unique_ptr<endpoint_type>(
+ if (!multicast_local_) {
+ multicast_local_ = std::unique_ptr<endpoint_type>(
new endpoint_type(boost::asio::ip::address_v4::any(), local_port_));
}
@@ -305,7 +319,7 @@ void udp_server_endpoint_impl::join(const std::string &_address) {
multicast_socket_->set_option(optionReuseAddress, ec);
boost::asio::detail::throw_error(ec, "reuse address in multicast");
- multicast_socket_->bind(*multicast_ep_, ec);
+ multicast_socket_->bind(*multicast_local_, ec);
boost::asio::detail::throw_error(ec, "bind multicast");
const std::uint32_t its_udp_recv_buffer_size =
@@ -342,8 +356,8 @@ void udp_server_endpoint_impl::join(const std::string &_address) {
::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO,
&optval, sizeof(optval));
#endif
-
- receive_multicast();
+ multicast_id_++;
+ receive_multicast(multicast_id_);
}
bool is_v4(false);
@@ -355,55 +369,50 @@ void udp_server_endpoint_impl::join(const std::string &_address) {
}
if (is_v4) {
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true));
multicast_socket_->set_option(
boost::asio::ip::multicast::enable_loopback(false));
-#ifdef _WIN32
multicast_socket_->set_option(boost::asio::ip::multicast::join_group(
boost::asio::ip::address::from_string(_address).to_v4(),
local_.address().to_v4()));
-#else
- multicast_socket_->set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address).to_v4()));
-#endif
} else if (is_v6) {
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true));
multicast_socket_->set_option(
boost::asio::ip::multicast::enable_loopback(false));
-#ifdef _WIN32
multicast_socket_->set_option(boost::asio::ip::multicast::join_group(
boost::asio::ip::address::from_string(_address).to_v6(),
local_.address().to_v6().scope_id()));
-#else
- multicast_socket_->set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address).to_v6()));
-#endif
- }
- {
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
- joined_[_address] = false;
}
+
+ joined_[_address] = false;
joined_group_ = true;
+
} catch (const std::exception &e) {
VSOMEIP_ERROR << "udp_server_endpoint_impl::join" << ":" << e.what();
}
};
+ std::lock_guard<std::mutex> its_lock(multicast_mutex_);
if (!is_joined(_address, &has_received)) {
join_func(_address);
} else if (!has_received) {
// joined the multicast group but didn't receive a event yet -> rejoin
- leave(_address);
+ leave_unlocked(_address);
join_func(_address);
}
}
void udp_server_endpoint_impl::leave(const std::string &_address) {
+
+ std::lock_guard<std::mutex> its_lock(multicast_mutex_);
+ leave_unlocked(_address);
+}
+
+void udp_server_endpoint_impl::leave_unlocked(const std::string &_address) {
+
try {
if (is_joined(_address)) {
- VSOMEIP_TRACE << "Leaving the multicast group " << _address
+ VSOMEIP_DEBUG << "Leaving the multicast group " << _address
<< " from " << local_.address().to_string();
bool is_v4(false);
@@ -414,24 +423,22 @@ void udp_server_endpoint_impl::leave(const std::string &_address) {
is_v6 = local_.address().is_v6();
}
if (is_v4) {
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
multicast_socket_->set_option(boost::asio::ip::multicast::leave_group(
boost::asio::ip::address::from_string(_address)));
} else if (is_v6) {
- std::lock_guard<std::mutex> its_lock(multicast_socket_mutex_);
multicast_socket_->set_option(boost::asio::ip::multicast::leave_group(
boost::asio::ip::address::from_string(_address)));
}
- {
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
- joined_.erase(_address);
- if (!joined_.size()) {
- joined_group_ = false;
-
- multicast_socket_.reset(nullptr);
- multicast_ep_.reset(nullptr);
- multicast_recv_buffer_.reset(nullptr);
- }
+
+ joined_.erase(_address);
+ if (0 == joined_.size()) {
+ joined_group_ = false;
+
+ boost::system::error_code ec;
+ multicast_socket_->cancel(ec);
+
+ multicast_socket_.reset(nullptr);
+ multicast_local_.reset(nullptr);
}
}
}
@@ -473,21 +480,36 @@ void udp_server_endpoint_impl::on_unicast_received(
boost::system::error_code const &_error,
std::size_t _bytes,
boost::asio::ip::address const &_destination) {
- on_message_received(_error, _bytes, _destination, unicast_remote_, unicast_recv_buffer_);
- receive_unicast();
+
+ if (_error != boost::asio::error::operation_aborted) {
+ {
+ // By locking the multicast mutex here it is ensured that unicast
+ // & multicast messages are not processed in parallel. This aligns
+ // the behavior of endpoints with one and two active sockets.
+ std::lock_guard<std::mutex> its_lock(multicast_mutex_);
+ on_message_received(_error, _bytes, _destination,
+ unicast_remote_, unicast_recv_buffer_);
+ }
+ receive_unicast();
+ }
}
void udp_server_endpoint_impl::on_multicast_received(
boost::system::error_code const &_error,
std::size_t _bytes,
- boost::asio::ip::address const &_destination) {
+ boost::asio::ip::address const &_destination,
+ uint8_t _multicast_id) {
+
+ std::lock_guard<std::mutex> its_lock(multicast_mutex_);
+ if (_error != boost::asio::error::operation_aborted) {
+ // Filter messages sent from the same source address
+ if (multicast_remote_.address() != local_.address()) {
+ on_message_received(_error, _bytes, _destination,
+ multicast_remote_, multicast_recv_buffer_);
+ }
- // Filter messages sent from the same source address
- if (multicast_remote_.address() != local_.address()) {
- on_message_received(_error, _bytes, _destination, multicast_remote_, *multicast_recv_buffer_);
+ receive_multicast(_multicast_id);
}
-
- receive_multicast();
}
void udp_server_endpoint_impl::on_message_received(
@@ -579,7 +601,6 @@ void udp_server_endpoint_impl::on_message_received(
} else if (its_service != VSOMEIP_SD_SERVICE
&& utility::is_notification(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])
&& joined_group_) {
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
boost::system::error_code ec;
const auto found_address = joined_.find(_destination.to_string(ec));
if (found_address != joined_.end()) {
@@ -599,14 +620,12 @@ void udp_server_endpoint_impl::on_message_received(
const session_t its_session = VSOMEIP_BYTES_TO_WORD(
res.second[VSOMEIP_SESSION_POS_MIN],
res.second[VSOMEIP_SESSION_POS_MAX]);
- clients_mutex_.lock();
+ std::lock_guard<std::mutex> its_client_lock(clients_mutex_);
clients_[its_client][its_session] = _remote;
- clients_mutex_.unlock();
}
} else if (its_service != VSOMEIP_SD_SERVICE
&& utility::is_notification(res.second[VSOMEIP_MESSAGE_TYPE_POS])
&& joined_group_) {
- std::lock_guard<std::mutex> its_lock(joined_mutex_);
boost::system::error_code ec;
const auto found_address = joined_.find(_destination.to_string(ec));
if (found_address != joined_.end()) {
@@ -668,9 +687,10 @@ void udp_server_endpoint_impl::print_status() {
VSOMEIP_INFO << "status use: " << std::dec << local_port_
<< " number queues: " << std::dec << queues_.size()
- << " recv_buffer: " << std::dec << unicast_recv_buffer_.capacity()
- << " multicast_recv_buffer: " << std::dec
- << (multicast_recv_buffer_ ? multicast_recv_buffer_->capacity() : 0);
+ << " recv_buffer: "
+ << std::dec << unicast_recv_buffer_.capacity()
+ << " multicast_recv_buffer: "
+ << std::dec << multicast_recv_buffer_.capacity();
for (const auto &c : queues_) {
std::size_t its_data_size(0);
@@ -706,7 +726,8 @@ bool udp_server_endpoint_impl::is_reliable() const {
}
const std::string udp_server_endpoint_impl::get_address_port_local() const {
- std::lock_guard<std::mutex> its_lock(unicast_socket_mutex_);
+
+ std::lock_guard<std::mutex> its_lock(unicast_mutex_);
std::string its_address_port;
its_address_port.reserve(21);
boost::system::error_code ec;
@@ -721,8 +742,9 @@ const std::string udp_server_endpoint_impl::get_address_port_local() const {
return its_address_port;
}
-bool udp_server_endpoint_impl::tp_segmentation_enabled(service_t _service,
- method_t _method) const {
+bool udp_server_endpoint_impl::tp_segmentation_enabled(
+ service_t _service, method_t _method) const {
+
return configuration_->tp_segment_messages_service_to_client(_service,
local_.address().to_string(),
local_.port(), _method);
diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp
index fcf04c1..81485ff 100644
--- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp
+++ b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp
@@ -37,7 +37,7 @@ public:
reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type,
const MutableBufferSequence& buffers, Endpoint& endpoint,
socket_base::message_flags flags, func_type complete_func)
- : reactor_op(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func),
+ : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func),
socket_(socket),
protocol_type_(protocol_type),
buffers_(buffers),
diff --git a/implementation/logger/include/logger_impl.hpp b/implementation/logger/include/logger_impl.hpp
new file mode 100644
index 0000000..bb83363
--- /dev/null
+++ b/implementation/logger/include/logger_impl.hpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_V3_LOGGER_CONFIGURATION_HPP_
+#define VSOMEIP_V3_LOGGER_CONFIGURATION_HPP_
+
+#include <memory>
+#include <mutex>
+
+#ifdef USE_DLT
+#include <dlt/dlt.h>
+#endif
+
+#include <vsomeip/internal/logger.hpp>
+
+namespace vsomeip_v3 {
+
+class configuration;
+
+namespace logger {
+
+class logger_impl {
+public:
+ VSOMEIP_IMPORT_EXPORT static void init(const std::shared_ptr<configuration> &_configuration);
+ static std::shared_ptr<logger_impl> get();
+
+ logger_impl() = default;
+ ~logger_impl();
+
+ std::shared_ptr<configuration> get_configuration() const;
+
+#ifdef USE_DLT
+ void log(level_e _level, const char *_data);
+
+private:
+ void enable_dlt(const std::string &_application, const std::string &_context);
+#endif
+
+private:
+ static std::mutex mutex__;
+ std::shared_ptr<configuration> configuration_;
+
+#ifdef USE_DLT
+ DLT_DECLARE_CONTEXT(dlt_);
+#endif
+};
+
+} // namespace logger
+} // namespace vsomeip_v3
+
+#endif // VSOMEIP_V3_LOGGER_CONFIGURATION_HPP_
diff --git a/implementation/logger/src/logger_impl.cpp b/implementation/logger/src/logger_impl.cpp
new file mode 100644
index 0000000..7e79aa2
--- /dev/null
+++ b/implementation/logger/src/logger_impl.cpp
@@ -0,0 +1,114 @@
+// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <iostream>
+
+#include <vsomeip/runtime.hpp>
+
+#include "../include/logger_impl.hpp"
+#include "../../configuration/include/configuration.hpp"
+
+namespace vsomeip_v3 {
+namespace logger {
+
+std::mutex logger_impl::mutex__;
+
+void
+logger_impl::init(const std::shared_ptr<configuration> &_configuration) {
+ std::lock_guard<std::mutex> its_lock(mutex__);
+ auto its_logger = logger_impl::get();
+ its_logger->configuration_ = _configuration;
+
+#ifdef USE_DLT
+# define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP"
+# define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context"
+
+ std::string its_context_id = runtime::get_property("LogContext");
+ if (its_context_id == "")
+ its_context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID;
+
+ DLT_REGISTER_CONTEXT(its_logger->dlt_, its_context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME);
+#endif
+}
+
+logger_impl::~logger_impl() {
+#ifdef USE_DLT
+ DLT_UNREGISTER_CONTEXT(dlt_);
+#endif
+}
+
+std::shared_ptr<configuration>
+logger_impl::get_configuration() const {
+ return configuration_;
+}
+
+#ifdef USE_DLT
+void
+logger_impl::log(level_e _level, const char *_data) {
+
+ // Prepare log level
+ DltLogLevelType its_level;
+ switch (_level) {
+ case level_e::LL_FATAL:
+ its_level = DLT_LOG_FATAL;
+ break;
+ case level_e::LL_ERROR:
+ its_level = DLT_LOG_ERROR;
+ break;
+ case level_e::LL_WARNING:
+ its_level = DLT_LOG_WARN;
+ break;
+ case level_e::LL_INFO:
+ its_level = DLT_LOG_INFO;
+ break;
+ case level_e::LL_DEBUG:
+ its_level = DLT_LOG_DEBUG;
+ break;
+ case level_e::LL_VERBOSE:
+ its_level = DLT_LOG_VERBOSE;
+ break;
+ default:
+ its_level = DLT_LOG_DEFAULT;
+ };
+
+ DLT_LOG_STRING(dlt_, its_level, _data);
+}
+#endif
+
+static std::shared_ptr<logger_impl> *the_logger_ptr__(nullptr);
+static std::mutex the_logger_mutex__;
+
+std::shared_ptr<logger_impl>
+logger_impl::get() {
+#ifndef _WIN32
+ std::lock_guard<std::mutex> its_lock(the_logger_mutex__);
+#endif
+ if (the_logger_ptr__ == nullptr) {
+ the_logger_ptr__ = new std::shared_ptr<logger_impl>();
+ }
+ if (the_logger_ptr__ != nullptr) {
+ if (!(*the_logger_ptr__)) {
+ *the_logger_ptr__ = std::make_shared<logger_impl>();
+ }
+ return (*the_logger_ptr__);
+ }
+ return (nullptr);
+}
+
+#ifndef _WIN32
+static void logger_impl_teardown(void) __attribute__((destructor));
+static void logger_impl_teardown(void)
+{
+ if (the_logger_ptr__ != nullptr) {
+ std::lock_guard<std::mutex> its_lock(the_logger_mutex__);
+ the_logger_ptr__->reset();
+ delete the_logger_ptr__;
+ the_logger_ptr__ = nullptr;
+ }
+}
+#endif
+
+} // namespace logger
+} // namespace vsomeip_v3
diff --git a/implementation/logger/src/message.cpp b/implementation/logger/src/message.cpp
new file mode 100644
index 0000000..363db37
--- /dev/null
+++ b/implementation/logger/src/message.cpp
@@ -0,0 +1,157 @@
+// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <chrono>
+#include <ctime>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#ifdef ANDROID
+#include <utils/Log.h>
+#endif
+
+#include <vsomeip/internal/logger.hpp>
+
+#include "../include/logger_impl.hpp"
+#include "../../configuration/include/configuration.hpp"
+
+namespace vsomeip_v3 {
+namespace logger {
+
+std::mutex message::mutex__;
+
+message::message(level_e _level)
+ : std::ostream(&buffer_),
+ level_(_level) {
+
+ when_ = std::chrono::system_clock::now();
+}
+
+message::~message() {
+ std::lock_guard<std::mutex> its_lock(mutex__);
+ auto its_logger = logger_impl::get();
+ auto its_configuration = its_logger->get_configuration();
+
+ if (!its_configuration)
+ return;
+
+ if (level_ > its_configuration->get_loglevel())
+ return;
+
+ if (its_configuration->has_console_log()
+ || its_configuration->has_file_log()) {
+
+ // Prepare log level
+ const char *its_level;
+ switch (level_) {
+ case level_e::LL_FATAL:
+ its_level = "fatal";
+ break;
+ case level_e::LL_ERROR:
+ its_level = "error";
+ break;
+ case level_e::LL_WARNING:
+ its_level = "warning";
+ break;
+ case level_e::LL_INFO:
+ its_level = "info";
+ break;
+ case level_e::LL_DEBUG:
+ its_level = "debug";
+ break;
+ case level_e::LL_VERBOSE:
+ its_level = "verbose";
+ break;
+ default:
+ its_level = "none";
+ };
+
+ // Prepare time stamp
+ auto its_time_t = std::chrono::system_clock::to_time_t(when_);
+ auto its_time = std::localtime(&its_time_t);
+ auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000;
+
+ if (its_configuration->has_console_log()) {
+#ifndef ANDROID
+ std::cout
+ << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon << "-"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " "
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "."
+ << std::dec << std::setw(6) << std::setfill('0') << its_ms << " ["
+ << its_level << "] "
+ << buffer_.data_.str()
+ << std::endl;
+#else
+ switch (level_) {
+ case level_e::LL_FATAL:
+ ALOGE(buffer_.data_.str());
+ break;
+ case level_e::LL_ERROR:
+ ALOGE(buffer_.data_.str());
+ break;
+ case level_e::LL_WARNING:
+ ALOGW(buffer_.data_.str());
+ break;
+ case level_e::LL_INFO:
+ ALOGI(buffer_.data_.str());
+ break;
+ case level_e::LL_DEBUG:
+ ALOGD(buffer_.data_.str());
+ break;
+ case level_e::LL_VERBOSE:
+ ALOGV(buffer_.data_.str());
+ break;
+ default:
+ ALOGI(buffer_.data_.str());
+ };
+#endif // !ANDROID
+ }
+
+ if (its_configuration->has_file_log()) {
+ std::ofstream its_logfile(
+ its_configuration->get_logfile(),
+ std::ios_base::app);
+ if (its_logfile.is_open()) {
+ its_logfile
+ << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon << "-"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " "
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":"
+ << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "."
+ << std::dec << std::setw(6) << std::setfill('0') << its_ms << " ["
+ << its_level << "] "
+ << buffer_.data_.str()
+ << std::endl;
+ }
+ }
+ } else if (its_configuration->has_dlt_log()) {
+#ifdef USE_DLT
+ its_logger->log(level_, buffer_.data_.str().c_str());
+#endif // USE_DLT
+ }
+}
+
+std::streambuf::int_type
+message::buffer::overflow(std::streambuf::int_type c) {
+ if (c != EOF) {
+ data_ << (char)c;
+ }
+
+ return (c);
+}
+
+std::streamsize
+message::buffer::xsputn(const char *s, std::streamsize n) {
+ data_.write(s, n);
+ return (n);
+}
+
+} // namespace logger
+} // namespace vsomeip_v3
diff --git a/implementation/logging/include/android_sink_backend.hpp b/implementation/logging/include/android_sink_backend.hpp
deleted file mode 100644
index defda48..0000000
--- a/implementation/logging/include/android_sink_backend.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_V3_ANDROID_SINK_BACKEND_HPP_
-#define VSOMEIP_V3_ANDROID_SINK_BACKEND_HPP_
-
-#include <boost/log/core.hpp>
-#include <boost/log/sinks/basic_sink_backend.hpp>
-#include <boost/log/trivial.hpp>
-
-namespace logging = boost::log;
-namespace sinks = boost::log::sinks;
-
-namespace vsomeip_v3 {
-
-class android_sink_backend :
- public sinks::basic_sink_backend<
- sinks::combine_requirements<
- sinks::synchronized_feeding
- >::type
- > {
-public:
- android_sink_backend();
- virtual ~android_sink_backend();
-
- void consume(const logging::record_view &rec);
-};
-
-} // namespace vsomeip_v3
-
-#endif // VSOMEIP_V3_ANDROID_SINK_BACKEND_HPP_
diff --git a/implementation/logging/include/defines.hpp b/implementation/logging/include/defines.hpp
deleted file mode 100644
index de5142d..0000000
--- a/implementation/logging/include/defines.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef LOGGING_DEFINES_HPP_
-#define LOGGING_DEFINES_HPP_
-
-#define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP"
-#define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context"
-
-#endif /* LOGGING_DEFINES_HPP_ */
diff --git a/implementation/logging/include/dlt_sink_backend.hpp b/implementation/logging/include/dlt_sink_backend.hpp
deleted file mode 100644
index 73a9e79..0000000
--- a/implementation/logging/include/dlt_sink_backend.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_V3_DLT_SINK_BACKEND_HPP_
-#define VSOMEIP_V3_DLT_SINK_BACKEND_HPP_
-
-#ifdef USE_DLT
-#include <dlt/dlt.h>
-#endif
-
-#include <boost/log/core.hpp>
-#include <boost/log/sinks/basic_sink_backend.hpp>
-#include <boost/log/trivial.hpp>
-
-namespace logging = boost::log;
-namespace sinks = boost::log::sinks;
-
-namespace vsomeip_v3 {
-
-class dlt_sink_backend :
- public sinks::basic_sink_backend<
- sinks::combine_requirements<
- sinks::synchronized_feeding
- >::type
- > {
-public:
- dlt_sink_backend(const std::string &_app_id,
- const std::string &_context_id);
- virtual ~dlt_sink_backend();
-
- void consume(const logging::record_view &rec);
-
-private:
-
-#ifdef USE_DLT
- DltLogLevelType level_as_dlt(logging::trivial::severity_level _level);
- DLT_DECLARE_CONTEXT(dlt_)
-#endif
-};
-
-} // namespace vsomeip_v3
-
-#endif // VSOMEIP_V3_DLT_SINK_BACKEND_HPP_
diff --git a/implementation/logging/include/logger_impl.hpp b/implementation/logging/include/logger_impl.hpp
deleted file mode 100644
index 4556f0d..0000000
--- a/implementation/logging/include/logger_impl.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_V3_LOGGER_IMPL_HPP
-#define VSOMEIP_V3_LOGGER_IMPL_HPP
-
-#include <memory>
-#include <string>
-
-#include <boost/log/sinks/sync_frontend.hpp>
-#include <boost/log/sinks/text_ostream_backend.hpp>
-#include <boost/log/sources/severity_logger.hpp>
-#include <boost/log/trivial.hpp>
-
-#include <vsomeip/internal/logger.hpp>
-#include "dlt_sink_backend.hpp"
-#include "android_sink_backend.hpp"
-
-namespace vsomeip_v3 {
-
-class configuration;
-
-BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
-BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity",
- boost::log::trivial::severity_level)
-
-typedef boost::log::sinks::synchronous_sink<
- boost::log::sinks::text_ostream_backend> sink_t;
-typedef boost::log::sinks::synchronous_sink<
- dlt_sink_backend> dlt_sink_t;
-typedef boost::log::sinks::synchronous_sink<
- android_sink_backend> android_sink_t;
-
-class logger_impl: public logger {
-public:
- static std::shared_ptr<logger_impl> & get();
- VSOMEIP_IMPORT_EXPORT static void init(const std::shared_ptr<configuration> &_configuration);
-
- logger_impl();
-
- boost::log::sources::severity_logger_mt<
- boost::log::trivial::severity_level> & get_internal();
-
-private:
- void enable_console();
- void disable_console();
-
- void enable_file(const std::string &_path);
- void disable_file();
-
- void enable_dlt(const std::string &_app_id,
- const std::string &_context_id);
- void disable_dlt();
-
- void enable_android();
- void disable_android();
-
-private:
- boost::log::sources::severity_logger_mt<
- boost::log::trivial::severity_level> logger_;
- boost::log::trivial::severity_level loglevel_;
-
- boost::shared_ptr<sink_t> console_sink_;
- boost::shared_ptr<sink_t> file_sink_;
- boost::shared_ptr<dlt_sink_t> dlt_sink_;
- boost::shared_ptr<android_sink_t> android_sink_;
- boost::log::core_ptr log_core_;
-
-private:
- void use_null_logger();
-};
-
-} // namespace vsomeip_v3
-
-#endif // VSOMEIP_V3_LOGGER_IMPL_HPP
diff --git a/implementation/logging/src/android_sink_backend.cpp b/implementation/logging/src/android_sink_backend.cpp
deleted file mode 100644
index bde7afb..0000000
--- a/implementation/logging/src/android_sink_backend.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include "../include/android_sink_backend.hpp"
-
-#define LOG_TAG "vSomeIP"
-
-#ifdef ANDROID
-#include <utils/Log.h>
-#endif
-
-#include <boost/log/expressions.hpp>
-#include "../include/defines.hpp"
-
-namespace expressions = boost::log::expressions;
-
-namespace vsomeip_v3
-{
-
-android_sink_backend::android_sink_backend() {
-
-}
-
-android_sink_backend::~android_sink_backend() {
-
-}
-
-BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level)
-
-void android_sink_backend::consume(const logging::record_view &rec) {
-#ifdef ANDROID
- auto message = rec[expressions::smessage].get<std::string>().c_str();
- auto severity_level = rec[severity];
-
- switch (*severity_level) {
- case logging::trivial::fatal:
- ALOGE(message);
- break;
- case logging::trivial::error:
- ALOGE(message);
- break;
- case logging::trivial::warning:
- ALOGW(message);
- break;
- case logging::trivial::info:
- ALOGI(message);
- break;
- case logging::trivial::debug:
- ALOGD(message);
- break;
- case logging::trivial::trace:
- ALOGV(message);
- break;
- default:
- ALOGI(message);
- break;
- }
-
-#else
- (void)rec;
-#endif
-}
-
-} // namespace vsomeip_v3
diff --git a/implementation/logging/src/dlt_sink_backend.cpp b/implementation/logging/src/dlt_sink_backend.cpp
deleted file mode 100644
index d38039c..0000000
--- a/implementation/logging/src/dlt_sink_backend.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include "../include/dlt_sink_backend.hpp"
-
-#ifdef USE_DLT
-#include <dlt/dlt.h>
-#endif
-
-#include <boost/log/expressions.hpp>
-#include "../include/defines.hpp"
-
-namespace expressions = boost::log::expressions;
-
-namespace vsomeip_v3
-{
-
-dlt_sink_backend::dlt_sink_backend(const std::string &_app_id,
- const std::string &_context_id) {
- (void)_app_id;
-#ifdef USE_DLT
- DLT_REGISTER_CONTEXT(dlt_, _context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME);
-#else
- (void)_context_id;
-#endif
-}
-
-dlt_sink_backend::~dlt_sink_backend() {
-#ifdef USE_DLT
- DLT_UNREGISTER_CONTEXT(dlt_);
-#endif
-}
-
-BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level)
-
-void dlt_sink_backend::consume(const logging::record_view &rec) {
-#ifdef USE_DLT
- auto message = rec[expressions::smessage];
- auto severity_level = rec[severity];
- DLT_LOG_STRING(dlt_, (severity_level)?level_as_dlt(*severity_level):DLT_LOG_WARN,
- (message)?message.get<std::string>().c_str():"consume() w/o message");
-#else
- (void)rec;
-#endif
-}
-
-#ifdef USE_DLT
-DltLogLevelType dlt_sink_backend::level_as_dlt(logging::trivial::severity_level _level) {
- switch (_level) {
- case logging::trivial::fatal:
- return DLT_LOG_FATAL;
- case logging::trivial::error:
- return DLT_LOG_ERROR;
- case logging::trivial::warning:
- return DLT_LOG_WARN;
- case logging::trivial::info:
- return DLT_LOG_INFO;
- case logging::trivial::debug:
- return DLT_LOG_DEBUG;
- case logging::trivial::trace:
- return DLT_LOG_VERBOSE;
- default:
- return DLT_LOG_DEFAULT;
- }
-}
-#endif
-
-} // namespace vsomeip_v3
diff --git a/implementation/logging/src/logger.cpp b/implementation/logging/src/logger.cpp
deleted file mode 100644
index 9e22fd0..0000000
--- a/implementation/logging/src/logger.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include "../include/logger_impl.hpp"
-
-namespace vsomeip_v3 {
-
-std::shared_ptr<logger> logger::get() {
- return logger_impl::get();
-}
-
-} // namespace vsomeip_v3l
diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp
deleted file mode 100644
index ec3aa9b..0000000
--- a/implementation/logging/src/logger_impl.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <fstream>
-
-#include <boost/log/core.hpp>
-#include <boost/log/expressions.hpp>
-#include <boost/log/sources/logger.hpp>
-#include <boost/log/support/date_time.hpp>
-#include <boost/log/utility/setup/console.hpp>
-#include <boost/log/utility/setup/file.hpp>
-#include <boost/log/utility/setup/common_attributes.hpp>
-#include <boost/log/utility/exception_handler.hpp>
-#include <boost/phoenix/bind/bind_member_function.hpp>
-#include <boost/shared_ptr.hpp>
-
-// The "empty_deleter"-struct was moved from the log-package
-// to the more generic "utility"-package in V1.55. If we'd
-// use the "old" include, we get a "deprecation" warning
-// when compiling with the newer boost version. Therefore a
-// version dependent include handling is done here, which
-// can/should be removed in case GPT is updating Boost to V1.55.
-#if BOOST_VERSION < 105500
-#include <boost/log/utility/empty_deleter.hpp>
-#elif BOOST_VERSION < 105600
-#include <boost/utility/empty_deleter.hpp>
-#else
-#include <boost/core/null_deleter.hpp>
-#endif
-
-#include <vsomeip/runtime.hpp>
-
-#include "../include/logger_impl.hpp"
-#include "../../configuration/include/configuration.hpp"
-#include "../include/defines.hpp"
-
-namespace logging = boost::log;
-namespace sources = boost::log::sources;
-namespace sinks = boost::log::sinks;
-namespace keywords = boost::log::keywords;
-namespace expressions = boost::log::expressions;
-namespace attributes = boost::log::attributes;
-
-using namespace boost::log::trivial;
-
-namespace vsomeip_v3 {
-
-std::shared_ptr<logger_impl> & logger_impl::get() {
- static std::shared_ptr<logger_impl> the_logger__ = std::make_shared<
- logger_impl>();
- return the_logger__;
-}
-
-logger_impl::logger_impl()
- : loglevel_(debug),
- log_core_(logging::core::get()) {
- logging::add_common_attributes();
-}
-
-boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> &
-logger_impl::get_internal() {
- return logger_;
-}
-
-void logger_impl::init(const std::shared_ptr<configuration> &_configuration) {
- get()->loglevel_ = _configuration->get_loglevel();
- logging::core::get()->set_exception_handler(boost::log::make_exception_suppressor());
- logging::core::get()->set_filter(
- logging::trivial::severity >= get()->loglevel_);
-
- if (_configuration->has_console_log()) {
- get()->enable_console();
-#ifdef ANDROID
- get()->enable_android();
-#endif
- } else {
- get()->disable_console();
- }
-
- if (_configuration->has_file_log())
- get()->enable_file(_configuration->get_logfile());
- else
- get()->disable_file();
-
- if (_configuration->has_dlt_log()) {
- std::string app_id = runtime::get_property("LogApplication");
- if (app_id == "") app_id = VSOMEIP_LOG_DEFAULT_APPLICATION_ID;
- std::string context_id = runtime::get_property("LogContext");
- if (context_id == "") context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID;
- get()->enable_dlt(app_id, context_id);
- } else
- get()->disable_dlt();
-
- if (!_configuration->has_console_log() &&
- !_configuration->has_file_log() &&
- !_configuration->has_dlt_log()) {
- get()->use_null_logger();
- }
-}
-
-void logger_impl::enable_console() {
- if (console_sink_)
- return;
-
- auto vsomeip_log_format = expressions::stream
- << expressions::format_date_time<boost::posix_time::ptime>(
- "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " ["
- << expressions::attr<severity_level>("Severity") << "] "
- << expressions::smessage;
-
- boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
- sinks::text_ostream_backend>();
- backend->add_stream(boost::shared_ptr<std::ostream>(&std::clog,
-#if BOOST_VERSION < 105500
- boost::log::empty_deleter()
-#elif BOOST_VERSION < 105600
- boost::empty_deleter()
-#else
- boost::null_deleter()
-#endif
- ));
-
- console_sink_ = boost::make_shared<sink_t>(backend);
- console_sink_->set_formatter(vsomeip_log_format);
- logging::core::get()->add_sink(console_sink_);
-}
-
-void logger_impl::disable_console() {
- if (console_sink_)
- logging::core::get()->remove_sink(console_sink_);
-}
-
-void logger_impl::enable_file(const std::string &_path) {
- if (file_sink_)
- return;
-
- auto vsomeip_log_format = expressions::stream
- << expressions::format_date_time<boost::posix_time::ptime>(
- "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " ["
- << expressions::attr<severity_level>("Severity") << "] "
- << expressions::smessage;
-
- boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
- sinks::text_ostream_backend>();
- backend->add_stream(
- boost::shared_ptr<std::ostream>(
- boost::make_shared<std::ofstream>(_path)));
-
- file_sink_ = boost::make_shared<sink_t>(backend);
- file_sink_->set_formatter(vsomeip_log_format);
- logging::core::get()->add_sink(file_sink_);
-}
-
-void logger_impl::disable_file() {
- if (file_sink_)
- logging::core::get()->remove_sink(file_sink_);
-}
-
-
-void logger_impl::enable_dlt(const std::string &_app_id,
- const std::string &_context_id) {
-#ifdef USE_DLT
- if (dlt_sink_)
- return;
-
- boost::shared_ptr<dlt_sink_backend> backend = boost::make_shared<dlt_sink_backend>(_app_id,
- _context_id);
- dlt_sink_ = boost::make_shared<dlt_sink_t>(backend);
- logging::core::get()->add_sink(dlt_sink_);
-#else
- (void)_app_id;
- (void)_context_id;
-#endif
-}
-
-void logger_impl::disable_dlt() {
- if (dlt_sink_)
- logging::core::get()->remove_sink(dlt_sink_);
-}
-
-void logger_impl::enable_android() {
-#ifdef ANDROID
- if (android_sink_)
- return;
-
- boost::shared_ptr<android_sink_backend> backend = boost::make_shared<android_sink_backend>();
- android_sink_ = boost::make_shared<android_sink_t>(backend);
- logging::core::get()->add_sink(android_sink_);
-#endif
-}
-
-void logger_impl::disable_android() {
- if (android_sink_)
- logging::core::get()->remove_sink(android_sink_);
-}
-
-void logger_impl::use_null_logger() {
- boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
- sinks::text_ostream_backend>();
- backend->add_stream(
- boost::shared_ptr<std::ostream>(new std::ofstream("/dev/null") // TODO: how to call this on windows
- ));
-
- file_sink_ = boost::make_shared<sink_t>(backend);
- logging::core::get()->add_sink(file_sink_);
-}
-
-} // namespace vsomeip_v3
-
diff --git a/implementation/plugin/src/plugin_manager_impl.cpp b/implementation/plugin/src/plugin_manager_impl.cpp
index 6da2d82..159eea9 100644
--- a/implementation/plugin/src/plugin_manager_impl.cpp
+++ b/implementation/plugin/src/plugin_manager_impl.cpp
@@ -200,6 +200,7 @@ void * plugin_manager_impl::load_symbol(void * _handle,
}
#else
if (0 != _handle) {
+ dlerror(); // Clear previous error
its_symbol = dlsym(_handle, _symbol.c_str());
const char *dlsym_error = dlerror();
if (dlsym_error) {
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index 684a49b..b22b6ed 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -104,7 +104,7 @@ public:
void remove_subscriber(eventgroup_t _eventgroup, client_t _client);
bool has_subscriber(eventgroup_t _eventgroup, client_t _client);
std::set<client_t> get_subscribers();
- std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
+ VSOMEIP_EXPORT std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
void clear_subscribers();
void add_ref(client_t _client, bool _is_provided);
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index 65f7e89..32ce5f2 100644
--- a/implementation/routing/include/eventgroupinfo.hpp
+++ b/implementation/routing/include/eventgroupinfo.hpp
@@ -71,6 +71,8 @@ public:
VSOMEIP_EXPORT void add_event(const std::shared_ptr<event>& _event);
VSOMEIP_EXPORT void remove_event(const std::shared_ptr<event>& _event);
VSOMEIP_EXPORT reliability_type_e get_reliability() const;
+ VSOMEIP_EXPORT void set_reliability(reliability_type_e _reliability);
+ VSOMEIP_EXPORT bool is_reliability_auto_mode() const;
VSOMEIP_EXPORT std::set<std::shared_ptr<remote_subscription>>
get_remote_subscriptions() const;
@@ -90,6 +92,8 @@ public:
VSOMEIP_EXPORT void remove_remote_subscription(
const remote_subscription_id_t _id);
+ void clear_remote_subscriptions();
+
VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
get_unicast_targets() const;
VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
@@ -129,6 +133,7 @@ private:
remote_subscription_id_t id_;
std::atomic<reliability_type_e> reliability_;
+ std::atomic<bool> reliability_auto_mode_;
};
} // namespace vsomeip_v3
diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp
index 00f2b57..685aad9 100644
--- a/implementation/routing/include/remote_subscription.hpp
+++ b/implementation/routing/include/remote_subscription.hpp
@@ -43,7 +43,7 @@ public:
remote_subscription_id_t get_id() const;
void set_id(const remote_subscription_id_t _id);
- std::shared_ptr<remote_subscription> get_parent() const;
+ VSOMEIP_EXPORT std::shared_ptr<remote_subscription> get_parent() const;
void set_parent(const std::shared_ptr<remote_subscription> &_parent);
VSOMEIP_EXPORT std::shared_ptr<eventgroupinfo> get_eventgroupinfo() const;
@@ -87,7 +87,7 @@ public:
const bool _is_subscribe);
VSOMEIP_EXPORT std::uint32_t get_answers() const;
- void set_answers(const std::uint32_t _answers);
+ VSOMEIP_EXPORT void set_answers(const std::uint32_t _answers);
private:
std::atomic<remote_subscription_id_t> id_;
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index bead207..767d60e 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -153,8 +153,7 @@ public:
}
std::shared_ptr<endpoint> find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable,
- client_t _client);
+ service_t _service, instance_t _instance, bool _reliable);
void remove_local(client_t _client, bool _remove_uid);
void on_stop_offer_service(client_t _client,
@@ -230,7 +229,16 @@ public:
std::shared_ptr<remote_subscription> &_subscription);
void expire_subscriptions(const boost::asio::ip::address &_address);
+ void expire_subscriptions(const boost::asio::ip::address &_address,
+ std::uint16_t _port, bool _reliable);
+ void expire_subscriptions(const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range,
+ bool _reliable);
void expire_services(const boost::asio::ip::address &_address);
+ void expire_services(const boost::asio::ip::address &_address,
+ std::uint16_t _port , bool _reliable);
+ void expire_services(const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range , bool _reliable);
std::chrono::steady_clock::time_point expire_subscriptions(bool _force);
@@ -269,7 +277,9 @@ public:
void register_reboot_notification_handler(const reboot_notification_handler_t& _handler) const;
void register_routing_ready_handler(const routing_ready_handler_t& _handler);
void register_routing_state_handler(const routing_state_handler_t& _handler);
- void sd_acceptance_enabled(const boost::asio::ip::address& _address);
+ void sd_acceptance_enabled(const boost::asio::ip::address& _address,
+ const configuration::port_range_t& _range,
+ bool _reliable);
void on_resend_provided_events_response(pending_remote_offer_id_t _id);
bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy,
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index d1a29df..346e733 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -25,8 +25,6 @@ class configuration;
class event;
class routing_manager_host;
-class logger;
-
class routing_manager_proxy: public routing_manager_base {
public:
routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging,
@@ -252,8 +250,6 @@ private:
boost::asio::steady_timer register_application_timer_;
- std::shared_ptr<logger> logger_;
-
std::mutex request_timer_mutex_;
boost::asio::steady_timer request_debounce_timer_;
bool request_debounce_timer_running_;
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index 7575733..bc0ba3e 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -67,7 +67,7 @@ event_t event::get_event() const {
}
void event::set_event(event_t _event) {
- message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit
+ message_->set_method(_event);
}
event_type_e event::get_type() const {
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index 52c6c1e..3b3a808 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -25,7 +25,8 @@ eventgroupinfo::eventgroupinfo()
port_(ILLEGAL_PORT),
threshold_(0),
id_(PENDING_SUBSCRIPTION_ID),
- reliability_(reliability_type_e::RT_UNKNOWN) {
+ reliability_(reliability_type_e::RT_UNKNOWN),
+ reliability_auto_mode_(false) {
}
eventgroupinfo::eventgroupinfo(
@@ -40,7 +41,8 @@ eventgroupinfo::eventgroupinfo(
port_(ILLEGAL_PORT),
threshold_(0),
id_(PENDING_SUBSCRIPTION_ID),
- reliability_(reliability_type_e::RT_UNKNOWN) {
+ reliability_(reliability_type_e::RT_UNKNOWN),
+ reliability_auto_mode_(false) {
}
eventgroupinfo::~eventgroupinfo() {
@@ -124,6 +126,12 @@ void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) {
std::lock_guard<std::mutex> its_lock(events_mutex_);
events_.insert(_event);
+ if (!reliability_auto_mode_ &&
+ _event->get_reliability() == reliability_type_e::RT_UNKNOWN) {
+ reliability_auto_mode_ = true;
+ return;
+ }
+
switch (_event->get_reliability()) {
case reliability_type_e::RT_RELIABLE:
if (reliability_ == reliability_type_e::RT_UNRELIABLE) {
@@ -156,6 +164,14 @@ reliability_type_e eventgroupinfo::get_reliability() const {
return reliability_;
}
+void eventgroupinfo::set_reliability(reliability_type_e _reliability) {
+ reliability_ = _reliability;
+}
+
+bool eventgroupinfo::is_reliability_auto_mode() const {
+ return reliability_auto_mode_;
+}
+
uint32_t
eventgroupinfo::get_unreliable_target_count() const {
uint32_t its_count(0);
@@ -228,6 +244,8 @@ eventgroupinfo::update_remote_subscription(
} else {
its_item.second->set_answers(
its_item.second->get_answers() + 1);
+ _subscription->set_parent(its_item.second);
+ _subscription->set_answers(0);
}
}
} else {
@@ -276,6 +294,12 @@ eventgroupinfo::remove_remote_subscription(
subscriptions_.erase(_id);
}
+void
+eventgroupinfo::clear_remote_subscriptions() {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ subscriptions_.clear();
+}
+
std::set<std::shared_ptr<endpoint_definition> >
eventgroupinfo::get_unicast_targets() const {
std::set<std::shared_ptr<endpoint_definition>> its_targets;
@@ -300,7 +324,7 @@ eventgroupinfo::get_multicast_targets() const {
}
bool eventgroupinfo::is_selective() const {
- /* Selective eventgroups always contain a single event */
+ // Selective eventgroups always contain a single event
std::lock_guard<std::mutex> its_lock(events_mutex_);
if (events_.size() != 1)
return false;
@@ -320,39 +344,57 @@ void
eventgroupinfo::send_initial_events(
const std::shared_ptr<endpoint_definition> &_reliable,
const std::shared_ptr<endpoint_definition> &_unreliable) const {
- std::lock_guard<std::mutex> its_lock(events_mutex_);
- for (const auto &its_event : events_) {
- if (its_event && its_event->get_type() == event_type_e::ET_FIELD) {
-#ifndef VSOMEIP_ENABLE_COMPAT
- const auto its_reliability = its_event->get_reliability();
- switch (its_reliability) {
- case reliability_type_e::RT_RELIABLE:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- break;
- case reliability_type_e::RT_UNRELIABLE:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- break;
- case reliability_type_e::RT_BOTH:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- break;
- default:
- VSOMEIP_WARNING << __func__ << "Event reliability unknown: ["
- << std::hex << std::setw(4) << std::setfill('0') << service_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << instance_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]";
- }
-#else
- if (_reliable) {
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- }
- if (_unreliable) {
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- }
+
+ std::set<std::shared_ptr<event> > its_reliable_events, its_unreliable_events;
+
+ // Build sets of reliable/unreliable events first to avoid having to
+ // hold the "events_mutex_" in parallel to the internal event mutexes.
+ {
+ std::lock_guard<std::mutex> its_lock(events_mutex_);
+ for (const auto &its_event : events_) {
+ if (its_event && its_event->get_type() == event_type_e::ET_FIELD) {
+ auto its_reliability = its_event->get_reliability();
+#ifdef VSOMEIP_ENABLE_COMPAT
+ if (its_reliability == reliability_type_e::RT_UNKNOWN) {
+ if (_reliable) {
+ if (_unreliable) {
+ its_reliability = reliability_type_e::RT_BOTH;
+ } else {
+ its_reliability = reliability_type_e::RT_RELIABLE;
+ }
+ } else if (_unreliable) {
+ its_reliability = reliability_type_e::RT_UNRELIABLE;
+ }
+ }
#endif
+ switch (its_reliability) {
+ case reliability_type_e::RT_RELIABLE:
+ its_reliable_events.insert(its_event);
+ break;
+ case reliability_type_e::RT_UNRELIABLE:
+ its_unreliable_events.insert(its_event);
+ break;
+ case reliability_type_e::RT_BOTH:
+ its_reliable_events.insert(its_event);
+ its_unreliable_events.insert(its_event);
+ break;
+ default:
+ VSOMEIP_WARNING << __func__ << "Event reliability unknown: ["
+ << std::hex << std::setw(4) << std::setfill('0') << service_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << instance_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]";
+ }
+ }
}
}
+
+ // Send events
+ for (const auto its_event : its_reliable_events)
+ its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
+
+ for (const auto its_event : its_unreliable_events)
+ its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
}
} // namespace vsomeip_v3
diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp
index a896b36..939e0d1 100644
--- a/implementation/routing/src/remote_subscription.cpp
+++ b/implementation/routing/src/remote_subscription.cpp
@@ -178,7 +178,8 @@ remote_subscription::set_client_state(const client_t _client,
if (found_item->second.second == std::chrono::steady_clock::time_point()
&& (_state == remote_subscription_state_e::SUBSCRIPTION_ACKED
|| _state == remote_subscription_state_e::SUBSCRIPTION_NACKED)) {
- found_item->second.second = std::chrono::steady_clock::now();
+ found_item->second.second = std::chrono::steady_clock::now()
+ + std::chrono::seconds(ttl_);
}
}
}
diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp
index 77e5b83..5b1149e 100644
--- a/implementation/routing/src/routing_manager_base.cpp
+++ b/implementation/routing/src/routing_manager_base.cpp
@@ -1265,11 +1265,15 @@ std::shared_ptr<serializer> routing_manager_base::get_serializer() {
std::unique_lock<std::mutex> its_lock(serializer_mutex_);
while (serializers_.empty()) {
- VSOMEIP_INFO << std::hex << "client " << get_client() <<
- "routing_manager_base::get_serializer ~> all in use!";
+ VSOMEIP_INFO << __func__ << ": Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << get_client()
+ << " has no available serializer. Waiting...";
serializer_condition_.wait(its_lock);
- VSOMEIP_INFO << std::hex << "client " << get_client() <<
- "routing_manager_base::get_serializer ~> wait finished!";
+ VSOMEIP_INFO << __func__ << ": Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << get_client()
+ << " now checking for available serializer.";
}
auto its_serializer = serializers_.front();
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index 48e2cb5..c132569 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -162,9 +162,17 @@ void routing_manager_impl::init() {
void routing_manager_impl::start() {
#ifndef _WIN32
- netlink_connector_ = std::make_shared<netlink_connector>(host_->get_io(),
- configuration_->get_unicast_address(),
- boost::asio::ip::address::from_string(configuration_->get_sd_multicast()));
+ boost::asio::ip::address its_multicast;
+ try {
+ its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast());
+ } catch (...) {
+ VSOMEIP_ERROR << "Illegal multicast address \""
+ << configuration_->get_sd_multicast()
+ << "\". Please check your configuration.";
+ }
+
+ netlink_connector_ = std::make_shared<netlink_connector>(
+ host_->get_io(), configuration_->get_unicast_address(), its_multicast);
netlink_connector_->register_net_if_changes_handler(
std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed,
this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
@@ -326,7 +334,7 @@ bool routing_manager_impl::offer_service(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << std::dec << _minor << "]"
- << " (" << _must_queue << ")";
+ << " (" << std::boolalpha << _must_queue << ")";
// only queue commands if method was NOT called via erase_offer_command()
if (_must_queue) {
@@ -420,7 +428,7 @@ void routing_manager_impl::stop_offer_service(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << _minor << "]"
- << " (" << _must_queue << ")";
+ << " (" << std::boolalpha << _must_queue << ")";
if (_must_queue) {
if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE,
@@ -505,7 +513,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
}
its_info->add_client(_client);
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, true);
}
}
}
@@ -617,7 +625,8 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid,
if (its_info) {
discovery_->subscribe(_service, _instance, _eventgroup,
_major, configured_ttl,
- its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
+ its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT,
+ its_info);
}
} else {
its_critical.unlock();
@@ -653,7 +662,6 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
bool last_subscriber_removed(true);
- auto its_event = find_event(_service, _instance, _event);
std::shared_ptr<eventgroupinfo> its_info
= find_eventgroup(_service, _instance, _eventgroup);
if (its_info) {
@@ -682,12 +690,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
}
}
- if (last_subscriber_removed
- || (its_event && its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT)) {
- if (its_info) {
- discovery_->unsubscribe(_service, _instance, _eventgroup,
- its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
- }
+ if (its_info &&
+ (last_subscriber_removed || its_info->is_selective())) {
+
+ discovery_->unsubscribe(_service, _instance, _eventgroup,
+ its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
}
} else {
if (get_client() == _client) {
@@ -797,9 +804,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
}
}
if (is_request) {
- client_t client = VSOMEIP_ROUTING_CLIENT;
its_target = ep_mgr_impl_->find_or_create_remote_client(
- its_service, _instance, _reliable, client);
+ its_service, _instance, _reliable);
if (its_target) {
#ifdef USE_DLT
const uint16_t its_data_size
@@ -1089,7 +1095,7 @@ void routing_manager_impl::register_event(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << _notifier
- << ":is_provider=" << _is_provided << "]";
+ << ":is_provider=" << std::boolalpha << _is_provided << "]";
}
void routing_manager_impl::register_shadow_event(client_t _client,
@@ -1681,6 +1687,17 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se
}
erase_offer_command(_service, _instance);
}
+
+ std::lock_guard<std::mutex> its_eventgroups_lock(eventgroups_mutex_);
+ auto find_service = eventgroups_.find(_service);
+ if (find_service != eventgroups_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ for (auto e : find_instance->second) {
+ e.second->clear_remote_subscriptions();
+ }
+ }
+ }
} else {
erase_offer_command(_service, _instance);
}
@@ -2186,10 +2203,10 @@ void routing_manager_impl::add_routing_info(
if (udp_inserted) {
// atomically create reliable and unreliable endpoint
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance);
} else {
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, true);
}
connected = true;
}
@@ -2265,7 +2282,7 @@ void routing_manager_impl::add_routing_info(
== ANY_MINOR)) {
if(!connected) {
ep_mgr_impl_->find_or_create_remote_client(_service, _instance,
- false, VSOMEIP_ROUTING_CLIENT);
+ false);
connected = true;
}
its_info->add_client(client_id.first);
@@ -2463,45 +2480,59 @@ void routing_manager_impl::update_routing_info(std::chrono::milliseconds _elapse
}
}
-void routing_manager_impl::expire_services(const boost::asio::ip::address &_address) {
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address) {
+ expire_services(_address, configuration::port_range_t(ANY_PORT, ANY_PORT),
+ false);
+}
+
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address, std::uint16_t _port,
+ bool _reliable) {
+ expire_services(_address, configuration::port_range_t(_port, _port),
+ _reliable);
+}
+
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range, bool _reliable) {
std::map<service_t, std::vector<instance_t> > its_expired_offers;
+ const bool expire_all = (_range.first == ANY_PORT
+ && _range.second == ANY_PORT);
+
for (auto &s : get_services_remote()) {
for (auto &i : s.second) {
- bool is_gone(false);
boost::asio::ip::address its_address;
std::shared_ptr<client_endpoint> its_client_endpoint =
std::dynamic_pointer_cast<client_endpoint>(
- i.second->get_endpoint(true));
+ i.second->get_endpoint(_reliable));
+ if (!its_client_endpoint && expire_all) {
+ its_client_endpoint = std::dynamic_pointer_cast<client_endpoint>(
+ i.second->get_endpoint(!_reliable));
+ }
if (its_client_endpoint) {
- if (its_client_endpoint->get_remote_address(its_address)) {
- is_gone = (its_address == _address);
- }
- } else {
- its_client_endpoint =
- std::dynamic_pointer_cast<client_endpoint>(
- i.second->get_endpoint(false));
- if (its_client_endpoint) {
- if (its_client_endpoint->get_remote_address(its_address)) {
- is_gone = (its_address == _address);
+ if ((expire_all || (its_client_endpoint->get_remote_port() >= _range.first
+ && its_client_endpoint->get_remote_port() <= _range.second))
+ && its_client_endpoint->get_remote_address(its_address)
+ && its_address == _address) {
+ if (discovery_) {
+ discovery_->unsubscribe_all(s.first, i.first);
}
+ its_expired_offers[s.first].push_back(i.first);
}
}
-
- if (is_gone) {
- if (discovery_)
- discovery_->unsubscribe_all(s.first, i.first);
- its_expired_offers[s.first].push_back(i.first);
- }
}
}
for (auto &s : its_expired_offers) {
for (auto &i : s.second) {
- VSOMEIP_INFO << "expire_services for address: " << _address.to_string()
+ VSOMEIP_INFO << "expire_services for address: " << _address
<< " : delete service/instance "
<< std::hex << std::setw(4) << std::setfill('0') << s.first
- << "." << std::hex << std::setw(4) << std::setfill('0') << i;
+ << "." << std::hex << std::setw(4) << std::setfill('0') << i
+ << " port [" << std::dec << _range.first << "," << _range.second
+ << "] reliability=" << std::boolalpha << _reliable;
del_routing_info(s.first, i, true, true);
}
}
@@ -2510,49 +2541,74 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr
void
routing_manager_impl::expire_subscriptions(
const boost::asio::ip::address &_address) {
- {
- std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
- for (const auto &its_service : eventgroups_) {
- for (const auto &its_instance : its_service.second) {
- for (const auto &its_eventgroup : its_instance.second) {
- const auto its_info = its_eventgroup.second;
- for (auto its_subscription
- : its_info->get_remote_subscriptions()) {
- // Note: get_remote_subscription delivers a copied
- // set of subscriptions. Thus, its is possible to
- // to remove them within the loop.
- const auto its_reliable = its_subscription->get_reliable();
- const auto its_unreliable = its_subscription->get_unreliable();
- if ((its_reliable && its_reliable->get_address() == _address)
- || (its_unreliable && its_unreliable->get_address() == _address)) {
-
- // TODO: Check whether subscriptions to different hosts are valid.
- // IF yes, we probably need to simply reset the corresponding
- // endpoint instead of removing the subscription...
-
- if (its_reliable) {
- VSOMEIP_ERROR << __func__
- << ": removing subscription to "
- << std::hex << its_info->get_service() << "."
- << std::hex << its_info->get_instance() << "."
- << std::hex << its_info->get_eventgroup()
- << " from target "
- << its_reliable->get_address().to_string() << ":"
- << std::dec << its_reliable->get_port();
- }
- if (its_unreliable) {
+ expire_subscriptions(_address,
+ configuration::port_range_t(ANY_PORT, ANY_PORT), false);
+}
+
+void
+routing_manager_impl::expire_subscriptions(
+ const boost::asio::ip::address &_address, std::uint16_t _port,
+ bool _reliable) {
+ expire_subscriptions(_address, configuration::port_range_t(_port, _port),
+ _reliable);
+}
+
+void
+routing_manager_impl::expire_subscriptions(
+ const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range, bool _reliable) {
+ const bool expire_all = (_range.first == ANY_PORT
+ && _range.second == ANY_PORT);
+
+ std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
+ for (const auto &its_service : eventgroups_) {
+ for (const auto &its_instance : its_service.second) {
+ for (const auto &its_eventgroup : its_instance.second) {
+ const auto its_info = its_eventgroup.second;
+ for (auto its_subscription
+ : its_info->get_remote_subscriptions()) {
+ // Note: get_remote_subscription delivers a copied
+ // set of subscriptions. Thus, its is possible to
+ // to remove them within the loop.
+ const auto its_ep_definition =
+ (_reliable) ? its_subscription->get_reliable() :
+ its_subscription->get_unreliable();
+
+ if (its_ep_definition
+ && its_ep_definition->get_address() == _address
+ && (expire_all ||
+ (its_ep_definition->get_remote_port() >= _range.first
+ && its_ep_definition->get_remote_port() <= _range.second))) {
+
+ // TODO: Check whether subscriptions to different hosts are valid.
+ // IF yes, we probably need to simply reset the corresponding
+ // endpoint instead of removing the subscription...
+ VSOMEIP_ERROR << __func__
+ << ": removing subscription to "
+ << std::hex << its_info->get_service() << "."
+ << std::hex << its_info->get_instance() << "."
+ << std::hex << its_info->get_eventgroup()
+ << " from target "
+ << its_ep_definition->get_address() << ":"
+ << std::dec << its_ep_definition->get_port()
+ << " reliable=" << _reliable;
+ if (expire_all) {
+ const auto its_ep_definition2 =
+ (!_reliable) ? its_subscription->get_reliable() :
+ its_subscription->get_unreliable();
+ if (its_ep_definition2) {
VSOMEIP_ERROR << __func__
<< ": removing subscription to "
<< std::hex << its_info->get_service() << "."
<< std::hex << its_info->get_instance() << "."
<< std::hex << its_info->get_eventgroup()
<< " from target "
- << its_unreliable->get_address().to_string() << ":"
- << std::dec << its_unreliable->get_port();
+ << its_ep_definition2->get_address() << ":"
+ << std::dec << its_ep_definition2->get_port()
+ << " reliable=" << !_reliable;
}
-
- on_remote_unsubscribe(its_subscription);
}
+ on_remote_unsubscribe(its_subscription);
}
}
}
@@ -2570,22 +2626,34 @@ void routing_manager_impl::init_routing_info() {
= configuration_->get_reliable_port(i.first, i.second);
uint16_t its_unreliable_port
= configuration_->get_unreliable_port(i.first, i.second);
+ major_version_t its_major
+ = configuration_->get_major_version(i.first, i.second);
+ minor_version_t its_minor
+ = configuration_->get_minor_version(i.first, i.second);
+ ttl_t its_ttl
+ = configuration_->get_ttl(i.first, i.second);
if (its_reliable_port != ILLEGAL_PORT
|| its_unreliable_port != ILLEGAL_PORT) {
+ VSOMEIP_INFO << "Adding static remote service ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << i.first << "." << i.second
+ << std::dec << ":" << +its_major << "." << its_minor
+ << "]";
+
add_routing_info(i.first, i.second,
- DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL,
+ its_major, its_minor, its_ttl,
its_address, its_reliable_port,
its_address, its_unreliable_port);
if(its_reliable_port != ILLEGAL_PORT) {
ep_mgr_impl_->find_or_create_remote_client(
- i.first, i.second, true, VSOMEIP_ROUTING_CLIENT);
+ i.first, i.second, true);
}
if(its_unreliable_port != ILLEGAL_PORT) {
ep_mgr_impl_->find_or_create_remote_client(
- i.first, i.second, false, VSOMEIP_ROUTING_CLIENT);
+ i.first, i.second, false);
}
}
}
@@ -2660,6 +2728,7 @@ void routing_manager_impl::on_remote_subscribe(
if (its_reliable && its_unreliable)
its_warning << "]";
VSOMEIP_WARNING << its_warning.str();
+ _callback(_subscription);
}
} else { // new subscription
auto its_id
@@ -2810,10 +2879,9 @@ void routing_manager_impl::on_subscribe_ack(client_t _client,
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable,
- client_t _client) {
+ service_t _service, instance_t _instance, bool _reliable) {
return ep_mgr_impl_->find_or_create_remote_client(_service,
- _instance, _reliable, _client);
+ _instance, _reliable);
}
void routing_manager_impl::on_subscribe_nack(client_t _client,
@@ -3082,7 +3150,7 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const
#ifndef VSOMEIP_VERSION
#define VSOMEIP_VERSION "unknown version"
#endif
- static int counter(0);
+ static int its_counter(0);
static uint32_t its_interval = configuration_->get_log_version_interval();
bool is_diag_mode(false);
@@ -3104,11 +3172,11 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const
<< ((is_diag_mode == true) ? "diagnosis)" : "default)")
<< its_last_resume.str();
- counter++;
- if (counter == 6) {
+ its_counter++;
+ if (its_counter == 6) {
ep_mgr_->log_client_states();
ep_mgr_impl_->log_client_states();
- counter = 0;
+ its_counter = 0;
}
{
@@ -3852,12 +3920,10 @@ void routing_manager_impl::register_routing_state_handler(
}
void routing_manager_impl::sd_acceptance_enabled(
- const boost::asio::ip::address& _address) {
- boost::system::error_code ec;
- VSOMEIP_INFO << "ipsec-plugin-mgu: expire subscriptions and services: "
- << _address.to_string(ec);
- expire_subscriptions(_address);
- expire_services(_address);
+ const boost::asio::ip::address& _address,
+ const configuration::port_range_t& _range, bool _reliable) {
+ expire_subscriptions(_address, _range, _reliable);
+ expire_services(_address, _range, _reliable);
}
void routing_manager_impl::memory_log_timer_cbk(
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index 8135c3f..3b95a2d 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -45,7 +45,6 @@ routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host,
sender_(nullptr),
receiver_(nullptr),
register_application_timer_(io_),
- logger_(logger::get()),
request_debounce_timer_ (io_),
request_debounce_timer_running_(false),
client_side_logging_(_client_side_logging),
@@ -342,9 +341,35 @@ void routing_manager_proxy::register_event(client_t _client,
std::lock_guard<std::mutex> its_lock(state_mutex_);
is_first = pending_event_registrations_.find(registration)
== pending_event_registrations_.end();
+#ifndef VSOMEIP_ENABLE_COMPAT
if (is_first) {
pending_event_registrations_.insert(registration);
}
+#else
+ bool insert = true;
+ if (is_first) {
+ for (auto iter = pending_event_registrations_.begin();
+ iter != pending_event_registrations_.end();) {
+ if (iter->service_ == _service
+ && iter->instance_ == _instance
+ && iter->notifier_ == _notifier
+ && iter->is_provided_ == _is_provided
+ && iter->type_ == event_type_e::ET_EVENT
+ && _type == event_type_e::ET_SELECTIVE_EVENT) {
+ iter = pending_event_registrations_.erase(iter);
+ iter = pending_event_registrations_.insert(registration).first;
+ is_first = true;
+ insert = false;
+ break;
+ } else {
+ iter++;
+ }
+ }
+ if (insert) {
+ pending_event_registrations_.insert(registration);
+ }
+ }
+#endif
}
if (is_first || _is_provided) {
routing_manager_base::register_event(_client,
@@ -399,17 +424,19 @@ void routing_manager_proxy::unregister_event(client_t _client,
}
}
}
- auto it = pending_event_registrations_.begin();
- while (it != pending_event_registrations_.end()) {
- if (it->service_ == _service
- && it->instance_ == _instance
- && it->notifier_ == _notifier) {
+
+ for (auto iter = pending_event_registrations_.begin();
+ iter != pending_event_registrations_.end(); ) {
+ if (iter->service_ == _service
+ && iter->instance_ == _instance
+ && iter->notifier_ == _notifier
+ && iter->is_provided_ == _is_provided) {
+ pending_event_registrations_.erase(iter);
break;
+ } else {
+ iter++;
}
- it++;
}
- if (it != pending_event_registrations_.end())
- pending_event_registrations_.erase(it);
}
}
@@ -455,7 +482,7 @@ void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid,
std::lock_guard<std::mutex> its_lock(state_mutex_);
if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) {
- send_subscribe(_client, _service, _instance, _eventgroup, _major, _event );
+ send_subscribe(client_, _service, _instance, _eventgroup, _major, _event );
}
subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid};
pending_subscriptions_.insert(subscription);
@@ -1548,20 +1575,23 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
return;
}
#endif
-
- // inform host about its own registration state changes
- host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
-
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
- boost::system::error_code ec;
- register_application_timer_.cancel(ec);
- send_registered_ack();
- send_pending_commands();
- state_ = inner_state_type_e::ST_REGISTERED;
- // Notify stop() call about clean deregistration
- state_condition_.notify_one();
+ if (state_ == inner_state_type_e::ST_REGISTERING) {
+ boost::system::error_code ec;
+ register_application_timer_.cancel(ec);
+ send_registered_ack();
+ send_pending_commands();
+ state_ = inner_state_type_e::ST_REGISTERED;
+ // Notify stop() call about clean deregistration
+ state_condition_.notify_one();
+ }
}
+
+ // inform host about its own registration state changes
+ if (state_ == inner_state_type_e::ST_REGISTERED)
+ host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
+
}
} else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) {
{
@@ -2278,25 +2308,23 @@ routing_manager_proxy::assign_client_timeout_cbk(
void routing_manager_proxy::register_application_timeout_cbk(
boost::system::error_code const &_error) {
- if (!_error) {
- bool register_again(false);
- {
- std::lock_guard<std::mutex> its_lock(state_mutex_);
- if (state_ != inner_state_type_e::ST_REGISTERED) {
- state_ = inner_state_type_e::ST_DEREGISTERED;
- register_again = true;
- }
- }
- if (register_again) {
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
- << " register timeout! Trying again...";
- if (sender_) {
- sender_->restart();
- }
+ bool register_again(false);
+ {
+ std::lock_guard<std::mutex> its_lock(state_mutex_);
+ if (!_error && state_ != inner_state_type_e::ST_REGISTERED) {
+ state_ = inner_state_type_e::ST_DEREGISTERED;
+ register_again = true;
}
}
+ if (register_again) {
+ std::lock_guard<std::mutex> its_lock(sender_mutex_);
+ VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
+ << " register timeout! Trying again...";
+
+ if (sender_)
+ sender_->restart();
+ }
}
void routing_manager_proxy::send_registered_ack() {
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 65945f7..d7a1dd2 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -784,8 +784,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
void routing_manager_stub::on_register_application(client_t _client) {
auto endpoint = host_->find_local(_client);
if (endpoint) {
- VSOMEIP_ERROR << "Registering application: " << std::hex << _client
- << " failed. It is already registered!";
+ VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client
+ << ". Last registration might have been taken too long.";
} else {
(void)host_->find_or_create_local(_client);
std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp
index b439501..f60c390 100644
--- a/implementation/runtime/include/application_impl.hpp
+++ b/implementation/runtime/include/application_impl.hpp
@@ -33,7 +33,6 @@ namespace vsomeip_v3 {
class runtime;
class configuration;
-class logger;
class routing_manager;
class routing_manager_stub;
@@ -175,6 +174,7 @@ public:
const std::string& _path, bool _enable);
VSOMEIP_EXPORT void set_sd_acceptance_required(
const sd_acceptance_map_type_t& _remotes, bool _enable);
+
VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required();
VSOMEIP_EXPORT void register_sd_acceptance_handler(sd_acceptance_handler_t _handler);
@@ -389,9 +389,6 @@ private:
std::size_t max_dispatchers_;
std::size_t max_dispatch_time_;
- // Workaround for destruction problem
- std::shared_ptr<logger> logger_;
-
std::condition_variable stop_cv_;
std::mutex start_stop_mutex_;
bool stopped_;
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index 0018340..44b14fd 100644
--- a/implementation/runtime/src/application_impl.cpp
+++ b/implementation/runtime/src/application_impl.cpp
@@ -9,7 +9,6 @@
#include <iostream>
#include <boost/exception/diagnostic_information.hpp>
-#include <boost/log/exceptions.hpp>
#ifndef _WIN32
#include <dlfcn.h>
@@ -63,7 +62,6 @@ application_impl::application_impl(const std::string &_name)
is_dispatching_(false),
max_dispatchers_(VSOMEIP_MAX_DISPATCHERS),
max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME),
- logger_(logger::get()),
stopped_(false),
block_stopping_(false),
is_routing_manager_host_(false),
@@ -420,10 +418,6 @@ void application_impl::start() {
#endif
try {
io_.run();
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "catched boost::log system_error in I/O thread" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::start() "
"catched exception: " << e.what();
@@ -469,10 +463,6 @@ void application_impl::start() {
stop_thread_.join();
}
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "catched boost::log system_error in I/O thread" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::start() catched exception: " << e.what();
}
@@ -502,14 +492,10 @@ void application_impl::start() {
}
void application_impl::stop() {
-#if !defined(_WIN32) && !defined(ANDROID)
- try {
- VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\" ("
+
+ VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\" ("
<< std::hex << std::setw(4) << std::setfill('0') << client_ << ").";
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "catched boost::log system_error application_impl::stop" << std::endl;
- }
-#endif
+
bool block = true;
{
std::lock_guard<std::mutex> its_lock_start_stop(start_stop_mutex_);
@@ -1954,11 +1940,6 @@ void application_impl::shutdown() {
running_dispatchers_.clear();
elapsed_dispatchers_.clear();
dispatchers_.clear();
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "application_impl::" << __func__ << ": stopping dispatchers, "
- << "catched boost::log system_error" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping dispatchers, "
<< " catched exception: " << e.what();
@@ -1967,11 +1948,6 @@ void application_impl::shutdown() {
try {
if (routing_)
routing_->stop();
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "application_impl::" << __func__ << ": stopping routing, "
- << "catched boost::log system_error" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping routing, "
<< " catched exception: " << e.what();
@@ -1980,11 +1956,6 @@ void application_impl::shutdown() {
try {
work_.reset();
io_.stop();
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "application_impl::" << __func__ << ": stopping io, "
- << "catched boost::log system_error" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping io, "
<< " catched exception: " << e.what();
@@ -1998,11 +1969,6 @@ void application_impl::shutdown() {
}
}
io_threads_.clear();
-#if !defined(_WIN32) && !defined(ANDROID)
- } catch (const boost::log::v2_mt_posix::system_error &e) {
- std::cerr << "application_impl::" << __func__ << ": joining threads, "
- << "catched boost::log system_error" << std::endl;
-#endif
} catch (const std::exception &e) {
VSOMEIP_ERROR << "application_impl::" << __func__ << ": joining threads, "
<< " catched exception: " << e.what();
@@ -2390,46 +2356,136 @@ void application_impl::register_reboot_notification_handler(
}
void application_impl::set_sd_acceptance_required(
- const remote_info_t& _remote, const std::string& _path, bool _enable) {
- if (is_routing()) {
- const boost::asio::ip::address its_address = _remote.ip_.is_v4_ ?
- static_cast<boost::asio::ip::address>(boost::asio::ip::address_v4(_remote.ip_.address_.v4_)) :
- static_cast<boost::asio::ip::address>(boost::asio::ip::address_v6(_remote.ip_.address_.v6_));
- configuration_->set_sd_acceptance_required(its_address, _remote.port_, _path, _enable);
- if (_enable && routing_) {
- const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
- rm_impl->sd_acceptance_enabled(its_address);
- }
+ const remote_info_t &_remote, const std::string &_path, bool _enable) {
+
+ if (!is_routing()) {
+ return;
+ }
+
+ const boost::asio::ip::address its_address(_remote.ip_.is_v4_ ?
+ static_cast<boost::asio::ip::address>(boost::asio::ip::address_v4(
+ _remote.ip_.address_.v4_)) :
+ static_cast<boost::asio::ip::address>(boost::asio::ip::address_v6(
+ _remote.ip_.address_.v6_)));
+
+ if (_remote.first_ == std::numeric_limits<std::uint16_t>::max()
+ && _remote.last_ == 0) {
+ // special case to (de)activate rules per IP
+ configuration_->set_sd_acceptance_rules_active(its_address, _enable);
+ return;
+ }
+
+ configuration::port_range_t its_range { _remote.first_, _remote.last_ };
+ configuration_->set_sd_acceptance_rule(its_address,
+ its_range, port_type_e::PT_UNKNOWN,
+ _path, _remote.is_reliable_, _enable, true);
+
+ if (_enable && routing_) {
+ const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
+ rm_impl->sd_acceptance_enabled(its_address, its_range,
+ _remote.is_reliable_);
}
}
-void application_impl::set_sd_acceptance_required(const sd_acceptance_map_type_t& _remotes,
- bool _enable) {
- (void) _remotes;
- (void) _enable;
+void application_impl::set_sd_acceptance_required(
+ const sd_acceptance_map_type_t& _remotes, bool _enable) {
+
+ (void)_remotes;
+ (void)_enable;
+
+#if 0
+ if (!is_routing()) {
+ return;
+ }
+
+ configuration::sd_acceptance_rules_t its_rules;
+ for (const auto& remote_info : _remotes) {
+ const boost::asio::ip::address its_address(remote_info.first.ip_.is_v4_ ?
+ static_cast<boost::asio::ip::address>(boost::asio::ip::address_v4(
+ remote_info.first.ip_.address_.v4_)) :
+ static_cast<boost::asio::ip::address>(boost::asio::ip::address_v6(
+ remote_info.first.ip_.address_.v6_)));
+ const boost::icl::interval<std::uint16_t>::interval_type its_interval =
+ remote_info.first.is_range_ ?
+ boost::icl::interval<std::uint16_t>::closed(
+ remote_info.first.first_,
+ ((remote_info.first.last_ == ANY_PORT) ?
+ std::numeric_limits<std::uint16_t>::max() :
+ remote_info.first.last_)) :
+ boost::icl::interval<std::uint16_t>::closed(
+ remote_info.first.first_, remote_info.first.first_);
+
+ const bool its_reliability = remote_info.first.is_reliable_;
+
+ const auto found_address = its_rules.find(its_address);
+ if (found_address != its_rules.end()) {
+ const auto found_reliability = found_address->second.second.find(
+ its_reliability);
+ if (found_reliability != found_address->second.second.end()) {
+ found_reliability->second.insert(its_interval);
+ } else {
+ found_address->second.second.emplace(std::make_pair(
+ its_reliability,
+ boost::icl::interval_set<std::uint16_t>(its_interval)));
+ }
+ } else {
+ its_rules.insert(std::make_pair(its_address,
+ std::make_pair(remote_info.second,
+ std::map<bool, boost::icl::interval_set<std::uint16_t>>(
+ {{ its_reliability,
+ boost::icl::interval_set<std::uint16_t>(
+ its_interval) } }))));
+ }
+ }
+
+ configuration_->set_sd_acceptance_rules(its_rules, _enable);
+#endif
}
application::sd_acceptance_map_type_t
application_impl::get_sd_acceptance_required() {
+
sd_acceptance_map_type_t its_ret;
+
if (is_routing()) {
- for (const auto& e : configuration_->get_sd_acceptance_required()) {
+ for (const auto& e : configuration_->get_sd_acceptance_rules()) {
remote_info_t its_remote_info;
- its_remote_info.ip_.is_v4_ = e.first.first.is_v4();
- if (e.first.first.is_v4()) {
- its_remote_info.ip_.address_.v4_ = e.first.first.to_v4().to_bytes();
- its_remote_info.ip_.is_v4_ = true;
+ its_remote_info.ip_.is_v4_ = e.first.is_v4();
+ if (its_remote_info.ip_.is_v4_) {
+ its_remote_info.ip_.address_.v4_ = e.first.to_v4().to_bytes();
} else {
- its_remote_info.ip_.address_.v6_ = e.first.first.to_v6().to_bytes();
- its_remote_info.ip_.is_v4_ = false;
+ its_remote_info.ip_.address_.v6_ = e.first.to_v6().to_bytes();
+ }
+ for (const auto& reliability : e.second.second) {
+ its_remote_info.is_reliable_ = reliability.first;
+ for (const auto& port_range : reliability.second.first) {
+ if (port_range.lower() == port_range.upper()) {
+ its_remote_info.first_ = port_range.lower();
+ its_remote_info.last_ = port_range.lower();
+ its_remote_info.is_range_ = false;
+ } else {
+ its_remote_info.first_ = port_range.lower();
+ its_remote_info.last_ = port_range.upper();
+ its_remote_info.is_range_ = true;
+ }
+ its_ret[its_remote_info] = e.second.first;
+ }
+ for (const auto& port_range : reliability.second.second) {
+ if (port_range.lower() == port_range.upper()) {
+ its_remote_info.first_ = port_range.lower();
+ its_remote_info.last_ = port_range.lower();
+ its_remote_info.is_range_ = false;
+ } else {
+ its_remote_info.first_ = port_range.lower();
+ its_remote_info.last_ = port_range.upper();
+ its_remote_info.is_range_ = true;
+ }
+ its_ret[its_remote_info] = e.second.first;
+ }
}
- its_remote_info.port_ = e.first.second;
- its_remote_info.first_ = ANY_PORT;
- its_remote_info.last_ = ANY_PORT;
- its_remote_info.is_range_ = false;
- its_ret[its_remote_info] = e.second;
}
}
+
return its_ret;
}
diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp
index 018fbd5..f8727f8 100644
--- a/implementation/security/include/policy.hpp
+++ b/implementation/security/include/policy.hpp
@@ -6,9 +6,11 @@
#ifndef VSOMEIP_V3_POLICY_HPP_
#define VSOMEIP_V3_POLICY_HPP_
-#include <utility>
-#include <set>
#include <cstring>
+#include <map>
+#include <mutex>
+#include <set>
+#include <utility>
#include <vsomeip/constants.hpp>
#include <vsomeip/primitive_types.hpp>
@@ -25,9 +27,11 @@ struct policy {
ids_t ids_;
bool allow_who_;
- std::set<std::pair<service_t, ids_t>> services_;
- std::set<std::pair<service_t, ranges_t>> offers_;
+ std::map<service_t, ids_t> services_;
+ std::map<service_t, ranges_t> offers_;
bool allow_what_;
+
+ std::mutex mutex_;
};
} // namespace vsomeip_v3
diff --git a/implementation/security/src/security_impl.cpp b/implementation/security/src/security_impl.cpp
index a60a6f8..ef1404d 100644
--- a/implementation/security/src/security_impl.cpp
+++ b/implementation/security/src/security_impl.cpp
@@ -81,6 +81,7 @@ security_impl::check_credentials(client_t _client, uid_t _uid,
}
for (const auto &p : its_policies) {
+ std::lock_guard<std::mutex> its_policy_lock(p->mutex_);
for (auto its_credential : p->ids_) {
bool has_uid(false), has_gid(false);
for (auto its_range : std::get<0>(its_credential)) {
@@ -163,6 +164,7 @@ security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client,
}
for (const auto &p : its_policies) {
+ std::lock_guard<std::mutex> its_policy_lock(p->mutex_);
bool has_uid(false), has_gid(false), has_service(false), has_instance_id(false), has_method_id(false);
for (auto its_credential : p->ids_) {
has_uid = has_gid = false;
@@ -183,35 +185,32 @@ security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client,
break;
}
- for (auto its_offer : p->services_) {
- if (std::get<0>(its_offer) == _service) {
- for (auto its_ids : std::get<1>(its_offer)) {
- has_service = has_instance_id = has_method_id = false;
- for (auto its_instance_range : std::get<0>(its_ids)) {
- if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) {
- has_instance_id = true;
- break;
- }
+ auto its_service = p->services_.find(_service);
+ if (its_service != p->services_.end()) {
+ for (auto its_ids : its_service->second) {
+ has_service = has_instance_id = has_method_id = false;
+ for (auto its_instance_range : std::get<0>(its_ids)) {
+ if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) {
+ has_instance_id = true;
+ break;
}
- if (!_is_request_service) {
- for (auto its_method_range : std::get<1>(its_ids)) {
- if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) {
- has_method_id = true;
- break;
- }
+ }
+ if (!_is_request_service) {
+ for (auto its_method_range : std::get<1>(its_ids)) {
+ if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) {
+ has_method_id = true;
+ break;
}
- } else {
- // handle VSOMEIP_REQUEST_SERVICE
- has_method_id = true;
- }
-
- if (has_instance_id && has_method_id) {
- has_service = true;
- break;
}
+ } else {
+ // handle VSOMEIP_REQUEST_SERVICE
+ has_method_id = true;
}
- if (has_service)
+
+ if (has_instance_id && has_method_id) {
+ has_service = true;
break;
+ }
}
}
@@ -281,6 +280,7 @@ security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client,
}
for (const auto &p : its_policies) {
+ std::lock_guard<std::mutex> its_policy_lock(p->mutex_);
bool has_uid(false), has_gid(false), has_offer(false);
for (auto its_credential : p->ids_) {
has_uid = has_gid = false;
@@ -301,21 +301,19 @@ security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client,
break;
}
- for (auto its_offer : p->offers_) {
- has_offer = false;
- if (std::get<0>(its_offer) == _service) {
- for (auto its_instance_range : std::get<1>(its_offer)) {
- if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) {
- has_offer = true;
- break;
- }
- }
- if (has_offer)
+ auto find_service = p->offers_.find(_service);
+ if (find_service != p->offers_.end()) {
+ for (auto its_instance_range : find_service->second) {
+ if (std::get<0>(its_instance_range) <= _instance
+ && _instance <= std::get<1>(its_instance_range)) {
+ has_offer = true;
break;
+ }
}
}
- if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) {
+ if ((has_uid && has_gid && p->allow_who_)
+ || ((!has_uid || !has_gid) && !p->allow_who_)) {
if (p->allow_what_ == has_offer) {
return true;
}
@@ -458,6 +456,7 @@ security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) {
if (!any_client_policies_.empty()) {
std::vector<std::shared_ptr<policy>>::iterator p_it = any_client_policies_.begin();
while (p_it != any_client_policies_.end()) {
+ std::lock_guard<std::mutex> its_policy_lock((*p_it)->mutex_);
bool has_uid(false), has_gid(false);
for (auto its_credential : p_it->get()->ids_) {
has_uid = has_gid = false;
@@ -492,7 +491,7 @@ security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) {
}
void
-security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy) {
+security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy> &_policy) {
remove_security_policy(_uid, _gid);
std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
any_client_policies_.push_back(_policy);
@@ -500,13 +499,14 @@ security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::s
void
security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid,
- const std::shared_ptr<policy>& _credentials_policy, client_t _client) {
+ const std::shared_ptr<policy> &_policy, client_t _client) {
bool was_found(false);
std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
- for (const auto& its_policy : any_client_policies_) {
+ for (const auto &p : any_client_policies_) {
+ std::lock_guard<std::mutex> its_policy_lock(p->mutex_);
bool has_uid(false), has_gid(false);
- for (auto its_credential : its_policy->ids_) {
+ for (auto its_credential : p->ids_) {
has_uid = has_gid = false;
for (auto its_range : std::get<0>(its_credential)) {
if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) {
@@ -520,7 +520,7 @@ security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid,
break;
}
}
- if (has_uid && has_gid && its_policy->allow_who_) {
+ if (has_uid && has_gid && p->allow_who_) {
was_found = true;
break;
}
@@ -531,7 +531,7 @@ security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid,
}
// Do not add the new (credentials-only-policy) if a allow credentials policy with same credentials was found
if (!was_found) {
- any_client_policies_.push_back(_credentials_policy);
+ any_client_policies_.push_back(_policy);
VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x"
<< std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid;
}
@@ -581,6 +581,7 @@ security_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &
if (uid_allowed) {
std::lock_guard<std::mutex> its_lock(service_interface_whitelist_mutex_);
+ std::lock_guard<std::mutex> its_policy_lock(_policy->mutex_);
for (auto its_request : _policy->services_) {
auto its_requested_service = std::get<0>(its_request);
bool has_service(false);
@@ -668,6 +669,8 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size,
// get user ID String
if (parse_uid_gid(_buffer, _buffer_size, its_uid, its_gid)) {
+ std::lock_guard<std::mutex> its_policy_lock(_policy->mutex_);
+
_uid = its_uid;
_gid = its_gid;
@@ -762,8 +765,14 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size,
parsed_req_bytes += (skip_array_length_ + instances_array_length);
}
if (!its_instance_method_ranges.empty()) {
- _policy->services_.insert(
+ auto find_service = _policy->services_.find(its_service_id);
+ if (find_service != _policy->services_.end()) {
+ find_service->second.insert(its_instance_method_ranges.begin(),
+ its_instance_method_ranges.end());
+ } else {
+ _policy->services_.insert(
std::make_pair(its_service_id, its_instance_method_ranges));
+ }
}
}
}
@@ -803,8 +812,14 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size,
parsed_offers_bytes += (skip_array_length_ + ids_array_length);
}
if (!its_instance_ranges.empty()) {
- _policy->offers_.insert(
- std::make_pair(its_service_id, its_instance_ranges));
+ auto find_service = _policy->offers_.find(its_service_id);
+ if (find_service != _policy->offers_.end()) {
+ find_service->second.insert(its_instance_ranges.begin(),
+ its_instance_ranges.end());
+ } else {
+ _policy->offers_.insert(
+ std::make_pair(its_service_id, its_instance_ranges));
+ }
}
}
}
@@ -1166,8 +1181,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) {
}
}
if (service != 0x0 && !its_instance_method_ranges.empty()) {
- policy->services_.insert(
+ auto find_policy = policy->services_.find(service);
+ if (find_policy != policy->services_.end()) {
+ find_policy->second.insert(its_instance_method_ranges.begin(),
+ its_instance_method_ranges.end());
+ } else {
+ policy->services_.insert(
std::make_pair(service, its_instance_method_ranges));
+ }
}
}
} else if (l->first == "offers") {
@@ -1197,8 +1218,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) {
}
}
if (service != 0x0 && !its_instance_ranges.empty()) {
- policy->offers_.insert(
- std::make_pair(service, its_instance_ranges));
+ auto find_service = policy->offers_.find(service);
+ if (find_service != policy->offers_.end()) {
+ find_service->second.insert(its_instance_ranges.begin(),
+ its_instance_ranges.end());
+ } else {
+ policy->offers_.insert(
+ std::make_pair(service, its_instance_ranges));
+ }
}
}
}
@@ -1268,8 +1295,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) {
}
}
if (service != 0x0 && !its_instance_method_ranges.empty()) {
- policy->services_.insert(
+ auto find_policy = policy->services_.find(service);
+ if (find_policy != policy->services_.end()) {
+ find_policy->second.insert(its_instance_method_ranges.begin(),
+ its_instance_method_ranges.end());
+ } else {
+ policy->services_.insert(
std::make_pair(service, its_instance_method_ranges));
+ }
}
}
}
@@ -1300,8 +1333,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) {
}
}
if (service != 0x0 && !its_instance_ranges.empty()) {
- policy->offers_.insert(
- std::make_pair(service, its_instance_ranges));
+ auto find_service = policy->offers_.find(service);
+ if (find_service != policy->offers_.end()) {
+ find_service->second.insert(its_instance_ranges.begin(),
+ its_instance_ranges.end());
+ } else {
+ policy->offers_.insert(
+ std::make_pair(service, its_instance_ranges));
+ }
}
}
}
@@ -1620,7 +1659,7 @@ static void security_teardown(void) __attribute__((destructor));
static void security_teardown(void)
{
if (the_security_ptr__ != nullptr) {
- std::lock_guard<std::mutex> itsLock(the_security_mutex__);
+ std::lock_guard<std::mutex> its_lock(the_security_mutex__);
the_security_ptr__->reset();
delete the_security_ptr__;
the_security_ptr__ = nullptr;
diff --git a/implementation/service_discovery/include/selective_option_impl.hpp b/implementation/service_discovery/include/selective_option_impl.hpp
index 0660f1e..863408f 100644
--- a/implementation/service_discovery/include/selective_option_impl.hpp
+++ b/implementation/service_discovery/include/selective_option_impl.hpp
@@ -28,6 +28,7 @@ public:
bool operator==(const option_impl &_other) const;
std::set<client_t> get_clients() const;
+ void set_clients(const std::set<client_t> &_clients);
bool add_client(client_t _client);
bool remove_client(client_t _client);
bool has_clients() const;
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp
index 0a5adc0..778ce08 100644
--- a/implementation/service_discovery/include/service_discovery.hpp
+++ b/implementation/service_discovery/include/service_discovery.hpp
@@ -19,6 +19,7 @@
namespace vsomeip_v3 {
class configuration;
+class eventgroupinfo;
namespace sd {
@@ -39,7 +40,8 @@ public:
virtual void subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl, client_t _client) = 0;
+ ttl_t _ttl, client_t _client,
+ const std::shared_ptr<eventgroupinfo>& _info) = 0;
virtual void unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client) = 0;
virtual void unsubscribe_all(service_t _service, instance_t _instance) = 0;
diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp
index 94b67ec..88e093b 100644
--- a/implementation/service_discovery/include/service_discovery_host.hpp
+++ b/implementation/service_discovery/include/service_discovery_host.hpp
@@ -69,10 +69,15 @@ public:
const boost::asio::ip::address &_address, uint16_t _port) = 0;
virtual std::shared_ptr<endpoint> find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) = 0;
+ service_t _service, instance_t _instance, bool _reliable) = 0;
virtual void expire_subscriptions(const boost::asio::ip::address &_address) = 0;
+ virtual void expire_subscriptions(const boost::asio::ip::address &_address,
+ std::uint16_t _port, bool _reliable) = 0;
virtual void expire_services(const boost::asio::ip::address &_address) = 0;
+ virtual void expire_services(const boost::asio::ip::address &_address,
+ std::uint16_t _port, bool _reliable) = 0;
+
virtual void on_remote_subscribe(
std::shared_ptr<remote_subscription> &_subscription,
@@ -88,6 +93,9 @@ public:
service_t _service, instance_t _instance) const = 0;
virtual std::map<instance_t, std::shared_ptr<serviceinfo>> get_offered_service_instances(
service_t _service) const = 0;
+
+ virtual std::set<eventgroup_t> get_subscribed_eventgroups(service_t _service,
+ instance_t _instance) = 0;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp
index ba3c723..53b18c0 100644
--- a/implementation/service_discovery/include/service_discovery_impl.hpp
+++ b/implementation/service_discovery/include/service_discovery_impl.hpp
@@ -75,7 +75,7 @@ public:
void subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl,
- client_t _client);
+ client_t _client, const std::shared_ptr<eventgroupinfo>& _info);
void unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client);
void unsubscribe_all(service_t _service, instance_t _instance);
@@ -128,18 +128,30 @@ private:
entry_data_t create_eventgroup_entry(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
const std::shared_ptr<subscription> &_subscription,
- remote_offer_type_e _offer_type);
+ reliability_type_e _offer_type);
void insert_subscription_ack(
const std::shared_ptr<remote_subscription_ack>& _acknowledgement,
const std::shared_ptr<eventgroupinfo> &_info, ttl_t _ttl,
- const std::shared_ptr<endpoint_definition> &_target = nullptr,
- const client_t _client = VSOMEIP_ROUTING_CLIENT);
+ const std::shared_ptr<endpoint_definition> &_target,
+ const std::set<client_t> &_clients);
+ typedef std::set<std::pair<bool, std::uint16_t>> expired_ports_t;
+ struct sd_acceptance_state_t {
+ explicit sd_acceptance_state_t(expired_ports_t& _expired_ports)
+ : expired_ports_(_expired_ports),
+ sd_acceptance_required_(false),
+ accept_entries_(false) {
+ }
+
+ expired_ports_t& expired_ports_;
+ bool sd_acceptance_required_;
+ bool accept_entries_;
+ };
void process_serviceentry(std::shared_ptr<serviceentry_impl> &_entry,
const std::vector<std::shared_ptr<option_impl> > &_options,
bool _unicast_flag, std::vector<std::shared_ptr<message_impl> > &_resubscribes,
- bool _received_via_mcast, bool _accept_offers);
+ bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state);
void process_offerservice_serviceentry(
service_t _service, instance_t _instance, major_version_t _major,
minor_version_t _minor, ttl_t _ttl,
@@ -148,7 +160,7 @@ private:
const boost::asio::ip::address &_unreliable_address,
uint16_t _unreliable_port,
std::vector<std::shared_ptr<message_impl> > &_resubscribes,
- bool _received_via_mcast);
+ bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state);
void send_offer_service(
const std::shared_ptr<const serviceinfo> &_info, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor,
@@ -164,7 +176,8 @@ private:
const std::vector<std::shared_ptr<option_impl> > &_options,
std::shared_ptr<remote_subscription_ack> &_acknowledgement,
const boost::asio::ip::address &_destination,
- bool _is_stop_subscribe_subscribe, bool _force_initial_events);
+ bool _is_stop_subscribe_subscribe, bool _force_initial_events,
+ const sd_acceptance_state_t& _sd_ac_state);
void handle_eventgroup_subscription(service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl, uint8_t _counter, uint16_t _reserved,
@@ -175,6 +188,7 @@ private:
std::shared_ptr<remote_subscription_ack> &_acknowledgement,
bool _is_stop_subscribe_subscribe, bool _force_initial_events,
const std::set<client_t> &_clients,
+ const sd_acceptance_state_t& _sd_ac_state,
const std::shared_ptr<eventgroupinfo>& _info);
void handle_eventgroup_subscription_ack(service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
@@ -300,16 +314,23 @@ private:
bool update_remote_offer_type(service_t _service, instance_t _instance,
remote_offer_type_e _offer_type,
const boost::asio::ip::address &_reliable_address,
- const boost::asio::ip::address &_unreliable_address);
+ std::uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ std::uint16_t _unreliable_port);
void remove_remote_offer_type(service_t _service, instance_t _instance,
- const boost::asio::ip::address &_address);
+ const boost::asio::ip::address &_reliable_address,
+ std::uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ std::uint16_t _unreliable_port);
void remove_remote_offer_type_by_ip(const boost::asio::ip::address &_address);
+ void remove_remote_offer_type_by_ip(const boost::asio::ip::address &_address,
+ std::uint16_t _port, bool _reliable);
std::shared_ptr<subscription> create_subscription(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl,
const std::shared_ptr<endpoint> &_reliable,
- const std::shared_ptr<endpoint> &_unreliable);
+ const std::shared_ptr<endpoint> &_unreliable,
+ const std::shared_ptr<eventgroupinfo> &_info);
std::shared_ptr<remote_subscription> get_remote_subscription(
const service_t _service, const instance_t _instance,
@@ -332,6 +353,9 @@ private:
void add_entry_data_to_remote_subscription_ack_msg(
const std::shared_ptr<remote_subscription_ack>& _acknowledgement,
const entry_data_t &_data);
+ reliability_type_e get_eventgroup_reliability(
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ const std::shared_ptr<subscription>& _subscription);
private:
boost::asio::io_service &io_;
@@ -436,7 +460,9 @@ private:
mutable std::mutex remote_offer_types_mutex_;
std::map<std::pair<service_t, instance_t>, remote_offer_type_e> remote_offer_types_;
- std::map<boost::asio::ip::address, std::set<std::pair<service_t, instance_t>>> remote_offers_by_ip_;
+ std::map<boost::asio::ip::address,
+ std::map<std::pair<bool, std::uint16_t>,
+ std::set<std::pair<service_t, instance_t>>>> remote_offers_by_ip_;
reboot_notification_handler_t reboot_notification_handler_;
sd_acceptance_handler_t sd_acceptance_handler_;
diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp
index f172348..adbd66c 100644
--- a/implementation/service_discovery/include/subscription.hpp
+++ b/implementation/service_discovery/include/subscription.hpp
@@ -17,6 +17,7 @@
namespace vsomeip_v3 {
class endpoint;
+class eventgroupinfo;
namespace sd {
@@ -60,6 +61,9 @@ public:
bool has_client() const;
bool has_client(const client_t _client) const;
+ void set_eventgroupinfo(const std::shared_ptr<eventgroupinfo> _info);
+ std::weak_ptr<eventgroupinfo> get_eventgroupinfo() const;
+
private:
major_version_t major_;
ttl_t ttl_;
@@ -74,6 +78,8 @@ private:
mutable std::mutex clients_mutex_;
std::map<client_t, subscription_state_e> clients_; // client-> is acknowledged?
+
+ std::weak_ptr<eventgroupinfo> eg_info_;
};
} // namespace sd
diff --git a/implementation/service_discovery/src/remote_subscription_ack.cpp b/implementation/service_discovery/src/remote_subscription_ack.cpp
index 80be082..03270c9 100644
--- a/implementation/service_discovery/src/remote_subscription_ack.cpp
+++ b/implementation/service_discovery/src/remote_subscription_ack.cpp
@@ -59,15 +59,14 @@ remote_subscription_ack::get_target_address() const {
bool
remote_subscription_ack::is_pending() const {
for (const auto& its_subscription : subscriptions_) {
- if (its_subscription->is_pending()) {
+ if (its_subscription->is_pending()
+ && its_subscription->get_answers() != 0) {
return true;
}
}
return false;
}
-
-
std::set<std::shared_ptr<remote_subscription> >
remote_subscription_ack::get_subscriptions() const {
return subscriptions_;
diff --git a/implementation/service_discovery/src/selective_option_impl.cpp b/implementation/service_discovery/src/selective_option_impl.cpp
index c61be22..17063d9 100755
--- a/implementation/service_discovery/src/selective_option_impl.cpp
+++ b/implementation/service_discovery/src/selective_option_impl.cpp
@@ -36,6 +36,11 @@ std::set<client_t> selective_option_impl::get_clients() const {
return (its_clients);
}
+void selective_option_impl::set_clients(const std::set<client_t> &_clients) {
+ clients_ = _clients;
+ length_ = uint16_t(1 + clients_.size() * sizeof(client_t));
+}
+
bool selective_option_impl::add_client(client_t _client) {
auto its_result = clients_.insert(_client);
length_ = uint16_t(1 + clients_.size() * sizeof(client_t));
diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp
index e5c4a32..7ae5395 100644
--- a/implementation/service_discovery/src/service_discovery_impl.cpp
+++ b/implementation/service_discovery/src/service_discovery_impl.cpp
@@ -35,6 +35,7 @@
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
#include "../../message/include/serializer.hpp"
#include "../../plugin/include/plugin_manager_impl.hpp"
+#include "../../routing/include/event.hpp"
#include "../../routing/include/eventgroupinfo.hpp"
#include "../../routing/include/serviceinfo.hpp"
#include "../../utility/include/byteorder.hpp"
@@ -73,7 +74,7 @@ service_discovery_impl::service_discovery_impl(
last_msg_received_timer_(_host->get_io()),
last_msg_received_timer_timeout_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY +
(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY / 10)) {
- // TODO: cleanup start condition!
+
next_subscription_expiration_ = std::chrono::steady_clock::now() + std::chrono::hours(24);
}
@@ -234,31 +235,45 @@ void
service_discovery_impl::subscribe(
service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl, client_t _client) {
- {
- std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- auto its_subscription = found_eventgroup->second;
- if (its_subscription->get_major() != _major) {
- VSOMEIP_ERROR
- << "Subscriptions to different versions of the same "
- "service instance are not supported!";
- } else if (its_subscription->is_selective()) {
- if (its_subscription->add_client(_client)) {
- its_subscription->set_state(_client,
- subscription_state_e::ST_NOT_ACKNOWLEDGED);
- send_subscription(its_subscription,
- _service, _instance, _eventgroup,
- _client);
+ ttl_t _ttl, client_t _client,
+ const std::shared_ptr<eventgroupinfo> &_info) {
+#ifdef VSOMEIP_ENABLE_COMPAT
+ bool is_selective(_info ? _info->is_selective() : false);
+#endif // VSOMEIP_ENABLE_COMPAT
+
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ auto its_subscription = found_eventgroup->second;
+#ifdef VSOMEIP_ENABLE_COMPAT
+ if (!its_subscription->is_selective() && is_selective) {
+ its_subscription->set_selective(true);
+ its_subscription->remove_client(VSOMEIP_ROUTING_CLIENT);
+ for (const auto e : _info->get_events()) {
+ for (const auto c : e->get_subscribers(_eventgroup)) {
+ its_subscription->add_client(c);
}
}
- return;
}
+#endif // VSOMEIP_ENABLE_COMPAT
+ if (its_subscription->get_major() != _major) {
+ VSOMEIP_ERROR
+ << "Subscriptions to different versions of the same "
+ "service instance are not supported!";
+ } else if (its_subscription->is_selective()) {
+ if (its_subscription->add_client(_client)) {
+ its_subscription->set_state(_client,
+ subscription_state_e::ST_NOT_ACKNOWLEDGED);
+ send_subscription(its_subscription,
+ _service, _instance, _eventgroup,
+ _client);
+ }
+ }
+ return;
}
}
}
@@ -267,31 +282,26 @@ service_discovery_impl::subscribe(
get_subscription_endpoints(_service, _instance,
its_reliable, its_unreliable);
- {
- std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+ // New subscription
+ std::shared_ptr<subscription> its_subscription
+ = create_subscription(
+ _major, _ttl, its_reliable, its_unreliable, _info);
- // New subscription
- std::shared_ptr<subscription> its_subscription
- = create_subscription(
- _service, _instance, _eventgroup, _major,
- _ttl, its_reliable, its_unreliable);
-
- if (!its_subscription) {
- VSOMEIP_ERROR << __func__
- << ": creating subscription failed!";
- return;
- }
+ if (!its_subscription) {
+ VSOMEIP_ERROR << __func__
+ << ": creating subscription failed!";
+ return;
+ }
- subscribed_[_service][_instance][_eventgroup] = its_subscription;
+ subscribed_[_service][_instance][_eventgroup] = its_subscription;
- its_subscription->add_client(_client);
- its_subscription->set_state(_client,
- subscription_state_e::ST_NOT_ACKNOWLEDGED);
+ its_subscription->add_client(_client);
+ its_subscription->set_state(_client,
+ subscription_state_e::ST_NOT_ACKNOWLEDGED);
- send_subscription(its_subscription,
- _service, _instance, _eventgroup,
- _client);
- }
+ send_subscription(its_subscription,
+ _service, _instance, _eventgroup,
+ _client);
}
void
@@ -300,38 +310,36 @@ service_discovery_impl::send_subscription(
const service_t _service, const instance_t _instance,
const eventgroup_t _eventgroup,
const client_t _client) {
+ (void)_client;
+
auto its_reliable = _subscription->get_endpoint(true);
auto its_unreliable = _subscription->get_endpoint(false);
boost::asio::ip::address its_address;
get_subscription_address(its_reliable, its_unreliable, its_address);
-
if (!its_address.is_unspecified()) {
entry_data_t its_data;
-
- const remote_offer_type_e its_offer_type
- = get_remote_offer_type(_service, _instance);
- if (its_offer_type == remote_offer_type_e::UNRELIABLE &&
- !its_reliable && its_unreliable) {
+ const reliability_type_e its_reliability_type =
+ get_eventgroup_reliability(_service, _instance, _eventgroup, _subscription);
+ if (its_reliability_type == reliability_type_e::RT_UNRELIABLE && its_unreliable) {
if (its_unreliable->is_established()) {
its_data = create_eventgroup_entry(_service, _instance,
- _eventgroup, _subscription, its_offer_type);
+ _eventgroup, _subscription, its_reliability_type);
} else {
_subscription->set_udp_connection_established(false);
}
- } else if (its_offer_type == remote_offer_type_e::RELIABLE &&
- its_reliable && !its_unreliable) {
+ } else if (its_reliability_type == reliability_type_e::RT_RELIABLE && its_reliable) {
if (its_reliable->is_established()) {
its_data = create_eventgroup_entry(_service, _instance,
- _eventgroup, _subscription, its_offer_type);
+ _eventgroup, _subscription, its_reliability_type);
} else {
_subscription->set_tcp_connection_established(false);
}
- } else if (its_offer_type == remote_offer_type_e::RELIABLE_UNRELIABLE &&
+ } else if (its_reliability_type == reliability_type_e::RT_BOTH &&
its_reliable && its_unreliable) {
if (its_reliable->is_established() && its_unreliable->is_established()) {
its_data = create_eventgroup_entry(_service, _instance,
- _eventgroup, _subscription, its_offer_type);
+ _eventgroup, _subscription, its_reliability_type);
} else {
if (!its_reliable->is_established()) {
_subscription->set_tcp_connection_established(false);
@@ -340,16 +348,14 @@ service_discovery_impl::send_subscription(
_subscription->set_udp_connection_established(false);
}
}
+ } else if (its_reliability_type == reliability_type_e::RT_UNKNOWN) {
+ VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine reliability type for subscription to ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] ";
}
if (its_data.entry_) {
- if (_subscription->is_selective()) {
- auto its_selective_option = std::make_shared<selective_option_impl>();
- (void)its_selective_option->add_client(_client);
-
- its_data.options_.push_back(its_selective_option);
- }
-
// TODO: Implement a simple path, that sends a single message
auto its_current_message = std::make_shared<message_impl>();
std::vector<std::shared_ptr<message_impl> > its_messages;
@@ -368,9 +374,9 @@ service_discovery_impl::get_subscription_endpoints(
std::shared_ptr<endpoint> &_reliable,
std::shared_ptr<endpoint> &_unreliable) const {
_unreliable = host_->find_or_create_remote_client(
- _service, _instance, false, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, false);
_reliable = host_->find_or_create_remote_client(
- _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, true);
}
void
@@ -423,28 +429,37 @@ service_discovery_impl::unsubscribe(service_t _service,
if (!its_subscription->has_client()) {
its_subscription->set_ttl(0);
} else if (its_subscription->is_selective()) {
- auto its_major = its_subscription->get_major();
-
// create a dummy subscription object to unsubscribe
// the single client.
+ auto its_major = its_subscription->get_major();
+
its_subscription = std::make_shared<subscription>();
its_subscription->set_major(its_major);
its_subscription->set_ttl(0);
its_subscription->set_selective(true);
- its_subscription->add_client(_client);
its_subscription->set_endpoint(its_reliable, true);
its_subscription->set_endpoint(its_unreliable, false);
}
}
- const remote_offer_type_e its_offer_type
- = get_remote_offer_type(its_subscription);
+ // For selective subscriptions, the client must be added again
+ // to generate the selective option
+ if (its_subscription->is_selective())
+ its_subscription->add_client(_client);
+ const reliability_type_e its_reliability_type =
+ get_eventgroup_reliability(_service, _instance, _eventgroup, its_subscription);
auto its_data = create_eventgroup_entry(_service, _instance,
- _eventgroup, its_subscription, its_offer_type);
- if (its_data.entry_) {
+ _eventgroup, its_subscription, its_reliability_type);
+ if (its_data.entry_)
its_current_message->add_entry_data(its_data.entry_, its_data.options_);
- }
+
+ // Remove it again before updating (only impacts last unsubscribe)
+ if (its_subscription->is_selective())
+ (void)its_subscription->remove_client(_client);
+
+ // Ensure to update the "real" subscription
+ its_subscription = found_eventgroup->second;
// Finally update the subscriptions
if (!its_subscription->has_client()) {
@@ -470,8 +485,6 @@ service_discovery_impl::unsubscribe_all(
auto its_current_message = std::make_shared<message_impl>();;
boost::asio::ip::address its_address;
- const remote_offer_type_e its_offer_type
- = get_remote_offer_type(_service, _instance);
{
std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
@@ -482,8 +495,13 @@ service_discovery_impl::unsubscribe_all(
for (auto &its_eventgroup : found_instance->second) {
auto its_subscription = its_eventgroup.second;
its_subscription->set_ttl(0);
+
+ const reliability_type_e its_reliability =
+ get_eventgroup_reliability(_service, _instance,
+ its_eventgroup.first, its_subscription);
+
auto its_data = create_eventgroup_entry(_service, _instance,
- its_eventgroup.first, its_subscription, its_offer_type);
+ its_eventgroup.first, its_subscription, its_reliability);
auto its_reliable = its_subscription->get_endpoint(true);
auto its_unreliable = its_subscription->get_endpoint(false);
get_subscription_address(
@@ -672,7 +690,7 @@ entry_data_t
service_discovery_impl::create_eventgroup_entry(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
const std::shared_ptr<subscription> &_subscription,
- remote_offer_type_e _offer_type) {
+ reliability_type_e _reliability_type) {
entry_data_t its_data;
its_data.entry_ = nullptr;
@@ -683,18 +701,18 @@ service_discovery_impl::create_eventgroup_entry(
bool insert_reliable(false);
bool insert_unreliable(false);
- switch (_offer_type) {
- case remote_offer_type_e::RELIABLE:
+ switch (_reliability_type) {
+ case reliability_type_e::RT_RELIABLE:
if (its_reliable_endpoint) {
insert_reliable = true;
}
break;
- case remote_offer_type_e::UNRELIABLE:
+ case reliability_type_e::RT_UNRELIABLE:
if (its_unreliable_endpoint) {
insert_unreliable = true;
}
break;
- case remote_offer_type_e::RELIABLE_UNRELIABLE:
+ case reliability_type_e::RT_BOTH:
if (its_reliable_endpoint && its_unreliable_endpoint) {
insert_reliable = true;
insert_unreliable = true;
@@ -705,13 +723,13 @@ service_discovery_impl::create_eventgroup_entry(
}
if (!insert_reliable && !insert_unreliable
- && _offer_type != remote_offer_type_e::UNKNOWN) {
+ && _reliability_type != reliability_type_e::RT_UNKNOWN) {
VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as "
- "subscription doesn't match offer type: ["
+ "subscription doesn't match reliability type: ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] "
- << _offer_type;
+ << (uint16_t) _reliability_type;
return its_data;
}
std::shared_ptr<eventgroupentry_impl> its_entry, its_other;
@@ -753,11 +771,13 @@ service_discovery_impl::create_eventgroup_entry(
auto its_option = create_ip_option(unicast_, its_port, true);
its_data.options_.push_back(its_option);
} else {
- VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as "
+ VSOMEIP_WARNING << __func__ << ": Cannot create subscription as "
"local reliable port is zero: ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]";
+ its_data.entry_ = nullptr;
+ its_data.other_ = nullptr;
return its_data;
}
}
@@ -805,21 +825,20 @@ service_discovery_impl::create_eventgroup_entry(
auto its_option = create_ip_option(unicast_, its_port, false);
its_data.options_.push_back(its_option);
} else {
- VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as "
+ VSOMEIP_WARNING << __func__ << ": Cannot create subscription as "
" local unreliable port is zero: ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]";
+ its_data.entry_ = nullptr;
+ its_data.other_ = nullptr;
return its_data;
}
}
- if (its_entry
- &&_subscription->is_selective()) {
+ if (its_entry &&_subscription->is_selective()) {
auto its_selective_option = std::make_shared<selective_option_impl>();
- for (const auto &its_client : _subscription->get_clients())
- (void)its_selective_option->add_client(its_client);
-
+ its_selective_option->set_clients(_subscription->get_clients());
its_data.options_.push_back(its_selective_option);
}
@@ -836,7 +855,7 @@ service_discovery_impl::insert_subscription_ack(
const std::shared_ptr<remote_subscription_ack>& _acknowledgement,
const std::shared_ptr<eventgroupinfo> &_info, ttl_t _ttl,
const std::shared_ptr<endpoint_definition> &_target,
- const client_t _client) {
+ const std::set<client_t> &_clients) {
std::unique_lock<std::recursive_mutex> its_lock(_acknowledgement->get_lock());
auto its_message = _acknowledgement->get_current_message();
@@ -871,11 +890,10 @@ service_discovery_impl::insert_subscription_ack(
}
}
- if (_client != VSOMEIP_ROUTING_CLIENT) {
+ if (_clients.size() > 1 || (*(_clients.begin())) != 0) {
auto its_selective_option = its_eventgroup_entry->get_selective_option();
- if (its_selective_option) {
- its_selective_option->add_client(_client);
- }
+ if (its_selective_option)
+ its_selective_option->set_clients(_clients);
}
return;
@@ -911,10 +929,11 @@ service_discovery_impl::insert_subscription_ack(
its_data.options_.push_back(its_option);
}
}
+
// Selective
- if (_client != VSOMEIP_ROUTING_CLIENT) {
+ if (_clients.size() > 1 || (*(_clients.begin())) != 0) {
auto its_selective_option = std::make_shared<selective_option_impl>();
- (void)its_selective_option->add_client(_client);
+ (void)its_selective_option->set_clients(_clients);
its_data.options_.push_back(its_selective_option);
}
@@ -1031,43 +1050,30 @@ service_discovery_impl::on_message(
bool force_initial_events(false);
bool sd_acceptance_queried(false);
- bool accept_offers(false);
- bool expired_services(false);
+ expired_ports_t expired_ports;
+ sd_acceptance_state_t accept_state(expired_ports);
for (auto iter = its_entries.begin(); iter != its_end; iter++) {
if (!sd_acceptance_queried) {
+ sd_acceptance_queried = true;
if (sd_acceptance_handler_) {
+ accept_state.sd_acceptance_required_
+ = configuration_->is_protected_device(_sender);
remote_info_t remote;
- remote.port_ = ANY_PORT;
remote.first_ = ANY_PORT;
remote.last_ = ANY_PORT;
remote.is_range_ = false;
- if (configuration_->sd_acceptance_required(_sender, ANY_PORT)) {
- if (_sender.is_v4()) {
- remote.ip_.address_.v4_ = _sender.to_v4().to_bytes();
- remote.ip_.is_v4_ = true;
- } else {
- remote.ip_.address_.v6_ = _sender.to_v6().to_bytes();
- remote.ip_.is_v4_ = false;
- }
- accept_offers = sd_acceptance_handler_(remote);
- if (!accept_offers && !expired_services) {
- VSOMEIP_WARNING << "service_discovery_impl::" << __func__
- << ": Do not accept offer / subscribe from "
- << std::hex << std::setw(4) << std::setfill('0')
- << _sender.to_string();
- remove_remote_offer_type_by_ip(_sender);
- host_->expire_subscriptions(_sender);
- host_->expire_services(_sender);
- expired_services = true;
- }
+ if (_sender.is_v4()) {
+ remote.ip_.address_.v4_ = _sender.to_v4().to_bytes();
+ remote.ip_.is_v4_ = true;
} else {
- accept_offers = true;
+ remote.ip_.address_.v6_ = _sender.to_v6().to_bytes();
+ remote.ip_.is_v4_ = false;
}
+ accept_state.accept_entries_ = sd_acceptance_handler_(remote);
} else {
- accept_offers = true;
+ accept_state.accept_entries_ = true;
}
- sd_acceptance_queried = true;
}
if ((*iter)->is_service_entry()) {
std::shared_ptr<serviceentry_impl> its_service_entry
@@ -1075,8 +1081,8 @@ service_discovery_impl::on_message(
bool its_unicast_flag = its_message->get_unicast_flag();
process_serviceentry(its_service_entry, its_options,
its_unicast_flag, its_resubscribes,
- received_via_mcast, accept_offers);
- } else if (accept_offers) {
+ received_via_mcast, accept_state);
+ } else {
std::shared_ptr<eventgroupentry_impl> its_eventgroup_entry
= std::dynamic_pointer_cast<eventgroupentry_impl>(*iter);
@@ -1095,7 +1101,8 @@ service_discovery_impl::on_message(
check_stop_subscribe_subscribe(iter, its_end, its_options);
process_eventgroupentry(its_eventgroup_entry, its_options,
its_acknowledgement, _destination,
- is_stop_subscribe_subscribe, force_initial_events);
+ is_stop_subscribe_subscribe, force_initial_events,
+ accept_state);
}
}
@@ -1139,7 +1146,8 @@ service_discovery_impl::process_serviceentry(
const std::vector<std::shared_ptr<option_impl> > &_options,
bool _unicast_flag,
std::vector<std::shared_ptr<message_impl> > &_resubscribes,
- bool _received_via_mcast, bool _accept_offers) {
+ bool _received_via_mcast,
+ const sd_acceptance_state_t& _sd_ac_state) {
// Read service info from entry
entry_type_e its_type = _entry->get_type();
@@ -1221,20 +1229,17 @@ service_discovery_impl::process_serviceentry(
its_major, its_minor, _unicast_flag);
break;
case entry_type_e::OFFER_SERVICE:
- if (_accept_offers) {
process_offerservice_serviceentry(its_service, its_instance,
its_major, its_minor, its_ttl,
its_reliable_address, its_reliable_port,
its_unreliable_address, its_unreliable_port, _resubscribes,
- _received_via_mcast);
- }
+ _received_via_mcast, _sd_ac_state);
break;
case entry_type_e::UNKNOWN:
default:
VSOMEIP_ERROR << __func__ << ": Unsupported service entry type";
}
-
- } else if (_accept_offers) {
+ } else if (!_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_) {
std::shared_ptr<request> its_request = find_request(its_service, its_instance);
if (its_request) {
std::lock_guard<std::mutex> its_lock(requested_mutex_);
@@ -1242,8 +1247,8 @@ service_discovery_impl::process_serviceentry(
its_request->set_sent_counter(std::uint8_t(repetitions_max_ + 1));
}
remove_remote_offer_type(its_service, its_instance,
- (its_reliable_port != ILLEGAL_PORT ?
- its_reliable_address : its_unreliable_address));
+ its_reliable_address, its_reliable_port,
+ its_unreliable_address, its_unreliable_port);
unsubscribe_all(its_service, its_instance);
if (!is_diagnosis_ && !is_suspended_) {
host_->del_routing_info(its_service, its_instance,
@@ -1262,7 +1267,7 @@ service_discovery_impl::process_offerservice_serviceentry(
const boost::asio::ip::address &_unreliable_address,
uint16_t _unreliable_port,
std::vector<std::shared_ptr<message_impl> > &_resubscribes,
- bool _received_via_mcast) {
+ bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state) {
std::shared_ptr < runtime > its_runtime = runtime_.lock();
if (!its_runtime)
return;
@@ -1290,11 +1295,106 @@ service_discovery_impl::process_offerservice_serviceentry(
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "]";
}
- if (update_remote_offer_type(_service,_instance, offer_type,
- _reliable_address, _unreliable_address)) {
+ if (_sd_ac_state.sd_acceptance_required_) {
+
+ auto expire_subscriptions_and_services =
+ [this, &_sd_ac_state](const boost::asio::ip::address& _address,
+ std::uint16_t _port, bool _reliable) {
+ const auto its_port_pair = std::make_pair(_reliable, _port);
+ if (_sd_ac_state.expired_ports_.find(its_port_pair) ==
+ _sd_ac_state.expired_ports_.end()) {
+ VSOMEIP_WARNING << "service_discovery_impl::" << __func__
+ << ": Do not accept offer from "
+ << _address.to_string() << ":"
+ << std::dec << _port << " reliable=" << _reliable;
+ remove_remote_offer_type_by_ip(_address, _port, _reliable);
+ host_->expire_subscriptions(_address, _port, _reliable);
+ host_->expire_services(_address, _port, _reliable);
+ _sd_ac_state.expired_ports_.insert(its_port_pair);
+ }
+ };
+
+ // return if the registered sd_acceptance handler returned false
+ // and for the provided port sd_acceptance is necessary
+ switch (offer_type) {
+ case remote_offer_type_e::UNRELIABLE:
+ if (!_sd_ac_state.accept_entries_
+ && configuration_->is_protected_port(
+ _unreliable_address, _unreliable_port, false)) {
+ expire_subscriptions_and_services(_unreliable_address,
+ _unreliable_port, false);
+ return;
+ }
+ break;
+ case remote_offer_type_e::RELIABLE:
+ if (!_sd_ac_state.accept_entries_
+ && configuration_->is_protected_port(
+ _reliable_address, _reliable_port, true)) {
+ expire_subscriptions_and_services(_reliable_address,
+ _reliable_port, true);
+ return;
+ }
+ break;
+ case remote_offer_type_e::RELIABLE_UNRELIABLE:
+ if (!_sd_ac_state.accept_entries_
+ && (configuration_->is_protected_port(
+ _unreliable_address, _unreliable_port, false)
+ || configuration_->is_protected_port(
+ _reliable_address, _reliable_port, true))) {
+ expire_subscriptions_and_services(_unreliable_address,
+ _unreliable_port, false);
+ expire_subscriptions_and_services(_reliable_address,
+ _reliable_port, true);
+ return;
+ }
+ break;
+ case remote_offer_type_e::UNKNOWN:
+ default:
+ break;
+ }
+ }
+
+ if (update_remote_offer_type(_service, _instance, offer_type,
+ _reliable_address, _reliable_port,
+ _unreliable_address, _unreliable_port)) {
VSOMEIP_WARNING << __func__ << ": Remote offer type changed ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "]";
+
+ // Only update eventgroup reliability type if it was initially unknown
+ auto its_eventgroups = host_->get_subscribed_eventgroups(_service, _instance);
+ for (auto eg : its_eventgroups) {
+ auto its_info = host_->find_eventgroup(
+ _service, _instance, eg);
+ if (its_info) {
+ if (its_info->is_reliability_auto_mode()) {
+ reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN);
+ switch (offer_type) {
+ case remote_offer_type_e::RELIABLE:
+ its_reliability = reliability_type_e::RT_RELIABLE;
+ break;
+ case remote_offer_type_e::UNRELIABLE:
+ its_reliability = reliability_type_e::RT_UNRELIABLE;
+ break;
+ case remote_offer_type_e::RELIABLE_UNRELIABLE:
+ its_reliability = reliability_type_e::RT_BOTH;
+ break;
+ default:
+ ;
+ }
+ if (its_reliability != reliability_type_e::RT_UNKNOWN
+ && its_reliability != its_info->get_reliability()) {
+ VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type changed ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << eg << "]"
+ << " using reliability type: "
+ << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability;
+ its_info->set_reliability(its_reliability);
+ }
+ }
+ }
+ }
}
host_->add_routing_info(_service, _instance,
@@ -1314,8 +1414,6 @@ service_discovery_impl::process_offerservice_serviceentry(
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
if (0 < found_instance->second.size()) {
- const remote_offer_type_e its_offer_type =
- get_remote_offer_type(_service, _instance);
for (const auto& its_eventgroup : found_instance->second) {
auto its_subscription = its_eventgroup.second;
std::shared_ptr<endpoint> its_reliable, its_unreliable;
@@ -1333,8 +1431,12 @@ service_discovery_impl::process_offerservice_serviceentry(
subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED);
}
}
+ const reliability_type_e its_reliability =
+ get_eventgroup_reliability(_service, _instance,
+ its_eventgroup.first, its_subscription);
+
auto its_data = create_eventgroup_entry(_service, _instance,
- its_eventgroup.first, its_subscription, its_offer_type);
+ its_eventgroup.first, its_subscription, its_reliability);
if (its_data.entry_) {
add_entry_data(_resubscribes, its_data);
}
@@ -1443,8 +1545,6 @@ service_discovery_impl::on_endpoint_connected(
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
if (0 < found_instance->second.size()) {
- const remote_offer_type_e its_offer_type =
- get_remote_offer_type(_service, _instance);
for (const auto &its_eventgroup : found_instance->second) {
std::shared_ptr<subscription> its_subscription(its_eventgroup.second);
if (its_subscription) {
@@ -1487,8 +1587,10 @@ service_discovery_impl::on_endpoint_connected(
its_subscription->set_state(its_client,
subscription_state_e::ST_NOT_ACKNOWLEDGED);
+ const reliability_type_e its_reliability_type =
+ get_eventgroup_reliability(_service, _instance, its_eventgroup.first, its_subscription);
auto its_data = create_eventgroup_entry(_service, _instance,
- its_eventgroup.first, its_subscription, its_offer_type);
+ its_eventgroup.first, its_subscription, its_reliability_type);
if (its_data.entry_) {
add_entry_data(its_messages, its_data);
@@ -1571,7 +1673,10 @@ service_discovery_impl::process_eventgroupentry(
const std::vector<std::shared_ptr<option_impl> > &_options,
std::shared_ptr<remote_subscription_ack> &_acknowledgement,
const boost::asio::ip::address &_destination,
- bool _is_stop_subscribe_subscribe, bool _force_initial_events) {
+ bool _is_stop_subscribe_subscribe, bool _force_initial_events,
+ const sd_acceptance_state_t& _sd_ac_state) {
+
+ std::set<client_t> its_clients({0}); // maybe overridden for selectives
auto its_sender = _acknowledgement->get_target_address();
auto its_session = _entry->get_owning_message()->get_session();
@@ -1601,7 +1706,7 @@ service_discovery_impl::process_eventgroupentry(
<< "] session: " << std::hex << std::setw(4) << std::setfill('0')
<< its_session << ", ttl: " << its_ttl;
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
} else {
// We received a subscription [n]ack for an eventgroup that does not exist.
@@ -1617,7 +1722,7 @@ service_discovery_impl::process_eventgroupentry(
<< its_sender.to_string(ec) << " session: "
<< std::hex << std::setw(4) << std::setfill('0') << its_session;
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1630,7 +1735,7 @@ service_discovery_impl::process_eventgroupentry(
<< its_sender.to_string(ec) << " session: "
<< std::hex << std::setw(4) << std::setfill('0') << its_session;
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1644,7 +1749,7 @@ service_discovery_impl::process_eventgroupentry(
if (its_ttl > 0) {
// increase number of required acks by one as number required acks
// is calculated based on the number of referenced options
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1655,7 +1760,7 @@ service_discovery_impl::process_eventgroupentry(
<< its_sender.to_string(ec) << " session: "
<< std::hex << std::setw(4) << std::setfill('0') << its_session;
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1672,7 +1777,7 @@ service_discovery_impl::process_eventgroupentry(
<< std::hex << std::setw(4) << std::setfill('0') << its_session;
if (its_ttl > 0) {
// set to 0 to ensure an answer containing at least this subscribe_nack is sent out
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1697,7 +1802,6 @@ service_discovery_impl::process_eventgroupentry(
boost::asio::ip::address its_second_address;
uint16_t its_second_port(ILLEGAL_PORT);
bool is_second_reliable(false);
- std::set<client_t> its_clients({0}); // maybe overridden for selectives
for (auto i : { 1, 2 }) {
for (auto its_index : _entry->get_options(uint8_t(i))) {
@@ -1718,7 +1822,7 @@ service_discovery_impl::process_eventgroupentry(
<< std::hex << std::setw(4) << std::setfill('0')
<< its_session;
if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type && its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1733,7 +1837,7 @@ service_discovery_impl::process_eventgroupentry(
its_ipv4_option->get_address());
if (!check_layer_four_protocol(its_ipv4_option)) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
return;
}
@@ -1749,7 +1853,7 @@ service_discovery_impl::process_eventgroupentry(
if (is_first_reliable == is_second_reliable
&& its_second_port != ILLEGAL_PORT) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1763,7 +1867,7 @@ service_discovery_impl::process_eventgroupentry(
if (!check_ipv4_address(its_first_address)
|| 0 == its_first_port) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1784,7 +1888,7 @@ service_discovery_impl::process_eventgroupentry(
if (is_second_reliable == is_first_reliable
&& its_first_port != ILLEGAL_PORT) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1798,7 +1902,7 @@ service_discovery_impl::process_eventgroupentry(
if (!check_ipv4_address(its_second_address)
|| 0 == its_second_port) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1829,7 +1933,7 @@ service_discovery_impl::process_eventgroupentry(
its_ipv6_option->get_address());
if (!check_layer_four_protocol(its_ipv6_option)) {
if(its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << "Invalid layer 4 protocol type in IPv6 endpoint option specified! "
@@ -1847,7 +1951,7 @@ service_discovery_impl::process_eventgroupentry(
if (is_first_reliable == is_second_reliable
&& its_second_port != ILLEGAL_PORT) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1867,7 +1971,7 @@ service_discovery_impl::process_eventgroupentry(
if (is_second_reliable == is_first_reliable
&& its_first_port != ILLEGAL_PORT) {
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
}
boost::system::error_code ec;
VSOMEIP_ERROR << __func__
@@ -1983,7 +2087,7 @@ service_discovery_impl::process_eventgroupentry(
<< its_sender.to_string(ec) << " session: "
<< std::hex << std::setw(4) << std::setfill('0') << its_session;
if (its_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients);
return;
}
break;
@@ -1997,7 +2101,7 @@ service_discovery_impl::process_eventgroupentry(
its_first_address, its_first_port, is_first_reliable,
its_second_address, its_second_port, is_second_reliable,
_acknowledgement, _is_stop_subscribe_subscribe,
- _force_initial_events, its_clients, its_info);
+ _force_initial_events, its_clients, _sd_ac_state, its_info);
} else {
if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { //this type is used for ACK and NACK messages
if (its_ttl > 0) {
@@ -2025,6 +2129,7 @@ service_discovery_impl::handle_eventgroup_subscription(
std::shared_ptr<remote_subscription_ack> &_acknowledgement,
bool _is_stop_subscribe_subscribe, bool _force_initial_events,
const std::set<client_t> &_clients,
+ const sd_acceptance_state_t& _sd_ac_state,
const std::shared_ptr<eventgroupinfo>& _info) {
(void)_counter;
(void)_reserved;
@@ -2062,7 +2167,7 @@ service_discovery_impl::handle_eventgroup_subscription(
}
}
if (reliablility_nack && _ttl > 0) {
- insert_subscription_ack(_acknowledgement, _info, 0);
+ insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients);
boost::system::error_code ec;
// TODO: Add sender and session id
VSOMEIP_WARNING << __func__
@@ -2103,13 +2208,13 @@ service_discovery_impl::handle_eventgroup_subscription(
<< (uint32_t) _info->get_major() << "] subscriber: "
<< _first_address.to_string(ec) << ":" << std::dec << _first_port;
if (_ttl > 0) {
- insert_subscription_ack(_acknowledgement, its_info, 0);
+ insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, _clients);
}
return;
} else {
boost::asio::ip::address its_first_address, its_second_address;
- uint16_t its_first_port, its_second_port;
if (ILLEGAL_PORT != _first_port) {
+ uint16_t its_first_port(0);
its_subscriber = endpoint_definition::get(
_first_address, _first_port, _is_first_reliable, _service, _instance);
if (!_is_first_reliable &&
@@ -2121,7 +2226,7 @@ service_discovery_impl::handle_eventgroup_subscription(
its_reliable = its_subscriber;
// check if TCP connection is established by client
if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) {
- insert_subscription_ack(_acknowledgement, _info, 0);
+ insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients);
boost::system::error_code ec;
// TODO: Add sender and session id
VSOMEIP_ERROR << "TCP connection to target1: ["
@@ -2139,6 +2244,7 @@ service_discovery_impl::handle_eventgroup_subscription(
}
if (ILLEGAL_PORT != _second_port) {
+ uint16_t its_second_port(0);
its_subscriber = endpoint_definition::get(
_second_address, _second_port, _is_second_reliable, _service, _instance);
if (!_is_second_reliable &&
@@ -2150,7 +2256,7 @@ service_discovery_impl::handle_eventgroup_subscription(
its_reliable = its_subscriber;
// check if TCP connection is established by client
if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) {
- insert_subscription_ack(_acknowledgement, _info, 0);
+ insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients);
boost::system::error_code ec;
// TODO: Add sender and session id
VSOMEIP_ERROR << "TCP connection to target2 : ["
@@ -2168,6 +2274,26 @@ service_discovery_impl::handle_eventgroup_subscription(
}
}
+ // check if the subscription should be rejected because of sd_acceptance_handling
+ if (_ttl > 0 && _sd_ac_state.sd_acceptance_required_) {
+ bool insert_nack(false);
+ if (_first_port != ILLEGAL_PORT && !_sd_ac_state.accept_entries_
+ && configuration_->is_protected_port(_first_address,
+ _first_port, _is_first_reliable)) {
+ insert_nack = true;
+ }
+ if (!insert_nack && _second_port != ILLEGAL_PORT
+ && !_sd_ac_state.accept_entries_
+ && configuration_->is_protected_port(_second_address,
+ _second_port, _is_second_reliable)) {
+ insert_nack = true;
+ }
+ if (insert_nack) {
+ insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients);
+ return;
+ }
+ }
+
// Create subscription object
auto its_subscription = std::make_shared<remote_subscription>();
its_subscription->set_eventgroupinfo(_info);
@@ -2953,9 +3079,10 @@ service_discovery_impl::last_offer_shorter_half_offer_delay_ago() {
bool
service_discovery_impl::check_source_address(
const boost::asio::ip::address &its_source_address) const {
+
bool is_valid = true;
// Check if source address is same as nodes unicast address
- if(unicast_ == its_source_address) {
+ if (unicast_ == its_source_address) {
VSOMEIP_ERROR << "Source address of message is same as DUT's unicast address! : "
<< its_source_address.to_string();
is_valid = false;
@@ -2965,18 +3092,21 @@ service_discovery_impl::check_source_address(
void
service_discovery_impl::set_diagnosis_mode(const bool _activate) {
+
is_diagnosis_ = _activate;
}
bool
service_discovery_impl::get_diagnosis_mode() {
+
return is_diagnosis_;
}
void
service_discovery_impl::update_remote_subscription(
const std::shared_ptr<remote_subscription> &_subscription) {
- if (!_subscription->is_pending()) {
+
+ if (!_subscription->is_pending() || 0 == _subscription->get_answers()) {
std::shared_ptr<remote_subscription_ack> its_ack;
{
std::lock_guard<std::mutex> its_lock(pending_remote_subscriptions_mutex_);
@@ -2995,13 +3125,15 @@ service_discovery_impl::update_remote_subscription(
void
service_discovery_impl::update_acknowledgement(
const std::shared_ptr<remote_subscription_ack> &_acknowledgement) {
+
if (_acknowledgement->is_complete()
&& !_acknowledgement->is_pending()
&& !_acknowledgement->is_done()) {
+
send_subscription_ack(_acknowledgement);
std::lock_guard<std::mutex> its_lock(pending_remote_subscriptions_mutex_);
- for (const auto& its_subscription : _acknowledgement->get_subscriptions())
+ for (const auto &its_subscription : _acknowledgement->get_subscriptions())
pending_remote_subscriptions_.erase(its_subscription);
}
}
@@ -3241,7 +3373,9 @@ service_discovery_impl::update_remote_offer_type(
service_t _service, instance_t _instance,
remote_offer_type_e _offer_type,
const boost::asio::ip::address &_reliable_address,
- const boost::asio::ip::address &_unreliable_address) {
+ std::uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ std::uint16_t _unreliable_port) {
bool ret(false);
std::lock_guard<std::mutex> its_lock(remote_offer_types_mutex_);
const std::pair<service_t, instance_t> its_si_pair = std::make_pair(_service, _instance);
@@ -3256,13 +3390,18 @@ service_discovery_impl::update_remote_offer_type(
}
switch (_offer_type) {
case remote_offer_type_e::UNRELIABLE:
- remote_offers_by_ip_[_unreliable_address].insert(its_si_pair);
+ remote_offers_by_ip_[_unreliable_address][std::make_pair(false,
+ _unreliable_port)].insert(its_si_pair);
break;
case remote_offer_type_e::RELIABLE:
- remote_offers_by_ip_[_reliable_address].insert(its_si_pair);
+ remote_offers_by_ip_[_reliable_address][std::make_pair(true,
+ _reliable_port)].insert(its_si_pair);
break;
case remote_offer_type_e::RELIABLE_UNRELIABLE:
- remote_offers_by_ip_[_unreliable_address].insert(its_si_pair);
+ remote_offers_by_ip_[_unreliable_address][std::make_pair(false,
+ _unreliable_port)].insert(its_si_pair);
+ remote_offers_by_ip_[_unreliable_address][std::make_pair(true,
+ _reliable_port)].insert(its_si_pair);
break;
case remote_offer_type_e::UNKNOWN:
default:
@@ -3278,35 +3417,83 @@ service_discovery_impl::update_remote_offer_type(
void
service_discovery_impl::remove_remote_offer_type(
service_t _service, instance_t _instance,
- const boost::asio::ip::address &_address) {
+ const boost::asio::ip::address &_reliable_address,
+ std::uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ std::uint16_t _unreliable_port) {
std::lock_guard<std::mutex> its_lock(remote_offer_types_mutex_);
const std::pair<service_t, instance_t> its_si_pair =
std::make_pair(_service, _instance);
remote_offer_types_.erase(its_si_pair);
- auto found_services = remote_offers_by_ip_.find(_address);
- if (found_services != remote_offers_by_ip_.end()) {
- found_services->second.erase(its_si_pair);
+
+ auto delete_from_remote_offers_by_ip = [&](
+ const boost::asio::ip::address& _address, std::uint16_t _port,
+ bool _reliable) {
+ const auto found_address = remote_offers_by_ip_.find(_address);
+ if (found_address != remote_offers_by_ip_.end()) {
+ auto found_port = found_address->second.find(
+ std::make_pair(_reliable, _port));
+ if (found_port != found_address->second.end()) {
+ if (found_port->second.erase(std::make_pair(_service, _instance))) {
+ if (found_port->second.empty()) {
+ found_address->second.erase(found_port);
+ if (found_address->second.empty()) {
+ remote_offers_by_ip_.erase(found_address);
+ }
+ }
+ }
+ }
+ }
+ };
+ if (_reliable_port != ILLEGAL_PORT) {
+ delete_from_remote_offers_by_ip(_reliable_address, _reliable_port,
+ true);
+ }
+ if (_unreliable_port != ILLEGAL_PORT) {
+ delete_from_remote_offers_by_ip(_unreliable_address, _unreliable_port,
+ false);
}
}
void service_discovery_impl::remove_remote_offer_type_by_ip(
const boost::asio::ip::address &_address) {
+ remove_remote_offer_type_by_ip(_address, ANY_PORT, false);
+}
+
+void service_discovery_impl::remove_remote_offer_type_by_ip(
+ const boost::asio::ip::address &_address, std::uint16_t _port, bool _reliable) {
std::lock_guard<std::mutex> its_lock(remote_offer_types_mutex_);
- auto found_services = remote_offers_by_ip_.find(_address);
- if (found_services != remote_offers_by_ip_.end()) {
- for (const auto& si : found_services->second) {
- remote_offer_types_.erase(si);
+ const auto found_address = remote_offers_by_ip_.find(_address);
+ if (found_address != remote_offers_by_ip_.end()) {
+ if (_port == ANY_PORT) {
+ for (const auto& port : found_address->second) {
+ for (const auto& si : port.second) {
+ remote_offer_types_.erase(si);
+ }
+ }
+ remote_offers_by_ip_.erase(_address);
+ } else {
+ const auto its_port_reliability = std::make_pair(_reliable, _port);
+ const auto found_port = found_address->second.find(its_port_reliability);
+ if (found_port != found_address->second.end()) {
+ for (const auto& si : found_port->second) {
+ remote_offer_types_.erase(si);
+ }
+ found_address->second.erase(found_port);
+ if (found_address->second.empty()) {
+ remote_offers_by_ip_.erase(found_address);
+ }
+ }
}
}
- remote_offers_by_ip_.erase(_address);
}
std::shared_ptr<subscription>
service_discovery_impl::create_subscription(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl,
const std::shared_ptr<endpoint> &_reliable,
- const std::shared_ptr<endpoint> &_unreliable) {
+ const std::shared_ptr<endpoint> &_unreliable,
+ const std::shared_ptr<eventgroupinfo> &_info) {
auto its_subscription = std::make_shared<subscription>();
its_subscription->set_major(_major);
its_subscription->set_ttl(_ttl);
@@ -3322,10 +3509,9 @@ service_discovery_impl::create_subscription(
}
// check whether the eventgroup is selective
- auto its_eventgroup = host_->find_eventgroup(_service, _instance, _eventgroup);
- if (its_eventgroup) {
- its_subscription->set_selective(its_eventgroup->is_selective());
- }
+ its_subscription->set_selective(_info->is_selective());
+
+ its_subscription->set_eventgroupinfo(_info);
return its_subscription;
}
@@ -3333,33 +3519,70 @@ service_discovery_impl::create_subscription(
void
service_discovery_impl::send_subscription_ack(
const std::shared_ptr<remote_subscription_ack> &_acknowledgement) {
+
if (_acknowledgement->is_done())
return;
_acknowledgement->done();
- std::uint32_t its_answers(1);
+ std::uint32_t its_max_answers(1); // Must be 1 as "_acknowledgement" not
+ // necessarily contains subscriptions
+ bool do_not_answer(false);
+ std::shared_ptr<remote_subscription> its_parent;
// Find highest number of necessary answers
for (const auto& its_subscription : _acknowledgement->get_subscriptions()) {
- if (its_subscription->get_answers() > its_answers)
- its_answers = its_subscription->get_answers();
+ auto its_answers = its_subscription->get_answers();
+ if (its_answers > its_max_answers) {
+ its_max_answers = its_answers;
+ } else if (its_answers == 0) {
+ do_not_answer = true;
+ its_parent = its_subscription->get_parent();
+ }
+ }
+
+ if (do_not_answer) {
+ if (its_parent) {
+ std::lock_guard<std::mutex> its_lock(pending_remote_subscriptions_mutex_);
+ auto its_parent_ack = pending_remote_subscriptions_[its_parent];
+ if (its_parent_ack) {
+ for (const auto &its_subscription : its_parent_ack->get_subscriptions()) {
+ if (its_subscription != its_parent)
+ its_subscription->set_answers(its_subscription->get_answers() + 1);
+ }
+ }
+ }
+ return;
}
// send messages
- for (std::uint32_t i = 0; i < its_answers; i++) {
- for (const auto& its_subscription : _acknowledgement->get_subscriptions()) {
+ for (std::uint32_t i = 0; i < its_max_answers; i++) {
+ for (const auto &its_subscription : _acknowledgement->get_subscriptions()) {
if (i < its_subscription->get_answers()) {
if (its_subscription->get_ttl() > 0) {
auto its_info = its_subscription->get_eventgroupinfo();
if (its_info) {
+ std::set<client_t> its_acked;
+ std::set<client_t> its_nacked;
for (const auto& its_client : its_subscription->get_clients()) {
- auto its_ttl = (its_subscription->get_client_state(its_client)
- == remote_subscription_state_e::SUBSCRIPTION_ACKED ?
- its_subscription->get_ttl() : 0);
+ if (its_subscription->get_client_state(its_client)
+ == remote_subscription_state_e::SUBSCRIPTION_ACKED) {
+ its_acked.insert(its_client);
+ } else {
+ its_nacked.insert(its_client);
+ }
+ }
- insert_subscription_ack(_acknowledgement, its_info, its_ttl,
- its_subscription->get_subscriber(), its_client);
+ if (0 < its_acked.size()) {
+ insert_subscription_ack(_acknowledgement, its_info,
+ its_subscription->get_ttl(),
+ its_subscription->get_subscriber(), its_acked);
+ }
+
+ if (0 < its_nacked.size()) {
+ insert_subscription_ack(_acknowledgement, its_info,
+ 0,
+ its_subscription->get_subscriber(), its_nacked);
}
}
}
@@ -3371,6 +3594,8 @@ service_discovery_impl::send_subscription_ack(
update_subscription_expiration_timer(its_messages);
}
+ std::this_thread::yield();
+
// We might need to send initial events
for (const auto &its_subscription : _acknowledgement->get_subscriptions()) {
// Assumption: We do _NOT_ need to check whether this is a child
@@ -3430,5 +3655,58 @@ service_discovery_impl::register_reboot_notification_handler(
reboot_notification_handler_ = _handler;
}
+reliability_type_e service_discovery_impl::get_eventgroup_reliability(
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ const std::shared_ptr<subscription>& _subscription) {
+ reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN;
+ auto its_info = _subscription->get_eventgroupinfo().lock();
+ if (its_info) {
+ its_reliability = its_info->get_reliability();
+ if (its_reliability == reliability_type_e::RT_UNKNOWN
+ && its_info->is_reliability_auto_mode()) {
+ // fallback: determine how service is offered
+ // and update reliability type of eventgroup
+ switch (get_remote_offer_type(_service, _instance)) {
+ case remote_offer_type_e::RELIABLE:
+ its_reliability = reliability_type_e::RT_RELIABLE;
+ break;
+ case remote_offer_type_e::UNRELIABLE:
+ its_reliability = reliability_type_e::RT_UNRELIABLE;
+ break;
+ case remote_offer_type_e::RELIABLE_UNRELIABLE:
+ its_reliability = reliability_type_e::RT_BOTH;
+ break;
+ default:
+ ;
+ }
+ VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine eventgroup reliability type for ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"
+ << " using reliability type: "
+ << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability;
+ its_info->set_reliability(its_reliability);
+ }
+ } else {
+ VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't lock eventgroupinfo ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] ";
+ auto its_eg_info = host_->find_eventgroup(_service, _instance, _eventgroup);
+ if (its_eg_info) {
+ _subscription->set_eventgroupinfo(its_eg_info);
+ its_reliability = its_eg_info->get_reliability();
+ }
+ }
+
+ if (its_reliability == reliability_type_e::RT_UNKNOWN) {
+ VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type is unknown ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]";
+ }
+ return its_reliability;
+}
+
} // namespace sd
} // namespace vsomeip_v3
diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp
index 03a55d7..8869f50 100644
--- a/implementation/service_discovery/src/subscription.cpp
+++ b/implementation/service_discovery/src/subscription.cpp
@@ -116,5 +116,13 @@ bool subscription::has_client(const client_t _client) const {
return (clients_.find(_client) != clients_.end());
}
+void subscription::set_eventgroupinfo(
+ const std::shared_ptr<eventgroupinfo> _info) {
+ eg_info_ = _info;
+}
+std::weak_ptr<eventgroupinfo> subscription::get_eventgroupinfo() const {
+ return eg_info_;
+}
+
} // namespace sd
} // namespace vsomeip_v3
diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp
index 4147463..7f05e95 100644
--- a/implementation/utility/src/utility.cpp
+++ b/implementation/utility/src/utility.cpp
@@ -75,8 +75,7 @@ bool utility::is_routing_manager(const std::shared_ptr<configuration> &_config)
its_lockfile.append(its_network.begin(), its_network.end());
lock_handle__ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
if (lock_handle__ == INVALID_HANDLE_VALUE) {
- VSOMEIP_ERROR << __func__ << ": CreateFileW failed: "
- << its_lockfile << " " << std::hex << GetLastError();
+ VSOMEIP_ERROR << __func__ << ": CreateFileW failed: " << std::hex << GetLastError();
}
} else {
VSOMEIP_ERROR << __func__ << ": Could not get temp folder: "
@@ -87,6 +86,12 @@ bool utility::is_routing_manager(const std::shared_ptr<configuration> &_config)
return (lock_handle__ != INVALID_HANDLE_VALUE);
#else
std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network());
+#ifdef __ANDROID__ // NDK
+ const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH);
+ if (nullptr != env_base_path) {
+ its_base_path = {env_base_path + _config->get_network()};
+ }
+#endif
std::string its_lockfile(its_base_path + ".lck");
int its_lock_ctrl(-1);
@@ -123,7 +128,7 @@ void utility::remove_lockfile(const std::shared_ptr<configuration> &_config) {
its_lockfile.append(its_network.begin(), its_network.end());
if (DeleteFileW(its_lockfile.c_str()) == 0) {
VSOMEIP_ERROR << __func__ << ": DeleteFileW failed: "
- << its_lockfile << ": " << std::hex << GetLastError();
+ << std::hex << GetLastError();
}
} else {
@@ -133,6 +138,12 @@ void utility::remove_lockfile(const std::shared_ptr<configuration> &_config) {
}
#else
std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network());
+#ifdef __ANDROID__ // NDK
+ const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH);
+ if (nullptr != env_base_path) {
+ its_base_path = {env_base_path + _config->get_network()};
+ }
+#endif
std::string its_lockfile(its_base_path + ".lck");
if (lock_fd__ != -1) {
@@ -174,7 +185,17 @@ bool utility::is_folder(const std::string &_path) {
const std::string utility::get_base_path(
const std::shared_ptr<configuration> &_config) {
+#ifdef __ANDROID__ // NDK
+ const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH);
+ if (nullptr != env_base_path) {
+ std::string its_base_path(env_base_path + _config->get_network());
+ return std::string(env_base_path + _config->get_network() + "-");
+ } else {
+ return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-");
+ }
+#else
return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-");
+#endif
}
client_t