summaryrefslogtreecommitdiff
path: root/implementation/runtime/src/application_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/runtime/src/application_impl.cpp')
-rw-r--r--implementation/runtime/src/application_impl.cpp837
1 files changed, 586 insertions, 251 deletions
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index 467bca2..e854958 100644
--- a/implementation/runtime/src/application_impl.cpp
+++ b/implementation/runtime/src/application_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// Copyright (C) 2014-2021 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/.
@@ -8,9 +8,11 @@
#include <iomanip>
#include <iostream>
+#include <boost/asio/ip/host_name.hpp>
+#include <boost/asio/ip/tcp.hpp>
#include <boost/exception/diagnostic_information.hpp>
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
#include <dlfcn.h>
#include <sys/syscall.h>
#endif
@@ -28,14 +30,14 @@
#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/configuration_plugin.hpp"
#endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS
+#include "../../endpoints/include/endpoint.hpp"
#include "../../message/include/serializer.hpp"
-#include "../../routing/include/routing_manager_impl.hpp"
-#include "../../routing/include/routing_manager_proxy.hpp"
-#include "../../utility/include/utility.hpp"
-#include "../../tracing/include/connector_impl.hpp"
#include "../../plugin/include/plugin_manager_impl.hpp"
-#include "../../endpoints/include/endpoint.hpp"
+#include "../../routing/include/routing_manager_impl.hpp"
+#include "../../routing/include/routing_manager_client.hpp"
#include "../../security/include/security.hpp"
+#include "../../tracing/include/connector_impl.hpp"
+#include "../../utility/include/utility.hpp"
namespace vsomeip_v3 {
@@ -46,12 +48,14 @@ configuration::~configuration() {}
uint32_t application_impl::app_counter__ = 0;
std::mutex application_impl::app_counter_mutex__;
-application_impl::application_impl(const std::string &_name)
+application_impl::application_impl(const std::string &_name, const std::string &_path)
: runtime_(runtime::get()),
client_(VSOMEIP_CLIENT_UNSET),
session_(0),
- is_initialized_(false), name_(_name),
- work_(std::make_shared<boost::asio::io_service::work>(io_)),
+ is_initialized_(false),
+ name_(_name),
+ path_(_path),
+ work_(std::make_shared<boost::asio::io_context::work>(io_)),
routing_(0),
state_(state_type_e::ST_DEREGISTERED),
security_mode_(security_mode_e::SM_OFF),
@@ -67,17 +71,9 @@ application_impl::application_impl(const std::string &_name)
is_routing_manager_host_(false),
stopped_called_(false),
watchdog_timer_(io_),
- client_side_logging_(false)
-#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG
- , has_session_handling_(true)
-#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG
+ client_side_logging_(false),
+ has_session_handling_(true)
{
- own_uid_ = ANY_UID;
- own_gid_ = ANY_GID;
-#ifndef _WIN32
- own_uid_ = getuid();
- own_gid_ = getgid();
-#endif
}
application_impl::~application_impl() {
@@ -143,19 +139,19 @@ bool application_impl::init() {
auto its_configuration_plugin
= std::dynamic_pointer_cast<configuration_plugin>(its_plugin);
if (its_configuration_plugin) {
- configuration_ = its_configuration_plugin->get_configuration(name_);
+ configuration_ = its_configuration_plugin->get_configuration(name_, path_);
VSOMEIP_INFO << "Configuration module loaded.";
} else {
std::cerr << "Invalid configuration module!" << std::endl;
std::exit(EXIT_FAILURE);
}
} else {
- std::cerr << "Configuration module could not be loaded!" << std::endl;
+ std::cerr << "1 Configuration module could not be loaded!" << std::endl;
std::exit(EXIT_FAILURE);
}
#else
configuration_ = std::dynamic_pointer_cast<configuration>(
- std::make_shared<vsomeip_v3::cfg::configuration_impl>());
+ std::make_shared<vsomeip_v3::cfg::configuration_impl>(configuration_path));
if (configuration_path.length()) {
configuration_->set_configuration_path(configuration_path);
}
@@ -163,14 +159,31 @@ bool application_impl::init() {
#endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS
}
+ if (configuration_->is_local_routing()) {
+ sec_client_.client_type = VSOMEIP_CLIENT_UDS;
+#ifdef __unix__
+ sec_client_.client.uds_client.user = getuid();
+ sec_client_.client.uds_client.group = getgid();
+#else
+ sec_client_.client.uds_client.user = ANY_UID;
+ sec_client_.client.uds_client.group = ANY_GID;
+#endif
+ } else {
+ sec_client_.client_type = VSOMEIP_CLIENT_TCP;
+ }
+
// Set security mode
- auto its_security = security::get();
- if (its_security->is_enabled()) {
- if (its_security->is_audit()) {
+ if (configuration_->is_security_enabled()) {
+ if (configuration_->is_security_audit()) {
security_mode_ = security_mode_e::SM_AUDIT;
} else {
security_mode_ = security_mode_e::SM_ON;
}
+
+ if (security::load()) {
+ VSOMEIP_INFO << "Using external security implementation!";
+ security::initialize();
+ }
} else {
security_mode_ = security_mode_e::SM_OFF;
}
@@ -234,18 +247,16 @@ bool application_impl::init() {
max_dispatchers_ = its_configuration->get_max_dispatchers(name_) + 1;
max_dispatch_time_ = its_configuration->get_max_dispatch_time(name_);
-#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG
has_session_handling_ = its_configuration->has_session_handling(name_);
if (!has_session_handling_)
VSOMEIP_INFO << "application: " << name_
<< " has session handling switched off!";
-#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG
- std::string its_routing_host = its_configuration->get_routing_host();
+ std::string its_routing_host = its_configuration->get_routing_host_name();
if (its_routing_host != "") {
is_routing_manager_host_ = (its_routing_host == name_);
if (is_routing_manager_host_ &&
- !utility::is_routing_manager(configuration_)) {
+ !utility::is_routing_manager(configuration_->get_network())) {
#ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS
VSOMEIP_ERROR << "application: " << name_ << " configured as "
"routing but other routing manager present. Won't "
@@ -257,7 +268,11 @@ bool application_impl::init() {
#endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS
}
} else {
- is_routing_manager_host_ = utility::is_routing_manager(configuration_);
+ auto its_routing_address = its_configuration->get_routing_host_address();
+ auto its_routing_port = its_configuration->get_routing_host_port();
+ if (its_routing_address.is_unspecified()
+ || is_local_endpoint(its_routing_address, its_routing_port))
+ is_routing_manager_host_ = utility::is_routing_manager(configuration_->get_network());
}
if (is_routing_manager_host_) {
@@ -271,10 +286,9 @@ bool application_impl::init() {
routing_ = std::make_shared<routing_manager_impl>(this);
} else {
VSOMEIP_INFO << "Instantiating routing manager [Proxy].";
- routing_ = std::make_shared<routing_manager_proxy>(this, client_side_logging_, client_side_logging_filter_);
+ routing_ = std::make_shared<routing_manager_client>(this, client_side_logging_, client_side_logging_filter_);
}
- routing_->set_client(client_);
routing_->init();
#ifdef USE_DLT
@@ -343,7 +357,7 @@ bool application_impl::init() {
}
void application_impl::start() {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
if (getpid() != static_cast<pid_t>(syscall(SYS_gettid))) {
// only set threadname if calling thread isn't the main thread
std::stringstream s;
@@ -382,7 +396,7 @@ void application_impl::start() {
VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\" ("
<< std::hex << std::setw(4) << std::setfill('0') << client_
<< ") using " << std::dec << io_thread_count << " threads"
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " I/O nice " << io_thread_nice_level
#endif
;
@@ -411,11 +425,11 @@ void application_impl::start() {
<< std::hex << std::setw(4) << std::setfill('0')
<< client_ << " (" << name_ << ") is: " << std::hex
<< std::this_thread::get_id()
- #ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " TID: " << std::dec << static_cast<int>(syscall(SYS_gettid))
- #endif
+#endif
;
- #ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
{
std::stringstream s;
s << std::hex << std::setw(4) << std::setfill('0')
@@ -426,7 +440,7 @@ void application_impl::start() {
if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) {
VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id();
}
- #endif
+#endif
try {
io_.run();
} catch (const std::exception &e) {
@@ -458,11 +472,11 @@ void application_impl::start() {
VSOMEIP_INFO << "io thread id from application: "
<< std::hex << std::setw(4) << std::setfill('0') << client_ << " ("
<< name_ << ") is: " << std::hex << std::this_thread::get_id()
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " TID: " << std::dec << static_cast<int>(syscall(SYS_gettid))
#endif
;
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) {
VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id();
}
@@ -546,9 +560,7 @@ void application_impl::stop() {
if (block) {
std::unique_lock<std::mutex> block_stop_lock(block_stop_mutex_);
- while (!block_stopping_) {
- block_stop_cv_.wait(block_stop_lock);
- }
+ block_stop_cv_.wait(block_stop_lock, [this] { return block_stopping_; });
block_stopping_ = false;
}
}
@@ -603,8 +615,9 @@ void application_impl::subscribe(service_t _service, instance_t _instance,
}
if (check_subscription_state(_service, _instance, _eventgroup, _event)) {
- routing_->subscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _major,
- _event);
+ routing_->subscribe(client_, &sec_client_,
+ _service, _instance, _eventgroup, _major,
+ _event, nullptr);
}
}
}
@@ -613,45 +626,45 @@ void application_impl::unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup) {
remove_subscription(_service, _instance, _eventgroup, ANY_EVENT);
if (routing_)
- routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, ANY_EVENT);
+ routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, ANY_EVENT);
}
void application_impl::unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event) {
remove_subscription(_service, _instance, _eventgroup, _event);
if (routing_)
- routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _event);
+ routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, _event);
}
bool application_impl::is_available(
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) const {
- std::lock_guard<std::recursive_mutex> its_lock(availability_mutex_);
- return is_available_unlocked(_service, _instance, _major, _minor);
+ std::lock_guard<std::mutex> its_lock(availability_mutex_);
+ return (is_available_unlocked(_service, _instance, _major, _minor)
+ == availability_state_e::AS_AVAILABLE);
}
-bool application_impl::is_available_unlocked(
+availability_state_e
+application_impl::is_available_unlocked(
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) const {
- bool is_available(false);
+ availability_state_e its_state(availability_state_e::AS_UNKNOWN);
- auto check_major_minor = [&](const std::map<instance_t,
- std::map<major_version_t,
- minor_version_t >>::const_iterator &_found_instance) {
+ auto check_major_minor = [&](const available_instance_t::const_iterator &_found_instance) {
auto found_major = _found_instance->second.find(_major);
if (found_major != _found_instance->second.end()) {
- if (_minor <= found_major->second || _minor == ANY_MINOR
+ if (_minor <= found_major->second.first || _minor == ANY_MINOR
|| _minor == DEFAULT_MINOR) {
- is_available = true;
+ its_state = found_major->second.second;
}
} else if ((_major == DEFAULT_MAJOR || _major == ANY_MAJOR)) {
for (const auto &found_major : _found_instance->second) {
if (_minor == DEFAULT_MINOR || _minor == ANY_MINOR) {
- is_available = true;
+ its_state = found_major.second.second;
break;
- } else if (_minor <= found_major.second) {
- is_available = true;
+ } else if (_minor <= found_major.second.first) {
+ its_state = found_major.second.second;
break;
}
}
@@ -666,7 +679,7 @@ bool application_impl::is_available_unlocked(
for (auto it = found_service->second.cbegin();
it != found_service->second.cend(); it++) {
check_major_minor(it);
- if (is_available) {
+ if (its_state != availability_state_e::AS_UNKNOWN) {
break;
}
}
@@ -676,49 +689,53 @@ bool application_impl::is_available_unlocked(
auto found_instance = found_service.second.find(_instance);
if (found_instance != found_service.second.end()) {
check_major_minor(found_instance);
- if (is_available) {
+ if (its_state != availability_state_e::AS_UNKNOWN) {
break;
}
} else if (_instance == ANY_INSTANCE) {
for (auto it = found_service.second.cbegin();
it != found_service.second.cend(); it++) {
check_major_minor(it);
- if (is_available) {
+ if (its_state != availability_state_e::AS_UNKNOWN) {
break;
}
}
}
- if (is_available) {
+ if (its_state != availability_state_e::AS_UNKNOWN) {
break;
}
}
}
- return is_available;
+ return (its_state);
}
bool application_impl::are_available(
available_t &_available,
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) const {
- std::lock_guard<std::recursive_mutex> its_lock(availability_mutex_);
- return are_available_unlocked(_available, _service, _instance, _major, _minor);
+ std::lock_guard<std::mutex> its_lock(availability_mutex_);
+ return (are_available_unlocked(_available, _service, _instance, _major, _minor)
+ == availability_state_e::AS_AVAILABLE);
}
-bool application_impl::are_available_unlocked(available_t &_available,
- service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor) const {
+availability_state_e
+application_impl::are_available_unlocked(available_t &_available,
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor) const {
//find available services
if(_service == ANY_SERVICE) {
//add all available services
for(auto its_available_services_it = available_.begin();
its_available_services_it != available_.end();
- ++its_available_services_it)
+ ++its_available_services_it) {
_available[its_available_services_it->first];
+ }
} else {
// check if specific service is available
- if(available_.find(_service) != available_.end())
+ if(available_.find(_service) != available_.end()) {
_available[_service];
+ }
}
//find available instances
@@ -733,11 +750,13 @@ bool application_impl::are_available_unlocked(available_t &_available,
//add all available instances
for(auto its_available_instances_it = found_available_service->second.begin();
its_available_instances_it != found_available_service->second.end();
- ++its_available_instances_it)
+ ++its_available_instances_it) {
_available[its_available_services_it->first][its_available_instances_it->first];
+ }
} else {
- if(found_available_service->second.find(_instance) != found_available_service->second.end())
+ if(found_available_service->second.find(_instance) != found_available_service->second.end()) {
_available[its_available_services_it->first][_instance];
+ }
}
}
}
@@ -761,11 +780,13 @@ bool application_impl::are_available_unlocked(available_t &_available,
//add all major versions
for(auto its_available_major_it = found_available_instance->second.begin();
its_available_major_it != found_available_instance->second.end();
- ++its_available_major_it)
+ ++its_available_major_it) {
_available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first];
+ }
} else {
- if(found_available_instance->second.find(_major) != found_available_instance->second.end())
+ if(found_available_instance->second.find(_major) != found_available_instance->second.end()) {
_available[its_available_services_it->first][its_available_instances_it->first][_major];
+ }
}
}
}
@@ -793,11 +814,13 @@ bool application_impl::are_available_unlocked(available_t &_available,
++its_available_major_it) {
//get available major version
auto found_available_major = found_available_instance->second.find(its_available_major_it->first);
- if(found_available_major != found_available_instance->second.end()) {
- if(_minor == ANY_MINOR || _minor == DEFAULT_MINOR
- || _minor <= found_available_major->second) {
+ if (found_available_major != found_available_instance->second.end()) {
+ if ((_minor == ANY_MINOR || _minor == DEFAULT_MINOR
+ || _minor <= found_available_major->second.first)
+ && availability_state_e::AS_AVAILABLE == found_available_major->second.second) {
//add minor version
- _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first] = found_available_major->second;
+ _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first]
+ = found_available_major->second.first;
found_minor = true;
}
}
@@ -811,11 +834,12 @@ bool application_impl::are_available_unlocked(available_t &_available,
its_available_services_it = _available.erase(its_available_services_it);
}
- if(_available.empty()) {
+ if (_available.empty()) {
_available[_service][_instance][_major] = _minor ;
- return false;
+
+ return (availability_state_e::AS_UNAVAILABLE);
}
- return true;
+ return (availability_state_e::AS_AVAILABLE);
}
void application_impl::send(std::shared_ptr<message> _message) {
@@ -840,15 +864,16 @@ void application_impl::send(std::shared_ptr<message> _message) {
// in case of requests set the request-id (client-id|session-id)
if (is_request) {
_message->set_client(client_);
- _message->set_session(get_session());
+ _message->set_session(get_session(true));
}
// Always increment the session-id
- (void)routing_->send(client_, _message);
+ (void)routing_->send(client_, _message, false);
}
}
void application_impl::notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload, bool _force) const {
+
if (routing_)
routing_->notify(_service, _instance, _event, _payload, _force);
}
@@ -866,7 +891,7 @@ void application_impl::notify_one(service_t _service, instance_t _instance,
}
}
-void application_impl::register_state_handler(state_handler_t _handler) {
+void application_impl::register_state_handler(const state_handler_t &_handler) {
std::lock_guard<std::mutex> its_lock(state_handler_mutex_);
handler_ = _handler;
}
@@ -877,45 +902,62 @@ void application_impl::unregister_state_handler() {
}
void application_impl::register_availability_handler(service_t _service,
- instance_t _instance, availability_handler_t _handler,
+ instance_t _instance, const availability_handler_t &_handler,
major_version_t _major, minor_version_t _minor) {
- std::lock_guard<std::recursive_mutex> availability_lock(availability_mutex_);
- if (state_ == state_type_e::ST_REGISTERED) {
- do_register_availability_handler(_service, _instance,
- _handler, _major, _minor);
- } else {
- availability_[_service][_instance][_major][_minor] = std::make_pair(
- _handler, false);
- }
+
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
+ auto its_handler_ext = [_handler](service_t _service, instance_t _instance,
+ availability_state_e _state) {
+ _handler(_service, _instance,
+ (_state == availability_state_e::AS_AVAILABLE));
+ };
+
+ register_availability_handler_unlocked(_service, _instance,
+ its_handler_ext, _major, _minor);
}
-void application_impl::do_register_availability_handler(service_t _service,
- instance_t _instance, availability_handler_t _handler,
+void application_impl::register_availability_handler(service_t _service,
+ instance_t _instance, const availability_state_handler_t &_handler,
major_version_t _major, minor_version_t _minor) {
- available_t available;
- bool are_available = are_available_unlocked(available, _service, _instance, _major, _minor);
- availability_[_service][_instance][_major][_minor] = std::make_pair(
- _handler, true);
- std::lock_guard<std::mutex> handlers_lock(handlers_mutex_);
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
+ register_availability_handler_unlocked(_service, _instance,
+ _handler, _major, _minor);
+}
- std::shared_ptr<sync_handler> its_sync_handler
- = std::make_shared<sync_handler>([_handler, are_available, available]() {
- for(const auto& available_services_it : available)
- for(const auto& available_instances_it : available_services_it.second)
- _handler(available_services_it.first, available_instances_it.first, are_available);
- });
- its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY;
- its_sync_handler->service_id_ = _service;
- its_sync_handler->instance_id_ = _instance;
- handlers_.push_back(its_sync_handler);
+void application_impl::register_availability_handler_unlocked(service_t _service,
+ instance_t _instance, availability_state_handler_t _handler,
+ major_version_t _major, minor_version_t _minor) {
+
+ if (state_ == state_type_e::ST_REGISTERED) {
+ available_t its_available;
+ auto are_available = are_available_unlocked(its_available, _service, _instance, _major, _minor);
+ availability_[_service][_instance][_major][_minor]
+ = std::make_pair(_handler, true);
+
+ std::lock_guard<std::mutex> handlers_lock(handlers_mutex_);
+
+ std::shared_ptr<sync_handler> its_sync_handler
+ = std::make_shared<sync_handler>([_handler, are_available, its_available]() {
+ for(const auto& available_services_it : its_available)
+ for(const auto& available_instances_it : available_services_it.second)
+ _handler(available_services_it.first, available_instances_it.first, are_available);
+ });
+ its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY;
+ its_sync_handler->service_id_ = _service;
+ its_sync_handler->instance_id_ = _instance;
+ handlers_.push_back(its_sync_handler);
- dispatcher_condition_.notify_one();
+ dispatcher_condition_.notify_one();
+ } else {
+ availability_[_service][_instance][_major][_minor]
+ = std::make_pair(_handler, false);
+ }
}
void application_impl::unregister_availability_handler(service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor) {
- std::lock_guard<std::recursive_mutex> its_lock(availability_mutex_);
+ std::lock_guard<std::mutex> its_lock(availability_mutex_);
auto found_service = availability_.find(_service);
if (found_service != availability_.end()) {
auto found_instance = found_service->second.find(_instance);
@@ -941,11 +983,14 @@ void application_impl::unregister_availability_handler(service_t _service,
}
}
-void application_impl::on_subscription(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid,
- bool _subscribed, std::function<void(bool)> _accepted_cb) {
+void application_impl::on_subscription(
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ client_t _client, const vsomeip_sec_client_t *_sec_client,
+ const std::string &_env, bool _subscribed,
+ const std::function<void(bool)> &_accepted_cb) {
+
bool handler_found = false;
- std::pair<subscription_handler_t, async_subscription_handler_t> its_handlers;
+ std::pair<subscription_handler_sec_t, async_subscription_handler_sec_t> its_handlers;
{
std::lock_guard<std::mutex> its_lock(subscription_mutex_);
auto found_service = subscription_.find(_service);
@@ -964,10 +1009,10 @@ void application_impl::on_subscription(service_t _service, instance_t _instance,
if (handler_found) {
if(auto its_handler = its_handlers.first) {
// "normal" subscription handler exists
- _accepted_cb(its_handler(_client, _uid, _gid, _subscribed));
+ _accepted_cb(its_handler(_client, _sec_client, _env, _subscribed));
} else if(auto its_handler = its_handlers.second) {
// async subscription handler exists
- its_handler(_client, _uid, _gid, _subscribed, _accepted_cb);
+ its_handler(_client, _sec_client, _env, _subscribed, _accepted_cb);
}
} else {
_accepted_cb(true);
@@ -976,12 +1021,59 @@ void application_impl::on_subscription(service_t _service, instance_t _instance,
void application_impl::register_subscription_handler(service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- subscription_handler_t _handler) {
+ const subscription_handler_t &_handler) {
+
+ subscription_handler_ext_t its_handler_ext
+ = [_handler](client_t _client, uid_t _uid, gid_t _gid,
+ const std::string &_env, bool _is_subscribed) {
+
+ (void)_env; // compatibility
+ return _handler(_client, _uid, _gid, _is_subscribed);
+ };
+
+ register_subscription_handler(_service, _instance, _eventgroup,
+ its_handler_ext);
+}
+
+void application_impl::register_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ const subscription_handler_ext_t &_handler) {
+
+ subscription_handler_sec_t its_handler_sec = [_handler](
+ client_t _client,
+ const vsomeip_sec_client_t* _sec_client,
+ const std::string& _env,
+ bool _is_subscribed
+ ){
+ uid_t its_uid{ANY_UID};
+ gid_t its_gid{ANY_GID};
+
+ if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) {
+ its_uid = _sec_client->client.uds_client.user;
+ its_gid = _sec_client->client.uds_client.group;
+ }
+
+ return _handler(
+ _client,
+ its_uid,
+ its_gid,
+ _env,
+ _is_subscribed
+ );
+ };
+
+ register_subscription_handler(_service, _instance, _eventgroup, its_handler_sec);
+}
+
+void application_impl::register_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ const subscription_handler_sec_t &_handler) {
std::lock_guard<std::mutex> its_lock(subscription_mutex_);
subscription_[_service][_instance][_eventgroup] = std::make_pair(_handler, nullptr);
}
+
void application_impl::unregister_subscription_handler(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) {
std::lock_guard<std::mutex> its_lock(subscription_mutex_);
@@ -997,40 +1089,49 @@ void application_impl::unregister_subscription_handler(service_t _service,
}
}
-void application_impl::on_subscription_status(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, event_t _event,
- uint16_t _error) {
+void application_impl::on_subscription_status(
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, event_t _event, uint16_t _error) {
+
bool entry_found(false);
{
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event);
std::lock_guard<std::mutex> its_lock(subscriptions_state_mutex_);
- auto its_subscription_state = subscription_state_.find(its_tuple);
- if (its_subscription_state == subscription_state_.end()) {
- its_tuple = std::make_tuple(_service, _instance, _eventgroup, ANY_EVENT);
- auto its_any_subscription_state = subscription_state_.find(its_tuple);
- if (its_any_subscription_state == subscription_state_.end()) {
- VSOMEIP_TRACE << std::hex << get_client( )
- << " application_impl::on_subscription_status: "
- << "Received a subscription status without subscribe for "
- << std::hex << _service << "/" << _instance << "/"
- << _eventgroup << "/" << _event << "/error=" << _error;
- } else {
- entry_found = true;
- }
- } else {
- entry_found = true;
- }
- if (entry_found) {
- if (_error) {
- subscription_state_[its_tuple] =
- subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED;
- } else {
- subscription_state_[its_tuple] =
- subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED;
+ auto its_service = subscription_state_.find(_service);
+ if (its_service == subscription_state_.end())
+ its_service = subscription_state_.find(ANY_SERVICE);
+
+ if (its_service != subscription_state_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance == its_service->second.end())
+ its_instance = its_service->second.find(ANY_INSTANCE);
+
+ if (its_instance != its_service->second.end()) {
+ auto its_eventgroup = its_instance->second.find(_eventgroup);
+ if (its_eventgroup == its_instance->second.end())
+ its_eventgroup = its_instance->second.find(ANY_EVENTGROUP);
+
+ if (its_eventgroup != its_instance->second.end()) {
+ auto its_event = its_eventgroup->second.find(_event);
+ if (its_event == its_eventgroup->second.end())
+ its_event = its_eventgroup->second.find(ANY_EVENT);
+
+ if (its_event != its_eventgroup->second.end()) {
+ entry_found = true;
+ its_event->second = (_error ?
+ subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED :
+ subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED);
+ }
+ auto its_any_event = its_eventgroup->second.find(ANY_EVENT);
+ if (its_any_event != its_eventgroup->second.end()) {
+ entry_found = true;
+ its_any_event->second = (_error ?
+ subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED :
+ subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED);
+ }
+ }
}
}
}
-
if (entry_found) {
deliver_subscription_state(_service, _instance, _eventgroup, _event, _error);
}
@@ -1038,6 +1139,7 @@ void application_impl::on_subscription_status(service_t _service,
void application_impl::deliver_subscription_state(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event, uint16_t _error) {
+
std::vector<subscription_status_handler_t> handlers;
{
std::lock_guard<std::mutex> its_lock(subscription_status_handlers_mutex_);
@@ -1052,12 +1154,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t
if (!_error || (_error && found_event->second.second)) {
handlers.push_back(found_event->second.first);
}
- } else {
- auto its_any_event = found_eventgroup->second.find(ANY_EVENT);
- if (its_any_event != found_eventgroup->second.end()) {
- if (!_error || (_error && its_any_event->second.second)) {
- handlers.push_back(its_any_event->second.first);
- }
+ }
+ auto found_any_event = found_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
+ }
+ }
+ }
+ auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP);
+ if (found_any_eventgroup != found_instance->second.end()) {
+ auto found_event = found_any_eventgroup->second.find(_event);
+ if (found_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_event->second.second)) {
+ handlers.push_back(found_event->second.first);
+ }
+ }
+ auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
}
}
}
@@ -1071,12 +1187,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t
if (!_error || (_error && found_event->second.second)) {
handlers.push_back(found_event->second.first);
}
- } else {
- auto its_any_event = found_eventgroup->second.find(ANY_EVENT);
- if (its_any_event != found_eventgroup->second.end()) {
- if (!_error || (_error && its_any_event->second.second)) {
- handlers.push_back(its_any_event->second.first);
- }
+ }
+ auto found_any_event = found_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
+ }
+ }
+ }
+ auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP);
+ if (found_any_eventgroup != found_instance->second.end()) {
+ auto found_event = found_any_eventgroup->second.find(_event);
+ if (found_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_event->second.second)) {
+ handlers.push_back(found_event->second.first);
+ }
+ }
+ auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
}
}
}
@@ -1093,12 +1223,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t
if (!_error || (_error && found_event->second.second)) {
handlers.push_back(found_event->second.first);
}
- } else {
- auto its_any_event = found_eventgroup->second.find(ANY_EVENT);
- if (its_any_event != found_eventgroup->second.end()) {
- if (!_error || (_error && its_any_event->second.second)) {
- handlers.push_back(its_any_event->second.first);
- }
+ }
+ auto found_any_event = found_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
+ }
+ }
+ }
+ auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP);
+ if (found_any_eventgroup != found_instance->second.end()) {
+ auto found_event = found_any_eventgroup->second.find(_event);
+ if (found_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_event->second.second)) {
+ handlers.push_back(found_event->second.first);
+ }
+ }
+ auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
}
}
}
@@ -1112,12 +1256,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t
if (!_error || (_error && found_event->second.second)) {
handlers.push_back(found_event->second.first);
}
- } else {
- auto its_any_event = found_eventgroup->second.find(ANY_EVENT);
- if (its_any_event != found_eventgroup->second.end()) {
- if (!_error || (_error && its_any_event->second.second)) {
- handlers.push_back(its_any_event->second.first);
- }
+ }
+ auto found_any_event = found_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
+ }
+ }
+ }
+ auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP);
+ if (found_any_eventgroup != found_instance->second.end()) {
+ auto found_event = found_any_eventgroup->second.find(_event);
+ if (found_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_event->second.second)) {
+ handlers.push_back(found_event->second.first);
+ }
+ }
+ auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT);
+ if (found_any_event != found_any_eventgroup->second.end()) {
+ if (!_error || (_error && found_any_event->second.second)) {
+ handlers.push_back(found_any_event->second.first);
}
}
}
@@ -1191,7 +1349,7 @@ void application_impl::unregister_subscription_status_handler(service_t _service
}
void application_impl::register_message_handler(service_t _service,
- instance_t _instance, method_t _method, message_handler_t _handler) {
+ instance_t _instance, method_t _method, const message_handler_t &_handler) {
std::lock_guard<std::mutex> its_lock(members_mutex_);
members_[_service][_instance][_method] = _handler;
}
@@ -1218,12 +1376,33 @@ void application_impl::offer_event(service_t _service, instance_t _instance,
bool _update_on_change,
const epsilon_change_func_t &_epsilon_change_func,
reliability_type_e _reliability) {
- if (routing_)
+ if (routing_) {
+
+ if (_cycle == std::chrono::milliseconds::zero()
+ && _change_resets_cycle == false
+ && _update_on_change == true) {
+
+ configuration_->get_event_update_properties(
+ _service, _instance, _notifier,
+ _cycle, _change_resets_cycle, _update_on_change);
+
+ VSOMEIP_INFO << __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')
+ << _notifier << "] uses configured cycle time "
+ << std::dec << _cycle.count() << "ms";
+ }
+
routing_->register_event(client_,
_service, _instance,
_notifier, _eventgroups, _type, _reliability,
_cycle, _change_resets_cycle, _update_on_change,
_epsilon_change_func, true);
+ }
}
void application_impl::stop_offer_event(service_t _service, instance_t _instance,
@@ -1263,12 +1442,10 @@ void application_impl::set_client(const client_t &_client) {
client_ = _client;
}
-session_t application_impl::get_session() {
+session_t application_impl::get_session(bool _is_request) {
-#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG
- if (!has_session_handling_)
+ if (!has_session_handling_ && !_is_request)
return (0);
-#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG
std::lock_guard<std::mutex> its_lock(session_mutex_);
if (0 == ++session_) {
@@ -1279,6 +1456,11 @@ session_t application_impl::get_session() {
return session_;
}
+const vsomeip_sec_client_t *application_impl::get_sec_client() const {
+
+ return &sec_client_;
+}
+
std::shared_ptr<configuration> application_impl::get_configuration() const {
return configuration_;
}
@@ -1287,13 +1469,13 @@ diagnosis_t application_impl::get_diagnosis() const {
return configuration_->get_diagnosis_address();
}
-boost::asio::io_service & application_impl::get_io() {
+boost::asio::io_context &application_impl::get_io() {
return io_;
}
void application_impl::on_state(state_type_e _state) {
{
- std::lock_guard<std::recursive_mutex> availability_lock(availability_mutex_);
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
if (state_ != _state) {
state_ = _state;
if (state_ == state_type_e::ST_REGISTERED) {
@@ -1302,7 +1484,7 @@ void application_impl::on_state(state_type_e _state) {
for (const auto &its_major : its_instance.second) {
for (const auto &its_minor : its_major.second) {
if (!its_minor.second.second) {
- do_register_availability_handler(
+ register_availability_handler_unlocked(
its_service.first,
its_instance.first,
its_minor.second.first,
@@ -1312,17 +1494,6 @@ void application_impl::on_state(state_type_e _state) {
}
}
}
- } else {
- // Call on_availability callback on each service
- for (const auto &its_service : availability_) {
- for (const auto &its_instance : its_service.second) {
- for (const auto &its_major : its_instance.second) {
- for (const auto &its_minor : its_major.second) {
- on_availability(its_service.first, its_instance.first, false, its_major.first, its_minor.first);
- }
- }
- }
- }
}
}
}
@@ -1348,16 +1519,17 @@ void application_impl::on_state(state_type_e _state) {
}
void application_impl::on_availability(service_t _service, instance_t _instance,
- bool _is_available, major_version_t _major, minor_version_t _minor) {
- std::vector<availability_handler_t> its_handlers;
+ availability_state_e _state, major_version_t _major, minor_version_t _minor) {
+
+ std::vector<availability_state_handler_t> its_handlers;
{
- std::lock_guard<std::recursive_mutex> availability_lock(availability_mutex_);
- if (_is_available == is_available_unlocked(_service, _instance, _major, _minor)) {
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
+ if (_state == is_available_unlocked(_service, _instance, _major, _minor)) {
return;
}
- if (_is_available) {
- available_[_service][_instance][_major] = _minor;
+ if (_state != availability_state_e::AS_UNAVAILABLE) {
+ available_[_service][_instance][_major] = std::make_pair(_minor, _state);
} else {
auto found_available_service = available_.find(_service);
if (found_available_service != available_.end()) {
@@ -1365,7 +1537,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
if( found_instance != found_available_service->second.end()) {
auto found_major = found_instance->second.find(_major);
if( found_major != found_instance->second.end() ){
- if( _minor == found_major->second)
+ if(_minor == found_major->second.first)
found_available_service->second.erase(_instance);
}
}
@@ -1429,9 +1601,9 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
for (const auto &handler : its_handlers) {
std::shared_ptr<sync_handler> its_sync_handler =
std::make_shared<sync_handler>(
- [handler, _service, _instance, _is_available]()
+ [handler, _service, _instance, _state]()
{
- handler(_service, _instance, _is_available);
+ handler(_service, _instance, _state);
});
its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY;
its_sync_handler->service_id_ = _service;
@@ -1440,7 +1612,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
}
}
}
- if (!_is_available) {
+ if (_state == availability_state_e::AS_UNAVAILABLE) {
{
std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
auto found_service = subscriptions_.find(_service);
@@ -1457,11 +1629,16 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
}
{
std::lock_guard<std::mutex> its_lock(subscriptions_state_mutex_);
- for (auto &its_subscription_state : subscription_state_) {
- if (std::get<0>(its_subscription_state.first) == _service &&
- std::get<1>(its_subscription_state.first) == _instance) {
- its_subscription_state.second =
- subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED;
+ auto its_service = subscription_state_.find(_service);
+ if (its_service != subscription_state_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ for (auto &its_eventgroup : its_instance->second) {
+ for (auto &its_event : its_eventgroup.second) {
+ its_event.second
+ = subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED;
+ }
+ }
}
}
}
@@ -1481,10 +1658,11 @@ void application_impl::on_message(std::shared_ptr<message> &&_message) {
if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) {
if (!check_for_active_subscription(its_service, its_instance,
static_cast<event_t>(its_method))) {
- VSOMEIP_ERROR << "application_impl::on_message ["
+ VSOMEIP_INFO << "application_impl::on_message ["
<< 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_method << "]";
+ << std::hex << std::setw(4) << std::setfill('0') << its_method << "]"
+ << ": blocked as the subscription is already inactive.";
return;
}
}
@@ -1569,7 +1747,7 @@ routing_manager * application_impl::get_routing_manager() const {
}
void application_impl::main_dispatch() {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
{
std::stringstream s;
s << std::hex << std::setw(4) << std::setfill('0')
@@ -1581,7 +1759,7 @@ void application_impl::main_dispatch() {
VSOMEIP_INFO << "main dispatch thread id from application: "
<< std::hex << std::setw(4) << std::setfill('0') << client_ << " ("
<< name_ << ") is: " << std::hex << its_id
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " TID: " << std::dec << static_cast<int>(syscall(SYS_gettid))
#endif
;
@@ -1591,9 +1769,10 @@ void application_impl::main_dispatch() {
// Cancel other waiting dispatcher
dispatcher_condition_.notify_all();
// Wait for new handlers to execute
- while (is_dispatching_ && (handlers_.empty() || !is_active_dispatcher(its_id))) {
- dispatcher_condition_.wait(its_lock);
- }
+ dispatcher_condition_.wait(its_lock, [this, &its_id] {
+ return !(is_dispatching_
+ && (handlers_.empty() || !is_active_dispatcher(its_id)));
+ });
} else {
std::shared_ptr<sync_handler> its_handler;
while (is_dispatching_ && is_active_dispatcher(its_id)
@@ -1622,7 +1801,7 @@ void application_impl::main_dispatch() {
}
void application_impl::dispatch() {
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
{
std::stringstream s;
s << std::hex << std::setw(4) << std::setfill('0')
@@ -1634,14 +1813,15 @@ void application_impl::dispatch() {
VSOMEIP_INFO << "dispatch thread id from application: "
<< std::hex << std::setw(4) << std::setfill('0') << client_ << " ("
<< name_ << ") is: " << std::hex << its_id
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " TID: " << std::dec << static_cast<int>(syscall(SYS_gettid))
#endif
;
std::unique_lock<std::mutex> its_lock(handlers_mutex_);
while (is_active_dispatcher(its_id)) {
if (is_dispatching_ && handlers_.empty()) {
- dispatcher_condition_.wait(its_lock);
+ dispatcher_condition_.wait(its_lock,
+ [this, &its_id] { return !is_active_dispatcher(its_id); });
// Maybe woken up from main dispatcher
if (handlers_.empty() && !is_active_dispatcher(its_id)) {
if (!is_dispatching_) {
@@ -1775,7 +1955,9 @@ void application_impl::invoke_handler(std::shared_ptr<sync_handler> &_handler) {
<< get_client() << " is shutting down";
}
} else {
- VSOMEIP_ERROR << "Maximum number of dispatchers exceeded.";
+ VSOMEIP_ERROR << "Maximum number of dispatchers exceeded. Configuration: "
+ << " Max dispatchers: " << std::dec << max_dispatchers_
+ << " Max dispatch time: " << std::dec << max_dispatch_time_;
}
dispatcher_mutex_.unlock();
break;
@@ -1889,7 +2071,7 @@ void application_impl::clear_all_handler() {
}
{
- std::lock_guard<std::recursive_mutex> availability_lock(availability_mutex_);
+ std::lock_guard<std::mutex> availability_lock(availability_mutex_);
availability_.clear();
}
@@ -1917,11 +2099,11 @@ void application_impl::shutdown() {
VSOMEIP_INFO << "shutdown thread id from application: "
<< std::hex << std::setw(4) << std::setfill('0') << client_ << " ("
<< name_ << ") is: " << std::hex << std::this_thread::get_id()
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
<< " TID: " << std::dec << static_cast<int>(syscall(SYS_gettid))
#endif
;
-#ifndef _WIN32
+#if defined(__linux__) || defined(ANDROID)
boost::asio::detail::posix_signal_blocker blocker;
{
std::stringstream s;
@@ -1933,9 +2115,7 @@ void application_impl::shutdown() {
{
std::unique_lock<std::mutex> its_lock(start_stop_mutex_);
- while(!stopped_) {
- stop_cv_.wait(its_lock);
- }
+ stop_cv_.wait(its_lock, [this] {return stopped_; });
}
{
std::lock_guard<std::mutex> its_handler_lock(handlers_mutex_);
@@ -2102,9 +2282,28 @@ void application_impl::remove_subscription(service_t _service,
event_t _event) {
{
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event);
std::lock_guard<std::mutex> its_lock(subscriptions_state_mutex_);
- subscription_state_.erase(its_tuple);
+ auto its_service = subscription_state_.find(_service);
+ if (its_service != subscription_state_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ if (_event == ANY_EVENT) {
+ its_instance->second.erase(_eventgroup);
+ } else {
+ auto its_eventgroup = its_instance->second.find(_eventgroup);
+ if (its_eventgroup != its_instance->second.end()) {
+ its_eventgroup->second.erase(_event);
+ if (its_eventgroup->second.empty()) {
+ its_instance->second.erase(_eventgroup);
+ }
+ }
+ }
+ if (its_instance->second.empty())
+ its_service->second.erase(its_instance);
+ }
+ if (its_service->second.empty())
+ subscription_state_.erase(its_service);
+ }
}
std::lock_guard<std::mutex> its_lock(subscriptions_mutex_);
@@ -2157,7 +2356,7 @@ bool application_impl::check_for_active_subscription(service_t _service,
std::shared_ptr<event> its_event = routing_->find_event(
_service, _instance, _event);
if (its_event) {
- for (const auto& eg : its_event->get_eventgroups()) {
+ for (const auto eg : its_event->get_eventgroups()) {
auto found_eventgroup = found_any_event->second.find(eg);
if (found_eventgroup != found_any_event->second.end()) {
// set the flag for initial event received to true
@@ -2183,25 +2382,39 @@ bool application_impl::check_for_active_subscription(service_t _service,
bool application_impl::check_subscription_state(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event) {
+
bool is_acknowledged(false);
bool should_subscribe(true);
{
- auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event);
+ bool has_found(false);
+
std::lock_guard<std::mutex> its_lock(subscriptions_state_mutex_);
- auto its_subscription_state = subscription_state_.find(its_tuple);
- if (its_subscription_state != subscription_state_.end()) {
- if (its_subscription_state->second !=
- subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) {
- // only return true if subscription is NACK
- // as only then we need to subscribe!
- should_subscribe = false;
- if (its_subscription_state->second ==
- subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {
- is_acknowledged = true;
+ auto its_service = subscription_state_.find(_service);
+ if (its_service != subscription_state_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ auto its_eventgroup = its_instance->second.find(_eventgroup);
+ if (its_eventgroup != its_instance->second.end()) {
+ auto its_event = its_eventgroup->second.find(_event);
+ if (its_event != its_eventgroup->second.end()) {
+ if (its_event->second != subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) {
+ has_found = true;
+
+ // only return true if subscription is NACK
+ // as only then we need to subscribe!
+ should_subscribe = false;
+ if (its_event->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {
+ is_acknowledged = true;
+ }
+ }
+ }
}
}
- } else {
- subscription_state_[its_tuple] = subscription_state_e::IS_SUBSCRIBING;
+ }
+
+ if (!has_found) {
+ subscription_state_[_service][_instance][_eventgroup][_event]
+ = subscription_state_e::IS_SUBSCRIBING;
}
}
@@ -2257,7 +2470,8 @@ void application_impl::print_blocking_call(const std::shared_ptr<sync_handler>&
}
-void application_impl::get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) {
+void application_impl::get_offered_services_async(offer_type_e _offer_type,
+ const offered_services_handler_t &_handler) {
{
std::lock_guard<std::mutex> its_lock(offered_services_handler_mutex_);
offered_services_handler_ = _handler;
@@ -2343,7 +2557,7 @@ void application_impl::watchdog_cbk(boost::system::error_code const &_error) {
}
}
-void application_impl::set_watchdog_handler(watchdog_handler_t _handler,
+void application_impl::set_watchdog_handler(const watchdog_handler_t &_handler,
std::chrono::seconds _interval) {
if (_handler && std::chrono::seconds::zero() != _interval) {
std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_);
@@ -2362,14 +2576,63 @@ void application_impl::set_watchdog_handler(watchdog_handler_t _handler,
void application_impl::register_async_subscription_handler(service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- async_subscription_handler_t _handler) {
+ const async_subscription_handler_t &_handler) {
+
+ async_subscription_handler_ext_t its_handler_ext
+ = [_handler](client_t _client, uid_t _uid, gid_t _gid,
+ const std::string &_env, bool _is_subscribed,
+ const std::function< void (const bool) > &_cb) {
+
+ (void)_env; // compatibility
+ _handler(_client, _uid, _gid, _is_subscribed, _cb);
+ };
+
+ register_async_subscription_handler(_service, _instance, _eventgroup,
+ its_handler_ext);
+}
+
+void application_impl::register_async_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ const async_subscription_handler_ext_t &_handler) {
+
+ async_subscription_handler_sec_t its_handler_sec = [_handler](
+ client_t _client,
+ const vsomeip_sec_client_t* _sec_client,
+ const std::string& _env,
+ bool _is_subscribed,
+ const std::function<void(bool)> &_cb
+ ){
+ uid_t its_uid{ANY_UID};
+ gid_t its_gid{ANY_GID};
+
+ if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) {
+ its_uid = _sec_client->client.uds_client.user;
+ its_gid = _sec_client->client.uds_client.group;
+ }
+
+ _handler(
+ _client,
+ its_uid,
+ its_gid,
+ _env,
+ _is_subscribed,
+ _cb
+ );
+ };
+
+ register_async_subscription_handler(_service, _instance, _eventgroup, its_handler_sec);
+}
+
+void application_impl::register_async_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ async_subscription_handler_sec_t _handler) {
std::lock_guard<std::mutex> its_lock(subscription_mutex_);
- subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler);;
+ subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler);
}
void application_impl::register_sd_acceptance_handler(
- sd_acceptance_handler_t _handler) {
+ const sd_acceptance_handler_t &_handler) {
if (is_routing() && routing_) {
const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
rm_impl->register_sd_acceptance_handler(_handler);
@@ -2377,7 +2640,7 @@ void application_impl::register_sd_acceptance_handler(
}
void application_impl::register_reboot_notification_handler(
- reboot_notification_handler_t _handler) {
+ const reboot_notification_handler_t &_handler) {
if (is_routing() && routing_) {
const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
rm_impl->register_reboot_notification_handler(_handler);
@@ -2519,7 +2782,7 @@ application_impl::get_sd_acceptance_required() {
}
void application_impl::register_routing_ready_handler(
- routing_ready_handler_t _handler) {
+ const routing_ready_handler_t &_handler) {
if (is_routing() && routing_) {
const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
rm_impl->register_routing_ready_handler(_handler);
@@ -2527,7 +2790,7 @@ void application_impl::register_routing_ready_handler(
}
void application_impl::register_routing_state_handler(
- routing_state_handler_t _handler) {
+ const routing_state_handler_t &_handler) {
if (is_routing() && routing_) {
const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
rm_impl->register_routing_state_handler(_handler);
@@ -2565,7 +2828,14 @@ void application_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 security_update_handler_t &_handler) {
+#ifdef VSOMEIP_DISABLE_SECURITY
+ (void)_uid;
+ (void)_gid;
+ (void)_policy;
+ (void)_payload;
+ (void)_handler;
+#else
if (!is_routing()) {
VSOMEIP_ERROR << __func__ << " is only intended to be called by "
"application acting as routing manager host";
@@ -2577,11 +2847,17 @@ void application_impl::update_security_policy_configuration(uint32_t _uid,
rm_impl->update_security_policy_configuration(_uid, _gid, _policy, _payload, _handler);
}
}
+#endif // VSOMEIP_DISABLE_SECURITY
}
void application_impl::remove_security_policy_configuration(uint32_t _uid,
uint32_t _gid,
- security_update_handler_t _handler) {
+ const security_update_handler_t &_handler) {
+#ifdef VSOMEIP_DISABLE_SECURITY
+ (void)_uid;
+ (void)_gid;
+ (void)_handler;
+#else
if (!is_routing()) {
VSOMEIP_ERROR << __func__ << " is only intended to be called by "
"application acting as routing manager host";
@@ -2593,6 +2869,65 @@ void application_impl::remove_security_policy_configuration(uint32_t _uid,
rm_impl->remove_security_policy_configuration(_uid, _gid, _handler);
}
}
+#endif // !VSOMEIP_DISABLE_SECURITY
+}
+
+void application_impl::subscribe_with_debounce(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major,
+ event_t _event, const debounce_filter_t &_filter) {
+
+ if (routing_) {
+ bool send_back_cached(false);
+ bool send_back_cached_group(false);
+ check_send_back_cached_event(_service, _instance, _event, _eventgroup,
+ &send_back_cached, &send_back_cached_group);
+
+ if (send_back_cached) {
+ send_back_cached_event(_service, _instance, _event);
+ } else if(send_back_cached_group) {
+ send_back_cached_eventgroup(_service, _instance, _eventgroup);
+ }
+
+ if (check_subscription_state(_service, _instance, _eventgroup, _event)) {
+
+ auto its_filter = std::make_shared<debounce_filter_t>(_filter);
+ routing_->subscribe(client_, get_sec_client(),
+ _service, _instance, _eventgroup, _major,
+ _event, its_filter);
+ }
+ }
+}
+
+bool
+application_impl::is_local_endpoint(const boost::asio::ip::address &_unicast,
+ port_t _port) {
+
+ try {
+ boost::asio::ip::tcp::endpoint its_endpoint(_unicast, _port);
+ boost::asio::ip::tcp::socket its_socket(io_, its_endpoint);
+ its_socket.close();
+
+ return (true);
+ } catch (...) {
+ }
+
+ return (false);
+}
+
+void application_impl::register_message_acceptance_handler(
+ const message_acceptance_handler_t &_handler) {
+ if (is_routing() && routing_) {
+ const auto rm_impl = std::dynamic_pointer_cast<routing_manager_impl>(routing_);
+ rm_impl->register_message_acceptance_handler(_handler);
+ }
+}
+
+std::map<std::string, std::string>
+application_impl::get_additional_data(const std::string &_plugin_name) {
+ if (configuration_) {
+ return configuration_->get_additional_data(name_, _plugin_name);
+ }
+ return std::map<std::string, std::string>();
}
} // namespace vsomeip_v3