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_SERVER_ENDPOINT_IMPL_HPP_
7 #define VSOMEIP_V3_SERVER_ENDPOINT_IMPL_HPP_
8 
9 #include <deque>
10 #include <map>
11 #include <memory>
12 #include <mutex>
13 #include <set>
14 #include <vector>
15 
16 #include <boost/array.hpp>
17 #include <boost/asio/io_service.hpp>
18 
19 #include "buffer.hpp"
20 #include "endpoint_impl.hpp"
21 #include "tp.hpp"
22 
23 namespace vsomeip_v3 {
24 
25 template<typename Protocol>
26 class server_endpoint_impl: public endpoint_impl<Protocol>,
27         public std::enable_shared_from_this<server_endpoint_impl<Protocol> > {
28 public:
29     typedef typename Protocol::socket socket_type;
30     typedef typename Protocol::endpoint endpoint_type;
31     typedef typename std::map<endpoint_type, std::pair<size_t, std::deque<message_buffer_ptr_t>>> queue_type;
32     typedef typename queue_type::iterator queue_iterator_type;
33 
34     server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
35                          const std::shared_ptr<routing_host>& _routing_host,
36                          endpoint_type _local, boost::asio::io_service &_io,
37                          std::uint32_t _max_message_size,
38                          configuration::endpoint_queue_limit_t _queue_limit,
39                          const std::shared_ptr<configuration>& _configuration);
40     virtual ~server_endpoint_impl();
41 
42     bool is_client() const;
43     void restart(bool _force);
44     bool is_established() const;
45     bool is_established_or_connected() const;
46     void set_established(bool _established);
47     void set_connected(bool _connected);
48     bool send(const uint8_t *_data, uint32_t _size);
49     bool send(const std::vector<byte_t>& _cmd_header, const byte_t *_data,
50               uint32_t _size);
51 
52     void prepare_stop(endpoint::prepare_stop_handler_t _handler,
53                       service_t _service);
54     virtual void stop();
55     bool flush(endpoint_type _target,
56                const std::shared_ptr<train>& _train);
57 
58     size_t get_queue_size() const;
59 
60     virtual bool is_reliable() const = 0;
61     virtual std::uint16_t get_local_port() const = 0;
62     virtual void set_local_port(uint16_t _port) = 0;
63 
64 public:
65     void connect_cbk(boost::system::error_code const &_error);
66     void send_cbk(const queue_iterator_type _queue_iterator,
67                   boost::system::error_code const &_error, std::size_t _bytes);
68     void flush_cbk(endpoint_type _target,
69                    const std::shared_ptr<train>& _train,
70                    const boost::system::error_code &_error_code);
71 
72 protected:
73     virtual bool send_intern(endpoint_type _target, const byte_t *_data,
74                              uint32_t _port);
75     virtual void send_queued(const queue_iterator_type _queue_iterator) = 0;
76     virtual void get_configured_times_from_endpoint(
77             service_t _service, method_t _method,
78             std::chrono::nanoseconds *_debouncing,
79             std::chrono::nanoseconds *_maximum_retention) const = 0;
80 
81     virtual bool get_default_target(service_t _service,
82             endpoint_type &_target) const = 0;
83 
84     virtual void print_status() = 0;
85 
86     typename endpoint_impl<Protocol>::cms_ret_e check_message_size(
87             const std::uint8_t * const _data, std::uint32_t _size,
88             const endpoint_type& _target);
89     bool check_queue_limit(const uint8_t *_data, std::uint32_t _size,
90                            std::size_t _current_queue_size) const;
91     void queue_train(const queue_iterator_type _queue_iterator,
92                      const std::shared_ptr<train>& _train,
93                      bool _queue_size_zero_on_entry);
94     queue_iterator_type find_or_create_queue_unlocked(const endpoint_type& _target);
95     std::shared_ptr<train> find_or_create_train_unlocked(const endpoint_type& _target);
96 
97     void send_segments(const tp::tp_split_messages_t &_segments, const endpoint_type &_target);
98 
99 protected:
100     queue_type queues_;
101 
102     std::mutex requests_mutex_;
103     std::map<client_t,
104         std::map<std::tuple<session_t, service_t, instance_t>, endpoint_type>
105     > requests_;
106 
107     std::map<endpoint_type, std::shared_ptr<train>> trains_;
108 
109     std::map<service_t, endpoint::prepare_stop_handler_t> prepare_stop_handlers_;
110 
111     mutable std::mutex mutex_;
112 
113     std::mutex sent_mutex_;
114     bool is_sending_;
115     boost::asio::steady_timer sent_timer_;
116 
117 private:
118     virtual std::string get_remote_information(
119             const queue_iterator_type _queue_iterator) const = 0;
120     virtual std::string get_remote_information(
121             const endpoint_type& _remote) const = 0;
122     virtual bool tp_segmentation_enabled(service_t _service,
123                                          method_t _method) const = 0;
124     void wait_until_debounce_time_reached(const std::shared_ptr<train>& _train) const;
125 };
126 
127 } // namespace vsomeip_v3
128 
129 #endif // VSOMEIP_V3_SERVER_ENDPOINT_IMPL_HPP_
130