summaryrefslogtreecommitdiff
path: root/implementation/endpoints/src/endpoint_manager_base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/endpoints/src/endpoint_manager_base.cpp')
-rw-r--r--implementation/endpoints/src/endpoint_manager_base.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/implementation/endpoints/src/endpoint_manager_base.cpp b/implementation/endpoints/src/endpoint_manager_base.cpp
new file mode 100644
index 0000000..6c63e4f
--- /dev/null
+++ b/implementation/endpoints/src/endpoint_manager_base.cpp
@@ -0,0 +1,233 @@
+// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "../include/endpoint_manager_base.hpp"
+
+#include <vsomeip/internal/logger.hpp>
+#include "../../utility/include/utility.hpp"
+#include "../../routing/include/routing_manager_base.hpp"
+#include "../../configuration/include/configuration.hpp"
+#include "../include/local_client_endpoint_impl.hpp"
+#include "../include/local_server_endpoint_impl.hpp"
+
+#include <iomanip>
+
+namespace vsomeip_v3 {
+
+endpoint_manager_base::endpoint_manager_base(routing_manager_base* const _rm,
+ boost::asio::io_service& _io,
+ const std::shared_ptr<configuration>& _configuration) :
+ rm_(_rm),
+ io_(_io),
+ configuration_(_configuration){
+
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::create_local(client_t _client) {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ return create_local_unlocked(_client);
+}
+
+void endpoint_manager_base::remove_local(client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint(find_local(_client));
+ if (its_endpoint) {
+ its_endpoint->register_error_handler(nullptr);
+ its_endpoint->stop();
+ VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is closing connection to ["
+ << std::hex << _client << "]";
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ local_endpoints_.erase(_client);
+ }
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::find_or_create_local(client_t _client) {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint(find_local_unlocked(_client));
+ if (!its_endpoint) {
+ its_endpoint = create_local_unlocked(_client);
+ its_endpoint->start();
+ }
+ return (its_endpoint);
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::find_local(client_t _client) {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ return find_local_unlocked(_client);
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::find_local(service_t _service,
+ instance_t _instance) {
+ return find_local(rm_->find_local_client(_service, _instance));
+}
+
+
+std::unordered_set<client_t> endpoint_manager_base::get_connected_clients() const {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ std::unordered_set<client_t> clients;
+ for (const auto& its_client : local_endpoints_) {
+ clients.insert(its_client.first);
+ }
+ return clients;
+}
+
+std::shared_ptr<local_server_endpoint_impl> endpoint_manager_base::create_local_server(
+ const std::shared_ptr<routing_host>& _routing_host) {
+ std::shared_ptr<local_server_endpoint_impl> its_server_endpoint;
+ std::stringstream its_path;
+ its_path << utility::get_base_path(configuration_) << std::hex << rm_->get_client();
+ const client_t its_client = rm_->get_client();
+#ifdef _WIN32
+ ::_unlink(its_path.str().c_str());
+ int port = VSOMEIP_INTERNAL_BASE_PORT + its_client;
+#else
+ if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) {
+ VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed ("
+ << its_path.str() << "): "<< std::strerror(errno);
+ }
+#endif
+ try {
+ its_server_endpoint = std::make_shared<local_server_endpoint_impl>(
+ shared_from_this(), _routing_host,
+#ifdef _WIN32
+ boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
+#else
+ boost::asio::local::stream_protocol_ext::endpoint(its_path.str()),
+#endif
+ io_,
+ configuration_, false);
+#ifdef _WIN32
+ VSOMEIP_INFO << "Listening at " << port;
+#else
+ VSOMEIP_INFO << "Listening at " << its_path.str();
+#endif
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << "Local server endpoint creation failed. Client ID: "
+ << std::hex << std::setw(4) << std::setfill('0') << its_client
+#ifdef _WIN32
+ << " Port: " << std::dec << port
+#else
+ << " Path: " << its_path.str()
+#endif
+ << " Reason: " << e.what();
+ }
+ return its_server_endpoint;
+}
+
+void endpoint_manager_base::on_connect(std::shared_ptr<endpoint> _endpoint) {
+ rm_->on_connect(_endpoint);
+}
+
+void endpoint_manager_base::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
+ rm_->on_disconnect(_endpoint);
+}
+
+void endpoint_manager_base::on_error(
+ const byte_t *_data, length_t _length, endpoint* const _receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
+ (void)_data;
+ (void)_length;
+ (void)_receiver;
+ (void)_remote_address;
+ (void)_remote_port;
+ // intentionally left blank
+}
+
+void endpoint_manager_base::release_port(uint16_t _port, bool _reliable) {
+ (void)_port;
+ (void)_reliable;
+ // intentionally left blank
+}
+
+client_t endpoint_manager_base::get_client() const {
+ return rm_->get_client();
+}
+
+std::map<client_t, std::shared_ptr<endpoint>>
+endpoint_manager_base::get_local_endpoints() const {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ return local_endpoints_;
+}
+
+void
+endpoint_manager_base::log_client_states() const {
+ std::vector<std::pair<client_t, size_t> > its_client_queue_sizes;
+ std::stringstream its_log;
+
+ {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ for (const auto e : local_endpoints_) {
+ size_t its_queue_size = e.second->get_queue_size();
+ if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE) {
+ its_client_queue_sizes.push_back(
+ std::make_pair(e.first, its_queue_size));
+ }
+ }
+ }
+
+ std::sort(its_client_queue_sizes.begin(), its_client_queue_sizes.end(),
+ [](const std::pair<client_t, size_t> &_a,
+ const std::pair<client_t, size_t> &_b) {
+ return (_a.second > _b.second);
+ });
+
+ size_t its_max(std::min(size_t(10), its_client_queue_sizes.size()));
+ for (size_t i = 0; i < its_max; i++) {
+ its_log << std::hex << std::setw(4) << std::setfill('0')
+ << its_client_queue_sizes[i].first << ":"
+ << std::dec << its_client_queue_sizes[i].second;
+ if (i < its_max-1)
+ its_log << ", ";
+ }
+
+ if (its_log.str().length() > 0)
+ VSOMEIP_WARNING << "ICQ: [" << its_log.str() << "]";
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::create_local_unlocked(client_t _client) {
+ std::stringstream its_path;
+ its_path << utility::get_base_path(configuration_) << std::hex << _client;
+ std::shared_ptr<local_client_endpoint_impl> its_endpoint;
+
+#ifdef _WIN32
+ boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
+ int port = VSOMEIP_INTERNAL_BASE_PORT + _client;
+ VSOMEIP_INFO << "Connecting to ["
+ << std::hex << _client << "] at " << port;
+#else
+ VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to ["
+ << std::hex << _client << "] at " << its_path.str();
+#endif
+ its_endpoint = std::make_shared<local_client_endpoint_impl>(
+ shared_from_this(), rm_->shared_from_this(),
+#ifdef _WIN32
+ boost::asio::ip::tcp::endpoint(address, port)
+#else
+ boost::asio::local::stream_protocol::endpoint(its_path.str())
+#endif
+ , io_, configuration_);
+
+ // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to
+ // external devices. Therefore, its local endpoint must not be found by
+ // a call to find_local. Thus it must not be inserted to the list of local
+ // clients.
+ if (_client != VSOMEIP_ROUTING_CLIENT) {
+ local_endpoints_[_client] = its_endpoint;
+ }
+ rm_->register_client_error_handler(_client, its_endpoint);
+
+ return its_endpoint;
+}
+
+std::shared_ptr<endpoint> endpoint_manager_base::find_local_unlocked(client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_endpoint = local_endpoints_.find(_client);
+ if (found_endpoint != local_endpoints_.end()) {
+ its_endpoint = found_endpoint->second;
+ }
+ return (its_endpoint);
+}
+
+} // namespace vsomeip_v3