Line data Source code
1 : /********************************************************************************
2 : * Copyright (c) 2026 Accenture
3 : *
4 : * This program and the accompanying materials are made available under the
5 : * terms of the Apache License Version 2.0 which is available at
6 : * https://www.apache.org/licenses/LICENSE-2.0
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : ********************************************************************************/
10 :
11 : #pragma once
12 :
13 : #include "someip/SomeIpConstants.h"
14 : #include "someip/TcpProxy.h"
15 : #include "someip/TcpServer.h"
16 :
17 : #include <ip/IPEndpoint.h>
18 :
19 : #include <etl/array.h>
20 : #include <etl/expected.h>
21 : #include <etl/span.h>
22 : #include <etl/vector.h>
23 : #include <cstdint>
24 :
25 : namespace someip
26 : {
27 : /**
28 : * The TCP server configuration.
29 : */
30 : class TcpServerConfig
31 : {
32 : public:
33 : struct ClientBuffers
34 : {
35 : TcpServer::ClientBufferPool* clientBufferPool;
36 : uint16_t serverPort;
37 : };
38 :
39 : TcpServerConfig(
40 : ::etl::span<TcpServer> servers,
41 : ::etl::span<uint16_t> ports,
42 : ::etl::span<ClientBuffers> clientBuffers);
43 :
44 : size_t getSize() const;
45 :
46 : TcpServer* getServer(size_t pos) const;
47 : TcpServer* nextServer() const;
48 : TcpServer* getOpenServer(uint16_t localPort) const;
49 :
50 : bool setBufferPool(uint16_t port, ::etl::ivector<::etl::span<uint8_t>>& pool);
51 : TcpServer::ClientBufferPool* getBufferPool(uint16_t port) const;
52 :
53 : bool initPort(uint16_t port) const;
54 : ::etl::expected<uint16_t, PortError> getPort(size_t pos) const;
55 :
56 : void close();
57 :
58 : protected:
59 35 : void setServers(::etl::span<TcpServer> servers) { _servers = servers; }
60 :
61 : private:
62 : ::etl::span<TcpServer> _servers;
63 : ::etl::span<uint16_t> _ports;
64 : ::etl::span<ClientBuffers> _clientBuffers;
65 : };
66 :
67 : /**
68 : * The TCP proxy configuration.
69 : */
70 : class TcpProxyConfig
71 : {
72 : public:
73 : enum class BufferType : uint8_t
74 : {
75 : Internal,
76 : External
77 : };
78 :
79 : TcpProxyConfig(::etl::span<TcpProxy> proxies, BufferType bufferType);
80 :
81 : void setListener(INetworkListener& listener) const;
82 :
83 : size_t getSize() const;
84 :
85 : TcpProxy* getProxy(size_t pos) const;
86 : TcpProxy* getProxy(::tcp::AbstractSocket const& socket) const;
87 : TcpProxy* nextProxy() const;
88 : TcpProxy* getOpenProxy(::ip::IPAddress const& remoteIp, uint16_t localPort) const;
89 : TcpProxy* getOpenProxy(uint16_t localPort, ::ip::IPEndpoint const& remoteEndpoint) const;
90 :
91 19 : BufferType getBufferType() const { return _bufferType; }
92 :
93 54 : void setProxies(::etl::span<TcpProxy> proxies) { _proxies = proxies; }
94 :
95 : void close();
96 :
97 : private:
98 : ::etl::span<TcpProxy> _proxies;
99 : BufferType _bufferType;
100 : };
101 :
102 : /**
103 : * The TCP configuration.
104 : */
105 : class TcpConfig
106 : {
107 : public:
108 : TcpConfig(TcpConfig const&) = delete;
109 : TcpConfig& operator=(TcpConfig const&) = delete;
110 :
111 : TcpServerConfig& _tcpServers;
112 : TcpProxyConfig& _tcpProxies;
113 :
114 : protected:
115 : TcpConfig(TcpServerConfig& tcpServers, TcpProxyConfig& tcpProxies);
116 : };
117 :
118 : namespace internal
119 : {
120 : /**
121 : * Internal TCP server resources.
122 : */
123 : template<class SocketType, uint8_t NumSockets, size_t NumClientBuffers = 0U>
124 : class TcpServerResources : public TcpServerConfig
125 : {
126 : static_assert((NumClientBuffers == 0U) || (NumClientBuffers == NumSockets), "");
127 :
128 : public:
129 35 : explicit TcpServerResources(TcpProxyConfig& clientPool)
130 : : TcpServerConfig(
131 35 : ::etl::span<TcpServer>(),
132 35 : ::etl::span<uint16_t>(portArray),
133 0 : ::etl::span<ClientBuffers>(clientBuffersArray))
134 35 : , socketArray()
135 35 : , portArray()
136 35 : , servers()
137 70 : , clientBuffersArray()
138 : {
139 : #pragma GCC diagnostic push
140 : #pragma GCC diagnostic ignored "-Wtype-limits"
141 70 : for (size_t i = 0U; i < NumSockets; ++i)
142 : #pragma GCC diagnostic pop
143 : {
144 35 : servers.emplace_back(socketArray[i], clientPool);
145 35 : portArray[i] = port::INVALID;
146 : }
147 :
148 45 : for (auto& clientBuffer : clientBuffersArray)
149 : {
150 10 : clientBuffer.serverPort = port::INVALID;
151 : }
152 35 : setServers(servers);
153 35 : }
154 :
155 : ::etl::array<SocketType, NumSockets> socketArray;
156 : ::etl::array<uint16_t, NumSockets> portArray;
157 : ::etl::vector<TcpServer, NumSockets> servers;
158 : ::etl::array<ClientBuffers, NumClientBuffers> clientBuffersArray;
159 : };
160 :
161 : // Specialization for zero TCP servers
162 : template<class SocketType, size_t NumClientBuffers>
163 : class TcpServerResources<SocketType, 0, NumClientBuffers> : public TcpServerConfig
164 : {
165 : public:
166 : explicit TcpServerResources(TcpProxyConfig& /* clientPool */)
167 : : TcpServerConfig(
168 : ::etl::span<TcpServer>(), ::etl::span<uint16_t>(), ::etl::span<ClientBuffers>())
169 : {}
170 : };
171 :
172 : /**
173 : * Internal TCP proxy resources.
174 : */
175 : template<class SocketType, uint8_t NumSockets, size_t BufferSize>
176 : class TcpProxyResources : public TcpProxyConfig
177 : {
178 : public:
179 25 : TcpProxyResources(
180 : ::etl::span<uint8_t> const& inputBuffer, ::etl::span<uint8_t> const& outputBuffer)
181 0 : : TcpProxyConfig(::etl::span<TcpProxy>(), BufferType::Internal)
182 25 : , socketArray()
183 55 : , bufferArray()
184 50 : , proxies()
185 : {
186 : #pragma GCC diagnostic push
187 : #pragma GCC diagnostic ignored "-Wtype-limits"
188 55 : for (uint8_t i = 0U; i < NumSockets; ++i)
189 : {
190 30 : proxies.emplace_back(socketArray[i]);
191 30 : proxies.back().setInputBuffer(inputBuffer);
192 30 : proxies.back().setOutputBuffer(outputBuffer);
193 30 : proxies.back().setInternalBuffer(bufferArray[i]);
194 : }
195 : #pragma GCC diagnostic pop
196 25 : setProxies(proxies);
197 25 : }
198 :
199 : ::etl::array<SocketType, NumSockets> socketArray;
200 : ::etl::array<uint8_t, BufferSize> bufferArray[NumSockets];
201 : ::etl::vector<TcpProxy, NumSockets> proxies;
202 : };
203 :
204 : template<class SocketType, uint8_t NumSockets>
205 : class TcpProxyResources<SocketType, NumSockets, 0U> : public TcpProxyConfig
206 : {
207 : public:
208 10 : TcpProxyResources(
209 : ::etl::span<uint8_t> const& inputBuffer, ::etl::span<uint8_t> const& outputBuffer)
210 10 : : TcpProxyConfig(::etl::span<TcpProxy>(), BufferType::External), socketArray(), proxies()
211 : {
212 : #pragma GCC diagnostic push
213 : #pragma GCC diagnostic ignored "-Wtype-limits"
214 20 : for (uint8_t i = 0U; i < NumSockets; ++i)
215 : #pragma GCC diagnostic pop
216 : {
217 10 : proxies.emplace_back(socketArray[i]);
218 10 : proxies.back().setInputBuffer(inputBuffer);
219 10 : proxies.back().setOutputBuffer(outputBuffer);
220 : }
221 10 : setProxies(proxies);
222 10 : }
223 :
224 : ::etl::array<SocketType, NumSockets> socketArray;
225 : ::etl::vector<TcpProxy, NumSockets> proxies;
226 : };
227 :
228 : // Specialization for zero TCP proxies with zero buffer size
229 : template<class SocketType>
230 : class TcpProxyResources<SocketType, 0, 0U> : public TcpProxyConfig
231 : {
232 : public:
233 : TcpProxyResources(
234 : ::etl::span<uint8_t> const& /* inputBuffer */,
235 : ::etl::span<uint8_t> const& /* outputBuffer */)
236 : : TcpProxyConfig(::etl::span<TcpProxy>(), BufferType::External)
237 : {}
238 : };
239 :
240 : // Specialization for zero TCP proxies with internal buffer
241 : template<class SocketType, size_t BufferSize>
242 : class TcpProxyResources<SocketType, 0, BufferSize> : public TcpProxyConfig
243 : {
244 : public:
245 : TcpProxyResources(
246 : ::etl::span<uint8_t> const& /* inputBuffer */,
247 : ::etl::span<uint8_t> const& /* outputBuffer */)
248 : : TcpProxyConfig(::etl::span<TcpProxy>(), BufferType::Internal)
249 : {}
250 : };
251 :
252 : /**
253 : * Internal TCP resources.
254 : */
255 : template<
256 : class TcpServerSocketType,
257 : uint8_t NumTcpServerSockets,
258 : class TcpSocketType,
259 : uint8_t NumTcpRpcSockets,
260 : size_t TcpBufferSize>
261 : class TcpResources : public TcpConfig
262 : {
263 : public:
264 : #pragma GCC diagnostic push
265 : #pragma GCC diagnostic ignored "-Wuninitialized"
266 :
267 35 : TcpResources(::etl::span<uint8_t> const& inputBuffer, ::etl::span<uint8_t> const& outputBuffer)
268 : : TcpConfig(_serverResources, _proxyResources)
269 35 : , _proxyResources(inputBuffer, outputBuffer)
270 70 : , _serverResources(_proxyResources)
271 35 : {}
272 :
273 : #pragma GCC diagnostic pop
274 :
275 : private:
276 : TcpProxyResources<TcpSocketType, NumTcpRpcSockets, TcpBufferSize> _proxyResources;
277 : TcpServerResources<
278 : TcpServerSocketType,
279 : NumTcpServerSockets,
280 : TcpBufferSize == 0 ? NumTcpServerSockets : 0U>
281 : _serverResources;
282 : };
283 :
284 : } // namespace internal
285 : } // namespace someip
|