summaryrefslogtreecommitdiff
path: root/implementation/endpoints/include/udp_server_endpoint_impl.hpp
blob: dd7e224e071859e20e6fcb9ef0cb68b4f43b1e23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 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_UDP_SERVER_ENDPOINT_IMPL_HPP_
#define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_

#if VSOMEIP_BOOST_VERSION < 106600
#include <boost/asio/ip/udp_ext.hpp>
#else
#include <boost/asio/ip/udp.hpp>
#endif

#include <vsomeip/defines.hpp>

#include "server_endpoint_impl.hpp"
#include "tp_reassembler.hpp"

namespace vsomeip_v3 {

#if VSOMEIP_BOOST_VERSION < 106600
using udp_server_endpoint_base_impl =
    server_endpoint_impl<boost::asio::ip::udp_ext>;
#else
using udp_server_endpoint_base_impl =
    server_endpoint_impl<boost::asio::ip::udp>;
#endif

class udp_server_endpoint_impl: public udp_server_endpoint_base_impl {

public:
    udp_server_endpoint_impl(const std::shared_ptr<endpoint_host>& _endpoint_host,
                             const std::shared_ptr<routing_host>& _routing_host,
                             const endpoint_type& _local,
                             boost::asio::io_context &_io,
                             const std::shared_ptr<configuration>& _configuration);
    virtual ~udp_server_endpoint_impl();

    void start();
    void stop();

    void receive();

    bool send_to(const std::shared_ptr<endpoint_definition> _target,
            const byte_t *_data, uint32_t _size);
    bool send_error(const std::shared_ptr<endpoint_definition> _target,
                const byte_t *_data, uint32_t _size);
    bool send_queued(const target_data_iterator_type _it);
    void get_configured_times_from_endpoint(
            service_t _service, method_t _method,
            std::chrono::nanoseconds *_debouncing,
            std::chrono::nanoseconds *_maximum_retention) const;

    VSOMEIP_EXPORT void join(const std::string &_address);
    VSOMEIP_EXPORT void join_unlocked(const std::string &_address);
    VSOMEIP_EXPORT void leave(const std::string &_address);
    VSOMEIP_EXPORT void set_multicast_option(
            const boost::asio::ip::address &_address, bool _is_join);

    void add_default_target(service_t _service,
            const std::string &_address, uint16_t _port);
    void remove_default_target(service_t _service);
    bool get_default_target(service_t _service, endpoint_type &_target) const;

    std::uint16_t get_local_port() const;
    void set_local_port(uint16_t _port);
    bool is_local() const;

    void print_status();
    bool is_reliable() const;

private:
    void leave_unlocked(const std::string &_address);
    void set_broadcast();
    void receive_unicast();
    void receive_multicast(uint8_t _id);
    bool is_joined(const std::string &_address) const;
    bool is_joined(const std::string &_address, bool* _received) const;
    std::string get_remote_information(
            const target_data_iterator_type _it) const;
    std::string get_remote_information(const endpoint_type& _remote) const;

    std::string get_address_port_local() const;
    bool tp_segmentation_enabled(service_t _service, method_t _method) const;

    void on_unicast_received(boost::system::error_code const &_error,
            std::size_t _bytes);

    void on_multicast_received(boost::system::error_code const &_error,
            std::size_t _bytes, uint8_t _multicast_id,
			const boost::asio::ip::address &_destination);

    void on_message_received(boost::system::error_code const &_error,
                     std::size_t _bytes,
                     bool _is_multicast,
                     endpoint_type const &_remote,
                     message_buffer_t const &_buffer);

    bool is_same_subnet(const boost::asio::ip::address &_address) const;

private:
    socket_type unicast_socket_;
    endpoint_type unicast_remote_;
    message_buffer_t unicast_recv_buffer_;
    mutable std::mutex unicast_mutex_;

    bool is_v4_;

    std::unique_ptr<socket_type> multicast_socket_;
    std::unique_ptr<endpoint_type> multicast_local_;
    endpoint_type multicast_remote_;
    message_buffer_t multicast_recv_buffer_;
    mutable std::mutex multicast_mutex_;
    uint8_t multicast_id_;
    std::map<std::string, bool> joined_;
    std::atomic<bool> joined_group_;

    mutable std::mutex default_targets_mutex_;
    std::map<service_t, endpoint_type> default_targets_;

    boost::asio::ip::address netmask_;
    unsigned short prefix_;

    const std::uint16_t local_port_;

    std::shared_ptr<tp::tp_reassembler> tp_reassembler_;
    boost::asio::steady_timer tp_cleanup_timer_;
};

} // namespace vsomeip_v3

#endif // VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_