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 : #include "someip/EventTransceiver.h"
12 :
13 : #include "someip/BufferedEventSender.h"
14 : #include "someip/ISubscriptionManager.h"
15 : #include "someip/SomeIpParser.h"
16 : #include "someip/SubscribedEventGroup.h"
17 :
18 : #include <etl/algorithm.h>
19 :
20 : namespace someip
21 : {
22 15 : EventTransceiver::EventTransceiver(
23 : BufferedEventSender& eventSender,
24 : ISubscriptionManager& subscriptionManager,
25 15 : ::etl::ivector<SubscriptionEndpoint>& subscriptionEndpoints)
26 15 : : _eventSender(eventSender)
27 15 : , _subscriptionManager(subscriptionManager)
28 15 : , _eventListeners()
29 15 : , _subscriptionEndpoints(subscriptionEndpoints)
30 15 : {}
31 :
32 2 : void EventTransceiver::shutdown() { _eventListeners.clear(); }
33 :
34 : // virtual
35 1 : IEventSender::ErrorCode EventTransceiver::sendEvent(
36 : service_id::type serviceId,
37 : major_version::type majorVersion,
38 : uint16_t eventId,
39 : uint16_t maximumDelayTime,
40 : ISomeIpSerializable const* payload,
41 : port::type sourcePort,
42 : proto::type proto,
43 : ::ip::IPEndpoint const& destinationEndpoint,
44 : uint16_t sessionId)
45 : {
46 1 : return _eventSender.sendEvent(
47 : serviceId,
48 : majorVersion,
49 : eventId,
50 : static_cast<uint32_t>(maximumDelayTime),
51 : payload,
52 : sourcePort,
53 : proto,
54 : destinationEndpoint,
55 1 : sessionId);
56 : }
57 :
58 : // virtual
59 1 : IEventSender::ErrorCode EventTransceiver::sendEvent(
60 : service_id::type serviceId,
61 : major_version::type majorVersion,
62 : instance_id::type instanceId,
63 : uint16_t eventId,
64 : ::etl::span<eventgroup_id::type const> eventGroupIds,
65 : uint16_t maximumDelayTime,
66 : ISomeIpSerializable const* payload,
67 : port::type sourcePort,
68 : proto::type proto,
69 : uint16_t sessionId)
70 : {
71 1 : _subscriptionEndpoints.clear();
72 :
73 3 : for (auto const eventGroupId : eventGroupIds)
74 : {
75 2 : SubscribedEventGroup const eventgroup(serviceId, majorVersion, instanceId, eventGroupId);
76 : SubscriptionEndpointList* const endpoints
77 2 : = _subscriptionManager.getSubscriptions(eventgroup);
78 2 : if (endpoints == nullptr)
79 : {
80 0 : continue;
81 : }
82 :
83 5 : for (auto const& endpoint : *endpoints)
84 : {
85 3 : if (etl::find(_subscriptionEndpoints.begin(), _subscriptionEndpoints.end(), endpoint)
86 3 : == _subscriptionEndpoints.end())
87 : {
88 2 : _subscriptionEndpoints.push_back(endpoint);
89 : }
90 : }
91 2 : }
92 :
93 3 : for (auto const& unique_endpoint : _subscriptionEndpoints)
94 : {
95 2 : (void)_eventSender.sendEvent(
96 : serviceId,
97 : majorVersion,
98 : eventId,
99 : static_cast<uint32_t>(maximumDelayTime),
100 : payload,
101 : sourcePort,
102 : proto,
103 : unique_endpoint,
104 : sessionId);
105 : }
106 :
107 1 : return IEventSender::ErrorCode::EVENT_SEND_OK;
108 : }
109 :
110 : // virtual
111 3 : IEventSender::ErrorCode EventTransceiver::sendMulticastEvent(
112 : service_id::type serviceId,
113 : major_version::type majorVersion,
114 : instance_id::type instanceId,
115 : uint16_t eventId,
116 : ::etl::span<eventgroup_id::type const> eventGroupIds,
117 : uint16_t maximumDelayTime,
118 : ISomeIpSerializable const* payload,
119 : port::type sourcePort,
120 : proto::type proto,
121 : ::ip::IPEndpoint const& destinationEndpoint,
122 : uint16_t sessionId)
123 : {
124 3 : bool hasSubscriber = false;
125 :
126 4 : for (auto const eventGroupId : eventGroupIds)
127 : {
128 2 : SubscribedEventGroup const eventgroup(serviceId, majorVersion, instanceId, eventGroupId);
129 : SubscriptionEndpointList* const endpoints
130 2 : = _subscriptionManager.getSubscriptions(eventgroup);
131 2 : if (endpoints == nullptr)
132 : {
133 0 : continue;
134 : }
135 :
136 2 : if (!endpoints->empty())
137 : {
138 1 : hasSubscriber = true;
139 1 : break;
140 : }
141 2 : }
142 :
143 3 : IEventSender::ErrorCode result = IEventSender::ErrorCode::EVENT_SEND_OK;
144 :
145 3 : if (hasSubscriber)
146 : {
147 1 : result = _eventSender.sendEvent(
148 : serviceId,
149 : majorVersion,
150 : eventId,
151 : static_cast<uint32_t>(maximumDelayTime),
152 : payload,
153 : sourcePort,
154 : proto,
155 : destinationEndpoint,
156 : sessionId);
157 : }
158 :
159 3 : return result;
160 : }
161 :
162 : // virtual
163 3 : void EventTransceiver::eventReceived(
164 : service_id::type serviceId,
165 : uint16_t eventId,
166 : instance_id::type instanceId,
167 : major_version::type majorVersion,
168 : SomeIpParser& parser)
169 : {
170 3 : auto iter = _eventListeners.begin();
171 3 : auto const endIter = _eventListeners.end();
172 :
173 6 : for (; iter != endIter; ++iter)
174 : {
175 3 : parser.resetCurrentPosition();
176 3 : iter->eventReceived(serviceId, eventId, instanceId, majorVersion, parser);
177 : }
178 3 : }
179 :
180 : // virtual
181 5 : void EventTransceiver::addEventListener(IEventListener& listener)
182 : {
183 5 : _eventListeners.push_front(listener);
184 5 : }
185 :
186 : // virtual
187 4 : void EventTransceiver::removeEventListener(IEventListener& listener)
188 : {
189 9 : _eventListeners.remove_if([&listener](IEventListener const& l) { return &l == &listener; });
190 4 : }
191 :
192 : } // namespace someip
|