summaryrefslogtreecommitdiff
path: root/implementation/routing
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/routing')
-rw-r--r--implementation/routing/include/event.hpp83
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp123
-rw-r--r--implementation/routing/include/function_types.hpp19
-rw-r--r--implementation/routing/include/remote_subscription.hpp129
-rw-r--r--implementation/routing/include/routing_host.hpp44
-rw-r--r--implementation/routing/include/routing_manager.hpp61
-rw-r--r--implementation/routing/include/routing_manager_adapter.hpp10
-rw-r--r--implementation/routing/include/routing_manager_base.hpp191
-rw-r--r--implementation/routing/include/routing_manager_host.hpp22
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp360
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp133
-rw-r--r--implementation/routing/include/routing_manager_stub.hpp54
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp60
-rw-r--r--implementation/routing/include/serviceinfo.hpp21
-rw-r--r--implementation/routing/include/types.hpp94
-rw-r--r--implementation/routing/src/event.cpp151
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp486
-rw-r--r--implementation/routing/src/remote_subscription.cpp315
-rw-r--r--implementation/routing/src/routing_manager_base.cpp472
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp3714
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp756
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp561
-rw-r--r--implementation/routing/src/serviceinfo.cpp24
23 files changed, 3696 insertions, 4187 deletions
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index 668bbf4..684a49b 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -3,9 +3,10 @@
// 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_EVENT_IMPL_HPP
-#define VSOMEIP_EVENT_IMPL_HPP
+#ifndef VSOMEIP_V3_EVENT_IMPL_HPP_
+#define VSOMEIP_V3_EVENT_IMPL_HPP_
+#include <list>
#include <map>
#include <memory>
#include <mutex>
@@ -20,7 +21,13 @@
#include <vsomeip/function_types.hpp>
#include <vsomeip/payload.hpp>
-namespace vsomeip {
+#ifdef ANDROID
+#include "../../configuration/include/internal_android.hpp"
+#else
+#include "../../configuration/include/internal.hpp"
+#endif // ANDROID
+
+namespace vsomeip_v3 {
class endpoint;
class endpoint_definition;
@@ -28,7 +35,8 @@ class message;
class payload;
class routing_manager;
-class event: public std::enable_shared_from_this<event> {
+class event
+ : public std::enable_shared_from_this<event> {
public:
event(routing_manager *_routing, bool _is_shadow = false);
@@ -47,21 +55,25 @@ public:
const std::shared_ptr<payload> get_payload() const;
void set_payload(const std::shared_ptr<payload> &_payload,
- const client_t _client, bool _force, bool _flush);
+ const client_t _client, bool _force);
void set_payload(const std::shared_ptr<payload> &_payload,
- const std::shared_ptr<endpoint_definition> _target,
- bool _force, bool _flush);
+ const client_t _client,
+ const std::shared_ptr<endpoint_definition>& _target, bool _force);
bool set_payload_dont_notify(const std::shared_ptr<payload> &_payload);
+ bool set_payload_notify_pending(const std::shared_ptr<payload> &_payload);
- void set_payload(const std::shared_ptr<payload> &_payload,
- bool _force, bool _flush);
+ void set_payload(const std::shared_ptr<payload> &_payload, bool _force);
void unset_payload(bool _force = false);
- bool is_field() const;
- void set_field(bool _is_field);
+ event_type_e get_type() const;
+ void set_type(const event_type_e _type);
+
+ reliability_type_e get_reliability() const;
+ void set_reliability(const reliability_type_e _reliability);
+ bool is_field() const;
bool is_provided() const;
void set_provided(bool _is_provided);
@@ -75,25 +87,30 @@ public:
void set_update_on_change(bool _is_active);
// SIP_RPC_359 (epsilon change)
- void set_epsilon_change_function(const epsilon_change_func_t &_epsilon_change_func);
+ void set_epsilon_change_function(
+ const epsilon_change_func_t &_epsilon_change_func);
const std::set<eventgroup_t> get_eventgroups() const;
std::set<eventgroup_t> get_eventgroups(client_t _client) const;
void add_eventgroup(eventgroup_t _eventgroup);
void set_eventgroups(const std::set<eventgroup_t> &_eventgroups);
- void notify_one(const std::shared_ptr<endpoint_definition> &_target, bool _flush);
- void notify_one(client_t _client, bool _flush);
+ void notify_one(client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target);
+ void notify_one(client_t _client);
+
bool add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _force);
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);
void clear_subscribers();
void add_ref(client_t _client, bool _is_provided);
void remove_ref(client_t _client, bool _is_provided);
bool has_ref();
+ bool has_ref(client_t _client, bool _is_provided);
bool is_shadow() const;
void set_shadow(bool _shadow);
@@ -101,40 +118,36 @@ public:
bool is_cache_placeholder() const;
void set_cache_placeholder(bool _is_cache_place_holder);
- bool has_ref(client_t _client, bool _is_provided);
-
- std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
-
bool is_subscribed(client_t _client);
- bool is_reliable() const;
- void set_reliable(bool _is_reliable);
-
- bool get_remote_notification_pending();
- void set_remote_notification_pending(bool _value);
+ void remove_pending(const std::shared_ptr<endpoint_definition> &_target);
private:
void update_cbk(boost::system::error_code const &_error);
- void notify(bool _flush);
- void notify(client_t _client, const std::shared_ptr<endpoint_definition> &_target);
+ void notify();
+ void notify(client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target);
void start_cycle();
void stop_cycle();
- bool compare(const std::shared_ptr<payload> &_lhs, const std::shared_ptr<payload> &_rhs) const;
+ bool compare(const std::shared_ptr<payload> &_lhs,
+ const std::shared_ptr<payload> &_rhs) const;
- bool set_payload_helper(const std::shared_ptr<payload> &_payload, bool _force);
+ bool set_payload_helper(const std::shared_ptr<payload> &_payload,
+ bool _force);
void reset_payload(const std::shared_ptr<payload> &_payload);
- void notify_one_unlocked(const std::shared_ptr<endpoint_definition> &_target, bool _flush);
- void notify_one_unlocked(client_t _client, bool _flush);
+ void notify_one_unlocked(client_t _client);
+ void notify_one_unlocked(client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target);
private:
routing_manager *routing_;
mutable std::mutex mutex_;
std::shared_ptr<message> message_;
- std::atomic<bool> is_field_;
+ std::atomic<event_type_e> type_;
boost::asio::steady_timer cycle_timer_;
std::chrono::milliseconds cycle_;
@@ -143,7 +156,7 @@ private:
std::atomic<bool> is_updating_on_change_;
mutable std::mutex eventgroups_mutex_;
- std::map<eventgroup_t, std::set<client_t>> eventgroups_;
+ std::map<eventgroup_t, std::set<client_t> > eventgroups_;
std::atomic<bool> is_set_;
std::atomic<bool> is_provided_;
@@ -156,11 +169,11 @@ private:
epsilon_change_func_t epsilon_change_func_;
- std::atomic<bool> is_reliable_;
+ std::atomic<reliability_type_e> reliability_;
- std::atomic<bool> remote_notification_pending_;
+ std::set<std::shared_ptr<endpoint_definition> > pending_;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_EVENT_IMPL_HPP
+#endif // VSOMEIP_V3_EVENT_IMPL_HPP_
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index d6244b5..65f7e89 100644
--- a/implementation/routing/include/eventgroupinfo.hpp
+++ b/implementation/routing/include/eventgroupinfo.hpp
@@ -3,48 +3,62 @@
// 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_EVENTGROUPINFO_HPP
-#define VSOMEIP_EVENTGROUPINFO_HPP
+#ifndef VSOMEIP_V3_EVENTGROUPINFO_HPP_
+#define VSOMEIP_V3_EVENTGROUPINFO_HPP_
+#include <atomic>
#include <chrono>
#include <list>
#include <memory>
-#include <set>
#include <mutex>
-#include <atomic>
+#include <set>
+#include <vector>
#include <boost/asio/ip/address.hpp>
#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
+#include "remote_subscription.hpp"
#include "types.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
class endpoint_definition;
class event;
class eventgroupinfo {
public:
- struct target_t {
- std::shared_ptr<endpoint_definition> endpoint_;
+ struct subscription_t {
+ std::shared_ptr<remote_subscription> subscription_;
std::chrono::steady_clock::time_point expiration_;
- bool operator==(const target_t &_other) const {
- return (endpoint_ == _other.endpoint_);
+ bool operator==(const subscription_t &_other) const {
+ return (subscription_ == _other.subscription_);
}
};
VSOMEIP_EXPORT eventgroupinfo();
- VSOMEIP_EXPORT eventgroupinfo(major_version_t _major, ttl_t _ttl);
+ VSOMEIP_EXPORT eventgroupinfo(
+ const service_t _service, const service_t _instance,
+ const eventgroup_t _eventgroup, const major_version_t _major,
+ const ttl_t _ttl);
VSOMEIP_EXPORT ~eventgroupinfo();
+ VSOMEIP_EXPORT service_t get_service() const;
+ VSOMEIP_EXPORT void set_service(const service_t _service);
+
+ VSOMEIP_EXPORT instance_t get_instance() const;
+ VSOMEIP_EXPORT void set_instance(const instance_t _instance);
+
+ VSOMEIP_EXPORT eventgroup_t get_eventgroup() const;
+ VSOMEIP_EXPORT void set_eventgroup(const eventgroup_t _eventgroup);
+
VSOMEIP_EXPORT major_version_t get_major() const;
- VSOMEIP_EXPORT void set_major(major_version_t _major);
+ VSOMEIP_EXPORT void set_major(const major_version_t _major);
VSOMEIP_EXPORT ttl_t get_ttl() const;
- VSOMEIP_EXPORT void set_ttl(ttl_t _ttl);
+ VSOMEIP_EXPORT void set_ttl(const ttl_t _ttl);
VSOMEIP_EXPORT bool is_multicast() const;
VSOMEIP_EXPORT bool get_multicast(boost::asio::ip::address &_address,
@@ -54,39 +68,48 @@ public:
VSOMEIP_EXPORT bool is_sending_multicast() const;
VSOMEIP_EXPORT const std::set<std::shared_ptr<event> > get_events() const;
- VSOMEIP_EXPORT void add_event(std::shared_ptr<event> _event);
- VSOMEIP_EXPORT void remove_event(std::shared_ptr<event> _event);
- VSOMEIP_EXPORT void get_reliability(bool& _has_reliable, bool& _has_unreliable) const;
-
- VSOMEIP_EXPORT const std::list<target_t> get_targets() const;
- VSOMEIP_EXPORT uint32_t get_unreliable_target_count() const;
-
- VSOMEIP_EXPORT bool add_target(const target_t &_target);
- VSOMEIP_EXPORT bool add_target(const target_t &_target, const target_t &_subscriber);
- VSOMEIP_EXPORT bool update_target(
- const std::shared_ptr<endpoint_definition> &_target,
- const std::chrono::steady_clock::time_point &_expiration);
- VSOMEIP_EXPORT bool remove_target(
- const std::shared_ptr<endpoint_definition> &_target);
- VSOMEIP_EXPORT void clear_targets();
-
- VSOMEIP_EXPORT void add_multicast_target(const target_t &_multicast_target);
- VSOMEIP_EXPORT void clear_multicast_targets();
- VSOMEIP_EXPORT const std::list<target_t> get_multicast_targets() const;
+ 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 uint8_t get_threshold() const;
- VSOMEIP_EXPORT void set_threshold(uint8_t _threshold);
+ VSOMEIP_EXPORT std::set<std::shared_ptr<remote_subscription>>
+ get_remote_subscriptions() const;
+
+ std::shared_ptr<remote_subscription> get_remote_subscription(
+ const remote_subscription_id_t _id);
+
+ bool update_remote_subscription(
+ const std::shared_ptr<remote_subscription> &_subscription,
+ const std::chrono::steady_clock::time_point &_expiration,
+ std::set<client_t> &_changed, remote_subscription_id_t &_id,
+ const bool _is_subscribe);
+
+ remote_subscription_id_t add_remote_subscription(
+ const std::shared_ptr<remote_subscription> &_subscription);
- VSOMEIP_EXPORT std::unique_lock<std::mutex> get_subscription_lock();
+ VSOMEIP_EXPORT void remove_remote_subscription(
+ const remote_subscription_id_t _id);
- VSOMEIP_EXPORT pending_subscription_id_t add_pending_subscription(
- pending_subscription_t _pending_subscription);
+ VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
+ get_unicast_targets() const;
+ VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
+ get_multicast_targets() const;
- VSOMEIP_EXPORT std::vector<pending_subscription_t> remove_pending_subscription(
- pending_subscription_id_t _subscription_id);
+ VSOMEIP_EXPORT uint8_t get_threshold() const;
+ VSOMEIP_EXPORT void set_threshold(uint8_t _threshold);
- VSOMEIP_EXPORT void clear_pending_subscriptions();
+ VSOMEIP_EXPORT bool is_selective() const;
+
+ VSOMEIP_EXPORT void send_initial_events(
+ const std::shared_ptr<endpoint_definition> &_reliable,
+ const std::shared_ptr<endpoint_definition> &_unreliable) const;
private:
+ void update_id();
+ uint32_t get_unreliable_target_count() const;
+
+ std::atomic<service_t> service_;
+ std::atomic<instance_t> instance_;
+ std::atomic<eventgroup_t> eventgroup_;
std::atomic<major_version_t> major_;
std::atomic<ttl_t> ttl_;
@@ -96,24 +119,18 @@ private:
mutable std::mutex events_mutex_;
std::set<std::shared_ptr<event> > events_;
- mutable std::mutex targets_mutex_;
- std::list<target_t> targets_;
- mutable std::mutex multicast_targets_mutex_;
- std::list<target_t> multicast_targets_;
std::atomic<uint8_t> threshold_;
- std::mutex subscription_mutex_;
- std::atomic<bool> has_reliable_;
- std::atomic<bool> has_unreliable_;
+ mutable std::mutex subscriptions_mutex_;
+ std::map<remote_subscription_id_t,
+ std::shared_ptr<remote_subscription>
+ > subscriptions_;
+ remote_subscription_id_t id_;
- std::mutex pending_subscriptions_mutex_;
- std::map<pending_subscription_id_t, pending_subscription_t> pending_subscriptions_;
- std::map<std::tuple<boost::asio::ip::address, std::uint16_t, bool>,
- std::vector<pending_subscription_id_t>> pending_subscriptions_by_remote_;
- pending_subscription_id_t subscription_id_;
+ std::atomic<reliability_type_e> reliability_;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_EVENTGROUPINFO_HPP
+#endif // VSOMEIP_V3_EVENTGROUPINFO_HPP_
diff --git a/implementation/routing/include/function_types.hpp b/implementation/routing/include/function_types.hpp
new file mode 100644
index 0000000..3f89c08
--- /dev/null
+++ b/implementation/routing/include/function_types.hpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 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_ROUTING_FUNCTION_TYPES_HPP_
+#define VSOMEIP_V3_ROUTING_FUNCTION_TYPES_HPP_
+
+namespace vsomeip_v3 {
+
+class remote_subscription;
+
+typedef std::function<
+ void (const std::shared_ptr<remote_subscription> &_subscription)
+> remote_subscription_callback_t;
+
+} // namespace vsomeip_v3
+
+#endif // VSOMEIP_V3_ROUTING_FUNCTION_TYPES_HPP_
diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp
new file mode 100644
index 0000000..00f2b57
--- /dev/null
+++ b/implementation/routing/include/remote_subscription.hpp
@@ -0,0 +1,129 @@
+// Copyright (C) 2018 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_REMOTE_SUBSCRIPTION_HPP_
+#define VSOMEIP_V3_REMOTE_SUBSCRIPTION_HPP_
+
+#include <atomic>
+#include <map>
+#include <mutex>
+#include <set>
+
+#include <vsomeip/primitive_types.hpp>
+
+#include "../../endpoints/include/endpoint_definition.hpp"
+#include "types.hpp"
+#include <vsomeip/export.hpp>
+
+
+namespace vsomeip_v3 {
+
+class eventgroupinfo;
+
+const remote_subscription_id_t PENDING_SUBSCRIPTION_ID(0);
+
+class remote_subscription {
+public:
+ VSOMEIP_EXPORT remote_subscription();
+ VSOMEIP_EXPORT ~remote_subscription();
+
+ bool operator==(const remote_subscription &_other) const;
+ bool equals(const std::shared_ptr<remote_subscription> &_other) const;
+
+ VSOMEIP_EXPORT void reset(const std::set<client_t> &_clients);
+
+ VSOMEIP_EXPORT bool is_initial() const;
+ VSOMEIP_EXPORT void set_initial(const bool _is_initial);
+
+ VSOMEIP_EXPORT bool force_initial_events() const;
+ VSOMEIP_EXPORT void set_force_initial_events(const bool _force_initial_events);
+
+ remote_subscription_id_t get_id() const;
+ void set_id(const remote_subscription_id_t _id);
+
+ 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;
+ VSOMEIP_EXPORT void set_eventgroupinfo(const std::shared_ptr<eventgroupinfo> &_info);
+
+ VSOMEIP_EXPORT ttl_t get_ttl() const;
+ VSOMEIP_EXPORT void set_ttl(const ttl_t _ttl);
+
+ uint16_t get_reserved() const;
+ void set_reserved(const uint16_t _reserved);
+
+ uint8_t get_counter() const;
+ void set_counter(uint8_t _counter);
+
+ VSOMEIP_EXPORT std::set<client_t> get_clients() const;
+ bool has_client() const;
+ bool has_client(const client_t _client) const;
+ void remove_client(const client_t _client);
+
+ VSOMEIP_EXPORT remote_subscription_state_e get_client_state(const client_t _client) const;
+ void set_client_state(const client_t _client,
+ remote_subscription_state_e _state);
+ void set_all_client_states(remote_subscription_state_e _state);
+
+ std::chrono::steady_clock::time_point get_expiration(const client_t _client) const;
+
+ VSOMEIP_EXPORT std::shared_ptr<endpoint_definition> get_subscriber() const;
+ VSOMEIP_EXPORT void set_subscriber(const std::shared_ptr<endpoint_definition> &_subscriber);
+
+ VSOMEIP_EXPORT std::shared_ptr<endpoint_definition> get_reliable() const;
+ VSOMEIP_EXPORT void set_reliable(const std::shared_ptr<endpoint_definition> &_reliable);
+
+ VSOMEIP_EXPORT std::shared_ptr<endpoint_definition> get_unreliable() const;
+ VSOMEIP_EXPORT void set_unreliable(const std::shared_ptr<endpoint_definition> &_unreliable);
+
+ VSOMEIP_EXPORT bool is_pending() const;
+ bool is_acknowledged() const;
+
+ std::set<client_t> update(const std::set<client_t> &_clients,
+ const std::chrono::steady_clock::time_point &_timepoint,
+ const bool _is_subscribe);
+
+ VSOMEIP_EXPORT std::uint32_t get_answers() const;
+ void set_answers(const std::uint32_t _answers);
+
+private:
+ std::atomic<remote_subscription_id_t> id_;
+ std::atomic<bool> is_initial_;
+ std::atomic<bool> force_initial_events_;
+ std::weak_ptr<remote_subscription> parent_;
+
+ std::weak_ptr<eventgroupinfo> eventgroupinfo_;
+
+ major_version_t major_;
+ ttl_t ttl_;
+ std::uint16_t reserved_;
+ std::uint8_t counter_;
+
+ std::map<client_t,
+ std::pair<remote_subscription_state_e,
+ std::chrono::steady_clock::time_point
+ >
+ > clients_;
+
+ // The endpoint that sent(!) the subscription
+ std::shared_ptr<endpoint_definition> subscriber_;
+
+ // The endpoints defined by the endpoint options
+ std::shared_ptr<endpoint_definition> reliable_;
+ std::shared_ptr<endpoint_definition> unreliable_;
+
+ // Number of acknowledgements that must be sent
+ // for the subscriptions. This is usally 1, but
+ // may be larger if a matching subscription arrived
+ // before the subscription could be acknowledged
+ std::uint32_t answers_;
+
+ mutable std::mutex mutex_;
+};
+
+} // namespace vsomeip_v3
+
+#endif // VSOMEIP_V3_REMOTE_SUBSCRIPTION_HPP_
diff --git a/implementation/routing/include/routing_host.hpp b/implementation/routing/include/routing_host.hpp
new file mode 100644
index 0000000..337e4a7
--- /dev/null
+++ b/implementation/routing/include/routing_host.hpp
@@ -0,0 +1,44 @@
+// 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_ROUTING_HOST_
+#define VSOMEIP_V3_ROUTING_HOST_
+
+#include <memory>
+
+#include <boost/asio/ip/address.hpp>
+
+#include <vsomeip/primitive_types.hpp>
+
+#ifdef ANDROID
+#include "../../configuration/include/internal_android.hpp"
+#else
+#include "../../configuration/include/internal.hpp"
+#endif // ANDROID
+
+namespace vsomeip_v3 {
+
+class endpoint;
+
+class routing_host {
+public:
+ virtual ~routing_host() = default;
+
+ virtual void on_message(const byte_t *_data, length_t _length,
+ endpoint *_receiver,
+ const boost::asio::ip::address &_destination =
+ boost::asio::ip::address(),
+ client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
+ credentials_t _credentials = {ANY_UID, ANY_GID},
+ const boost::asio::ip::address &_remote_address =
+ boost::asio::ip::address(),
+ std::uint16_t _remote_port = 0) = 0;
+
+ virtual client_t get_client() const = 0;
+};
+
+} // namespace vsomeip_v3
+
+#endif // VSOMEIP_V3_ROUTING_HOST_
diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp
index 9ab09f4..fa0e675 100644
--- a/implementation/routing/include/routing_manager.hpp
+++ b/implementation/routing/include/routing_manager.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_MANAGER
-#define VSOMEIP_ROUTING_MANAGER
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_
+#define VSOMEIP_V3_ROUTING_MANAGER_
#include <memory>
#include <set>
@@ -17,12 +17,13 @@
#include <vsomeip/handler.hpp>
#include "types.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
class endpoint;
class endpoint_definition;
class event;
class payload;
+class security;
class routing_manager {
public:
@@ -31,6 +32,8 @@ public:
virtual boost::asio::io_service & get_io() = 0;
virtual client_t get_client() const = 0;
+ virtual void set_client(const client_t &_client) = 0;
+ virtual session_t get_session() = 0;
virtual void init() = 0;
virtual void start() = 0;
@@ -46,38 +49,41 @@ public:
virtual void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy) = 0;
+ minor_version_t _minor) = 0;
virtual void release_service(client_t _client, service_t _service,
instance_t _instance) = 0;
- virtual void subscribe(client_t _client, service_t _service,
+ virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type) = 0;
+ major_version_t _major, event_t _event) = 0;
- virtual void unsubscribe(client_t _client, service_t _service,
+ virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0;
- virtual bool send(client_t _client, std::shared_ptr<message> _message,
- bool _flush) = 0;
+ virtual bool send(client_t _client, std::shared_ptr<message> _message) = 0;
virtual bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable,
+ instance_t _instance, bool _reliable,
client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
- bool _is_valid_crc = true, bool _sent_from_remote = false) = 0;
+ credentials_t _credentials = {ANY_UID, ANY_GID},
+ uint8_t _status_check = 0, bool _sent_from_remote = false) = 0;
- virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message>, bool _flush) = 0;
+ virtual bool send_to(const client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message>) = 0;
virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush) = 0;
-
- virtual void register_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
- const std::set<eventgroup_t> &_eventgroups, bool _is_field,
+ const byte_t *_data, uint32_t _size, instance_t _instance) = 0;
+
+ virtual void register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups,
+ const event_type_e _type,
+ reliability_type_e _reliability,
std::chrono::milliseconds _cycle, bool _change_resets_cycle,
+ bool _update_on_change,
epsilon_change_func_t _epsilon_change_func,
bool _is_provided, bool _is_shadow = false,
bool _is_cache_placeholder = false) = 0;
@@ -93,20 +99,21 @@ public:
virtual void notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- bool _force, bool _flush) = 0;
+ bool _force) = 0;
virtual void notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- client_t _client, bool _force, bool _flush, bool _remote_subscriber) = 0;
-
- virtual void on_identify_response(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) = 0;
+ client_t _client, bool _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , bool _remote_subscriber
+#endif
+ ) = 0;
virtual void set_routing_state(routing_state_e _routing_state) = 0;
virtual void send_get_offered_services_info(client_t _client, offer_type_e _offer_type) = 0;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif
+#endif // VSOMEIP_V3_ROUTING_MANAGER_
diff --git a/implementation/routing/include/routing_manager_adapter.hpp b/implementation/routing/include/routing_manager_adapter.hpp
index 3d81120..a2195ee 100644
--- a/implementation/routing/include/routing_manager_adapter.hpp
+++ b/implementation/routing/include/routing_manager_adapter.hpp
@@ -3,10 +3,10 @@
// 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_ROUTING_MANAGER_ADAPTER
-#define VSOMEIP_ROUTING_MANAGER_ADAPTER
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_ADAPTER_
+#define VSOMEIP_V3_ROUTING_MANAGER_ADAPTER_
-namespace vsomeip {
+namespace vsomeip_v3 {
class routing_manager;
@@ -19,6 +19,6 @@ public:
virtual void process_command(const byte_t *_data, length_t _length) = 0;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_MANAGER_ADAPTER_HPP
+#endif // VSOMEIP_V3_ROUTING_MANAGER_ADAPTER_HPP_
diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp
index 6bee10c..acd57fe 100644
--- a/implementation/routing/include/routing_manager_base.hpp
+++ b/implementation/routing/include/routing_manager_base.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_MANAGER_BASE
-#define VSOMEIP_ROUTING_MANAGER_BASE
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_BASE_
+#define VSOMEIP_V3_ROUTING_MANAGER_BASE_
#include <mutex>
#include <unordered_set>
@@ -12,6 +12,8 @@
#include <condition_variable>
#include <vsomeip/constants.hpp>
+
+#include "routing_host.hpp"
#include "routing_manager.hpp"
#include "routing_manager_host.hpp"
#include "types.hpp"
@@ -21,9 +23,10 @@
#include "../../message/include/serializer.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../configuration/include/configuration.hpp"
-#include "../../endpoints/include/endpoint_host.hpp"
+#include "../../endpoints/include/endpoint_manager_base.hpp"
+
+namespace vsomeip_v3 {
-namespace vsomeip {
#ifdef USE_DLT
namespace trace {
class connector_impl;
@@ -33,90 +36,91 @@ class connector_impl;
class serializer;
class routing_manager_base : public routing_manager,
- public endpoint_host,
- public std::enable_shared_from_this<routing_manager_base>{
+ public routing_host,
+ public std::enable_shared_from_this<routing_manager_base> {
public:
routing_manager_base(routing_manager_host *_host);
- virtual ~routing_manager_base();
+ virtual ~routing_manager_base() = default;
virtual boost::asio::io_service & get_io();
virtual client_t get_client() const;
+ virtual void set_client(const client_t &_client);
+ virtual session_t get_session();
- virtual void init();
+ virtual void init() = 0;
+ void init(const std::shared_ptr<endpoint_manager_base>& _endpoint_manager);
- virtual bool offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor);
+ virtual bool offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- virtual void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor);
+ virtual void stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- virtual void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy);
+ virtual void request_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- virtual void release_service(client_t _client, service_t _service,
- instance_t _instance);
+ virtual void release_service(client_t _client,
+ service_t _service, instance_t _instance);
- virtual void register_event(client_t _client, service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups, bool _is_field,
+ virtual void register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups,
+ const event_type_e _type, reliability_type_e _reliability,
std::chrono::milliseconds _cycle, bool _change_resets_cycle,
- epsilon_change_func_t _epsilon_change_func,
- bool _is_provided, bool _is_shadow = false, bool _is_cache_placeholder = false);
+ bool _update_on_change, epsilon_change_func_t _epsilon_change_func,
+ bool _is_provided, bool _is_shadow = false,
+ bool _is_cache_placeholder = false);
- virtual void unregister_event(client_t _client, service_t _service, instance_t _instance,
- event_t _event, bool _is_provided);
+ virtual void unregister_event(client_t _client,
+ service_t _service, instance_t _instance, event_t _event,
+ bool _is_provided);
virtual std::set<std::shared_ptr<event>> find_events(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const;
- virtual void subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type);
+ virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, event_t _event);
- virtual void unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, event_t _event);
+ virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, event_t _event);
virtual void notify(service_t _service, instance_t _instance,
- event_t _event, std::shared_ptr<payload> _payload,
- bool _force, bool _flush);
+ event_t _event, std::shared_ptr<payload> _payload, bool _force);
virtual void notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- client_t _client, bool _force, bool _flush, bool _remote_subscriber);
+ client_t _client, bool _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , bool _remote_subscriber
+#endif
+ );
- virtual bool send(client_t _client, std::shared_ptr<message> _message,
- bool _flush);
+ virtual bool send(client_t _client, std::shared_ptr<message> _message);
virtual bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable,
+ instance_t _instance, bool _reliable,
client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
- bool _is_valid_crc = true, bool _sent_from_remote = false) = 0;
+ credentials_t _credentials = {ANY_UID, ANY_GID},
+ uint8_t _status_check = 0, bool _sent_from_remote = false) = 0;
- // Endpoint host ~> will be implemented by routing_manager_impl/_proxy/
- virtual void on_connect(std::shared_ptr<endpoint> _endpoint) = 0;
- virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint) = 0;
+ // routing host -> will be implemented by routing_manager_impl/_proxy/
virtual void on_message(const byte_t *_data, length_t _length,
endpoint *_receiver, const boost::asio::ip::address &_destination
= boost::asio::ip::address(), client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
+ credentials_t _credentials = {ANY_UID, ANY_GID},
const boost::asio::ip::address &_remote_address = boost::asio::ip::address(),
std::uint16_t _remote_port = 0) = 0;
- virtual void on_error(const byte_t *_data, length_t _length,
- endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port) = 0;
-#ifndef _WIN32
- virtual bool check_credentials(client_t _client, uid_t _uid, gid_t _gid);
-#endif
virtual void set_routing_state(routing_state_e _routing_state) = 0;
- virtual std::shared_ptr<event> find_event(service_t _service, instance_t _instance,
- event_t _event) const;
-
virtual void register_client_error_handler(client_t _client,
const std::shared_ptr<endpoint> &_endpoint) = 0;
@@ -124,8 +128,16 @@ public:
std::set<client_t> find_local_clients(service_t _service, instance_t _instance);
-protected:
std::shared_ptr<serviceinfo> find_service(service_t _service, instance_t _instance) const;
+
+ client_t find_local_client(service_t _service, instance_t _instance) const;
+
+ std::shared_ptr<event> find_event(service_t _service, instance_t _instance,
+ event_t _event) const;
+
+ virtual void on_connect(const std::shared_ptr<endpoint>& _endpoint) = 0;
+ virtual void on_disconnect(const std::shared_ptr<endpoint>& _endpoint) = 0;
+protected:
std::shared_ptr<serviceinfo> create_service_info(service_t _service,
instance_t _instance, major_version_t _major,
minor_version_t _minor, ttl_t _ttl, bool _is_local_service);
@@ -134,21 +146,12 @@ protected:
services_t get_services() const;
services_t get_services_remote() const;
bool is_available(service_t _service, instance_t _instance, major_version_t _major);
- client_t find_local_client(service_t _service, instance_t _instance);
- std::shared_ptr<endpoint> create_local(client_t _client);
- std::shared_ptr<endpoint> find_or_create_local(client_t _client);
void remove_local(client_t _client, bool _remove_uid);
void remove_local(client_t _client,
const std::set<std::tuple<service_t, instance_t, eventgroup_t>>& _subscribed_eventgroups,
bool _remove_uid);
- std::shared_ptr<endpoint> find_local(client_t _client);
- std::shared_ptr<endpoint> find_local(service_t _service,
- instance_t _instance);
-
- std::unordered_set<client_t> get_connected_clients();
-
std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const;
@@ -157,33 +160,35 @@ protected:
bool send_local_notification(client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush = true, bool _reliable = false, bool _is_valid_crc = true);
+ bool _reliable = false, uint8_t _status_check = 0);
bool send_local(
std::shared_ptr<endpoint> &_target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush, bool _reliable, uint8_t _command, bool _is_valid_crc = true) const;
+ bool _reliable, uint8_t _command, uint8_t _status_check = 0) const;
bool insert_subscription(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event, client_t _client,
std::set<event_t> *_already_subscribed_events);
+ std::shared_ptr<serializer> get_serializer();
+ void put_serializer(const std::shared_ptr<serializer> &_serializer);
std::shared_ptr<deserializer> get_deserializer();
- void put_deserializer(std::shared_ptr<deserializer>);
+ void put_deserializer(const std::shared_ptr<deserializer> &_deserializer);
void send_pending_subscriptions(service_t _service,
instance_t _instance, major_version_t _major);
virtual void send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type) = 0;
+ major_version_t _major, event_t _event) = 0;
void remove_pending_subscription(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
-
+#ifdef VSOMEIP_ENABLE_COMPAT
void send_pending_notify_ones(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client, bool _remote_subscriber = false);
+#endif
void unset_all_eventpayloads(service_t _service, instance_t _instance);
void unset_all_eventpayloads(service_t _service, instance_t _instance,
@@ -194,11 +199,6 @@ protected:
eventgroup_t _eventgroup, event_t _event,
const std::set<event_t> &_events_to_exclude);
- void send_identify_request(service_t _service, instance_t _instance,
- major_version_t _major, bool _reliable);
-
- std::map<client_t, std::shared_ptr<endpoint>> get_local_endpoints();
-
std::set<std::tuple<service_t, instance_t, eventgroup_t>>
get_subscriptions(const client_t _client);
@@ -206,9 +206,9 @@ protected:
bool is_response_allowed(client_t _sender, service_t _service,
instance_t _instance, method_t _method);
- bool is_subscribe_to_any_event_allowed(client_t _client,
+ bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup);
-
+#ifdef VSOMEIP_ENABLE_COMPAT
void set_incoming_subscription_state(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event, subscription_state_e _state);
@@ -217,12 +217,9 @@ protected:
void erase_incoming_subscription_state(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
+#endif
private:
- std::shared_ptr<endpoint> create_local_unlocked(client_t _client);
- std::shared_ptr<endpoint> find_local_unlocked(client_t _client);
-
-
virtual bool create_placeholder_event_and_subscribe(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
event_t _event, client_t _client) = 0;
@@ -230,18 +227,22 @@ private:
protected:
routing_manager_host *host_;
boost::asio::io_service &io_;
- client_t client_;
+ std::atomic<client_t> client_;
std::shared_ptr<configuration> configuration_;
- std::shared_ptr<serializer> serializer_;
- std::mutex serialize_mutex_;
+
+ std::queue<std::shared_ptr<serializer>> serializers_;
+ std::mutex serializer_mutex_;
+ std::condition_variable serializer_condition_;
std::queue<std::shared_ptr<deserializer>> deserializers_;
std::mutex deserializer_mutex_;
std::condition_variable deserializer_condition_;
- std::mutex local_services_mutex_;
- std::map<service_t, std::map<instance_t, std::tuple< major_version_t, minor_version_t, client_t> > > local_services_;
+ mutable std::mutex local_services_mutex_;
+ typedef std::map<service_t, std::map<instance_t,
+ std::tuple<major_version_t, minor_version_t, client_t>>> local_services_map_t;
+ local_services_map_t local_services_;
std::map<service_t, std::map<instance_t, std::set<client_t> > > local_services_history_;
// Eventgroups
@@ -252,7 +253,11 @@ protected:
// Events (part of one or more eventgroups)
mutable std::mutex events_mutex_;
std::map<service_t,
- std::map<instance_t, std::map<event_t, std::shared_ptr<event> > > > events_;
+ std::map<instance_t,
+ std::map<event_t,
+ std::shared_ptr<event> > > > events_;
+
+ std::mutex event_registration_mutex_;
#ifdef USE_DLT
std::shared_ptr<trace::connector_impl> tc_;
@@ -264,7 +269,8 @@ protected:
eventgroup_t eventgroup_;
major_version_t major_;
event_t event_;
- subscription_type_e subscription_type_;
+ uid_t uid_;
+ gid_t gid_;
bool operator<(const subscription_data_t &_other) const {
return (service_ < _other.service_
@@ -284,21 +290,21 @@ protected:
services_t services_remote_;
mutable std::mutex services_remote_mutex_;
+ std::shared_ptr<endpoint_manager_base> ep_mgr_;
+
+ std::uint32_t own_uid_;
+ std::uint32_t own_gid_;
+
private:
services_t services_;
mutable std::mutex services_mutex_;
- std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_;
- mutable std::mutex local_endpoint_mutex_;
-
+#ifdef VSOMEIP_ENABLE_COMPAT
std::map<service_t,
std::map<instance_t,
std::map<eventgroup_t,
std::shared_ptr<message> > > > pending_notify_ones_;
std::recursive_mutex pending_notify_ones_mutex_;
-
- std::mutex event_registration_mutex_;
-
std::map<client_t,
std::map<service_t,
std::map<instance_t,
@@ -306,9 +312,10 @@ private:
std::map<event_t,
subscription_state_e> > > > > incoming_subscription_state_;
std::recursive_mutex incoming_subscription_state_mutex_;
+#endif
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif //VSOMEIP_ROUTING_MANAGER_BASE
+#endif // VSOMEIP_V3_ROUTING_MANAGER_BASE_
diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp
index 7aa767a..69133e2 100644
--- a/implementation/routing/include/routing_manager_host.hpp
+++ b/implementation/routing/include/routing_manager_host.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_MANAGER_HOST
-#define VSOMEIP_ROUTING_MANAGER_HOST
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_HOST_
+#define VSOMEIP_V3_ROUTING_MANAGER_HOST_
#include <memory>
@@ -12,7 +12,7 @@
#include <vsomeip/error.hpp>
-namespace vsomeip {
+namespace vsomeip_v3 {
class configuration;
class message;
@@ -23,6 +23,8 @@ public:
}
virtual client_t get_client() const = 0;
+ virtual void set_client(const client_t &_client) = 0;
+ virtual session_t get_session() = 0;
virtual const std::string & get_name() const = 0;
virtual std::shared_ptr<configuration> get_configuration() const = 0;
virtual boost::asio::io_service & get_io() = 0;
@@ -30,19 +32,17 @@ public:
virtual void on_availability(service_t _service, instance_t _instance,
bool _is_available, major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor = DEFAULT_MINOR) = 0;
virtual void on_state(state_type_e _state) = 0;
- virtual void on_message(const std::shared_ptr<message> &&_message) = 0;
- virtual void on_error(error_code_e _error) = 0;
+ virtual void on_message(std::shared_ptr<message> &&_message) = 0;
virtual void on_subscription(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, client_t _client, bool _subscribed, std::function<void(bool)> _accepted_cb) = 0;
- virtual void on_subscription_error(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, uint16_t _error) = 0;
+ eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed,
+ std::function<void(bool)> _accepted_cb) = 0;
virtual void on_subscription_status(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event, uint16_t _error) = 0;
- virtual void send(std::shared_ptr<message> _message, bool _flush) = 0;
+ virtual void send(std::shared_ptr<message> _message) = 0;
virtual void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services) = 0;
virtual bool is_routing() const = 0;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_MANAGER_HOST
+#endif // VSOMEIP_V3_ROUTING_MANAGER_HOST_
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index 40abf73..bead207 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -1,10 +1,10 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// Copyright (C) 2014-2018 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_ROUTING_MANAGER_IMPL_HPP
-#define VSOMEIP_ROUTING_MANAGER_IMPL_HPP
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_IMPL_HPP_
+#define VSOMEIP_V3_ROUTING_MANAGER_IMPL_HPP_
#include <map>
#include <memory>
@@ -26,8 +26,10 @@
#include "../../endpoints/include/netlink_connector.hpp"
#include "../../service_discovery/include/service_discovery_host.hpp"
+#include "../../endpoints/include/endpoint_manager_impl.hpp"
-namespace vsomeip {
+
+namespace vsomeip_v3 {
class configuration;
class deserializer;
@@ -42,9 +44,9 @@ namespace sd {
class service_discovery;
} // namespace sd
-
-// TODO: encapsulate common parts of classes "routing_manager_impl"
-// and "routing_manager_proxy" into a base class.
+namespace e2e {
+class e2e_provider;
+} // namespace e2e
class routing_manager_impl: public routing_manager_base,
public routing_manager_stub_host,
@@ -55,61 +57,70 @@ public:
boost::asio::io_service & get_io();
client_t get_client() const;
- const std::shared_ptr<configuration> get_configuration() const;
void init();
void start();
void stop();
- bool offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor);
+ bool offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor);
+ void stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy);
+ void request_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void release_service(client_t _client, service_t _service,
- instance_t _instance);
+ void release_service(client_t _client,
+ service_t _service, instance_t _instance);
- void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, event_t _event,
- subscription_type_e _subscription_type);
+ void subscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, event_t _event);
- void unsubscribe(client_t _client, service_t _service, instance_t _instance,
+ void unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
- bool send(client_t _client, std::shared_ptr<message> _message, bool _flush);
+ bool send(client_t _client, std::shared_ptr<message> _message);
- virtual bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable,
+ bool send(client_t _client, const byte_t *_data, uint32_t _size,
+ instance_t _instance, bool _reliable,
client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
- bool _is_valid_crc = true, bool _sent_from_remote = false);
+ credentials_t _credentials = {ANY_UID, ANY_GID},
+ uint8_t _status_check = 0, bool _sent_from_remote = false);
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message, bool _flush);
+ bool send_to(const client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message);
bool send_to(const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush);
+ instance_t _instance);
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ bool send_via_sd(const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size, uint16_t _sd_port);
- void register_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
- const std::set<eventgroup_t> &_eventgroups, bool _is_field,
+ void register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups,
+ const event_type_e _type,
+ reliability_type_e _reliability,
std::chrono::milliseconds _cycle, bool _change_resets_cycle,
+ bool _update_on_change,
epsilon_change_func_t _epsilon_change_func,
bool _is_provided, bool _is_shadow, bool _is_cache_placeholder);
- void register_shadow_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
+ void register_shadow_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, bool _is_provided);
+ event_type_e _type, reliability_type_e _reliability,
+ bool _is_provided);
void unregister_shadow_event(client_t _client, service_t _service,
instance_t _instance, event_t _event,
@@ -117,63 +128,68 @@ public:
void notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- client_t _client, bool _force, bool _flush, bool _remote_subscriber);
+ client_t _client, bool _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , bool _remote_subscriber
+#endif
+ );
- void on_subscribe_nack(client_t _client, service_t _service,
+ void on_subscribe_ack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id);
+ remote_subscription_id_t _id);
- void on_subscribe_ack(client_t _client, service_t _service,
+ void on_subscribe_nack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id);
+ remote_subscription_id_t _id);
- void on_identify_response(client_t _client, service_t _service, instance_t _instance,
- bool _reliable);
// interface to stub
inline std::shared_ptr<endpoint> find_local(client_t _client) {
- return routing_manager_base::find_local(_client);
+ return ep_mgr_->find_local(_client);
}
inline std::shared_ptr<endpoint> find_or_create_local(
client_t _client) {
- return routing_manager_base::find_or_create_local(_client);
+ return ep_mgr_->find_or_create_local(_client);
}
+ std::shared_ptr<endpoint> find_or_create_remote_client(
+ service_t _service, instance_t _instance, bool _reliable,
+ client_t _client);
+
void remove_local(client_t _client, bool _remove_uid);
- void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance,
+ void on_stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor);
void on_availability(service_t _service, instance_t _instance,
- bool _is_available, major_version_t _major, minor_version_t _minor);
+ bool _is_available,
+ major_version_t _major, minor_version_t _minor);
void on_pong(client_t _client);
+ void on_subscribe_ack_with_multicast(
+ service_t _service, instance_t _instance,
+ const boost::asio::ip::address &_address, uint16_t _port);
void on_unsubscribe_ack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _unsubscription_id);
-
- // interface "endpoint_host"
- std::shared_ptr<endpoint> find_or_create_remote_client(service_t _service,
- instance_t _instance,
- bool _reliable, client_t _client);
- void on_connect(std::shared_ptr<endpoint> _endpoint);
- void on_disconnect(std::shared_ptr<endpoint> _endpoint);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port);
+ remote_subscription_id_t _id);
+
+ void on_connect(const std::shared_ptr<endpoint>& _endpoint);
+ void on_disconnect(const std::shared_ptr<endpoint>& _endpoint);
+
void on_message(const byte_t *_data, length_t _size, endpoint *_receiver,
const boost::asio::ip::address &_destination,
- client_t _bound_client,
+ client_t _bound_client, credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port);
bool on_message(service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _reliable,
- client_t _bound_client, bool _is_valid_crc = true,
+ client_t _bound_client, credentials_t _credentials,
+ uint8_t _check_status = 0,
bool _is_from_remote = false);
void on_notification(client_t _client, service_t _service,
instance_t _instance, const byte_t *_data, length_t _size,
bool _notify_one);
- void release_port(uint16_t _port, bool _reliable);
bool offer_service_remotely(service_t _service, instance_t _instance,
std::uint16_t _port, bool _reliable,
@@ -206,29 +222,22 @@ public:
bool _has_reliable, bool _has_unreliable);
void update_routing_info(std::chrono::milliseconds _elapsed);
- void on_remote_subscription(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- const std::shared_ptr<endpoint_definition> &_subscriber,
- const std::shared_ptr<endpoint_definition> &_target, ttl_t _ttl,
- const std::shared_ptr<sd_message_identifier_t> &_sd_message_id,
- const std::function<void(remote_subscription_state_e, client_t)>& _callback);
- void on_unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _target);
- void on_subscribe_ack(service_t _service, instance_t _instance,
- const boost::asio::ip::address &_address, uint16_t _port);
+ // Handle remote subscriptions / subscription acks
+ void on_remote_subscribe(
+ std::shared_ptr<remote_subscription> &_subscription,
+ const remote_subscription_callback_t& _callback);
+ void on_remote_unsubscribe(
+ std::shared_ptr<remote_subscription> &_subscription);
void expire_subscriptions(const boost::asio::ip::address &_address);
void expire_services(const boost::asio::ip::address &_address);
std::chrono::steady_clock::time_point expire_subscriptions(bool _force);
- bool has_identified(client_t _client, service_t _service,
- instance_t _instance, bool _reliable);
-
void register_client_error_handler(client_t _client,
const std::shared_ptr<endpoint> &_endpoint);
void handle_client_error(client_t _client);
+ std::shared_ptr<endpoint_manager_impl> get_endpoint_manager() const;
void set_routing_state(routing_state_e _routing_state);
@@ -241,46 +250,61 @@ public:
eventgroup_t _eventgroup,
const std::shared_ptr<endpoint_definition> &_subscriber);
- void register_offer_acceptance_handler(offer_acceptance_handler_t _handler) const;
- void register_reboot_notification_handler(reboot_notification_handler_t _handler) const;
- void register_routing_ready_handler(routing_ready_handler_t _handler);
- void register_routing_state_handler(routing_state_handler_t _handler);
- void offer_acceptance_enabled(boost::asio::ip::address _address);
+ void print_stub_status() const;
+
+ void send_error(return_code_e _return_code, const byte_t *_data,
+ length_t _size, instance_t _instance, bool _reliable,
+ endpoint* const _receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
+ void service_endpoint_connected(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ const std::shared_ptr<endpoint>& _endpoint,
+ bool _unreliable_only);
+ void service_endpoint_disconnected(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ const std::shared_ptr<endpoint>& _endpoint);
+
+ void register_sd_acceptance_handler(const sd_acceptance_handler_t& _handler) const;
+ 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 on_resend_provided_events_response(pending_remote_offer_id_t _id);
- bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, ::std::shared_ptr<policy> _policy,
- std::shared_ptr<payload> _payload, security_update_handler_t _handler);
- bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, security_update_handler_t _handler);
+ bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy,
+ const std::shared_ptr<payload>& _payload, const security_update_handler_t& _handler);
+ bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, const security_update_handler_t& _handler);
+ client_t find_local_client(service_t _service, instance_t _instance);
void on_security_update_response(pending_security_update_id_t _id, client_t _client);
std::set<client_t> find_local_clients(service_t _service, instance_t _instance);
- bool is_subscribe_to_any_event_allowed(client_t _client,
+ bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup);
private:
+ bool offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ bool _must_queue);
+
+ void stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ bool _must_queue);
+
bool deliver_message(const byte_t *_data, length_t _size,
instance_t _instance, bool _reliable, client_t _bound_client,
- bool _is_valid_crc = true, bool _is_from_remote = false);
+ credentials_t _credentials,
+ uint8_t _status_check = 0, bool _is_from_remote = false);
bool deliver_notification(service_t _service, instance_t _instance,
const byte_t *_data, length_t _length, bool _reliable, client_t _bound_client,
- bool _is_valid_crc = true, bool _is_from_remote = false);
+ credentials_t _credentials,
+ uint8_t _status_check = 0, bool _is_from_remote = false);
- instance_t find_instance(service_t _service, endpoint *_endpoint);
void init_service_info(service_t _service,
instance_t _instance, bool _is_local_service);
- 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);
-
- std::shared_ptr<endpoint> create_server_endpoint(uint16_t _port,
- bool _reliable, bool _start);
- std::shared_ptr<endpoint> find_server_endpoint(uint16_t _port,
- bool _reliable) const;
- std::shared_ptr<endpoint> find_or_create_server_endpoint(uint16_t _port,
- bool _reliable, bool _start);
-
bool is_field(service_t _service, instance_t _instance,
event_t _event) const;
@@ -290,74 +314,32 @@ private:
std::shared_ptr<endpoint> create_remote_client(service_t _service,
instance_t _instance, bool _reliable, client_t _client);
- bool deliver_specific_endpoint_message(service_t _service, instance_t _instance,
- const byte_t *_data, length_t _size, endpoint *_receiver);
-
void clear_client_endpoints(service_t _service, instance_t _instance, bool _reliable);
void clear_multicast_endpoints(service_t _service, instance_t _instance);
- bool is_identifying(client_t _client, service_t _service,
- instance_t _instance, bool _reliable);
-
std::set<eventgroup_t> get_subscribed_eventgroups(service_t _service,
instance_t _instance);
void clear_targets_and_pending_sub_from_eventgroups(service_t _service, instance_t _instance);
void clear_remote_subscriber(service_t _service, instance_t _instance);
-private:
+
return_code_e check_error(const byte_t *_data, length_t _size,
instance_t _instance);
- void send_error(return_code_e _return_code, const byte_t *_data,
- length_t _size, instance_t _instance, bool _reliable,
- endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port);
-
- void identify_for_subscribe(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- subscription_type_e _subscription_type);
- bool send_identify_message(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- bool _reliable);
-
bool supports_selective(service_t _service, instance_t _instance);
- client_t find_client(service_t _service, instance_t _instance,
- const std::shared_ptr<eventgroupinfo> &_eventgroup,
- const std::shared_ptr<endpoint_definition> &_target) const;
-
void clear_remote_subscriber(service_t _service, instance_t _instance,
client_t _client,
const std::shared_ptr<endpoint_definition> &_target);
void log_version_timer_cbk(boost::system::error_code const & _error);
- void clear_remote_service_info(service_t _service, instance_t _instance, bool _reliable);
-
bool handle_local_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,minor_version_t _minor);
- void remove_specific_client_endpoint(client_t _client, service_t _service, instance_t _instance, bool _reliable);
-
- void clear_identified_clients( service_t _service, instance_t _instance);
-
- void clear_identifying_clients( service_t _service, instance_t _instance);
-
- void remove_identified_client(service_t _service, instance_t _instance, client_t _client);
-
- void remove_identifying_client(service_t _service, instance_t _instance, client_t _client);
-
- void unsubscribe_specific_client_at_sd(service_t _service, instance_t _instance, client_t _client);
-
- inline std::shared_ptr<endpoint> find_local(service_t _service, instance_t _instance) {
- return routing_manager_base::find_local(_service, _instance);
- }
-
void send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type);
+ major_version_t _major, event_t _event);
void on_net_interface_or_route_state_changed(bool _is_interface,
std::string _if,
@@ -373,7 +355,7 @@ private:
void call_sd_endpoint_connected(const boost::system::error_code& _error,
service_t _service, instance_t _instance,
- std::shared_ptr<endpoint> _endpoint,
+ const std::shared_ptr<endpoint>& _endpoint,
std::shared_ptr<boost::asio::steady_timer> _timer);
bool create_placeholder_event_and_subscribe(service_t _service,
@@ -385,29 +367,26 @@ private:
void handle_subscription_state(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
- client_t is_specific_endpoint_client(client_t _client, service_t _service, instance_t _instance);
- std::unordered_set<client_t> get_specific_endpoint_clients(service_t _service, instance_t _instance);
-
void memory_log_timer_cbk(boost::system::error_code const & _error);
void status_log_timer_cbk(boost::system::error_code const & _error);
- void send_subscription(client_t _offering_client,
- client_t _subscribing_client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major,
- pending_subscription_id_t _pending_subscription_id);
+ void send_subscription(const client_t _offering_client,
+ const service_t _service, const instance_t _instance,
+ const eventgroup_t _eventgroup, const major_version_t _major,
+ const std::set<client_t> &_clients,
+ const remote_subscription_id_t _id);
- void send_unsubscription(
- client_t _offering_client, client_t _subscribing_client,
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _pending_unsubscription_id);
+ void send_unsubscription(client_t _offering_client,
+ const service_t _service, const instance_t _instance,
+ const eventgroup_t _eventgroup, const major_version_t _major,
+ const std::set<client_t> &_removed,
+ const remote_subscription_id_t _id);
void cleanup_server_endpoint(service_t _service,
const std::shared_ptr<endpoint>& _endpoint);
pending_remote_offer_id_t pending_remote_offer_add(service_t _service,
instance_t _instance);
-
std::pair<service_t, instance_t> pending_remote_offer_remove(
pending_remote_offer_id_t _id);
@@ -417,7 +396,7 @@ private:
std::shared_ptr<boost::asio::steady_timer> _timer);
pending_security_update_id_t pending_security_update_add(
- std::unordered_set<client_t> _clients);
+ const std::unordered_set<client_t>& _clients);
std::unordered_set<client_t> pending_security_update_get(
pending_security_update_id_t _id);
@@ -428,54 +407,28 @@ private:
bool is_pending_security_update_finished(
pending_security_update_id_t _id);
- std::shared_ptr<routing_manager_stub> stub_;
- std::shared_ptr<sd::service_discovery> discovery_;
-
- // Server endpoints for local services
- typedef std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint>>> server_endpoints_t;
- server_endpoints_t server_endpoints_;
- std::map<service_t, std::map<endpoint *, instance_t> > service_instances_;
+ bool insert_offer_command(service_t _service, instance_t _instance, uint8_t _command,
+ client_t _client, major_version_t _major, minor_version_t _minor);
+ bool erase_offer_command(service_t _service, instance_t _instance);
- // Multicast endpoint info (notifications)
- std::map<service_t, std::map<instance_t, std::shared_ptr<endpoint_definition> > > multicast_info;
+ bool is_last_stop_callback(const uint32_t _callback_id);
- // Client endpoints for remote services
- 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;
- remote_services_t remote_services_;
+private:
+ std::shared_ptr<routing_manager_stub> stub_;
+ std::shared_ptr<sd::service_discovery> discovery_;
- typedef std::map<boost::asio::ip::address, std::map<uint16_t,
- std::map<bool, std::shared_ptr<endpoint>>>> client_endpoints_by_ip_t;
- client_endpoints_by_ip_t client_endpoints_by_ip_;
+ std::mutex requested_services_mutex_;
std::map<client_t,
std::map<service_t,
std::map<instance_t,
std::set<std::pair<major_version_t, minor_version_t>>>>> requested_services_;
- // Mutexes
- mutable std::recursive_mutex endpoint_mutex_;
- std::mutex identified_clients_mutex_;
- std::mutex requested_services_mutex_;
-
std::mutex remote_subscribers_mutex_;
std::map<service_t, std::map<instance_t, std::map<client_t,
std::set<std::shared_ptr<endpoint_definition>>>>> remote_subscribers_;
- std::mutex specific_endpoint_clients_mutex_;
- std::map<service_t, std::map<instance_t, std::unordered_set<client_t>>>specific_endpoint_clients_;
- std::map<service_t, std::map<instance_t,
- std::map<bool, std::unordered_set<client_t> > > > identified_clients_;
- std::map<service_t, std::map<instance_t,
- std::map<bool, std::unordered_set<client_t> > > > identifying_clients_;
-
std::shared_ptr<serviceinfo> sd_info_;
- std::map<bool, std::set<uint16_t>> used_client_ports_;
- std::mutex used_client_ports_mutex_;
-
std::mutex version_log_timer_mutex_;
boost::asio::steady_timer version_log_timer_;
@@ -488,12 +441,6 @@ private:
std::shared_ptr<netlink_connector> netlink_connector_;
#endif
-#ifndef WITHOUT_SYSTEMD
- std::mutex watchdog_timer_mutex_;
- boost::asio::steady_timer watchdog_timer_;
- void watchdog_cbk(boost::system::error_code const &_error);
-#endif
-
std::mutex pending_offers_mutex_;
// map to store pending offers.
// 1st client id in tuple: client id of new offering application
@@ -509,8 +456,7 @@ private:
std::map<std::tuple<service_t, instance_t, eventgroup_t, client_t>,
subscription_state_e> remote_subscription_state_;
- std::map<e2exf::data_identifier_t, std::shared_ptr<e2e::profile_interface::protector>> custom_protectors;
- std::map<e2exf::data_identifier_t, std::shared_ptr<e2e::profile_interface::checker>> custom_checkers;
+ std::shared_ptr<e2e::e2e_provider> e2e_provider_;
std::mutex status_log_timer_mutex_;
boost::asio::steady_timer status_log_timer_;
@@ -518,6 +464,10 @@ private:
std::mutex memory_log_timer_mutex_;
boost::asio::steady_timer memory_log_timer_;
+ std::shared_ptr<endpoint_manager_impl> ep_mgr_impl_;
+
+ reboot_notification_handler_t reboot_notification_handler_;
+
routing_ready_handler_t routing_ready_handler_;
routing_state_handler_t routing_state_handler_;
@@ -537,8 +487,14 @@ private:
std::mutex security_update_timers_mutex_;
std::map<pending_security_update_id_t, std::shared_ptr<boost::asio::steady_timer>> security_update_timers_;
+
+ std::mutex offer_serialization_mutex_;
+ std::map<std::pair<service_t, instance_t>, std::deque<std::tuple<uint8_t, client_t, major_version_t, minor_version_t>>> offer_commands_;
+
+ std::mutex callback_counts_mutex_;
+ std::map<uint32_t, uint16_t> callback_counts_;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_MANAGER_IMPL_HPP
+#endif // VSOMEIP_V3_ROUTING_MANAGER_IMPL_HPP_
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index fbe775d..d1a29df 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_MANAGER_PROXY_HPP
-#define VSOMEIP_ROUTING_MANAGER_PROXY_HPP
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP
+#define VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP
#include <map>
#include <mutex>
@@ -19,7 +19,7 @@
#include <vsomeip/enumeration_types.hpp>
#include <vsomeip/handler.hpp>
-namespace vsomeip {
+namespace vsomeip_v3 {
class configuration;
class event;
@@ -37,68 +37,70 @@ public:
void start();
void stop();
- const std::shared_ptr<configuration> get_configuration() const;
+ std::shared_ptr<configuration> get_configuration() const;
- bool offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor);
+ bool offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor);
+ void stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy);
+ void request_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor);
- void release_service(client_t _client, service_t _service,
- instance_t _instance);
+ void release_service(client_t _client,
+ service_t _service, instance_t _instance);
- void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, event_t _event,
- subscription_type_e _subscription_type);
+ void subscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major,
+ event_t _event);
- void unsubscribe(client_t _client, service_t _service, instance_t _instance,
+ void unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event);
bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable,
+ instance_t _instance, bool _reliable,
client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
- bool _is_valid_crc = true, bool _sent_from_remote = false);
+ credentials_t _credentials = {ANY_UID, ANY_GID},
+ uint8_t _status_check = 0, bool _sent_from_remote = false);
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message, bool _flush);
+ bool send_to(const client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message);
bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size, instance_t _instance, bool _flush);
+ const byte_t *_data, uint32_t _size, instance_t _instance);
- void register_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
- const std::set<eventgroup_t> &_eventgroups, bool _is_field,
+ void register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups,
+ const event_type_e _type,
+ reliability_type_e _reliability,
std::chrono::milliseconds _cycle, bool _change_resets_cycle,
+ bool _update_on_change,
epsilon_change_func_t _epsilon_change_func,
bool _is_provided, bool _is_shadow, bool _is_cache_placeholder);
void unregister_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
- bool _is_provided);
+ instance_t _instance, event_t _notifier, bool _is_provided);
- void on_connect(std::shared_ptr<endpoint> _endpoint);
- void on_disconnect(std::shared_ptr<endpoint> _endpoint);
+ void on_connect(const std::shared_ptr<endpoint>& _endpoint);
+ void on_disconnect(const std::shared_ptr<endpoint>& _endpoint);
void on_message(const byte_t *_data, length_t _size, endpoint *_receiver,
const boost::asio::ip::address &_destination,
client_t _bound_client,
+ credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port);
- void release_port(uint16_t _port, bool _reliable);
void on_routing_info(const byte_t *_data, uint32_t _size);
- void on_identify_response(client_t _client, service_t _service, instance_t _instance,
- bool _reliable);
-
void register_client_error_handler(client_t _client,
const std::shared_ptr<endpoint> &_endpoint);
void handle_client_error(client_t _client);
@@ -108,6 +110,7 @@ public:
void send_get_offered_services_info(client_t _client, offer_type_e _offer_type);
private:
+ void assign_client();
void register_application();
void deregister_application();
@@ -117,24 +120,25 @@ private:
void send_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
minor_version_t _minor);
- void send_release_service(client_t _client, service_t _service,
- instance_t _instance);
- void send_register_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
+ void send_release_service(client_t _client,
+ service_t _service, instance_t _instance);
+ void send_register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, bool _is_provided);
+ const event_type_e _type, reliability_type_e _reliability,
+ bool _is_provided);
void send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type);
+ major_version_t _major, event_t _event);
void send_subscribe_nack(client_t _subscriber, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id);
+ remote_subscription_id_t _id);
void send_subscribe_ack(client_t _subscriber, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id);
+ remote_subscription_id_t _id);
bool is_field(service_t _service, instance_t _instance,
event_t _event) const;
@@ -161,6 +165,8 @@ private:
eventgroup_t _eventgroup, bool _increment);
void clear_remote_subscriber_count(service_t _service, instance_t _instance);
+ void assign_client_timeout_cbk(boost::system::error_code const &_error);
+
void register_application_timeout_cbk(boost::system::error_code const &_error);
void send_registered_ack();
@@ -171,19 +177,16 @@ private:
bool is_client_known(client_t _client);
- bool create_placeholder_event_and_subscribe(service_t _service,
- instance_t _instance,
- eventgroup_t _eventgroup,
- event_t _event,
- client_t _client);
+ bool create_placeholder_event_and_subscribe(
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, event_t _notifier, client_t _client);
void request_debounce_timeout_cbk(boost::system::error_code const &_error);
void send_request_services(std::set<service_data_t>& _requests);
void send_unsubscribe_ack(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- pending_subscription_id_t _subscription_id);
+ eventgroup_t _eventgroup, remote_subscription_id_t _id);
void resend_provided_event_registrations();
void send_resend_provided_event_response(pending_remote_offer_id_t _id);
@@ -191,12 +194,15 @@ private:
void send_update_security_policy_response(pending_security_update_id_t _update_id);
void send_remove_security_policy_response(pending_security_update_id_t _update_id);
void on_update_security_credentials(const byte_t *_data, uint32_t _size);
+ void on_client_assign_ack(const client_t &_client);
private:
enum class inner_state_type_e : std::uint8_t {
ST_REGISTERED = 0x0,
ST_DEREGISTERED = 0x1,
- ST_REGISTERING = 0x2
+ ST_REGISTERING = 0x2,
+ ST_ASSIGNING = 0x3,
+ ST_ASSIGNED = 0x4
};
std::atomic<bool> is_connected_;
@@ -216,17 +222,18 @@ private:
struct event_data_t {
service_t service_;
instance_t instance_;
- event_t event_;
- bool is_field_;
+ event_t notifier_;
+ event_type_e type_;
+ reliability_type_e reliability_;
bool is_provided_;
std::set<eventgroup_t> eventgroups_;
bool operator<(const event_data_t &_other) const {
- return std::tie(service_, instance_, event_, is_field_,
- is_provided_, eventgroups_)
- < std::tie(_other.service_, _other.instance_, _other.event_,
- _other.is_field_, _other.is_provided_,
- _other.eventgroups_);
+ return std::tie(service_, instance_, notifier_,
+ type_, reliability_, is_provided_, eventgroups_)
+ < std::tie(_other.service_, _other.instance_,
+ _other.notifier_, _other.type_, _other.reliability_,
+ _other.is_provided_, _other.eventgroups_);
}
};
std::set<event_data_t> pending_event_registrations_;
@@ -255,6 +262,6 @@ private:
const std::set<std::tuple<service_t, instance_t> > client_side_logging_filter_;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_MANAGER_PROXY_HPP
+#endif // VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP_
diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp
index d586518..4a37644 100644
--- a/implementation/routing/include/routing_manager_stub.hpp
+++ b/implementation/routing/include/routing_manager_stub.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_MANAGER_STUB
-#define VSOMEIP_ROUTING_MANAGER_STUB
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_STUB_
+#define VSOMEIP_V3_ROUTING_MANAGER_STUB_
#include <condition_variable>
#include <list>
@@ -20,54 +20,48 @@
#include <boost/asio/steady_timer.hpp>
#include "../../endpoints/include/endpoint_host.hpp"
-#include "../../configuration/include/internal.hpp"
+#include "../include/routing_host.hpp"
+
#include "types.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
class configuration;
class routing_manager_stub_host;
-class routing_manager_stub: public endpoint_host,
+class routing_manager_stub: public routing_host,
public std::enable_shared_from_this<routing_manager_stub> {
public:
routing_manager_stub(
routing_manager_stub_host *_host,
- std::shared_ptr<configuration> _configuration);
+ const std::shared_ptr<configuration>& _configuration);
virtual ~routing_manager_stub();
void init();
void start();
void stop();
- const std::shared_ptr<configuration> get_configuration() const;
-
- void on_connect(std::shared_ptr<endpoint> _endpoint);
- void on_disconnect(std::shared_ptr<endpoint> _endpoint);
void on_message(const byte_t *_data, length_t _size, endpoint *_receiver,
const boost::asio::ip::address &_destination,
client_t _bound_client,
+ credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port);
- void release_port(uint16_t _port, bool _reliable);
void on_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor);
void on_stop_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor);
- bool send_subscribe(std::shared_ptr<vsomeip::endpoint> _target,
+ bool send_subscribe(const std::shared_ptr<endpoint>& _target,
client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, pending_subscription_id_t _subscription_id);
+ eventgroup_t _eventgroup, major_version_t _major, event_t _event,
+ remote_subscription_id_t _id);
- bool send_unsubscribe(std::shared_ptr<vsomeip::endpoint> _target,
+ bool send_unsubscribe(const std::shared_ptr<endpoint>& _target,
client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, pending_subscription_id_t _unsubscription_id);
+ event_t _event, remote_subscription_id_t _id);
void send_subscribe_nack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event);
@@ -86,14 +80,6 @@ public:
void handle_credentials(const client_t _client, std::set<service_data_t>& _requests);
void handle_requests(const client_t _client, std::set<service_data_t>& _requests);
- void send_identify_request_command(std::shared_ptr<vsomeip::endpoint> _target,
- service_t _service, instance_t _instance, major_version_t _major,
- bool _reliable);
-
-#ifndef _WIN32
- virtual bool check_credentials(client_t _client, uid_t _uid, gid_t _gid);
-#endif
-
void update_registration(client_t _client, registration_type_e _type);
void print_endpoint_status() const;
@@ -103,12 +89,12 @@ public:
bool is_policy_cached(uint32_t _uid);
- void policy_cache_add(uint32_t _uid, std::shared_ptr<payload> _payload);
+ void policy_cache_add(uint32_t _uid, const std::shared_ptr<payload>& _payload);
void policy_cache_remove(uint32_t _uid);
bool send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id,
- uint32_t _uid, std::shared_ptr<payload> _payload);
+ uint32_t _uid, const std::shared_ptr<payload>& _payload);
bool send_remove_security_policy_request(client_t _client, pending_security_update_id_t _update_id,
uint32_t _uid, uint32_t _gid);
@@ -131,7 +117,6 @@ private:
void on_pong(client_t _client);
void start_watchdog();
void check_watchdog();
- void send_application_lost(std::list<client_t> &_lost);
void client_registration_func(void);
void init_routing_endpoint();
@@ -175,8 +160,6 @@ private:
std::set<client_t> used_client_ids_;
std::mutex used_client_ids_mutex_;
- std::string endpoint_path_;
- std::string local_receiver_path_;
std::shared_ptr<endpoint> endpoint_;
std::shared_ptr<endpoint> local_receiver_;
std::mutex local_receiver_mutex_;
@@ -186,8 +169,6 @@ private:
mutable std::mutex routing_info_mutex_;
std::shared_ptr<configuration> configuration_;
- size_t routingCommandSize_;
-
bool is_socket_activated_;
std::atomic<bool> client_registration_running_;
std::shared_ptr<std::thread> client_registration_thread_;
@@ -215,7 +196,6 @@ private:
};
-} // namespace vsomeip
-
-#endif // VSOMEIP_ROUTING_MANAGER_STUB
+} // namespace vsomeip_v3
+#endif // VSOMEIP_V3_ROUTING_MANAGER_STUB_
diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp
index 5c474fb..b89134d 100644
--- a/implementation/routing/include/routing_manager_stub_host.hpp
+++ b/implementation/routing/include/routing_manager_stub_host.hpp
@@ -3,15 +3,17 @@
// 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_ROUTING_MANAGER_STUB_HOST
-#define VSOMEIP_ROUTING_MANAGER_STUB_HOST
+#ifndef VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_
+#define VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_
#include <boost/asio/io_service.hpp>
#include <vsomeip/handler.hpp>
#include "types.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
+
+class endpoint_manager_impl;
class routing_manager_stub_host {
public:
@@ -20,49 +22,52 @@ public:
virtual bool offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor) = 0;
+ minor_version_t _minor, bool _must_queue = true) = 0;
virtual void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor) = 0;
-
- virtual void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy) = 0;
+ minor_version_t _minor, bool _must_queue = true) = 0;
+
+ virtual void request_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) = 0;
- virtual void release_service(client_t _client, service_t _service,
- instance_t _instance) = 0;
+ virtual void release_service(client_t _client,
+ service_t _service, instance_t _instance) = 0;
- virtual void register_shadow_event(client_t _client, service_t _service,
- instance_t _instance, event_t _event,
+ virtual void register_shadow_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, bool _is_provided) = 0;
+ event_type_e _type, reliability_type_e _reliability,
+ bool _is_provided) = 0;
virtual void unregister_shadow_event(client_t _client, service_t _service,
instance_t _instance, event_t _event, bool _is_provided) = 0;
- virtual void subscribe(client_t _client, service_t _service,
+ virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type) = 0;
+ major_version_t _major, event_t _event) = 0;
virtual void on_subscribe_nack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id) = 0;
+ remote_subscription_id_t _subscription_id) = 0;
virtual void on_subscribe_ack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _subscription_id) = 0;
+ remote_subscription_id_t _subscription_id) = 0;
- virtual void unsubscribe(client_t _client, service_t _service,
+ virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0;
virtual void on_unsubscribe_ack(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _unsubscription_id) = 0;
+ remote_subscription_id_t _unsubscription_id) = 0;
virtual bool on_message(service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _reliable, client_t _bound_client,
- bool _is_valid_crc = true, bool _is_from_remote = false) = 0;
+ credentials_t _credentials,
+ uint8_t _status_check = 0, bool _is_from_remote = false) = 0;
virtual void on_notification(client_t _client,
service_t _service, instance_t _instance,
@@ -84,25 +89,24 @@ public:
virtual boost::asio::io_service & get_io() = 0;
virtual client_t get_client() const = 0;
- virtual void on_identify_response(client_t _client, service_t _service, instance_t _instance,
- bool _reliable) = 0;
-
virtual void on_pong(client_t _client) = 0;
virtual void handle_client_error(client_t _client) = 0;
- virtual void set_routing_state(routing_state_e _routing_state) = 0;
+ virtual std::shared_ptr<endpoint_manager_impl> get_endpoint_manager() const = 0;
virtual void on_resend_provided_events_response(pending_remote_offer_id_t _id) = 0;
virtual void on_security_update_response(pending_security_update_id_t _id, client_t _client) = 0;
+ virtual client_t find_local_client(service_t _service, instance_t _instance) = 0;
+
virtual std::set<client_t> find_local_clients(service_t _service, instance_t _instance) = 0;
- virtual bool is_subscribe_to_any_event_allowed(client_t _client,
+ virtual bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_MANAGER_STUB_HOST
+#endif // VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_
diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp
index 72be585..a405cf0 100644
--- a/implementation/routing/include/serviceinfo.hpp
+++ b/implementation/routing/include/serviceinfo.hpp
@@ -3,8 +3,8 @@
// 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_SERVICEINFO_HPP
-#define VSOMEIP_SERVICEINFO_HPP
+#ifndef VSOMEIP_V3_SERVICEINFO_HPP_
+#define VSOMEIP_V3_SERVICEINFO_HPP_
#include <memory>
#include <set>
@@ -15,14 +15,15 @@
#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
-namespace vsomeip {
+namespace vsomeip_v3 {
class endpoint;
class servicegroup;
class serviceinfo {
public:
- VSOMEIP_EXPORT serviceinfo(major_version_t _major, minor_version_t _minor,
+ VSOMEIP_EXPORT serviceinfo(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
ttl_t _ttl, bool _is_local);
VSOMEIP_EXPORT serviceinfo(const serviceinfo& _other);
VSOMEIP_EXPORT ~serviceinfo();
@@ -30,6 +31,9 @@ public:
VSOMEIP_EXPORT servicegroup * get_group() const;
VSOMEIP_EXPORT void set_group(servicegroup *_group);
+ VSOMEIP_EXPORT service_t get_service() const;
+ VSOMEIP_EXPORT instance_t get_instance() const;
+
VSOMEIP_EXPORT major_version_t get_major() const;
VSOMEIP_EXPORT minor_version_t get_minor() const;
@@ -40,7 +44,7 @@ public:
VSOMEIP_EXPORT void set_precise_ttl(std::chrono::milliseconds _precise_ttl);
VSOMEIP_EXPORT std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
- VSOMEIP_EXPORT void set_endpoint(std::shared_ptr<endpoint> _endpoint,
+ VSOMEIP_EXPORT void set_endpoint(const std::shared_ptr<endpoint>& _endpoint,
bool _reliable);
VSOMEIP_EXPORT void add_client(client_t _client);
@@ -55,6 +59,9 @@ public:
private:
servicegroup *group_;
+ service_t service_;
+ instance_t instance_;
+
major_version_t major_;
minor_version_t minor_;
@@ -72,6 +79,6 @@ private:
bool is_in_mainphase_;
};
-} // namespace vsomeip
+} // namespace vsomeip_v3
-#endif // VSOMEIP_SERVICEINFO_HPP
+#endif // VSOMEIP_V3_SERVICEINFO_HPP_
diff --git a/implementation/routing/include/types.hpp b/implementation/routing/include/types.hpp
index 59acfa3..389b226 100644
--- a/implementation/routing/include/types.hpp
+++ b/implementation/routing/include/types.hpp
@@ -3,8 +3,8 @@
// 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_ROUTING_TYPES_HPP
-#define VSOMEIP_ROUTING_TYPES_HPP
+#ifndef VSOMEIP_V3_ROUTING_TYPES_HPP_
+#define VSOMEIP_V3_ROUTING_TYPES_HPP_
#include <map>
#include <memory>
@@ -13,10 +13,7 @@
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/constants.hpp>
-#include "../../service_discovery/include/message_impl.hpp"
-#include "../../configuration/include/internal.hpp"
-
-namespace vsomeip {
+namespace vsomeip_v3 {
class serviceinfo;
class endpoint_definition;
@@ -40,87 +37,20 @@ enum class registration_type_e : std::uint8_t {
DEREGISTER_ON_ERROR = 0x3
};
-struct sd_message_identifier_t {
- sd_message_identifier_t(session_t _session,
- boost::asio::ip::address _sender,
- boost::asio::ip::address _destination,
- const std::shared_ptr<sd::message_impl> &_response) :
- session_(_session),
- sender_(_sender),
- destination_(_destination),
- response_(_response) {
- }
-
- sd_message_identifier_t() :
- session_(0),
- sender_(boost::asio::ip::address()),
- destination_(boost::asio::ip::address()),
- response_(std::shared_ptr<sd::message_impl>()) {
- }
-
- bool operator==(const sd_message_identifier_t &_other) const {
- return !(session_ != _other.session_ ||
- sender_ != _other.sender_ ||
- destination_ != _other.destination_ ||
- response_ != _other.response_);
- }
-
- bool operator<(const sd_message_identifier_t &_other) const {
- return (session_ < _other.session_
- || (session_ == _other.session_ && sender_ < _other.sender_)
- || (session_ == _other.session_ && sender_ == _other.sender_
- && destination_ < _other.destination_)
- || (session_ == _other.session_ && sender_ == _other.sender_
- && destination_ == _other.destination_
- && response_ < _other.response_));
- }
-
- session_t session_;
- boost::asio::ip::address sender_;
- boost::asio::ip::address destination_;
- std::shared_ptr<sd::message_impl> response_;
-};
+enum class remote_subscription_state_e : std::uint8_t {
+ SUBSCRIPTION_PENDING = 0x00,
-struct pending_subscription_t {
- pending_subscription_t(
- std::shared_ptr<sd_message_identifier_t> _sd_message_identifier,
- std::shared_ptr<endpoint_definition> _subscriber,
- std::shared_ptr<endpoint_definition> _target,
- ttl_t _ttl,
- client_t _subscribing_client) :
- sd_message_identifier_(_sd_message_identifier),
- subscriber_(_subscriber),
- target_(_target),
- ttl_(_ttl),
- subscribing_client_(_subscribing_client),
- pending_subscription_id_(DEFAULT_SUBSCRIPTION) {
- }
- pending_subscription_t () :
- sd_message_identifier_(std::shared_ptr<sd_message_identifier_t>()),
- subscriber_(std::shared_ptr<endpoint_definition>()),
- target_(std::shared_ptr<endpoint_definition>()),
- ttl_(0),
- subscribing_client_(VSOMEIP_ROUTING_CLIENT),
- pending_subscription_id_(DEFAULT_SUBSCRIPTION) {
- }
- std::shared_ptr<sd_message_identifier_t> sd_message_identifier_;
- std::shared_ptr<endpoint_definition> subscriber_;
- std::shared_ptr<endpoint_definition> target_;
- ttl_t ttl_;
- client_t subscribing_client_;
- pending_subscription_id_t pending_subscription_id_;
-};
+ SUBSCRIPTION_ACKED = 0x01,
+ SUBSCRIPTION_NACKED = 0x02,
-enum remote_subscription_state_e : std::uint8_t {
- SUBSCRIPTION_ACKED,
- SUBSCRIPTION_NACKED,
- SUBSCRIPTION_PENDING,
- SUBSCRIPTION_ERROR
+ SUBSCRIPTION_ERROR = 0x03,
+ SUBSCRIPTION_UNKNOWN = 0xFF
};
+typedef std::uint16_t remote_subscription_id_t;
typedef std::uint32_t pending_remote_offer_id_t;
}
-// namespace vsomeip
+// namespace vsomeip_v3
-#endif // VSOMEIP_ROUTING_TYPES_HPP
+#endif // VSOMEIP_V3_ROUTING_TYPES_HPP_
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index ce78a65..7575733 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -4,25 +4,27 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iomanip>
+#include <sstream>
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
#include <vsomeip/message.hpp>
#include <vsomeip/payload.hpp>
#include <vsomeip/runtime.hpp>
+#include <vsomeip/internal/logger.hpp>
#include "../include/event.hpp"
#include "../include/routing_manager.hpp"
-#include "../../configuration/include/internal.hpp"
-#include "../../logging/include/logger.hpp"
#include "../../message/include/payload_impl.hpp"
-namespace vsomeip {
+#include "../../endpoints/include/endpoint_definition.hpp"
+
+namespace vsomeip_v3 {
event::event(routing_manager *_routing, bool _is_shadow) :
routing_(_routing),
message_(runtime::get()->create_notification()),
- is_field_(false),
+ type_(event_type_e::ET_EVENT),
cycle_timer_(_routing->get_io()),
cycle_(std::chrono::milliseconds::zero()),
change_resets_cycle_(false),
@@ -33,8 +35,7 @@ event::event(routing_manager *_routing, bool _is_shadow) :
is_cache_placeholder_(false),
epsilon_change_func_(std::bind(&event::compare, this,
std::placeholders::_1, std::placeholders::_2)),
- is_reliable_(false),
- remote_notification_pending_(false) {
+ reliability_(reliability_type_e::RT_UNKNOWN) {
}
service_t event::get_service() const {
@@ -69,12 +70,16 @@ void event::set_event(event_t _event) {
message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit
}
-bool event::is_field() const {
- return (is_field_);
+event_type_e event::get_type() const {
+ return (type_);
}
-void event::set_field(bool _is_field) {
- is_field_ = _is_field;
+void event::set_type(const event_type_e _type) {
+ type_ = _type;
+}
+
+bool event::is_field() const {
+ return (type_ == event_type_e::ET_FIELD);
}
bool event::is_provided() const {
@@ -109,8 +114,7 @@ bool event::set_payload_dont_notify(const std::shared_ptr<payload> &_payload) {
return true;
}
-void event::set_payload(const std::shared_ptr<payload> &_payload,
- bool _force, bool _flush) {
+void event::set_payload(const std::shared_ptr<payload> &_payload, bool _force) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (is_provided_) {
if (set_payload_helper(_payload, _force)) {
@@ -119,7 +123,7 @@ void event::set_payload(const std::shared_ptr<payload> &_payload,
if (change_resets_cycle_)
stop_cycle();
- notify(_flush);
+ notify();
if (change_resets_cycle_)
start_cycle();
@@ -132,13 +136,13 @@ void event::set_payload(const std::shared_ptr<payload> &_payload,
}
void event::set_payload(const std::shared_ptr<payload> &_payload, client_t _client,
- bool _force, bool _flush) {
+ bool _force) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (is_provided_) {
if (set_payload_helper(_payload, _force)) {
reset_payload(_payload);
if (is_updating_on_change_) {
- notify_one_unlocked(_client, _flush);
+ notify_one_unlocked(_client);
}
}
} else {
@@ -148,14 +152,15 @@ void event::set_payload(const std::shared_ptr<payload> &_payload, client_t _clie
}
void event::set_payload(const std::shared_ptr<payload> &_payload,
- const std::shared_ptr<endpoint_definition> _target,
- bool _force, bool _flush) {
+ const client_t _client,
+ const std::shared_ptr<endpoint_definition>& _target,
+ bool _force) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (is_provided_) {
if (set_payload_helper(_payload, _force)) {
reset_payload(_payload);
if (is_updating_on_change_) {
- notify_one_unlocked(_target, _flush);
+ notify_one_unlocked(_client, _target);
}
}
} else {
@@ -164,6 +169,25 @@ void event::set_payload(const std::shared_ptr<payload> &_payload,
}
}
+bool event::set_payload_notify_pending(const std::shared_ptr<payload> &_payload) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ if (!is_set_ && is_provided_) {
+ reset_payload(_payload);
+
+ // Send pending initial events.
+ for (const auto &its_target : pending_) {
+ message_->set_session(routing_->get_session());
+ routing_->send_to(VSOMEIP_ROUTING_CLIENT,
+ its_target, message_);
+ }
+ pending_.clear();
+
+ return true;
+ }
+
+ return false;
+}
+
void event::unset_payload(bool _force) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (_force) {
@@ -209,7 +233,7 @@ const std::set<eventgroup_t> event::get_eventgroups() const {
std::set<eventgroup_t> its_eventgroups;
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
- for (const auto e : eventgroups_) {
+ for (const auto& e : eventgroups_) {
its_eventgroups.insert(e.first);
}
}
@@ -243,7 +267,7 @@ void event::update_cbk(boost::system::error_code const &_error) {
if (!_error) {
std::lock_guard<std::mutex> its_lock(mutex_);
cycle_timer_.expires_from_now(cycle_);
- notify(true);
+ notify();
auto its_handler =
std::bind(&event::update_cbk, shared_from_this(),
std::placeholders::_1);
@@ -251,47 +275,70 @@ void event::update_cbk(boost::system::error_code const &_error) {
}
}
-void event::notify(bool _flush) {
+void event::notify() {
if (is_set_) {
- routing_->send(VSOMEIP_ROUTING_CLIENT, message_, _flush);
+ message_->set_session(routing_->get_session());
+ routing_->send(VSOMEIP_ROUTING_CLIENT, message_);
} else {
- VSOMEIP_INFO << "Notify event " << std::hex << message_->get_method()
- << "failed. Event payload not set!";
+ VSOMEIP_INFO << __func__
+ << ": Notifying " << std::hex << get_event()
+ << " failed. Event payload not (yet) set!";
}
}
-void event::notify_one(const std::shared_ptr<endpoint_definition> &_target, bool _flush) {
- std::lock_guard<std::mutex> its_lock(mutex_);
- notify_one_unlocked(_target, _flush);
+void event::notify_one(client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target) {
+ if (_target) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ notify_one_unlocked(_client, _target);
+ } else {
+ VSOMEIP_WARNING << __func__
+ << ": Notifying " << std::hex << get_event()
+ << " failed. Target undefined";
+ }
}
-void event::notify_one_unlocked(const std::shared_ptr<endpoint_definition> &_target, bool _flush) {
- if (is_set_) {
- routing_->send_to(_target, message_, _flush);
+void event::notify_one_unlocked(client_t _client,
+ const std::shared_ptr<endpoint_definition> &_target) {
+ if (_target) {
+ if (is_set_) {
+ message_->set_session(routing_->get_session());
+ routing_->send_to(_client, _target, message_);
+ } else {
+ VSOMEIP_INFO << __func__
+ << ": Notifying " << std::hex << get_event()
+ << " failed. Event payload not (yet) set!";
+ pending_.insert(_target);
+ }
} else {
- VSOMEIP_INFO << "Notify one event " << std::hex << message_->get_method()
- << "failed. Event payload not set!";
+ VSOMEIP_WARNING << __func__
+ << ": Notifying " << std::hex << get_event()
+ << " failed. Target undefined";
}
}
-void event::notify_one(client_t _client, bool _flush) {
+void event::notify_one(client_t _client) {
std::lock_guard<std::mutex> its_lock(mutex_);
- notify_one_unlocked(_client, _flush);
+ notify_one_unlocked(_client);
}
-void event::notify_one_unlocked(client_t _client, bool _flush) {
+void event::notify_one_unlocked(client_t _client) {
if (is_set_) {
- routing_->send(_client, message_, _flush);
+ message_->set_session(routing_->get_session());
+ routing_->send(_client, message_);
} else {
- VSOMEIP_INFO << "Notify one event " << std::hex << message_->get_method()
- << " to client " << _client << " failed. Event payload not set!";
+ VSOMEIP_INFO << __func__
+ << ": Notifying "
+ << std::hex << message_->get_method()
+ << " to client " << _client
+ << " failed. Event payload not set!";
}
}
bool event::set_payload_helper(const std::shared_ptr<payload> &_payload, bool _force) {
std::shared_ptr<payload> its_payload = message_->get_payload();
- bool is_change(!is_field_);
- if (is_field_) {
+ bool is_change(type_ != event_type_e::ET_FIELD);
+ if (!is_change) {
is_change = _force || epsilon_change_func_(its_payload, _payload);
}
return is_change;
@@ -357,7 +404,7 @@ bool event::add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _for
} else {
VSOMEIP_WARNING << __func__ << ": Didnt' insert client "
<< std::hex << std::setw(4) << std::setfill('0') << _client
- << "to eventgroup 0x"
+ << " to eventgroup 0x"
<< std::hex << std::setw(4) << std::setfill('0') << _eventgroup;
}
return ret;
@@ -480,20 +527,20 @@ bool event::is_subscribed(client_t _client) {
return false;
}
-bool event::is_reliable() const {
- return is_reliable_;
+reliability_type_e
+event::get_reliability() const {
+ return reliability_;
}
-void event::set_reliable(bool _is_reliable) {
- is_reliable_ = _is_reliable;
+void
+event::set_reliability(const reliability_type_e _reliability) {
+ reliability_ = _reliability;
}
-bool event::get_remote_notification_pending() {
- return remote_notification_pending_;
-}
-
-void event::set_remote_notification_pending(bool _value) {
- remote_notification_pending_ = _value;
+void
+event::remove_pending(const std::shared_ptr<endpoint_definition> &_target) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ pending_.erase(_target);
}
-} // namespace vsomeip
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index 77bb228..52c6c1e 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -4,46 +4,77 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <algorithm>
+#include <iomanip>
#include <vsomeip/constants.hpp>
-
+#include <vsomeip/internal/logger.hpp>
#include "../include/eventgroupinfo.hpp"
#include "../include/event.hpp"
+#include "../include/remote_subscription.hpp"
#include "../../endpoints/include/endpoint_definition.hpp"
-#include "../../logging/include/logger.hpp"
-#include "../../configuration/include/internal.hpp"
-
-namespace vsomeip {
-eventgroupinfo::eventgroupinfo() :
- major_(DEFAULT_MAJOR),
- ttl_(DEFAULT_TTL),
- port_(ILLEGAL_PORT),
- threshold_(0),
- has_reliable_(false),
- has_unreliable_(false),
- subscription_id_(DEFAULT_SUBSCRIPTION) {
+namespace vsomeip_v3 {
+
+eventgroupinfo::eventgroupinfo()
+ : service_(0),
+ instance_(0),
+ eventgroup_(0),
+ major_(DEFAULT_MAJOR),
+ ttl_(DEFAULT_TTL),
+ port_(ILLEGAL_PORT),
+ threshold_(0),
+ id_(PENDING_SUBSCRIPTION_ID),
+ reliability_(reliability_type_e::RT_UNKNOWN) {
}
-eventgroupinfo::eventgroupinfo(major_version_t _major, ttl_t _ttl) :
- major_(_major),
- ttl_(_ttl),
- port_(ILLEGAL_PORT),
- threshold_(0),
- has_reliable_(false),
- has_unreliable_(false),
- subscription_id_(DEFAULT_SUBSCRIPTION) {
+eventgroupinfo::eventgroupinfo(
+ const service_t _service, const instance_t _instance,
+ const eventgroup_t _eventgroup, const major_version_t _major,
+ const ttl_t _ttl)
+ : service_(_service),
+ instance_(_instance),
+ eventgroup_(_eventgroup),
+ major_(_major),
+ ttl_(_ttl),
+ port_(ILLEGAL_PORT),
+ threshold_(0),
+ id_(PENDING_SUBSCRIPTION_ID),
+ reliability_(reliability_type_e::RT_UNKNOWN) {
}
eventgroupinfo::~eventgroupinfo() {
}
+service_t eventgroupinfo::get_service() const {
+ return service_;
+}
+
+void eventgroupinfo::set_service(const service_t _service) {
+ service_ = _service;
+}
+
+instance_t eventgroupinfo::get_instance() const {
+ return instance_;
+}
+
+void eventgroupinfo::set_instance(const instance_t _instance) {
+ instance_ = _instance;
+}
+
+eventgroup_t eventgroupinfo::get_eventgroup() const {
+ return eventgroup_;
+}
+
+void eventgroupinfo::set_eventgroup(const eventgroup_t _eventgroup) {
+ eventgroup_ = _eventgroup;
+}
+
major_version_t eventgroupinfo::get_major() const {
return major_;
}
-void eventgroupinfo::set_major(major_version_t _major) {
+void eventgroupinfo::set_major(const major_version_t _major) {
major_ = _major;
}
@@ -51,7 +82,7 @@ ttl_t eventgroupinfo::get_ttl() const {
return ttl_;
}
-void eventgroupinfo::set_ttl(ttl_t _ttl) {
+void eventgroupinfo::set_ttl(const ttl_t _ttl) {
ttl_ = _ttl;
}
@@ -89,264 +120,239 @@ const std::set<std::shared_ptr<event> > eventgroupinfo::get_events() const {
return events_;
}
-void eventgroupinfo::add_event(std::shared_ptr<event> _event) {
+void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) {
std::lock_guard<std::mutex> its_lock(events_mutex_);
events_.insert(_event);
- _event->is_reliable() ? has_reliable_ = true : has_unreliable_ = true;
+
+ switch (_event->get_reliability()) {
+ case reliability_type_e::RT_RELIABLE:
+ if (reliability_ == reliability_type_e::RT_UNRELIABLE) {
+ reliability_ = reliability_type_e::RT_BOTH;
+ } else if (reliability_ != reliability_type_e::RT_BOTH) {
+ reliability_ = reliability_type_e::RT_RELIABLE;
+ }
+ break;
+ case reliability_type_e::RT_UNRELIABLE:
+ if (reliability_ == reliability_type_e::RT_RELIABLE) {
+ reliability_ = reliability_type_e::RT_BOTH;
+ } else if (reliability_ != reliability_type_e::RT_BOTH) {
+ reliability_ = reliability_type_e::RT_UNRELIABLE;
+ }
+ break;
+ case reliability_type_e::RT_BOTH:
+ reliability_ = reliability_type_e::RT_BOTH;
+ break;
+ default:
+ ;
+ }
}
-void eventgroupinfo::remove_event(std::shared_ptr<event> _event) {
+void eventgroupinfo::remove_event(const std::shared_ptr<event>& _event) {
std::lock_guard<std::mutex> its_lock(events_mutex_);
events_.erase(_event);
}
-void eventgroupinfo::get_reliability(bool& _has_reliable, bool& _has_unreliable) const {
- _has_reliable = has_reliable_;
- _has_unreliable = has_unreliable_;
+reliability_type_e eventgroupinfo::get_reliability() const {
+ return reliability_;
}
-const std::list<eventgroupinfo::target_t> eventgroupinfo::get_targets() const {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- return targets_;
-}
+uint32_t
+eventgroupinfo::get_unreliable_target_count() const {
+ uint32_t its_count(0);
-uint32_t eventgroupinfo::get_unreliable_target_count() const {
- uint32_t _count(0);
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- for (auto i = targets_.begin(); i != targets_.end(); i++) {
- if (!i->endpoint_->is_reliable()) {
- _count++;
- }
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ for (const auto &s : subscriptions_) {
+ auto its_subscription = s.second;
+ if (!its_subscription->get_parent()
+ && its_subscription->get_unreliable()) {
+ its_count++;
+ }
}
- return _count;
+
+ return its_count;
}
-void eventgroupinfo::add_multicast_target(const eventgroupinfo::target_t &_multicast_target) {
- std::lock_guard<std::mutex> its_lock(multicast_targets_mutex_);
- if (std::find(multicast_targets_.begin(), multicast_targets_.end(), _multicast_target)
- == multicast_targets_.end()) {
- multicast_targets_.push_back(_multicast_target);
- }
+uint8_t eventgroupinfo::get_threshold() const {
+ return threshold_;
}
-void eventgroupinfo::clear_multicast_targets() {
- std::lock_guard<std::mutex> its_lock(multicast_targets_mutex_);
- multicast_targets_.clear();
+void eventgroupinfo::set_threshold(uint8_t _threshold) {
+ threshold_ = _threshold;
}
-const std::list<eventgroupinfo::target_t> eventgroupinfo::get_multicast_targets() const {
- std::lock_guard<std::mutex> its_lock(multicast_targets_mutex_);
- return multicast_targets_;
+std::set<std::shared_ptr<remote_subscription> >
+eventgroupinfo::get_remote_subscriptions() const {
+ std::set<std::shared_ptr<remote_subscription> > its_subscriptions;
+
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ for (const auto &i : subscriptions_)
+ its_subscriptions.insert(i.second);
+
+ return its_subscriptions;
}
-bool eventgroupinfo::add_target(const eventgroupinfo::target_t &_target) {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- std::size_t its_size = targets_.size();
- if (std::find(targets_.begin(), targets_.end(), _target) == targets_.end()) {
- targets_.push_back(_target);
- }
- return (its_size != targets_.size());
-}
-
-bool eventgroupinfo::add_target(const eventgroupinfo::target_t &_target,
- const eventgroupinfo::target_t &_subscriber) {
- bool found(false);
- bool add(false);
- bool ret(false);
- {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- std::size_t its_size = targets_.size();
-
- for (auto i = targets_.begin(); i != targets_.end(); i++) {
- if (i->endpoint_->get_address() == _subscriber.endpoint_->get_address() &&
- i->endpoint_->get_port() == _subscriber.endpoint_->get_port() &&
- i->endpoint_->is_reliable() == _subscriber.endpoint_->is_reliable()) {
- found = true;
- break;
+bool
+eventgroupinfo::update_remote_subscription(
+ const std::shared_ptr<remote_subscription> &_subscription,
+ const std::chrono::steady_clock::time_point &_expiration,
+ std::set<client_t> &_changed, remote_subscription_id_t &_id,
+ const bool _is_subscribe) {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+
+ for (const auto& its_item : subscriptions_) {
+ if (its_item.second->equals(_subscription)) {
+ // update existing subscription
+ _changed = its_item.second->update(
+ _subscription->get_clients(), _expiration, _is_subscribe);
+ _id = its_item.second->get_id();
+
+ // Copy acknowledgment states from existing subscription
+ for (const auto its_client : _subscription->get_clients()) {
+ _subscription->set_client_state(its_client,
+ its_item.second->get_client_state(its_client));
}
- }
- if (!found) {
- targets_.push_back(_subscriber);
- add = true;
- }
- ret = (its_size != targets_.size());
- }
- if (add) {
- add_multicast_target(_target);
- }
- return ret;
-}
-
-bool eventgroupinfo::update_target(
- const std::shared_ptr<endpoint_definition> &_target,
- const std::chrono::steady_clock::time_point &_expiration) {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- bool updated_target(false);
-
- for (auto i = targets_.begin(); i != targets_.end(); i++) {
- if (i->endpoint_->get_address() == _target->get_address() &&
- i->endpoint_->get_port() == _target->get_port() &&
- i->endpoint_->is_reliable() == _target->is_reliable() ) {
- i->expiration_ = _expiration;
- updated_target = true;
- break;
+ if (_is_subscribe) {
+ if (!_changed.empty()) {
+ // New clients:
+ // Let this be a child subscription
+ _subscription->set_parent(its_item.second);
+ update_id();
+ _subscription->set_id(id_);
+ subscriptions_[id_] = _subscription;
+ } else {
+ if (!_subscription->is_pending()) {
+ if (!_subscription->force_initial_events()) {
+ _subscription->set_initial(false);
+ }
+ } else {
+ its_item.second->set_answers(
+ its_item.second->get_answers() + 1);
+ }
+ }
+ } else {
+ if (its_item.second->is_pending()) {
+ for (const auto &its_event : events_)
+ its_event->remove_pending(
+ its_item.second->get_subscriber());
+ }
+ }
+
+ return true;
}
}
- return updated_target;
+
+ return false;
}
-bool eventgroupinfo::remove_target(
- const std::shared_ptr<endpoint_definition> &_target) {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- std::size_t its_size = targets_.size();
+remote_subscription_id_t
+eventgroupinfo::add_remote_subscription(
+ const std::shared_ptr<remote_subscription> &_subscription) {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ update_id();
- for (auto i = targets_.begin(); i != targets_.end(); i++) {
- if (i->endpoint_->get_address() == _target->get_address() &&
- i->endpoint_->get_port() == _target->get_port() &&
- i->endpoint_->is_reliable() == _target->is_reliable()) {
- targets_.erase(i);
- break;
- }
- }
+ _subscription->set_id(id_);
+ subscriptions_[id_] = _subscription;
- return (its_size != targets_.size());
+ return id_;
}
-void eventgroupinfo::clear_targets() {
- std::lock_guard<std::mutex> its_lock(targets_mutex_);
- targets_.clear();
+std::shared_ptr<remote_subscription>
+eventgroupinfo::get_remote_subscription(
+ const remote_subscription_id_t _id) {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+
+ auto find_subscription = subscriptions_.find(_id);
+ if (find_subscription != subscriptions_.end())
+ return find_subscription->second;
+
+ return nullptr;
}
-uint8_t eventgroupinfo::get_threshold() const {
- return threshold_;
+void
+eventgroupinfo::remove_remote_subscription(
+ const remote_subscription_id_t _id) {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ subscriptions_.erase(_id);
}
-void eventgroupinfo::set_threshold(uint8_t _threshold) {
- threshold_ = _threshold;
+std::set<std::shared_ptr<endpoint_definition> >
+eventgroupinfo::get_unicast_targets() const {
+ std::set<std::shared_ptr<endpoint_definition>> its_targets;
+
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ for (const auto &s : subscriptions_) {
+ const auto its_reliable = s.second->get_reliable();
+ if (its_reliable)
+ its_targets.insert(its_reliable);
+ const auto its_unreliable = s.second->get_unreliable();
+ if (its_unreliable)
+ its_targets.insert(its_unreliable);
+ }
+
+ return its_targets;
}
-std::unique_lock<std::mutex> eventgroupinfo::get_subscription_lock() {
- return std::unique_lock<std::mutex>(subscription_mutex_);
+std::set<std::shared_ptr<endpoint_definition> >
+eventgroupinfo::get_multicast_targets() const {
+ std::set<std::shared_ptr<endpoint_definition>> its_targets;
+ return its_targets;
}
-pending_subscription_id_t eventgroupinfo::add_pending_subscription(
- pending_subscription_t _pending_subscription) {
- std::lock_guard<std::mutex> its_lock(pending_subscriptions_mutex_);
- if (++subscription_id_ == DEFAULT_SUBSCRIPTION) {
- subscription_id_++;
- }
- _pending_subscription.pending_subscription_id_ = subscription_id_;
- pending_subscriptions_[subscription_id_] = _pending_subscription;
-
- const auto remote_address_port = std::make_tuple(
- _pending_subscription.subscriber_->get_address(),
- _pending_subscription.subscriber_->get_port(),
- _pending_subscription.subscriber_->is_reliable());
-
- auto found_address = pending_subscriptions_by_remote_.find(remote_address_port);
- if (found_address != pending_subscriptions_by_remote_.end()) {
- found_address->second.push_back(subscription_id_);
- VSOMEIP_WARNING << __func__ << " num pending subscriptions: "
- << std::dec << found_address->second.size();
- return DEFAULT_SUBSCRIPTION;
- } else {
- pending_subscriptions_by_remote_[remote_address_port].push_back(subscription_id_);
- }
- return subscription_id_;
-}
-
-std::vector<pending_subscription_t> eventgroupinfo::remove_pending_subscription(
- pending_subscription_id_t _subscription_id) {
- std::vector<pending_subscription_t> its_pending_subscriptions;
- std::lock_guard<std::mutex> its_lock(pending_subscriptions_mutex_);
- const auto found_pending_subscription = pending_subscriptions_.find(
- _subscription_id);
- if (found_pending_subscription != pending_subscriptions_.end()) {
- pending_subscription_t its_pending_sub = found_pending_subscription->second;
- const auto remote_address_port = std::make_tuple(
- its_pending_sub.subscriber_->get_address(),
- its_pending_sub.subscriber_->get_port(),
- its_pending_sub.subscriber_->is_reliable());
- const bool removed_is_subscribe = (found_pending_subscription->second.ttl_ > 0);
-
- // check if more (un)subscriptions to this eventgroup arrived from the
- // same remote during the time the current pending subscription was processed
- auto found_remote = pending_subscriptions_by_remote_.find(remote_address_port);
- if (found_remote != pending_subscriptions_by_remote_.end()) {
- if (found_remote->second.size()
- && found_remote->second.front() == _subscription_id) {
- pending_subscriptions_.erase(found_pending_subscription);
- found_remote->second.erase(found_remote->second.begin());
-
- // return removed (un)subscription as first element
- its_pending_subscriptions.push_back(its_pending_sub);
-
- // retrieve all pending (un)subscriptions which arrived during
- // the time the rm_proxy answered the currently processed subscription
- for (auto iter = found_remote->second.begin();
- iter != found_remote->second.end();) {
- const auto other_pen_sub = pending_subscriptions_.find(*iter);
- if (other_pen_sub != pending_subscriptions_.end()) {
- const bool queued_is_subscribe = (other_pen_sub->second.ttl_ > 0);
- if (removed_is_subscribe) {
- its_pending_subscriptions.push_back(other_pen_sub->second);
- if (!queued_is_subscribe) {
- // unsubscribe was queued and needs to be sent to
- // rm_proxy first before continuing processing
- // following queued (un)subscriptions
- break;
- } else {
- iter = found_remote->second.erase(iter);
- pending_subscriptions_.erase(other_pen_sub);
- }
- } else {
- if (queued_is_subscribe) {
- // subscribe was queued and needs to be sent to
- // rm_proxy first before continuing processing
- // following queued (un)subscriptions
- its_pending_subscriptions.push_back(other_pen_sub->second);
- break;
- } else {
- // further queued unsubscriptions can be ignored
- iter = found_remote->second.erase(iter);
- pending_subscriptions_.erase(other_pen_sub);
- }
- }
- } else {
- VSOMEIP_ERROR << __func__ << " didn't find queued subscription: "
- << *iter;
- ++iter;
- }
- }
+bool eventgroupinfo::is_selective() const {
+ /* Selective eventgroups always contain a single event */
+ std::lock_guard<std::mutex> its_lock(events_mutex_);
+ if (events_.size() != 1)
+ return false;
- if (found_remote->second.empty()) {
- pending_subscriptions_by_remote_.erase(found_remote);
- }
- } else {
- boost::system::error_code ec;
- VSOMEIP_WARNING << __func__ << " Subscriptions were answered in "
- << " in wrong order by rm_proxy! ["
- << " subscriber: " << std::get<0>(remote_address_port).to_string(ec)
- << ":" << std::dec << std::get<1>(remote_address_port);
- // found_pending_subscription isn't deleted from
- // pending_subscriptions_ map in this case to ensure answer
- // sequence of SD messages.
- its_pending_subscriptions.clear();
- }
- }
- } else {
- VSOMEIP_ERROR << __func__ << " didn't find pending_subscription: "
- << _subscription_id;
- }
- return its_pending_subscriptions;
+ return ((*events_.begin())->get_type()
+ == event_type_e::ET_SELECTIVE_EVENT);
}
+void
+eventgroupinfo::update_id() {
+ id_++;
+ if (id_ == PENDING_SUBSCRIPTION_ID)
+ id_ = 1;
+}
-void eventgroupinfo::clear_pending_subscriptions() {
- std::lock_guard<std::mutex> its_lock(pending_subscriptions_mutex_);
- pending_subscriptions_.clear();
- pending_subscriptions_by_remote_.clear();
+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);
+ }
+#endif
+ }
+ }
}
-} // namespace vsomeip
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp
new file mode 100644
index 0000000..a896b36
--- /dev/null
+++ b/implementation/routing/src/remote_subscription.cpp
@@ -0,0 +1,315 @@
+// Copyright (C) 2018 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/remote_subscription.hpp"
+
+#include <vsomeip/internal/logger.hpp>
+
+namespace vsomeip_v3 {
+
+remote_subscription::remote_subscription()
+ : id_(PENDING_SUBSCRIPTION_ID),
+ is_initial_(true),
+ force_initial_events_(false),
+ major_(DEFAULT_MAJOR),
+ ttl_(DEFAULT_TTL),
+ reserved_(0),
+ counter_(0),
+ answers_(1) {
+}
+
+remote_subscription::~remote_subscription() {
+}
+
+bool
+remote_subscription::operator==(
+ const remote_subscription &_other) const {
+ auto own_egi = eventgroupinfo_.lock();
+ auto other_egi = _other.eventgroupinfo_.lock();
+ bool reliable_equal(true);
+ if (reliable_ && _other.reliable_) {
+ reliable_equal = (reliable_ == _other.reliable_);
+ }
+ bool unreliable_equal(true);
+ if (unreliable_ && _other.unreliable_) {
+ unreliable_equal = (unreliable_ == _other.unreliable_);
+ }
+ return (own_egi && other_egi && own_egi == other_egi && unreliable_equal
+ && reliable_equal);
+}
+
+bool
+remote_subscription::equals(
+ const std::shared_ptr<remote_subscription> &_other) const {
+ return operator ==(*_other);
+}
+
+void
+remote_subscription::reset(const std::set<client_t> &_clients) {
+ auto its_client_state = std::make_pair(
+ remote_subscription_state_e::SUBSCRIPTION_PENDING,
+ std::chrono::steady_clock::time_point());
+ if (_clients.empty()) {
+ clients_[0] = its_client_state;
+ } else {
+ for (const auto &its_client : _clients)
+ clients_[its_client] = its_client_state;
+ }
+}
+
+bool
+remote_subscription::is_initial() const {
+ return is_initial_;
+}
+
+void
+remote_subscription::set_initial(const bool _is_initial) {
+ is_initial_ = _is_initial;
+}
+
+bool
+remote_subscription::force_initial_events() const {
+ return force_initial_events_;
+}
+
+void
+remote_subscription::set_force_initial_events(
+ const bool _force_initial_events) {
+ force_initial_events_ = _force_initial_events;
+}
+
+remote_subscription_id_t
+remote_subscription::get_id() const {
+ return id_;
+}
+
+void
+remote_subscription::set_id(const remote_subscription_id_t _id) {
+ id_ = _id;
+}
+
+std::shared_ptr<eventgroupinfo>
+remote_subscription::get_eventgroupinfo() const {
+ return eventgroupinfo_.lock();
+}
+
+void
+remote_subscription::set_eventgroupinfo(
+ const std::shared_ptr<eventgroupinfo> &_info) {
+ eventgroupinfo_ = _info;
+}
+
+ttl_t
+remote_subscription::get_ttl() const {
+ return ttl_;
+}
+
+void
+remote_subscription::set_ttl(const ttl_t _ttl) {
+ ttl_ = _ttl;
+}
+
+uint16_t
+remote_subscription::get_reserved() const {
+ return reserved_;
+}
+
+void
+remote_subscription::set_reserved(const uint16_t _reserved) {
+ reserved_ = _reserved;
+}
+
+uint8_t
+remote_subscription::get_counter() const {
+ return counter_;
+}
+
+void
+remote_subscription::set_counter(uint8_t _counter) {
+ counter_ = _counter;
+}
+
+std::set<client_t>
+remote_subscription::get_clients() const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ std::set<client_t> its_clients;
+ for (const auto its_item : clients_)
+ its_clients.insert(its_item.first);
+ return its_clients;
+}
+
+bool
+remote_subscription::has_client() const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ return (clients_.size() > 0);
+}
+
+bool
+remote_subscription::has_client(const client_t _client) const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ return (clients_.find(_client) != clients_.end());
+}
+
+void
+remote_subscription::remove_client(const client_t _client) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ clients_.erase(_client);
+}
+
+remote_subscription_state_e
+remote_subscription::get_client_state(const client_t _client) const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ auto found_client = clients_.find(_client);
+ if (found_client != clients_.end()) {
+ return found_client->second.first;
+ }
+ return remote_subscription_state_e::SUBSCRIPTION_UNKNOWN;
+}
+
+void
+remote_subscription::set_client_state(const client_t _client,
+ remote_subscription_state_e _state) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ auto found_item = clients_.find(_client);
+ if (found_item != clients_.end()) {
+ found_item->second.first = _state;
+ 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();
+ }
+ }
+}
+
+void
+remote_subscription::set_all_client_states(remote_subscription_state_e _state) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ for (auto &its_item : clients_)
+ its_item.second.first = _state;
+}
+
+std::shared_ptr<endpoint_definition>
+remote_subscription::get_subscriber() const {
+ return subscriber_;
+}
+
+void
+remote_subscription::set_subscriber(
+ const std::shared_ptr<endpoint_definition> &_subscriber) {
+ subscriber_ = _subscriber;
+}
+
+std::shared_ptr<endpoint_definition>
+remote_subscription::get_reliable() const {
+ return reliable_;
+}
+
+void
+remote_subscription::set_reliable(
+ const std::shared_ptr<endpoint_definition> &_reliable) {
+ reliable_ = _reliable;
+}
+
+std::shared_ptr<endpoint_definition>
+remote_subscription::get_unreliable() const {
+ return unreliable_;
+}
+
+void
+remote_subscription::set_unreliable(
+ const std::shared_ptr<endpoint_definition> &_unreliable) {
+ unreliable_ = _unreliable;
+}
+
+bool
+remote_subscription::is_pending() const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ for (auto its_client : clients_) {
+ if (its_client.second.first
+ == remote_subscription_state_e::SUBSCRIPTION_PENDING) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+remote_subscription::is_acknowledged() const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ for (auto its_client : clients_) {
+ if (its_client.second.first
+ != remote_subscription_state_e::SUBSCRIPTION_ACKED) {
+ return false;
+ }
+ }
+ return true;
+}
+
+std::chrono::steady_clock::time_point
+remote_subscription::get_expiration(const client_t _client) const {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ auto found_client = clients_.find(_client);
+ if (found_client != clients_.end()) {
+ return found_client->second.second;
+ }
+ return std::chrono::steady_clock::now();
+}
+
+std::set<client_t>
+remote_subscription::update(const std::set<client_t> &_clients,
+ const std::chrono::steady_clock::time_point &_timepoint,
+ const bool _is_subscribe) {
+ std::set<client_t> its_changed;
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ for (const auto &its_client : _clients) {
+ auto found_client = clients_.find(its_client);
+ if (_is_subscribe) {
+ if (found_client != clients_.end()) {
+ found_client->second.second = _timepoint;
+ } else {
+ its_changed.insert(its_client);
+ }
+ } else {
+ if (found_client != clients_.end()) {
+ its_changed.insert(its_client);
+ }
+ }
+ }
+
+ for (const auto &its_client : its_changed) {
+ if (_is_subscribe) {
+ clients_[its_client] = std::make_pair(
+ remote_subscription_state_e::SUBSCRIPTION_PENDING, _timepoint);
+ } else {
+ clients_.erase(its_client);
+ }
+ }
+
+ return its_changed;
+}
+
+std::shared_ptr<remote_subscription>
+remote_subscription::get_parent() const {
+ return parent_.lock();
+}
+
+void
+remote_subscription::set_parent(
+ const std::shared_ptr<remote_subscription> &_parent) {
+ parent_ = _parent;
+}
+
+std::uint32_t
+remote_subscription::get_answers() const {
+ return answers_;
+}
+
+void
+remote_subscription::set_answers(const std::uint32_t _answers) {
+ answers_ = _answers;
+}
+
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp
index 517ccdb..77e5b83 100644
--- a/implementation/routing/src/routing_manager_base.cpp
+++ b/implementation/routing/src/routing_manager_base.cpp
@@ -6,40 +6,47 @@
#include <iomanip>
#include <vsomeip/runtime.hpp>
+#include <vsomeip/internal/logger.hpp>
-#include "../../utility/include/utility.hpp"
-#include "../../utility/include/byteorder.hpp"
#include "../include/routing_manager_base.hpp"
-#include "../../logging/include/logger.hpp"
#include "../../endpoints/include/local_client_endpoint_impl.hpp"
#include "../../endpoints/include/local_server_endpoint_impl.hpp"
+#include "../../security/include/security.hpp"
#ifdef USE_DLT
#include "../../tracing/include/connector_impl.hpp"
#endif
+#include "../../utility/include/byteorder.hpp"
+#include "../../utility/include/utility.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
routing_manager_base::routing_manager_base(routing_manager_host *_host) :
host_(_host),
io_(host_->get_io()),
client_(host_->get_client()),
- configuration_(host_->get_configuration()),
- serializer_(
- std::make_shared<serializer>(
- configuration_->get_buffer_shrink_threshold()))
+ configuration_(host_->get_configuration())
#ifdef USE_DLT
, tc_(trace::connector_impl::get())
#endif
{
+ const std::size_t its_max = configuration_->get_io_thread_count(host_->get_name());
const uint32_t its_buffer_shrink_threshold =
configuration_->get_buffer_shrink_threshold();
- for (int i = 0; i < VSOMEIP_MAX_DESERIALIZER; ++i) {
+
+ for (std::size_t i = 0; i < its_max; ++i) {
+ serializers_.push(
+ std::make_shared<serializer>(its_buffer_shrink_threshold));
deserializers_.push(
- std::make_shared<deserializer>(its_buffer_shrink_threshold));
+ std::make_shared<deserializer>(its_buffer_shrink_threshold));
}
-}
-routing_manager_base::~routing_manager_base() {
+ own_uid_ = ANY_UID;
+ own_gid_ = ANY_GID;
+#ifndef _WIN32
+ own_uid_ = getuid();
+ own_gid_ = getgid();
+#endif
+
}
boost::asio::io_service & routing_manager_base::get_io() {
@@ -50,12 +57,21 @@ client_t routing_manager_base::get_client() const {
return client_;
}
-void routing_manager_base::init() {
+void routing_manager_base::set_client(const client_t &_client) {
+ client_ = _client;
+}
+
+session_t routing_manager_base::get_session() {
+ return host_->get_session();
+}
+
+void routing_manager_base::init(const std::shared_ptr<endpoint_manager_base>& _endpoint_manager) {
+ ep_mgr_ = _endpoint_manager;
}
-bool routing_manager_base::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor) {
+bool routing_manager_base::offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
(void)_client;
// Remote route (incoming only)
@@ -67,7 +83,6 @@ bool routing_manager_base::offer_service(client_t _client, service_t _service,
&& its_info->get_minor() == _minor) {
its_info->set_ttl(DEFAULT_TTL);
} else {
- host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
VSOMEIP_ERROR << "rm_base::offer_service service property mismatch ("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
@@ -98,11 +113,13 @@ bool routing_manager_base::offer_service(client_t _client, service_t _service,
return true;
}
-void routing_manager_base::stop_offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor) {
+void routing_manager_base::stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
(void)_client;
(void)_major;
(void)_minor;
+
std::map<event_t, std::shared_ptr<event> > events;
{
std::lock_guard<std::mutex> its_lock(events_mutex_);
@@ -122,11 +139,9 @@ void routing_manager_base::stop_offer_service(client_t _client, service_t _servi
}
}
-void routing_manager_base::request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy) {
- (void)_use_exclusive_proxy;
-
+void routing_manager_base::request_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
auto its_info = find_service(_service, _instance);
if (its_info) {
if ((_major == its_info->get_major()
@@ -137,7 +152,6 @@ void routing_manager_base::request_service(client_t _client, service_t _service,
|| _minor == ANY_MINOR)) {
its_info->add_client(_client);
} else {
- host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
VSOMEIP_ERROR << "rm_base::request_service service property mismatch ("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
@@ -150,8 +164,8 @@ void routing_manager_base::request_service(client_t _client, service_t _service,
}
}
-void routing_manager_base::release_service(client_t _client, service_t _service,
- instance_t _instance) {
+void routing_manager_base::release_service(client_t _client,
+ service_t _service, instance_t _instance) {
auto its_info = find_service(_service, _instance);
if (its_info) {
its_info->remove_client(_client);
@@ -168,38 +182,84 @@ void routing_manager_base::release_service(client_t _client, service_t _service,
}
}
-void routing_manager_base::register_event(client_t _client, service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups, bool _is_field,
- std::chrono::milliseconds _cycle, bool _change_resets_cycle,
- epsilon_change_func_t _epsilon_change_func,
- bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) {
- std::lock_guard<std::mutex> its_event_reg_lock(event_registration_mutex_);
- std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
+void routing_manager_base::register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups,
+ const event_type_e _type,
+ reliability_type_e _reliability,
+ std::chrono::milliseconds _cycle, bool _change_resets_cycle,
+ bool _update_on_change,
+ epsilon_change_func_t _epsilon_change_func,
+ bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) {
+ std::lock_guard<std::mutex> its_registration_lock(event_registration_mutex_);
+
+ auto determine_event_reliability = [this, &_service, &_instance,
+ &_notifier, &_reliability]() {
+ reliability_type_e its_reliability =
+ configuration_->get_event_reliability(_service, _instance, _notifier);
+ if (its_reliability != reliability_type_e::RT_UNKNOWN) {
+ // event was explicitly configured -> overwrite value passed via API
+ return its_reliability;
+ } else if (_reliability != reliability_type_e::RT_UNKNOWN) {
+ // use value provided via API
+ return _reliability;
+ } else { // automatic mode, user service' reliability
+ return configuration_->get_service_reliability(_service, _instance);
+ }
+ };
+
+ std::shared_ptr<event> its_event = find_event(_service, _instance, _notifier);
bool transfer_subscriptions_from_any_event(false);
if (its_event) {
- if(!its_event->is_cache_placeholder()) {
- if (its_event->is_field() == _is_field) {
+ if (!its_event->is_cache_placeholder()) {
+ if (_type == its_event->get_type()
+ || its_event->get_type() == event_type_e::ET_UNKNOWN
+#ifdef VSOMEIP_ENABLE_COMPAT
+ || (its_event->get_type() == event_type_e::ET_EVENT
+ && _type == event_type_e::ET_SELECTIVE_EVENT)
+ || (its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT
+ && _type == event_type_e::ET_EVENT && _is_provided)
+#endif
+ ) {
+#ifdef VSOMEIP_ENABLE_COMPAT
+ if (its_event->get_type() == event_type_e::ET_EVENT
+ && _type == event_type_e::ET_SELECTIVE_EVENT) {
+ its_event->set_type(_type);
+ VSOMEIP_INFO << "Event type changed to selective ("
+ << std::hex << std::setw(4) << std::setfill('0') << _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 << "]";
+ }
+#endif
if (_is_provided) {
its_event->set_provided(true);
+ its_event->set_reliability(determine_event_reliability());
}
if (_is_shadow && _is_provided) {
its_event->set_shadow(_is_shadow);
}
if (_client == host_->get_client() && _is_provided) {
its_event->set_shadow(false);
+ its_event->set_update_on_change(_update_on_change);
}
for (auto eg : _eventgroups) {
its_event->add_eventgroup(eg);
}
transfer_subscriptions_from_any_event = true;
} else {
- VSOMEIP_ERROR << "Event registration update failed. "
- "Specified arguments do not match existing registration.";
+#ifdef VSOMEIP_ENABLE_COMPAT
+ if (!(its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT
+ && _type == event_type_e::ET_EVENT))
+#endif
+ VSOMEIP_ERROR << "Event registration update failed. "
+ "Specified arguments do not match existing registration.";
}
} else {
// the found event was a placeholder for caching.
// update it with the real values
- if(!_is_field) {
+ if (_type != event_type_e::ET_FIELD) {
// don't cache payload for non-fields
its_event->unset_payload(true);
}
@@ -208,8 +268,10 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
}
if (_client == host_->get_client() && _is_provided) {
its_event->set_shadow(false);
+ its_event->set_update_on_change(_update_on_change);
}
- its_event->set_field(_is_field);
+ its_event->set_type(_type);
+ its_event->set_reliability(determine_event_reliability());
its_event->set_provided(_is_provided);
its_event->set_cache_placeholder(false);
std::shared_ptr<serviceinfo> its_service = find_service(_service, _instance);
@@ -218,7 +280,7 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
}
if (_eventgroups.size() == 0) { // No eventgroup specified
std::set<eventgroup_t> its_eventgroups;
- its_eventgroups.insert(_event);
+ its_eventgroups.insert(_notifier);
its_event->set_eventgroups(its_eventgroups);
} else {
for (auto eg : _eventgroups) {
@@ -232,11 +294,11 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
}
} else {
its_event = std::make_shared<event>(this, _is_shadow);
- its_event->set_reliable(configuration_->is_event_reliable(_service, _instance, _event));
its_event->set_service(_service);
its_event->set_instance(_instance);
- its_event->set_event(_event);
- its_event->set_field(_is_field);
+ its_event->set_event(_notifier);
+ its_event->set_type(_type);
+ its_event->set_reliability(determine_event_reliability());
its_event->set_provided(_is_provided);
its_event->set_cache_placeholder(_is_cache_placeholder);
std::shared_ptr<serviceinfo> its_service = find_service(_service, _instance);
@@ -246,15 +308,15 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
if (_eventgroups.size() == 0) { // No eventgroup specified
std::set<eventgroup_t> its_eventgroups;
- its_eventgroups.insert(_event);
+ its_eventgroups.insert(_notifier);
its_event->set_eventgroups(its_eventgroups);
} else {
its_event->set_eventgroups(_eventgroups);
}
if (_is_shadow && !_epsilon_change_func) {
- std::shared_ptr<vsomeip::cfg::debounce> its_debounce
- = configuration_->get_debounce(_service, _instance, _event);
+ std::shared_ptr<cfg::debounce> its_debounce
+ = configuration_->get_debounce(_service, _instance, _notifier);
if (its_debounce) {
VSOMEIP_WARNING << "Using debounce configuration for "
<< " SOME/IP event "
@@ -263,7 +325,7 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
<< std::hex << std::setw(4) << std::setfill('0')
<< _instance << "."
<< std::hex << std::setw(4) << std::setfill('0')
- << _event << ".";
+ << _notifier << ".";
std::stringstream its_debounce_parameters;
its_debounce_parameters << "(on_change="
<< (its_debounce->on_change_ ? "true" : "false")
@@ -349,6 +411,7 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
its_event->set_epsilon_change_function(_epsilon_change_func);
its_event->set_change_resets_cycle(_change_resets_cycle);
its_event->set_update_cycle(_cycle);
+ its_event->set_update_on_change(_update_on_change);
if (_is_provided) {
transfer_subscriptions_from_any_event = true;
@@ -381,18 +444,21 @@ void routing_manager_base::register_event(client_t _client, service_t _service,
}
for (auto eg : _eventgroups) {
- std::shared_ptr<eventgroupinfo> its_eventgroup_info
+ std::shared_ptr<eventgroupinfo> its_eventgroupinfo
= find_eventgroup(_service, _instance, eg);
- if (!its_eventgroup_info) {
- its_eventgroup_info = std::make_shared<eventgroupinfo>();
+ if (!its_eventgroupinfo) {
+ its_eventgroupinfo = std::make_shared<eventgroupinfo>();
+ its_eventgroupinfo->set_service(_service);
+ its_eventgroupinfo->set_instance(_instance);
+ its_eventgroupinfo->set_eventgroup(eg);
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
- eventgroups_[_service][_instance][eg] = its_eventgroup_info;
+ eventgroups_[_service][_instance][eg] = its_eventgroupinfo;
}
- its_eventgroup_info->add_event(its_event);
+ its_eventgroupinfo->add_event(its_event);
}
std::lock_guard<std::mutex> its_lock(events_mutex_);
- events_[_service][_instance][_event] = its_event;
+ events_[_service][_instance][_notifier] = its_event;
}
void routing_manager_base::unregister_event(client_t _client, service_t _service, instance_t _instance,
@@ -470,7 +536,9 @@ std::vector<event_t> routing_manager_base::find_events(
bool routing_manager_base::is_response_allowed(client_t _sender, service_t _service,
instance_t _instance, method_t _method) {
- if (!configuration_->is_security_enabled()) {
+
+ const auto its_security(security::get());
+ if (!its_security->is_enabled()) {
return true;
}
@@ -495,7 +563,7 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv
// service is now offered by another client
// or service is not offered at all
std::string security_mode_text = "!";
- if (!configuration_->is_audit_mode_enabled()) {
+ if (!its_security->is_audit()) {
security_mode_text = ", but will be allowed due to audit mode is active!";
}
@@ -506,16 +574,23 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv
<< _service << "/" << _instance << "/" << _method
<< security_mode_text;
- return !configuration_->is_audit_mode_enabled();
+ return !its_security->is_audit();
}
-bool routing_manager_base::is_subscribe_to_any_event_allowed(client_t _client,
+bool routing_manager_base::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
+
+ const auto its_security(security::get());
+ const uid_t its_uid(std::get<0>(_credentials));
+ const gid_t its_gid(std::get<1>(_credentials));
+
bool is_allowed(true);
+
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- for (auto e : its_eventgroup->get_events()) {
- if (!configuration_->is_client_allowed(_client, _service, _instance, e->get_event())) {
+ for (const auto& e : its_eventgroup->get_events()) {
+ if (!its_security->is_client_allowed(its_uid, its_gid,
+ _client, _service, _instance, e->get_event())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex
<< _client << " : routing_manager_base::is_subscribe_to_any_event_allowed: "
<< "subscribes to service/instance/event "
@@ -526,16 +601,17 @@ bool routing_manager_base::is_subscribe_to_any_event_allowed(client_t _client,
}
}
}
+
return is_allowed;
}
-void routing_manager_base::subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, event_t _event,
- subscription_type_e _subscription_type) {
+void routing_manager_base::subscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, event_t _event) {
(void) _major;
- (void) _subscription_type;
+ (void)_uid;
+ (void)_gid;
std::set<event_t> its_already_subscribed_events;
bool inserted = insert_subscription(_service, _instance, _eventgroup,
_event, _client, &its_already_subscribed_events);
@@ -545,8 +621,10 @@ void routing_manager_base::subscribe(client_t _client, service_t _service,
}
}
-void routing_manager_base::unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
+void routing_manager_base::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,event_t _event) {
+ (void)_uid;
+ (void)_gid;
if (_event != ANY_EVENT) {
auto its_event = find_event(_service, _instance, _event);
if (its_event) {
@@ -555,8 +633,9 @@ void routing_manager_base::unsubscribe(client_t _client, service_t _service,
} else {
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- for (auto e : its_eventgroup->get_events()) {
- e->remove_subscriber(_eventgroup, _client);
+ for (const auto &e : its_eventgroup->get_events()) {
+ if (e)
+ e->remove_subscriber(_eventgroup, _client);
}
}
}
@@ -564,10 +643,10 @@ void routing_manager_base::unsubscribe(client_t _client, service_t _service,
void routing_manager_base::notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- bool _force, bool _flush) {
+ bool _force) {
std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
if (its_event) {
- its_event->set_payload(_payload, _force, _flush);
+ its_event->set_payload(_payload, _force);
} else {
VSOMEIP_WARNING << "Attempt to update the undefined event/field ["
<< std::hex << _service << "." << _instance << "." << _event
@@ -577,14 +656,20 @@ void routing_manager_base::notify(service_t _service, instance_t _instance,
void routing_manager_base::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
- client_t _client, bool _force, bool _flush, bool _remote_subscriber) {
+ client_t _client, bool _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , bool _remote_subscriber
+#endif
+ ) {
std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
if (its_event) {
// Event is valid for service/instance
bool found_eventgroup(false);
bool already_subscribed(false);
+#ifdef VSOMEIP_ENABLE_COMPAT
eventgroup_t valid_group = 0;
subscription_state_e its_subscription_state(subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED);
+#endif
// Iterate over all groups of the event to ensure at least
// one valid eventgroup for service/instance exists.
for (auto its_group : its_event->get_eventgroups()) {
@@ -592,14 +677,21 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
if (its_eventgroup) {
// Eventgroup is valid for service/instance
found_eventgroup = true;
+#ifdef VSOMEIP_ENABLE_COMPAT
valid_group = its_group;
its_subscription_state = get_incoming_subscription_state(_client, _service,
_instance, valid_group, _event);
- if (find_local(_client)) {
+#endif
+ if (ep_mgr_->find_local(_client)) {
already_subscribed = its_event->has_subscriber(its_group, _client);
+#ifdef VSOMEIP_ENABLE_COMPAT
} else if (subscription_state_e::IS_SUBSCRIBING != its_subscription_state
|| _remote_subscriber) {
// Remotes always needs to be marked as subscribed here if they are not currently subscribing
+#else
+ } else {
+ // Remotes always needs to be marked as subscribed here
+#endif
already_subscribed = true;
}
break;
@@ -607,8 +699,10 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
}
if (found_eventgroup) {
if (already_subscribed) {
- its_event->set_payload(_payload, _client, _force, _flush);
- } else {
+ its_event->set_payload(_payload, _client, _force);
+ }
+#ifdef VSOMEIP_ENABLE_COMPAT
+ else {
// cache notification if subscription is in progress
if (subscription_state_e::IS_SUBSCRIBING == its_subscription_state) {
VSOMEIP_INFO << "routing_manager_base::notify_one("
@@ -634,6 +728,7 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
}
}
}
+#endif
}
} else {
VSOMEIP_WARNING << "Attempt to update the undefined event/field ["
@@ -642,6 +737,7 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
}
}
+#ifdef VSOMEIP_ENABLE_COMPAT
void routing_manager_base::send_pending_notify_ones(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client, bool _remote_subscriber) {
std::lock_guard<std::recursive_mutex> its_lock(pending_notify_ones_mutex_);
@@ -659,12 +755,13 @@ void routing_manager_base::send_pending_notify_ones(service_t _service, instance
<< std::hex << std::setw(4) << std::setfill('0') << its_group->second->get_method() << "]";
notify_one(_service, _instance, its_group->second->get_method(),
- its_group->second->get_payload(), _client, false, true, _remote_subscriber);
+ its_group->second->get_payload(), _client, false, _remote_subscriber);
its_instance->second.erase(_eventgroup);
}
}
}
}
+#endif
void routing_manager_base::unset_all_eventpayloads(service_t _service,
instance_t _instance) {
@@ -719,16 +816,16 @@ void routing_manager_base::notify_one_current_value(
if (_event != ANY_EVENT) {
std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
if (its_event && its_event->is_field())
- its_event->notify_one(_client, true);
+ its_event->notify_one(_client);
} else {
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
std::set<std::shared_ptr<event> > its_events = its_eventgroup->get_events();
- for (auto e : its_events) {
+ for (const auto &e : its_events) {
if (e->is_field()
&& _events_to_exclude.find(e->get_event())
== _events_to_exclude.end()) {
- e->notify_one(_client, true); // TODO: use _flush to send all events together!
+ e->notify_one(_client);
}
}
}
@@ -736,18 +833,19 @@ void routing_manager_base::notify_one_current_value(
}
bool routing_manager_base::send(client_t _client,
- std::shared_ptr<message> _message,
- bool _flush) {
+ std::shared_ptr<message> _message) {
bool is_sent(false);
if (utility::is_request(_message->get_message_type())) {
_message->set_client(_client);
}
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(_message.get())) {
- is_sent = send(_client, serializer_->get_data(),
- serializer_->get_size(), _message->get_instance(),
- _flush, _message->is_reliable(), get_client(), true, false);
- serializer_->reset();
+
+ std::shared_ptr<serializer> its_serializer(get_serializer());
+ if (its_serializer->serialize(_message.get())) {
+ is_sent = send(_client, its_serializer->get_data(),
+ its_serializer->get_size(), _message->get_instance(),
+ _message->is_reliable(), get_client(), std::make_pair(ANY_UID, ANY_GID), 0, false);
+ its_serializer->reset();
+ put_serializer(its_serializer);
} else {
VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
}
@@ -759,7 +857,8 @@ std::shared_ptr<serviceinfo> routing_manager_base::create_service_info(
service_t _service, instance_t _instance, major_version_t _major,
minor_version_t _minor, ttl_t _ttl, bool _is_local_service) {
std::shared_ptr<serviceinfo> its_info =
- std::make_shared<serviceinfo>(_major, _minor, _ttl, _is_local_service);
+ std::make_shared<serviceinfo>(_service, _instance,
+ _major, _minor, _ttl, _is_local_service);
{
std::lock_guard<std::mutex> its_lock(services_mutex_);
services_[_service][_instance] = its_info;
@@ -873,7 +972,8 @@ std::set<client_t> routing_manager_base::find_local_clients(service_t _service,
return its_clients;
}
-client_t routing_manager_base::find_local_client(service_t _service, instance_t _instance) {
+client_t routing_manager_base::find_local_client(service_t _service,
+ instance_t _instance) const {
std::lock_guard<std::mutex> its_lock(local_services_mutex_);
client_t its_client(VSOMEIP_ROUTING_CLIENT);
auto its_service = local_services_.find(_service);
@@ -886,70 +986,6 @@ client_t routing_manager_base::find_local_client(service_t _service, instance_t
return its_client;
}
-std::shared_ptr<endpoint> routing_manager_base::create_local_unlocked(client_t _client) {
- std::stringstream its_path;
- its_path << utility::get_base_path(configuration_) << std::hex << _client;
-
-#ifdef _WIN32
- boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
- int port = VSOMEIP_INTERNAL_BASE_PORT + _client;
- VSOMEIP_INFO << "Connecting to ["
- << std::hex << _client << "] at " << port;
-#else
- VSOMEIP_INFO << "Client [" << std::hex << get_client() << "] is connecting to ["
- << std::hex << _client << "] at " << its_path.str();
-#endif
- std::shared_ptr<local_client_endpoint_impl> its_endpoint = std::make_shared<
- local_client_endpoint_impl>(shared_from_this(),
-#ifdef _WIN32
- boost::asio::ip::tcp::endpoint(address, port)
-#else
- boost::asio::local::stream_protocol::endpoint(its_path.str())
-#endif
- , io_, configuration_->get_max_message_size_local(),
- configuration_->get_endpoint_queue_limit_local());
-
- // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to
- // external devices. Therefore, its local endpoint must not be found by
- // a call to find_local. Thus it must not be inserted to the list of local
- // clients.
- if (_client != VSOMEIP_ROUTING_CLIENT) {
- local_endpoints_[_client] = its_endpoint;
- }
- register_client_error_handler(_client, its_endpoint);
-
- return its_endpoint;
-}
-
-std::shared_ptr<endpoint> routing_manager_base::create_local(client_t _client) {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- return create_local_unlocked(_client);
-}
-
-std::shared_ptr<endpoint> routing_manager_base::find_local_unlocked(client_t _client) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_endpoint = local_endpoints_.find(_client);
- if (found_endpoint != local_endpoints_.end()) {
- its_endpoint = found_endpoint->second;
- }
- return (its_endpoint);
-}
-
-std::shared_ptr<endpoint> routing_manager_base::find_local(client_t _client) {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- return find_local_unlocked(_client);
-}
-
-std::shared_ptr<endpoint> routing_manager_base::find_or_create_local(client_t _client) {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint(find_local_unlocked(_client));
- if (!its_endpoint) {
- its_endpoint = create_local_unlocked(_client);
- its_endpoint->start();
- }
- return (its_endpoint);
-}
-
void routing_manager_base::remove_local(client_t _client, bool _remove_uid) {
remove_local(_client, get_subscriptions(_client), _remove_uid);
}
@@ -957,24 +993,20 @@ void routing_manager_base::remove_local(client_t _client, bool _remove_uid) {
void routing_manager_base::remove_local(client_t _client,
const std::set<std::tuple<service_t, instance_t, eventgroup_t>>& _subscribed_eventgroups,
bool _remove_uid) {
+
+ std::pair<uid_t, gid_t> its_uid_gid(ANY_UID, ANY_GID);
+ security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid);
+
if (_remove_uid) {
- configuration_->remove_client_to_uid_gid_mapping(_client);
+ security::get()->remove_client_to_uid_gid_mapping(_client);
}
for (auto its_subscription : _subscribed_eventgroups) {
host_->on_subscription(std::get<0>(its_subscription), std::get<1>(its_subscription),
- std::get<2>(its_subscription), _client, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
- routing_manager_base::unsubscribe(_client, std::get<0>(its_subscription),
+ std::get<2>(its_subscription), _client, its_uid_gid.first, its_uid_gid.second, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
+ routing_manager_base::unsubscribe(_client, its_uid_gid.first, its_uid_gid.second, std::get<0>(its_subscription),
std::get<1>(its_subscription), std::get<2>(its_subscription), ANY_EVENT);
}
- std::shared_ptr<endpoint> its_endpoint(find_local(_client));
- if (its_endpoint) {
- its_endpoint->register_error_handler(nullptr);
- its_endpoint->stop();
- VSOMEIP_INFO << "Client [" << std::hex << get_client() << "] is closing connection to ["
- << std::hex << _client << "]";
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- local_endpoints_.erase(_client);
- }
+ ep_mgr_->remove_local(_client);
{
std::lock_guard<std::mutex> its_lock(local_services_mutex_);
// Finally remove all services that are implemented by the client.
@@ -1016,24 +1048,10 @@ void routing_manager_base::remove_local(client_t _client,
}
}
-std::shared_ptr<endpoint> routing_manager_base::find_local(service_t _service,
- instance_t _instance) {
- return find_local(find_local_client(_service, _instance));
-}
-
-std::unordered_set<client_t> routing_manager_base::get_connected_clients() {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- std::unordered_set<client_t> clients;
- for (auto its_client : local_endpoints_) {
- clients.insert(its_client.first);
- }
- return clients;
-}
-
std::shared_ptr<event> routing_manager_base::find_event(service_t _service,
instance_t _instance, event_t _event) const {
- std::shared_ptr<event> its_event;
std::lock_guard<std::mutex> its_lock(events_mutex_);
+ std::shared_ptr<event> its_event;
auto find_service = events_.find(_service);
if (find_service != events_.end()) {
auto find_instance = find_service->second.find(_instance);
@@ -1082,6 +1100,8 @@ std::shared_ptr<eventgroupinfo> routing_manager_base::find_eventgroup(
"multicast address is configured!";
}
}
+
+ // LB: THIS IS STRANGE. A "FIND" - METHOD SHOULD NOT ADD INFORMATION...
its_info->set_major(its_service_info->get_major());
its_info->set_ttl(its_service_info->get_ttl());
its_info->set_threshold(configuration_->get_threshold(
@@ -1107,7 +1127,7 @@ void routing_manager_base::remove_eventgroup_info(service_t _service,
bool routing_manager_base::send_local_notification(client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush, bool _reliable, bool _is_valid_crc) {
+ bool _reliable, uint8_t _status_check) {
#ifdef USE_DLT
bool has_local(false);
#endif
@@ -1118,7 +1138,6 @@ bool routing_manager_base::send_local_notification(client_t _client,
_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
std::shared_ptr<event> its_event = find_event(its_service, _instance, its_method);
if (its_event && !its_event->is_shadow()) {
- std::vector< byte_t > its_data;
for (auto its_client : its_event->get_subscribers()) {
// local
@@ -1131,10 +1150,10 @@ bool routing_manager_base::send_local_notification(client_t _client,
has_local = true;
}
#endif
- std::shared_ptr<endpoint> its_local_target = find_local(its_client);
+ std::shared_ptr<endpoint> its_local_target = ep_mgr_->find_local(its_client);
if (its_local_target) {
send_local(its_local_target, _client, _data, _size,
- _instance, _flush, _reliable, VSOMEIP_SEND, _is_valid_crc);
+ _instance, _reliable, VSOMEIP_SEND, _status_check);
}
}
}
@@ -1156,7 +1175,7 @@ bool routing_manager_base::send_local_notification(client_t _client,
bool routing_manager_base::send_local(
std::shared_ptr<endpoint>& _target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush, bool _reliable, uint8_t _command, bool _is_valid_crc) const {
+ bool _reliable, uint8_t _command, uint8_t _status_check) const {
const std::size_t its_complete_size = VSOMEIP_SEND_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE + _size;
const client_t sender = get_client();
@@ -1169,12 +1188,10 @@ bool routing_manager_base::send_local(
&its_complete_size, sizeof(_size));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
&_instance, sizeof(instance_t));
- std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_FLUSH_POS],
- &_flush, sizeof(bool));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
&_reliable, sizeof(bool));
- std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_VALID_CRC_POS],
- &_is_valid_crc, sizeof(bool));
+ std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
+ &_status_check, sizeof(uint8_t));
// Add target client, only relevant for selective notifications
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN],
&_client, sizeof(client_t));
@@ -1244,7 +1261,33 @@ bool routing_manager_base::insert_subscription(
return is_inserted;
}
+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!";
+ serializer_condition_.wait(its_lock);
+ VSOMEIP_INFO << std::hex << "client " << get_client() <<
+ "routing_manager_base::get_serializer ~> wait finished!";
+ }
+
+ auto its_serializer = serializers_.front();
+ serializers_.pop();
+
+ return (its_serializer);
+}
+
+void routing_manager_base::put_serializer(
+ const std::shared_ptr<serializer> &_serializer) {
+
+ std::lock_guard<std::mutex> its_lock(serializer_mutex_);
+ serializers_.push(_serializer);
+ serializer_condition_.notify_one();
+}
+
std::shared_ptr<deserializer> routing_manager_base::get_deserializer() {
+
std::unique_lock<std::mutex> its_lock(deserializer_mutex_);
while (deserializers_.empty()) {
VSOMEIP_INFO << std::hex << "client " << get_client() <<
@@ -1253,30 +1296,28 @@ std::shared_ptr<deserializer> routing_manager_base::get_deserializer() {
VSOMEIP_INFO << std::hex << "client " << get_client() <<
"routing_manager_base::get_deserializer ~> wait finished!";
}
- auto deserializer = deserializers_.front();
+
+ auto its_deserializer = deserializers_.front();
deserializers_.pop();
- return deserializer;
+
+ return (its_deserializer);
}
-void routing_manager_base::put_deserializer(std::shared_ptr<deserializer> _deserializer) {
+void routing_manager_base::put_deserializer(
+ const std::shared_ptr<deserializer> &_deserializer) {
+
std::lock_guard<std::mutex> its_lock(deserializer_mutex_);
deserializers_.push(_deserializer);
deserializer_condition_.notify_one();
}
-#ifndef _WIN32
-bool routing_manager_base::check_credentials(client_t _client, uid_t _uid, gid_t _gid) {
- return configuration_->check_credentials(_client, _uid, _gid);
-}
-#endif
-
void routing_manager_base::send_pending_subscriptions(service_t _service,
instance_t _instance, major_version_t _major) {
for (auto &ps : pending_subscriptions_) {
if (ps.service_ == _service &&
ps.instance_ == _instance && ps.major_ == _major) {
send_subscribe(client_, ps.service_, ps.instance_,
- ps.eventgroup_, ps.major_, ps.event_, ps.subscription_type_);
+ ps.eventgroup_, ps.major_, ps.event_);
}
}
}
@@ -1324,11 +1365,11 @@ std::set<std::tuple<service_t, instance_t, eventgroup_t>>
routing_manager_base::get_subscriptions(const client_t _client) {
std::set<std::tuple<service_t, instance_t, eventgroup_t>> result;
std::lock_guard<std::mutex> its_lock(events_mutex_);
- for (auto its_service : events_) {
- for (auto its_instance : its_service.second) {
- for (auto its_event : its_instance.second) {
+ for (const auto& its_service : events_) {
+ for (const auto& its_instance : its_service.second) {
+ for (const auto& its_event : its_instance.second) {
auto its_eventgroups = its_event.second->get_eventgroups(_client);
- for (auto e : its_eventgroups) {
+ for (const auto& e : its_eventgroups) {
result.insert(std::make_tuple(
its_service.first,
its_instance.first,
@@ -1340,27 +1381,7 @@ routing_manager_base::get_subscriptions(const client_t _client) {
return result;
}
-void routing_manager_base::send_identify_request(service_t _service,
- instance_t _instance, major_version_t _major, bool _reliable) {
- auto message = runtime::get()->create_message(_reliable);
- message->set_service(_service);
- message->set_instance(_instance);
- message->set_client(get_client());
- message->set_method(ANY_METHOD - 1);
- message->set_interface_version(_major);
- message->set_message_type(message_type_e::MT_REQUEST);
-
- // Initiate a request/response to the remote service
- // Use host for sending to ensure correct session id is set
- host_->send(message, true);
-}
-
-std::map<client_t, std::shared_ptr<endpoint>>
-routing_manager_base::get_local_endpoints() {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
- return local_endpoints_;
-}
-
+#ifdef VSOMEIP_ENABLE_COMPAT
void routing_manager_base::set_incoming_subscription_state(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event, subscription_state_e _state) {
std::lock_guard<std::recursive_mutex> its_lock(incoming_subscription_state_mutex_);
@@ -1427,5 +1448,6 @@ void routing_manager_base::erase_incoming_subscription_state(client_t _client, s
}
}
}
+#endif
-} // namespace vsomeip
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index f8dbd14..48e2cb5 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// Copyright (C) 2014-2018 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/.
@@ -15,25 +15,23 @@
#include <time.h>
#endif
-#ifndef WITHOUT_SYSTEMD
-#include <systemd/sd-daemon.h>
-#endif
-
#include <boost/asio/steady_timer.hpp>
#include <vsomeip/constants.hpp>
-#include <vsomeip/message.hpp>
#include <vsomeip/payload.hpp>
#include <vsomeip/runtime.hpp>
+#include <vsomeip/internal/logger.hpp>
#include "../include/event.hpp"
#include "../include/eventgroupinfo.hpp"
+#include "../include/remote_subscription.hpp"
#include "../include/routing_manager_host.hpp"
#include "../include/routing_manager_impl.hpp"
#include "../include/routing_manager_stub.hpp"
#include "../include/serviceinfo.hpp"
#include "../../configuration/include/configuration.hpp"
-#include "../../configuration/include/internal.hpp"
+#include "../../security/include/security.hpp"
+
#include "../../endpoints/include/endpoint_definition.hpp"
#include "../../endpoints/include/local_client_endpoint_impl.hpp"
#include "../../endpoints/include/tcp_client_endpoint_impl.hpp"
@@ -41,32 +39,38 @@
#include "../../endpoints/include/udp_client_endpoint_impl.hpp"
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
#include "../../endpoints/include/virtual_server_endpoint_impl.hpp"
-#include "../../logging/include/logger.hpp"
#include "../../message/include/deserializer.hpp"
+#include "../../message/include/message_impl.hpp"
#include "../../message/include/serializer.hpp"
#include "../../service_discovery/include/constants.hpp"
#include "../../service_discovery/include/defines.hpp"
#include "../../service_discovery/include/runtime.hpp"
-#include "../../service_discovery/include/service_discovery_impl.hpp"
+#include "../../service_discovery/include/service_discovery.hpp"
#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
-#include "../../plugin/include/plugin_manager.hpp"
+#include "../../plugin/include/plugin_manager_impl.hpp"
#ifdef USE_DLT
#include "../../tracing/include/connector_impl.hpp"
#endif
+#ifndef ANDROID
#include "../../e2e_protection/include/buffer/buffer.hpp"
#include "../../e2e_protection/include/e2exf/config.hpp"
-#include "../../e2e_protection/include/e2e/profile/profile01/profile_01.hpp"
-#include "../../e2e_protection/include/e2e/profile/profile01/protector.hpp"
-#include "../../e2e_protection/include/e2e/profile/profile01/checker.hpp"
+#include "../../e2e_protection/include/e2e/profile/e2e_provider.hpp"
+#endif
-#include "../../e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp"
-#include "../../e2e_protection/include/e2e/profile/profile_custom/protector.hpp"
-#include "../../e2e_protection/include/e2e/profile/profile_custom/checker.hpp"
+#ifdef USE_DLT
+#include "../../tracing/include/connector_impl.hpp"
+#endif
-namespace vsomeip {
+namespace vsomeip_v3 {
+
+#ifdef ANDROID
+namespace sd {
+runtime::~runtime() {}
+}
+#endif
routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
routing_manager_base(_host),
@@ -74,11 +78,9 @@ routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
if_state_running_(false),
sd_route_set_(false),
routing_running_(false),
-#ifndef WITHOUT_SYSTEMD
- watchdog_timer_(_host->get_io()),
-#endif
status_log_timer_(_host->get_io()),
memory_log_timer_(_host->get_io()),
+ ep_mgr_impl_(std::make_shared<endpoint_manager_impl>(this, io_, configuration_)),
pending_remote_offer_id_(0),
last_resume_(std::chrono::steady_clock::now().min()),
pending_security_update_id_(0)
@@ -86,6 +88,8 @@ routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
}
routing_manager_impl::~routing_manager_impl() {
+ utility::remove_lockfile(configuration_);
+ utility::reset_client_ids();
}
boost::asio::io_service & routing_manager_impl::get_io() {
@@ -100,22 +104,23 @@ std::set<client_t> routing_manager_impl::find_local_clients(service_t _service,
return routing_manager_base::find_local_clients(_service, _instance);
}
-bool routing_manager_impl::is_subscribe_to_any_event_allowed(client_t _client,
+client_t routing_manager_impl::find_local_client(service_t _service, instance_t _instance) {
+ return routing_manager_base::find_local_client(_service, _instance);
+}
+
+bool routing_manager_impl::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
- return routing_manager_base::is_subscribe_to_any_event_allowed(_client,
+ return routing_manager_base::is_subscribe_to_any_event_allowed(_credentials, _client,
_service, _instance, _eventgroup);
}
void routing_manager_impl::init() {
- routing_manager_base::init();
+ routing_manager_base::init(ep_mgr_impl_);
// TODO: Only instantiate the stub if needed
stub_ = std::make_shared<routing_manager_stub>(this, configuration_);
stub_->init();
- // We need to be able to send messages to ourself (for delivering events)
- (void)create_local(VSOMEIP_ROUTING_CLIENT);
-
if (configuration_->is_sd_enabled()) {
VSOMEIP_INFO<< "Service Discovery enabled. Trying to load module.";
auto its_plugin = plugin_manager::get()->get_plugin(
@@ -130,34 +135,29 @@ void routing_manager_impl::init() {
}
}
+#ifndef ANDROID
if( configuration_->is_e2e_enabled()) {
VSOMEIP_INFO << "E2E protection enabled.";
+
+ const char *its_e2e_module = getenv(VSOMEIP_ENV_E2E_PROTECTION_MODULE);
+ std::string plugin_name = its_e2e_module != nullptr ? its_e2e_module : VSOMEIP_E2E_LIBRARY;
+
+ auto its_plugin = plugin_manager::get()->get_plugin(plugin_type_e::APPLICATION_PLUGIN, plugin_name);
+ if (its_plugin) {
+ VSOMEIP_INFO << "E2E module loaded.";
+ e2e_provider_ = std::dynamic_pointer_cast<e2e::e2e_provider>(its_plugin);
+ }
+ }
+
+ if(e2e_provider_) {
std::map<e2exf::data_identifier_t, std::shared_ptr<cfg::e2e>> its_e2e_configuration = configuration_->get_e2e_configuration();
for (auto &identifier : its_e2e_configuration) {
- auto its_cfg = identifier.second;
- if(its_cfg->profile == "CRC8") {
- e2exf::data_identifier_t its_data_identifier = {its_cfg->service_id, its_cfg->event_id};
- e2e::profile01::profile_config its_profile_config = e2e::profile01::profile_config(its_cfg->crc_offset, its_cfg->data_id,
- (e2e::profile01::p01_data_id_mode) its_cfg->data_id_mode, its_cfg->data_length, its_cfg->counter_offset, its_cfg->data_id_nibble_offset);
- if ((its_cfg->variant == "protector") || (its_cfg->variant == "both")) {
- custom_protectors[its_data_identifier] = std::make_shared<e2e::profile01::protector>(its_profile_config);
- }
- if ((its_cfg->variant == "checker") || (its_cfg->variant == "both")) {
- custom_checkers[its_data_identifier] = std::make_shared<e2e::profile01::profile_01_checker>(its_profile_config);
- }
- } else if(its_cfg->profile == "CRC32") {
- e2exf::data_identifier_t its_data_identifier = {its_cfg->service_id, its_cfg->event_id};
- e2e::profile_custom::profile_config its_profile_config = e2e::profile_custom::profile_config(its_cfg->crc_offset);
-
- if ((its_cfg->variant == "protector") || (its_cfg->variant == "both")) {
- custom_protectors[its_data_identifier] = std::make_shared<e2e::profile_custom::protector>(its_profile_config);
- }
- if ((its_cfg->variant == "checker") || (its_cfg->variant == "both")) {
- custom_checkers[its_data_identifier] = std::make_shared<e2e::profile_custom::profile_custom_checker>(its_profile_config);
- }
+ if(!e2e_provider_->add_configuration(identifier.second)) {
+ VSOMEIP_INFO << "Unknown E2E profile: " << identifier.second->profile << ", skipping ...";
}
}
}
+#endif
}
void routing_manager_impl::start() {
@@ -186,15 +186,6 @@ void routing_manager_impl::start() {
version_log_timer_.async_wait(std::bind(&routing_manager_impl::log_version_timer_cbk,
this, std::placeholders::_1));
}
-
-#ifndef WITHOUT_SYSTEMD
- {
- std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
- watchdog_timer_.expires_from_now(std::chrono::seconds(0));
- watchdog_timer_.async_wait(std::bind(&routing_manager_impl::watchdog_cbk,
- this, std::placeholders::_1));
- }
-#endif
#ifndef _WIN32
if (configuration_->log_memory()) {
std::lock_guard<std::mutex> its_lock(memory_log_timer_mutex_);
@@ -216,6 +207,26 @@ void routing_manager_impl::start() {
}
void routing_manager_impl::stop() {
+ // Ensure to StopOffer all services that are offered by the application hosting the rm
+ local_services_map_t its_services;
+ {
+ std::lock_guard<std::mutex> its_lock(local_services_mutex_);
+ for (const auto& s : local_services_) {
+ for (const auto& i : s.second) {
+ if (std::get<2>(i.second) == client_) {
+ its_services[s.first][i.first] = i.second;
+ }
+ }
+ }
+
+ }
+ for (const auto& s : its_services) {
+ for (const auto& i : s.second) {
+ on_stop_offer_service(std::get<2>(i.second), s.first, i.first,
+ std::get<0>(i.second), std::get<1>(i.second));
+ }
+ }
+
{
std::lock_guard<std::mutex> its_lock(version_log_timer_mutex_);
version_log_timer_.cancel();
@@ -236,37 +247,119 @@ void routing_manager_impl::stop() {
boost::system::error_code ec;
status_log_timer_.cancel(ec);
}
-#ifndef WITHOUT_SYSTEMD
- {
- std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
- watchdog_timer_.cancel();
- }
- sd_notify(0, "STOPPING=1");
- VSOMEIP_INFO << "Sent STOPPING to systemd watchdog";
-#endif
-
host_->on_state(state_type_e::ST_DEREGISTERED);
if (discovery_)
discovery_->stop();
stub_->stop();
- for (auto client: get_connected_clients()) {
+ for (auto client: ep_mgr_->get_connected_clients()) {
if (client != VSOMEIP_ROUTING_CLIENT) {
remove_local(client, true);
}
}
}
-bool routing_manager_impl::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor) {
+bool routing_manager_impl::insert_offer_command(service_t _service, instance_t _instance, uint8_t _command,
+ client_t _client, major_version_t _major, minor_version_t _minor) {
+ std::lock_guard<std::mutex> its_lock(offer_serialization_mutex_);
+ // flag to indicate whether caller of this function can start directly processing the command
+ bool must_process(false);
+ auto found_service_instance = offer_commands_.find(std::make_pair(_service, _instance));
+ if (found_service_instance != offer_commands_.end()) {
+ // if nothing is queued
+ if (found_service_instance->second.empty()) {
+ must_process = true;
+ }
+ found_service_instance->second.push_back(
+ std::make_tuple(_command, _client, _major, _minor));
+ } else {
+ // nothing is queued -> add command to queue and process command directly
+ offer_commands_[std::make_pair(_service, _instance)].push_back(
+ std::make_tuple(_command, _client, _major, _minor));
+ must_process = true;
+ }
+ return must_process;
+}
+
+bool routing_manager_impl::erase_offer_command(service_t _service, instance_t _instance) {
+ std::lock_guard<std::mutex> its_lock(offer_serialization_mutex_);
+ auto found_service_instance = offer_commands_.find(std::make_pair(_service, _instance));
+ if (found_service_instance != offer_commands_.end()) {
+ // erase processed command
+ if (!found_service_instance->second.empty()) {
+ found_service_instance->second.pop_front();
+ if (!found_service_instance->second.empty()) {
+ // check for other commands to be processed
+ auto its_command = found_service_instance->second.front();
+ if (std::get<0>(its_command) == VSOMEIP_OFFER_SERVICE) {
+ io_.post([&, its_command, _service, _instance](){
+ offer_service(std::get<1>(its_command), _service, _instance,
+ std::get<2>(its_command), std::get<3>(its_command), false);
+ });
+ } else {
+ io_.post([&, its_command, _service, _instance](){
+ stop_offer_service(std::get<1>(its_command), _service, _instance,
+ std::get<2>(its_command), std::get<3>(its_command), false);
+ });
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool routing_manager_impl::offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
+
+ return offer_service(_client, _service, _instance, _major, _minor, true);
+}
+
+bool routing_manager_impl::offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ bool _must_queue) {
+
VSOMEIP_INFO << "OFFER("
<< std::hex << std::setw(4) << std::setfill('0') << _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 << "]";
+ << ":" << std::dec << int(_major) << "." << std::dec << _minor << "]"
+ << " (" << _must_queue << ")";
+
+ // only queue commands if method was NOT called via erase_offer_command()
+ if (_must_queue) {
+ if (!insert_offer_command(_service, _instance, VSOMEIP_OFFER_SERVICE,
+ _client, _major, _minor)) {
+ return false;
+ }
+ }
+
+ // Check if the application hosted by routing manager is allowed to offer
+ // offer_service requests of local proxies are checked in rms::on:message
+ if (_client == get_client()) {
+#ifdef _WIN32
+ std::uint32_t its_routing_uid = ANY_UID;
+ std::uint32_t its_routing_gid = ANY_GID;
+#else
+ std::uint32_t its_routing_uid = getuid();
+ std::uint32_t its_routing_gid = getgid();
+#endif
+ if (!security::get()->is_offer_allowed(its_routing_uid, its_routing_gid,
+ _client, _service, _instance)) {
+ VSOMEIP_WARNING << "routing_manager_impl::offer_service: "
+ << std::hex << "Security: Client 0x" << _client
+ << " isn't allowed to offer the following service/instance "
+ << _service << "/" << _instance
+ << " ~> Skip offer!";
+ erase_offer_command(_service, _instance);
+ return false;
+ }
+ }
- if(!handle_local_offer_service(_client, _service, _instance, _major, _minor)) {
+ if (!handle_local_offer_service(_client, _service, _instance, _major, _minor)) {
+ erase_offer_command(_service, _instance);
return false;
}
@@ -282,7 +375,7 @@ bool routing_manager_impl::offer_service(client_t _client, service_t _service,
if (discovery_) {
std::shared_ptr<serviceinfo> its_info = find_service(_service, _instance);
if (its_info) {
- discovery_->offer_service(_service, _instance, its_info);
+ discovery_->offer_service(its_info);
}
}
@@ -290,16 +383,23 @@ bool routing_manager_impl::offer_service(client_t _client, service_t _service,
std::lock_guard<std::mutex> ist_lock(pending_subscription_mutex_);
std::set<event_t> its_already_subscribed_events;
for (auto &ps : pending_subscriptions_) {
- if (ps.service_ == _service &&
- ps.instance_ == _instance && ps.major_ == _major) {
+ if (ps.service_ == _service
+ && ps.instance_ == _instance
+ && ps.major_ == _major) {
insert_subscription(ps.service_, ps.instance_,
ps.eventgroup_, ps.event_, client_, &its_already_subscribed_events);
- }
+ VSOMEIP_ERROR << __func__
+ << ": event="
+ << std::hex << ps.service_ << "."
+ << std::hex << ps.instance_ << "."
+ << std::hex << ps.event_; }
}
+
send_pending_subscriptions(_service, _instance, _major);
}
stub_->on_offer_service(_client, _service, _instance, _major, _minor);
on_availability(_service, _instance, true, _major, _minor);
+ erase_offer_command(_service, _instance);
return true;
}
@@ -307,11 +407,28 @@ void routing_manager_impl::stop_offer_service(client_t _client,
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
+ stop_offer_service(_client, _service, _instance, _major, _minor, true);
+}
+
+void routing_manager_impl::stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ bool _must_queue) {
+
VSOMEIP_INFO << "STOP OFFER("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
- << ":" << std::dec << int(_major) << "." << _minor << "]";
+ << ":" << std::dec << int(_major) << "." << _minor << "]"
+ << " (" << _must_queue << ")";
+
+ if (_must_queue) {
+ if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE,
+ _client, _major, _minor)) {
+ return;
+ }
+ }
+
bool is_local(false);
{
std::shared_ptr<serviceinfo> its_info = find_service(_service, _instance);
@@ -340,12 +457,12 @@ void routing_manager_impl::stop_offer_service(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << _minor << "] "
<< "for remote service --> ignore";
+ erase_offer_command(_service, _instance);
}
}
void routing_manager_impl::request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- bool _use_exclusive_proxy) {
+ instance_t _instance, major_version_t _major, minor_version_t _minor) {
VSOMEIP_INFO << "REQUEST("
<< std::hex << std::setw(4) << std::setfill('0') << _client << "): ["
@@ -353,8 +470,8 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
<< std::hex << std::setw(4) << std::setfill('0') << _instance << ":"
<< std::dec << int(_major) << "." << std::dec << _minor << "]";
- routing_manager_base::request_service(_client, _service, _instance, _major,
- _minor, _use_exclusive_proxy);
+ routing_manager_base::request_service(_client,
+ _service, _instance, _major, _minor);
auto its_info = find_service(_service, _instance);
if (!its_info) {
@@ -381,27 +498,22 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
|| _minor == ANY_MINOR)) {
if(!its_info->is_local()) {
requested_service_add(_client, _service, _instance, _major, _minor);
- its_info->add_client(_client);
- find_or_create_remote_client(_service, _instance, true, VSOMEIP_ROUTING_CLIENT);
- if (_use_exclusive_proxy) {
- std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(true);
- if(its_endpoint) {
- find_or_create_remote_client(_service, _instance, true, _client);
- }
+ if (discovery_) {
+ // Non local service instance ~> tell SD to find it!
+ discovery_->request_service(_service, _instance, _major,
+ _minor, DEFAULT_TTL);
}
+ its_info->add_client(_client);
+ ep_mgr_impl_->find_or_create_remote_client(
+ _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
}
}
}
- if (_use_exclusive_proxy) {
- std::lock_guard<std::mutex> its_lock(specific_endpoint_clients_mutex_);
- specific_endpoint_clients_[_service][_instance].insert(_client);
- }
-
if (_client == get_client()) {
stub_->create_local_receiver();
- service_data_t request = { _service, _instance, _major, _minor, _use_exclusive_proxy };
+ service_data_t request = { _service, _instance, _major, _minor };
std::set<service_data_t> requests;
requests.insert(request);
stub_->handle_requests(_client, requests);
@@ -424,36 +536,28 @@ void routing_manager_impl::release_service(client_t _client, service_t _service,
requested_service_remove(_client, _service, _instance);
std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if(its_info && !its_info->is_local()) {
- unsubscribe_specific_client_at_sd(_service, _instance, _client);
- if(!its_info->get_requesters_size()) {
- if(discovery_) {
+ if (its_info && !its_info->is_local()) {
+ if (!its_info->get_requesters_size()) {
+ if (discovery_) {
discovery_->release_service(_service, _instance);
- discovery_->unsubscribe_client(_service, _instance, VSOMEIP_ROUTING_CLIENT);
+ discovery_->unsubscribe_all(_service, _instance);
}
- clear_client_endpoints(_service, _instance, true);
- clear_client_endpoints(_service, _instance, false);
+ ep_mgr_impl_->clear_client_endpoints(_service, _instance, true);
+ ep_mgr_impl_->clear_client_endpoints(_service, _instance, false);
its_info->set_endpoint(nullptr, true);
its_info->set_endpoint(nullptr, false);
- clear_identified_clients(_service, _instance);
- clear_identifying_clients( _service, _instance);
unset_all_eventpayloads(_service, _instance);
- } else {
- remove_identified_client(_service, _instance, _client);
- remove_identifying_client(_service, _instance, _client);
- remove_specific_client_endpoint(_service, _instance, _client, true);
- remove_specific_client_endpoint(_service, _instance, _client, false);
}
} else {
- if(discovery_) {
+ if (discovery_) {
discovery_->release_service(_service, _instance);
}
}
}
-void routing_manager_impl::subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, subscription_type_e _subscription_type) {
+void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, event_t _event) {
VSOMEIP_INFO << "SUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
@@ -464,14 +568,16 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
<< std::dec << (uint16_t)_major << "]";
const client_t its_local_client = find_local_client(_service, _instance);
if (get_client() == its_local_client) {
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::set_incoming_subscription_state(_client, _service, _instance,
_eventgroup, _event, subscription_state_e::IS_SUBSCRIBING);
+#endif
auto self = shared_from_this();
- host_->on_subscription(_service, _instance, _eventgroup, _client, true,
- [this, self, _client, _service, _instance, _eventgroup,
- _event, _major, _subscription_type]
+ host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, true,
+ [this, self, _client, _uid, _gid, _service, _instance, _eventgroup,
+ _event, _major]
(const bool _subscription_accepted) {
- (void) find_or_create_local(_client);
+ (void) ep_mgr_->find_or_create_local(_client);
if (!_subscription_accepted) {
stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup, _event);
VSOMEIP_INFO << "Subscription request from client: 0x" << std::hex
@@ -481,58 +587,52 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
} else {
stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event);
}
- routing_manager_base::subscribe(_client, _service, _instance, _eventgroup, _major, _event, _subscription_type);
+ routing_manager_base::subscribe(_client, _uid, _gid, _service, _instance, _eventgroup, _major, _event);
+#ifdef VSOMEIP_ENABLE_COMPAT
send_pending_notify_ones(_service, _instance, _eventgroup, _client);
routing_manager_base::erase_incoming_subscription_state(_client, _service, _instance,
_eventgroup, _event);
+#endif
});
} else {
if (discovery_) {
- client_t subscriber = VSOMEIP_ROUTING_CLIENT;
- if (0 == its_local_client) {
- subscriber = is_specific_endpoint_client(_client, _service, _instance);
- if (subscriber != VSOMEIP_ROUTING_CLIENT) {
- if (supports_selective(_service, _instance)) {
- identify_for_subscribe(_client, _service, _instance,
- _major, _subscription_type);
- } else {
- VSOMEIP_INFO << "Subcribe to legacy selective service: " << std::hex
- << _service << ":" << _instance << ".";
- }
- }
- }
- std::unique_lock<std::mutex> eventgroup_lock;
- auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
- if (its_eventgroup) {
- eventgroup_lock = its_eventgroup->get_subscription_lock();
- }
std::set<event_t> its_already_subscribed_events;
+
+ // Note: The calls to insert_subscription & handle_subscription_state must not
+ // run concurrently to a call to on_subscribe_ack. Therefore the lock is acquired
+ // before calling insert_subscription and released after the call to
+ // handle_subscription_state.
+ std::unique_lock<std::mutex> its_critical(remote_subscription_state_mutex_);
bool inserted = insert_subscription(_service, _instance, _eventgroup,
_event, _client, &its_already_subscribed_events);
if (inserted) {
if (0 == its_local_client) {
handle_subscription_state(_client, _service, _instance, _eventgroup, _event);
- if (its_eventgroup) {
- eventgroup_lock.unlock();
- }
+ its_critical.unlock();
static const ttl_t configured_ttl(configuration_->get_sd_ttl());
notify_one_current_value(_client, _service, _instance,
_eventgroup, _event, its_already_subscribed_events);
- discovery_->subscribe(_service, _instance, _eventgroup,
- _major, configured_ttl, subscriber, _subscription_type);
+
+ auto its_info = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_info) {
+ discovery_->subscribe(_service, _instance, _eventgroup,
+ _major, configured_ttl,
+ its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
+ }
} else {
+ its_critical.unlock();
if (is_available(_service, _instance, _major)) {
- stub_->send_subscribe(find_local(_service, _instance),
- _client, _service, _instance, _eventgroup, _major, _event, DEFAULT_SUBSCRIPTION);
+ stub_->send_subscribe(ep_mgr_->find_local(_service, _instance),
+ _client, _service, _instance, _eventgroup, _major, _event,
+ PENDING_SUBSCRIPTION_ID);
}
}
- } else if (its_eventgroup) {
- eventgroup_lock.unlock();
}
if (get_client() == _client) {
std::lock_guard<std::mutex> ist_lock(pending_subscription_mutex_);
- subscription_data_t subscription = { _service, _instance, _eventgroup, _major,
- _event, _subscription_type};
+ subscription_data_t subscription = {
+ _service, _instance, _eventgroup, _major, _event, _uid, _gid
+ };
pending_subscriptions_.insert(subscription);
}
} else {
@@ -541,8 +641,8 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
}
}
-void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
+void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
VSOMEIP_INFO << "UNSUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << _client << "): ["
@@ -552,14 +652,16 @@ void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
<< std::hex << std::setw(4) << std::setfill('0') << _event << "]";
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) {
- for (auto e : its_info->get_events()) {
+ for (const auto& e : its_info->get_events()) {
if (e->get_event() == _event || ANY_EVENT == _event)
e->remove_subscriber(_eventgroup, _client);
}
- for (auto e : its_info->get_events()) {
+ for (const auto& e : its_info->get_events()) {
if (e->has_subscriber(_eventgroup, ANY_CLIENT)) {
last_subscriber_removed = false;
break;
@@ -568,40 +670,36 @@ void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
}
if (discovery_) {
- host_->on_subscription(_service, _instance, _eventgroup, _client, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
+ host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, false,
+ [](const bool _subscription_accepted){ (void)_subscription_accepted; });
if (0 == find_local_client(_service, _instance)) {
- client_t subscriber = is_specific_endpoint_client(_client, _service, _instance);
if (last_subscriber_removed) {
unset_all_eventpayloads(_service, _instance, _eventgroup);
- }
- if (subscriber == VSOMEIP_ROUTING_CLIENT && last_subscriber_removed) {
{
- auto tuple = std::make_tuple(_service, _instance, _eventgroup, subscriber);
+ auto tuple = std::make_tuple(_service, _instance, _eventgroup, _client);
std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
remote_subscription_state_.erase(tuple);
}
- // for normal subscribers only unsubscribe via SD if last
- // subscriber was removed
- discovery_->unsubscribe(_service, _instance, _eventgroup, subscriber);
- } else if (subscriber != VSOMEIP_ROUTING_CLIENT) {
- {
- auto tuple = std::make_tuple(_service, _instance, _eventgroup, subscriber);
- std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
- remote_subscription_state_.erase(tuple);
+ }
+
+ 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);
}
- // for selective subscribers always unsubscribe at the SD
- discovery_->unsubscribe(_service, _instance, _eventgroup, subscriber);
}
} else {
if (get_client() == _client) {
std::lock_guard<std::mutex> ist_lock(pending_subscription_mutex_);
remove_pending_subscription(_service, _instance, _eventgroup, _event);
- stub_->send_unsubscribe(find_local(_service, _instance),
+ stub_->send_unsubscribe(
+ ep_mgr_->find_local(_service, _instance),
_client, _service, _instance, _eventgroup, _event,
- DEFAULT_SUBSCRIPTION);
+ PENDING_SUBSCRIPTION_ID);
}
}
- clear_multicast_endpoints(_service, _instance);
+ ep_mgr_impl_->clear_multicast_endpoints(_service, _instance);
} else {
VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
@@ -609,18 +707,21 @@ void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
}
bool routing_manager_impl::send(client_t _client,
- std::shared_ptr<message> _message, bool _flush) {
- return routing_manager_base::send(_client, _message, _flush);
+ std::shared_ptr<message> _message) {
+ return routing_manager_base::send(_client, _message);
}
bool routing_manager_impl::send(client_t _client, const byte_t *_data,
- length_t _size, instance_t _instance, bool _flush, bool _reliable,
- client_t _bound_client, bool _is_valid_crc, bool _sent_from_remote) {
+ length_t _size, instance_t _instance, bool _reliable,
+ client_t _bound_client,
+ credentials_t _credentials,
+ uint8_t _status_check, bool _sent_from_remote) {
bool is_sent(false);
if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
std::shared_ptr<endpoint> its_target;
bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]);
bool is_notification = utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]);
+ bool is_response = utility::is_response(_data[VSOMEIP_MESSAGE_TYPE_POS]);
client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN],
_data[VSOMEIP_CLIENT_POS_MAX]);
@@ -629,21 +730,14 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
method_t its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
- bool is_service_discovery = (its_service == vsomeip::sd::service
- && its_method == vsomeip::sd::method);
-
-#ifdef USE_DLT
- bool is_response(false);
-#endif
+ bool is_service_discovery
+ = (its_service == sd::service && its_method == sd::method);
if (is_request) {
- its_target = find_local(its_service, _instance);
+ its_target = ep_mgr_->find_local(its_service, _instance);
} else if (!is_notification) {
-#ifdef USE_DLT
- is_response = true;
-#endif
its_target = find_local(its_client);
- } else if (is_notification && _client) { // Selective notifications!
+ } else if (is_notification && _client && !is_service_discovery) { // Selective notifications!
if (_client == get_client()) {
#ifdef USE_DLT
const uint16_t its_data_size
@@ -654,7 +748,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
#endif
- deliver_message(_data, _size, _instance, _reliable, _bound_client, _is_valid_crc, _sent_from_remote);
+ deliver_message(_data, _size, _instance, _reliable, _bound_client, _credentials, _status_check, _sent_from_remote);
return true;
}
its_target = find_local(_client);
@@ -673,36 +767,39 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
_data, its_data_size);
}
#endif
- is_sent = send_local(its_target, get_client(), _data, _size, _instance, _flush, _reliable, VSOMEIP_SEND, _is_valid_crc);
+ is_sent = send_local(its_target, get_client(), _data, _size, _instance, _reliable, VSOMEIP_SEND, _status_check);
} else {
// Check whether hosting application should get the message
// If not, check routes to external
- if ((its_client == host_->get_client() && !is_request)
+ if ((its_client == host_->get_client() && is_response)
|| (find_local_client(its_service, _instance)
== host_->get_client() && is_request)) {
- // TODO: find out how to handle session id here
- is_sent = deliver_message(_data, _size, _instance, _reliable, _bound_client, _is_valid_crc, _sent_from_remote);
+ // TODO: Find out how to handle session id here
+ is_sent = deliver_message(_data, _size, _instance, _reliable, VSOMEIP_ROUTING_CLIENT, _credentials, _status_check);
} else {
e2e_buffer outputBuffer;
- if( configuration_->is_e2e_enabled()) {
+ if (e2e_provider_) {
if ( !is_service_discovery) {
service_t its_service = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
method_t its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
- if( custom_protectors.count({its_service, its_method})) {
+#ifndef ANDROID
+ if (e2e_provider_->is_protected({its_service, its_method})) {
outputBuffer.assign(_data, _data + VSOMEIP_PAYLOAD_POS);
e2e_buffer inputBuffer(_data + VSOMEIP_PAYLOAD_POS, _data +_size);
- custom_protectors[{its_service, its_method}]->protect( inputBuffer);
+ e2e_provider_->protect({its_service, its_method}, inputBuffer);
outputBuffer.resize(inputBuffer.size() + VSOMEIP_PAYLOAD_POS);
std::copy(inputBuffer.begin(), inputBuffer.end(), outputBuffer.begin() + VSOMEIP_PAYLOAD_POS);
_data = outputBuffer.data();
}
+#endif
}
}
if (is_request) {
- client_t client = is_specific_endpoint_client(its_client, its_service, _instance);
- its_target = find_or_create_remote_client(its_service, _instance, _reliable, client);
+ client_t client = VSOMEIP_ROUTING_CLIENT;
+ its_target = ep_mgr_impl_->find_or_create_remote_client(
+ its_service, _instance, _reliable, client);
if (its_target) {
#ifdef USE_DLT
const uint16_t its_data_size
@@ -713,7 +810,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
#endif
- is_sent = its_target->send(_data, _size, _flush);
+ is_sent = its_target->send(_data, _size);
} else {
const session_t its_session = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SESSION_POS_MIN],
@@ -729,7 +826,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
std::shared_ptr<serviceinfo> its_info(find_service(its_service, _instance));
if (its_info || is_service_discovery) {
if (is_notification && !is_service_discovery) {
- send_local_notification(get_client(), _data, _size, _instance, _flush, _reliable, _is_valid_crc);
+ send_local_notification(get_client(), _data, _size, _instance, _reliable, _status_check);
method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
_data[VSOMEIP_METHOD_POS_MAX]);
std::shared_ptr<event> its_event = find_event(its_service, _instance, its_method);
@@ -741,42 +838,49 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
// we need both endpoints as clients can subscribe to events via TCP and UDP
std::shared_ptr<endpoint> its_udp_server_endpoint = its_info->get_endpoint(false);
std::shared_ptr<endpoint> its_tcp_server_endpoint = its_info->get_endpoint(true);
- bool is_offered_both(false);
- if (its_udp_server_endpoint && its_tcp_server_endpoint) {
- is_offered_both = true;
- }
+
if (its_udp_server_endpoint || its_tcp_server_endpoint) {
+ const auto its_reliability = its_event->get_reliability();
for (auto its_group : its_event->get_eventgroups()) {
auto its_eventgroup = find_eventgroup(its_service, _instance, its_group);
if (its_eventgroup) {
// Unicast targets
- for (const auto &its_remote : its_eventgroup->get_targets()) {
- if(its_remote.endpoint_->is_reliable() && its_tcp_server_endpoint) {
- if (!is_offered_both || (is_offered_both && its_event->is_reliable())) {
- its_targets.insert(its_remote.endpoint_);
+ for (const auto &its_remote : its_eventgroup->get_unicast_targets()) {
+ if (its_remote->is_reliable() && its_tcp_server_endpoint) {
+ if (its_reliability == reliability_type_e::RT_RELIABLE
+ || its_reliability == reliability_type_e::RT_BOTH) {
+ its_targets.insert(its_remote);
}
} else if (its_udp_server_endpoint && !its_eventgroup->is_sending_multicast()) {
- if (!is_offered_both || (is_offered_both && !its_event->is_reliable())) {
- its_targets.insert(its_remote.endpoint_);
+ if (its_reliability == reliability_type_e::RT_UNRELIABLE
+ || its_reliability == reliability_type_e::RT_BOTH) {
+ its_targets.insert(its_remote);
}
}
}
// Send to multicast targets if subscribers are still interested
if (its_eventgroup->is_sending_multicast()) {
- for (auto its_multicast_target : its_eventgroup->get_multicast_targets()) {
- if (!is_offered_both || (is_offered_both && !its_event->is_reliable())) {
- its_targets.insert(its_multicast_target.endpoint_);
+ if (its_reliability == reliability_type_e::RT_UNRELIABLE
+ || its_reliability == reliability_type_e::RT_BOTH) {
+ boost::asio::ip::address its_address;
+ uint16_t its_port;
+ if (its_eventgroup->get_multicast(its_address, its_port)) {
+ std::shared_ptr<endpoint_definition> its_multicast_target;
+ its_multicast_target = endpoint_definition::get(its_address,
+ its_port, false, its_service, _instance);
+ its_targets.insert(its_multicast_target);
}
}
}
}
}
}
+
for (auto const &target : its_targets) {
if (target->is_reliable()) {
- its_tcp_server_endpoint->send_to(target, _data, _size, _flush);
+ its_tcp_server_endpoint->send_to(target, _data, _size);
} else {
- its_udp_server_endpoint->send_to(target, _data, _size, _flush);
+ its_udp_server_endpoint->send_to(target, _data, _size);
}
#ifdef USE_DLT
has_sent = true;
@@ -798,7 +902,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
if ((utility::is_response(_data[VSOMEIP_MESSAGE_TYPE_POS])
|| utility::is_error(_data[VSOMEIP_MESSAGE_TYPE_POS]))
&& !its_info->is_local()) {
- // we received a response/error but neither the hosting application
+ // We received a response/error but neither the hosting application
// nor another local client could be found --> drop
const session_t its_session = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SESSION_POS_MIN],
@@ -824,7 +928,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
#endif
- is_sent = its_target->send(_data, _size, _flush);
+ is_sent = its_target->send(_data, _size);
} else {
const session_t its_session = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SESSION_POS_MIN],
@@ -860,30 +964,43 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
}
bool routing_manager_impl::send_to(
+ const client_t _client,
const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message, bool _flush) {
+ std::shared_ptr<message> _message) {
bool is_sent(false);
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(_message.get())) {
- const byte_t *_data = serializer_->get_data();
- length_t _size = serializer_->get_size();
- e2e_buffer outputBuffer;
- if( configuration_->is_e2e_enabled()) {
+
+ std::shared_ptr<serializer> its_serializer(get_serializer());
+ if (its_serializer->serialize(_message.get())) {
+ const byte_t *its_data = its_serializer->get_data();
+ length_t its_size = its_serializer->get_size();
+ e2e_buffer its_output_buffer;
+ if (e2e_provider_) {
service_t its_service = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
+ its_data[VSOMEIP_SERVICE_POS_MIN],
+ its_data[VSOMEIP_SERVICE_POS_MAX]);
method_t its_method = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
- if( custom_protectors.count({its_service, its_method})) {
- outputBuffer.assign(_data, _data + VSOMEIP_PAYLOAD_POS);
- e2e_buffer inputBuffer(_data + VSOMEIP_PAYLOAD_POS, _data +_size);
- custom_protectors[{its_service, its_method}]->protect( inputBuffer);
- outputBuffer.resize(inputBuffer.size() + VSOMEIP_PAYLOAD_POS);
- std::copy(inputBuffer.begin(), inputBuffer.end(), outputBuffer.begin() + VSOMEIP_PAYLOAD_POS);
- _data = outputBuffer.data();
+ its_data[VSOMEIP_METHOD_POS_MIN],
+ its_data[VSOMEIP_METHOD_POS_MAX]);
+#ifndef ANDROID
+ if(e2e_provider_->is_protected({its_service, its_method})) {
+ its_output_buffer.assign(its_data, its_data + VSOMEIP_PAYLOAD_POS);
+ e2e_buffer its_input_buffer(its_data + VSOMEIP_PAYLOAD_POS, its_data + its_size);
+ e2e_provider_->protect({its_service, its_method}, its_input_buffer);
+ its_output_buffer.resize(its_input_buffer.size() + VSOMEIP_PAYLOAD_POS);
+ std::copy(its_input_buffer.begin(), its_input_buffer.end(),
+ its_output_buffer.begin() + VSOMEIP_PAYLOAD_POS);
+ its_data = its_output_buffer.data();
}
+#endif
}
- is_sent = send_to(_target, _data, _size, _message->get_instance(), _flush);
- serializer_->reset();
+
+ const_cast<byte_t*>(its_data)[VSOMEIP_CLIENT_POS_MIN] = VSOMEIP_WORD_BYTE1(_client);
+ const_cast<byte_t*>(its_data)[VSOMEIP_CLIENT_POS_MAX] = VSOMEIP_WORD_BYTE0(_client);
+
+ is_sent = send_to(_target, its_data, its_size, _message->get_instance());
+
+ its_serializer->reset();
+ put_serializer(its_serializer);
} else {
VSOMEIP_ERROR<< "routing_manager_impl::send_to: serialization failed.";
}
@@ -892,10 +1009,10 @@ bool routing_manager_impl::send_to(
bool routing_manager_impl::send_to(
const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush) {
- std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(
- _target->get_remote_port(), _target->is_reliable());
+ const byte_t *_data, uint32_t _size, instance_t _instance) {
+ std::shared_ptr<endpoint> its_endpoint =
+ ep_mgr_impl_->find_server_endpoint(
+ _target->get_remote_port(), _target->is_reliable());
if (its_endpoint) {
#ifdef USE_DLT
@@ -909,26 +1026,30 @@ bool routing_manager_impl::send_to(
#else
(void) _instance;
#endif
- return its_endpoint->send_to(_target, _data, _size, _flush);
+ return its_endpoint->send_to(_target, _data, _size);
}
return false;
}
-bool routing_manager_impl::send_to(
+bool routing_manager_impl::send_via_sd(
const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size, uint16_t _sd_port) {
- std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(
- _sd_port, _target->is_reliable());
+ std::shared_ptr<endpoint> its_endpoint =
+ ep_mgr_impl_->find_server_endpoint(_sd_port,
+ _target->is_reliable());
if (its_endpoint) {
#ifdef USE_DLT
- const uint16_t its_data_size
- = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
+ if (tc_->is_sd_enabled()) {
+ const uint16_t its_data_size
+ = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
- trace::header its_header;
- if (its_header.prepare(its_endpoint, true, 0x0))
- tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
- _data, its_data_size);
+ trace::header its_header;
+ if (its_header.prepare(its_endpoint, true, 0x0))
+ tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
+ _data, its_data_size);
+
+ }
#endif
return its_endpoint->send_to(_target, _data, _size);
}
@@ -936,13 +1057,16 @@ bool routing_manager_impl::send_to(
return false;
}
-void routing_manager_impl::register_event(
- client_t _client, service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, std::chrono::milliseconds _cycle,
- bool _change_resets_cycle, epsilon_change_func_t _epsilon_change_func,
+void routing_manager_impl::register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups, const event_type_e _type,
+ reliability_type_e _reliability,
+ std::chrono::milliseconds _cycle, bool _change_resets_cycle,
+ bool _update_on_change,
+ epsilon_change_func_t _epsilon_change_func,
bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) {
- auto its_event = find_event(_service, _instance, _event);
+ auto its_event = find_event(_service, _instance, _notifier);
bool is_first(false);
if (its_event) {
if (!its_event->has_ref(_client, _is_provided)) {
@@ -952,8 +1076,11 @@ void routing_manager_impl::register_event(
is_first = true;
}
if (is_first) {
- routing_manager_base::register_event(_client, _service, _instance,
- _event, _eventgroups, _is_field, _cycle, _change_resets_cycle,
+ routing_manager_base::register_event(_client,
+ _service, _instance,
+ _notifier,
+ _eventgroups, _type, _reliability,
+ _cycle, _change_resets_cycle, _update_on_change,
_epsilon_change_func, _is_provided, _is_shadow,
_is_cache_placeholder);
}
@@ -961,17 +1088,20 @@ void routing_manager_impl::register_event(
<< std::hex << std::setw(4) << std::setfill('0') << _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') << _event
+ << std::hex << std::setw(4) << std::setfill('0') << _notifier
<< ":is_provider=" << _is_provided << "]";
}
void routing_manager_impl::register_shadow_event(client_t _client,
service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, bool _is_provided) {
- routing_manager_base::register_event(_client, _service, _instance,
- _event, _eventgroups, _is_field,
- std::chrono::milliseconds::zero(), false,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups, event_type_e _type,
+ reliability_type_e _reliability, bool _is_provided) {
+ routing_manager_base::register_event(_client,
+ _service, _instance,
+ _notifier,
+ _eventgroups, _type, _reliability,
+ std::chrono::milliseconds::zero(), false, true,
nullptr,
_is_provided, true);
}
@@ -985,56 +1115,49 @@ void routing_manager_impl::unregister_shadow_event(client_t _client,
void routing_manager_impl::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload, client_t _client,
- bool _force, bool _flush, bool _remote_subscriber) {
+ bool _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , bool _remote_subscriber
+#endif
+ ) {
if (find_local(_client)) {
routing_manager_base::notify_one(_service, _instance, _event, _payload,
- _client, _force, _flush, _remote_subscriber);
+ _client, _force
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , _remote_subscriber
+#endif
+ );
} else {
std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
if (its_event) {
- // Event is valid for service/instance
- bool found_eventgroup(false);
- // Iterate over all groups of the event to ensure at least
- // one valid eventgroup for service/instance exists.
- for (auto its_group : its_event->get_eventgroups()) {
- auto its_eventgroup = find_eventgroup(_service, _instance, its_group);
+ std::set<std::shared_ptr<endpoint_definition> > its_targets;
+ const auto its_reliability = its_event->get_reliability();
+ for (const auto g : its_event->get_eventgroups()) {
+ const auto its_eventgroup = find_eventgroup(_service, _instance, g);
if (its_eventgroup) {
- // Eventgroup is valid for service/instance
- found_eventgroup = true;
- break;
- }
- }
- if (found_eventgroup) {
- const bool is_offered_both =
- (configuration_->get_reliable_port(_service, _instance) != ILLEGAL_PORT &&
- configuration_->get_unreliable_port(_service, _instance) != ILLEGAL_PORT);
-
- std::set<std::shared_ptr<endpoint_definition>> its_targets;
- // Now set event's payload!
- // Either with endpoint_definition (remote) or with client (local).
- {
- std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_);
- auto its_service = remote_subscribers_.find(_service);
- if (its_service != remote_subscribers_.end()) {
- auto its_instance = its_service->second.find(_instance);
- if (its_instance != its_service->second.end()) {
- auto its_subscriber = its_instance->second.find(_client);
- if (its_subscriber != its_instance->second.end()) {
- its_targets = its_subscriber->second;
+ const auto its_subscriptions = its_eventgroup->get_remote_subscriptions();
+ for (const auto &s : its_subscriptions) {
+ if (s->has_client(_client)) {
+ if (its_reliability == reliability_type_e::RT_RELIABLE
+ || its_reliability == reliability_type_e::RT_BOTH) {
+ const auto its_reliable = s->get_reliable();
+ if (its_reliable)
+ its_targets.insert(its_reliable);
+ }
+ if (its_reliability == reliability_type_e::RT_UNRELIABLE
+ || its_reliability == reliability_type_e::RT_BOTH) {
+ const auto its_unreliable = s->get_unreliable();
+ if (its_unreliable)
+ its_targets.insert(its_unreliable);
}
}
}
}
+ }
+
+ if (its_targets.size() > 0) {
for (const auto &its_target : its_targets) {
- if (!is_offered_both) {
- its_event->set_payload(_payload, its_target, _force, _flush);
- } else {
- if (its_event->is_reliable() && its_target->is_reliable()) {
- its_event->set_payload(_payload, its_target, _force, _flush);
- } else if (!its_event->is_reliable() && !its_target->is_reliable()) {
- its_event->set_payload(_payload, its_target, _force, _flush);
- }
- }
+ its_event->set_payload(_payload, _client, its_target, _force);
}
}
} else {
@@ -1050,24 +1173,6 @@ void routing_manager_impl::on_availability(service_t _service, instance_t _insta
host_->on_availability(_service, _instance, _is_available, _major, _minor);
}
-void routing_manager_impl::on_error(
- const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port) {
- instance_t its_instance = 0;
- if (_length >= VSOMEIP_SERVICE_POS_MAX) {
- service_t its_service = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
- its_instance = find_instance(its_service, _receiver);
- }
- send_error(return_code_e::E_MALFORMED_MESSAGE, _data, _length, its_instance,
- _receiver->is_reliable(), _receiver, _remote_address, _remote_port);
-}
-
-void routing_manager_impl::release_port(uint16_t _port, bool _reliable) {
- std::lock_guard<std::mutex> its_lock(used_client_ports_mutex_);
- used_client_ports_[_reliable].erase(_port);
-}
bool routing_manager_impl::offer_service_remotely(service_t _service,
instance_t _instance,
@@ -1156,7 +1261,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service,
clear_remote_subscriber(_service, _instance);
if (discovery_ && its_info) {
- discovery_->stop_offer_service(_service, _instance, its_info);
+ discovery_->stop_offer_service(its_info);
its_info->set_endpoint(std::shared_ptr<endpoint>(), _reliable);
}
} else {
@@ -1168,7 +1273,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service,
// ensure to not send StopOffer for endpoint on which the service is
// still offered
its_copied_info->set_endpoint(std::shared_ptr<endpoint>(), !_reliable);
- discovery_->stop_offer_service(_service, _instance, its_copied_info);
+ discovery_->stop_offer_service(its_copied_info);
}
}
@@ -1178,7 +1283,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service,
void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
- client_t _bound_client,
+ client_t _bound_client, credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port) {
#if 0
@@ -1191,7 +1296,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
(void)_bound_client;
service_t its_service;
method_t its_method;
- bool its_is_crc_valid(true);
+ uint8_t its_check_status = e2e::profile_interface::generic_check_status::E2E_OK;
instance_t its_instance(0x0);
#ifdef USE_DLT
bool is_forwarded(true);
@@ -1215,7 +1320,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
}
}
} else {
- its_instance = find_instance(its_service, _receiver);
+ its_instance = ep_mgr_impl_->find_instance(its_service, _receiver);
if (its_instance == 0xFFFF) {
its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN],
@@ -1256,7 +1361,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
}
// Security checks if enabled!
- if (configuration_->is_security_enabled()) {
+ if (security::get()->is_enabled()) {
if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
client_t requester = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_CLIENT_POS_MIN],
@@ -1276,7 +1381,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
<< " which is already used locally ~> Skip message!";
return;
}
- if (!configuration_->is_remote_client_allowed()) {
+ if (!security::get()->is_remote_client_allowed()) {
// check if policy allows remote requests.
VSOMEIP_WARNING << "routing_manager_impl::on_message: "
<< std::hex << "Security: Remote client with client ID 0x" << requester
@@ -1287,37 +1392,28 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
}
}
}
- if( configuration_->is_e2e_enabled()) {
+ if (e2e_provider_) {
its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN],
_data[VSOMEIP_METHOD_POS_MAX]);
- if( custom_checkers.count({its_service, its_method})) {
+#ifndef ANDROID
+ if( e2e_provider_->is_checked({its_service, its_method})) {
e2e_buffer inputBuffer(_data + VSOMEIP_PAYLOAD_POS, _data + _size);
- e2e::profile_interface::generic_check_status check_status;
- custom_checkers[{its_service, its_method}]->check( inputBuffer, check_status);
+ e2e_provider_->check({its_service, its_method}, inputBuffer, its_check_status);
- if ( check_status != e2e::profile_interface::generic_check_status::E2E_OK ) {
+ if ( its_check_status != e2e::profile_interface::generic_check_status::E2E_OK ) {
VSOMEIP_INFO << std::hex << "E2E protection: CRC check failed for service: " << its_service << " method: " << its_method;
- its_is_crc_valid = false;
}
}
+#endif
}
- if (!deliver_specific_endpoint_message(
- its_service, its_instance, _data, _size, _receiver)) {
- // set client ID to zero for all messages
- if( utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
- byte_t *its_data = const_cast<byte_t *>(_data);
- its_data[VSOMEIP_CLIENT_POS_MIN] = 0x0;
- its_data[VSOMEIP_CLIENT_POS_MAX] = 0x0;
- }
- // Common way of message handling
+
+ // Common way of message handling
#ifdef USE_DLT
- is_forwarded =
+ is_forwarded =
#endif
- on_message(its_service, its_instance, _data, _size, _receiver->is_reliable(),
- _bound_client, its_is_crc_valid, true);
-
- }
+ on_message(its_service, its_instance, _data, _size, _receiver->is_reliable(),
+ _bound_client, _credentials, its_check_status, true);
}
}
#ifdef USE_DLT
@@ -1345,7 +1441,8 @@ bool routing_manager_impl::on_message(
service_t _service, instance_t _instance,
const byte_t *_data, length_t _size,
bool _reliable, client_t _bound_client,
- bool _is_valid_crc,
+ credentials_t _credentials,
+ uint8_t _check_status,
bool _is_from_remote) {
#if 0
std::stringstream msg;
@@ -1367,15 +1464,15 @@ bool routing_manager_impl::on_message(
_data[VSOMEIP_CLIENT_POS_MAX]);
}
- if (its_client == VSOMEIP_ROUTING_CLIENT
- && utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
is_forwarded = deliver_notification(_service, _instance, _data, _size,
- _reliable, _bound_client, _is_valid_crc, _is_from_remote);
+ _reliable, _bound_client, _credentials, _check_status, _is_from_remote);
} else if (its_client == host_->get_client()) {
deliver_message(_data, _size, _instance,
- _reliable, _bound_client, _is_valid_crc, _is_from_remote);
+ _reliable, _bound_client, _credentials, _check_status, _is_from_remote);
} else {
- send(its_client, _data, _size, _instance, true, _reliable, _bound_client, _is_valid_crc, _is_from_remote); //send to proxy
+ send(its_client, _data, _size, _instance, _reliable,
+ _bound_client, _credentials, _check_status, _is_from_remote); //send to proxy
}
return is_forwarded;
}
@@ -1384,9 +1481,7 @@ void routing_manager_impl::on_notification(client_t _client,
service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _notify_one) {
event_t its_event_id = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
-
+ _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
std::shared_ptr<event> its_event = find_event(_service, _instance, its_event_id);
if (its_event) {
uint32_t its_length = utility::get_payload_size(_data, _size);
@@ -1396,197 +1491,37 @@ void routing_manager_impl::on_notification(client_t _client,
its_length);
if (_notify_one) {
- notify_one(_service, _instance, its_event->get_event(), its_payload, _client, true, true, false);
+ notify_one(_service, _instance, its_event->get_event(),
+ its_payload, _client, true
+#ifdef VSOMEIP_ENABLE_COMPAT
+ , false
+#endif
+ );
} else {
if (its_event->is_field()) {
- if (its_event->is_set()) {
- its_event->set_payload(its_payload, false, true);
- } else {
- // new subscribers will be notified by SD via sent_initiale_events;
- if (its_event->get_remote_notification_pending()) {
- // Set payload first time ~> notify all remote subscriber per unicast (initial field)
- std::vector<std::unique_lock<std::mutex>> its_locks;
- std::vector<std::shared_ptr<eventgroupinfo>> its_eventgroupinfos;
- for (auto its_group : its_event->get_eventgroups()) {
- auto its_eventgroup = find_eventgroup(_service, _instance, its_group);
- if (its_eventgroup) {
- its_locks.push_back(its_eventgroup->get_subscription_lock());
- its_eventgroupinfos.push_back(its_eventgroup);
- }
- }
-
- bool is_offered_both(false);
- if (configuration_->get_reliable_port(_service, _instance) != ILLEGAL_PORT &&
- configuration_->get_unreliable_port(_service, _instance) != ILLEGAL_PORT) {
- is_offered_both = true;
- }
- for (const auto &its_eventgroup : its_eventgroupinfos) {
- //Unicast targets
- for (auto its_remote : its_eventgroup->get_targets()) {
- if (!is_offered_both) {
- its_event->set_payload(its_payload, its_remote.endpoint_, true, true);
- } else {
- bool was_set(false);
- if (its_event->is_reliable() && its_remote.endpoint_->is_reliable()) {
- its_event->set_payload(its_payload, its_remote.endpoint_, true, true);
- was_set = true;
- }
- if (!its_event->is_reliable() && !its_remote.endpoint_->is_reliable()) {
- its_event->set_payload(its_payload, its_remote.endpoint_, true, true);
- was_set = true;
- }
- if (!was_set) {
- its_event->set_payload_dont_notify(its_payload);
- }
- }
- }
- }
- its_event->set_remote_notification_pending(false);
- } else {
- its_event->set_payload_dont_notify(its_payload);
- }
+ if (!its_event->set_payload_notify_pending(its_payload)) {
+ its_event->set_payload(its_payload, false);
}
} else {
- its_event->set_payload(its_payload, false, true);
+ its_event->set_payload(its_payload, false, true);
}
}
}
}
-void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
- // Is called when endpoint->connect succeeded!
- struct service_info {
- service_t service_id_;
- instance_t instance_id_;
- major_version_t major_;
- minor_version_t minor_;
- bool reliable_;
- std::shared_ptr<endpoint> endpoint_;
- };
-
- // Set to state CONNECTED as connection is not yet fully established in remote side POV
- // but endpoint is ready to send / receive. Set to ESTABLISHED after timer expires
- // to prevent inserting subscriptions twice or send out subscription before remote side
- // is finished with TCP 3 way handshake
- _endpoint->set_connected(true);
-
- std::forward_list<struct service_info> services_to_report_;
- {
- 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(false);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second.get() == _endpoint.get()) {
- std::shared_ptr<serviceinfo> its_info(find_service(its_service.first, its_instance.first));
- if (!its_info) {
- _endpoint->set_established(true);
- return;
- }
- services_to_report_.push_front(
- { its_service.first,
- its_instance.first,
- its_info->get_major(),
- its_info->get_minor(),
- false, _endpoint });
- }
- }
- found_endpoint = its_client.second.find(true);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second.get() == _endpoint.get()) {
- std::shared_ptr<serviceinfo> its_info(find_service(its_service.first, its_instance.first));
- if (!its_info) {
- _endpoint->set_established(true);
- return;
- }
- services_to_report_.push_front(
- { its_service.first,
- its_instance.first,
- its_info->get_major(),
- its_info->get_minor(),
- true, _endpoint });
- }
- }
- }
- }
- }
+bool routing_manager_impl::is_last_stop_callback(const uint32_t _callback_id) {
+ bool last_callback(false);
+ auto found_id = callback_counts_.find(_callback_id);
+ if (found_id != callback_counts_.end()) {
+ found_id->second--;
+ if (found_id->second == 0) {
+ last_callback = true;
}
}
-
- for (const auto &s : services_to_report_) {
- on_availability(s.service_id_, s.instance_id_, true, s.major_, s.minor_);
- if (s.reliable_) {
- stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, s.service_id_,
- s.instance_id_, s.major_, s.minor_);
- }
- std::shared_ptr<boost::asio::steady_timer> its_timer =
- std::make_shared<boost::asio::steady_timer>(io_);
- boost::system::error_code ec;
- its_timer->expires_from_now(std::chrono::milliseconds(3), ec);
- if (!ec) {
- its_timer->async_wait(
- std::bind(
- &routing_manager_impl::call_sd_endpoint_connected,
- std::static_pointer_cast<routing_manager_impl>(
- shared_from_this()),
- std::placeholders::_1, s.service_id_,
- s.instance_id_, s.endpoint_, its_timer));
- } else {
- VSOMEIP_ERROR<< "routing_manager_impl::on_connect: " << ec.message();
- }
- }
- if (services_to_report_.empty()) {
- _endpoint->set_established(true);
- }
-}
-
-void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
- // Is called when endpoint->connect fails!
- 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(false);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second.get() == _endpoint.get()) {
-
- std::shared_ptr<serviceinfo> its_info(find_service(its_service.first, its_instance.first));
- if(!its_info){
- return;
- }
- on_availability(its_service.first, its_instance.first,
- false, its_info->get_major(), its_info->get_minor());
- }
- }
- found_endpoint = its_client.second.find(true);
- if (found_endpoint != its_client.second.end()) {
- if (found_endpoint->second.get() == _endpoint.get()) {
-
- std::shared_ptr<serviceinfo> its_info(find_service(its_service.first, its_instance.first));
- if(!its_info){
- return;
- }
- on_availability(its_service.first, its_instance.first,
- false, its_info->get_major(), its_info->get_minor());
- stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT,
- its_service.first, its_instance.first,
- its_info->get_major(),
- its_info->get_minor());
- VSOMEIP_WARNING << __func__
- << ": lost connection to remote service: "
- << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_instance.first;
- }
- }
- }
- }
- }
+ if (last_callback) {
+ callback_counts_.erase(_callback_id);
}
+ return last_callback;
}
void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _service,
@@ -1643,47 +1578,133 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se
if (its_info) {
its_reliable_endpoint = its_info->get_endpoint(true);
its_unreliable_endpoint = its_info->get_endpoint(false);
- }
+ static std::atomic<uint32_t> callback_id(0);
+ const uint32_t its_callback_id = ++callback_id;
+
+ struct ready_to_stop_t {
+ ready_to_stop_t() : reliable_(false), unreliable_(false){}
+ std::atomic<bool> reliable_;
+ std::atomic<bool> unreliable_;
+ };
+ auto ready_to_stop = std::make_shared<ready_to_stop_t>();
+ auto ptr = shared_from_this();
+
+ auto callback = [&, its_callback_id, ptr, its_info, its_reliable_endpoint, its_unreliable_endpoint,
+ ready_to_stop, _service, _instance, _major, _minor]
+ (std::shared_ptr<endpoint> _endpoint, service_t _stopped_service) {
+ (void)_stopped_service;
+ if (its_reliable_endpoint && its_reliable_endpoint == _endpoint) {
+ ready_to_stop->reliable_ = true;
+ }
+ if (its_unreliable_endpoint && its_unreliable_endpoint == _endpoint) {
+ ready_to_stop->unreliable_ = true;
+ }
+ if ((its_unreliable_endpoint && !ready_to_stop->unreliable_) ||
+ (its_reliable_endpoint && !ready_to_stop->reliable_)) {
+ {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ if (is_last_stop_callback(its_callback_id)) {
+ erase_offer_command(_service, _instance);
+ }
+ }
+ return;
+ }
- if (discovery_) {
- if (its_info) {
- if (its_info->get_major() == _major && its_info->get_minor() == _minor) {
- discovery_->stop_offer_service(_service, _instance, its_info);
+ if (discovery_) {
+ if (its_info->get_major() == _major && its_info->get_minor() == _minor) {
+ discovery_->stop_offer_service(its_info);
+ }
}
- }
- }
- del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr),
- (its_unreliable_endpoint != nullptr));
+ del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr),
+ (its_unreliable_endpoint != nullptr));
- // Cleanup reliable & unreliable server endpoints hold before
- if (its_info) {
- if (its_unreliable_endpoint) {
- cleanup_server_endpoint(_service, its_unreliable_endpoint);
- // Clear service info and service group
- clear_service_info(_service, _instance, false);
+ for (const auto& ep: {its_reliable_endpoint, its_unreliable_endpoint}) {
+ if (ep) {
+ if (ep_mgr_impl_->remove_instance(_service, ep.get())) {
+ {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ callback_counts_[its_callback_id]++;
+ }
+ // last instance -> pass ANY_INSTANCE and shutdown completely
+ ep->prepare_stop(
+ [&, _service, _instance, its_callback_id, ptr, its_reliable_endpoint, its_unreliable_endpoint]
+ (std::shared_ptr<endpoint> _endpoint,
+ service_t _stopped_service) {
+ (void)_stopped_service;
+ if (ep_mgr_impl_->remove_server_endpoint(
+ _endpoint->get_local_port(),
+ _endpoint->is_reliable())) {
+ _endpoint->stop();
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ if (is_last_stop_callback(its_callback_id)) {
+ erase_offer_command(_service, _instance);
+ }
+ }
+ }, ANY_SERVICE);
+ }
+ // Clear service info and service group
+ clear_service_info(_service, _instance, ep->is_reliable());
+ }
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ if (is_last_stop_callback(its_callback_id)) {
+ erase_offer_command(_service, _instance);
+ }
+ }
+ };
+
+ // determine callback count
+ for (const auto& ep : {its_reliable_endpoint, its_unreliable_endpoint}) {
+ if (ep) {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ auto found_id = callback_counts_.find(its_callback_id);
+ if (found_id != callback_counts_.end()) {
+ found_id->second++;
+ } else {
+ callback_counts_[its_callback_id] = 1;
+ }
+ }
}
- if (its_reliable_endpoint) {
- cleanup_server_endpoint(_service, its_reliable_endpoint);
- // Clear service info and service group
- clear_service_info(_service, _instance, true);
+ for (const auto& ep : {its_reliable_endpoint, its_unreliable_endpoint}) {
+ if (ep) {
+ ep->prepare_stop(callback, _service);
+ }
+ }
+
+ if (!its_reliable_endpoint && !its_unreliable_endpoint) {
+ {
+ std::lock_guard<std::mutex> its_lock(callback_counts_mutex_);
+ callback_counts_.erase(its_callback_id);
+ }
+ erase_offer_command(_service, _instance);
}
+ } else {
+ erase_offer_command(_service, _instance);
}
}
bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
- instance_t _instance, bool _reliable, client_t _bound_client, bool _is_valid_crc, bool _is_from_remote) {
+ instance_t _instance, bool _reliable, client_t _bound_client, credentials_t _credentials,
+ uint8_t _status_check, bool _is_from_remote) {
bool is_delivered(false);
+ std::uint32_t its_sender_uid = std::get<0>(_credentials);
+ std::uint32_t its_sender_gid = std::get<1>(_credentials);
- auto a_deserializer = get_deserializer();
- a_deserializer->set_data(_data, _size);
- std::shared_ptr<message> its_message(a_deserializer->deserialize_message());
- a_deserializer->reset();
- put_deserializer(a_deserializer);
+ auto its_deserializer = get_deserializer();
+ its_deserializer->set_data(_data, _size);
+ std::shared_ptr<message_impl> its_message(its_deserializer->deserialize_message());
+ its_deserializer->reset();
+ put_deserializer(its_deserializer);
if (its_message) {
its_message->set_instance(_instance);
its_message->set_reliable(_reliable);
- its_message->set_is_valid_crc(_is_valid_crc);
+ its_message->set_check_result(_status_check);
+ its_message->set_uid(std::get<0>(_credentials));
+ its_message->set_gid(std::get<1>(_credentials));
if (!_is_from_remote) {
if (utility::is_notification(its_message->get_message_type())) {
@@ -1698,7 +1719,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
<< " ~> Skip message!";
return false;
} else {
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
+ if (!security::get()->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_impl::deliver_message: "
@@ -1711,7 +1733,7 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
}
}
} else if (utility::is_request(its_message->get_message_type())) {
- if (configuration_->is_security_enabled()
+ if (security::get()->is_enabled()
&& its_message->get_client() != _bound_client) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_impl::deliver_message:"
@@ -1720,12 +1742,13 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
<< its_message->get_service() << "/" << its_message->get_instance()
<< "/" << its_message->get_method() << " which doesn't match the bound client 0x"
<< std::setw(4) << std::setfill('0') << _bound_client
- << " ~> skip message!";
+ << " ~> Skip message!";
return false;
}
- if (!configuration_->is_client_allowed(its_message->get_client(),
- its_message->get_service(), its_message->get_instance(), its_message->get_method())) {
+ if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_message->get_client(), its_message->get_service(),
+ its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_impl::deliver_message: "
<< " isn't allowed to send a request to service/instance/method "
@@ -1746,8 +1769,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
<< " ~> Skip message!";
return false;
} else {
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
- its_message->get_instance(), its_message->get_method())) {
+ if (!security::get()->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
+ its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_impl::deliver_message: "
<< " isn't allowed to receive a response from service/instance/method "
@@ -1760,7 +1784,7 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
}
}
} else {
- if (!configuration_->is_remote_client_allowed()) {
+ if (!security::get()->is_remote_client_allowed()) {
// if the message is from remote, check if
// policy allows remote requests.
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
@@ -1773,7 +1797,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
<< " ~> Skip message!";
return false;
} else if (utility::is_notification(its_message->get_message_type())) {
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
+ if (!security::get()->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_impl::deliver_message: "
@@ -1800,11 +1825,14 @@ bool routing_manager_impl::deliver_notification(
service_t _service, instance_t _instance,
const byte_t *_data, length_t _length,
bool _reliable, client_t _bound_client,
- bool _is_valid_crc, bool _is_from_remote) {
- method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
+ credentials_t _credentials,
+ uint8_t _status_check, bool _is_from_remote) {
+ event_t its_event_id = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
+ client_t its_client_id = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]);
- std::shared_ptr<event> its_event = find_event(_service, _instance, its_method);
+ std::shared_ptr<event> its_event = find_event(_service, _instance, its_event_id);
if (its_event) {
if (!its_event->is_provided()) {
if (its_event->get_subscribers().size() == 0) {
@@ -1843,17 +1871,46 @@ bool routing_manager_impl::deliver_notification(
}
}
- for (const auto its_local_client : its_event->get_subscribers()) {
- if (its_local_client == host_->get_client()) {
- deliver_message(_data, _length, _instance, _reliable, _bound_client, _is_valid_crc, _is_from_remote);
- } else {
- std::shared_ptr<endpoint> its_local_target = find_local(its_local_client);
- if (its_local_target) {
- send_local(its_local_target, VSOMEIP_ROUTING_CLIENT,
- _data, _length, _instance, true, _reliable, VSOMEIP_SEND, _is_valid_crc);
+ if (its_event->get_type() != event_type_e::ET_SELECTIVE_EVENT) {
+ for (const auto its_local_client : its_event->get_subscribers()) {
+ if (its_local_client == host_->get_client()) {
+ deliver_message(_data, _length, _instance, _reliable,
+ _bound_client, _credentials, _status_check, _is_from_remote);
+ } else {
+ std::shared_ptr<endpoint> its_local_target = find_local(its_local_client);
+ if (its_local_target) {
+ send_local(its_local_target, VSOMEIP_ROUTING_CLIENT,
+ _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check);
+ }
+ }
+ }
+ } else {
+ // TODO: Check whether it makes more sense to set the client id
+ // for internal selective events. This would create some extra
+ // effort but we could avoid this hack.
+ if (its_client_id == VSOMEIP_ROUTING_CLIENT)
+ its_client_id = get_client();
+
+ auto its_subscribers = its_event->get_subscribers();
+ if (its_subscribers.find(its_client_id) != its_subscribers.end()) {
+ if (its_client_id == host_->get_client()) {
+ deliver_message(_data, _length, _instance, _reliable,
+ _bound_client, _credentials, _status_check, _is_from_remote);
+ } else {
+ std::shared_ptr<endpoint> its_local_target = find_local(its_client_id);
+ if (its_local_target) {
+ send_local(its_local_target, VSOMEIP_ROUTING_CLIENT,
+ _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check);
+ }
}
}
}
+ } else {
+ VSOMEIP_WARNING << __func__ << ": Event ["
+ << 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') << its_event_id << "]"
+ << " is not registered. The message is dropped.";
}
return true;
@@ -1865,34 +1922,40 @@ std::shared_ptr<eventgroupinfo> routing_manager_impl::find_eventgroup(
return routing_manager_base::find_eventgroup(_service, _instance, _eventgroup);
}
-const std::shared_ptr<configuration> routing_manager_impl::get_configuration() const {
- return (host_->get_configuration());
-}
-
std::shared_ptr<endpoint> routing_manager_impl::create_service_discovery_endpoint(
const std::string &_address, uint16_t _port, bool _reliable) {
- std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port,
- _reliable);
+ std::shared_ptr<endpoint> its_service_endpoint =
+ ep_mgr_impl_->find_server_endpoint(_port, _reliable);
if (!its_service_endpoint) {
try {
- its_service_endpoint = create_server_endpoint(_port, _reliable,
- true);
+ its_service_endpoint =
+ ep_mgr_impl_->create_server_endpoint(_port,
+ _reliable, true);
if (its_service_endpoint) {
- sd_info_ = std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR,
- DEFAULT_TTL, false); // false, because we do _not_ want to announce it...
+ sd_info_ = std::make_shared<serviceinfo>(
+ VSOMEIP_SD_SERVICE, VSOMEIP_SD_INSTANCE,
+ ANY_MAJOR, ANY_MINOR, DEFAULT_TTL,
+ false); // false, because we do _not_ want to announce it...
sd_info_->set_endpoint(its_service_endpoint, _reliable);
its_service_endpoint->add_default_target(VSOMEIP_SD_SERVICE,
_address, _port);
- its_service_endpoint->join(_address);
+ if (!_reliable) {
+#if defined(_WIN32) || defined(ANDROID)
+ dynamic_cast<udp_server_endpoint_impl*>(
+ its_service_endpoint.get())->join(_address);
+#else
+ reinterpret_cast<udp_server_endpoint_impl*>(
+ its_service_endpoint.get())->join(_address);
+#endif
+ }
} else {
VSOMEIP_ERROR<< "Service Discovery endpoint could not be created. "
"Please check your network configuration.";
}
} catch (const std::exception &e) {
- host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
- VSOMEIP_ERROR << "Service Discovery endpoint could not be created: "
- << e.what();
+ VSOMEIP_ERROR << "Server endpoint creation failed: Service "
+ "Discovery endpoint could not be created: " << e.what();
}
}
return its_service_endpoint;
@@ -1900,8 +1963,8 @@ std::shared_ptr<endpoint> routing_manager_impl::create_service_discovery_endpoin
services_t routing_manager_impl::get_offered_services() const {
services_t its_services;
- for (auto s : get_services()) {
- for (auto i : s.second) {
+ for (const auto& s : get_services()) {
+ for (const auto& i : s.second) {
if (i.second->is_local()) {
its_services[s.first][i.first] = i.second;
}
@@ -1926,7 +1989,7 @@ routing_manager_impl::get_offered_service_instances(service_t _service) const {
const services_t its_services(get_services());
const auto found_service = its_services.find(_service);
if (found_service != its_services.end()) {
- for (const auto i : found_service->second) {
+ for (const auto& i : found_service->second) {
if (i.second->is_local()) {
its_instances[i.first] = i.second;
}
@@ -1935,25 +1998,6 @@ routing_manager_impl::get_offered_service_instances(service_t _service) const {
return its_instances;
}
-std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
- 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);
- if (!its_endpoint) {
- its_endpoint = create_remote_client(_service, _instance, _reliable, _client);
- start_endpoint = true;
- }
- }
- if (start_endpoint && its_endpoint
- && configuration_->is_someip(_service, _instance)) {
- its_endpoint->start();
- }
- return its_endpoint;
-}
-
///////////////////////////////////////////////////////////////////////////////
// PRIVATE
///////////////////////////////////////////////////////////////////////////////
@@ -1969,39 +2013,29 @@ void routing_manager_impl::init_service_info(
return;
}
if (configuration_) {
- std::shared_ptr<endpoint> its_reliable_endpoint;
- std::shared_ptr<endpoint> its_unreliable_endpoint;
-
- uint16_t its_reliable_port = configuration_->get_reliable_port(_service,
- _instance);
- uint16_t its_unreliable_port = configuration_->get_unreliable_port(
- _service, _instance);
-
- bool is_someip = configuration_->is_someip(_service, _instance);
-
// Create server endpoints for local services only
if (_is_local_service) {
+ const bool is_someip = configuration_->is_someip(_service, _instance);
+ uint16_t its_reliable_port = configuration_->get_reliable_port(
+ _service, _instance);
if (ILLEGAL_PORT != its_reliable_port) {
- its_reliable_endpoint = find_or_create_server_endpoint(
- its_reliable_port, true, is_someip);
+ std::shared_ptr<endpoint> its_reliable_endpoint =
+ ep_mgr_impl_->find_or_create_server_endpoint(
+ its_reliable_port, true, is_someip, _service,
+ _instance);
if (its_reliable_endpoint) {
its_info->set_endpoint(its_reliable_endpoint, true);
- its_reliable_endpoint->increment_use_count();
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- service_instances_[_service][its_reliable_endpoint.get()] =
- _instance;
}
}
-
+ uint16_t its_unreliable_port = configuration_->get_unreliable_port(
+ _service, _instance);
if (ILLEGAL_PORT != its_unreliable_port) {
- its_unreliable_endpoint = find_or_create_server_endpoint(
- its_unreliable_port, false, is_someip);
+ std::shared_ptr<endpoint> its_unreliable_endpoint =
+ ep_mgr_impl_->find_or_create_server_endpoint(
+ its_unreliable_port, false, is_someip, _service,
+ _instance);
if (its_unreliable_endpoint) {
its_info->set_endpoint(its_unreliable_endpoint, false);
- its_unreliable_endpoint->increment_use_count();
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- service_instances_[_service][its_unreliable_endpoint.get()] =
- _instance;
}
}
@@ -2013,143 +2047,8 @@ void routing_manager_impl::init_service_info(
}
}
} else {
- host_->on_error(error_code_e::CONFIGURATION_MISSING);
- }
-}
-
-std::shared_ptr<endpoint> routing_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;
-
- std::shared_ptr<endpoint> its_endpoint;
- try {
- if (_reliable) {
- its_endpoint = std::make_shared<tcp_client_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::tcp::endpoint(
- (_address.is_v4() ?
- boost::asio::ip::tcp::v4() :
- boost::asio::ip::tcp::v6()),
- _local_port),
- boost::asio::ip::tcp::endpoint(_address, _remote_port),
- io_,
- configuration_->get_max_message_size_reliable(
- _address.to_string(), _remote_port),
- configuration_->get_buffer_shrink_threshold(),
- // send timeout after 2/3 of configured ttl, warning after 1/3
- std::chrono::milliseconds(configuration_->get_sd_ttl() * 666),
- configuration_->get_endpoint_queue_limit(
- _address.to_string(), _remote_port),
- configuration_->get_max_tcp_restart_aborts(),
- configuration_->get_max_tcp_connect_time());
-
- if (configuration_->has_enabled_magic_cookies(_address.to_string(),
- _remote_port)) {
- its_endpoint->enable_magic_cookies();
- }
- } else {
- its_endpoint = std::make_shared<udp_client_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::udp::endpoint(
- (_address.is_v4() ?
- boost::asio::ip::udp::v4() :
- boost::asio::ip::udp::v6()),
- _local_port),
- boost::asio::ip::udp::endpoint(_address, _remote_port),
- io_, configuration_->get_endpoint_queue_limit(
- _address.to_string(), _remote_port),
- configuration_->get_udp_receive_buffer_size());
- }
- } catch (...) {
- host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED);
+ VSOMEIP_ERROR << "Missing vsomeip configuration.";
}
-
- return (its_endpoint);
-}
-
-std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
- uint16_t _port, bool _reliable, bool _start) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint;
- try {
- boost::asio::ip::address its_unicast = configuration_->get_unicast_address();
- if (_start) {
- if (_reliable) {
- its_endpoint = std::make_shared<tcp_server_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::tcp::endpoint(its_unicast, _port), io_,
- configuration_->get_max_message_size_reliable(
- its_unicast.to_string(), _port),
- configuration_->get_buffer_shrink_threshold(),
- // send timeout after 2/3 of configured ttl, warning after 1/3
- std::chrono::milliseconds(configuration_->get_sd_ttl() * 666),
- configuration_->get_endpoint_queue_limit(
- its_unicast.to_string(), _port));
- if (configuration_->has_enabled_magic_cookies(
- its_unicast.to_string(), _port) ||
- configuration_->has_enabled_magic_cookies(
- "local", _port)) {
- its_endpoint->enable_magic_cookies();
- }
- } else {
- configuration::endpoint_queue_limit_t its_limit =
- configuration_->get_endpoint_queue_limit(
- its_unicast.to_string(), _port);
-#ifndef _WIN32
- if (its_unicast.is_v4()) {
- its_unicast = boost::asio::ip::address_v4::any();
- } else if (its_unicast.is_v6()) {
- its_unicast = boost::asio::ip::address_v6::any();
- }
-#endif
- boost::asio::ip::udp::endpoint ep(its_unicast, _port);
- its_endpoint = std::make_shared<udp_server_endpoint_impl>(
- shared_from_this(), ep, io_, its_limit,
- configuration_->get_udp_receive_buffer_size());
- }
-
- } else {
- its_endpoint = std::make_shared<virtual_server_endpoint_impl>(
- its_unicast.to_string(), _port, _reliable);
- }
-
- if (its_endpoint) {
- server_endpoints_[_port][_reliable] = its_endpoint;
- its_endpoint->start();
- }
- } catch (const std::exception &e) {
- host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
- VSOMEIP_ERROR << e.what();
- }
-
- return (its_endpoint);
-}
-
-std::shared_ptr<endpoint> routing_manager_impl::find_server_endpoint(
- uint16_t _port, bool _reliable) const {
- std::shared_ptr<endpoint> its_endpoint;
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- auto found_port = server_endpoints_.find(_port);
- if (found_port != server_endpoints_.end()) {
- auto found_endpoint = found_port->second.find(_reliable);
- if (found_endpoint != found_port->second.end()) {
- its_endpoint = found_endpoint->second;
- }
- }
-
- return (its_endpoint);
-}
-
-std::shared_ptr<endpoint> routing_manager_impl::find_or_create_server_endpoint(
- uint16_t _port, bool _reliable, bool _start) {
- std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port,
- _reliable);
- if (!its_endpoint) {
- its_endpoint = create_server_endpoint(_port, _reliable, _start);
- }
- return (its_endpoint);
}
void routing_manager_impl::remove_local(client_t _client, bool _remove_uid) {
@@ -2167,8 +2066,8 @@ void routing_manager_impl::remove_local(client_t _client, bool _remove_uid) {
std::lock_guard<std::mutex> its_lock(requested_services_mutex_);
auto its_client = requested_services_.find(_client);
if (its_client != requested_services_.end()) {
- for (auto its_service : its_client->second) {
- for (auto its_instance : its_service.second) {
+ for (const auto& its_service : its_client->second) {
+ for (const auto& its_instance : its_service.second) {
services_to_release_.push_front(
{ its_service.first, its_instance.first });
}
@@ -2180,162 +2079,6 @@ void routing_manager_impl::remove_local(client_t _client, bool _remove_uid) {
}
}
-instance_t routing_manager_impl::find_instance(service_t _service,
- endpoint * _endpoint) {
- instance_t its_instance(0xFFFF);
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- auto found_service = service_instances_.find(_service);
- if (found_service != service_instances_.end()) {
- auto found_endpoint = found_service->second.find(_endpoint);
- if (found_endpoint != found_service->second.end()) {
- its_instance = found_endpoint->second;
- }
- }
- }
- return (its_instance);
-}
-
-std::shared_ptr<endpoint> routing_manager_impl::create_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
- std::shared_ptr<endpoint> its_endpoint;
- std::shared_ptr<endpoint_definition> its_endpoint_def;
- uint16_t its_local_port;
- uint16_t its_remote_port = ILLEGAL_PORT;
-
- auto found_service = remote_service_info_.find(_service);
- if (found_service != remote_service_info_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_reliability = found_instance->second.find(_reliable);
- if (found_reliability != found_instance->second.end()) {
- its_endpoint_def = found_reliability->second;
- its_remote_port = its_endpoint_def->get_port();
- }
- }
- }
-
- if( its_remote_port != ILLEGAL_PORT) {
- // if client port range for remote service port range is configured
- // and remote port is in range, determine unused client port
- std::unique_lock<std::mutex> its_lock(used_client_ports_mutex_);
- if (configuration_->get_client_port(_service, _instance, its_remote_port, _reliable,
- used_client_ports_, its_local_port)) {
- if(its_endpoint_def) {
- its_endpoint = create_client_endpoint(
- its_endpoint_def->get_address(),
- its_local_port,
- its_endpoint_def->get_port(),
- _reliable, _client
- );
- }
-
- 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 = find_service(_service, _instance);
- if (found_service_info) {
- found_service_info->set_endpoint(its_endpoint, _reliable);
- }
- }
- }
- }
- }
- return its_endpoint;
-}
-
-
-std::shared_ptr<endpoint> routing_manager_impl::find_remote_client(
- service_t _service, instance_t _instance, bool _reliable, client_t _client) {
- 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;
- }
- }
- }
- }
- if (its_endpoint || _client != VSOMEIP_ROUTING_CLIENT) {
- return its_endpoint;
- }
-
- // If another service is hosted on the same server_endpoint
- // reuse the existing client_endpoint.
- auto found_service_info = remote_service_info_.find(_service);
- if(found_service_info != remote_service_info_.end()) {
- auto found_instance = found_service_info->second.find(_instance);
- if(found_instance != found_service_info->second.end()) {
- auto found_reliable = found_instance->second.find(_reliable);
- if(found_reliable != found_instance->second.end()) {
- std::shared_ptr<endpoint_definition> its_ep_def =
- found_reliable->second;
- auto found_address = client_endpoints_by_ip_.find(
- its_ep_def->get_address());
- if(found_address != client_endpoints_by_ip_.end()) {
- auto found_port = found_address->second.find(
- its_ep_def->get_remote_port());
- if(found_port != found_address->second.end()) {
- auto found_reliable2 = found_port->second.find(
- _reliable);
- if(found_reliable2 != found_port->second.end()) {
- 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] =
- its_endpoint;
- service_instances_[_service][its_endpoint.get()] = _instance;
- // add endpoint to serviceinfo object
- auto found_service_info = find_service(_service,_instance);
- if (found_service_info) {
- found_service_info->set_endpoint(its_endpoint, _reliable);
- }
- }
- }
- }
- }
- }
- }
- return its_endpoint;
-}
-
-client_t routing_manager_impl::find_client(
- service_t _service, instance_t _instance,
- const std::shared_ptr<eventgroupinfo> &_eventgroup,
- const std::shared_ptr<endpoint_definition> &_target) const {
- client_t its_client = VSOMEIP_ROUTING_CLIENT;
- if (!_eventgroup->is_multicast()) {
- if (!_target->is_reliable()) {
- uint16_t unreliable_port = configuration_->get_unreliable_port(_service, _instance);
- auto endpoint = find_server_endpoint(unreliable_port, false);
- if (endpoint) {
- its_client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
- get_client(_target);
- }
- } else {
- uint16_t reliable_port = configuration_->get_reliable_port(_service, _instance);
- auto endpoint = find_server_endpoint(reliable_port, true);
- if (endpoint) {
- its_client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
- get_client(_target);
- }
- }
- }
- return its_client;
-}
-
bool routing_manager_impl::is_field(service_t _service, instance_t _instance,
event_t _event) const {
std::lock_guard<std::mutex> its_lock(events_mutex_);
@@ -2398,60 +2141,12 @@ void routing_manager_impl::add_routing_info(
// Check whether remote services are unchanged
bool is_reliable_known(false);
bool is_unreliable_known(false);
-
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- auto found_service = remote_service_info_.find(_service);
- if (found_service != remote_service_info_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- std::shared_ptr<endpoint_definition> its_definition;
- if (_reliable_port != ILLEGAL_PORT) {
- auto found_reliable = found_instance->second.find(true);
- if (found_reliable != found_instance->second.end()) {
- its_definition = found_reliable->second;
- if (its_definition->get_address() == _reliable_address
- && its_definition->get_port() == _reliable_port) {
- is_reliable_known = true;
- } else {
- VSOMEIP_WARNING << "Reliable service endpoint has changed: ["
- << std::hex << std::setfill('0') << std::setw(4) << _service << "."
- << std::hex << std::setfill('0') << std::setw(4) << _instance << "."
- << std::dec << static_cast<std::uint32_t>(_major) << "."
- << std::dec << _minor << "] old: "
- << its_definition->get_address().to_string() << ":"
- << its_definition->get_port() << " new: "
- << _reliable_address.to_string() << ":"
- << _reliable_port;
- }
- }
- }
- if (_unreliable_port != ILLEGAL_PORT) {
- auto found_unreliable = found_instance->second.find(false);
- if (found_unreliable != found_instance->second.end()) {
- its_definition = found_unreliable->second;
- if (its_definition->get_address() == _unreliable_address
- && its_definition->get_port() == _unreliable_port) {
- is_unreliable_known = true;
- } else {
- VSOMEIP_WARNING << "Unreliable service endpoint has changed: ["
- << std::hex << std::setfill('0') << std::setw(4) << _service << "."
- << std::hex << std::setfill('0') << std::setw(4) << _instance << "."
- << std::dec << static_cast<std::uint32_t>(_major) << "."
- << std::dec << _minor << "] old: "
- << its_definition->get_address().to_string() << ":"
- << its_definition->get_port() << " new: "
- << _unreliable_address.to_string() << ":"
- << _unreliable_port;
- }
- }
- }
- }
- }
- }
+ ep_mgr_impl_->is_remote_service_known(_service, _instance, _major,
+ _minor, _reliable_address, _reliable_port, &is_reliable_known,
+ _unreliable_address, _unreliable_port, &is_unreliable_known);
bool udp_inserted(false);
-
+ bool tcp_inserted(false);
// Add endpoint(s) if necessary
if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) {
std::shared_ptr<endpoint_definition> endpoint_def_tcp
@@ -2459,15 +2154,14 @@ void routing_manager_impl::add_routing_info(
if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) {
std::shared_ptr<endpoint_definition> endpoint_def_udp
= endpoint_definition::get(_unreliable_address, _unreliable_port, false, _service, _instance);
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- remote_service_info_[_service][_instance][false] = endpoint_def_udp;
- remote_service_info_[_service][_instance][true] = endpoint_def_tcp;
- }
+ ep_mgr_impl_->add_remote_service_info(_service, _instance,
+ endpoint_def_tcp, endpoint_def_udp);
udp_inserted = true;
+ tcp_inserted = true;
} else {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- remote_service_info_[_service][_instance][true] = endpoint_def_tcp;
+ ep_mgr_impl_->add_remote_service_info(_service, _instance,
+ endpoint_def_tcp);
+ tcp_inserted = true;
}
// check if service was requested and establish TCP connection if necessary
@@ -2489,11 +2183,13 @@ void routing_manager_impl::add_routing_info(
// SWS_SD_00376 establish TCP connection to service
// service is marked as available later in on_connect()
if(!connected) {
- find_or_create_remote_client(_service, _instance,
- true, VSOMEIP_ROUTING_CLIENT);
if (udp_inserted) {
- find_or_create_remote_client(_service, _instance,
- false, VSOMEIP_ROUTING_CLIENT);
+ // atomically create reliable and unreliable endpoint
+ ep_mgr_impl_->find_or_create_remote_client(
+ _service, _instance, VSOMEIP_ROUTING_CLIENT);
+ } else {
+ ep_mgr_impl_->find_or_create_remote_client(
+ _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
}
connected = true;
}
@@ -2505,10 +2201,6 @@ void routing_manager_impl::add_routing_info(
}
}
}
- auto specific_endpoint_clients = get_specific_endpoint_clients(_service, _instance);
- for (const client_t& c : specific_endpoint_clients) {
- find_or_create_remote_client(_service, _instance, true, c);
- }
} else if (_reliable_port != ILLEGAL_PORT && is_reliable_known) {
std::lock_guard<std::mutex> its_lock(requested_services_mutex_);
for(const auto &client_id : requested_services_) {
@@ -2523,7 +2215,9 @@ void routing_manager_impl::add_routing_info(
&& (major_minor_pair.second <= _minor
|| _minor == DEFAULT_MINOR
|| major_minor_pair.second == ANY_MINOR)) {
- if (!stub_->contained_in_routing_info(
+ std::shared_ptr<endpoint> ep = its_info->get_endpoint(true);
+ if (ep && ep->is_established() &&
+ !stub_->contained_in_routing_info(
VSOMEIP_ROUTING_CLIENT, _service, _instance,
its_info->get_major(),
its_info->get_minor())) {
@@ -2534,12 +2228,8 @@ void routing_manager_impl::add_routing_info(
its_info->get_major(),
its_info->get_minor());
if (discovery_) {
- std::shared_ptr<endpoint> ep = its_info->get_endpoint(true);
- if (ep && ep->is_established()) {
- discovery_->on_endpoint_connected(
- _service, _instance,
- ep);
- }
+ discovery_->on_endpoint_connected(
+ _service, _instance, ep);
}
}
break;
@@ -2554,10 +2244,7 @@ void routing_manager_impl::add_routing_info(
if (!udp_inserted) {
std::shared_ptr<endpoint_definition> endpoint_def
= endpoint_definition::get(_unreliable_address, _unreliable_port, false, _service, _instance);
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- remote_service_info_[_service][_instance][false] = endpoint_def;
- }
+ ep_mgr_impl_->add_remote_service_info(_service, _instance, endpoint_def);
// check if service was requested and increase requester count if necessary
{
bool connected(false);
@@ -2577,7 +2264,7 @@ void routing_manager_impl::add_routing_info(
|| major_minor_pair.second
== ANY_MINOR)) {
if(!connected) {
- find_or_create_remote_client(_service, _instance,
+ ep_mgr_impl_->find_or_create_remote_client(_service, _instance,
false, VSOMEIP_ROUTING_CLIENT);
connected = true;
}
@@ -2590,7 +2277,8 @@ void routing_manager_impl::add_routing_info(
}
}
}
- if (!is_reliable_known) {
+ if (!is_reliable_known && !tcp_inserted) {
+ // UDP only service can be marked as available instantly
on_availability(_service, _instance, true, _major, _minor);
stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor);
}
@@ -2649,26 +2337,81 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst
if(!its_info)
return;
- on_availability(_service, _instance, false, its_info->get_major(), its_info->get_minor());
- stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, its_info->get_major(), its_info->get_minor());
+ on_availability(_service, _instance, false,
+ its_info->get_major(), its_info->get_minor());
+ stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance,
+ its_info->get_major(), its_info->get_minor());
// Implicit unsubscribe
- clear_targets_and_pending_sub_from_eventgroups(_service, _instance);
- clear_identified_clients( _service, _instance);
- clear_identifying_clients( _service, _instance);
+ std::vector<std::shared_ptr<event>> its_events;
+ {
+ std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
+ auto found_service = eventgroups_.find(_service);
+ if (found_service != eventgroups_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto &its_eventgroup : found_instance->second) {
+ // As the service is gone, all subscriptions to its events
+ // do no longer exist and the last received payload is no
+ // longer valid.
+ for (auto &its_event : its_eventgroup.second->get_events()) {
+ const auto its_subscribers = its_event->get_subscribers();
+ for (const auto its_subscriber : its_subscribers) {
+ if (its_subscriber != get_client()) {
+ its_event->remove_subscriber(
+ its_eventgroup.first, its_subscriber);
+ }
+ }
+ its_events.push_back(its_event);
+ remove_pending_subscription(_service, _instance,
+ its_eventgroup.first, its_event->get_event());
+ }
+
+ }
+ }
+ }
+ }
+ for (const auto& e : its_events) {
+ e->unset_payload(true);
+ }
- clear_remote_subscriber(_service, _instance);
+ {
+ std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
+ std::set<std::tuple<
+ service_t, instance_t, eventgroup_t, client_t> > its_invalid;
+
+ for (const auto its_state : remote_subscription_state_) {
+ if (std::get<0>(its_state.first) == _service
+ && std::get<1>(its_state.first) == _instance) {
+ its_invalid.insert(its_state.first);
+ }
+ }
+
+ for (const auto its_key : its_invalid)
+ remote_subscription_state_.erase(its_key);
+ }
+
+ {
+ std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_);
+ auto found_service = remote_subscribers_.find(_service);
+ if (found_service != remote_subscribers_.end()) {
+ if (found_service->second.erase(_instance) > 0 &&
+ !found_service->second.size()) {
+ remote_subscribers_.erase(found_service);
+ }
+ }
+ }
if (_has_reliable) {
- clear_client_endpoints(_service, _instance, true);
- clear_remote_service_info(_service, _instance, true);
+ ep_mgr_impl_->clear_client_endpoints(_service, _instance, true);
+ ep_mgr_impl_->clear_remote_service_info(_service, _instance, true);
}
if (_has_unreliable) {
- clear_client_endpoints(_service, _instance, false);
- clear_remote_service_info(_service, _instance, false);
+ ep_mgr_impl_->clear_client_endpoints(_service, _instance, false);
+ ep_mgr_impl_->clear_remote_service_info(_service, _instance, false);
}
- clear_multicast_endpoints(_service, _instance);
+ ep_mgr_impl_->clear_multicast_endpoints(_service, _instance);
if (_has_reliable)
clear_service_info(_service, _instance, true);
@@ -2677,8 +2420,8 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst
// For expired services using only unreliable endpoints that have never been created before
if (!_has_reliable && !_has_unreliable) {
- clear_remote_service_info(_service, _instance, true);
- clear_remote_service_info(_service, _instance, false);
+ ep_mgr_impl_->clear_remote_service_info(_service, _instance, true);
+ ep_mgr_impl_->clear_remote_service_info(_service, _instance, false);
clear_service_info(_service, _instance, true);
clear_service_info(_service, _instance, false);
}
@@ -2764,83 +2507,57 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr
}
}
-void routing_manager_impl::expire_subscriptions(const boost::asio::ip::address &_address) {
- struct subscriptions_info {
- service_t service_id_;
- instance_t instance_id_;
- eventgroup_t eventgroup_id_;
- std::shared_ptr<endpoint_definition> invalid_endpoint_;
- client_t client_;
- std::set<std::shared_ptr<event>> events_;
- std::shared_ptr<eventgroupinfo> eventgroupinfo_;
- };
- std::vector<struct subscriptions_info> subscriptions_to_expire_;
+void
+routing_manager_impl::expire_subscriptions(
+ const boost::asio::ip::address &_address) {
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
- for (auto &its_service : eventgroups_) {
- for (auto &its_instance : its_service.second) {
- for (auto &its_eventgroup : its_instance.second) {
- std::set<std::shared_ptr<endpoint_definition>> its_invalid_endpoints;
- for (auto &its_target : its_eventgroup.second->get_targets()) {
- if (its_target.endpoint_->get_address() == _address)
- its_invalid_endpoints.insert(its_target.endpoint_);
- }
+ 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) {
+ 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();
+ }
- for (auto &its_endpoint : its_invalid_endpoints) {
- its_eventgroup.second->remove_target(its_endpoint);
- client_t its_client = find_client(its_service.first,
- its_instance.first, its_eventgroup.second,
- its_endpoint);
- clear_remote_subscriber(its_service.first,
- its_instance.first, its_client, its_endpoint);
-
- std::set<std::shared_ptr<event> > its_events;
- if (its_eventgroup.second->get_targets().size() == 0) {
- its_events = its_eventgroup.second->get_events();
+ on_remote_unsubscribe(its_subscription);
}
- subscriptions_to_expire_.push_back({its_service.first,
- its_instance.first,
- its_eventgroup.first,
- its_endpoint,
- its_client,
- its_events,
- its_eventgroup.second});
- }
- if(its_eventgroup.second->is_multicast() && its_invalid_endpoints.size() &&
- 0 == its_eventgroup.second->get_unreliable_target_count() ) {
- //clear multicast targets if no subscriber is left for multicast eventgroup
- its_eventgroup.second->clear_multicast_targets();
}
}
}
}
}
-
- for (const auto &s : subscriptions_to_expire_) {
- if (s.invalid_endpoint_) {
- for (const auto e: s.events_) {
- if (e->is_shadow()) {
- e->unset_payload();
- }
- }
- const client_t its_hosting_client = find_local_client(
- s.service_id_, s.instance_id_);
- if (its_hosting_client != VSOMEIP_ROUTING_CLIENT) {
- const pending_subscription_t its_pending_unsubscription(
- std::shared_ptr<sd_message_identifier_t>(),
- s.invalid_endpoint_, s.invalid_endpoint_,
- 0, s.client_);
- pending_subscription_id_t its_pending_unsubscription_id =
- s.eventgroupinfo_->add_pending_subscription(
- its_pending_unsubscription);
- if (its_pending_unsubscription_id != DEFAULT_SUBSCRIPTION) {
- send_unsubscription(its_hosting_client, s.client_,
- s.service_id_, s.instance_id_, s.eventgroup_id_,
- its_pending_unsubscription_id);
- }
- }
- }
- }
}
void routing_manager_impl::init_routing_info() {
@@ -2863,200 +2580,194 @@ void routing_manager_impl::init_routing_info() {
its_address, its_unreliable_port);
if(its_reliable_port != ILLEGAL_PORT) {
- find_or_create_remote_client(i.first, i.second, true, VSOMEIP_ROUTING_CLIENT);
+ ep_mgr_impl_->find_or_create_remote_client(
+ i.first, i.second, true, VSOMEIP_ROUTING_CLIENT);
}
if(its_unreliable_port != ILLEGAL_PORT) {
- find_or_create_remote_client(i.first, i.second, false, VSOMEIP_ROUTING_CLIENT);
+ ep_mgr_impl_->find_or_create_remote_client(
+ i.first, i.second, false, VSOMEIP_ROUTING_CLIENT);
}
}
}
}
-void routing_manager_impl::on_remote_subscription(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- const std::shared_ptr<endpoint_definition> &_subscriber,
- const std::shared_ptr<endpoint_definition> &_target, ttl_t _ttl,
- const std::shared_ptr<sd_message_identifier_t> &_sd_message_id,
- const std::function<void(remote_subscription_state_e, client_t)>& _callback) {
- std::shared_ptr<eventgroupinfo> its_eventgroup
- = find_eventgroup(_service, _instance, _eventgroup);
- client_t its_subscribing_client(ILLEGAL_CLIENT);
- if (!its_eventgroup) {
- VSOMEIP_ERROR << "REMOTE SUBSCRIBE: attempt to subscribe to unknown eventgroup ["
- << 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 << "]"
- << " from " << _subscriber->get_address().to_string()
- << ":" << std::dec << _subscriber->get_port()
- << (_subscriber->is_reliable() ? " reliable" : " unreliable");
- _callback(remote_subscription_state_e::SUBSCRIPTION_ERROR, its_subscribing_client);
+void routing_manager_impl::on_remote_subscribe(
+ std::shared_ptr<remote_subscription> &_subscription,
+ const remote_subscription_callback_t &_callback) {
+ auto its_eventgroupinfo = _subscription->get_eventgroupinfo();
+ if (!its_eventgroupinfo) {
+ VSOMEIP_ERROR << __func__ << " eventgroupinfo is invalid";
return;
}
- // find out client id for selective subscriber
- if (!_subscriber->is_reliable()) {
- uint16_t unreliable_port = configuration_->get_unreliable_port(_service, _instance);
- _subscriber->set_remote_port(unreliable_port);
- if (!its_eventgroup->is_multicast()) {
- auto endpoint = find_server_endpoint(unreliable_port, false);
- if (endpoint) {
- its_subscribing_client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
- get_client(_subscriber);
- }
- }
- } else {
- uint16_t reliable_port = configuration_->get_reliable_port(_service, _instance);
- _subscriber->set_remote_port(reliable_port);
- auto endpoint = find_server_endpoint(reliable_port, true);
- if (endpoint) {
- its_subscribing_client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
- get_client(_subscriber);
- }
- }
- std::unique_lock<std::mutex> eventgroup_lock(its_eventgroup->get_subscription_lock());
- const std::chrono::steady_clock::time_point its_expiration =
- std::chrono::steady_clock::now() + std::chrono::seconds(_ttl);
- if (its_eventgroup->update_target(_subscriber, its_expiration)) {
- _callback(remote_subscription_state_e::SUBSCRIPTION_ACKED,its_subscribing_client);
- return;
- } else {
- const pending_subscription_id_t its_subscription_id =
- its_eventgroup->add_pending_subscription(
- pending_subscription_t(_sd_message_id, _subscriber,
- _target, _ttl, its_subscribing_client));
- if (its_subscription_id != DEFAULT_SUBSCRIPTION) {
- // only sent subscription to rm_proxy / hosting application if there's
- // no subscription for this eventgroup from the same remote subscriber
- // already pending
- const client_t its_offering_client = find_local_client(_service, _instance);
- send_subscription(its_offering_client, its_subscribing_client,
- _service, _instance, _eventgroup,
- its_eventgroup->get_major(), its_subscription_id);
- } else {
- VSOMEIP_WARNING << __func__ << " a remote subscription is already pending ["
- << 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 << "]"
- << " from " << _subscriber->get_address().to_string()
- << ":" << std::dec << _subscriber->get_port()
- << (_subscriber->is_reliable() ? " reliable" : " unreliable");
- }
- _callback(remote_subscription_state_e::SUBSCRIPTION_PENDING, its_subscribing_client);
+ const ttl_t its_ttl = _subscription->get_ttl();
+
+ const auto its_service = its_eventgroupinfo->get_service();
+ const auto its_instance = its_eventgroupinfo->get_instance();
+ const auto its_eventgroup = its_eventgroupinfo->get_eventgroup();
+ const auto its_major = its_eventgroupinfo->get_major();
+
+ // Get remote port(s)
+ auto its_reliable = _subscription->get_reliable();
+ if (its_reliable) {
+ uint16_t its_port
+ = configuration_->get_reliable_port(its_service, its_instance);
+ its_reliable->set_remote_port(its_port);
+ }
+
+ auto its_unreliable = _subscription->get_unreliable();
+ if (its_unreliable) {
+ uint16_t its_port
+ = configuration_->get_unreliable_port(its_service, its_instance);
+ its_unreliable->set_remote_port(its_port);
+ }
+
+ // Calculate expiration time
+ const std::chrono::steady_clock::time_point its_expiration
+ = std::chrono::steady_clock::now() + std::chrono::seconds(its_ttl);
+
+ // Try to update the subscription. This will fail, if the subscription does
+ // not exist or is still (partly) pending.
+ remote_subscription_id_t its_id;
+ std::set<client_t> its_added;
+ auto its_result = its_eventgroupinfo->update_remote_subscription(
+ _subscription, its_expiration, its_added, its_id, true);
+ if (its_result) {
+ if (!_subscription->is_pending()) { // resubscription without change
+ _callback(_subscription);
+ } else if (!its_added.empty()) { // new clients for a selective subscription
+ const client_t its_offering_client
+ = find_local_client(its_service, its_instance);
+ send_subscription(its_offering_client,
+ its_service, its_instance, its_eventgroup, its_major,
+ its_added, _subscription->get_id());
+ } else { // identical subscription is not yet processed
+ std::stringstream its_warning;
+ its_warning << __func__ << " a remote subscription is already pending ["
+ << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
+ << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]"
+ << " from ";
+ if (its_reliable && its_unreliable)
+ its_warning << "[";
+ if (its_reliable)
+ its_warning << its_reliable->get_address().to_string()
+ << ":" << std::dec << its_reliable->get_port();
+ if (its_reliable && its_unreliable)
+ its_warning << ", ";
+ if (its_unreliable)
+ its_warning << its_unreliable->get_address().to_string()
+ << ":" << std::dec << its_unreliable->get_port();
+ if (its_reliable && its_unreliable)
+ its_warning << "]";
+ VSOMEIP_WARNING << its_warning.str();
+ }
+ } else { // new subscription
+ auto its_id
+ = its_eventgroupinfo->add_remote_subscription(_subscription);
+
+ const client_t its_offering_client
+ = find_local_client(its_service, its_instance);
+ send_subscription(its_offering_client,
+ its_service, its_instance, its_eventgroup, its_major,
+ _subscription->get_clients(), its_id);
+ }
+}
+
+void routing_manager_impl::on_remote_unsubscribe(
+ std::shared_ptr<remote_subscription> &_subscription) {
+ std::shared_ptr<eventgroupinfo> its_info
+ = _subscription->get_eventgroupinfo();
+ if (!its_info) {
+ VSOMEIP_ERROR << __func__
+ << ": Received Unsubscribe for unregistered eventgroup.";
return;
}
- _callback(remote_subscription_state_e::SUBSCRIPTION_ERROR, its_subscribing_client);
-}
-void routing_manager_impl::on_unsubscribe(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _target) {
- std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
- _instance, _eventgroup);
- if (its_eventgroup) {
- client_t its_client = find_client(_service, _instance, its_eventgroup, _target);
- const pending_subscription_t its_pending_unsubscription(
- std::shared_ptr<sd_message_identifier_t>(), _target, _target,
- 0, its_client);
- pending_subscription_id_t its_pending_unsubscription_id =
- its_eventgroup->add_pending_subscription(
- its_pending_unsubscription);
-
- its_eventgroup->remove_target(_target);
- clear_remote_subscriber(_service, _instance, its_client, _target);
-
- if (its_pending_unsubscription_id != DEFAULT_SUBSCRIPTION) {
- // there are no pending (un)subscriptions
- const client_t its_offering_client = find_local_client(_service, _instance);
- send_unsubscription(its_offering_client, its_client, _service,
- _instance, _eventgroup, its_pending_unsubscription_id);
- }
+ const auto its_service = its_info->get_service();
+ const auto its_instance = its_info->get_instance();
+ const auto its_eventgroup = its_info->get_eventgroup();
+ const auto its_major = its_info->get_major();
- if (its_eventgroup->get_targets().size() == 0) {
- std::set<std::shared_ptr<event> > its_events
- = its_eventgroup->get_events();
- for (auto e : its_events) {
- if (e->is_shadow()) {
- e->unset_payload();
- }
- }
- }
- VSOMEIP_INFO << "REMOTE UNSUBSCRIBE("
- << std::hex << std::setw(4) << std::setfill('0') << its_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') << _eventgroup << "]"
- << " from " << _target->get_address().to_string()
- << ":" << std::dec <<_target->get_port()
- << (_target->is_reliable() ? " reliable" : " unreliable");
+ auto its_subscriber = _subscription->get_subscriber();
- } else {
- VSOMEIP_ERROR << "REMOTE UNSUBSCRIBE: attempt to subscribe to unknown eventgroup ["
- << 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 << "]"
- << " from " << _target->get_address().to_string()
- << ":" << std::dec <<_target->get_port()
- << (_target->is_reliable() ? " reliable" : " unreliable");
+ // Get remote port(s)
+ auto its_reliable = _subscription->get_reliable();
+ if (its_reliable) {
+ uint16_t its_port
+ = configuration_->get_reliable_port(its_service, its_instance);
+ its_reliable->set_remote_port(its_port);
}
-}
-
-void routing_manager_impl::on_subscribe_ack(service_t _service,
- instance_t _instance, const boost::asio::ip::address &_address,
- uint16_t _port) {
- bool multicast_known(false);
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- const auto found_service = multicast_info.find(_service);
- if (found_service != multicast_info.end()) {
- const auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- const auto& endpoint_def = found_instance->second;
- if (endpoint_def->get_address() == _address &&
- endpoint_def->get_port() == _port) {
- // Multicast info and endpoint already created before
- // This can happen when more than one client subscribe on the same instance!
- multicast_known = true;
- }
- }
- }
- if (!multicast_known) {
- // Save multicast info to be able to delete the endpoint
- // as soon as the instance stops offering its service
- std::shared_ptr<endpoint_definition> endpoint_def =
- endpoint_definition::get(_address, _port, false, _service, _instance);
- multicast_info[_service][_instance] = endpoint_def;
- }
+ auto its_unreliable = _subscription->get_unreliable();
+ if (its_unreliable) {
+ uint16_t its_port
+ = configuration_->get_unreliable_port(its_service, its_instance);
+ its_unreliable->set_remote_port(its_port);
}
- const bool is_someip = configuration_->is_someip(_service, _instance);
- // Create multicast endpoint & join multicase group
- std::shared_ptr<endpoint> its_endpoint
- = find_or_create_server_endpoint(_port, false, is_someip);
- if (its_endpoint) {
- if (!multicast_known) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- service_instances_[_service][its_endpoint.get()] = _instance;
- }
- its_endpoint->join(_address.to_string());
- } else {
- VSOMEIP_ERROR<<"Could not find/create multicast endpoint!";
+ remote_subscription_id_t its_id(0);
+ std::set<client_t> its_removed;
+ auto its_result = its_info->update_remote_subscription(
+ _subscription, std::chrono::steady_clock::now(),
+ its_removed, its_id, false);
+
+ if (its_result) {
+ const client_t its_offering_client
+ = find_local_client(its_service, its_instance);
+ send_unsubscription(its_offering_client,
+ its_service, its_instance, its_eventgroup, its_major,
+ its_removed, its_id);
}
}
+void routing_manager_impl::on_subscribe_ack_with_multicast(
+ service_t _service, instance_t _instance,
+ const boost::asio::ip::address &_address, uint16_t _port) {
+ ep_mgr_impl_->find_or_create_multicast_endpoint(_service,
+ _instance, _address, _port);
+}
+
void routing_manager_impl::on_subscribe_ack(client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, pending_subscription_id_t _subscription_id) {
- client_t its_client = is_specific_endpoint_client(_client, _service, _instance);
- bool specific_endpoint_client = its_client != VSOMEIP_ROUTING_CLIENT;
+ event_t _event, remote_subscription_id_t _id) {
+ std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- std::unique_lock<std::mutex> eventgroup_lock(its_eventgroup->get_subscription_lock());
- if (_subscription_id == DEFAULT_SUBSCRIPTION) {
- // ACK coming in via SD from remote or as answer to a subscription
- // of the application hosting the rm_impl to a local service
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, its_client);
- std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
- auto its_state = remote_subscription_state_.find(its_tuple);
+ auto its_subscription = its_eventgroup->get_remote_subscription(_id);
+ if (its_subscription) {
+ its_subscription->set_client_state(_client,
+ remote_subscription_state_e::SUBSCRIPTION_ACKED);
+
+ auto its_parent = its_subscription->get_parent();
+ if (its_parent) {
+ its_parent->set_client_state(_client,
+ remote_subscription_state_e::SUBSCRIPTION_ACKED);
+ if (!its_subscription->is_pending()) {
+ its_eventgroup->remove_remote_subscription(_id);
+ }
+ }
+
+ if (discovery_) {
+ std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_);
+ remote_subscribers_[_service][_instance][VSOMEIP_ROUTING_CLIENT].insert(
+ its_subscription->get_subscriber());
+ discovery_->update_remote_subscription(its_subscription);
+
+ VSOMEIP_INFO << "REMOTE SUBSCRIBE("
+ << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]"
+ << " from " << its_subscription->get_subscriber()->get_address()
+ << ":" << std::dec << its_subscription->get_subscriber()->get_port()
+ << (its_subscription->get_subscriber()->is_reliable() ? " reliable" : " unreliable")
+ << " was accepted";
+
+ return;
+ }
+ } else {
+ const auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _client);
+ const auto its_state = remote_subscription_state_.find(its_tuple);
if (its_state != remote_subscription_state_.end()) {
if (its_state->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {
// Already notified!
@@ -3064,385 +2775,79 @@ void routing_manager_impl::on_subscribe_ack(client_t _client,
}
}
remote_subscription_state_[its_tuple] = subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED;
- } else { // ACK sent back from local client as answer to a remote subscription
- const client_t its_offering_client = find_local_client(_service, _instance);
- if (its_offering_client == VSOMEIP_ROUTING_CLIENT) {
- // service was stopped while subscription was pending
- // send subscribe_nack back instead
- eventgroup_lock.unlock();
- on_subscribe_nack(_client, _service, _instance, _eventgroup,
- _event, _subscription_id);
- return;
- }
- if (discovery_) {
- std::vector<pending_subscription_t> its_pending_subscriptions =
- its_eventgroup->remove_pending_subscription(_subscription_id);
- for (const pending_subscription_t& its_sd_message_id : its_pending_subscriptions) {
- if (its_sd_message_id.ttl_ > 0) {
- if (its_sd_message_id.sd_message_identifier_
- && its_sd_message_id.subscriber_
- && its_sd_message_id.target_) {
- {
- std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_);
- remote_subscribers_[_service][_instance][_client].insert(its_sd_message_id.subscriber_);
- }
- const std::chrono::steady_clock::time_point its_expiration =
- std::chrono::steady_clock::now()
- + std::chrono::seconds(
- its_sd_message_id.ttl_);
- // IP address of target is a multicast address if the event is in a multicast eventgroup
- if (its_eventgroup->is_multicast()
- && !its_sd_message_id.subscriber_->is_reliable()) {
- // Event is in multicast eventgroup and subscribe for UDP
- its_eventgroup->add_target(
- { its_sd_message_id.target_, its_expiration },
- { its_sd_message_id.subscriber_, its_expiration });
- } else {
- // subscribe for TCP or UDP
- its_eventgroup->add_target(
- { its_sd_message_id.subscriber_, its_expiration });
- }
- discovery_->remote_subscription_acknowledge(_service,
- _instance, _eventgroup, _client, true,
- its_sd_message_id.sd_message_identifier_);
+ }
- VSOMEIP_INFO << "REMOTE SUBSCRIBE("
- << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]"
- << " from " << its_sd_message_id.subscriber_->get_address().to_string()
- << ":" << std::dec << its_sd_message_id.subscriber_->get_port()
- << (its_sd_message_id.subscriber_->is_reliable() ? " reliable" : " unreliable")
- << " was accepted";
- }
- } else { // unsubscription was queued while subscription was pending -> send it to client
- send_unsubscription(its_offering_client,
- its_sd_message_id.subscribing_client_,
- _service, _instance, _eventgroup,
- its_sd_message_id.pending_subscription_id_);
- }
+ std::set<client_t> subscribed_clients;
+ if (_client == VSOMEIP_ROUTING_CLIENT) {
+ for (const auto &its_event : its_eventgroup->get_events()) {
+ if (_event == ANY_EVENT || _event == its_event->get_event()) {
+ const auto &its_subscribers = its_event->get_subscribers();
+ subscribed_clients.insert(its_subscribers.begin(), its_subscribers.end());
}
}
- return;
+ } else {
+ subscribed_clients.insert(_client);
}
- if (specific_endpoint_client) {
- if (_client == get_client()) {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x0 /*OK*/);
+ for (const auto &its_subscriber : subscribed_clients) {
+ if (its_subscriber == get_client()) {
if (_event == ANY_EVENT) {
- for (const auto &its_event : its_eventgroup->get_events())
- host_->on_subscription_status(_service, _instance,
- _eventgroup, its_event->get_event(), 0x0 /*OK*/);
- } else {
- host_->on_subscription_status(_service, _instance,
- _eventgroup, _event, 0x0 /*OK*/);
- }
- } else {
- stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup,
- _event);
- }
- } else {
- std::set<client_t> subscribed_clients;
- for (auto its_event : its_eventgroup->get_events()) {
- for (auto its_client : its_event->get_subscribers()) {
- subscribed_clients.insert(its_client);
- }
- }
- for (auto its_subscriber : subscribed_clients) {
- if (its_subscriber == get_client()) {
- host_->on_subscription_error(_service, _instance,
- _eventgroup, 0x0 /*OK*/);
- for (auto its_event : its_eventgroup->get_events()) {
+ for (const auto &its_event : its_eventgroup->get_events()) {
host_->on_subscription_status(_service, _instance,
_eventgroup, its_event->get_event(),
0x0 /*OK*/);
}
} else {
- stub_->send_subscribe_ack(its_subscriber, _service,
- _instance, _eventgroup, _event);
- }
- }
- }
- }
-}
-
-void routing_manager_impl::on_subscribe_nack(client_t _client,
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, pending_subscription_id_t _subscription_id) {
- client_t its_client = is_specific_endpoint_client(_client, _service, _instance);
- bool specific_endpoint_client = its_client != VSOMEIP_ROUTING_CLIENT;
- auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
- if (its_eventgroup) {
- std::unique_lock<std::mutex> eventgroup_lock(its_eventgroup->get_subscription_lock());
- if (_subscription_id == DEFAULT_SUBSCRIPTION) {
- // NACK coming in via SD from remote or as answer to a subscription
- // of the application hosting the rm_impl to a local service
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, its_client);
- std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
- auto its_state = remote_subscription_state_.find(its_tuple);
- if (its_state != remote_subscription_state_.end()) {
- if (its_state->second == subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) {
- // Already notified!
- return;
- }
- }
- remote_subscription_state_[its_tuple] = subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED;
- } else { // NACK sent back from local client as answer to a remote subscription
- if (discovery_) {
- std::vector<pending_subscription_t> its_pending_subscriptions =
- its_eventgroup->remove_pending_subscription(_subscription_id);
- for (const pending_subscription_t& its_sd_message_id : its_pending_subscriptions) {
- if (its_sd_message_id.ttl_ > 0) {
- if (its_sd_message_id.sd_message_identifier_ && its_sd_message_id.subscriber_) {
- discovery_->remote_subscription_acknowledge(_service, _instance,
- _eventgroup, _client, false, its_sd_message_id.sd_message_identifier_);
- VSOMEIP_INFO << "REMOTE SUBSCRIBE("
- << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]"
- << " from " << its_sd_message_id.subscriber_->get_address().to_string()
- << ":" << std::dec <<its_sd_message_id.subscriber_->get_port()
- << (its_sd_message_id.subscriber_->is_reliable() ? " reliable" : " unreliable")
- << " was not accepted";
- }
- } else { // unsubscription was queued while subscription was pending -> send it to client
- const client_t its_offering_client = find_local_client(_service, _instance);
- send_unsubscription(its_offering_client,
- its_sd_message_id.subscribing_client_, _service,
- _instance, _eventgroup,
- its_sd_message_id.pending_subscription_id_);
- }
+ host_->on_subscription_status(_service, _instance,
+ _eventgroup, _event, 0x0 /*OK*/);
}
- }
- return;
- }
- if (specific_endpoint_client) {
- if (_client == get_client()) {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x7 /*Rejected*/);
- host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/);
} else {
- stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup,
- _event);
- }
- } else {
- std::set<client_t> subscribed_clients;
- for (auto its_event : its_eventgroup->get_events()) {
- for (auto its_client : its_event->get_subscribers()) {
- subscribed_clients.insert(its_client);
- }
- }
- for (auto its_subscriber : subscribed_clients) {
- if (its_subscriber == get_client()) {
- host_->on_subscription_error(_service, _instance,
- _eventgroup, 0x7 /*Rejected*/);
- for (auto its_event : its_eventgroup->get_events()) {
- host_->on_subscription_status(_service, _instance,
- _eventgroup, its_event->get_event(),
- 0x7 /*Rejected*/);
- }
- } else {
- stub_->send_subscribe_nack(its_subscriber, _service,
- _instance, _eventgroup, _event);
- }
+ stub_->send_subscribe_ack(its_subscriber, _service,
+ _instance, _eventgroup, _event);
}
}
- }
+ }
}
-bool routing_manager_impl::deliver_specific_endpoint_message(service_t _service,
- instance_t _instance, const byte_t *_data, length_t _size, endpoint *_receiver) {
- client_t its_client(0x0);
-
- // Try to deliver specific endpoint message (for selective subscribers)
- {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- auto found_servic = remote_services_.find(_service);
- if (found_servic != remote_services_.end()) {
- auto found_instance = found_servic->second.find(_instance);
- if (found_instance != found_servic->second.end()) {
- for (auto client_entry : found_instance->second) {
- if (!client_entry.first) {
- continue;
- }
- auto found_reliability = client_entry.second.find(_receiver->is_reliable());
- if (found_reliability != client_entry.second.end()) {
- auto found_enpoint = found_reliability->second;
- if (found_enpoint.get() == _receiver) {
- its_client = client_entry.first;
- break;
- }
- }
- }
- }
- }
- }
- if (its_client) {
- if (its_client != get_client()) {
- auto local_endpoint = find_local(its_client);
- if (local_endpoint) {
- send_local(local_endpoint, its_client, _data, _size, _instance, true,
- _receiver->is_reliable(), VSOMEIP_SEND);
- }
- } else {
- deliver_message(_data, _size, _instance, _receiver->is_reliable(), VSOMEIP_ROUTING_CLIENT, true, true);
- }
- return true;
- }
-
- return false;
+std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
+ service_t _service, instance_t _instance, bool _reliable,
+ client_t _client) {
+ return ep_mgr_impl_->find_or_create_remote_client(_service,
+ _instance, _reliable, _client);
}
-void routing_manager_impl::clear_client_endpoints(service_t _service, instance_t _instance,
- bool _reliable) {
- auto its_specific_endpoint_clients = get_specific_endpoint_clients(_service, _instance);
- 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);
- }
- // erase specific client endpoints
- for (const client_t &client : its_specific_endpoint_clients) {
- auto endpoint = remote_services_[_service][_instance][client][_reliable];
- if (endpoint) {
- service_instances_[_service].erase(endpoint.get());
- its_specific_endpoints.push_back(endpoint);
- }
- remote_services_[_service][_instance][client].erase(_reliable);
- auto found_endpoint = remote_services_[_service][_instance][client].find(!_reliable);
- if (found_endpoint == remote_services_[_service][_instance][client].end()) {
- remote_services_[_service][_instance].erase(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);
- }
- }
- }
- }
-
- 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;
- }
- }
- }
- if (other_services_reachable_through_endpoint) { break; }
- }
- if (other_services_reachable_through_endpoint) { break; }
- }
+void routing_manager_impl::on_subscribe_nack(client_t _client,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ event_t _event, remote_subscription_id_t _id) {
+ (void)_event; // TODO: Remove completely?
- if (!other_services_reachable_through_endpoint) {
- std::uint16_t its_port(0);
- boost::asio::ip::address its_address;
- if (_reliable) {
- std::shared_ptr<tcp_client_endpoint_impl> ep =
- std::dynamic_pointer_cast<tcp_client_endpoint_impl>(endpoint_to_delete);
- if (ep) {
- its_port = ep->get_remote_port();
- ep->get_remote_address(its_address);
- }
- } else {
- std::shared_ptr<udp_client_endpoint_impl> ep =
- std::dynamic_pointer_cast<udp_client_endpoint_impl>(endpoint_to_delete);
- if (ep) {
- its_port = ep->get_remote_port();
- ep->get_remote_address(its_address);
- }
- }
- const auto found_ip = client_endpoints_by_ip_.find(its_address);
- if (found_ip != client_endpoints_by_ip_.end()) {
- const auto found_port = found_ip->second.find(its_port);
- if (found_port != found_ip->second.end()) {
- const auto found_reliable = found_port->second.find(_reliable);
- if (found_reliable != found_port->second.end()) {
- if (found_reliable->second == endpoint_to_delete) {
- found_port->second.erase(_reliable);
- // delete if necessary
- if (!found_port->second.size()) {
- found_ip->second.erase(found_port);
- if (!found_ip->second.size()) {
- client_endpoints_by_ip_.erase(found_ip);
- }
- }
- }
- }
- }
+ auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_eventgroup) {
+ auto its_subscription = its_eventgroup->get_remote_subscription(_id);
+ if (its_subscription) {
+ its_subscription->set_client_state(_client,
+ remote_subscription_state_e::SUBSCRIPTION_NACKED);
+
+ auto its_parent = its_subscription->get_parent();
+ if (its_parent) {
+ its_parent->set_client_state(_client,
+ remote_subscription_state_e::SUBSCRIPTION_NACKED);
+ if (!its_subscription->is_pending()) {
+ its_eventgroup->remove_remote_subscription(_id);
}
}
- }
- }
- 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 routing_manager_impl::clear_multicast_endpoints(service_t _service, instance_t _instance) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- // Clear multicast info and endpoint and multicast instance (remote service)
- if (multicast_info.find(_service) != multicast_info.end()) {
- if (multicast_info[_service].find(_instance) != multicast_info[_service].end()) {
- std::string address = multicast_info[_service][_instance]->get_address().to_string();
- uint16_t port = multicast_info[_service][_instance]->get_port();
- std::shared_ptr<endpoint> multicast_endpoint;
- auto found_port = server_endpoints_.find(port);
- if (found_port != server_endpoints_.end()) {
- auto found_unreliable = found_port->second.find(false);
- if (found_unreliable != found_port->second.end()) {
- multicast_endpoint = found_unreliable->second;
- multicast_endpoint->leave(address);
- multicast_endpoint->stop();
- server_endpoints_[port].erase(false);
- }
- if (found_port->second.find(true) == found_port->second.end()) {
- server_endpoints_.erase(port);
- }
- }
- multicast_info[_service].erase(_instance);
- if (0 >= multicast_info[_service].size()) {
- multicast_info.erase(_service);
- }
- // Clear service_instances_ for multicase endpoint
- if (1 >= service_instances_[_service].size()) {
- service_instances_.erase(_service);
- } else if (multicast_endpoint) {
- service_instances_[_service].erase(multicast_endpoint.get());
+ if (discovery_) {
+ discovery_->update_remote_subscription(its_subscription);
+ VSOMEIP_INFO << "REMOTE SUBSCRIBE("
+ << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]"
+ << " from " << its_subscription->get_subscriber()->get_address()
+ << ":" << std::dec << its_subscription->get_subscriber()->get_port()
+ << (its_subscription->get_subscriber()->is_reliable() ? " reliable" : " unreliable")
+ << " was not accepted";
}
}
}
@@ -3495,7 +2900,7 @@ return_code_e routing_manager_impl::check_error(const byte_t *_data, length_t _s
void routing_manager_impl::send_error(return_code_e _return_code,
const byte_t *_data, length_t _size,
instance_t _instance, bool _reliable,
- endpoint *_receiver,
+ endpoint* const _receiver,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port) {
@@ -3535,150 +2940,39 @@ void routing_manager_impl::send_error(return_code_e _return_code,
error_message->set_service(its_service);
error_message->set_session(its_session);
{
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(error_message.get())) {
+ std::shared_ptr<serializer> its_serializer(get_serializer());
+ if (its_serializer->serialize(error_message.get())) {
if (_receiver) {
auto its_endpoint_def = std::make_shared<endpoint_definition>(
_remote_address, _remote_port,
_receiver->is_reliable());
its_endpoint_def->set_remote_port(_receiver->get_local_port());
- send_to(its_endpoint_def, serializer_->get_data(),
- serializer_->get_size(), _instance, true);
- }
- serializer_->reset();
- } else {
- VSOMEIP_ERROR<< "Failed to serialize error message.";
- }
- }
-}
-
-void routing_manager_impl::on_identify_response(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) {
- {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identifying_clients_.find(_service);
- if (its_service != identifying_clients_.end()) {
- auto its_instance = its_service->second.find(_instance);
- if (its_instance != its_service->second.end()) {
- auto its_reliable = its_instance->second.find(_reliable);
- if (its_reliable != its_instance->second.end()) {
- its_reliable->second.erase(_client);
- }
- }
- }
- identified_clients_[_service][_instance][_reliable].insert(_client);
- }
- discovery_->send_subscriptions(_service, _instance, _client, _reliable);
-}
-
-void routing_manager_impl::identify_for_subscribe(client_t _client,
- service_t _service, instance_t _instance, major_version_t _major,
- subscription_type_e _subscription_type) {
- (void)_subscription_type;
- if (!has_identified(_client, _service, _instance, false)
- && !is_identifying(_client, _service, _instance, false)) {
- send_identify_message(_client, _service, _instance, _major, false);
- }
- if (!has_identified(_client, _service, _instance, true)
- && !is_identifying(_client, _service, _instance, true)) {
- send_identify_message(_client, _service, _instance, _major, true);
- }
-}
-
-bool routing_manager_impl::send_identify_message(client_t _client,
- service_t _service,
- instance_t _instance,
- major_version_t _major,
- bool _reliable) {
- auto its_endpoint = find_or_create_remote_client(_service, _instance,
- _reliable, _client);
- if (!its_endpoint) {
- VSOMEIP_WARNING << "routing_manager_impl::send_identify_message: "
- << "No " << (_reliable ? "reliable" : "unreliable")
- << " route for identify message to service/instance "
- << std::hex << _service << "/" << _instance << " for client "
- << _client;
- return false;
- }
- {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- identifying_clients_[_service][_instance][_reliable].insert(_client);
- }
-
- if (_client == get_client()) {
- send_identify_request(_service, _instance, _major, _reliable);
- } else {
- stub_->send_identify_request_command(find_local(_client),
- _service, _instance, _major, _reliable);
- }
-
- return true;
-}
-
-
-bool routing_manager_impl::supports_selective(service_t _service, instance_t _instance) {
- bool supports_selective(false);
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- auto its_service = remote_service_info_.find(_service);
- if (its_service != remote_service_info_.end()) {
- auto its_instance = its_service->second.find(_instance);
- if (its_instance != its_service->second.end()) {
- for (auto its_reliable : its_instance->second) {
- supports_selective |= configuration_->
- supports_selective_broadcasts(
- its_reliable.second->get_address());
- }
- }
- }
- return supports_selective;
-}
-
-bool routing_manager_impl::is_identifying(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) {
- if (!supports_selective(_service, _instance)) {
- // For legacy selective services clients can't be identified!
- return false;
- }
- bool is_identifieing(false);
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identifying_clients_.find(_service);
- if (its_service != identifying_clients_.end()) {
- auto its_instance = its_service->second.find(_instance);
- if (its_instance != its_service->second.end()) {
- auto its_reliable = its_instance->second.find(_reliable);
- if (its_reliable != its_instance->second.end()) {
- auto its_client = its_reliable->second.find(_client);
- if (its_client != its_reliable->second.end()) {
- is_identifieing = true;
- }
- }
- }
- }
- return is_identifieing;
-}
+ std::shared_ptr<endpoint> its_endpoint =
+ ep_mgr_impl_->find_server_endpoint(
+ its_endpoint_def->get_remote_port(),
+ its_endpoint_def->is_reliable());
+ if (its_endpoint) {
+ #ifdef USE_DLT
+ const uint16_t its_data_size
+ = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
-bool routing_manager_impl::has_identified(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) {
- if (!supports_selective(_service, _instance)) {
- // For legacy selective services clients can't be identified!
- return true;
- }
- bool has_identified(false);
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identified_clients_.find(_service);
- if (its_service != identified_clients_.end()) {
- auto its_instance = its_service->second.find(_instance);
- if (its_instance != its_service->second.end()) {
- auto its_reliable = its_instance->second.find(_reliable);
- if (its_reliable != its_instance->second.end()) {
- auto its_client = its_reliable->second.find(_client);
- if (its_client != its_reliable->second.end()) {
- has_identified = true;
+ trace::header its_header;
+ if (its_header.prepare(its_endpoint, true, _instance))
+ tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
+ _data, its_data_size);
+ #else
+ (void) _instance;
+ #endif
+ its_endpoint->send_error(its_endpoint_def,
+ its_serializer->get_data(), its_serializer->get_size());
}
}
+ its_serializer->reset();
+ put_serializer(its_serializer);
+ } else {
+ VSOMEIP_ERROR<< "Failed to serialize error message.";
}
}
- return has_identified;
}
void routing_manager_impl::clear_remote_subscriber(
@@ -3703,19 +2997,12 @@ void routing_manager_impl::clear_remote_subscriber(
std::chrono::steady_clock::time_point
routing_manager_impl::expire_subscriptions(bool _force) {
- struct subscriptions_info {
- service_t service_id_;
- instance_t instance_id_;
- eventgroup_t eventgroup_id_;
- std::shared_ptr<endpoint_definition> invalid_endpoint_;
- client_t client_;
- std::set<std::shared_ptr<event>> events_;
- std::shared_ptr<eventgroupinfo> eventgroupinfo_;
- };
- std::vector<struct subscriptions_info> subscriptions_to_expire_;
+ std::map<std::shared_ptr<remote_subscription>,
+ std::set<client_t> > its_expired_subscriptions;
+
std::chrono::steady_clock::time_point now
= std::chrono::steady_clock::now();
- std::chrono::steady_clock::time_point next_expiration
+ std::chrono::steady_clock::time_point its_next_expiration
= std::chrono::steady_clock::now() + std::chrono::hours(24);
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
@@ -3723,86 +3010,70 @@ routing_manager_impl::expire_subscriptions(bool _force) {
for (auto &its_service : eventgroups_) {
for (auto &its_instance : its_service.second) {
for (auto &its_eventgroup : its_instance.second) {
- std::set<std::shared_ptr<endpoint_definition>> its_expired_endpoints;
- for (auto &its_target : its_eventgroup.second->get_targets()) {
- if (_force) {
- its_expired_endpoints.insert(its_target.endpoint_);
- } else {
- if (its_target.expiration_ < now) {
- its_expired_endpoints.insert(its_target.endpoint_);
- } else if (its_target.expiration_ < next_expiration) {
- next_expiration = its_target.expiration_;
+ auto its_subscriptions
+ = its_eventgroup.second->get_remote_subscriptions();
+ for (auto &s : its_subscriptions) {
+ for (auto its_client : s->get_clients()) {
+ if (_force) {
+ its_expired_subscriptions[s].insert(its_client);
+ } else {
+ auto its_expiration = s->get_expiration(its_client);
+ if (its_expiration != std::chrono::steady_clock::time_point()) {
+ if (its_expiration < now) {
+ its_expired_subscriptions[s].insert(its_client);
+ } else if (its_expiration < its_next_expiration) {
+ its_next_expiration = its_expiration;
+ }
+ }
}
}
}
-
- for (auto its_endpoint : its_expired_endpoints) {
- its_eventgroup.second->remove_target(its_endpoint);
-
- client_t its_client
- = find_client(its_service.first, its_instance.first,
- its_eventgroup.second, its_endpoint);
- clear_remote_subscriber(its_service.first, its_instance.first,
- its_client, its_endpoint);
-
- std::set<std::shared_ptr<event> > its_events;
- if (its_eventgroup.second->get_targets().size() == 0) {
- its_events = its_eventgroup.second->get_events();
- }
- subscriptions_to_expire_.push_back({its_service.first,
- its_instance.first,
- its_eventgroup.first,
- its_endpoint,
- its_client,
- its_events,
- its_eventgroup.second});
- }
- if(its_eventgroup.second->is_multicast() && its_expired_endpoints.size() &&
- 0 == its_eventgroup.second->get_unreliable_target_count() ) {
- //clear multicast targets if no unreliable subscriber is left for multicast eventgroup
- its_eventgroup.second->clear_multicast_targets();
- }
}
}
}
}
- for (const auto &s : subscriptions_to_expire_) {
- if (s.invalid_endpoint_) {
- for (const auto e: s.events_) {
- if (e->is_shadow()) {
- e->unset_payload();
- }
+ for (auto &s : its_expired_subscriptions) {
+ auto its_info = s.first->get_eventgroupinfo();
+ if (its_info) {
+ auto its_service = its_info->get_service();
+ auto its_instance = its_info->get_instance();
+ auto its_eventgroup = its_info->get_eventgroup();
+ auto its_major = its_info->get_major();
+
+ remote_subscription_id_t its_id;
+ auto its_result = its_info->update_remote_subscription(
+ s.first, std::chrono::steady_clock::now(),
+ s.second, its_id, false);
+ if (its_result) {
+ const client_t its_offering_client
+ = find_local_client(its_service, its_instance);
+ send_unsubscription(its_offering_client,
+ its_service, its_instance, its_eventgroup, its_major,
+ s.second, s.first->get_id());
}
- const client_t its_hosting_client = find_local_client(s.service_id_,
- s.instance_id_);
-
- if (its_hosting_client != VSOMEIP_ROUTING_CLIENT) {
- const pending_subscription_t its_pending_unsubscription(
- std::shared_ptr<sd_message_identifier_t>(),
- s.invalid_endpoint_, s.invalid_endpoint_,
- 0, s.client_);
- pending_subscription_id_t its_pending_unsubscription_id =
- s.eventgroupinfo_->add_pending_subscription(
- its_pending_unsubscription);
- if (its_pending_unsubscription_id != DEFAULT_SUBSCRIPTION) {
- send_unsubscription(its_hosting_client, s.client_, s.service_id_,
- s.instance_id_, s.eventgroup_id_,
- its_pending_unsubscription_id);
- }
+
+ if (s.first->get_unreliable()) {
+ VSOMEIP_INFO << "Expired subscription ["
+ << std::hex << std::setfill('0') << std::setw(4) << its_service << "."
+ << std::hex << std::setfill('0') << std::setw(4) << its_instance << "."
+ << std::hex << std::setfill('0') << std::setw(4) << its_eventgroup << "] unreliable from "
+ << s.first->get_unreliable()->get_address() << ":"
+ << std::dec << s.first->get_unreliable()->get_port();
}
- VSOMEIP_INFO << "Expired subscription ["
- << std::hex << std::setfill('0') << std::setw(4) << s.service_id_ << "."
- << std::hex << std::setfill('0') << std::setw(4) << s.instance_id_ << "."
- << std::hex << std::setfill('0') << std::setw(4) << s.eventgroup_id_ << "] from "
- << s.invalid_endpoint_->get_address() << ":"
- << std::dec << s.invalid_endpoint_->get_port()
- << "(" << std::hex << std::setfill('0') << std::setw(4) << s.client_ << ") "
- << _force;
+ if (s.first->get_reliable()) {
+ VSOMEIP_INFO << "Expired subscription ["
+ << std::hex << std::setfill('0') << std::setw(4) << its_service << "."
+ << std::hex << std::setfill('0') << std::setw(4) << its_instance << "."
+ << std::hex << std::setfill('0') << std::setw(4) << its_eventgroup << "] reliable from "
+ << s.first->get_reliable()->get_address() << ":"
+ << std::dec << s.first->get_reliable()->get_port();
+ }
}
}
- return next_expiration;
+
+ return its_next_expiration;
}
void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const & _error) {
@@ -3811,6 +3082,9 @@ 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 uint32_t its_interval = configuration_->get_log_version_interval();
+
bool is_diag_mode(false);
if (discovery_) {
@@ -3825,62 +3099,24 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const
std::chrono::steady_clock::now() - last_resume_).count() << "s";
}
}
+
VSOMEIP_INFO << "vSomeIP " << VSOMEIP_VERSION << " | ("
<< ((is_diag_mode == true) ? "diagnosis)" : "default)")
<< its_last_resume.str();
- {
- std::lock_guard<std::mutex> its_lock(version_log_timer_mutex_);
- version_log_timer_.expires_from_now(
- std::chrono::seconds(configuration_->get_log_version_interval()));
- version_log_timer_.async_wait(std::bind(&routing_manager_impl::log_version_timer_cbk,
- this, std::placeholders::_1));
- }
- }
-}
-
-#ifndef WITHOUT_SYSTEMD
-void routing_manager_impl::watchdog_cbk(boost::system::error_code const &_error) {
- if (!_error) {
- static bool is_ready(false);
- static bool has_interval(false);
- static uint64_t its_interval(0);
-
- if (is_ready) {
- sd_notify(0, "WATCHDOG=1");
- VSOMEIP_INFO << "Triggered systemd watchdog";
- } else {
- is_ready = true;
- sd_notify(0, "READY=1");
- VSOMEIP_INFO << "Sent READY to systemd watchdog";
- if (0 < sd_watchdog_enabled(0, &its_interval)) {
- has_interval = true;
- VSOMEIP_INFO << "systemd watchdog is enabled";
- }
- }
- if (has_interval) {
- std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
- watchdog_timer_.expires_from_now(std::chrono::microseconds(its_interval / 2));
- watchdog_timer_.async_wait(std::bind(&routing_manager_impl::watchdog_cbk,
- this, std::placeholders::_1));
+ counter++;
+ if (counter == 6) {
+ ep_mgr_->log_client_states();
+ ep_mgr_impl_->log_client_states();
+ counter = 0;
}
- }
-}
-#endif
-void routing_manager_impl::clear_remote_service_info(service_t _service, instance_t _instance, bool _reliable) {
- // Clear remote_service_info_
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- if (remote_service_info_.find(_service) != remote_service_info_.end()) {
- if (remote_service_info_[_service].find(_instance) != remote_service_info_[_service].end()) {
- remote_service_info_[_service][_instance].erase(_reliable);
- auto found_endpoint_def = remote_service_info_[_service][_instance].find(!_reliable);
- if (found_endpoint_def == remote_service_info_[_service][_instance].end()) {
- remote_service_info_[_service].erase(_instance);
- if (0 >= remote_service_info_[_service].size()) {
- remote_service_info_.erase(_service);
- }
- }
+ {
+ std::lock_guard<std::mutex> its_lock(version_log_timer_mutex_);
+ version_log_timer_.expires_from_now(std::chrono::seconds(its_interval));
+ version_log_timer_.async_wait(
+ std::bind(&routing_manager_impl::log_version_timer_cbk,
+ this, std::placeholders::_1));
}
}
}
@@ -4123,135 +3359,28 @@ void routing_manager_impl::handle_client_error(client_t _client) {
}
for (const auto &offer : its_offers) {
offer_service(std::get<0>(offer), std::get<1>(offer), std::get<2>(offer),
- std::get<3>(offer), std::get<4>(offer));
+ std::get<3>(offer), std::get<4>(offer), true);
}
}
-void routing_manager_impl::remove_specific_client_endpoint(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) {
- client_t its_client = is_specific_endpoint_client(_client, _service, _instance);
- if (its_client != VSOMEIP_ROUTING_CLIENT) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- if (remote_services_.find(_service) != remote_services_.end()) {
- if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
- auto endpoint = remote_services_[_service][_instance][_client][_reliable];
- if (endpoint) {
- service_instances_[_service].erase(endpoint.get());
- endpoint->stop();
- }
- remote_services_[_service][_instance][_client].erase(_reliable);
- auto found_endpoint = remote_services_[_service][_instance][_client].find(!_reliable);
- if (found_endpoint == remote_services_[_service][_instance][_client].end()) {
- remote_services_[_service][_instance].erase(_client);
- }
- }
- }
- }
-}
-
-void routing_manager_impl::clear_identified_clients( service_t _service, instance_t _instance) {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identified_clients_.find(_service);
- if (its_service != identified_clients_.end()) {
- auto found_instance = its_service->second.find(_instance);
- if (found_instance != its_service->second.end()) {
- auto found_reliable = found_instance->second.find(true);
- if (found_reliable != found_instance->second.end()) {
- found_reliable->second.clear();
- }
- auto found_unreliable = found_instance->second.find(false);
- if (found_unreliable != found_instance->second.end()) {
- found_unreliable->second.clear();
- }
- }
- }
-}
-
-void routing_manager_impl::clear_identifying_clients( service_t _service, instance_t _instance) {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identifying_clients_.find(_service);
- if (its_service != identifying_clients_.end()) {
- auto found_instance = its_service->second.find(_instance);
- if (found_instance != its_service->second.end()) {
- auto found_reliable = found_instance->second.find(true);
- if (found_reliable != found_instance->second.end()) {
- found_reliable->second.clear();
- }
- auto found_unreliable = found_instance->second.find(false);
- if (found_unreliable != found_instance->second.end()) {
- found_unreliable->second.clear();
- }
- }
- }
-}
-
-void routing_manager_impl::remove_identified_client(service_t _service, instance_t _instance, client_t _client) {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identified_clients_.find(_service);
- if (its_service != identified_clients_.end()) {
- auto found_instance = its_service->second.find(_instance);
- if (found_instance != its_service->second.end()) {
- auto found_reliable = found_instance->second.find(true);
- if (found_reliable != found_instance->second.end()) {
- auto found_client = found_reliable->second.find(_client);
- if(found_client != found_reliable->second.end())
- found_reliable->second.erase(_client);
- }
- auto found_unreliable = found_instance->second.find(false);
- if (found_unreliable != found_instance->second.end()) {
- auto found_client = found_unreliable->second.find(_client);
- if(found_client != found_unreliable->second.end())
- found_unreliable->second.erase(_client);
- }
- }
- }
-}
-
-void routing_manager_impl::remove_identifying_client(service_t _service, instance_t _instance, client_t _client) {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- auto its_service = identifying_clients_.find(_service);
- if (its_service != identifying_clients_.end()) {
- auto found_instance = its_service->second.find(_instance);
- if (found_instance != its_service->second.end()) {
- auto found_reliable = found_instance->second.find(true);
- if (found_reliable != found_instance->second.end()) {
- auto found_client = found_reliable->second.find(_client);
- if(found_client != found_reliable->second.end())
- found_reliable->second.erase(_client);
- }
- auto found_unreliable = found_instance->second.find(false);
- if (found_unreliable != found_instance->second.end()) {
- auto found_client = found_unreliable->second.find(_client);
- if(found_client != found_unreliable->second.end())
- found_unreliable->second.erase(_client);
- }
- }
- }
-}
-
-void routing_manager_impl::unsubscribe_specific_client_at_sd(
- service_t _service, instance_t _instance, client_t _client) {
- client_t subscriber = is_specific_endpoint_client(_client, _service, _instance);
- if (subscriber != VSOMEIP_ROUTING_CLIENT && discovery_) {
- discovery_->unsubscribe_client(_service, _instance, _client);
- }
+std::shared_ptr<endpoint_manager_impl> routing_manager_impl::get_endpoint_manager() const {
+ return ep_mgr_impl_;
}
void routing_manager_impl::send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, subscription_type_e _subscription_type) {
- (void)_subscription_type;
- auto endpoint = find_local(_service, _instance);
+ event_t _event) {
+ auto endpoint = ep_mgr_->find_local(_service, _instance);
if (endpoint) {
stub_->send_subscribe(endpoint, _client,
- _service, _instance, _eventgroup, _major, _event, DEFAULT_SUBSCRIPTION);
+ _service, _instance, _eventgroup, _major, _event, PENDING_SUBSCRIPTION_ID);
}
}
void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
if(discovery_) {
switch (_routing_state) {
- case vsomeip::routing_state_e::RS_SUSPENDED:
+ case routing_state_e::RS_SUSPENDED:
{
VSOMEIP_INFO << "Set routing to suspend mode, diagnosis mode is "
<< ((discovery_->get_diagnosis_mode() == true) ? "active." : "inactive.");
@@ -4271,7 +3400,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
<< std::hex << std::setw(4) << std::setfill('0') << its_instance.first << " still offered by "
<< std::hex << std::setw(4) << std::setfill('0') << its_client;
}
- discovery_->stop_offer_service(its_service.first, its_instance.first, its_instance.second);
+ discovery_->stop_offer_service(its_instance.second);
}
}
{
@@ -4289,13 +3418,6 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
// determine existing subscriptions to remote service and send StopSubscribe
for (auto its_eventgroup : get_subscribed_eventgroups(s.first, i.first)) {
discovery_->unsubscribe(s.first, i.first, its_eventgroup, VSOMEIP_ROUTING_CLIENT);
- auto specific_endpoint_clients = get_specific_endpoint_clients(s.first, i.first);
- for (auto its_client : specific_endpoint_clients) {
- discovery_->unsubscribe(s.first, i.first, its_eventgroup, its_client);
- }
- for (const auto &e : find_events(s.first, i.first, its_eventgroup)) {
- e->clear_subscribers();
- }
}
const bool has_reliable(i.second->get_endpoint(true));
@@ -4308,7 +3430,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
}
break;
}
- case vsomeip::routing_state_e::RS_RESUMED:
+ case routing_state_e::RS_RESUMED:
{
VSOMEIP_INFO << "Set routing to resume mode, diagnosis mode was "
<< ((discovery_->get_diagnosis_mode() == true) ? "active." : "inactive.");
@@ -4337,8 +3459,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
// Trigger initial offer phase for relevant services
for (const auto &its_service : get_offered_services()) {
for (const auto &its_instance : its_service.second) {
- discovery_->offer_service(its_service.first,
- its_instance.first, its_instance.second);
+ discovery_->offer_service(its_instance.second);
}
}
break;
@@ -4353,8 +3474,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
for (const auto &its_instance : its_service.second) {
if (host_->get_configuration()->is_someip(
its_service.first, its_instance.first)) {
- discovery_->stop_offer_service(
- its_service.first, its_instance.first, its_instance.second);
+ discovery_->stop_offer_service(its_instance.second);
}
}
}
@@ -4382,8 +3502,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
for (const auto &its_instance : its_service.second) {
if (host_->get_configuration()->is_someip(
its_service.first, its_instance.first)) {
- discovery_->offer_service(its_service.first,
- its_instance.first, its_instance.second);
+ discovery_->offer_service(its_instance.second);
}
}
}
@@ -4446,6 +3565,10 @@ void routing_manager_impl::on_net_interface_or_route_state_changed(
}
void routing_manager_impl::start_ip_routing() {
+#ifdef _WIN32
+ if_state_running_ = true;
+#endif
+
if (routing_ready_handler_) {
routing_ready_handler_();
}
@@ -4506,8 +3629,8 @@ routing_manager_impl::get_subscribed_eventgroups(
if (found_service != eventgroups_.end()) {
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
- for (auto its_group : found_instance->second) {
- for (auto its_event : its_group.second->get_events()) {
+ for (const auto& its_group : found_instance->second) {
+ for (const auto& its_event : its_group.second->get_events()) {
if (its_event->has_subscriber(its_group.first, ANY_CLIENT)) {
its_eventgroups.insert(its_group.first);
}
@@ -4540,7 +3663,7 @@ void routing_manager_impl::clear_targets_and_pending_sub_from_eventgroups(
its_eventgroup.first, its_subscriber);
}
- client_t its_client = is_specific_endpoint_client(its_subscriber, _service, _instance);
+ client_t its_client = VSOMEIP_ROUTING_CLIENT; //is_specific_endpoint_client(its_subscriber, _service, _instance);
{
std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
const auto its_tuple =
@@ -4551,8 +3674,9 @@ void routing_manager_impl::clear_targets_and_pending_sub_from_eventgroups(
}
its_events.push_back(its_event);
}
- its_eventgroup.second->clear_targets();
- its_eventgroup.second->clear_pending_subscriptions();
+ // TODO dn: find out why this was commented out
+ //its_eventgroup.second->clear_targets();
+ //its_eventgroup.second->clear_pending_subscriptions();
}
}
}
@@ -4578,7 +3702,7 @@ void routing_manager_impl::clear_remote_subscriber(service_t _service,
void routing_manager_impl::call_sd_endpoint_connected(
const boost::system::error_code& _error,
service_t _service, instance_t _instance,
- std::shared_ptr<endpoint> _endpoint,
+ const std::shared_ptr<endpoint>& _endpoint,
std::shared_ptr<boost::asio::steady_timer> _timer) {
(void)_timer;
if (_error) {
@@ -4604,14 +3728,20 @@ bool routing_manager_impl::create_placeholder_event_and_subscribe(
if (its_local_client == host_->get_client()) {
// received subscription for event of a service instance hosted by
// application acting as rm_impl register with own client id and shadow = false
- register_event(host_->get_client(), _service, _instance, _event,
- its_eventgroups, true, std::chrono::milliseconds::zero(), false,
+ register_event(host_->get_client(),
+ _service, _instance,
+ _event,
+ its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN,
+ std::chrono::milliseconds::zero(), false, true,
nullptr, false, false, true);
} else if (its_local_client != VSOMEIP_ROUTING_CLIENT) {
// received subscription for event of a service instance hosted on
// this node register with client id of local_client and set shadow to true
- register_event(its_local_client, _service, _instance, _event,
- its_eventgroups, true, std::chrono::milliseconds::zero(), false,
+ register_event(its_local_client,
+ _service, _instance,
+ _event, its_eventgroups, event_type_e::ET_UNKNOWN,
+ reliability_type_e::RT_UNKNOWN,
+ std::chrono::milliseconds::zero(), false, true,
nullptr, false, true, true);
} else {
// received subscription for event of a unknown or remote service instance
@@ -4620,9 +3750,12 @@ bool routing_manager_impl::create_placeholder_event_and_subscribe(
if (its_info && !its_info->is_local()) {
// remote service, register shadow event with client ID of subscriber
// which should have called register_event
- register_event(_client, _service, _instance, _event,
- its_eventgroups, true, std::chrono::milliseconds::zero(),
- false, nullptr, false, true, true);
+ register_event(_client,
+ _service, _instance,
+ _event, its_eventgroups, event_type_e::ET_UNKNOWN,
+ reliability_type_e::RT_UNKNOWN,
+ std::chrono::milliseconds::zero(),
+ false, true, nullptr, false, true, true);
} else {
VSOMEIP_WARNING
<< "routing_manager_impl::create_placeholder_event_and_subscribe("
@@ -4642,126 +3775,84 @@ bool routing_manager_impl::create_placeholder_event_and_subscribe(
return is_inserted;
}
-void routing_manager_impl::handle_subscription_state(client_t _client, service_t _service, instance_t _instance,
+void routing_manager_impl::handle_subscription_state(
+ client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event) {
+#if 0
+ VSOMEIP_ERROR << "routing_manager_impl::" << __func__
+ << "(" << std::hex << _client << "): "
+ << "event="
+ << std::hex << _service << "."
+ << std::hex << _instance << "."
+ << std::hex << _eventgroup << "."
+ << std::hex << _event
+ << " me="
+ << std::hex << get_client();
+#endif
+ // Note: remote_subscription_state_mutex_ is already locked as this
+ // method builds a critical section together with insert_subscription
+ // from routing_manager_base.
+ // Todo: Improve this situation...
+ auto its_event = find_event(_service, _instance, _event);
+ client_t its_client(VSOMEIP_ROUTING_CLIENT);
+ if (its_event &&
+ its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT) {
+ its_client = _client;
+ }
- client_t subscriber = is_specific_endpoint_client(_client, _service, _instance);
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, subscriber);
-
- std::lock_guard<std::mutex> its_lock(remote_subscription_state_mutex_);
+ auto its_tuple
+ = std::make_tuple(_service, _instance, _eventgroup, its_client);
auto its_state = remote_subscription_state_.find(its_tuple);
if (its_state != remote_subscription_state_.end()) {
+#if 0
+ VSOMEIP_ERROR << "routing_manager_impl::" << __func__
+ << "(" << std::hex << _client << "): "
+ << "event="
+ << std::hex << _service << "."
+ << std::hex << _instance << "."
+ << std::hex << _eventgroup << "."
+ << std::hex << _event
+ << " state=" << std::hex << (int)its_state->second
+ << " me="
+ << std::hex << get_client();
+#endif
if (its_state->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {
// Subscription already acknowledged!
if (_client == get_client()) {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x0 /*OK*/);
host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/);
} else {
stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event);
}
}
- } else {
- remote_subscription_state_[its_tuple] = subscription_state_e::IS_SUBSCRIBING;
}
}
-client_t routing_manager_impl::is_specific_endpoint_client(client_t _client,
- service_t _service, instance_t _instance) {
- client_t result = VSOMEIP_ROUTING_CLIENT;
- {
- std::lock_guard<std::mutex> its_lock(specific_endpoint_clients_mutex_);
- auto found_service = specific_endpoint_clients_.find(_service);
- if (found_service != specific_endpoint_clients_.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()) {
- result = _client;
- }
- }
- }
- }
- // A client_t != VSOMEIP_ROUTING_CLIENT implies true
- return result;
-}
-
-std::unordered_set<client_t> routing_manager_impl::get_specific_endpoint_clients(
- service_t _service, instance_t _instance) {
- std::unordered_set<client_t> result;
- {
- std::lock_guard<std::mutex> its_lock(specific_endpoint_clients_mutex_);
- auto found_service = specific_endpoint_clients_.find(_service);
- if (found_service != specific_endpoint_clients_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- result = found_instance->second;
- }
- }
- }
- return result;
-}
-
-void routing_manager_impl::send_initial_events(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- const std::shared_ptr<endpoint_definition> &_subscriber) {
- std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
- _instance, _eventgroup);
- if (!its_eventgroup) {
- return;
- }
- bool is_offered_both(false);
- if (configuration_->get_reliable_port(_service, _instance) != ILLEGAL_PORT &&
- configuration_->get_unreliable_port(_service, _instance) != ILLEGAL_PORT) {
- is_offered_both = true;
- }
- // send initial events if we already have a cached field (is_set)
- for (const auto &its_event : its_eventgroup->get_events()) {
- if (its_event->is_field()) {
- if (its_event->is_set()) {
- if (!is_offered_both) {
- its_event->notify_one(_subscriber, true);
- } else {
- if (its_event->is_reliable() && _subscriber->is_reliable()) {
- its_event->notify_one(_subscriber, true);
- }
- if (!its_event->is_reliable() && !_subscriber->is_reliable()) {
- its_event->notify_one(_subscriber, true);
- }
- }
- } else {
- // received a subscription but can't notify due to missing payload
- its_event->set_remote_notification_pending(true);
- }
- }
- }
-}
-
-void routing_manager_impl::register_offer_acceptance_handler(
- vsomeip::offer_acceptance_handler_t _handler) const {
+void routing_manager_impl::register_sd_acceptance_handler(
+ const sd_acceptance_handler_t& _handler) const {
if (discovery_) {
- discovery_->register_offer_acceptance_handler(_handler);
+ discovery_->register_sd_acceptance_handler(_handler);
}
}
void routing_manager_impl::register_reboot_notification_handler(
- vsomeip::reboot_notification_handler_t _handler) const {
+ const reboot_notification_handler_t& _handler) const {
if (discovery_) {
discovery_->register_reboot_notification_handler(_handler);
}
}
void routing_manager_impl::register_routing_ready_handler(
- routing_ready_handler_t _handler) {
+ const routing_ready_handler_t& _handler) {
routing_ready_handler_ = _handler;
}
void routing_manager_impl::register_routing_state_handler(
- routing_state_handler_t _handler) {
+ const routing_state_handler_t& _handler) {
routing_state_handler_ = _handler;
}
-void routing_manager_impl::offer_acceptance_enabled(
- boost::asio::ip::address _address) {
+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);
@@ -4775,7 +3866,7 @@ void routing_manager_impl::memory_log_timer_cbk(
return;
}
#ifndef _WIN32
- static const std::uint32_t its_pagesize = getpagesize() / 1024;
+ static const std::uint32_t its_pagesize = static_cast<std::uint32_t>(getpagesize() / 1024);
#else
static const std::uint32_t its_pagesize = 4096 / 1024;
#endif
@@ -4836,75 +3927,7 @@ void routing_manager_impl::status_log_timer_cbk(
return;
}
- // local client endpoints
- {
- std::map<client_t, std::shared_ptr<endpoint>> lces = get_local_endpoints();
- VSOMEIP_INFO << "status local client endpoints: " << std::dec << lces.size();
- for (const auto lce : lces) {
- lce.second->print_status();
- }
- }
-
- // 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:";
- std::uint32_t num_remote_client_endpoints(0);
- // normal endpoints
- for (const auto &a : client_endpoints_by_ip) {
- for (const auto p : a.second) {
- for (const auto ru : p.second) {
- ru.second->print_status();
- num_remote_client_endpoints++;
- }
- }
- }
- 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
- stub_->print_endpoint_status();
-
- // server endpoints
- for (const auto p : server_endpoints) {
- for (const auto ru : p.second ) {
- ru.second->print_status();
- num_server_endpoints++;
- }
- }
- VSOMEIP_INFO << "status end server endpoints:"
- << std::dec << num_server_endpoints;
- }
-
-
+ ep_mgr_impl_->print_status();
{
std::lock_guard<std::mutex> its_lock(status_log_timer_mutex_);
boost::system::error_code ec;
@@ -4916,138 +3939,107 @@ void routing_manager_impl::status_log_timer_cbk(
}
}
-void routing_manager_impl::on_unsubscribe_ack(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _unsubscription_id) {
- std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
- _instance, _eventgroup);
- if (!its_eventgroup) {
- VSOMEIP_ERROR << __func__ << ": Received UNSUBSCRIBE_ACK for unknown "
- << "eventgroup: ("
- << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]";
- return;
- }
- // there will only be one or zero subscriptions returned here
- std::vector<pending_subscription_t> its_pending_subscriptions =
- its_eventgroup->remove_pending_subscription(_unsubscription_id);
- for (const pending_subscription_t& its_sd_message_id : its_pending_subscriptions) {
- if (its_sd_message_id.pending_subscription_id_ == _unsubscription_id) {
- its_eventgroup->remove_target(its_sd_message_id.target_);
- clear_remote_subscriber(_service, _instance,
- its_sd_message_id.subscribing_client_,
- its_sd_message_id.target_);
- if (its_eventgroup->get_targets().size() == 0) {
- for (auto e : its_eventgroup->get_events()) {
- if (e->is_shadow()) {
- e->unset_payload();
+void
+routing_manager_impl::on_unsubscribe_ack(client_t _client,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ remote_subscription_id_t _id) {
+ std::shared_ptr<eventgroupinfo> its_info
+ = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_info) {
+ const auto its_subscription = its_info->get_remote_subscription(_id);
+ if (its_subscription) {
+ its_info->remove_remote_subscription(_id);
+
+ std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_);
+ remote_subscribers_[_service][_instance].erase(_client);
+
+ if (its_info->get_remote_subscriptions().size() == 0) {
+ for (const auto &its_event : its_info->get_events()) {
+ bool has_remote_subscriber(false);
+ for (const auto &its_eventgroup : its_event->get_eventgroups()) {
+ const auto its_eventgroup_info
+ = find_eventgroup(_service, _instance, its_eventgroup);
+ if (its_eventgroup_info
+ && its_eventgroup_info->get_remote_subscriptions().size() > 0) {
+ has_remote_subscriber = true;
+ }
+ }
+
+ if (!has_remote_subscriber && its_event->is_shadow()) {
+ its_event->unset_payload();
}
}
}
} else {
- const pending_subscription_id_t its_subscription_id =
- its_sd_message_id.pending_subscription_id_;
- const client_t its_subscribing_client = its_sd_message_id.subscribing_client_;
- const client_t its_offering_client = find_local_client(_service, _instance);
- send_subscription(its_offering_client, its_subscribing_client, _service,
- _instance, _eventgroup, its_eventgroup->get_major(),
- its_subscription_id);
+ VSOMEIP_ERROR << __func__
+ << ": Unknown StopSubscribe " << std::dec << _id << " for eventgroup ["
+ << 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 << "]";
}
+ } else {
+ VSOMEIP_ERROR << __func__
+ << ": Received StopSubscribe for unknown eventgroup: ("
+ << std::hex << std::setw(4) << std::setfill('0') << _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') << _eventgroup << "]";
}
}
-void routing_manager_impl::send_unsubscription(
- client_t _offering_client, client_t _subscribing_client,
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _pending_unsubscription_id) {
+void routing_manager_impl::on_connect(const std::shared_ptr<endpoint>& _endpoint) {
+ (void)_endpoint;
+}
+void routing_manager_impl::on_disconnect(const std::shared_ptr<endpoint>& _endpoint) {
+ (void)_endpoint;
+}
+void routing_manager_impl::send_subscription(
+ const client_t _offering_client,
+ const service_t _service, const instance_t _instance,
+ const eventgroup_t _eventgroup, const major_version_t _major,
+ const std::set<client_t> &_clients,
+ const remote_subscription_id_t _id) {
if (host_->get_client() == _offering_client) {
auto self = shared_from_this();
- host_->on_subscription(_service, _instance, _eventgroup,
- _subscribing_client, false,
- [this, self, _service, _instance, _eventgroup,
- _subscribing_client, _pending_unsubscription_id, _offering_client]
- (const bool _subscription_accepted) {
- (void)_subscription_accepted;
+ for (const auto its_client : _clients) {
+ host_->on_subscription(_service, _instance, _eventgroup, its_client, own_uid_, own_gid_, true,
+ [this, self, _service, _instance, _eventgroup, its_client, _id]
+ (const bool _is_accepted) {
try {
- const auto its_callback = std::bind(
- &routing_manager_stub_host::on_unsubscribe_ack,
- std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
- _offering_client, _service, _instance,
- _eventgroup, _pending_unsubscription_id);
- io_.post(its_callback);
+ if (!_is_accepted) {
+ const auto its_callback = std::bind(
+ &routing_manager_stub_host::on_subscribe_nack,
+ std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
+ its_client, _service, _instance,
+ _eventgroup, ANY_EVENT, _id);
+ io_.post(its_callback);
+ } else {
+ const auto its_callback = std::bind(
+ &routing_manager_stub_host::on_subscribe_ack,
+ std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
+ its_client, _service, _instance,
+ _eventgroup, ANY_EVENT, _id);
+ io_.post(its_callback);
+ }
} catch (const std::exception &e) {
VSOMEIP_ERROR << __func__ << e.what();
}
- }
- );
- } else {
- if (!stub_->send_unsubscribe(find_local(_offering_client),
- _subscribing_client,
- _service, _instance, _eventgroup, ANY_EVENT,
- _pending_unsubscription_id)) {
- try {
- const auto its_callback = std::bind(
- &routing_manager_stub_host::on_unsubscribe_ack,
- std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
- _offering_client, _service, _instance,
- _eventgroup, _pending_unsubscription_id);
- io_.post(its_callback);
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << __func__ << e.what();
- }
+ });
}
- }
-}
-
-void routing_manager_impl::send_subscription(
- client_t _offering_client, client_t _subscribing_client,
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major,
- pending_subscription_id_t _pending_subscription_id) {
- if (host_->get_client() == _offering_client) {
- auto self = shared_from_this();
- host_->on_subscription(_service, _instance, _eventgroup,
- _subscribing_client, true,
- [this, self, _service, _instance,
- _eventgroup, _subscribing_client, _pending_subscription_id]
- (const bool _subscription_accepted) {
- try {
- if (!_subscription_accepted) {
+ } else { // service hosted by local client
+ for (const auto its_client : _clients) {
+ if (!stub_->send_subscribe(find_local(_offering_client), its_client,
+ _service, _instance, _eventgroup, _major, ANY_EVENT, _id)) {
+ try {
const auto its_callback = std::bind(
&routing_manager_stub_host::on_subscribe_nack,
std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
- _subscribing_client, _service, _instance,
- _eventgroup, ANY_EVENT, _pending_subscription_id);
- io_.post(its_callback);
- } else {
- const auto its_callback = std::bind(
- &routing_manager_stub_host::on_subscribe_ack,
- std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
- _subscribing_client, _service, _instance,
- _eventgroup, ANY_EVENT, _pending_subscription_id);
+ its_client, _service, _instance, _eventgroup,
+ ANY_EVENT, _id);
io_.post(its_callback);
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << __func__ << e.what();
}
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << __func__ << e.what();
- }
- });
- } else { // service hosted by local client
- if (!stub_->send_subscribe(find_local(_offering_client),
- _subscribing_client,
- _service, _instance, _eventgroup,
- _major, ANY_EVENT,
- _pending_subscription_id)) {
- try {
- const auto its_callback = std::bind(
- &routing_manager_stub_host::on_subscribe_nack,
- std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
- _subscribing_client, _service, _instance,
- _eventgroup, ANY_EVENT, _pending_subscription_id);
- io_.post(its_callback);
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << __func__ << e.what();
}
}
}
@@ -5056,31 +4048,15 @@ void routing_manager_impl::send_subscription(
void routing_manager_impl::cleanup_server_endpoint(
service_t _service, const std::shared_ptr<endpoint>& _endpoint) {
if (_endpoint) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- bool reliable = _endpoint->is_reliable();
- // Check whether any service still uses this endpoint
- _endpoint->decrement_use_count();
- bool isLastService = (_endpoint->get_use_count() == 0);
-
- // Clear service_instances_
- if (1 >= service_instances_[_service].size()) {
- service_instances_.erase(_service);
- } else {
- service_instances_[_service].erase(_endpoint.get());
- }
-
- // Clear server endpoint if no service remains using it
- if (isLastService) {
- const uint16_t port = _endpoint->get_local_port();
- if (server_endpoints_.find(port) != server_endpoints_.end()) {
- server_endpoints_[port].erase(reliable);
- if (server_endpoints_[port].find(!reliable) == server_endpoints_[port].end()) {
- server_endpoints_.erase(port);
- }
+ // Clear service_instances_, check whether any service still
+ // uses this endpoint and clear server endpoint if no service
+ // remains using it
+ if (ep_mgr_impl_->remove_instance(_service, _endpoint.get())) {
+ if (ep_mgr_impl_->remove_server_endpoint(
+ _endpoint->get_local_port(), _endpoint->is_reliable())) {
+ // Stop endpoint (close socket) to release its async_handlers!
+ _endpoint->stop();
}
-
- // Stop endpoint (close socket) to release its async_handlers!
- _endpoint->stop();
}
}
}
@@ -5182,16 +4158,18 @@ void routing_manager_impl::on_security_update_timeout(
bool routing_manager_impl::update_security_policy_configuration(
uint32_t _uid, uint32_t _gid,
- ::std::shared_ptr<policy> _policy, std::shared_ptr<payload> _payload, security_update_handler_t _handler) {
+ const std::shared_ptr<policy>& _policy,
+ const std::shared_ptr<payload>& _payload,
+ const security_update_handler_t& _handler) {
bool ret(true);
// cache security policy payload for later distribution to new registering clients
stub_->policy_cache_add(_uid, _payload);
// update security policy from configuration
- configuration_->update_security_policy(_uid, _gid, _policy);
+ security::get()->update_security_policy(_uid, _gid, _policy);
// determine currently connected clients
- std::unordered_set<client_t> its_clients_to_inform = get_connected_clients();
+ std::unordered_set<client_t> its_clients_to_inform = ep_mgr_impl_->get_connected_clients();
// add handler
pending_security_update_id_t its_id;
@@ -5254,13 +4232,13 @@ bool routing_manager_impl::update_security_policy_configuration(
}
bool routing_manager_impl::remove_security_policy_configuration(
- uint32_t _uid, uint32_t _gid, security_update_handler_t _handler) {
+ uint32_t _uid, uint32_t _gid, const security_update_handler_t& _handler) {
bool ret(true);
// remove security policy from configuration (only if there was a updateACL call before)
if (stub_->is_policy_cached(_uid)) {
- if (!configuration_->remove_security_policy(_uid, _gid)) {
- _handler(vsomeip::security_update_state_e::SU_UNKNOWN_USER_ID);
+ if (!security::get()->remove_security_policy(_uid, _gid)) {
+ _handler(security_update_state_e::SU_UNKNOWN_USER_ID);
ret = false;
} else {
// remove policy from cache to prevent sending it to registering clients
@@ -5270,7 +4248,7 @@ bool routing_manager_impl::remove_security_policy_configuration(
pending_security_update_id_t its_id;
// determine currently connected clients
- std::unordered_set<client_t> its_clients_to_inform = get_connected_clients();
+ std::unordered_set<client_t> its_clients_to_inform = ep_mgr_impl_->get_connected_clients();
if (!its_clients_to_inform.empty()) {
its_id = pending_security_update_add(its_clients_to_inform);
@@ -5330,14 +4308,14 @@ bool routing_manager_impl::remove_security_policy_configuration(
}
}
else {
- _handler(vsomeip::security_update_state_e::SU_UNKNOWN_USER_ID);
+ _handler(security_update_state_e::SU_UNKNOWN_USER_ID);
ret = false;
}
return ret;
}
pending_security_update_id_t routing_manager_impl::pending_security_update_add(
- std::unordered_set<client_t> _clients) {
+ const std::unordered_set<client_t>& _clients) {
std::lock_guard<std::mutex> its_lock(pending_security_updates_mutex_);
if (++pending_security_update_id_ == 0) {
pending_security_update_id_++;
@@ -5423,4 +4401,96 @@ void routing_manager_impl::on_security_update_response(
}
}
-} // namespace vsomeip
+void routing_manager_impl::print_stub_status() const {
+ stub_->print_endpoint_status();
+}
+
+void routing_manager_impl::service_endpoint_connected(
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, const std::shared_ptr<endpoint>& _endpoint,
+ bool _unreliable_only) {
+
+ if (!_unreliable_only) {
+ // Mark only TCP-only and TCP+UDP services available here
+ // UDP-only services are already marked as available in add_routing_info
+ on_availability(_service, _instance, true, _major, _minor);
+ stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance,
+ _major, _minor);
+ }
+
+ std::shared_ptr<boost::asio::steady_timer> its_timer =
+ std::make_shared<boost::asio::steady_timer>(io_);
+ boost::system::error_code ec;
+ its_timer->expires_from_now(std::chrono::milliseconds(3), ec);
+ if (!ec) {
+ its_timer->async_wait(
+ std::bind(&routing_manager_impl::call_sd_endpoint_connected,
+ std::static_pointer_cast<routing_manager_impl>(
+ shared_from_this()), std::placeholders::_1,
+ _service, _instance, _endpoint, its_timer));
+ } else {
+ VSOMEIP_ERROR << __func__ << " " << ec.message();
+ }
+}
+
+void routing_manager_impl::service_endpoint_disconnected(
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, const std::shared_ptr<endpoint>& _endpoint) {
+ (void)_endpoint;
+ on_availability(_service, _instance, false, _major, _minor);
+ stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance,
+ _major, _minor);
+ VSOMEIP_WARNING << __func__ << ": lost connection to remote service: ["
+ << std::hex << std::setw(4) << std::setfill('0') << _service << "."
+ << std::hex << std::setw(4) << std::setfill('0') << _instance << "]";
+}
+
+void
+routing_manager_impl::send_unsubscription(client_t _offering_client,
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major,
+ const std::set<client_t> &_removed,
+ remote_subscription_id_t _id) {
+
+ (void)_major; // TODO: Remove completely?
+
+ if (host_->get_client() == _offering_client) {
+ auto self = shared_from_this();
+ for (const auto its_client : _removed) {
+ host_->on_subscription(_service, _instance,
+ _eventgroup, its_client, own_uid_, own_gid_, false,
+ [this, self, _service, _instance, _eventgroup,
+ its_client, _id, _offering_client]
+ (const bool _is_accepted) {
+ (void)_is_accepted;
+ try {
+ const auto its_callback = std::bind(
+ &routing_manager_stub_host::on_unsubscribe_ack,
+ std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
+ its_client, _service, _instance, _eventgroup, _id);
+ io_.post(its_callback);
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << __func__ << e.what();
+ }
+ }
+ );
+ }
+ } else {
+ for (const auto its_client : _removed) {
+ if (!stub_->send_unsubscribe(find_local(_offering_client), its_client,
+ _service, _instance, _eventgroup, ANY_EVENT, _id)) {
+ try {
+ const auto its_callback = std::bind(
+ &routing_manager_stub_host::on_unsubscribe_ack,
+ std::dynamic_pointer_cast<routing_manager_stub_host>(shared_from_this()),
+ its_client, _service, _instance, _eventgroup, _id);
+ io_.post(its_callback);
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << __func__ << e.what();
+ }
+ }
+ }
+ }
+}
+
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index d439654..8135c3f 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -12,26 +12,28 @@
#include <vsomeip/constants.hpp>
#include <vsomeip/runtime.hpp>
+#include <vsomeip/internal/logger.hpp>
#include "../include/event.hpp"
#include "../include/routing_manager_host.hpp"
#include "../include/routing_manager_proxy.hpp"
#include "../../configuration/include/configuration.hpp"
-#include "../../configuration/include/internal.hpp"
+#include "../../security/include/policy.hpp"
+#include "../../security/include/security_impl.hpp"
+
#include "../../endpoints/include/local_client_endpoint_impl.hpp"
#include "../../endpoints/include/local_server_endpoint_impl.hpp"
-#include "../../logging/include/logger.hpp"
#include "../../message/include/deserializer.hpp"
+#include "../../message/include/message_impl.hpp"
#include "../../message/include/serializer.hpp"
#include "../../service_discovery/include/runtime.hpp"
#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
-#include "../../configuration/include/policy.hpp"
#ifdef USE_DLT
#include "../../tracing/include/connector_impl.hpp"
#endif
-namespace vsomeip {
+namespace vsomeip_v3 {
routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host,
bool _client_side_logging,
@@ -40,8 +42,8 @@ routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host,
is_connected_(false),
is_started_(false),
state_(inner_state_type_e::ST_DEREGISTERED),
- sender_(0),
- receiver_(0),
+ sender_(nullptr),
+ receiver_(nullptr),
register_application_timer_(io_),
logger_(logger::get()),
request_debounce_timer_ (io_),
@@ -55,31 +57,20 @@ routing_manager_proxy::~routing_manager_proxy() {
}
void routing_manager_proxy::init() {
- routing_manager_base::init();
+ routing_manager_base::init(std::make_shared<endpoint_manager_base>(this, io_, configuration_));
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
- sender_ = create_local(VSOMEIP_ROUTING_CLIENT);
+ sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
}
-
- init_receiver();
}
void routing_manager_proxy::start() {
is_started_ = true;
-
- if (!receiver_) {
- // application has been stopped and started again
- init_receiver();
- }
- if (receiver_) {
- receiver_->start();
- }
-
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
if (!sender_) {
// application has been stopped and started again
- sender_ = create_local(VSOMEIP_ROUTING_CLIENT);
+ sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT);
}
if (sender_) {
sender_->start();
@@ -135,7 +126,7 @@ void routing_manager_proxy::stop() {
sender_ = nullptr;
}
- for (auto client: get_connected_clients()) {
+ for (auto client: ep_mgr_->get_connected_clients()) {
if (client != VSOMEIP_ROUTING_CLIENT) {
remove_local(client, true);
}
@@ -153,12 +144,14 @@ void routing_manager_proxy::stop() {
#endif
}
-const std::shared_ptr<configuration> routing_manager_proxy::get_configuration() const {
+std::shared_ptr<configuration> routing_manager_proxy::get_configuration() const {
return host_->get_configuration();
}
-bool routing_manager_proxy::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor) {
+bool routing_manager_proxy::offer_service(client_t _client,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
+
if(!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) {
VSOMEIP_WARNING << "routing_manager_proxy::offer_service,"
<< "routing_manager_base::offer_service returned false";
@@ -168,15 +161,15 @@ bool routing_manager_proxy::offer_service(client_t _client, service_t _service,
if (state_ == inner_state_type_e::ST_REGISTERED) {
send_offer_service(_client, _service, _instance, _major, _minor);
}
- service_data_t offer = { _service, _instance, _major, _minor, false };
+ service_data_t offer = { _service, _instance, _major, _minor };
pending_offers_.insert(offer);
}
return true;
}
void routing_manager_proxy::send_offer_service(client_t _client,
- service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor) {
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
(void)_client;
byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
@@ -207,6 +200,7 @@ void routing_manager_proxy::send_offer_service(client_t _client,
void routing_manager_proxy::stop_offer_service(client_t _client,
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
+
(void)_client;
routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor);
@@ -256,14 +250,14 @@ void routing_manager_proxy::stop_offer_service(client_t _client,
}
void routing_manager_proxy::request_service(client_t _client,
- service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, bool _use_exclusive_proxy) {
- routing_manager_base::request_service(_client, _service, _instance, _major,
- _minor, _use_exclusive_proxy);
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) {
+ routing_manager_base::request_service(_client,
+ _service, _instance, _major, _minor);
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name());
- service_data_t request = { _service, _instance, _major, _minor, _use_exclusive_proxy };
+ service_data_t request = { _service, _instance, _major, _minor };
if (!request_debouncing_time) {
if (state_ == inner_state_type_e::ST_REGISTERED) {
std::set<service_data_t> requests;
@@ -325,10 +319,11 @@ void routing_manager_proxy::release_service(client_t _client,
void routing_manager_proxy::register_event(client_t _client,
service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups,
- bool _is_field,
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups, const event_type_e _type,
+ reliability_type_e _reliability,
std::chrono::milliseconds _cycle, bool _change_resets_cycle,
- epsilon_change_func_t _epsilon_change_func,
+ bool _update_on_change, epsilon_change_func_t _epsilon_change_func,
bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) {
(void)_is_shadow;
(void)_is_cache_placeholder;
@@ -336,8 +331,9 @@ void routing_manager_proxy::register_event(client_t _client,
const event_data_t registration = {
_service,
_instance,
- _event,
- _is_field,
+ _notifier,
+ _type,
+ _reliability,
_is_provided,
_eventgroups
};
@@ -351,36 +347,29 @@ void routing_manager_proxy::register_event(client_t _client,
}
}
if (is_first || _is_provided) {
- routing_manager_base::register_event(_client, _service, _instance,
- _event,_eventgroups, _is_field,
- _cycle, _change_resets_cycle,
- _epsilon_change_func,
- _is_provided);
+ routing_manager_base::register_event(_client,
+ _service, _instance,
+ _notifier,
+ _eventgroups, _type, _reliability,
+ _cycle, _change_resets_cycle, _update_on_change,
+ _epsilon_change_func,
+ _is_provided);
}
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
if (state_ == inner_state_type_e::ST_REGISTERED && is_first) {
send_register_event(client_, _service, _instance,
- _event, _eventgroups, _is_field, _is_provided);
+ _notifier, _eventgroups, _type, _reliability, _is_provided);
}
}
-
- if(_is_provided) {
- VSOMEIP_INFO << "REGISTER EVENT("
- << std::hex << std::setw(4) << std::setfill('0') << _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') << _event
- << ":is_provider=" << _is_provided << "]";
- }
}
void routing_manager_proxy::unregister_event(client_t _client,
- service_t _service, instance_t _instance, event_t _event,
+ service_t _service, instance_t _instance, event_t _notifier,
bool _is_provided) {
routing_manager_base::unregister_event(_client, _service, _instance,
- _event, _is_provided);
+ _notifier, _is_provided);
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
@@ -398,8 +387,8 @@ void routing_manager_proxy::unregister_event(client_t _client,
sizeof(_service));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_event,
- sizeof(_event));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier,
+ sizeof(_notifier));
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6]
= static_cast<byte_t>(_is_provided);
@@ -414,7 +403,7 @@ void routing_manager_proxy::unregister_event(client_t _client,
while (it != pending_event_registrations_.end()) {
if (it->service_ == _service
&& it->instance_ == _instance
- && it->event_ == _event) {
+ && it->notifier_ == _notifier) {
break;
}
it++;
@@ -433,12 +422,15 @@ bool routing_manager_proxy::is_field(service_t _service, instance_t _instance,
return false;
}
-void routing_manager_proxy::subscribe(client_t _client, service_t _service,
+void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, subscription_type_e _subscription_type) {
+ event_t _event) {
+ (void)_uid;
+ (void)_gid;
{
+ credentials_t its_credentials = std::make_pair(own_uid_, own_gid_);
if (_event == ANY_EVENT) {
- if (!is_subscribe_to_any_event_allowed(_client, _service, _instance, _eventgroup)) {
+ if (!is_subscribe_to_any_event_allowed(its_credentials, _client, _service, _instance, _eventgroup)) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client
<< " : routing_manager_proxy::subscribe: "
<< " isn't allowed to subscribe to service/instance/event "
@@ -447,8 +439,11 @@ void routing_manager_proxy::subscribe(client_t _client, service_t _service,
return;
}
} else {
- if (!configuration_->is_client_allowed(_client, _service,
- _instance, _event)) {
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
+ if (!its_security->is_client_allowed(own_uid_, own_gid_,
+ _client, _service, _instance, _event)) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client
<< " : routing_manager_proxy::subscribe: "
<< " isn't allowed to subscribe to service/instance/event "
@@ -460,18 +455,16 @@ void routing_manager_proxy::subscribe(client_t _client, service_t _service,
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, _subscription_type);
+ send_subscribe(_client, _service, _instance, _eventgroup, _major, _event );
}
- subscription_data_t subscription = { _service, _instance, _eventgroup, _major,
- _event, _subscription_type};
+ subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid};
pending_subscriptions_.insert(subscription);
}
}
void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, subscription_type_e _subscription_type) {
+ event_t _event) {
(void)_client;
byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
@@ -492,14 +485,12 @@ void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event,
sizeof(_event));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_subscription_type,
- sizeof(_subscription_type));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &DEFAULT_SUBSCRIPTION,
- sizeof(DEFAULT_SUBSCRIPTION)); // local subscription
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
+ &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
client_t target_client = find_local_client(_service, _instance);
if (target_client != VSOMEIP_ROUTING_CLIENT) {
- auto its_target = find_or_create_local(target_client);
+ auto its_target = ep_mgr_->find_or_create_local(target_client);
its_target->send(its_command, sizeof(its_command));
} else {
std::lock_guard<std::mutex> its_lock(sender_mutex_);
@@ -511,7 +502,7 @@ void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
void routing_manager_proxy::send_subscribe_nack(client_t _subscriber,
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, pending_subscription_id_t _subscription_id) {
+ event_t _event, remote_subscription_id_t _id) {
byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE;
@@ -532,12 +523,12 @@ void routing_manager_proxy::send_subscribe_nack(client_t _subscriber,
sizeof(_subscriber));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
sizeof(_event));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
- &_subscription_id, sizeof(_subscription_id));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id,
+ sizeof(_id));
if (_subscriber != VSOMEIP_ROUTING_CLIENT
- && _subscription_id == DEFAULT_SUBSCRIPTION) {
- auto its_target = find_local(_subscriber);
+ && _id == PENDING_SUBSCRIPTION_ID) {
+ auto its_target = ep_mgr_->find_local(_subscriber);
if (its_target) {
its_target->send(its_command, sizeof(its_command));
return;
@@ -553,7 +544,7 @@ void routing_manager_proxy::send_subscribe_nack(client_t _subscriber,
void routing_manager_proxy::send_subscribe_ack(client_t _subscriber,
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, pending_subscription_id_t _subscription_id) {
+ event_t _event, remote_subscription_id_t _id) {
byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE;
@@ -574,12 +565,12 @@ void routing_manager_proxy::send_subscribe_ack(client_t _subscriber,
sizeof(_subscriber));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
sizeof(_event));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
- &_subscription_id, sizeof(_subscription_id));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id,
+ sizeof(_id));
if (_subscriber != VSOMEIP_ROUTING_CLIENT
- && _subscription_id == DEFAULT_SUBSCRIPTION) {
- auto its_target = find_local(_subscriber);
+ && _id == PENDING_SUBSCRIPTION_ID) {
+ auto its_target = ep_mgr_->find_local(_subscriber);
if (its_target) {
its_target->send(its_command, sizeof(its_command));
return;
@@ -593,9 +584,11 @@ void routing_manager_proxy::send_subscribe_ack(client_t _subscriber,
}
}
-void routing_manager_proxy::unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
+void routing_manager_proxy::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
(void)_client;
+ (void)_uid;
+ (void)_gid;
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
remove_pending_subscription(_service, _instance, _eventgroup, _event);
@@ -618,10 +611,10 @@ void routing_manager_proxy::unsubscribe(client_t _client, service_t _service,
sizeof(_eventgroup));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event,
sizeof(_event));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &DEFAULT_SUBSCRIPTION,
- sizeof(DEFAULT_SUBSCRIPTION)); // is_local
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
+ &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
- auto its_target = find_local(_service, _instance);
+ auto its_target = ep_mgr_->find_local(_service, _instance);
if (its_target) {
its_target->send(its_command, sizeof(its_command));
} else {
@@ -636,13 +629,14 @@ void routing_manager_proxy::unsubscribe(client_t _client, service_t _service,
bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
length_t _size, instance_t _instance,
- bool _flush,
bool _reliable,
client_t _bound_client,
- bool _is_valid_crc,
+ credentials_t _credentials,
+ uint8_t _status_check,
bool _sent_from_remote) {
(void)_client;
(void)_bound_client;
+ (void)_credentials;
(void)_sent_from_remote;
bool is_sent(false);
bool has_remote_subscribers(false);
@@ -695,7 +689,7 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
client_t its_client = find_local_client(its_service, _instance);
if (its_client != VSOMEIP_ROUTING_CLIENT) {
if (is_client_known(its_client)) {
- its_target = find_or_create_local(its_client);
+ its_target = ep_mgr_->find_or_create_local(its_client);
}
}
} else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
@@ -705,18 +699,18 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
_data[VSOMEIP_CLIENT_POS_MAX]);
if (its_client != VSOMEIP_ROUTING_CLIENT) {
if (is_client_known(its_client)) {
- its_target = find_or_create_local(its_client);
+ its_target = ep_mgr_->find_or_create_local(its_client);
}
}
} else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
_client == VSOMEIP_ROUTING_CLIENT) {
// notify
has_remote_subscribers = send_local_notification(get_client(), _data, _size,
- _instance, _flush, _reliable, _is_valid_crc);
+ _instance, _reliable, _status_check);
} else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
_client != VSOMEIP_ROUTING_CLIENT) {
// notify_one
- its_target = find_local(_client);
+ its_target = ep_mgr_->find_local(_client);
if (its_target) {
#ifdef USE_DLT
const uint16_t its_data_size
@@ -728,7 +722,7 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
_data, its_data_size);
#endif
return send_local(its_target, get_client(), _data, _size,
- _instance, _flush, _reliable, VSOMEIP_SEND, _is_valid_crc);
+ _instance, _reliable, VSOMEIP_SEND, _status_check);
}
}
// If no direct endpoint could be found
@@ -775,35 +769,32 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
if (send) {
is_sent = send_local(its_target,
(command == VSOMEIP_NOTIFY_ONE ? _client : get_client()),
- _data, _size, _instance, _flush, _reliable, command, _is_valid_crc);
+ _data, _size, _instance, _reliable, command, _status_check);
}
}
return (is_sent);
}
-bool routing_manager_proxy::send_to(
+bool routing_manager_proxy::send_to(const client_t _client,
const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message,
- bool _flush) {
+ std::shared_ptr<message> _message) {
+ (void)_client;
(void)_target;
(void)_message;
- (void)_flush;
return (false);
}
bool routing_manager_proxy::send_to(
const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size, instance_t _instance,
- bool _flush) {
+ const byte_t *_data, uint32_t _size, instance_t _instance) {
(void)_target;
(void)_data;
(void)_size;
(void)_instance;
- (void)_flush;
return (false);
}
-void routing_manager_proxy::on_connect(std::shared_ptr<endpoint> _endpoint) {
+void routing_manager_proxy::on_connect(const std::shared_ptr<endpoint>& _endpoint) {
_endpoint->set_connected(true);
_endpoint->set_established(true);
{
@@ -813,14 +804,10 @@ void routing_manager_proxy::on_connect(std::shared_ptr<endpoint> _endpoint) {
}
}
is_connected_ = true;
- if (is_connected_ && is_started_) {
- VSOMEIP_INFO << std::hex << "Client " << client_
- << " successfully connected to routing ~> registering..";
- register_application();
- }
+ assign_client();
}
-void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
+void routing_manager_proxy::on_disconnect(const std::shared_ptr<endpoint>& _endpoint) {
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
is_connected_ = !(_endpoint == sender_);
@@ -833,29 +820,10 @@ void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
}
}
-void routing_manager_proxy::on_error(
- const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port) {
-
- // Implement me when needed
-
- (void)(_data);
- (void)(_length);
- (void)(_receiver);
- (void)(_remote_address);
- (void)(_remote_port);
-}
-
-void routing_manager_proxy::release_port(uint16_t _port, bool _reliable) {
- (void)_port;
- (void)_reliable;
- // intentionally empty
-}
-
void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
client_t _bound_client,
+ credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port) {
(void)_receiver;
@@ -879,10 +847,16 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
major_version_t its_major;
client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host());
client_t its_subscriber;
- bool its_reliable;
- pending_subscription_id_t its_subscription_id(DEFAULT_SUBSCRIPTION);
+ remote_subscription_id_t its_subscription_id(PENDING_SUBSCRIPTION_ID);
std::uint32_t its_remote_subscriber_count(0);
+ std::uint32_t its_sender_uid = std::get<0>(_credentials);
+ std::uint32_t its_sender_gid = std::get<1>(_credentials);
+
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
+
if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) {
its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
@@ -891,7 +865,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(its_length));
bool message_from_routing(false);
- if (configuration_->is_security_enabled()) {
+ if (its_security->is_enabled()) {
// if security is enabled, client ID of routing must be configured
// and credential passing is active. Otherwise bound client is zero by default
message_from_routing = (_bound_client == routing_host_id);
@@ -899,7 +873,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
message_from_routing = (its_client == routing_host_id);
}
- if (configuration_->is_security_enabled() && !message_from_routing &&
+ if (its_security->is_enabled() && !message_from_routing &&
_bound_client != its_client) {
VSOMEIP_WARNING << std::hex << "Client " << std::setw(4) << std::setfill('0') << get_client()
<< " received a message with command " << (uint32_t)its_command
@@ -918,13 +892,13 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
}
instance_t its_instance;
bool its_reliable;
- bool its_is_valid_crc;
+ uint8_t its_check_status;
std::memcpy(&its_instance,&_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
sizeof(instance_t));
std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
sizeof(its_reliable));
- std::memcpy(&its_is_valid_crc, &_data[VSOMEIP_SEND_COMMAND_VALID_CRC_POS],
- sizeof(its_is_valid_crc));
+ std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
+ sizeof(its_check_status));
// reduce by size of instance, flush, reliable, client and is_valid_crc flag
const std::uint32_t its_message_size = its_length -
@@ -943,14 +917,17 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
auto a_deserializer = get_deserializer();
a_deserializer->set_data(&_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS],
its_message_size);
- std::shared_ptr<message> its_message(a_deserializer->deserialize_message());
+ std::shared_ptr<message_impl> its_message(a_deserializer->deserialize_message());
a_deserializer->reset();
put_deserializer(a_deserializer);
if (its_message) {
its_message->set_instance(its_instance);
its_message->set_reliable(its_reliable);
- its_message->set_is_valid_crc(its_is_valid_crc);
+ its_message->set_check_result(its_check_status);
+ its_message->set_uid(std::get<0>(_credentials));
+ its_message->set_gid(std::get<1>(_credentials));
+
if (!message_from_routing) {
if (utility::is_notification(its_message->get_message_type())) {
if (!is_response_allowed(_bound_client, its_message->get_service(),
@@ -964,7 +941,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
<< " ~> Skip message!";
return;
} else {
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
+ if (!its_security->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_proxy::on_message: "
@@ -978,7 +956,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
cache_event_payload(its_message);
}
} else if (utility::is_request(its_message->get_message_type())) {
- if (configuration_->is_security_enabled()
+ if (its_security->is_enabled()
&& its_message->get_client() != _bound_client) {
VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client()
<< " received a request from client 0x" << std::setw(4) << std::setfill('0')
@@ -990,8 +968,9 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
return;
}
- if (!configuration_->is_client_allowed(its_message->get_client(),
- its_message->get_service(), its_message->get_instance(), its_message->get_method())) {
+ if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_message->get_client(), its_message->get_service(),
+ its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client()
<< " : routing_manager_proxy::on_message: "
<< "isn't allowed to send a request to service/instance/method "
@@ -1012,7 +991,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
<< " ~> Skip message!";
return;
} else {
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
+ if (!its_security->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_proxy::on_message: "
@@ -1026,7 +1006,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
}
}
} else {
- if (!configuration_->is_remote_client_allowed()) {
+ if (!its_security->is_remote_client_allowed()) {
// if the message is from routing manager, check if
// policy allows remote requests.
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
@@ -1042,7 +1022,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
// As subscription is sent on eventgroup level, incoming remote event ID's
// need to be checked as well if remote clients are allowed
// and the local policy only allows specific events in the eventgroup to be received.
- if (!configuration_->is_client_allowed(get_client(), its_message->get_service(),
+ if (!its_security->is_client_allowed(own_uid_, own_gid_,
+ get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_proxy::on_message: "
@@ -1068,6 +1049,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
static_cast<std::uint16_t>(its_message_size));
}
#endif
+
host_->on_message(std::move(its_message));
} else {
VSOMEIP_ERROR << "Routing proxy: on_message: "
@@ -1076,12 +1058,23 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
break;
}
+ case VSOMEIP_ASSIGN_CLIENT_ACK: {
+ if (_size != VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE) {
+ VSOMEIP_WARNING << "Received a VSOMEIP_ASSIGN_CLIENT_ACK command with wrong size ~> skip!";
+ break;
+ }
+ client_t its_assigned_client(VSOMEIP_CLIENT_UNSET);
+ std::memcpy(&its_assigned_client,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS], sizeof(client_));
+ on_client_assign_ack(its_assigned_client);
+ break;
+ }
case VSOMEIP_ROUTING_INFO:
if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
VSOMEIP_WARNING << "Received a ROUTING_INFO command with invalid size -> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
} else {
VSOMEIP_WARNING << "routing_manager_proxy::on_message: "
@@ -1116,18 +1109,20 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(its_major));
std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
sizeof(its_event));
- std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
+ std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
sizeof(its_subscription_id));
{
std::unique_lock<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
- if (its_subscription_id != DEFAULT_SUBSCRIPTION) {
+ if (its_subscription_id != PENDING_SUBSCRIPTION_ID) {
its_lock.unlock();
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::set_incoming_subscription_state(its_client, its_service,
its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING);
+#endif
// Remote subscriber: Notify routing manager initially + count subscribes
auto self = shared_from_this();
host_->on_subscription(its_service, its_instance, its_eventgroup,
- its_client, true,
+ its_client, its_sender_uid, its_sender_gid, true,
[this, self, its_client, its_service, its_instance,
its_eventgroup, its_event, its_subscription_id, its_major]
(const bool _subscription_accepted){
@@ -1145,8 +1140,9 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
notify_remote_initially(its_service, its_instance, its_eventgroup,
its_already_subscribed_events);
}
+#ifdef VSOMEIP_ENABLE_COMPAT
send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true);
-
+#endif
std::uint32_t its_count = get_remote_subscriber_count(
its_service, its_instance, its_eventgroup, true);
VSOMEIP_INFO << "SUBSCRIBE("
@@ -1156,17 +1152,18 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
<< std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":"
<< std::hex << std::setw(4) << std::setfill('0') << its_event << ":"
<< std::dec << (uint16_t)its_major << "]"
- << (bool)(its_subscription_id != DEFAULT_SUBSCRIPTION) << " "
+ << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " "
<< std::dec << its_count;
-
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::erase_incoming_subscription_state(its_client, its_service,
its_instance, its_eventgroup, its_event);
+#endif
});
} else if (is_client_known(its_client)) {
its_lock.unlock();
if (!message_from_routing) {
if (its_event == ANY_EVENT) {
- if (!is_subscribe_to_any_event_allowed(its_client, its_service, its_instance, its_eventgroup)) {
+ if (!is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, its_instance, its_eventgroup)) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
<< " : routing_manager_proxy::on_message: "
<< " isn't allowed to subscribe to service/instance/event "
@@ -1175,8 +1172,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
return;
}
} else {
- if (!configuration_->is_client_allowed(its_client,
- its_service, its_instance, its_event)) {
+ if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_client, its_service, its_instance, its_event)) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
<< " : routing_manager_proxy::on_message: "
<< " subscribes to service/instance/event "
@@ -1186,7 +1183,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
}
}
} else {
- if (!configuration_->is_remote_client_allowed()) {
+ if (!its_security->is_remote_client_allowed()) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
<< " : routing_manager_proxy::on_message: "
<< std::hex << "Routing manager with client ID 0x"
@@ -1201,38 +1198,42 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
}
// Local & already known subscriber: create endpoint + send (N)ACK + insert subscription
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::set_incoming_subscription_state(its_client, its_service,
its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING);
- (void) find_or_create_local(its_client);
+#endif
+ (void) ep_mgr_->find_or_create_local(its_client);
auto self = shared_from_this();
host_->on_subscription(its_service, its_instance,
- its_eventgroup, its_client, true,
- [this, self, its_client, its_service, its_instance, its_eventgroup,
- its_event, its_major]
+ its_eventgroup, its_client, its_sender_uid, its_sender_gid, true,
+ [this, self, its_client, its_sender_uid, its_sender_gid, its_service,
+ its_instance, its_eventgroup, its_event, its_major]
(const bool _subscription_accepted) {
if (!_subscription_accepted) {
- send_subscribe_nack(its_client, its_service,
- its_instance, its_eventgroup, its_event, DEFAULT_SUBSCRIPTION);
+ send_subscribe_nack(its_client, its_service, its_instance,
+ its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID);
} else {
send_subscribe_ack(its_client, its_service, its_instance,
- its_eventgroup, its_event, DEFAULT_SUBSCRIPTION);
- routing_manager_base::subscribe(its_client, its_service, its_instance,
- its_eventgroup, its_major, its_event,
- subscription_type_e::SU_RELIABLE_AND_UNRELIABLE);
+ its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID);
+ routing_manager_base::subscribe(its_client, its_sender_uid, its_sender_gid,
+ its_service, its_instance, its_eventgroup, its_major, its_event);
+#ifdef VSOMEIP_ENABLE_COMPAT
send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client);
+#endif
}
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::erase_incoming_subscription_state(its_client, its_service,
its_instance, its_eventgroup, its_event);
+#endif
});
} else {
// Local & not yet known subscriber ~> set pending until subscriber gets known!
subscription_data_t subscription = { its_service, its_instance,
- its_eventgroup, its_major, its_event,
- subscription_type_e::SU_RELIABLE_AND_UNRELIABLE};
+ its_eventgroup, its_major, its_event, its_sender_uid, its_sender_gid };
pending_incoming_subscripitons_[its_client].insert(subscription);
}
}
- if (its_subscription_id == DEFAULT_SUBSCRIPTION) { // local subscription
+ if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { // local subscription
VSOMEIP_INFO << "SUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
@@ -1258,16 +1259,16 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(its_event));
std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
sizeof(its_subscription_id));
- host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
- if (its_subscription_id == DEFAULT_SUBSCRIPTION) {
+ host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; });
+ if (its_subscription_id == PENDING_SUBSCRIPTION_ID) {
// Local subscriber: withdraw subscription
- routing_manager_base::unsubscribe(its_client, its_service, its_instance, its_eventgroup, its_event);
+ routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event);
} else {
// Remote subscriber: withdraw subscription only if no more remote subscriber exists
its_remote_subscriber_count = get_remote_subscriber_count(its_service,
its_instance, its_eventgroup, false);
if (!its_remote_subscriber_count) {
- routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, its_service,
+ routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service,
its_instance, its_eventgroup, its_event);
}
send_unsubscribe_ack(its_service, its_instance, its_eventgroup,
@@ -1279,7 +1280,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_event << "] "
- << (bool)(its_subscription_id != DEFAULT_SUBSCRIPTION) << " "
+ << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " "
<< std::dec << its_remote_subscriber_count;
break;
@@ -1333,30 +1334,12 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
<< std::hex << std::setw(4) << std::setfill('0') << its_event << "]";
break;
- case VSOMEIP_ID_REQUEST:
- if (_size < VSOMEIP_ID_REQUEST_COMMAND_SIZE) {
- VSOMEIP_WARNING << "Received a VSOMEIP_ID_REQUEST command with wrong size ~> skip!";
- break;
- }
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_major));
- std::memcpy(&its_reliable, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
- sizeof(its_reliable));
-
- send_identify_request(its_service, its_instance, its_major, its_reliable);
-
- break;
-
case VSOMEIP_OFFERED_SERVICES_RESPONSE:
if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) {
VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_RESPONSE command with invalid size -> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
on_offered_services_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
} else {
VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client()
@@ -1385,7 +1368,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY command with wrong size -> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
pending_security_update_id_t its_update_id(0);
uint32_t its_uid(0);
uint32_t its_gid(0);
@@ -1399,10 +1382,10 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
uint32_t its_size = uint32_t(_size - (VSOMEIP_COMMAND_PAYLOAD_POS
+ sizeof(pending_security_update_id_t)));
- utility::parse_policy(buffer_ptr, its_size, its_uid, its_gid, its_policy);
+ its_security->parse_policy(buffer_ptr, its_size, its_uid, its_gid, its_policy);
- if (configuration_->is_policy_update_allowed(its_uid, its_policy)) {
- configuration_->update_security_policy(its_uid, its_gid, its_policy);
+ if (its_security->is_policy_update_allowed(its_uid, its_policy)) {
+ its_security->update_security_policy(its_uid, its_gid, its_policy);
send_update_security_policy_response(its_update_id);
}
} else {
@@ -1418,10 +1401,10 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY command with wrong size ~> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
pending_security_update_id_t its_update_id(0);
- uint32_t its_uid(0xffffffff);
- uint32_t its_gid(0xffffffff);
+ uint32_t its_uid(ANY_UID);
+ uint32_t its_gid(ANY_GID);
std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(pending_security_update_id_t));
@@ -1429,8 +1412,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(uint32_t));
std::memcpy(&its_gid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
sizeof(uint32_t));
- if (configuration_->is_policy_removal_allowed(its_uid)) {
- configuration_->remove_security_policy(its_uid, its_gid);
+ if (its_security->is_policy_removal_allowed(its_uid)) {
+ its_security->remove_security_policy(its_uid, its_gid);
send_remove_security_policy_response(its_update_id);
}
} else {
@@ -1447,7 +1430,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_DISTRIBUTE_SECURITY_POLICIES command with wrong size -> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
uint32_t its_policy_count(0);
uint32_t its_policy_size(0);
const byte_t* buffer_ptr = 0;
@@ -1471,9 +1454,9 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
buffer_ptr += sizeof(uint32_t);
if (buffer_ptr + its_policy_size <= _data + _size) {
- if (utility::parse_policy(buffer_ptr, its_policy_size, its_uid, its_gid, its_policy)) {
- if (configuration_->is_policy_update_allowed(its_uid, its_policy)) {
- configuration_->update_security_policy(its_uid, its_gid, its_policy);
+ if (its_security->parse_policy(buffer_ptr, its_policy_size, its_uid, its_gid, its_policy)) {
+ if (its_security->is_policy_update_allowed(its_uid, its_policy)) {
+ its_security->update_security_policy(its_uid, its_gid, its_policy);
}
} else {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " could not parse policy!";
@@ -1496,7 +1479,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_CREDENTIALS command with wrong size -> skip!";
break;
}
- if (!configuration_->is_security_enabled() || message_from_routing) {
+ if (!its_security->is_enabled() || message_from_routing) {
on_update_security_credentials(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
} else {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client()
@@ -1521,6 +1504,9 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
VSOMEIP_INFO << msg.str();
#endif
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
uint32_t i = 0;
while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) {
@@ -1550,10 +1536,10 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
}
if (its_client == get_client()) {
VSOMEIP_INFO << std::hex << "Application/Client " << get_client()
- << " is registered.";
+ << " (" << host_->get_name() << ") is registered.";
#ifndef _WIN32
- if (!check_credentials(get_client(), getuid(), getgid())) {
+ if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) {
VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_proxy::on_routing_info: RIE_ADD_CLIENT: isn't allowed"
<< " to use the server endpoint due to credential check failed!";
@@ -1583,9 +1569,9 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
known_clients_.erase(its_client);
}
if (its_client == get_client()) {
- configuration_->remove_client_to_uid_gid_mapping(its_client);
+ its_security->remove_client_to_uid_gid_mapping(its_client);
VSOMEIP_INFO << std::hex << "Application/Client " << get_client()
- << " is deregistered.";
+ << " (" << host_->get_name() << ") is deregistered.";
// inform host about its own registration state changes
host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
@@ -1684,6 +1670,8 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
client_t client_id_;
major_version_t major_;
event_t event_;
+ uid_t uid_;
+ gid_t gid_;
};
std::lock_guard<std::recursive_mutex> its_lock(incoming_subscriptions_mutex_);
std::forward_list<struct subscription_info> subscription_actions;
@@ -1697,35 +1685,41 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
subscription_actions.push_front(
{ subscription.service_, subscription.instance_,
subscription.eventgroup_, client,
- subscription.major_, subscription.event_ });
+ subscription.major_, subscription.event_,
+ subscription.uid_, subscription.gid_ });
}
}
}
}
for (const subscription_info &si : subscription_actions) {
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_,
si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING);
- (void) find_or_create_local(si.client_id_);
+#endif
+ (void) ep_mgr_->find_or_create_local(si.client_id_);
auto self = shared_from_this();
host_->on_subscription(
si.service_id_, si.instance_id_, si.eventgroup_id_,
- si.client_id_, true,
+ si.client_id_, si.uid_, si.gid_, true,
[this, self, si](const bool _subscription_accepted) {
if (!_subscription_accepted) {
send_subscribe_nack(si.client_id_, si.service_id_,
- si.instance_id_, si.eventgroup_id_, si.event_, DEFAULT_SUBSCRIPTION);
+ si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID);
} else {
- routing_manager_base::subscribe(si.client_id_,
+ routing_manager_base::subscribe(si.client_id_, si.uid_, si.gid_,
si.service_id_, si.instance_id_, si.eventgroup_id_,
- si.major_, si.event_,
- subscription_type_e::SU_RELIABLE_AND_UNRELIABLE);
+ si.major_, si.event_);
send_subscribe_ack(si.client_id_, si.service_id_,
- si.instance_id_, si.eventgroup_id_, si.event_, DEFAULT_SUBSCRIPTION);
+ si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID);
+#ifdef VSOMEIP_ENABLE_COMPAT
send_pending_notify_ones(si.service_id_,
si.instance_id_, si.eventgroup_id_, si.client_id_);
+#endif
}
+#ifdef VSOMEIP_ENABLE_COMPAT
routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_,
si.instance_id_, si.eventgroup_id_, si.event_);
+#endif
{
std::lock_guard<std::recursive_mutex> its_lock2(incoming_subscriptions_mutex_);
pending_incoming_subscripitons_.erase(si.client_id_);
@@ -1788,6 +1782,10 @@ void routing_manager_proxy::on_offered_services_info(const byte_t *_data,
}
void routing_manager_proxy::reconnect(const std::unordered_set<client_t> &_clients) {
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
+
// inform host about its own registration state changes
host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED));
@@ -1810,7 +1808,7 @@ void routing_manager_proxy::reconnect(const std::unordered_set<client_t> &_clien
<<": Reconnecting to routing manager.";
#ifndef _WIN32
- if (!check_credentials(get_client(), getuid(), getgid())) {
+ if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) {
VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_proxy::reconnect: isn't allowed"
<< " to use the server endpoint due to credential check failed!";
@@ -1828,6 +1826,44 @@ void routing_manager_proxy::reconnect(const std::unordered_set<client_t> &_clien
}
}
+void routing_manager_proxy::assign_client() {
+ std::vector<byte_t> its_command;
+
+ std::string its_name(host_->get_name());
+ uint32_t its_size(static_cast<uint32_t>(its_name.size()));
+ its_command.resize(7 + its_name.size());
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ASSIGN_CLIENT;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ if (0 < its_name.size())
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], its_name.c_str(),
+ its_name.size());
+
+ std::lock_guard<std::mutex> its_state_lock(state_mutex_);
+ if (is_connected_) {
+ std::lock_guard<std::mutex> its_lock(sender_mutex_);
+ if (sender_) {
+ if (state_ != inner_state_type_e::ST_DEREGISTERED)
+ return;
+ state_ = inner_state_type_e::ST_ASSIGNING;
+
+ sender_->send(&its_command[0], static_cast<uint32_t>(its_command.size()));
+
+ boost::system::error_code ec;
+ register_application_timer_.cancel(ec);
+ register_application_timer_.expires_from_now(std::chrono::milliseconds(10000));
+ register_application_timer_.async_wait(
+ std::bind(
+ &routing_manager_proxy::assign_client_timeout_cbk,
+ std::dynamic_pointer_cast<routing_manager_proxy>(shared_from_this()),
+ std::placeholders::_1));
+ }
+ }
+}
+
void routing_manager_proxy::register_application() {
byte_t its_command[] = {
VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -1836,12 +1872,9 @@ void routing_manager_proxy::register_application() {
sizeof(client_));
if (is_connected_) {
- std::lock_guard<std::mutex> its_state_lock(state_mutex_);
std::lock_guard<std::mutex> its_lock(sender_mutex_);
if (sender_) {
- {
- state_ = inner_state_type_e::ST_REGISTERING;
- }
+ state_ = inner_state_type_e::ST_REGISTERING;
sender_->send(its_command, sizeof(its_command));
register_application_timer_.cancel();
@@ -1898,32 +1931,31 @@ void routing_manager_proxy::send_request_services(std::set<service_data_t>& _req
std::vector<byte_t> its_command(its_size + VSOMEIP_COMMAND_HEADER_SIZE);
its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(std::uint32_t));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS],
+ &client_, sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN],
+ &its_size, sizeof(std::uint32_t));
- uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t)
- + sizeof(minor_version_t) + sizeof(bool));
+ uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t)
+ + sizeof(major_version_t) + sizeof(minor_version_t));
- int i = 0;
+ unsigned int i = 0;
for (auto its_service : _requests) {
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], &its_service.service_,
- sizeof(its_service.service_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], &its_service.instance_,
- sizeof(its_service.instance_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)],
+ &its_service.service_, sizeof(its_service.service_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)],
+ &its_service.instance_, sizeof(its_service.instance_));
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)] = its_service.major_;
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], &its_service.minor_,
- sizeof(its_service.minor_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9 + (i * entry_size)], &its_service.use_exclusive_proxy_,
- sizeof(its_service.use_exclusive_proxy_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)],
+ &its_service.minor_, sizeof(its_service.minor_));
++i;
}
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
if (sender_) {
- sender_->send(&its_command[0], static_cast<std::uint32_t>(its_size + VSOMEIP_COMMAND_HEADER_SIZE));
+ sender_->send(&its_command[0],
+ static_cast<std::uint32_t>(its_size + VSOMEIP_COMMAND_HEADER_SIZE));
}
}
}
@@ -1955,8 +1987,10 @@ void routing_manager_proxy::send_release_service(client_t _client, service_t _se
void routing_manager_proxy::send_register_event(client_t _client,
service_t _service, instance_t _instance,
- event_t _event, const std::set<eventgroup_t> &_eventgroups,
- bool _is_field, bool _is_provided) {
+ event_t _notifier,
+ const std::set<eventgroup_t> &_eventgroups, const event_type_e _type,
+ reliability_type_e _reliability,
+ bool _is_provided) {
std::size_t its_eventgroups_size = (_eventgroups.size() * sizeof(eventgroup_t)) +
VSOMEIP_REGISTER_EVENT_COMMAND_SIZE;
@@ -1978,14 +2012,16 @@ void routing_manager_proxy::send_register_event(client_t _client,
sizeof(_service));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_event,
- sizeof(_event));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier,
+ sizeof(_notifier));
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6]
- = static_cast<byte_t>(_is_field);
+ = static_cast<byte_t>(_type);
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7]
= static_cast<byte_t>(_is_provided);
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8]
+ = static_cast<byte_t>(_reliability);
- std::size_t i = 8;
+ std::size_t i = 9;
for (auto eg : _eventgroups) {
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + i], &eg,
sizeof(eventgroup_t));
@@ -1999,22 +2035,38 @@ void routing_manager_proxy::send_register_event(client_t _client,
}
}
+ if (_is_provided) {
+ VSOMEIP_INFO << "REGISTER EVENT("
+ << std::hex << std::setw(4) << std::setfill('0') << 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 << "]";
+ }
+
delete[] its_command;
}
void routing_manager_proxy::on_subscribe_ack(client_t _client,
service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) {
(void)_client;
+#if 0
+ VSOMEIP_ERROR << "routing_manager_proxy::" << __func__
+ << "(" << std::hex << host_->get_client() << "):"
+ << "event="
+ << std::hex << _service << "."
+ << std::hex << _instance << "."
+ << std::hex << _eventgroup << "."
+ << std::hex << _event;
+#endif
if (_event == ANY_EVENT) {
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- for (auto its_event : its_eventgroup->get_events()) {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x0 /*OK*/);
+ for (const auto& its_event : its_eventgroup->get_events()) {
host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/);
}
}
} else {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x0 /*OK*/);
host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/);
}
}
@@ -2025,41 +2077,15 @@ void routing_manager_proxy::on_subscribe_nack(client_t _client,
if (_event == ANY_EVENT) {
auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- for (auto its_event : its_eventgroup->get_events()) {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x7 /*Rejected*/);
+ for (const auto& its_event : its_eventgroup->get_events()) {
host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/);
}
}
} else {
- host_->on_subscription_error(_service, _instance, _eventgroup, 0x7 /*Rejected*/);
host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/);
}
}
-void routing_manager_proxy::on_identify_response(client_t _client, service_t _service,
- instance_t _instance, bool _reliable) {
- static const uint32_t size = VSOMEIP_ID_RESPONSE_COMMAND_SIZE;
- byte_t its_command[size];
- uint32_t its_size = size - VSOMEIP_COMMAND_HEADER_SIZE;
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ID_RESPONSE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
- sizeof(_client));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_reliable,
- sizeof(_reliable));
- {
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- if (sender_) {
- sender_->send(its_command, size);
- }
- }
-}
-
void routing_manager_proxy::cache_event_payload(
const std::shared_ptr<message> &_message) {
const service_t its_service(_message->get_service());
@@ -2075,9 +2101,12 @@ void routing_manager_proxy::cache_event_payload(
std::set<eventgroup_t> its_eventgroups;
// create a placeholder field until someone requests this event with
// full information like eventgroup, field or not etc.
- routing_manager_base::register_event(host_->get_client(), its_service,
- its_instance, its_method, its_eventgroups, true,
- std::chrono::milliseconds::zero(), false,
+ routing_manager_base::register_event(host_->get_client(),
+ its_service, its_instance,
+ its_method,
+ its_eventgroups, event_type_e::ET_UNKNOWN,
+ reliability_type_e::RT_UNKNOWN,
+ std::chrono::milliseconds::zero(), false, true,
nullptr,
false, false, true);
std::shared_ptr<event> its_event = find_event(its_service, its_instance, its_method);
@@ -2113,52 +2142,30 @@ void routing_manager_proxy::on_stop_offer_service(service_t _service,
void routing_manager_proxy::send_pending_commands() {
for (auto &po : pending_offers_)
- send_offer_service(client_, po.service_, po.instance_,
+ send_offer_service(client_,
+ po.service_, po.instance_,
po.major_, po.minor_);
for (auto &per : pending_event_registrations_)
- send_register_event(client_, per.service_, per.instance_,
- per.event_, per.eventgroups_,
- per.is_field_, per.is_provided_);
+ send_register_event(client_,
+ per.service_, per.instance_,
+ per.notifier_,
+ per.eventgroups_, per.type_, per.reliability_,
+ per.is_provided_);
send_request_services(requests_);
}
void routing_manager_proxy::init_receiver() {
- std::stringstream its_client;
- its_client << utility::get_base_path(configuration_) << std::hex << client_;
-#ifdef _WIN32
- ::_unlink(its_client.str().c_str());
- int port = VSOMEIP_INTERNAL_BASE_PORT + client_;
-#else
- configuration_->store_client_to_uid_gid_mapping(get_client(), getuid(), getgid());
- configuration_->store_uid_gid_to_client_mapping(getuid(), getgid(), get_client());
+#ifndef _WIN32
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
- if (-1 == ::unlink(its_client.str().c_str()) && errno != ENOENT) {
- VSOMEIP_ERROR << "routing_manager_proxy::init_receiver unlink failed ("
- << its_client.str() << "): "<< std::strerror(errno);
- }
-#endif
- try {
- receiver_ = std::make_shared<local_server_endpoint_impl>(shared_from_this(),
-#ifdef _WIN32
- boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
-#else
- boost::asio::local::stream_protocol::endpoint(its_client.str()),
-#endif
- io_, configuration_->get_max_message_size_local(),
- configuration_->get_buffer_shrink_threshold(),
- configuration_->get_endpoint_queue_limit_local(),
- configuration_->get_permissions_uds());
-#ifdef _WIN32
- VSOMEIP_INFO << "Listening at " << port;
-#else
- VSOMEIP_INFO << "Listening at " << its_client.str();
+ its_security->store_client_to_uid_gid_mapping(get_client(), own_uid_, own_gid_);
+ its_security->store_uid_gid_to_client_mapping(own_uid_, own_gid_, get_client());
#endif
- } catch (const std::exception &e) {
- host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
- VSOMEIP_ERROR << "Client ID: " << std::hex << client_ << ": " << e.what();
- }
+ receiver_ = ep_mgr_->create_local_server(shared_from_this());
}
void routing_manager_proxy::notify_remote_initially(service_t _service, instance_t _instance,
@@ -2179,16 +2186,18 @@ void routing_manager_proxy::notify_remote_initially(service_t _service, instance
if (service_info) {
its_notification->set_interface_version(service_info->get_major());
}
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(its_notification.get())) {
+
+ std::shared_ptr<serializer> its_serializer(get_serializer());
+ if (its_serializer->serialize(its_notification.get())) {
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
if (sender_) {
- send_local(sender_, VSOMEIP_ROUTING_CLIENT, serializer_->get_data(),
- serializer_->get_size(), _instance, true, false, VSOMEIP_NOTIFY);
+ send_local(sender_, VSOMEIP_ROUTING_CLIENT, its_serializer->get_data(),
+ its_serializer->get_size(), _instance, false, VSOMEIP_NOTIFY);
}
}
- serializer_->reset();
+ its_serializer->reset();
+ put_serializer(its_serializer);
} else {
VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
}
@@ -2243,6 +2252,30 @@ void routing_manager_proxy::clear_remote_subscriber_count(
}
}
+void
+routing_manager_proxy::assign_client_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()
+ << " request client timeout! Trying again...";
+
+ if (sender_) {
+ sender_->restart();
+ }
+ }
+ }
+}
+
void routing_manager_proxy::register_application_timeout_cbk(
boost::system::error_code const &_error) {
if (!_error) {
@@ -2256,8 +2289,9 @@ void routing_manager_proxy::register_application_timeout_cbk(
}
if (register_again) {
std::lock_guard<std::mutex> its_lock(sender_mutex_);
- VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() << " register timeout!"
- << " : Restart route to stub!";
+ VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
+ << " register timeout! Trying again...";
+
if (sender_) {
sender_->restart();
}
@@ -2285,19 +2319,21 @@ bool routing_manager_proxy::is_client_known(client_t _client) {
}
bool routing_manager_proxy::create_placeholder_event_and_subscribe(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- event_t _event, client_t _client) {
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, event_t _notifier, client_t _client) {
+
bool is_inserted(false);
// we received a event which was not yet requested/offered
// create a placeholder field until someone requests/offers this event with
// full information like eventgroup, field or not etc.
std::set<eventgroup_t> its_eventgroups({ _eventgroup });
// routing_manager_proxy: Always register with own client id and shadow = false
- routing_manager_base::register_event(host_->get_client(), _service,
- _instance, _event, its_eventgroups, true,
- std::chrono::milliseconds::zero(), false, nullptr, false, false,
+ routing_manager_base::register_event(host_->get_client(),
+ _service, _instance, _notifier,
+ its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN,
+ std::chrono::milliseconds::zero(), false, true, nullptr, false, false,
true);
- std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
+ std::shared_ptr<event> its_event = find_event(_service, _instance, _notifier);
if (its_event) {
is_inserted = its_event->add_subscriber(_eventgroup, _client, false);
}
@@ -2318,7 +2354,8 @@ void routing_manager_proxy::request_debounce_timeout_cbk(
{
std::lock_guard<std::mutex> its_lock(request_timer_mutex_);
request_debounce_timer_running_ = true;
- request_debounce_timer_.expires_from_now(std::chrono::milliseconds(configuration_->get_request_debouncing(host_->get_name())));
+ request_debounce_timer_.expires_from_now(std::chrono::milliseconds(
+ configuration_->get_request_debouncing(host_->get_name())));
request_debounce_timer_.async_wait(
std::bind(
&routing_manager_proxy::request_debounce_timeout_cbk,
@@ -2358,7 +2395,7 @@ void routing_manager_proxy::handle_client_error(client_t _client) {
std::lock_guard<std::mutex> its_lock(known_clients_mutex_);
its_known_clients = known_clients_;
}
- reconnect(its_known_clients);
+ reconnect(its_known_clients);
}
}
}
@@ -2386,7 +2423,7 @@ void routing_manager_proxy::send_get_offered_services_info(client_t _client, off
void routing_manager_proxy::send_unsubscribe_ack(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- pending_subscription_id_t _subscription_id) {
+ remote_subscription_id_t _id) {
byte_t its_command[VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE];
const std::uint32_t its_size = VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE;
@@ -2403,8 +2440,8 @@ void routing_manager_proxy::send_unsubscribe_ack(
sizeof(_instance));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
sizeof(_eventgroup));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
- &_subscription_id, sizeof(_subscription_id));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_id,
+ sizeof(_id));
{
std::lock_guard<std::mutex> its_lock(sender_mutex_);
@@ -2419,8 +2456,8 @@ void routing_manager_proxy::resend_provided_event_registrations() {
for (const event_data_t& ed : pending_event_registrations_) {
if (ed.is_provided_) {
send_register_event(client_, ed.service_, ed.instance_,
- ed.event_, ed.eventgroups_,
- ed.is_field_, ed.is_provided_);
+ ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_,
+ ed.is_provided_);
}
}
}
@@ -2489,6 +2526,10 @@ void routing_manager_proxy::send_remove_security_policy_response(pending_securit
}
void routing_manager_proxy::on_update_security_credentials(const byte_t *_data, uint32_t _size) {
+ auto its_security = security_impl::get();
+ if (!its_security)
+ return;
+
uint32_t i = 0;
while ( (i + sizeof(uint32_t) + sizeof(uint32_t)) <= _size) {
std::shared_ptr<policy> its_policy(std::make_shared<policy>());
@@ -2505,8 +2546,49 @@ void routing_manager_proxy::on_update_security_credentials(const byte_t *_data,
its_policy->allow_who_ = true;
its_policy->ids_.insert(std::make_pair(its_uid_ranges, its_gid_ranges));
- configuration_->add_security_credentials(its_uid, its_gid, its_policy, get_client());
+ its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client());
+ }
+}
+
+void routing_manager_proxy::on_client_assign_ack(const client_t &_client) {
+ std::lock_guard<std::mutex> its_lock(state_mutex_);
+ if (state_ == inner_state_type_e::ST_ASSIGNING) {
+ if (_client != VSOMEIP_CLIENT_UNSET) {
+ state_ = inner_state_type_e::ST_ASSIGNED;
+
+ boost::system::error_code ec;
+ register_application_timer_.cancel(ec);
+ host_->set_client(_client);
+ client_ = _client;
+
+ if (is_started_) {
+ init_receiver();
+ if (receiver_) {
+ receiver_->start();
+
+ VSOMEIP_INFO << std::hex << "Client " << client_
+ << " (" << host_->get_name()
+ << ") successfully connected to routing ~> registering..";
+ register_application();
+ } else {
+ state_ = inner_state_type_e::ST_DEREGISTERED;
+
+ host_->set_client(VSOMEIP_CLIENT_UNSET);
+ client_ = VSOMEIP_CLIENT_UNSET;
+
+ sender_->restart();
+ }
+ }
+ } else {
+ VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application.";
+ }
+ } else {
+ VSOMEIP_WARNING << "Client " << std::hex << client_
+ << " received another client identifier ("
+ << std::hex << _client
+ << "). Ignoring it. ("
+ << (int)state_ << ")";
}
}
-} // namespace vsomeip
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 5c19af9..65945f7 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -14,30 +14,28 @@
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/runtime.hpp>
#include <vsomeip/error.hpp>
-
-#ifndef WITHOUT_SYSTEMD
-#include <systemd/sd-daemon.h>
-#endif
-#define SD_LISTEN_FDS_START 3
+#include <vsomeip/internal/logger.hpp>
#include "../include/routing_manager_stub.hpp"
#include "../include/routing_manager_stub_host.hpp"
+#include "../include/remote_subscription.hpp"
#include "../../configuration/include/configuration.hpp"
-#include "../../configuration/include/internal.hpp"
+#include "../../security/include/security.hpp"
+
#include "../../endpoints/include/local_server_endpoint_impl.hpp"
-#include "../../logging/include/logger.hpp"
+#include "../../endpoints/include/endpoint_manager_impl.hpp"
#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
#include "../implementation/message/include/payload_impl.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
const std::vector<byte_t> routing_manager_stub::its_ping_(
{ VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
routing_manager_stub::routing_manager_stub(
routing_manager_stub_host *_host,
- std::shared_ptr<configuration> _configuration) :
+ const std::shared_ptr<configuration>& _configuration) :
host_(_host),
io_(_host->get_io()),
watchdog_timer_(_host->get_io()),
@@ -45,7 +43,6 @@ routing_manager_stub::routing_manager_stub(
endpoint_(nullptr),
local_receiver_(nullptr),
configuration_(_configuration),
- routingCommandSize_(VSOMEIP_ROUTING_INFO_SIZE_INIT),
is_socket_activated_(false),
client_registration_running_(false),
max_local_message_size_(configuration_->get_max_message_size_local()),
@@ -75,11 +72,11 @@ void routing_manager_stub::start() {
std::placeholders::_1));
}
- if(!endpoint_) {
+ if (!endpoint_) {
// application has been stopped and started again
init_routing_endpoint();
}
- if(endpoint_) {
+ if (endpoint_) {
endpoint_->start();
}
@@ -127,12 +124,15 @@ void routing_manager_stub::stop() {
if( !is_socket_activated_) {
endpoint_->stop();
endpoint_ = nullptr;
+ std::stringstream its_endpoint_path;
+ its_endpoint_path << utility::get_base_path(configuration_) << std::hex
+ << VSOMEIP_ROUTING_CLIENT;
#ifdef _WIN32
- ::_unlink(endpoint_path_.c_str());
+ ::_unlink(its_endpoint_path.str().c_str());
#else
- if (-1 == ::unlink(endpoint_path_.c_str())) {
+ if (-1 == ::unlink(its_endpoint_path.str().c_str())) {
VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed ("
- << endpoint_path_ << "): "<< std::strerror(errno);
+ << its_endpoint_path.str() << "): "<< std::strerror(errno);
}
#endif
}
@@ -140,53 +140,24 @@ void routing_manager_stub::stop() {
if(local_receiver_) {
local_receiver_->stop();
local_receiver_ = nullptr;
+ std::stringstream its_local_receiver_path;
+ its_local_receiver_path << utility::get_base_path(configuration_)
+ << std::hex << host_->get_client();
#ifdef _WIN32
- ::_unlink(local_receiver_path_.c_str());
+ ::_unlink(its_local_receiver_path.str().c_str());
#else
- if (-1 == ::unlink(local_receiver_path_.c_str())) {
+ if (-1 == ::unlink(its_local_receiver_path.str().c_str())) {
VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed ("
- << local_receiver_path_ << "): "<< std::strerror(errno);
+ << its_local_receiver_path.str() << "): "<< std::strerror(errno);
}
#endif
}
}
-const std::shared_ptr<configuration> routing_manager_stub::get_configuration() const {
- return configuration_;
-}
-
-void routing_manager_stub::on_connect(std::shared_ptr<endpoint> _endpoint) {
- _endpoint->set_connected(true);
- _endpoint->set_established(true);
-}
-
-void routing_manager_stub::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
- (void)_endpoint;
-}
-
-void routing_manager_stub::on_error(
- const byte_t *_data, length_t _length, endpoint *_receiver,
- const boost::asio::ip::address &_remote_address,
- std::uint16_t _remote_port) {
-
- // Implement me when needed
-
- (void)(_data);
- (void)(_length);
- (void)(_receiver);
- (void)(_remote_address);
- (void)(_remote_port);
-}
-
-void routing_manager_stub::release_port(uint16_t _port, bool _reliable) {
- (void)_port;
- (void)_reliable;
- // intentionally empty
-}
-
void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
client_t _bound_client,
+ credentials_t _credentials,
const boost::asio::ip::address &_remote_address,
std::uint16_t _remote_port) {
(void)_receiver;
@@ -201,6 +172,9 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
VSOMEIP_INFO << msg.str();
#endif
+ std::uint32_t its_sender_uid = std::get<0>(_credentials);
+ std::uint32_t its_sender_gid = std::get<1>(_credentials);
+
if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) {
byte_t its_command;
client_t its_client;
@@ -209,9 +183,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
instance_t its_instance;
method_t its_method;
eventgroup_t its_eventgroup;
- std::set<eventgroup_t> its_eventgroups;
- event_t its_event;
- bool is_field(false);
+ event_t its_notifier;
+ event_type_e its_event_type;
bool is_provided(false);
major_version_t its_major;
minor_version_t its_minor;
@@ -219,19 +192,18 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
const byte_t *its_data;
uint32_t its_size;
bool its_reliable(false);
- subscription_type_e its_subscription_type;
client_t its_client_from_header;
client_t its_target_client;
client_t its_subscriber;
- bool its_is_valid_crc(true);
- std::uint16_t its_subscription_id(DEFAULT_SUBSCRIPTION);
+ uint8_t its_check_status(0);
+ std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID);
offer_type_e its_offer_type;
its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
sizeof(its_client));
- if (configuration_->is_security_enabled() && _bound_client != its_client) {
+ if (security::get()->is_enabled() && _bound_client != its_client) {
VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: "
<< "Routing Manager received a message from client "
<< std::hex << std::setw(4) << std::setfill('0')
@@ -278,6 +250,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!";
break;
}
+
std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(its_service));
std::memcpy(&its_instance,
@@ -288,7 +261,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
sizeof(its_minor));
- if (configuration_->is_offer_allowed(its_client, its_service, its_instance)) {
+ if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid,
+ its_client, its_service, its_instance)) {
host_->offer_service(its_client, its_service, its_instance,
its_major, its_minor);
} else {
@@ -331,15 +305,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_eventgroup));
std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
sizeof(its_major));
- std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
- sizeof(its_event));
- std::memcpy(&its_subscription_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
- sizeof(its_subscription_type));
-
- if (its_event == ANY_EVENT) {
- if (host_->is_subscribe_to_any_event_allowed(its_client, its_service, its_instance, its_eventgroup)) {
- host_->subscribe(its_client, its_service, its_instance,
- its_eventgroup, its_major, its_event, its_subscription_type);
+ std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
+ sizeof(its_notifier));
+
+ if (its_notifier == ANY_EVENT) {
+ if (host_->is_subscribe_to_any_event_allowed(_credentials, its_client, its_service,
+ its_instance, its_eventgroup)) {
+ host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance,
+ its_eventgroup, its_major, its_notifier);
} else {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
<< " : routing_manager_stub::on_message: "
@@ -348,15 +321,15 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
<< " which violates the security policy ~> Skip subscribe!";
}
} else {
- if (configuration_->is_client_allowed(its_client,
- its_service, its_instance, its_event)) {
- host_->subscribe(its_client, its_service, its_instance,
- its_eventgroup, its_major, its_event, its_subscription_type);
+ if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_client, its_service, its_instance, its_notifier)) {
+ host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance,
+ its_eventgroup, its_major, its_notifier);
} else {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client
<< " : routing_manager_stub::on_message: "
<< " subscribes to service/instance/event "
- << its_service << "/" << its_instance << "/" << its_event
+ << its_service << "/" << its_instance << "/" << its_notifier
<< " which violates the security policy ~> Skip subscribe!";
}
}
@@ -373,11 +346,11 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_instance));
std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
sizeof(its_eventgroup));
- std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
- sizeof(its_event));
+ std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
+ sizeof(its_notifier));
- host_->unsubscribe(its_client, its_service,
- its_instance, its_eventgroup, its_event);
+ host_->unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service,
+ its_instance, its_eventgroup, its_notifier);
break;
case VSOMEIP_SUBSCRIBE_ACK:
@@ -393,18 +366,18 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_eventgroup));
std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
sizeof(its_subscriber));
- std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
- sizeof(its_event));
+ std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
+ sizeof(its_notifier));
std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
sizeof(its_subscription_id));
host_->on_subscribe_ack(its_subscriber, its_service,
- its_instance, its_eventgroup, its_event, its_subscription_id);
+ its_instance, its_eventgroup, its_notifier, its_subscription_id);
VSOMEIP_INFO << "SUBSCRIBE ACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event << "]";
+ << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]";
break;
case VSOMEIP_SUBSCRIBE_NACK:
@@ -420,18 +393,18 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_eventgroup));
std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
sizeof(its_subscriber));
- std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
- sizeof(its_event));
+ std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
+ sizeof(its_notifier));
std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
sizeof(its_subscription_id));
host_->on_subscribe_nack(its_subscriber, its_service,
- its_instance, its_eventgroup, its_event, its_subscription_id);
+ its_instance, its_eventgroup, its_notifier, its_subscription_id);
VSOMEIP_INFO << "SUBSCRIBE NACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event << "]";
+ << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]";
break;
case VSOMEIP_UNSUBSCRIBE_ACK:
if (_size != VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE) {
@@ -473,14 +446,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_instance));
std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
sizeof(its_reliable));
- std::memcpy(&its_is_valid_crc, &_data[VSOMEIP_SEND_COMMAND_VALID_CRC_POS],
- sizeof(its_is_valid_crc));
+ std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
+ sizeof(its_check_status));
// Allow response messages from local proxies as answer to remote requests
// but check requests sent by local proxies to remote against policy.
if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) {
- if (!configuration_->is_client_allowed(its_client_from_header,
- its_service, its_instance, its_method)) {
+ if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_client_from_header, its_service, its_instance, its_method)) {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client_from_header
<< " : routing_manager_stub::on_message: "
<< " isn't allowed to send a request to service/instance/method "
@@ -502,7 +475,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
break;
}
host_->on_message(its_service, its_instance, its_data, its_message_size,
- its_reliable, _bound_client, its_is_valid_crc, false);
+ its_reliable, _bound_client, _credentials, its_check_status, false);
break;
}
case VSOMEIP_NOTIFY: {
@@ -562,8 +535,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
}
case VSOMEIP_REQUEST_SERVICE:
{
- uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t)
- + sizeof(minor_version_t) + sizeof(bool));
+ uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t)
+ + sizeof(major_version_t) + sizeof(minor_version_t));
if (its_size % entry_size > 0) {
VSOMEIP_WARNING << "Received a REQUEST_SERVICE command with invalid size -> skip!";
break;
@@ -575,7 +548,6 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
instance_t its_instance;
major_version_t its_major;
minor_version_t its_minor;
- bool use_exclusive_proxy;
std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)],
sizeof(its_service));
std::memcpy(&its_instance,
@@ -585,13 +557,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_major));
std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)],
sizeof(its_minor));
- std::memcpy(&use_exclusive_proxy, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9 + (i * entry_size)],
- sizeof(use_exclusive_proxy));
- if (configuration_->is_client_allowed(its_client, its_service, its_instance, 0x00, true)) {
+ if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
+ its_client, its_service, its_instance, 0x00, true)) {
host_->request_service(its_client, its_service, its_instance,
- its_major, its_minor, use_exclusive_proxy);
- service_data_t request = { its_service, its_instance,
- its_major, its_minor, use_exclusive_proxy };
+ its_major, its_minor );
+ service_data_t request = {
+ its_service, its_instance,
+ its_major, its_minor
+ };
requests.insert(request);
} else {
VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex
@@ -601,7 +574,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
<< " which violates the security policy ~> Skip request!";
}
}
- if (configuration_->is_security_enabled()) {
+ if (security::get()->is_enabled()) {
handle_credentials(its_client, requests);
}
handle_requests(its_client, requests);
@@ -622,48 +595,58 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
host_->release_service(its_client, its_service, its_instance);
break;
- case VSOMEIP_REGISTER_EVENT:
+ case VSOMEIP_REGISTER_EVENT: {
if (_size < VSOMEIP_REGISTER_EVENT_COMMAND_SIZE) {
VSOMEIP_WARNING << "Received a REGISTER_EVENT command with wrong size ~> skip!";
break;
}
+
+ std::set<eventgroup_t> its_eventgroups;
+ reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN;
+
std::memcpy(&its_service,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(its_service));
std::memcpy(&its_instance,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
sizeof(its_instance));
- std::memcpy(&its_event,
+ std::memcpy(&its_notifier,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_event));
- std::memcpy(&is_field,
+ sizeof(its_notifier));
+ std::memcpy(&its_event_type,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
- sizeof(is_field));
+ sizeof(its_event_type));
std::memcpy(&is_provided,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
sizeof(is_provided));
+ std::memcpy(&its_reliability,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8],
+ sizeof(its_reliability));
if (is_provided
&& !configuration_->is_offered_remote(its_service,
its_instance)) {
break;
}
- for (std::size_t i = 8; i+1 < its_size; i++) {
+ for (std::size_t i = 9; i+1 < its_size; i++) {
std::memcpy(&its_eventgroup,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + i],
sizeof(its_eventgroup));
its_eventgroups.insert(its_eventgroup);
}
- host_->register_shadow_event(its_client, its_service,
- its_instance, its_event, its_eventgroups,
- is_field, is_provided);
+ host_->register_shadow_event(its_client,
+ its_service, its_instance,
+ its_notifier, its_eventgroups, its_event_type,
+ its_reliability,
+ is_provided);
VSOMEIP_INFO << "REGISTER EVENT("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event
- << ":is_provider=" << is_provided << "]";
+ << std::hex << std::setw(4) << std::setfill('0') << its_notifier
+ << ":is_provider=" << is_provided << ":reliability="
+ << (std::uint32_t)(its_reliability) << "]";
break;
-
+ }
case VSOMEIP_UNREGISTER_EVENT:
if (_size != VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE) {
VSOMEIP_WARNING << "Received a UNREGISTER_EVENT command with wrong size ~> skip!";
@@ -674,8 +657,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
std::memcpy(&its_instance,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
sizeof(its_instance));
- std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_event));
+ std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_notifier));
std::memcpy(&is_provided,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
sizeof(is_provided));
@@ -685,36 +668,15 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
break;
}
host_->unregister_shadow_event(its_client, its_service, its_instance,
- its_event, is_provided);
+ its_notifier, is_provided);
VSOMEIP_INFO << "UNREGISTER EVENT("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event
+ << std::hex << std::setw(4) << std::setfill('0') << its_notifier
<< ":is_provider=" << is_provided << "]";
break;
- case VSOMEIP_ID_RESPONSE:
- if (_size != VSOMEIP_ID_RESPONSE_COMMAND_SIZE) {
- VSOMEIP_WARNING << "Received a ID_RESPONSE command with wrong size ~> skip!";
- break;
- }
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance,
- &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- std::memcpy(&its_reliable,
- &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_reliable));
- host_->on_identify_response(its_client, its_service, its_instance, its_reliable);
- VSOMEIP_INFO << "ID RESPONSE("
- << std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
- << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_instance
- << ":is_reliable=" << its_reliable << "]";
- break;
-
case VSOMEIP_REGISTERED_ACK:
if (_size != VSOMEIP_REGISTERED_ACK_COMMAND_SIZE) {
VSOMEIP_WARNING << "Received a REGISTERED_ACK command with wrong size ~> skip!";
@@ -735,7 +697,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
create_offered_services_info(its_client);
- for (auto found_client : routing_info_) {
+ for (const auto& found_client : routing_info_) {
// skip services which are offered on remote hosts
if (found_client.first != VSOMEIP_ROUTING_CLIENT) {
for (const auto &its_service : found_client.second.second) {
@@ -879,7 +841,7 @@ void routing_manager_stub::client_registration_func(void) {
pending_client_registrations_.clear();
its_lock.unlock();
- for (auto r : its_registrations) {
+ for (const auto& r : its_registrations) {
for (auto b : r.second) {
if (b == registration_type_e::REGISTER) {
on_register_application(r.first);
@@ -921,7 +883,7 @@ void routing_manager_stub::client_registration_func(void) {
}
connection_matrix_.erase(r.first);
}
- for (auto its_client : connection_matrix_) {
+ for (const auto& its_client : connection_matrix_) {
connection_matrix_[its_client.first].erase(r.first);
}
service_requests_.erase(r.first);
@@ -929,9 +891,7 @@ void routing_manager_stub::client_registration_func(void) {
// Don't remove client ID to UID maping as same client
// could have passed its credentials again
host_->remove_local(r.first, false);
- if (b == registration_type_e::DEREGISTER_ON_ERROR) {
- utility::release_client_id(r.first);
- }
+ utility::release_client_id(r.first);
}
}
}
@@ -940,76 +900,8 @@ void routing_manager_stub::client_registration_func(void) {
}
void routing_manager_stub::init_routing_endpoint() {
- std::stringstream its_endpoint_path;
- its_endpoint_path << utility::get_base_path(configuration_) << VSOMEIP_ROUTING_CLIENT;
- endpoint_path_ = its_endpoint_path.str();
- client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host());
- if (configuration_->is_security_enabled() && get_client() != routing_host_id) {
- VSOMEIP_ERROR << __func__ << std::hex << " Client " << get_client() << " isn't allowed"
- << " to create the routing endpoint due to its not configured as the routing master!";
- return;
- }
- uint32_t native_socket_fd, num_fd = 0;
-#ifndef WITHOUT_SYSTEMD
- num_fd = sd_listen_fds(0);
-#endif
- if (num_fd > 1) {
- VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd;
- } else if (num_fd == 1) {
- native_socket_fd = SD_LISTEN_FDS_START + 0;
- VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd;
- #ifndef _WIN32
- try {
- endpoint_ =
- std::make_shared < local_server_endpoint_impl
- > (shared_from_this(),
- boost::asio::local::stream_protocol::endpoint(endpoint_path_),
- io_, configuration_->get_max_message_size_local(), native_socket_fd,
- configuration_->get_buffer_shrink_threshold(),
- configuration_->get_endpoint_queue_limit_local(),
- configuration_->get_permissions_uds());
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
- << " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
- VSOMEIP_ERROR << "routing_manager_stub::init_routing_endpoint Client ID: "
- << std::hex << VSOMEIP_ROUTING_CLIENT << ": " << e.what();
- }
- #endif
- is_socket_activated_ = true;
- } else {
- #if _WIN32
- ::_unlink(endpoint_path_.c_str());
- int port = VSOMEIP_INTERNAL_BASE_PORT;
- VSOMEIP_INFO << "Routing endpoint at " << port;
- #else
- if (-1 == ::unlink(endpoint_path_.c_str()) && errno != ENOENT) {
- VSOMEIP_ERROR << "routing_manager_stub::init_endpoint unlink failed ("
- << endpoint_path_ << "): "<< std::strerror(errno);
- }
- VSOMEIP_INFO << "init_routing_endpoint Routing endpoint at " << endpoint_path_;
- #endif
-
- try {
- endpoint_ =
- std::make_shared < local_server_endpoint_impl
- > (shared_from_this(),
- #ifdef _WIN32
- boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
- #else
- boost::asio::local::stream_protocol::endpoint(endpoint_path_),
- #endif
- io_, configuration_->get_max_message_size_local(),
- configuration_->get_buffer_shrink_threshold(),
- configuration_->get_endpoint_queue_limit_local(),
- configuration_->get_permissions_uds());
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
- << " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
- VSOMEIP_ERROR << "routing_manager_stub::init_routing_endpoint Client ID: "
- << std::hex << VSOMEIP_ROUTING_CLIENT << ": " << e.what();
- }
- is_socket_activated_ = false;
- }
+ endpoint_ = host_->get_endpoint_manager()->create_local_server(
+ &is_socket_activated_, shared_from_this());
}
void routing_manager_stub::on_offer_service(client_t _client,
@@ -1018,22 +910,13 @@ void routing_manager_stub::on_offer_service(client_t _client,
create_local_receiver();
}
- if (_client == VSOMEIP_ROUTING_CLIENT ||
- configuration_->is_offer_allowed(_client, _service, _instance)) {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor);
- if (configuration_->is_security_enabled()) {
- distribute_credentials(_client, _service, _instance);
- }
- inform_requesters(_client, _service, _instance, _major, _minor,
- routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true);
- } else {
- VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client
- << " : routing_manager_stub::on_offer_service: "
- << "isn't allowed to offer the following service/instance "
- << _service << "/" << _instance
- << " ~> Skip offer!";
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor);
+ if (security::get()->is_enabled()) {
+ distribute_credentials(_client, _service, _instance);
}
+ inform_requesters(_client, _service, _instance, _major, _minor,
+ routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true);
}
void routing_manager_stub::on_stop_offer_service(client_t _client,
@@ -1155,7 +1038,7 @@ void routing_manager_stub::send_client_credentials_info(const client_t _target)
// Send routing info or error!
if(its_command.size() <= max_local_message_size_
|| VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
- its_endpoint->send(&its_command[0], uint32_t(its_size), true);
+ its_endpoint->send(&its_command[0], uint32_t(its_size));
} else {
VSOMEIP_ERROR << "Credentials info exceeds maximum message size: Can't send!";
}
@@ -1212,7 +1095,7 @@ void routing_manager_stub::send_client_routing_info(const client_t _target) {
// Send routing info or error!
if(its_command.size() <= max_local_message_size_
|| VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
- its_endpoint->send(&its_command[0], uint32_t(its_size), true);
+ its_endpoint->send(&its_command[0], uint32_t(its_size));
} else {
VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!";
}
@@ -1249,7 +1132,7 @@ void routing_manager_stub::send_offered_services_info(const client_t _target) {
// Send routing info or error!
if(its_command.size() <= max_local_message_size_
|| VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
- its_endpoint->send(&its_command[0], uint32_t(its_size), true);
+ its_endpoint->send(&its_command[0], uint32_t(its_size));
} else {
VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!";
}
@@ -1406,10 +1289,10 @@ void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _s
// search for UID / GID linked with the client ID that offers the requested services
std::pair<uint32_t, uint32_t> its_uid_gid;
- if (configuration_->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) {
+ if (security::get()->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) {
for (auto its_requesting_client : its_requesting_clients) {
std::pair<uint32_t, uint32_t> its_requester_uid_gid;
- if (configuration_->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) {
+ if (security::get()->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) {
if (its_uid_gid != its_requester_uid_gid) {
its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid)));
create_client_credentials_info(its_requesting_client);
@@ -1465,21 +1348,21 @@ bool routing_manager_stub::is_already_connected(client_t _source, client_t _sink
void routing_manager_stub::broadcast(const std::vector<byte_t> &_command) const {
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- for (auto a : routing_info_) {
+ for (const auto& a : routing_info_) {
if (a.first != VSOMEIP_ROUTING_CLIENT && a.first != host_->get_client()) {
std::shared_ptr<endpoint> its_endpoint
= host_->find_local(a.first);
if (its_endpoint) {
- its_endpoint->send(&_command[0], uint32_t(_command.size()), true);
+ its_endpoint->send(&_command[0], uint32_t(_command.size()));
}
}
}
}
-bool routing_manager_stub::send_subscribe(std::shared_ptr<vsomeip::endpoint> _target,
+bool routing_manager_stub::send_subscribe(const std::shared_ptr<endpoint>& _target,
client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major,
- event_t _event, pending_subscription_id_t _subscription_id) {
+ event_t _event, remote_subscription_id_t _id) {
if (_target) {
byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
@@ -1498,11 +1381,8 @@ bool routing_manager_stub::send_subscribe(std::shared_ptr<vsomeip::endpoint> _ta
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event,
sizeof(_event));
- // set byte for subscription_type to zero. It's only used
- // in subscribe messages sent from rm_proxies to rm_stub.
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9] = 0x0;
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
- &_subscription_id, sizeof(_subscription_id));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_id,
+ sizeof(_id));
return _target->send(its_command, sizeof(its_command));
} else {
@@ -1517,10 +1397,11 @@ bool routing_manager_stub::send_subscribe(std::shared_ptr<vsomeip::endpoint> _ta
}
}
-bool routing_manager_stub::send_unsubscribe(std::shared_ptr<vsomeip::endpoint> _target,
+bool routing_manager_stub::send_unsubscribe(
+ const std::shared_ptr<endpoint>& _target,
client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event,
- pending_subscription_id_t _unsubscription_id) {
+ remote_subscription_id_t _id) {
if (_target) {
byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
@@ -1538,8 +1419,8 @@ bool routing_manager_stub::send_unsubscribe(std::shared_ptr<vsomeip::endpoint> _
sizeof(_eventgroup));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event,
sizeof(_event));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_unsubscription_id,
- sizeof(_unsubscription_id));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id,
+ sizeof(_id));
return _target->send(its_command, sizeof(its_command));
} else {
@@ -1580,9 +1461,9 @@ void routing_manager_stub::send_subscribe_ack(client_t _client, service_t _servi
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
sizeof(_event));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
- &DEFAULT_SUBSCRIPTION, sizeof(DEFAULT_SUBSCRIPTION));
+ &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
- its_endpoint->send(&its_command[0], sizeof(its_command), true);
+ its_endpoint->send(&its_command[0], sizeof(its_command));
}
}
@@ -1612,9 +1493,9 @@ void routing_manager_stub::send_subscribe_nack(client_t _client, service_t _serv
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event,
sizeof(_event));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10],
- &DEFAULT_SUBSCRIPTION, sizeof(DEFAULT_SUBSCRIPTION));
+ &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID));
- its_endpoint->send(&its_command[0], sizeof(its_command), true);
+ its_endpoint->send(&its_command[0], sizeof(its_command));
}
}
@@ -1691,7 +1572,7 @@ void routing_manager_stub::check_watchdog() {
std::list< client_t > lost;
{
std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
- for (auto i : routing_info_) {
+ for (const auto& i : routing_info_) {
if (i.first > 0 && i.first != host_->get_client()) {
if (i.second.first > configuration_->get_allowed_missing_pongs()) {
VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
@@ -1720,43 +1601,16 @@ void routing_manager_stub::create_local_receiver() {
if (local_receiver_) {
return;
}
- std::stringstream its_local_receiver_path;
- its_local_receiver_path << utility::get_base_path(configuration_) << std::hex << host_->get_client();
- local_receiver_path_ = its_local_receiver_path.str();
-#if _WIN32
- ::_unlink(local_receiver_path_.c_str());
- int port = VSOMEIP_INTERNAL_BASE_PORT;
-#else
- if (!check_credentials(get_client(), getuid(), getgid())) {
+#ifndef _WIN32
+ else if (!security::get()->check_credentials(get_client(), getuid(), getgid())) {
VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client()
<< " : routing_manager_stub::create_local_receiver: isn't allowed"
<< " to create a server endpoint due to credential check failed!";
return;
}
- if (-1 == ::unlink(local_receiver_path_.c_str()) && errno != ENOENT) {
- VSOMEIP_ERROR << "routing_manager_stub::create_local_receiver unlink (local receiver) failed ("
- << local_receiver_path_ << "): "<< std::strerror(errno);
- }
#endif
- try {
- local_receiver_ =
- std::make_shared < local_server_endpoint_impl
- > (shared_from_this(),
- #ifdef _WIN32
- boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port + host_->get_client()),
- #else
- boost::asio::local::stream_protocol::endpoint(local_receiver_path_),
- #endif
- io_, configuration_->get_max_message_size_local(),
- configuration_->get_buffer_shrink_threshold(),
- configuration_->get_endpoint_queue_limit_local(),
- configuration_->get_permissions_uds());
- } catch (const std::exception &e) {
- VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
- << " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
- VSOMEIP_ERROR << "routing_manager_stub::_local_receiver Client ID: "
- << std::hex << VSOMEIP_ROUTING_CLIENT << ": " << e.what();
- }
+ local_receiver_ = std::static_pointer_cast<endpoint_manager_base>(
+ host_->get_endpoint_manager())->create_local_server(shared_from_this());
local_receiver_->start();
}
@@ -1805,8 +1659,7 @@ bool routing_manager_stub::send_ping(client_t _client) {
pinged_clients_timer_.async_wait(
std::bind(&routing_manager_stub::on_ping_timer_expired, this,
std::placeholders::_1));
- return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size()),
- true);
+ return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size()));
}
}
@@ -1904,7 +1757,7 @@ void routing_manager_stub::remove_from_pinged_clients(client_t _client) {
}
pinged_clients_timer_.async_wait(
std::bind(&routing_manager_stub::on_ping_timer_expired, this,
- std::placeholders::_1));
+ std::placeholders::_1));
}
bool routing_manager_stub::is_registered(client_t _client) const {
@@ -1922,7 +1775,7 @@ void routing_manager_stub::update_registration(client_t _client,
"registering." : "deregistering.");
if (_type != registration_type_e::REGISTER) {
- configuration_->remove_client_to_uid_gid_mapping(_client);
+ security::get()->remove_client_to_uid_gid_mapping(_client);
}
if (_type == registration_type_e::DEREGISTER) {
@@ -1968,7 +1821,7 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set<s
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
std::set<std::pair<uint32_t, uint32_t>> its_credentials;
std::pair<uint32_t, uint32_t> its_requester_uid_gid;
- if (configuration_->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) {
+ if (security::get()->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) {
// determine credentials of offering clients using current routing info
std::set<client_t> its_offering_clients;
@@ -1984,7 +1837,7 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set<s
// search for UID / GID linked with the client ID that offers the requested services
for (auto its_offering_client : its_offering_clients) {
std::pair<uint32_t, uint32_t> its_uid_gid;
- if (configuration_->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) {
+ if (security::get()->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) {
if (its_uid_gid != its_requester_uid_gid) {
its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid)));
}
@@ -2010,51 +1863,63 @@ void routing_manager_stub::handle_requests(const client_t _client, std::set<serv
for (auto request : _requests) {
service_requests_[_client][request.service_][request.instance_]
= std::make_pair(request.major_, request.minor_);
- for (auto found_client : routing_info_) {
- auto found_service = found_client.second.second.find(request.service_);
- if (found_service != found_client.second.second.end()) {
- if (request.instance_ == ANY_INSTANCE) {
- if (found_client.first != VSOMEIP_ROUTING_CLIENT &&
- found_client.first != host_->get_client()) {
- if (!is_already_connected(found_client.first, _client)) {
- if (_client == found_client.first) {
- service_available = true;
- insert_client_routing_info(found_client.first,
+ if (request.instance_ == ANY_INSTANCE) {
+ std::set<client_t> its_clients = host_->find_local_clients(request.service_, request.instance_);
+ // insert VSOMEIP_ROUTING_CLIENT to check wether service is remotely offered
+ its_clients.insert(VSOMEIP_ROUTING_CLIENT);
+ for (const client_t c : its_clients) {
+ if (c != VSOMEIP_ROUTING_CLIENT &&
+ c != host_->get_client()) {
+ if (!is_already_connected(c, _client)) {
+ if (_client == c) {
+ service_available = true;
+ insert_client_routing_info(c,
+ routing_info_entry_e::RIE_ADD_CLIENT, _client);
+ } else {
+ create_client_routing_info(c);
+ insert_client_routing_info(c,
routing_info_entry_e::RIE_ADD_CLIENT, _client);
- } else {
- create_client_routing_info(found_client.first);
- insert_client_routing_info(found_client.first,
- routing_info_entry_e::RIE_ADD_CLIENT, _client);
- send_client_routing_info(found_client.first);
- }
+ send_client_routing_info(c);
}
}
- if (_client != VSOMEIP_ROUTING_CLIENT &&
- _client != host_->get_client()) {
- for (auto instance : found_service->second) {
- service_available = true;
- insert_client_routing_info(_client,
- routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
- found_client.first, request.service_, instance.first,
- instance.second.first, instance.second.second);
+ }
+ if (_client != VSOMEIP_ROUTING_CLIENT &&
+ _client != host_->get_client()) {
+ const auto found_client = routing_info_.find(c);
+ if (found_client != routing_info_.end()) {
+ const auto found_service = found_client->second.second.find(request.service_);
+ if (found_service != found_client->second.second.end()) {
+ for (auto instance : found_service->second) {
+ service_available = true;
+ insert_client_routing_info(_client,
+ routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
+ c, request.service_, instance.first,
+ instance.second.first, instance.second.second);
+ }
}
}
- break;
- } else {
- auto found_instance = found_service->second.find(request.instance_);
+ }
+ }
+ } else {
+ const client_t c = host_->find_local_client(request.service_, request.instance_);
+ const auto found_client = routing_info_.find(c);
+ if (found_client != routing_info_.end()) {
+ const auto found_service = found_client->second.second.find(request.service_);
+ if (found_service != found_client->second.second.end()) {
+ const auto found_instance = found_service->second.find(request.instance_);
if (found_instance != found_service->second.end()) {
- if (found_client.first != VSOMEIP_ROUTING_CLIENT &&
- found_client.first != host_->get_client()) {
- if (!is_already_connected(found_client.first, _client)) {
- if (_client == found_client.first) {
+ if (c != VSOMEIP_ROUTING_CLIENT &&
+ c != host_->get_client()) {
+ if (!is_already_connected(c, _client)) {
+ if (_client == c) {
service_available = true;
- insert_client_routing_info(found_client.first,
- routing_info_entry_e::RIE_ADD_CLIENT, _client);
+ insert_client_routing_info(c,
+ routing_info_entry_e::RIE_ADD_CLIENT, _client);
} else {
- create_client_routing_info(found_client.first);
- insert_client_routing_info(found_client.first,
+ create_client_routing_info(c);
+ insert_client_routing_info(c,
routing_info_entry_e::RIE_ADD_CLIENT, _client);
- send_client_routing_info(found_client.first);
+ send_client_routing_info(c);
}
}
}
@@ -2063,11 +1928,10 @@ void routing_manager_stub::handle_requests(const client_t _client, std::set<serv
service_available = true;
insert_client_routing_info(_client,
routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE,
- found_client.first, request.service_, request.instance_,
+ c, request.service_, request.instance_,
found_instance->second.first,
found_instance->second.second);
}
- break;
}
}
}
@@ -2078,37 +1942,6 @@ void routing_manager_stub::handle_requests(const client_t _client, std::set<serv
}
}
-#ifndef _WIN32
-bool routing_manager_stub::check_credentials(client_t _client, uid_t _uid, gid_t _gid) {
- return configuration_->check_credentials(_client, _uid, _gid);
-}
-#endif
-
-void routing_manager_stub::send_identify_request_command(std::shared_ptr<vsomeip::endpoint> _target,
- service_t _service, instance_t _instance, major_version_t _major, bool _reliable) {
- if (_target) {
- byte_t its_command[VSOMEIP_ID_REQUEST_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_ID_REQUEST_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ID_REQUEST;
- client_t client = get_client();
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client,
- sizeof(client));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_major,
- sizeof(_major));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_reliable,
- sizeof(_reliable));
-
- _target->send(its_command, sizeof(its_command));
- }
-}
-
void routing_manager_stub::on_client_id_timer_expired(boost::system::error_code const &_error) {
std::set<client_t> used_client_ids;
{
@@ -2152,8 +1985,9 @@ bool routing_manager_stub::send_provided_event_resend_request(client_t _client,
if (its_endpoint) {
byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE];
its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
- sizeof(client_t));
+ const client_t routing_client(VSOMEIP_ROUTING_CLIENT);
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &routing_client,
+ sizeof(routing_client));
std::uint32_t its_size = sizeof(pending_remote_offer_id_t);
std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
sizeof(its_size));
@@ -2182,7 +2016,7 @@ bool routing_manager_stub::is_policy_cached(uint32_t _uid) {
}
}
-void routing_manager_stub::policy_cache_add(uint32_t _uid, std::shared_ptr<payload> _payload) {
+void routing_manager_stub::policy_cache_add(uint32_t _uid, const std::shared_ptr<payload>& _payload) {
// cache security policy payload for later distribution to new registering clients
{
std::lock_guard<std::mutex> its_lock(updated_security_policies_mutex_);
@@ -2198,7 +2032,8 @@ void routing_manager_stub::policy_cache_remove(uint32_t _uid) {
}
bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id,
- uint32_t _uid, std::shared_ptr<payload> _payload) {
+ uint32_t _uid, const std::shared_ptr<payload>& _payload) {
+ (void)_uid;
std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
if (its_endpoint) {
std::vector<byte_t> its_command;
@@ -2269,7 +2104,7 @@ bool routing_manager_stub::send_cached_security_policies(client_t _client) {
reinterpret_cast<const byte_t*>(&its_policy_count)[i]);
}
- for (auto its_uid_gid : updated_security_policies_) {
+ for (const auto& its_uid_gid : updated_security_policies_) {
// policy payload length including gid and uid
std::uint32_t its_length = uint32_t(its_uid_gid.second->get_length());
for (uint32_t i = 0; i < sizeof(its_length); ++i) {
@@ -2318,4 +2153,4 @@ bool routing_manager_stub::send_remove_security_policy_request( client_t _client
}
}
-} // namespace vsomeip
+} // namespace vsomeip_v3
diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp
index 42db53b..324fcd7 100644
--- a/implementation/routing/src/serviceinfo.cpp
+++ b/implementation/routing/src/serviceinfo.cpp
@@ -5,11 +5,14 @@
#include "../include/serviceinfo.hpp"
-namespace vsomeip {
+namespace vsomeip_v3 {
-serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, bool _is_local)
+serviceinfo::serviceinfo(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl, bool _is_local)
: group_(0),
+ service_(_service),
+ instance_(_instance),
major_(_major),
minor_(_minor),
ttl_(0),
@@ -24,6 +27,8 @@ serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor,
serviceinfo::serviceinfo(const serviceinfo& _other) :
group_(_other.group_),
+ service_(_other.service_),
+ instance_(_other.instance_),
major_(_other.major_),
minor_(_other.minor_),
ttl_(_other.ttl_),
@@ -45,6 +50,14 @@ void serviceinfo::set_group(servicegroup *_group) {
group_ = _group;
}
+service_t serviceinfo::get_service() const {
+ return service_;
+}
+
+instance_t serviceinfo::get_instance() const {
+ return instance_;
+}
+
major_version_t serviceinfo::get_major() const {
return major_;
}
@@ -80,7 +93,7 @@ std::shared_ptr<endpoint> serviceinfo::get_endpoint(bool _reliable) const {
return (_reliable ? reliable_ : unreliable_);
}
-void serviceinfo::set_endpoint(std::shared_ptr<endpoint> _endpoint,
+void serviceinfo::set_endpoint(const std::shared_ptr<endpoint>& _endpoint,
bool _reliable) {
std::lock_guard<std::mutex> its_lock(endpoint_mutex_);
if (_reliable) {
@@ -117,5 +130,4 @@ void serviceinfo::set_is_in_mainphase(bool _in_mainphase) {
is_in_mainphase_ = _in_mainphase;
}
-} // namespace vsomeip
-
+} // namespace vsomeip_v3