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/IServiceTrackerListener.h"
14 : #include "someip/ServiceDescription.h"
15 : #include "someip/ServiceQuery.h"
16 :
17 : #include <ip/IPAddress.h>
18 :
19 : #include <etl/flat_set.h>
20 : #include <cstdint>
21 :
22 : namespace someip
23 : {
24 : namespace internal
25 : {
26 : struct TrackedService
27 : {
28 : ServiceDescription serviceDescription;
29 : uint32_t sequentialOffersReceived;
30 : uint64_t lastOfferTimestamp;
31 : };
32 :
33 : struct LessThanComparator
34 : {
35 : bool operator()(TrackedService const& lhs, TrackedService const& rhs) const;
36 : };
37 :
38 : class FindServiceCondition
39 : {
40 : public:
41 : explicit FindServiceCondition(ServiceDescription const& service, bool instanceAny = false);
42 :
43 : bool isValid() const;
44 : bool operator()(TrackedService const& service) const;
45 :
46 : private:
47 : ServiceDescription const& _service;
48 : bool _instanceAny;
49 : };
50 :
51 : class FindInstanceCondition
52 : {
53 : public:
54 : explicit FindInstanceCondition(ServiceDescription const& service);
55 :
56 : bool isValid() const;
57 : bool operator()(TrackedService const& service) const;
58 :
59 : private:
60 : ServiceDescription const& _service;
61 : };
62 :
63 : class RemoveIpCondition
64 : {
65 : public:
66 : RemoveIpCondition(::ip::IPAddress const& ipAddr, IServiceTrackerListener* listener);
67 :
68 : bool operator()(TrackedService const& service) const;
69 :
70 : private:
71 : ::ip::IPAddress const& _ip;
72 : IServiceTrackerListener* _pListener;
73 : };
74 :
75 : class UpdateTTLCondition
76 : {
77 : public:
78 : UpdateTTLCondition(uint32_t ticks, IServiceTrackerListener* listener);
79 :
80 : bool operator()(TrackedService const& service) const;
81 :
82 : private:
83 : uint32_t const _ticks;
84 : IServiceTrackerListener* _pListener;
85 : };
86 :
87 : } // namespace internal
88 :
89 : /**
90 : * Responsible to maintain a list of remote services.
91 : */
92 : class ServiceTracker
93 : {
94 : public:
95 : struct ServiceReliabilityConfig
96 : {
97 : uint32_t expectedOfferPeriodMs;
98 : uint32_t offerCountThreshold;
99 : };
100 :
101 : void init(IServiceTrackerListener& listener);
102 :
103 : /**
104 : * Add or update a service identified by:
105 : *
106 : * - serviceId
107 : * - majorVersion
108 : * - instanceId
109 : *
110 : * \note service TTL > 0 must be set.
111 : *
112 : * \post on success the service was added or internal values were updated.
113 : *
114 : * \return true if successful.
115 : */
116 : bool addService(ServiceDescription const& service);
117 :
118 : /**
119 : * Remove a service identified by:
120 : *
121 : * - serviceId
122 : * - majorVersion
123 : * - instanceId
124 : *
125 : * \post the service was removed if being contained.
126 : */
127 : void removeService(ServiceDescription const& service);
128 :
129 : /**
130 : * Remove all tracked services:
131 : */
132 : void stop();
133 :
134 : /**
135 : * Get a service identified by:
136 : *
137 : * - serviceId
138 : * - majorVersion
139 : * - instanceId
140 : *
141 : * \post on success the provided service was updated with internal values.
142 : *
143 : * \return true if service found.
144 : */
145 : bool getService(ServiceDescription& service) const;
146 :
147 : /**
148 : * Find instanceId of a service identified by:
149 : *
150 : * - serviceId
151 : * - majorVersion
152 : * - ipAddress
153 : * - port
154 : *
155 : * \return instanceId or instance_id::any if not found.
156 : */
157 : instance_id::type getInstanceId(ServiceDescription const& service) const;
158 :
159 : /**
160 : * Adjust TTL = 0 and remove services associated with this IP.
161 : */
162 : void rebootDetected(::ip::IPAddress const& ipAddr);
163 :
164 : /**
165 : * Adjust TTL -= ticks of all services and remove those with TTL == 0.
166 : */
167 : void updateTTLs(uint32_t ticks);
168 :
169 : /**
170 : * Notifies a service query if a service is contained matching:
171 : *
172 : * - serviceId
173 : * - majorVersion
174 : * - instanceId
175 : *
176 : * \note If instanceId == INSTANCE_ID_ANY all corresponding services will be notify.
177 : */
178 : void notifyServices(ServiceQuery& query) const;
179 :
180 : uint16_t getCurrentNumberOfServices() const;
181 : uint16_t getMaximumNumberOfServices() const;
182 :
183 : protected:
184 : using ServiceList = ::etl::iflat_set<internal::TrackedService, internal::LessThanComparator>;
185 :
186 : explicit ServiceTracker(ServiceList& serviceList);
187 : ServiceTracker(ServiceList& serviceList, ServiceReliabilityConfig const& reliabilityConfig);
188 :
189 : ~ServiceTracker() = default;
190 :
191 : private:
192 : ServiceList& _services;
193 : IServiceTrackerListener* _pListener;
194 : ServiceReliabilityConfig _reliabilityConfig;
195 : };
196 :
197 : namespace declare
198 : {
199 :
200 : template<uint16_t NUM_SERVICES>
201 : class ServiceTracker : public ::someip::ServiceTracker
202 : {
203 : public:
204 : ServiceTracker();
205 : explicit ServiceTracker(ServiceTracker::ServiceReliabilityConfig const& reliabilityConfig);
206 :
207 : private:
208 : ::etl::flat_set<internal::TrackedService, NUM_SERVICES, internal::LessThanComparator>
209 : _serviceList;
210 : };
211 :
212 : template<uint16_t NUM_SERVICES>
213 54 : inline ServiceTracker<NUM_SERVICES>::ServiceTracker()
214 54 : : ::someip::ServiceTracker(_serviceList), _serviceList()
215 54 : {}
216 :
217 : template<uint16_t NUM_SERVICES>
218 1 : inline ServiceTracker<NUM_SERVICES>::ServiceTracker(
219 : ServiceTracker::ServiceReliabilityConfig const& reliabilityConfig)
220 1 : : ::someip::ServiceTracker(_serviceList, reliabilityConfig), _serviceList()
221 1 : {}
222 :
223 : } // namespace declare
224 : } // namespace someip
|