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/EventMessage.h"
14 : #include "someip/IEventSender.h"
15 : #include "someip/INetwork.h"
16 : #include "someip/SomeIpConstants.h"
17 :
18 : #include <async/Types.h>
19 : #include <async/util/Call.h>
20 :
21 : #include <ip/IPEndpoint.h>
22 :
23 : #include <etl/flat_set.h>
24 : #include <etl/span.h>
25 : #include <etl/vector.h>
26 : #include <cstdint>
27 :
28 : namespace common
29 : {
30 : class ITimeoutManager2;
31 : }
32 :
33 : namespace someip
34 : {
35 : class ISomeIpSerializable;
36 : class ITpTransceiver;
37 :
38 : /**
39 : * Collects events before sending to minimize network traffic.
40 : */
41 : class BufferedEventSender
42 : {
43 : public:
44 25 : ~BufferedEventSender() = default;
45 :
46 : void init();
47 : void shutdown();
48 :
49 : /**
50 : * Enqueues an event for sending to a destination.
51 : *
52 : * \Note: Events is being send immediately if
53 : * maximumDelayTime == 0 or
54 : * payload > EventMessage::MAX_PAYLOAD_SIZE or
55 : * no available buffer for a new destination
56 : */
57 : IEventSender::ErrorCode sendEvent(
58 : service_id::type serviceId,
59 : major_version::type majorVersion,
60 : uint16_t eventId,
61 : uint32_t maximumDelayTime,
62 : ISomeIpSerializable const* payload,
63 : uint16_t localPort,
64 : uint8_t proto,
65 : ::ip::IPEndpoint const& destination,
66 : uint16_t sessionId = 0U);
67 :
68 : void sendNextMessage();
69 :
70 : // Only used in tests !
71 : size_t countMessages() const;
72 :
73 : protected:
74 : BufferedEventSender(
75 : INetwork& network,
76 : ::async::ContextType const ethernetContext,
77 : ITpTransceiver& tpTransceiver,
78 : ::etl::span<internal::EventMessage*> messages);
79 :
80 25 : void setMessages(::etl::span<internal::EventMessage*> messages) { _eventMessages = messages; }
81 :
82 : private:
83 : static uint32_t const MAX_PACKET_DELAY = 100U;
84 :
85 : IEventSender::ErrorCode sendSingleEvent(
86 : NetworkChannel& channel,
87 : uint16_t localPort,
88 : uint8_t proto,
89 : ::ip::IPEndpoint const& destination,
90 : uint16_t sessionId,
91 : size_t length) const;
92 :
93 : void sendBufferedEvents(internal::EventMessage& message);
94 :
95 : static bool bufferEvent(
96 : internal::EventMessage& message, size_t length, ::etl::span<uint8_t> const& eventBuffer);
97 :
98 : static bool serializeEvent(
99 : service_id::type,
100 : major_version::type,
101 : uint16_t eventId,
102 : ISomeIpSerializable const* payload,
103 : ::etl::span<uint8_t> buffer,
104 : size_t* length /* out */,
105 : uint16_t sessionId = 0);
106 :
107 : internal::EventMessage*
108 : findMessage(::ip::IPEndpoint const& destination, port::type localPort, proto::type proto) const;
109 :
110 : internal::EventMessage* getEmptyMessage() const;
111 : internal::EventMessage* getNextScheduledMessage() const;
112 :
113 : void updateSchedule(uint32_t currentTime);
114 :
115 : ::async::ContextType const _ethernetContext;
116 : ::async::Function _sendNextMessageFunction;
117 : ::async::TimeoutType _sendNextMessageTimeout;
118 : INetwork& _network;
119 : ITpTransceiver& _tpTransceiver;
120 : ::etl::span<internal::EventMessage*> _eventMessages;
121 : uint32_t _nextSendTime; // avoid TimeoutManager::getRemainingTime()
122 : };
123 :
124 : namespace declare
125 : {
126 : template<uint8_t NUM_BUFFERS>
127 : class BufferedEventSender : public ::someip::BufferedEventSender
128 : {
129 : public:
130 : BufferedEventSender(
131 : INetwork& network,
132 : ::async::ContextType const ethernetContext,
133 : ITpTransceiver& tpTransceiver);
134 :
135 : private:
136 : internal::EventMessage _messageArray[NUM_BUFFERS];
137 : ::etl::vector<internal::EventMessage*, NUM_BUFFERS> _messageList;
138 : };
139 :
140 : template<uint8_t NUM_BUFFERS>
141 25 : inline BufferedEventSender<NUM_BUFFERS>::BufferedEventSender(
142 : INetwork& network, ::async::ContextType const ethernetContext, ITpTransceiver& tpTransceiver)
143 : : ::someip::BufferedEventSender(
144 0 : network, ethernetContext, tpTransceiver, ::etl::span<internal::EventMessage*>())
145 176 : , _messageArray()
146 50 : , _messageList()
147 : {
148 : #pragma GCC diagnostic push
149 : #pragma GCC diagnostic ignored "-Wtype-limits"
150 176 : for (uint8_t i = 0U; i < NUM_BUFFERS; ++i)
151 : #pragma GCC diagnostic pop
152 : {
153 151 : internal::EventMessage& buffer = _messageArray[i];
154 151 : _messageList.push_back(&buffer);
155 : }
156 25 : setMessages(_messageList);
157 25 : }
158 :
159 : // Specialization for zero buffers
160 : template<>
161 : class BufferedEventSender<0> : public ::someip::BufferedEventSender
162 : {
163 : public:
164 : BufferedEventSender(
165 : INetwork& network,
166 : ::async::ContextType const ethernetContext,
167 : ITpTransceiver& tpTransceiver)
168 : : ::someip::BufferedEventSender(
169 : network, ethernetContext, tpTransceiver, ::etl::span<internal::EventMessage*>())
170 : {}
171 : };
172 :
173 : } // namespace declare
174 : } // namespace someip
|