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/IRpcReceiver.h"
14 : #include "someip/IServiceAnnouncer.h"
15 : #include "someip/IServiceListener.h"
16 : #include "someip/ServiceQuery.h"
17 : #include "someip/TcpClientChannelValidator.h"
18 :
19 : #include <ip/IPEndpoint.h>
20 :
21 : #include <etl/flat_set.h>
22 : #include <cstdint>
23 :
24 : namespace someip
25 : {
26 : /**
27 : * Responsible to maintain a list of service queries.
28 : */
29 : class QueryManager
30 : {
31 : public:
32 : void wire(IServiceAnnouncer* serviceAnnouncer, IRpcReceiver* rpcReceiver);
33 :
34 : /**
35 : * Initialize registered queries.
36 : */
37 : void start() const;
38 :
39 : /**
40 : * Update status of all queries to unavailable and send stop subscribes.
41 : */
42 : void stop() const;
43 :
44 : /**
45 : * Register a query.
46 : *
47 : * \post query will be initialized.
48 : *
49 : * \return true if query was registered.
50 : */
51 : bool registerQuery(ServiceQuery& query);
52 :
53 : /**
54 : * Unregister a query.
55 : *
56 : * \post query will be set to idle.
57 : *
58 : * \return true if query was removed.
59 : */
60 : bool unregisterQuery(ServiceQuery& query);
61 :
62 : /**
63 : * Answers if given query is registered.
64 : */
65 : bool hasQuery(ServiceQuery& query) const;
66 :
67 : /**
68 : * Returns query if registered or nullptr otherwise.
69 : */
70 : ServiceQuery const* getQuery(service_id::type serviceId, instance_id::type instanceId) const;
71 :
72 : /**
73 : * Check the presence of a local port in any eventgroup for given serviceId,
74 : * instanceId, majorVersion.
75 : *
76 : * \return true if a query with the specified port was found.
77 : */
78 : bool isEventgroupPort(
79 : service_id::type serviceId,
80 : instance_id::type instanceId,
81 : major_version::type majorVersion,
82 : uint16_t port) const;
83 :
84 : /**
85 : * Answers if there is a query registered with a given ServiceDescription.
86 : */
87 : bool hasServiceDescription(ServiceDescription const& service) const;
88 :
89 : /**
90 : * Update queries depending on service status change.
91 : *
92 : * \post query-listener will get notified on service status.
93 : */
94 : void
95 : updateQueries(ServiceDescription const& service, IServiceListener::ServiceStatus status) const;
96 :
97 : /**
98 : * Update queries depending on time change.
99 : *
100 : * \post service-announcer will get notified on findings.
101 : */
102 : void updateQueries(uint64_t timestamp) const;
103 :
104 : /**
105 : * Handle a received subscribe ack.
106 : *
107 : * \post rpc-receiver will get notified on multicast reception.
108 : */
109 : void subscribeAckReceived(
110 : ServiceDescription const& service,
111 : ::ip::IPEndpoint const& multicastEndpoint,
112 : ::ip::IPAddress const& sourceAddress);
113 :
114 : /**
115 : * Handle a received subscribe nack.
116 : *
117 : * \post query-listener will get notified on service status.
118 : */
119 : void
120 : subscribeNackReceived(ServiceDescription const& service, ::ip::IPAddress const& sourceAddress);
121 :
122 : /**
123 : * Handle a received offer.
124 : *
125 : * \post service-announcer will get notified on subscribe / unsubscribe.
126 : */
127 : void offerReceived(ServiceDescription const& service, ::ip::IPAddress const& sourceAddress);
128 :
129 : /**
130 : * Handle a received stop offer.
131 : */
132 : void stopOfferReceived(ServiceDescription const& service) const;
133 :
134 9 : uint32_t getMaxNumQueries() const { return static_cast<uint32_t>(_queries.max_size()); }
135 :
136 9 : uint32_t getNumQueries() const { return static_cast<uint32_t>(_queries.size()); }
137 :
138 : protected:
139 : struct ServiceIdComparator
140 : {
141 : bool operator()(ServiceQuery const* lhs, uint16_t rhs) const;
142 : };
143 :
144 : struct LessThanComparator
145 : {
146 : bool operator()(ServiceQuery const* lhs, ServiceQuery const* rhs) const;
147 : };
148 :
149 : using QueryList = ::etl::iflat_set<ServiceQuery*, LessThanComparator>;
150 :
151 : QueryManager(QueryList& queryList, TcpClientChannelValidator& validator);
152 :
153 : private:
154 : void updateQueryInInitialPhase(uint64_t timestamp, ServiceQuery& query) const;
155 : void updateQueryInRepetitionPhase(uint64_t timestamp, ServiceQuery& query) const;
156 :
157 : QueryList& _queries;
158 :
159 : IServiceAnnouncer* _pServiceAnnouncer;
160 : IRpcReceiver* _pRpcReceiver;
161 : TcpClientChannelValidator& _tcpClientChannelValidator;
162 : };
163 :
164 : namespace declare
165 : {
166 : template<uint16_t NUM_QUERIES>
167 : class QueryManager : public ::someip::QueryManager
168 : {
169 : public:
170 68 : explicit QueryManager(TcpClientChannelValidator& tcpClientChannelValidator)
171 68 : : ::someip::QueryManager(_queries, tcpClientChannelValidator)
172 68 : {}
173 :
174 : private:
175 : ::etl::flat_set<ServiceQuery*, NUM_QUERIES, LessThanComparator> _queries;
176 : };
177 :
178 : } // namespace declare
179 : } // namespace someip
|