Skip to content

Commit

Permalink
Allow to configure the initial routing state
Browse files Browse the repository at this point in the history
Summary
Allow to configure the initial routing state to allow suspended startup
Details
Add a configuration parameter service-discovery.initial_state to allow the configuration of the behavior
on startup. Additionally, ensure that new endpoints that are created while the routing is suspended are
not started. This will happen on the next resume.
  • Loading branch information
lutzbichler authored and duartenfonseca committed Nov 28, 2024
1 parent 4788c99 commit 93b7757
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 130 deletions.
5 changes: 5 additions & 0 deletions documentation/vsomeipUserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,11 @@ Configuration file element explanation:
Specifies whether the Service Discovery is enabled (valid values: _true_,
_false_). The default value is _true_.

* `initial_state`

Specifies the initial Service Discovery state after startup
(valid values: _unknown_, _suspended_, _resumed_). The default value is _unknown_.

* `multicast`

The multicast address which the messages of the Service Discovery will be sent
Expand Down
1 change: 1 addition & 0 deletions implementation/configuration/include/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class configuration {
uid_t _uid, gid_t _gid) const = 0;

virtual bool is_local_routing() const = 0;
virtual routing_state_e get_initial_routing_state() const = 0;

virtual std::string get_unicast_address(service_t _service,
instance_t _instance) const = 0;
Expand Down
6 changes: 5 additions & 1 deletion implementation/configuration/include/configuration_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class configuration_impl:

VSOMEIP_EXPORT bool is_routing_enabled() const;
VSOMEIP_EXPORT bool is_local_routing() const;
VSOMEIP_EXPORT routing_state_e get_initial_routing_state() const;

VSOMEIP_EXPORT const std::string &get_routing_host_name() const;
VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_host_address() const;
Expand Down Expand Up @@ -606,7 +607,8 @@ class configuration_impl:
ET_PARTITIONS,
ET_SECURITY_AUDIT_MODE,
ET_SECURITY_REMOTE_ACCESS,
ET_MAX = 46
ET_INITIAL_ROUTING_STATE,
ET_MAX = 47
};

bool is_configured_[ET_MAX];
Expand Down Expand Up @@ -683,6 +685,8 @@ class configuration_impl:
std::atomic_bool is_security_external_;
std::atomic_bool is_security_audit_;
std::atomic_bool is_remote_access_allowed_;

routing_state_e initial_routing_state_;
};

} // namespace cfg
Expand Down
167 changes: 78 additions & 89 deletions implementation/configuration/src/configuration_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,69 +44,45 @@
namespace vsomeip_v3 {
namespace cfg {

configuration_impl::configuration_impl(const std::string &_path)
: default_unicast_("local"),
is_loaded_(false),
is_logging_loaded_(false),
prefix_(VSOMEIP_PREFIX),
diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS),
diagnosis_mask_(0xFF00),
has_console_log_(true),
has_file_log_(false),
has_dlt_log_(false),
logfile_("/tmp/vsomeip.log"),
loglevel_(vsomeip_v3::logger::level_e::LL_INFO),
is_sd_enabled_(VSOMEIP_SD_DEFAULT_ENABLED),
sd_protocol_(VSOMEIP_SD_DEFAULT_PROTOCOL),
sd_multicast_(VSOMEIP_SD_DEFAULT_MULTICAST),
sd_port_(VSOMEIP_SD_DEFAULT_PORT),
sd_initial_delay_min_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN),
sd_initial_delay_max_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX),
sd_repetitions_base_delay_(VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY),
sd_repetitions_max_(VSOMEIP_SD_DEFAULT_REPETITIONS_MAX),
sd_ttl_(VSOMEIP_SD_DEFAULT_TTL),
sd_cyclic_offer_delay_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY),
sd_request_response_delay_(VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY),
sd_offer_debounce_time_(VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME),
sd_find_debounce_time_(VSOMEIP_SD_DEFAULT_FIND_DEBOUNCE_TIME),
max_configured_message_size_(0),
max_local_message_size_(0),
max_reliable_message_size_(0),
max_unreliable_message_size_(0),
buffer_shrink_threshold_(VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD),
trace_(std::make_shared<trace>()),
watchdog_(std::make_shared<watchdog>()),
log_version_(true),
log_version_interval_(10),
permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS),
network_("vsomeip"),
e2e_enabled_(false),
log_memory_(false),
log_memory_interval_(0),
log_status_(false),
log_status_interval_(0),
endpoint_queue_limit_external_(QUEUE_SIZE_UNLIMITED),
endpoint_queue_limit_local_(QUEUE_SIZE_UNLIMITED),
tcp_restart_aborts_max_(VSOMEIP_MAX_TCP_RESTART_ABORTS),
tcp_connect_time_max_(VSOMEIP_MAX_TCP_CONNECT_TIME),
has_issued_methods_warning_(false),
has_issued_clients_warning_(false),
udp_receive_buffer_size_(VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE),
npdu_default_debounce_requ_(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO),
npdu_default_debounce_resp_(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO),
npdu_default_max_retention_requ_(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO),
npdu_default_max_retention_resp_(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO),
shutdown_timeout_(VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT),
log_statistics_(true),
statistics_interval_(VSOMEIP_DEFAULT_STATISTICS_INTERVAL),
statistics_min_freq_(VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ),
statistics_max_messages_(VSOMEIP_DEFAULT_STATISTICS_MAX_MSG),
max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS),
path_(_path),
is_security_enabled_(false),
is_security_external_(false),
is_security_audit_(false),
is_remote_access_allowed_(true) {
configuration_impl::configuration_impl(const std::string& _path) :
default_unicast_ {"local"}, is_loaded_ {false}, is_logging_loaded_ {false},
prefix_ {VSOMEIP_PREFIX}, diagnosis_ {VSOMEIP_DIAGNOSIS_ADDRESS}, diagnosis_mask_ {0xFF00},
has_console_log_ {true}, has_file_log_ {false}, has_dlt_log_ {false},
logfile_ {"/tmp/vsomeip.log"}, loglevel_ {vsomeip_v3::logger::level_e::LL_INFO},
is_sd_enabled_ {VSOMEIP_SD_DEFAULT_ENABLED}, sd_protocol_ {VSOMEIP_SD_DEFAULT_PROTOCOL},
sd_multicast_ {VSOMEIP_SD_DEFAULT_MULTICAST}, sd_port_ {VSOMEIP_SD_DEFAULT_PORT},
sd_initial_delay_min_ {VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN},
sd_initial_delay_max_ {VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX},
sd_repetitions_base_delay_ {VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY},
sd_repetitions_max_ {VSOMEIP_SD_DEFAULT_REPETITIONS_MAX}, sd_ttl_ {VSOMEIP_SD_DEFAULT_TTL},
sd_cyclic_offer_delay_ {VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY},
sd_request_response_delay_ {VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY},
sd_offer_debounce_time_ {VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME},
sd_find_debounce_time_ {VSOMEIP_SD_DEFAULT_FIND_DEBOUNCE_TIME},
max_configured_message_size_ {0}, max_local_message_size_ {0}, max_reliable_message_size_ {0},
max_unreliable_message_size_ {0},
buffer_shrink_threshold_ {VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD},
trace_ {std::make_shared<trace>()}, watchdog_ {std::make_shared<watchdog>()},
log_version_ {true}, log_version_interval_ {10},
permissions_uds_ {VSOMEIP_DEFAULT_UDS_PERMISSIONS}, network_ {"vsomeip"}, e2e_enabled_ {false},
log_memory_ {false}, log_memory_interval_ {0}, log_status_ {false}, log_status_interval_ {0},
endpoint_queue_limit_external_ {QUEUE_SIZE_UNLIMITED},
endpoint_queue_limit_local_ {QUEUE_SIZE_UNLIMITED},
tcp_restart_aborts_max_ {VSOMEIP_MAX_TCP_RESTART_ABORTS},
tcp_connect_time_max_ {VSOMEIP_MAX_TCP_CONNECT_TIME}, has_issued_methods_warning_ {false},
has_issued_clients_warning_ {false},
udp_receive_buffer_size_ {VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE},
npdu_default_debounce_requ_ {VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO},
npdu_default_debounce_resp_ {VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO},
npdu_default_max_retention_requ_ {VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO},
npdu_default_max_retention_resp_ {VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO},
shutdown_timeout_ {VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT}, log_statistics_ {true},
statistics_interval_ {VSOMEIP_DEFAULT_STATISTICS_INTERVAL},
statistics_min_freq_ {VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ},
statistics_max_messages_ {VSOMEIP_DEFAULT_STATISTICS_MAX_MSG},
max_remote_subscribers_ {VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS}, path_ {_path},
is_security_enabled_ {false}, is_security_external_ {false}, is_security_audit_ {false},
is_remote_access_allowed_ {true}, initial_routing_state_ {routing_state_e::RS_UNKNOWN} {

policy_manager_ = std::make_shared<policy_manager_impl>();
security_ = std::make_shared<security>(policy_manager_);
Expand All @@ -123,32 +99,29 @@ configuration_impl::configuration_impl(const std::string &_path)
#endif
}

configuration_impl::configuration_impl(const configuration_impl &_other)
: std::enable_shared_from_this<configuration_impl>(_other),
default_unicast_(_other.default_unicast_),
is_loaded_(_other.is_loaded_),
is_logging_loaded_(_other.is_logging_loaded_),
mandatory_(_other.mandatory_),
has_console_log_(_other.has_console_log_.load()),
has_file_log_(_other.has_file_log_.load()),
has_dlt_log_(_other.has_dlt_log_.load()),
max_configured_message_size_(_other.max_configured_message_size_),
max_local_message_size_(_other.max_local_message_size_),
max_reliable_message_size_(_other.max_reliable_message_size_),
max_unreliable_message_size_(_other.max_unreliable_message_size_),
buffer_shrink_threshold_(_other.buffer_shrink_threshold_),
permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS),
endpoint_queue_limit_external_(_other.endpoint_queue_limit_external_),
endpoint_queue_limit_local_(_other.endpoint_queue_limit_local_),
tcp_restart_aborts_max_(_other.tcp_restart_aborts_max_),
tcp_connect_time_max_(_other.tcp_connect_time_max_),
udp_receive_buffer_size_(_other.udp_receive_buffer_size_),
npdu_default_debounce_requ_(_other.npdu_default_debounce_requ_),
npdu_default_debounce_resp_(_other.npdu_default_debounce_resp_),
npdu_default_max_retention_requ_(_other.npdu_default_max_retention_requ_),
npdu_default_max_retention_resp_(_other.npdu_default_max_retention_resp_),
shutdown_timeout_(_other.shutdown_timeout_),
path_(_other.path_) {
configuration_impl::configuration_impl(const configuration_impl& _other) :
std::enable_shared_from_this<configuration_impl>(_other),
default_unicast_ {_other.default_unicast_}, is_loaded_ {_other.is_loaded_},
is_logging_loaded_ {_other.is_logging_loaded_}, mandatory_ {_other.mandatory_},
has_console_log_ {_other.has_console_log_.load()}, has_file_log_ {_other.has_file_log_.load()},
has_dlt_log_ {_other.has_dlt_log_.load()},
max_configured_message_size_ {_other.max_configured_message_size_},
max_local_message_size_ {_other.max_local_message_size_},
max_reliable_message_size_ {_other.max_reliable_message_size_},
max_unreliable_message_size_ {_other.max_unreliable_message_size_},
buffer_shrink_threshold_ {_other.buffer_shrink_threshold_},
permissions_uds_ {VSOMEIP_DEFAULT_UDS_PERMISSIONS},
endpoint_queue_limit_external_ {_other.endpoint_queue_limit_external_},
endpoint_queue_limit_local_ {_other.endpoint_queue_limit_local_},
tcp_restart_aborts_max_ {_other.tcp_restart_aborts_max_},
tcp_connect_time_max_ {_other.tcp_connect_time_max_},
udp_receive_buffer_size_ {_other.udp_receive_buffer_size_},
npdu_default_debounce_requ_ {_other.npdu_default_debounce_requ_},
npdu_default_debounce_resp_ {_other.npdu_default_debounce_resp_},
npdu_default_max_retention_requ_ {_other.npdu_default_max_retention_requ_},
npdu_default_max_retention_resp_ {_other.npdu_default_max_retention_resp_},
shutdown_timeout_ {_other.shutdown_timeout_}, path_ {_other.path_},
initial_routing_state_ {_other.initial_routing_state_} {

applications_.insert(_other.applications_.begin(), _other.applications_.end());
client_identifiers_ = _other.client_identifiers_;
Expand Down Expand Up @@ -1877,6 +1850,18 @@ void configuration_impl::load_service_discovery(
}
is_configured_[ET_MAX_REMOTE_SUBSCRIBERS] = true;
}
} else if (its_key == "initial_state") {
if (is_configured_[ET_INITIAL_ROUTING_STATE]) {
VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_state."
" Ignoring definition from "
<< _element.name_;
} else {
if (its_value == "suspended") {
initial_routing_state_ = routing_state_e::RS_SUSPENDED;
} else if (its_value == "resumed") {
initial_routing_state_ = routing_state_e::RS_RESUMED;
}
}
}
}
} catch (...) {
Expand Down Expand Up @@ -5065,5 +5050,9 @@ std::shared_ptr<security> configuration_impl::get_security() const {
return security_;
}

routing_state_e configuration_impl::get_initial_routing_state() const {
return initial_routing_state_;
}

} // namespace cfg
} // namespace vsomeip_v3
65 changes: 33 additions & 32 deletions implementation/endpoints/src/endpoint_manager_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@

namespace vsomeip_v3 {

endpoint_manager_impl::endpoint_manager_impl(
routing_manager_base* const _rm, boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _configuration) :
endpoint_manager_base(_rm, _io, _configuration),
is_processing_options_(true),
options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) {
endpoint_manager_impl::endpoint_manager_impl(routing_manager_base* const _rm,
boost::asio::io_context& _io,
const std::shared_ptr<configuration>& _configuration) :
endpoint_manager_base(_rm, _io, _configuration), is_processing_options_(true),
options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) {

local_port_ = port_t(_configuration->get_routing_host_port() + 1);
if (!is_local_routing_) {
Expand Down Expand Up @@ -71,8 +70,8 @@ std::shared_ptr<endpoint> endpoint_manager_impl::find_or_create_remote_client(
start_endpoint = true;
}
}
if (start_endpoint && its_endpoint
&& configuration_->is_someip(_service, _instance)) {
if (start_endpoint && its_endpoint && configuration_->is_someip(_service, _instance)
&& rm_->get_routing_state() != routing_state_e::RS_SUSPENDED) {
its_endpoint->start();
}
return its_endpoint;
Expand All @@ -97,11 +96,13 @@ void endpoint_manager_impl::find_or_create_remote_client(
start_unreliable_endpoint = true;
}
}
const bool is_someip = configuration_->is_someip(_service, _instance);
if (start_reliable_endpoint && its_reliable_endpoint && is_someip) {
const bool is_someip {configuration_->is_someip(_service, _instance)};
const bool is_suspended {rm_->get_routing_state() == routing_state_e::RS_SUSPENDED};

if (start_reliable_endpoint && its_reliable_endpoint && is_someip && !is_suspended) {
its_reliable_endpoint->start();
}
if (start_unreliable_endpoint && its_unreliable_endpoint && is_someip) {
if (start_unreliable_endpoint && its_unreliable_endpoint && is_someip && !is_suspended) {
its_unreliable_endpoint->start();
}
}
Expand Down Expand Up @@ -288,7 +289,9 @@ endpoint_manager_impl::create_server_endpoint(uint16_t _port, bool _reliable, bo

if (its_server_endpoint) {
server_endpoints_[_port][_reliable] = its_server_endpoint;
its_server_endpoint->start();
if (rm_->get_routing_state() != routing_state_e::RS_SUSPENDED) {
its_server_endpoint->start();
}
} else {
VSOMEIP_ERROR << __func__
<< " Server endpoint creation failed."
Expand Down Expand Up @@ -1403,14 +1406,13 @@ void endpoint_manager_impl::suspend() {

// stop client endpoints
std::set<std::shared_ptr<client_endpoint>> its_suspended_client_endpoints;
for (auto& its_address : its_client_endpoints) {
for (auto& its_port : its_address.second) {
for (auto& its_protocol : its_port.second) {
for (auto& its_partition : its_protocol.second) {
its_partition.second->stop();

for (const auto& [its_address, ports] : its_client_endpoints) {
for (const auto& [its_port, protocols] : ports) {
for (const auto& [its_protocol, partitions] : protocols) {
for (const auto& [its_partition, its_endpoint] : partitions) {
its_endpoint->stop();
auto its_client_endpoint {
std::dynamic_pointer_cast<client_endpoint>(its_partition.second)};
std::dynamic_pointer_cast<client_endpoint>(its_endpoint)};
if (its_client_endpoint) {
its_suspended_client_endpoints.insert(its_client_endpoint);
}
Expand All @@ -1420,9 +1422,9 @@ void endpoint_manager_impl::suspend() {
}

// start server endpoints
for (auto& its_port : its_server_endpoints) {
for (auto& its_protocol : its_port.second) {
its_protocol.second->stop();
for (const auto& [its_port, protocols] : its_server_endpoints) {
for (const auto& [its_protocol, its_endpoint] : protocols) {
its_endpoint->stop();
}
}
// check that the clients are established again
Expand Down Expand Up @@ -1471,22 +1473,21 @@ void endpoint_manager_impl::resume() {
}

// start server endpoints
for (const auto& its_port : server_endpoints_) {
for (const auto& its_protocol : its_port.second) {
its_protocol.second->restart();
for (const auto& [its_port, protocols] : its_server_endpoints) {
for (const auto& [its_protocol, its_endpoint] : protocols) {
its_endpoint->restart();
}
}

// start client endpoints
std::set<std::shared_ptr<client_endpoint>> its_resumed_client_endpoints;
for (const auto& its_address : client_endpoints_) {
for (const auto& its_port : its_address.second) {
for (const auto& its_protocol : its_port.second) {
for (const auto& its_partition : its_protocol.second) {
its_partition.second->restart();

for (const auto& [its_address, ports] : its_client_endpoints) {
for (const auto& [its_port, protocols] : ports) {
for (const auto& [its_protocol, partitions] : protocols) {
for (const auto& [its_partition, its_endpoint] : partitions) {
its_endpoint->restart();
auto its_client_endpoint {
std::dynamic_pointer_cast<client_endpoint>(its_partition.second)};
std::dynamic_pointer_cast<client_endpoint>(its_endpoint)};
if (its_client_endpoint) {
its_resumed_client_endpoints.insert(its_client_endpoint);
}
Expand Down
14 changes: 7 additions & 7 deletions implementation/routing/src/routing_manager_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@

namespace vsomeip_v3 {

routing_manager_base::routing_manager_base(routing_manager_host *_host) :
host_(_host),
io_(host_->get_io()),
configuration_(host_->get_configuration()),
debounce_timer(host_->get_io()),
routing_state_(routing_state_e::RS_UNKNOWN)
routing_manager_base::routing_manager_base(routing_manager_host* _host) :
host_(_host), io_(host_->get_io()), configuration_(host_->get_configuration()),
debounce_timer(host_->get_io())
#ifdef USE_DLT
, tc_(trace::connector_impl::get())
,
tc_(trace::connector_impl::get())
#endif
{
routing_state_ = configuration_->get_initial_routing_state();

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();
Expand Down
Loading

0 comments on commit 93b7757

Please sign in to comment.