// 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/. #ifndef VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ #include #include #include #include #include #include #include #include #include #include #include #include #include "buffer.hpp" #include "endpoint_impl.hpp" #include "client_endpoint.hpp" #include "tp.hpp" namespace vsomeip_v3 { class endpoint; class endpoint_host; template class client_endpoint_impl: public endpoint_impl, public client_endpoint, public std::enable_shared_from_this > { public: using endpoint_type = typename Protocol::endpoint; using socket_type = typename Protocol::socket; client_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); virtual ~client_endpoint_impl(); bool send(const uint8_t *_data, uint32_t _size); bool send(const std::vector& _cmd_header, const byte_t *_data, uint32_t _size); bool send_to(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); bool flush(); void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); virtual void stop(); virtual void restart(bool _force = false) = 0; bool is_client() const; bool is_established() const; bool is_established_or_connected() const; void set_established(bool _established); void set_connected(bool _connected); virtual bool get_remote_address(boost::asio::ip::address &_address) const; virtual std::uint16_t get_remote_port() const; std::uint16_t get_local_port() const; void set_local_port(uint16_t _port); virtual bool is_reliable() const = 0; size_t get_queue_size() const; public: void connect_cbk(boost::system::error_code const &_error); void wait_connect_cbk(boost::system::error_code const &_error); void wait_connecting_cbk(boost::system::error_code const &_error); virtual void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); void flush_cbk(boost::system::error_code const &_error); public: virtual void connect() = 0; virtual void receive() = 0; virtual void print_status() = 0; protected: enum class cei_state_e : std::uint8_t { CLOSED, CONNECTING, CONNECTED, ESTABLISHED }; std::pair get_front(); virtual void send_queued(std::pair &_entry) = 0; virtual void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const = 0; void shutdown_and_close_socket(bool _recreate_socket); void shutdown_and_close_socket_unlocked(bool _recreate_socket); void start_connect_timer(); void start_connecting_timer(); typename endpoint_impl::cms_ret_e check_message_size( const std::uint8_t * const _data, std::uint32_t _size); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size) const; void queue_train(const std::shared_ptr &_train, bool _queue_size_zero_on_entry); void update_last_departure(); protected: mutable std::mutex socket_mutex_; std::unique_ptr socket_; const endpoint_type remote_; boost::asio::steady_timer flush_timer_; std::mutex connect_timer_mutex_; boost::asio::steady_timer connect_timer_; std::atomic connect_timeout_; std::atomic state_; std::atomic reconnect_counter_; std::mutex connecting_timer_mutex_; boost::asio::steady_timer connecting_timer_; std::atomic connecting_timeout_; // send data std::shared_ptr train_; std::map > > dispatched_trains_; boost::asio::steady_timer dispatch_timer_; std::chrono::steady_clock::time_point last_departure_; std::atomic has_last_departure_; std::deque > queue_; std::size_t queue_size_; mutable std::mutex mutex_; std::atomic was_not_connected_; std::atomic local_port_; boost::asio::io_context::strand strand_; private: virtual void set_local_port() = 0; virtual std::string get_remote_information() const = 0; virtual bool tp_segmentation_enabled(service_t _service, method_t _method) const = 0; virtual std::uint32_t get_max_allowed_reconnects() const = 0; virtual void max_allowed_reconnects_reached() = 0; void send_segments(const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time); void schedule_train(); void start_dispatch_timer(const std::chrono::steady_clock::time_point &_now); void cancel_dispatch_timer(); }; } // namespace vsomeip_v3 #endif // VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_