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_CLIENT_ENDPOINT_IMPL_HPP_ 7 #define VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ 8 9 #include <condition_variable> 10 #include <deque> 11 #include <mutex> 12 #include <vector> 13 #include <atomic> 14 #include <chrono> 15 16 #include <boost/array.hpp> 17 #include <boost/asio/io_service.hpp> 18 #include <boost/asio/strand.hpp> 19 #include <boost/asio/ip/udp.hpp> 20 #include <boost/utility.hpp> 21 #include <vsomeip/constants.hpp> 22 23 #include "buffer.hpp" 24 #include "endpoint_impl.hpp" 25 #include "client_endpoint.hpp" 26 #include "tp.hpp" 27 28 29 namespace vsomeip_v3 { 30 31 class endpoint; 32 class endpoint_host; 33 34 template<typename Protocol> 35 class client_endpoint_impl: public endpoint_impl<Protocol>, public client_endpoint, 36 public std::enable_shared_from_this<client_endpoint_impl<Protocol> > { 37 public: 38 typedef typename Protocol::endpoint endpoint_type; 39 typedef typename Protocol::socket socket_type; 40 41 client_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host, 42 const std::shared_ptr<routing_host>& _routing_host, 43 const endpoint_type& _local, const endpoint_type& _remote, 44 boost::asio::io_service &_io, 45 std::uint32_t _max_message_size, 46 configuration::endpoint_queue_limit_t _queue_limit, 47 const std::shared_ptr<configuration>& _configuration); 48 virtual ~client_endpoint_impl(); 49 50 bool send(const uint8_t *_data, uint32_t _size); 51 bool send(const std::vector<byte_t>& _cmd_header, const byte_t *_data, 52 uint32_t _size); 53 bool send_to(const std::shared_ptr<endpoint_definition> _target, 54 const byte_t *_data, uint32_t _size); 55 bool send_error(const std::shared_ptr<endpoint_definition> _target, 56 const byte_t *_data, uint32_t _size); 57 bool flush(); 58 59 void prepare_stop(endpoint::prepare_stop_handler_t _handler, service_t _service); 60 virtual void stop(); 61 virtual void restart(bool _force = false) = 0; 62 63 bool is_client() const; 64 65 bool is_established() const; 66 bool is_established_or_connected() const; 67 void set_established(bool _established); 68 void set_connected(bool _connected); 69 virtual bool get_remote_address(boost::asio::ip::address &_address) const; 70 virtual std::uint16_t get_remote_port() const; 71 72 std::uint16_t get_local_port() const; 73 void set_local_port(uint16_t _port); 74 virtual bool is_reliable() const = 0; 75 76 size_t get_queue_size() const; 77 78 public: 79 void connect_cbk(boost::system::error_code const &_error); 80 void wait_connect_cbk(boost::system::error_code const &_error); 81 virtual void send_cbk(boost::system::error_code const &_error, 82 std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); 83 void flush_cbk(boost::system::error_code const &_error); 84 85 public: 86 virtual void connect() = 0; 87 virtual void receive() = 0; 88 virtual void print_status() = 0; 89 90 protected: 91 enum class cei_state_e : std::uint8_t { 92 CLOSED, 93 CONNECTING, 94 CONNECTED, 95 ESTABLISHED 96 }; 97 message_buffer_ptr_t get_front(); 98 virtual void send_queued(message_buffer_ptr_t _buffer) = 0; 99 virtual void get_configured_times_from_endpoint( 100 service_t _service, method_t _method, 101 std::chrono::nanoseconds *_debouncing, 102 std::chrono::nanoseconds *_maximum_retention) const = 0; 103 void shutdown_and_close_socket(bool _recreate_socket); 104 void shutdown_and_close_socket_unlocked(bool _recreate_socket); 105 void start_connect_timer(); 106 typename endpoint_impl<Protocol>::cms_ret_e check_message_size( 107 const std::uint8_t * const _data, std::uint32_t _size); 108 bool check_queue_limit(const uint8_t *_data, std::uint32_t _size) const; 109 void queue_train(bool _queue_size_zero_on_entry); 110 111 protected: 112 mutable std::mutex socket_mutex_; 113 std::unique_ptr<socket_type> socket_; 114 const endpoint_type remote_; 115 116 boost::asio::steady_timer flush_timer_; 117 118 std::mutex connect_timer_mutex_; 119 boost::asio::steady_timer connect_timer_; 120 std::atomic<uint32_t> connect_timeout_; 121 std::atomic<cei_state_e> state_; 122 std::atomic<std::uint32_t> reconnect_counter_; 123 124 // send data 125 train train_; 126 127 std::deque<message_buffer_ptr_t> queue_; 128 std::size_t queue_size_; 129 130 mutable std::mutex mutex_; 131 132 std::atomic<bool> was_not_connected_; 133 134 std::atomic<std::uint16_t> local_port_; 135 136 boost::asio::io_service::strand strand_; 137 138 private: 139 virtual void set_local_port() = 0; 140 virtual std::string get_remote_information() const = 0; 141 virtual bool tp_segmentation_enabled(service_t _service, 142 method_t _method) const = 0; 143 virtual std::uint32_t get_max_allowed_reconnects() const = 0; 144 virtual void max_allowed_reconnects_reached() = 0; 145 void send_segments(const tp::tp_split_messages_t &_segments); 146 void wait_until_debounce_time_reached() const; 147 }; 148 149 } // namespace vsomeip_v3 150 151 #endif // VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ 152