@@ -186,6 +186,166 @@ rmw_get_subscriptions_info_by_topic(
186186 bool no_mangle ,
187187 rmw_topic_endpoint_info_array_t * subscriptions_info );
188188
189+ /// Retrieve endpoint information for each known client of a given service.
190+ /**
191+ * This function returns an array of endpoint information for each client
192+ * of a given service, as discovered so far by the given node.
193+ * Endpoint information includes the client's node name and namespace,
194+ * the associated topic type, the client's gid, and the client QoS profile.
195+ * Names of non-existent topics are allowed, in which case an empty array will be returned.
196+ *
197+ * Depending on the RMW in use, discovery may be asynchronous. Therefore, creating a client
198+ * and then calling this API may not show the newly created client immediately.
199+ *
200+ * \par QoS that are correctly read
201+ * Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details.
202+ *
203+ * <hr>
204+ * Attribute | Adherence
205+ * ------------------ | -------------
206+ * Allocates Memory | Yes
207+ * Thread-Safe | Yes
208+ * Uses Atomics | Maybe [1]
209+ * Lock-Free | Maybe [1]
210+ * <i>[1] rmw implementation defined, check the implementation documentation</i>
211+ *
212+ * \par Runtime behavior
213+ * To query the ROS graph is a synchronous operation.
214+ * It is also non-blocking, but it is not guaranteed to be lock-free.
215+ * Generally speaking, implementations may synchronize access to internal resources using
216+ * locks but are not allowed to wait for events with no guaranteed time bound (barring
217+ * the effects of starvation due to OS scheduling).
218+ *
219+ * \par Thread-safety
220+ * Nodes are thread-safe objects, and so are all operations on them except for finalization.
221+ * Therefore, it is safe to query the ROS graph using the same node concurrently.
222+ * However, when querying service names and types:
223+ * - Access to the array of topic endpoint information is not synchronized.
224+ * It is not safe to read or write `clients_info`
225+ * while rmw_get_clients_info_by_service() uses it.
226+ * - Access to C-style string arguments is read-only but it is not synchronized.
227+ * Concurrent `service_name` reads are safe, but concurrent reads and writes are not.
228+ * - The default allocators are thread-safe objects, but any custom `allocator` may not be.
229+ * Check your allocator documentation for further reference.
230+ *
231+ * \pre Given `node` must be a valid node handle, as returned by rmw_create_node().
232+ * \pre Given `clients_info` must be a zero-initialized array of endpoints' information,
233+ * as returned by rmw_get_zero_initialized_topic_endpoint_info_array().
234+ *
235+ * \param[in] node Node to query the ROS graph.
236+ * \param[in] allocator Allocator to be used when populating the `clients_info` array.
237+ * \param[in] service_name Name of the service for client lookup, often a fully qualified
238+ * topic name but not necessarily (see rmw_create_client()).
239+ * \param[in] no_mangle Whether to mangle the topic name before client lookup or not.
240+ * \param[out] clients_info Array of client information, populated on success,
241+ * left unchanged on failure.
242+ * If populated, it is up to the caller to finalize this array later on,
243+ * using rmw_topic_endpoint_info_array_fini().
244+ * QoS Profiles in the info array will use RMW_DURATION_INFINITE for infinite durations,
245+ * avoiding exposing any implementation-specific values.
246+ * \return `RMW_RET_OK` if the query was successful, or
247+ * \return `RMW_RET_INVALID_ARGUMENT` if `node` is NULL, or
248+ * \return `RMW_RET_INVALID_ARGUMENT` if `allocator` is not valid,
249+ * by rcutils_allocator_is_valid() definition, or
250+ * \return `RMW_RET_INVALID_ARGUMENT` if `service_name` is NULL, or
251+ * \return `RMW_RET_INVALID_ARGUMENT` if `clients_info` is NULL, or
252+ * \return `RMW_RET_INVALID_ARGUMENT` if `clients_info` is not a
253+ * zero-initialized array, or
254+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if the `node` implementation
255+ * identifier does not match this implementation, or
256+ * \return `RMW_RET_BAD_ALLOC` if memory allocation fails, or
257+ * \return `RMW_RET_ERROR` if an unspecified error occurs.
258+ */
259+ RMW_PUBLIC
260+ RMW_WARN_UNUSED
261+ rmw_ret_t
262+ rmw_get_clients_info_by_service (
263+ const rmw_node_t * node ,
264+ rcutils_allocator_t * allocator ,
265+ const char * service_name ,
266+ bool no_mangle ,
267+ rmw_topic_endpoint_info_array_t * clients_info );
268+
269+ /// Retrieve endpoint information for each known server of a given service.
270+ /**
271+ * This function returns an array of endpoint information for each server
272+ * of a given service, as discovered so far by the given node.
273+ * Endpoint information includes the server's node name and namespace,
274+ * the associated topic type, the server's gid, and the server QoS profile.
275+ * Names of non-existent topics are allowed, in which case an empty array will be returned.
276+ *
277+ * Depending on the RMW in use, discovery may be asynchronous. Therefore, creating a server
278+ * and then calling this API may not show the newly created server immediately.
279+ *
280+ * \par QoS that are correctly read
281+ * Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details.
282+ *
283+ * <hr>
284+ * Attribute | Adherence
285+ * ------------------ | -------------
286+ * Allocates Memory | Yes
287+ * Thread-Safe | Yes
288+ * Uses Atomics | Maybe [1]
289+ * Lock-Free | Maybe [1]
290+ * <i>[1] rmw implementation defined, check the implementation documentation</i>
291+ *
292+ * \par Runtime behavior
293+ * To query the ROS graph is a synchronous operation.
294+ * It is also non-blocking, but it is not guaranteed to be lock-free.
295+ * Generally speaking, implementations may synchronize access to internal resources using
296+ * locks but are not allowed to wait for events with no guaranteed time bound (barring
297+ * the effects of starvation due to OS scheduling).
298+ *
299+ * \par Thread-safety
300+ * Nodes are thread-safe objects, and so are all operations on them except for finalization.
301+ * Therefore, it is safe to query the ROS graph using the same node concurrently.
302+ * However, when querying topic names and types:
303+ * - Access to the array of topic endpoint information is not synchronized.
304+ * It is not safe to read or write `servers_info`
305+ * while rmw_get_servers_info_by_service() uses it.
306+ * - Access to C-style string arguments is read-only but it is not synchronized.
307+ * Concurrent `service_name` reads are safe, but concurrent reads and writes are not.
308+ * - The default allocators are thread-safe objects, but any custom `allocator` may not be.
309+ * Check your allocator documentation for further reference.
310+ *
311+ * \pre Given `node` must be a valid node handle, as returned by rmw_create_node().
312+ * \pre Given `servers_info` must be a zero-initialized array of endpoints' information,
313+ * as returned by rmw_get_zero_initialized_topic_endpoint_info_array().
314+ *
315+ * \param[in] node Node to query the ROS graph.
316+ * \param[in] allocator Allocator to be used when populating the `servers_info` array.
317+ * \param[in] service_name Name of the service for server lookup, often a fully qualified
318+ * topic name but not necessarily (see rmw_create_service()).
319+ * \param[in] no_mangle Whether to mangle the topic name before server lookup or not.
320+ * \param[out] servers_info Array of server information, populated on success,
321+ * left unchanged on failure.
322+ * If populated, it is up to the caller to finalize this array later on,
323+ * using rmw_topic_endpoint_info_array_fini().
324+ * QoS Profiles in the info array will use RMW_DURATION_INFINITE for infinite durations,
325+ * avoiding exposing any implementation-specific values.
326+ * \return `RMW_RET_OK` if the query was successful, or
327+ * \return `RMW_RET_INVALID_ARGUMENT` if `node` is NULL, or
328+ * \return `RMW_RET_INVALID_ARGUMENT` if `allocator` is not valid,
329+ * by rcutils_allocator_is_valid() definition, or
330+ * \return `RMW_RET_INVALID_ARGUMENT` if `service_name` is NULL, or
331+ * \return `RMW_RET_INVALID_ARGUMENT` if `servers_info` is NULL, or
332+ * \return `RMW_RET_INVALID_ARGUMENT` if `servers_info` is not a
333+ * zero-initialized array, or
334+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if the `node` implementation
335+ * identifier does not match this implementation, or
336+ * \return `RMW_RET_BAD_ALLOC` if memory allocation fails, or
337+ * \return `RMW_RET_ERROR` if an unspecified error occurs.
338+ */
339+ RMW_PUBLIC
340+ RMW_WARN_UNUSED
341+ rmw_ret_t
342+ rmw_get_servers_info_by_service (
343+ const rmw_node_t * node ,
344+ rcutils_allocator_t * allocator ,
345+ const char * service_name ,
346+ bool no_mangle ,
347+ rmw_topic_endpoint_info_array_t * servers_info );
348+
189349#ifdef __cplusplus
190350}
191351#endif
0 commit comments