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_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ 7 #define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ 8 9 #include <map> 10 #include <thread> 11 #include <condition_variable> 12 #include <memory> 13 14 #include <boost/asio/io_service.hpp> 15 #include <boost/asio/local/stream_protocol_ext.hpp> 16 17 18 #ifdef _WIN32 19 #include <boost/asio/ip/tcp.hpp> 20 #endif 21 22 #include <vsomeip/defines.hpp> 23 24 #include "buffer.hpp" 25 #include "server_endpoint_impl.hpp" 26 27 namespace vsomeip_v3 { 28 29 #ifdef _WIN32 30 typedef server_endpoint_impl< 31 boost::asio::ip::tcp 32 > local_server_endpoint_base_impl; 33 #else 34 typedef server_endpoint_impl< 35 boost::asio::local::stream_protocol_ext 36 > local_server_endpoint_base_impl; 37 #endif 38 39 class local_server_endpoint_impl: public local_server_endpoint_base_impl { 40 41 public: 42 local_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host, 43 const std::shared_ptr<routing_host>& _routing_host, 44 const endpoint_type& _local, 45 boost::asio::io_service &_io, 46 const std::shared_ptr<configuration>& _configuration, 47 bool _is_routing_endpoint); 48 49 local_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host, 50 const std::shared_ptr<routing_host>& _routing_host, 51 const endpoint_type& _local, 52 boost::asio::io_service &_io, 53 int native_socket, 54 const std::shared_ptr<configuration>& _configuration, 55 bool _is_routing_endpoint); 56 57 virtual ~local_server_endpoint_impl(); 58 59 void start(); 60 void stop(); 61 62 void receive(); 63 64 // this overrides server_endpoint_impl::send to disable the nPDU feature 65 // for local communication 66 bool send(const uint8_t *_data, uint32_t _size); 67 bool send_to(const std::shared_ptr<endpoint_definition>, 68 const byte_t *_data, uint32_t _size); 69 bool send_error(const std::shared_ptr<endpoint_definition> _target, 70 const byte_t *_data, uint32_t _size); 71 void send_queued(const queue_iterator_type _queue_iterator); 72 void get_configured_times_from_endpoint( 73 service_t _service, method_t _method, 74 std::chrono::nanoseconds *_debouncing, 75 std::chrono::nanoseconds *_maximum_retention) const; 76 77 bool get_default_target(service_t, endpoint_type &) const; 78 79 bool is_local() const; 80 81 void accept_client_func(); 82 void print_status(); 83 84 bool is_reliable() const; 85 std::uint16_t get_local_port() const; 86 void set_local_port(std::uint16_t _port); 87 88 client_t assign_client(const byte_t *_data, uint32_t _size); 89 90 private: 91 class connection: public std::enable_shared_from_this<connection> { 92 93 public: 94 typedef std::shared_ptr<connection> ptr; 95 96 static ptr create(const std::shared_ptr<local_server_endpoint_impl>& _server, 97 std::uint32_t _max_message_size, 98 std::uint32_t _buffer_shrink_threshold, 99 boost::asio::io_service &_io_service); 100 socket_type & get_socket(); 101 std::unique_lock<std::mutex> get_socket_lock(); 102 103 void start(); 104 void stop(); 105 106 107 void send_queued(const message_buffer_ptr_t& _buffer); 108 109 void set_bound_client(client_t _client); 110 client_t get_bound_client() const; 111 #ifndef _WIN32 112 void set_bound_uid_gid(uid_t _uid, gid_t _gid); 113 #endif 114 115 std::size_t get_recv_buffer_capacity() const; 116 117 private: 118 connection(const std::shared_ptr<local_server_endpoint_impl>& _server, 119 std::uint32_t _max_message_size, 120 std::uint32_t _initial_recv_buffer_size, 121 std::uint32_t _buffer_shrink_threshold, 122 boost::asio::io_service &_io_service); 123 124 void send_cbk(const message_buffer_ptr_t _buffer, 125 boost::system::error_code const &_error, std::size_t _bytes); 126 void receive_cbk(boost::system::error_code const &_error, 127 std::size_t _bytes 128 #ifndef _WIN32 129 , std::uint32_t const &_uid, std::uint32_t const &_gid 130 #endif 131 ); 132 void calculate_shrink_count(); 133 const std::string get_path_local() const; 134 const std::string get_path_remote() const; 135 void handle_recv_buffer_exception(const std::exception &_e); 136 137 std::mutex socket_mutex_; 138 local_server_endpoint_impl::socket_type socket_; 139 std::weak_ptr<local_server_endpoint_impl> server_; 140 141 const std::uint32_t recv_buffer_size_initial_; 142 const std::uint32_t max_message_size_; 143 144 message_buffer_t recv_buffer_; 145 size_t recv_buffer_size_; 146 std::uint32_t missing_capacity_; 147 std::uint32_t shrink_count_; 148 const std::uint32_t buffer_shrink_threshold_; 149 150 client_t bound_client_; 151 #ifndef _WIN32 152 uid_t bound_uid_; 153 gid_t bound_gid_; 154 #endif 155 bool assigned_client_; 156 }; 157 158 std::mutex acceptor_mutex_; 159 #ifdef _WIN32 160 boost::asio::ip::tcp::acceptor acceptor_; 161 #else 162 boost::asio::local::stream_protocol_ext::acceptor acceptor_; 163 #endif 164 165 typedef std::map<client_t, connection::ptr> connections_t; 166 std::mutex connections_mutex_; 167 connections_t connections_; 168 169 const std::uint32_t buffer_shrink_threshold_; 170 171 const bool is_routing_endpoint_; 172 173 private: 174 bool add_connection(const client_t &_client, 175 const std::shared_ptr<connection> &_connection); 176 void remove_connection(const client_t &_client); 177 void accept_cbk(const connection::ptr& _connection, 178 boost::system::error_code const &_error); 179 std::string get_remote_information( 180 const queue_iterator_type _queue_iterator) const; 181 std::string get_remote_information( 182 const endpoint_type& _remote) const; 183 184 bool check_packetizer_space(queue_iterator_type _queue_iterator, 185 message_buffer_ptr_t* _packetizer, 186 std::uint32_t _size); 187 bool tp_segmentation_enabled(service_t _service, method_t _method) const; 188 void send_client_identifier(const client_t &_client); 189 }; 190 191 } // namespace vsomeip_v3 192 193 #endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ 194