1 // Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) 2 // This Source Code Form is subject to the terms of the Mozilla Public 3 // License, v. 2.0. If a copy of the MPL was not distributed with this 4 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6 #ifndef VSOMEIP_V3_TCP_SERVER_ENDPOINT_IMPL_HPP_ 7 #define VSOMEIP_V3_TCP_SERVER_ENDPOINT_IMPL_HPP_ 8 9 #include <map> 10 #include <memory> 11 12 #include <boost/asio/ip/tcp.hpp> 13 14 #include <vsomeip/defines.hpp> 15 #include <vsomeip/export.hpp> 16 #include "server_endpoint_impl.hpp" 17 18 #include <chrono> 19 20 namespace vsomeip_v3 { 21 22 typedef server_endpoint_impl< 23 boost::asio::ip::tcp 24 > tcp_server_endpoint_base_impl; 25 26 class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { 27 28 public: 29 tcp_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host, 30 const std::shared_ptr<routing_host>& _routing_host, 31 const endpoint_type& _local, 32 boost::asio::io_service &_io, 33 const std::shared_ptr<configuration>& _configuration); 34 virtual ~tcp_server_endpoint_impl(); 35 36 void start(); 37 void stop(); 38 39 bool send_to(const std::shared_ptr<endpoint_definition> _target, 40 const byte_t *_data, uint32_t _size); 41 bool send_error(const std::shared_ptr<endpoint_definition> _target, 42 const byte_t *_data, uint32_t _size); 43 void send_queued(const queue_iterator_type _queue_iterator); 44 void send_queued_sync(const queue_iterator_type _queue_iterator); 45 void get_configured_times_from_endpoint( 46 service_t _service, method_t _method, 47 std::chrono::nanoseconds *_debouncing, 48 std::chrono::nanoseconds *_maximum_retention) const; 49 50 VSOMEIP_EXPORT bool is_established(const std::shared_ptr<endpoint_definition>& _endpoint); 51 52 bool get_default_target(service_t, endpoint_type &) const; 53 54 std::uint16_t get_local_port() const; 55 void set_local_port(uint16_t _port); 56 bool is_reliable() const; 57 bool is_local() const; 58 59 // dummies to implement endpoint_impl interface 60 // TODO: think about a better design! 61 void receive(); 62 void print_status(); 63 private: 64 class connection: public std::enable_shared_from_this<connection> { 65 66 public: 67 typedef std::shared_ptr<connection> ptr; 68 69 static ptr create(const std::weak_ptr<tcp_server_endpoint_impl>& _server, 70 std::uint32_t _max_message_size, 71 std::uint32_t _buffer_shrink_threshold, 72 bool _magic_cookies_enabled, 73 boost::asio::io_service & _io_service, 74 std::chrono::milliseconds _send_timeout); 75 socket_type & get_socket(); 76 std::unique_lock<std::mutex> get_socket_lock(); 77 78 void start(); 79 void stop(); 80 void receive(); 81 82 void send_queued(const queue_iterator_type _queue_iterator); 83 void send_queued_sync(const queue_iterator_type _queue_iterator); 84 85 void set_remote_info(const endpoint_type &_remote); 86 const std::string get_address_port_remote() const; 87 std::size_t get_recv_buffer_capacity() const; 88 89 private: 90 connection(const std::weak_ptr<tcp_server_endpoint_impl>& _server, 91 std::uint32_t _max_message_size, 92 std::uint32_t _recv_buffer_size_initial, 93 std::uint32_t _buffer_shrink_threshold, 94 bool _magic_cookies_enabled, 95 boost::asio::io_service & _io_service, 96 std::chrono::milliseconds _send_timeout); 97 bool send_magic_cookie(message_buffer_ptr_t &_buffer); 98 bool is_magic_cookie(size_t _offset) const; 99 void receive_cbk(boost::system::error_code const &_error, 100 std::size_t _bytes); 101 void calculate_shrink_count(); 102 const std::string get_address_port_local() const; 103 void handle_recv_buffer_exception(const std::exception &_e); 104 std::size_t write_completion_condition( 105 const boost::system::error_code& _error, 106 std::size_t _bytes_transferred, std::size_t _bytes_to_send, 107 service_t _service, method_t _method, client_t _client, session_t _session, 108 const std::chrono::steady_clock::time_point _start); 109 void stop_and_remove_connection(); 110 void wait_until_sent(const boost::system::error_code &_error); 111 112 std::mutex socket_mutex_; 113 tcp_server_endpoint_impl::socket_type socket_; 114 std::weak_ptr<tcp_server_endpoint_impl> server_; 115 116 const uint32_t max_message_size_; 117 const uint32_t recv_buffer_size_initial_; 118 119 message_buffer_t recv_buffer_; 120 size_t recv_buffer_size_; 121 std::uint32_t missing_capacity_; 122 std::uint32_t shrink_count_; 123 const std::uint32_t buffer_shrink_threshold_; 124 125 endpoint_type remote_; 126 boost::asio::ip::address remote_address_; 127 std::uint16_t remote_port_; 128 std::atomic<bool> magic_cookies_enabled_; 129 std::chrono::steady_clock::time_point last_cookie_sent_; 130 const std::chrono::milliseconds send_timeout_; 131 const std::chrono::milliseconds send_timeout_warning_; 132 }; 133 134 std::mutex acceptor_mutex_; 135 boost::asio::ip::tcp::acceptor acceptor_; 136 std::mutex connections_mutex_; 137 typedef std::map<endpoint_type, connection::ptr> connections_t; 138 connections_t connections_; 139 const std::uint32_t buffer_shrink_threshold_; 140 const std::uint16_t local_port_; 141 const std::chrono::milliseconds send_timeout_; 142 143 private: 144 void remove_connection(connection *_connection); 145 void accept_cbk(const connection::ptr& _connection, 146 boost::system::error_code const &_error); 147 std::string get_remote_information( 148 const queue_iterator_type _queue_iterator) const; 149 std::string get_remote_information(const endpoint_type& _remote) const; 150 bool tp_segmentation_enabled(service_t _service, method_t _method) const; 151 }; 152 153 } // namespace vsomeip_v3 154 155 #endif // VSOMEIP_V3_TCP_SERVER_ENDPOINT_IMPL_HPP_ 156