summaryrefslogtreecommitdiff
path: root/implementation/routing
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/routing')
-rw-r--r--implementation/routing/include/event.hpp2
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp5
-rw-r--r--implementation/routing/include/remote_subscription.hpp4
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp16
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp4
-rw-r--r--implementation/routing/src/event.cpp2
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp108
-rw-r--r--implementation/routing/src/remote_subscription.cpp3
-rw-r--r--implementation/routing/src/routing_manager_base.cpp12
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp250
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp102
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp4
12 files changed, 332 insertions, 180 deletions
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index 684a49b..b22b6ed 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -104,7 +104,7 @@ public:
void remove_subscriber(eventgroup_t _eventgroup, client_t _client);
bool has_subscriber(eventgroup_t _eventgroup, client_t _client);
std::set<client_t> get_subscribers();
- std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
+ VSOMEIP_EXPORT std::set<client_t> get_subscribers(eventgroup_t _eventgroup);
void clear_subscribers();
void add_ref(client_t _client, bool _is_provided);
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index 65f7e89..32ce5f2 100644
--- a/implementation/routing/include/eventgroupinfo.hpp
+++ b/implementation/routing/include/eventgroupinfo.hpp
@@ -71,6 +71,8 @@ public:
VSOMEIP_EXPORT void add_event(const std::shared_ptr<event>& _event);
VSOMEIP_EXPORT void remove_event(const std::shared_ptr<event>& _event);
VSOMEIP_EXPORT reliability_type_e get_reliability() const;
+ VSOMEIP_EXPORT void set_reliability(reliability_type_e _reliability);
+ VSOMEIP_EXPORT bool is_reliability_auto_mode() const;
VSOMEIP_EXPORT std::set<std::shared_ptr<remote_subscription>>
get_remote_subscriptions() const;
@@ -90,6 +92,8 @@ public:
VSOMEIP_EXPORT void remove_remote_subscription(
const remote_subscription_id_t _id);
+ void clear_remote_subscriptions();
+
VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
get_unicast_targets() const;
VSOMEIP_EXPORT std::set<std::shared_ptr<endpoint_definition> >
@@ -129,6 +133,7 @@ private:
remote_subscription_id_t id_;
std::atomic<reliability_type_e> reliability_;
+ std::atomic<bool> reliability_auto_mode_;
};
} // namespace vsomeip_v3
diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp
index 00f2b57..685aad9 100644
--- a/implementation/routing/include/remote_subscription.hpp
+++ b/implementation/routing/include/remote_subscription.hpp
@@ -43,7 +43,7 @@ public:
remote_subscription_id_t get_id() const;
void set_id(const remote_subscription_id_t _id);
- std::shared_ptr<remote_subscription> get_parent() const;
+ VSOMEIP_EXPORT std::shared_ptr<remote_subscription> get_parent() const;
void set_parent(const std::shared_ptr<remote_subscription> &_parent);
VSOMEIP_EXPORT std::shared_ptr<eventgroupinfo> get_eventgroupinfo() const;
@@ -87,7 +87,7 @@ public:
const bool _is_subscribe);
VSOMEIP_EXPORT std::uint32_t get_answers() const;
- void set_answers(const std::uint32_t _answers);
+ VSOMEIP_EXPORT void set_answers(const std::uint32_t _answers);
private:
std::atomic<remote_subscription_id_t> id_;
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index bead207..767d60e 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -153,8 +153,7 @@ public:
}
std::shared_ptr<endpoint> find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable,
- client_t _client);
+ service_t _service, instance_t _instance, bool _reliable);
void remove_local(client_t _client, bool _remove_uid);
void on_stop_offer_service(client_t _client,
@@ -230,7 +229,16 @@ public:
std::shared_ptr<remote_subscription> &_subscription);
void expire_subscriptions(const boost::asio::ip::address &_address);
+ void expire_subscriptions(const boost::asio::ip::address &_address,
+ std::uint16_t _port, bool _reliable);
+ void expire_subscriptions(const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range,
+ bool _reliable);
void expire_services(const boost::asio::ip::address &_address);
+ void expire_services(const boost::asio::ip::address &_address,
+ std::uint16_t _port , bool _reliable);
+ void expire_services(const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range , bool _reliable);
std::chrono::steady_clock::time_point expire_subscriptions(bool _force);
@@ -269,7 +277,9 @@ public:
void register_reboot_notification_handler(const reboot_notification_handler_t& _handler) const;
void register_routing_ready_handler(const routing_ready_handler_t& _handler);
void register_routing_state_handler(const routing_state_handler_t& _handler);
- void sd_acceptance_enabled(const boost::asio::ip::address& _address);
+ void sd_acceptance_enabled(const boost::asio::ip::address& _address,
+ const configuration::port_range_t& _range,
+ bool _reliable);
void on_resend_provided_events_response(pending_remote_offer_id_t _id);
bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy,
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index d1a29df..346e733 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -25,8 +25,6 @@ class configuration;
class event;
class routing_manager_host;
-class logger;
-
class routing_manager_proxy: public routing_manager_base {
public:
routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging,
@@ -252,8 +250,6 @@ private:
boost::asio::steady_timer register_application_timer_;
- std::shared_ptr<logger> logger_;
-
std::mutex request_timer_mutex_;
boost::asio::steady_timer request_debounce_timer_;
bool request_debounce_timer_running_;
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index 7575733..bc0ba3e 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -67,7 +67,7 @@ event_t event::get_event() const {
}
void event::set_event(event_t _event) {
- message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit
+ message_->set_method(_event);
}
event_type_e event::get_type() const {
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index 52c6c1e..3b3a808 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -25,7 +25,8 @@ eventgroupinfo::eventgroupinfo()
port_(ILLEGAL_PORT),
threshold_(0),
id_(PENDING_SUBSCRIPTION_ID),
- reliability_(reliability_type_e::RT_UNKNOWN) {
+ reliability_(reliability_type_e::RT_UNKNOWN),
+ reliability_auto_mode_(false) {
}
eventgroupinfo::eventgroupinfo(
@@ -40,7 +41,8 @@ eventgroupinfo::eventgroupinfo(
port_(ILLEGAL_PORT),
threshold_(0),
id_(PENDING_SUBSCRIPTION_ID),
- reliability_(reliability_type_e::RT_UNKNOWN) {
+ reliability_(reliability_type_e::RT_UNKNOWN),
+ reliability_auto_mode_(false) {
}
eventgroupinfo::~eventgroupinfo() {
@@ -124,6 +126,12 @@ void eventgroupinfo::add_event(const std::shared_ptr<event>& _event) {
std::lock_guard<std::mutex> its_lock(events_mutex_);
events_.insert(_event);
+ if (!reliability_auto_mode_ &&
+ _event->get_reliability() == reliability_type_e::RT_UNKNOWN) {
+ reliability_auto_mode_ = true;
+ return;
+ }
+
switch (_event->get_reliability()) {
case reliability_type_e::RT_RELIABLE:
if (reliability_ == reliability_type_e::RT_UNRELIABLE) {
@@ -156,6 +164,14 @@ reliability_type_e eventgroupinfo::get_reliability() const {
return reliability_;
}
+void eventgroupinfo::set_reliability(reliability_type_e _reliability) {
+ reliability_ = _reliability;
+}
+
+bool eventgroupinfo::is_reliability_auto_mode() const {
+ return reliability_auto_mode_;
+}
+
uint32_t
eventgroupinfo::get_unreliable_target_count() const {
uint32_t its_count(0);
@@ -228,6 +244,8 @@ eventgroupinfo::update_remote_subscription(
} else {
its_item.second->set_answers(
its_item.second->get_answers() + 1);
+ _subscription->set_parent(its_item.second);
+ _subscription->set_answers(0);
}
}
} else {
@@ -276,6 +294,12 @@ eventgroupinfo::remove_remote_subscription(
subscriptions_.erase(_id);
}
+void
+eventgroupinfo::clear_remote_subscriptions() {
+ std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
+ subscriptions_.clear();
+}
+
std::set<std::shared_ptr<endpoint_definition> >
eventgroupinfo::get_unicast_targets() const {
std::set<std::shared_ptr<endpoint_definition>> its_targets;
@@ -300,7 +324,7 @@ eventgroupinfo::get_multicast_targets() const {
}
bool eventgroupinfo::is_selective() const {
- /* Selective eventgroups always contain a single event */
+ // Selective eventgroups always contain a single event
std::lock_guard<std::mutex> its_lock(events_mutex_);
if (events_.size() != 1)
return false;
@@ -320,39 +344,57 @@ void
eventgroupinfo::send_initial_events(
const std::shared_ptr<endpoint_definition> &_reliable,
const std::shared_ptr<endpoint_definition> &_unreliable) const {
- std::lock_guard<std::mutex> its_lock(events_mutex_);
- for (const auto &its_event : events_) {
- if (its_event && its_event->get_type() == event_type_e::ET_FIELD) {
-#ifndef VSOMEIP_ENABLE_COMPAT
- const auto its_reliability = its_event->get_reliability();
- switch (its_reliability) {
- case reliability_type_e::RT_RELIABLE:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- break;
- case reliability_type_e::RT_UNRELIABLE:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- break;
- case reliability_type_e::RT_BOTH:
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- break;
- default:
- VSOMEIP_WARNING << __func__ << "Event reliability unknown: ["
- << std::hex << std::setw(4) << std::setfill('0') << service_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << instance_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "."
- << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]";
- }
-#else
- if (_reliable) {
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
- }
- if (_unreliable) {
- its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
- }
+
+ std::set<std::shared_ptr<event> > its_reliable_events, its_unreliable_events;
+
+ // Build sets of reliable/unreliable events first to avoid having to
+ // hold the "events_mutex_" in parallel to the internal event mutexes.
+ {
+ std::lock_guard<std::mutex> its_lock(events_mutex_);
+ for (const auto &its_event : events_) {
+ if (its_event && its_event->get_type() == event_type_e::ET_FIELD) {
+ auto its_reliability = its_event->get_reliability();
+#ifdef VSOMEIP_ENABLE_COMPAT
+ if (its_reliability == reliability_type_e::RT_UNKNOWN) {
+ if (_reliable) {
+ if (_unreliable) {
+ its_reliability = reliability_type_e::RT_BOTH;
+ } else {
+ its_reliability = reliability_type_e::RT_RELIABLE;
+ }
+ } else if (_unreliable) {
+ its_reliability = reliability_type_e::RT_UNRELIABLE;
+ }
+ }
#endif
+ switch (its_reliability) {
+ case reliability_type_e::RT_RELIABLE:
+ its_reliable_events.insert(its_event);
+ break;
+ case reliability_type_e::RT_UNRELIABLE:
+ its_unreliable_events.insert(its_event);
+ break;
+ case reliability_type_e::RT_BOTH:
+ its_reliable_events.insert(its_event);
+ its_unreliable_events.insert(its_event);
+ break;
+ default:
+ VSOMEIP_WARNING << __func__ << "Event reliability unknown: ["
+ << std::hex << std::setw(4) << std::setfill('0') << service_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << instance_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "."
+ << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]";
+ }
+ }
}
}
+
+ // Send events
+ for (const auto its_event : its_reliable_events)
+ its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable);
+
+ for (const auto its_event : its_unreliable_events)
+ its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable);
}
} // namespace vsomeip_v3
diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp
index a896b36..939e0d1 100644
--- a/implementation/routing/src/remote_subscription.cpp
+++ b/implementation/routing/src/remote_subscription.cpp
@@ -178,7 +178,8 @@ remote_subscription::set_client_state(const client_t _client,
if (found_item->second.second == std::chrono::steady_clock::time_point()
&& (_state == remote_subscription_state_e::SUBSCRIPTION_ACKED
|| _state == remote_subscription_state_e::SUBSCRIPTION_NACKED)) {
- found_item->second.second = std::chrono::steady_clock::now();
+ found_item->second.second = std::chrono::steady_clock::now()
+ + std::chrono::seconds(ttl_);
}
}
}
diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp
index 77e5b83..5b1149e 100644
--- a/implementation/routing/src/routing_manager_base.cpp
+++ b/implementation/routing/src/routing_manager_base.cpp
@@ -1265,11 +1265,15 @@ std::shared_ptr<serializer> routing_manager_base::get_serializer() {
std::unique_lock<std::mutex> its_lock(serializer_mutex_);
while (serializers_.empty()) {
- VSOMEIP_INFO << std::hex << "client " << get_client() <<
- "routing_manager_base::get_serializer ~> all in use!";
+ VSOMEIP_INFO << __func__ << ": Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << get_client()
+ << " has no available serializer. Waiting...";
serializer_condition_.wait(its_lock);
- VSOMEIP_INFO << std::hex << "client " << get_client() <<
- "routing_manager_base::get_serializer ~> wait finished!";
+ VSOMEIP_INFO << __func__ << ": Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << get_client()
+ << " now checking for available serializer.";
}
auto its_serializer = serializers_.front();
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index 48e2cb5..c132569 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -162,9 +162,17 @@ void routing_manager_impl::init() {
void routing_manager_impl::start() {
#ifndef _WIN32
- netlink_connector_ = std::make_shared<netlink_connector>(host_->get_io(),
- configuration_->get_unicast_address(),
- boost::asio::ip::address::from_string(configuration_->get_sd_multicast()));
+ boost::asio::ip::address its_multicast;
+ try {
+ its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast());
+ } catch (...) {
+ VSOMEIP_ERROR << "Illegal multicast address \""
+ << configuration_->get_sd_multicast()
+ << "\". Please check your configuration.";
+ }
+
+ netlink_connector_ = std::make_shared<netlink_connector>(
+ host_->get_io(), configuration_->get_unicast_address(), its_multicast);
netlink_connector_->register_net_if_changes_handler(
std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed,
this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
@@ -326,7 +334,7 @@ bool routing_manager_impl::offer_service(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << std::dec << _minor << "]"
- << " (" << _must_queue << ")";
+ << " (" << std::boolalpha << _must_queue << ")";
// only queue commands if method was NOT called via erase_offer_command()
if (_must_queue) {
@@ -420,7 +428,7 @@ void routing_manager_impl::stop_offer_service(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << _minor << "]"
- << " (" << _must_queue << ")";
+ << " (" << std::boolalpha << _must_queue << ")";
if (_must_queue) {
if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE,
@@ -505,7 +513,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
}
its_info->add_client(_client);
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, true);
}
}
}
@@ -617,7 +625,8 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid,
if (its_info) {
discovery_->subscribe(_service, _instance, _eventgroup,
_major, configured_ttl,
- its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
+ its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT,
+ its_info);
}
} else {
its_critical.unlock();
@@ -653,7 +662,6 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
bool last_subscriber_removed(true);
- auto its_event = find_event(_service, _instance, _event);
std::shared_ptr<eventgroupinfo> its_info
= find_eventgroup(_service, _instance, _eventgroup);
if (its_info) {
@@ -682,12 +690,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid,
}
}
- if (last_subscriber_removed
- || (its_event && its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT)) {
- if (its_info) {
- discovery_->unsubscribe(_service, _instance, _eventgroup,
- its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
- }
+ if (its_info &&
+ (last_subscriber_removed || its_info->is_selective())) {
+
+ discovery_->unsubscribe(_service, _instance, _eventgroup,
+ its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT);
}
} else {
if (get_client() == _client) {
@@ -797,9 +804,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
}
}
if (is_request) {
- client_t client = VSOMEIP_ROUTING_CLIENT;
its_target = ep_mgr_impl_->find_or_create_remote_client(
- its_service, _instance, _reliable, client);
+ its_service, _instance, _reliable);
if (its_target) {
#ifdef USE_DLT
const uint16_t its_data_size
@@ -1089,7 +1095,7 @@ void routing_manager_impl::register_event(client_t _client,
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << _notifier
- << ":is_provider=" << _is_provided << "]";
+ << ":is_provider=" << std::boolalpha << _is_provided << "]";
}
void routing_manager_impl::register_shadow_event(client_t _client,
@@ -1681,6 +1687,17 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se
}
erase_offer_command(_service, _instance);
}
+
+ std::lock_guard<std::mutex> its_eventgroups_lock(eventgroups_mutex_);
+ auto find_service = eventgroups_.find(_service);
+ if (find_service != eventgroups_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ for (auto e : find_instance->second) {
+ e.second->clear_remote_subscriptions();
+ }
+ }
+ }
} else {
erase_offer_command(_service, _instance);
}
@@ -2186,10 +2203,10 @@ void routing_manager_impl::add_routing_info(
if (udp_inserted) {
// atomically create reliable and unreliable endpoint
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance);
} else {
ep_mgr_impl_->find_or_create_remote_client(
- _service, _instance, true, VSOMEIP_ROUTING_CLIENT);
+ _service, _instance, true);
}
connected = true;
}
@@ -2265,7 +2282,7 @@ void routing_manager_impl::add_routing_info(
== ANY_MINOR)) {
if(!connected) {
ep_mgr_impl_->find_or_create_remote_client(_service, _instance,
- false, VSOMEIP_ROUTING_CLIENT);
+ false);
connected = true;
}
its_info->add_client(client_id.first);
@@ -2463,45 +2480,59 @@ void routing_manager_impl::update_routing_info(std::chrono::milliseconds _elapse
}
}
-void routing_manager_impl::expire_services(const boost::asio::ip::address &_address) {
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address) {
+ expire_services(_address, configuration::port_range_t(ANY_PORT, ANY_PORT),
+ false);
+}
+
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address, std::uint16_t _port,
+ bool _reliable) {
+ expire_services(_address, configuration::port_range_t(_port, _port),
+ _reliable);
+}
+
+void routing_manager_impl::expire_services(
+ const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range, bool _reliable) {
std::map<service_t, std::vector<instance_t> > its_expired_offers;
+ const bool expire_all = (_range.first == ANY_PORT
+ && _range.second == ANY_PORT);
+
for (auto &s : get_services_remote()) {
for (auto &i : s.second) {
- bool is_gone(false);
boost::asio::ip::address its_address;
std::shared_ptr<client_endpoint> its_client_endpoint =
std::dynamic_pointer_cast<client_endpoint>(
- i.second->get_endpoint(true));
+ i.second->get_endpoint(_reliable));
+ if (!its_client_endpoint && expire_all) {
+ its_client_endpoint = std::dynamic_pointer_cast<client_endpoint>(
+ i.second->get_endpoint(!_reliable));
+ }
if (its_client_endpoint) {
- if (its_client_endpoint->get_remote_address(its_address)) {
- is_gone = (its_address == _address);
- }
- } else {
- its_client_endpoint =
- std::dynamic_pointer_cast<client_endpoint>(
- i.second->get_endpoint(false));
- if (its_client_endpoint) {
- if (its_client_endpoint->get_remote_address(its_address)) {
- is_gone = (its_address == _address);
+ if ((expire_all || (its_client_endpoint->get_remote_port() >= _range.first
+ && its_client_endpoint->get_remote_port() <= _range.second))
+ && its_client_endpoint->get_remote_address(its_address)
+ && its_address == _address) {
+ if (discovery_) {
+ discovery_->unsubscribe_all(s.first, i.first);
}
+ its_expired_offers[s.first].push_back(i.first);
}
}
-
- if (is_gone) {
- if (discovery_)
- discovery_->unsubscribe_all(s.first, i.first);
- its_expired_offers[s.first].push_back(i.first);
- }
}
}
for (auto &s : its_expired_offers) {
for (auto &i : s.second) {
- VSOMEIP_INFO << "expire_services for address: " << _address.to_string()
+ VSOMEIP_INFO << "expire_services for address: " << _address
<< " : delete service/instance "
<< std::hex << std::setw(4) << std::setfill('0') << s.first
- << "." << std::hex << std::setw(4) << std::setfill('0') << i;
+ << "." << std::hex << std::setw(4) << std::setfill('0') << i
+ << " port [" << std::dec << _range.first << "," << _range.second
+ << "] reliability=" << std::boolalpha << _reliable;
del_routing_info(s.first, i, true, true);
}
}
@@ -2510,49 +2541,74 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr
void
routing_manager_impl::expire_subscriptions(
const boost::asio::ip::address &_address) {
- {
- std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
- for (const auto &its_service : eventgroups_) {
- for (const auto &its_instance : its_service.second) {
- for (const auto &its_eventgroup : its_instance.second) {
- const auto its_info = its_eventgroup.second;
- for (auto its_subscription
- : its_info->get_remote_subscriptions()) {
- // Note: get_remote_subscription delivers a copied
- // set of subscriptions. Thus, its is possible to
- // to remove them within the loop.
- const auto its_reliable = its_subscription->get_reliable();
- const auto its_unreliable = its_subscription->get_unreliable();
- if ((its_reliable && its_reliable->get_address() == _address)
- || (its_unreliable && its_unreliable->get_address() == _address)) {
-
- // TODO: Check whether subscriptions to different hosts are valid.
- // IF yes, we probably need to simply reset the corresponding
- // endpoint instead of removing the subscription...
-
- if (its_reliable) {
- VSOMEIP_ERROR << __func__
- << ": removing subscription to "
- << std::hex << its_info->get_service() << "."
- << std::hex << its_info->get_instance() << "."
- << std::hex << its_info->get_eventgroup()
- << " from target "
- << its_reliable->get_address().to_string() << ":"
- << std::dec << its_reliable->get_port();
- }
- if (its_unreliable) {
+ expire_subscriptions(_address,
+ configuration::port_range_t(ANY_PORT, ANY_PORT), false);
+}
+
+void
+routing_manager_impl::expire_subscriptions(
+ const boost::asio::ip::address &_address, std::uint16_t _port,
+ bool _reliable) {
+ expire_subscriptions(_address, configuration::port_range_t(_port, _port),
+ _reliable);
+}
+
+void
+routing_manager_impl::expire_subscriptions(
+ const boost::asio::ip::address &_address,
+ const configuration::port_range_t& _range, bool _reliable) {
+ const bool expire_all = (_range.first == ANY_PORT
+ && _range.second == ANY_PORT);
+
+ std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
+ for (const auto &its_service : eventgroups_) {
+ for (const auto &its_instance : its_service.second) {
+ for (const auto &its_eventgroup : its_instance.second) {
+ const auto its_info = its_eventgroup.second;
+ for (auto its_subscription
+ : its_info->get_remote_subscriptions()) {
+ // Note: get_remote_subscription delivers a copied
+ // set of subscriptions. Thus, its is possible to
+ // to remove them within the loop.
+ const auto its_ep_definition =
+ (_reliable) ? its_subscription->get_reliable() :
+ its_subscription->get_unreliable();
+
+ if (its_ep_definition
+ && its_ep_definition->get_address() == _address
+ && (expire_all ||
+ (its_ep_definition->get_remote_port() >= _range.first
+ && its_ep_definition->get_remote_port() <= _range.second))) {
+
+ // TODO: Check whether subscriptions to different hosts are valid.
+ // IF yes, we probably need to simply reset the corresponding
+ // endpoint instead of removing the subscription...
+ VSOMEIP_ERROR << __func__
+ << ": removing subscription to "
+ << std::hex << its_info->get_service() << "."
+ << std::hex << its_info->get_instance() << "."
+ << std::hex << its_info->get_eventgroup()
+ << " from target "
+ << its_ep_definition->get_address() << ":"
+ << std::dec << its_ep_definition->get_port()
+ << " reliable=" << _reliable;
+ if (expire_all) {
+ const auto its_ep_definition2 =
+ (!_reliable) ? its_subscription->get_reliable() :
+ its_subscription->get_unreliable();
+ if (its_ep_definition2) {
VSOMEIP_ERROR << __func__
<< ": removing subscription to "
<< std::hex << its_info->get_service() << "."
<< std::hex << its_info->get_instance() << "."
<< std::hex << its_info->get_eventgroup()
<< " from target "
- << its_unreliable->get_address().to_string() << ":"
- << std::dec << its_unreliable->get_port();
+ << its_ep_definition2->get_address() << ":"
+ << std::dec << its_ep_definition2->get_port()
+ << " reliable=" << !_reliable;
}
-
- on_remote_unsubscribe(its_subscription);
}
+ on_remote_unsubscribe(its_subscription);
}
}
}
@@ -2570,22 +2626,34 @@ void routing_manager_impl::init_routing_info() {
= configuration_->get_reliable_port(i.first, i.second);
uint16_t its_unreliable_port
= configuration_->get_unreliable_port(i.first, i.second);
+ major_version_t its_major
+ = configuration_->get_major_version(i.first, i.second);
+ minor_version_t its_minor
+ = configuration_->get_minor_version(i.first, i.second);
+ ttl_t its_ttl
+ = configuration_->get_ttl(i.first, i.second);
if (its_reliable_port != ILLEGAL_PORT
|| its_unreliable_port != ILLEGAL_PORT) {
+ VSOMEIP_INFO << "Adding static remote service ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << i.first << "." << i.second
+ << std::dec << ":" << +its_major << "." << its_minor
+ << "]";
+
add_routing_info(i.first, i.second,
- DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL,
+ its_major, its_minor, its_ttl,
its_address, its_reliable_port,
its_address, its_unreliable_port);
if(its_reliable_port != ILLEGAL_PORT) {
ep_mgr_impl_->find_or_create_remote_client(
- i.first, i.second, true, VSOMEIP_ROUTING_CLIENT);
+ i.first, i.second, true);
}
if(its_unreliable_port != ILLEGAL_PORT) {
ep_mgr_impl_->find_or_create_remote_client(
- i.first, i.second, false, VSOMEIP_ROUTING_CLIENT);
+ i.first, i.second, false);
}
}
}
@@ -2660,6 +2728,7 @@ void routing_manager_impl::on_remote_subscribe(
if (its_reliable && its_unreliable)
its_warning << "]";
VSOMEIP_WARNING << its_warning.str();
+ _callback(_subscription);
}
} else { // new subscription
auto its_id
@@ -2810,10 +2879,9 @@ void routing_manager_impl::on_subscribe_ack(client_t _client,
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
- service_t _service, instance_t _instance, bool _reliable,
- client_t _client) {
+ service_t _service, instance_t _instance, bool _reliable) {
return ep_mgr_impl_->find_or_create_remote_client(_service,
- _instance, _reliable, _client);
+ _instance, _reliable);
}
void routing_manager_impl::on_subscribe_nack(client_t _client,
@@ -3082,7 +3150,7 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const
#ifndef VSOMEIP_VERSION
#define VSOMEIP_VERSION "unknown version"
#endif
- static int counter(0);
+ static int its_counter(0);
static uint32_t its_interval = configuration_->get_log_version_interval();
bool is_diag_mode(false);
@@ -3104,11 +3172,11 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const
<< ((is_diag_mode == true) ? "diagnosis)" : "default)")
<< its_last_resume.str();
- counter++;
- if (counter == 6) {
+ its_counter++;
+ if (its_counter == 6) {
ep_mgr_->log_client_states();
ep_mgr_impl_->log_client_states();
- counter = 0;
+ its_counter = 0;
}
{
@@ -3852,12 +3920,10 @@ void routing_manager_impl::register_routing_state_handler(
}
void routing_manager_impl::sd_acceptance_enabled(
- const boost::asio::ip::address& _address) {
- boost::system::error_code ec;
- VSOMEIP_INFO << "ipsec-plugin-mgu: expire subscriptions and services: "
- << _address.to_string(ec);
- expire_subscriptions(_address);
- expire_services(_address);
+ const boost::asio::ip::address& _address,
+ const configuration::port_range_t& _range, bool _reliable) {
+ expire_subscriptions(_address, _range, _reliable);
+ expire_services(_address, _range, _reliable);
}
void routing_manager_impl::memory_log_timer_cbk(
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index 8135c3f..3b95a2d 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -45,7 +45,6 @@ routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host,
sender_(nullptr),
receiver_(nullptr),
register_application_timer_(io_),
- logger_(logger::get()),
request_debounce_timer_ (io_),
request_debounce_timer_running_(false),
client_side_logging_(_client_side_logging),
@@ -342,9 +341,35 @@ void routing_manager_proxy::register_event(client_t _client,
std::lock_guard<std::mutex> its_lock(state_mutex_);
is_first = pending_event_registrations_.find(registration)
== pending_event_registrations_.end();
+#ifndef VSOMEIP_ENABLE_COMPAT
if (is_first) {
pending_event_registrations_.insert(registration);
}
+#else
+ bool insert = true;
+ if (is_first) {
+ for (auto iter = pending_event_registrations_.begin();
+ iter != pending_event_registrations_.end();) {
+ if (iter->service_ == _service
+ && iter->instance_ == _instance
+ && iter->notifier_ == _notifier
+ && iter->is_provided_ == _is_provided
+ && iter->type_ == event_type_e::ET_EVENT
+ && _type == event_type_e::ET_SELECTIVE_EVENT) {
+ iter = pending_event_registrations_.erase(iter);
+ iter = pending_event_registrations_.insert(registration).first;
+ is_first = true;
+ insert = false;
+ break;
+ } else {
+ iter++;
+ }
+ }
+ if (insert) {
+ pending_event_registrations_.insert(registration);
+ }
+ }
+#endif
}
if (is_first || _is_provided) {
routing_manager_base::register_event(_client,
@@ -399,17 +424,19 @@ void routing_manager_proxy::unregister_event(client_t _client,
}
}
}
- auto it = pending_event_registrations_.begin();
- while (it != pending_event_registrations_.end()) {
- if (it->service_ == _service
- && it->instance_ == _instance
- && it->notifier_ == _notifier) {
+
+ for (auto iter = pending_event_registrations_.begin();
+ iter != pending_event_registrations_.end(); ) {
+ if (iter->service_ == _service
+ && iter->instance_ == _instance
+ && iter->notifier_ == _notifier
+ && iter->is_provided_ == _is_provided) {
+ pending_event_registrations_.erase(iter);
break;
+ } else {
+ iter++;
}
- it++;
}
- if (it != pending_event_registrations_.end())
- pending_event_registrations_.erase(it);
}
}
@@ -455,7 +482,7 @@ void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid,
std::lock_guard<std::mutex> its_lock(state_mutex_);
if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) {
- send_subscribe(_client, _service, _instance, _eventgroup, _major, _event );
+ send_subscribe(client_, _service, _instance, _eventgroup, _major, _event );
}
subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid};
pending_subscriptions_.insert(subscription);
@@ -1548,20 +1575,23 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
return;
}
#endif
-
- // inform host about its own registration state changes
- host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
-
{
std::lock_guard<std::mutex> its_lock(state_mutex_);
- boost::system::error_code ec;
- register_application_timer_.cancel(ec);
- send_registered_ack();
- send_pending_commands();
- state_ = inner_state_type_e::ST_REGISTERED;
- // Notify stop() call about clean deregistration
- state_condition_.notify_one();
+ if (state_ == inner_state_type_e::ST_REGISTERING) {
+ boost::system::error_code ec;
+ register_application_timer_.cancel(ec);
+ send_registered_ack();
+ send_pending_commands();
+ state_ = inner_state_type_e::ST_REGISTERED;
+ // Notify stop() call about clean deregistration
+ state_condition_.notify_one();
+ }
}
+
+ // inform host about its own registration state changes
+ if (state_ == inner_state_type_e::ST_REGISTERED)
+ host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_REGISTERED));
+
}
} else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) {
{
@@ -2278,25 +2308,23 @@ routing_manager_proxy::assign_client_timeout_cbk(
void routing_manager_proxy::register_application_timeout_cbk(
boost::system::error_code const &_error) {
- if (!_error) {
- bool register_again(false);
- {
- std::lock_guard<std::mutex> its_lock(state_mutex_);
- if (state_ != inner_state_type_e::ST_REGISTERED) {
- state_ = inner_state_type_e::ST_DEREGISTERED;
- register_again = true;
- }
- }
- if (register_again) {
- std::lock_guard<std::mutex> its_lock(sender_mutex_);
- VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
- << " register timeout! Trying again...";
- if (sender_) {
- sender_->restart();
- }
+ bool register_again(false);
+ {
+ std::lock_guard<std::mutex> its_lock(state_mutex_);
+ if (!_error && state_ != inner_state_type_e::ST_REGISTERED) {
+ state_ = inner_state_type_e::ST_DEREGISTERED;
+ register_again = true;
}
}
+ if (register_again) {
+ std::lock_guard<std::mutex> its_lock(sender_mutex_);
+ VSOMEIP_WARNING << std::hex << "Client 0x" << get_client()
+ << " register timeout! Trying again...";
+
+ if (sender_)
+ sender_->restart();
+ }
}
void routing_manager_proxy::send_registered_ack() {
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 65945f7..d7a1dd2 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -784,8 +784,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
void routing_manager_stub::on_register_application(client_t _client) {
auto endpoint = host_->find_local(_client);
if (endpoint) {
- VSOMEIP_ERROR << "Registering application: " << std::hex << _client
- << " failed. It is already registered!";
+ VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client
+ << ". Last registration might have been taken too long.";
} else {
(void)host_->find_or_create_local(_client);
std::lock_guard<std::mutex> its_lock(routing_info_mutex_);