Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #pragma once
18 : :
19 : : #include <memory>
20 : : #include <optional>
21 : : #include <string>
22 : : #include <string_view>
23 : : #include <vector>
24 : :
25 : : #include "wirestead/base/visibility.hpp"
26 : : #include "wirestead/config/uds_config.hpp"
27 : : #include "wirestead/diagnostics/error_types.hpp"
28 : : #include "wirestead/interface/channel.hpp"
29 : :
30 : : namespace boost {
31 : : namespace asio {
32 : : class io_context;
33 : : }
34 : : } // namespace boost
35 : :
36 : : namespace wirestead {
37 : :
38 : : namespace interface {
39 : : class UdsAcceptorInterface;
40 : : }
41 : :
42 : : namespace transport {
43 : :
44 : : /**
45 : : * @brief Thread-safe UDS Server implementation
46 : : */
47 : : class WIRESTEAD_API UdsServer : public interface::Channel, public std::enable_shared_from_this<UdsServer> {
48 : : public:
49 : : static std::shared_ptr<UdsServer> create(const config::UdsServerConfig& cfg);
50 : : static std::shared_ptr<UdsServer> create(const config::UdsServerConfig& cfg,
51 : : std::unique_ptr<interface::UdsAcceptorInterface> acceptor,
52 : : boost::asio::io_context& ioc);
53 : : ~UdsServer() override;
54 : :
55 : : // Move semantics
56 : : UdsServer(UdsServer&&) noexcept;
57 : : UdsServer& operator=(UdsServer&&) noexcept;
58 : :
59 : : // Non-copyable
60 : : UdsServer(const UdsServer&) = delete;
61 : : UdsServer& operator=(const UdsServer&) = delete;
62 : :
63 : : // Channel implementation
64 : : void start() override;
65 : : void stop() override;
66 : : bool is_connected() const override;
67 : : bool is_backpressure_active() const override;
68 : : bool is_backpressure_active(ClientId client_id) const;
69 : : boost::asio::any_io_executor get_executor() override;
70 : : bool async_write_copy(memory::ConstByteSpan data) override;
71 : : bool async_write_move(std::vector<uint8_t>&& data) override;
72 : : bool async_write_shared(std::shared_ptr<const std::vector<uint8_t>> data) override;
73 : : bool async_try_write_copy(memory::ConstByteSpan data) override;
74 : : bool async_try_write_move(std::vector<uint8_t>&& data) override;
75 : : bool async_try_write_shared(std::shared_ptr<const std::vector<uint8_t>> data) override;
76 : : void on_bytes(OnBytes cb) override;
77 : : void on_state(OnState cb) override;
78 : : void on_backpressure(OnBackpressure cb) override;
79 : : wrapper::RuntimeStats stats() const override;
80 : : void reset_stats() override;
81 : : std::optional<diagnostics::ErrorInfo> last_error_info() const override;
82 : :
83 : : // Multi-client support
84 : : bool broadcast(std::string_view message);
85 : : bool broadcast(memory::ConstByteSpan data);
86 : : bool send_to_client(ClientId client_id, std::string_view message);
87 : : bool send_to_client(ClientId client_id, memory::ConstByteSpan data);
88 : : bool try_send_to_client(ClientId client_id, std::string_view message);
89 : : bool try_send_to_client(ClientId client_id, memory::ConstByteSpan data);
90 : : size_t client_count() const;
91 : : std::vector<ClientId> connected_clients() const;
92 : : std::optional<wrapper::RuntimeStats> client_stats(ClientId client_id) const;
93 : : void set_client_limit(size_t max_clients);
94 : :
95 : : using MultiClientConnectHandler = std::function<void(ClientId client_id, const std::string& client_info)>;
96 : : using MultiClientDataHandler = std::function<void(ClientId client_id, memory::ConstByteSpan data)>;
97 : : using MultiClientDisconnectHandler = std::function<void(ClientId client_id)>;
98 : :
99 : : void on_multi_connect(MultiClientConnectHandler handler);
100 : : void on_multi_data(MultiClientDataHandler handler);
101 : : void on_multi_disconnect(MultiClientDisconnectHandler handler);
102 : :
103 : : base::LinkState state() const;
104 : :
105 : : private:
106 : : explicit UdsServer(const config::UdsServerConfig& cfg);
107 : : UdsServer(const config::UdsServerConfig& cfg, std::unique_ptr<interface::UdsAcceptorInterface> acceptor,
108 : : boost::asio::io_context& ioc);
109 : :
110 : : struct Impl;
111 : : const Impl* get_impl() const { return impl_.get(); }
112 : 23 : Impl* get_impl() { return impl_.get(); }
113 : : std::unique_ptr<Impl> impl_;
114 : : };
115 : : } // namespace transport
116 : : } // namespace wirestead
|