Skip to content

Commit 951bef1

Browse files
leeminju531fujitatomoya
authored andcommitted
Add get_clients_info_by_service and get_servers_info_by_service; introduce ServiceEntityInfo to handle service type hash in graph cache
Signed-off-by: Minju, Lee <[email protected]>
1 parent 16cae74 commit 951bef1

File tree

4 files changed

+342
-8
lines changed

4 files changed

+342
-8
lines changed

rmw_dds_common/include/rmw_dds_common/graph_cache.hpp

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "rcutils/logging_macros.h"
2727

2828
#include "rmw/names_and_types.h"
29+
#include "rmw/service_endpoint_info.h"
30+
#include "rmw/service_endpoint_info_array.h"
2931
#include "rmw/topic_endpoint_info.h"
3032
#include "rmw/topic_endpoint_info_array.h"
3133
#include "rmw/types.h"
@@ -42,6 +44,7 @@ namespace rmw_dds_common
4244
// Forward-declaration, defined at end of file.
4345
struct EntityInfo;
4446
struct ParticipantInfo;
47+
struct ServiceEntityInfo;
4548

4649
/// Graph cache data structure.
4750
/**
@@ -86,6 +89,8 @@ class GraphCache
8689
* \param type_hash Hash of the description of the topic type.
8790
* \param participant_gid GUID of the participant.
8891
* \param qos QoS profile of the data writer.
92+
* \param service_type_hash Optional pointer to the service type hash,
93+
* used when the writer is part of a service (e.g., request or reply topic)
8994
* \return `true` if the cache was updated, `false` if the data writer
9095
* was already present.
9196
*/
@@ -97,7 +102,8 @@ class GraphCache
97102
const std::string & type_name,
98103
const rosidl_type_hash_t & type_hash,
99104
const rmw_gid_t & participant_gid,
100-
const rmw_qos_profile_t & qos);
105+
const rmw_qos_profile_t & qos,
106+
const rosidl_type_hash_t * service_type_hash = nullptr);
101107

102108
/// Add a data reader based on discovery.
103109
/**
@@ -107,6 +113,8 @@ class GraphCache
107113
* \param type_hash Hash of the description of the topic type.
108114
* \param participant_gid GUID of the participant.
109115
* \param qos QoS profile of the data reader.
116+
* \param service_type_hash Optional pointer to the service type hash,
117+
* used when the reader is part of a service (e.g., request or reply topic)
110118
* \return `true` if the cache was updated, `false` if the data reader
111119
* was already present.
112120
*/
@@ -118,7 +126,8 @@ class GraphCache
118126
const std::string & type_name,
119127
const rosidl_type_hash_t & type_hash,
120128
const rmw_gid_t & participant_gid,
121-
const rmw_qos_profile_t & qos);
129+
const rmw_qos_profile_t & qos,
130+
const rosidl_type_hash_t * service_type_hash = nullptr);
122131

123132
/// Add a data reader or writer.
124133
/**
@@ -129,6 +138,8 @@ class GraphCache
129138
* \param participant_gid GUID of the participant.
130139
* \param qos QoS profile of the entity.
131140
* \param is_reader Whether the entity is a data reader or a writer.
141+
* \param service_type_hash Optional pointer to the service type hash,
142+
* used when the entity is part of a service (e.g., request or reply topic)
132143
* \return `true` if the cache was updated, `false` if the entity
133144
* was already present.
134145
*/
@@ -141,7 +152,8 @@ class GraphCache
141152
const rosidl_type_hash_t & type_hash,
142153
const rmw_gid_t & participant_gid,
143154
const rmw_qos_profile_t & qos,
144-
bool is_reader);
155+
bool is_reader,
156+
const rosidl_type_hash_t * service_type_hash = nullptr);
145157

146158
/// Remove a data writer.
147159
/**
@@ -399,6 +411,46 @@ class GraphCache
399411
rcutils_allocator_t * allocator,
400412
rmw_topic_endpoint_info_array_t * endpoints_info) const;
401413

414+
/// Get an array with information about the clients for a service.
415+
/**
416+
* \param[in] readers_info array containing data readers for the service’s reply topic.
417+
* \param[in] writers_info array containing data writers for the service’s request topic.
418+
* \param[in] allocator Allocator to allocate memory when populating `endpoints_info`.
419+
* \param[out] endpoints_info A zero-initialized service endpoint information
420+
* array to be populated with client information derived from the topic readers and writers.
421+
*
422+
* \return RMW_RET_INVALID_ARGUMENT if any input is null, or
423+
* \return RMW_RET_ERROR if an unexpected error occurs, or
424+
* \return RMW_RET_OK if successful.
425+
*/
426+
RMW_DDS_COMMON_PUBLIC
427+
rmw_ret_t
428+
get_clients_info_by_service(
429+
const rmw_topic_endpoint_info_array_t * readers_info,
430+
const rmw_topic_endpoint_info_array_t * writers_info,
431+
rcutils_allocator_t * allocator,
432+
rmw_service_endpoint_info_array_t * endpoints_info) const;
433+
434+
/// Get an array with information about the servers for a service.
435+
/**
436+
* \param[in] readers_info array containing data readers for the service’s request topic.
437+
* \param[in] writers_info array containing data writers for the service’s reply topic.
438+
* \param[in] allocator Allocator to allocate memory when populating `endpoints_info`.
439+
* \param[out] endpoints_info A zero-initialized service endpoint information array
440+
* to be populated with server information derived from the topic readers and writers.
441+
*
442+
* \return RMW_RET_INVALID_ARGUMENT if any input is null, or
443+
* \return RMW_RET_ERROR if an unexpected error occurs, or
444+
* \return RMW_RET_OK if successful.
445+
*/
446+
RMW_DDS_COMMON_PUBLIC
447+
rmw_ret_t
448+
get_servers_info_by_service(
449+
const rmw_topic_endpoint_info_array_t * readers_info,
450+
const rmw_topic_endpoint_info_array_t * writers_info,
451+
rcutils_allocator_t * allocator,
452+
rmw_service_endpoint_info_array_t * endpoints_info) const;
453+
402454
/// Get all topic names and types.
403455
/**
404456
* \param[in] demangle_topic Function to demangle DDS topic names.
@@ -519,10 +571,14 @@ class GraphCache
519571
/// Sequence of endpoints gids.
520572
using GidSeq =
521573
decltype(std::declval<rmw_dds_common::msg::NodeEntitiesInfo>().writer_gid_seq);
574+
/// \internal
575+
/// Map from endpoint gids to service endpoints discovery info.
576+
using EntityGidToServiceInfo = std::map<rmw_gid_t, ServiceEntityInfo, Compare_rmw_gid_t>;
522577

523578
private:
524579
EntityGidToInfo data_writers_;
525580
EntityGidToInfo data_readers_;
581+
EntityGidToServiceInfo data_services_;
526582
ParticipantToNodesMap participants_;
527583
std::function<void()> on_change_callback_ = nullptr;
528584

@@ -571,6 +627,20 @@ struct EntityInfo
571627
{}
572628
};
573629

630+
/// Structure to represent the service discovery data from an endpoint (data reader or writer).
631+
struct ServiceEntityInfo
632+
{
633+
/// Hash of the associated service type, if applicable.
634+
/// This field is used to associate endpoints (readers or writers) that form a service,
635+
/// whether the middleware explicitly supports services or represents them as separate topics.
636+
/// See: https://github.com/ros2/rmw/pull/371#issuecomment-2763634820
637+
rosidl_type_hash_t service_type_hash;
638+
639+
explicit ServiceEntityInfo(const rosidl_type_hash_t & service_type_hash)
640+
: service_type_hash(service_type_hash)
641+
{}
642+
};
643+
574644
} // namespace rmw_dds_common
575645

576646
#endif // RMW_DDS_COMMON__GRAPH_CACHE_HPP_

rmw_dds_common/include/rmw_dds_common/qos.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,37 @@ encode_type_hash_for_user_data_qos(
255255
const rosidl_type_hash_t & type_hash,
256256
std::string & string_out);
257257

258+
/// Parse USER_DATA "key=value;key=value;"" encoding, finding value of key "sertypehash"
259+
/**
260+
* \param[in] user_data USER_DATA qos raw bytes
261+
* \param[in] user_data_size Length of user_data
262+
* \param[out] type_hash_out Filled with type hash data if found, or to zero value if key not found
263+
* \return RMW_RET_OK if key parsed successfully
264+
* \return RMW_RET_UNSUPPORTED if key not found
265+
* \return RMW_RET_INVALID_ARGUMENT if user_data is null
266+
* \return RMW_RET_ERROR if sertypehash key found, but value could not be parsed
267+
*/
268+
RMW_DDS_COMMON_PUBLIC
269+
rmw_ret_t
270+
parse_sertype_hash_from_user_data(
271+
const uint8_t * user_data,
272+
size_t user_data_size,
273+
rosidl_type_hash_t & type_hash_out);
274+
275+
/// Encode type hash as "sertypehash=hash_string;" for use in USER_DATA QoS
276+
/**
277+
* \param[in] type_hash Type hash value to encode
278+
* \param[out] string_out On success, will be set to "sertypehash=stringified_type_hash;"
279+
* If type_hash's version is 0, string_out will be set to empty
280+
* \return RMW_RET_OK on success, including empty string for unset version
281+
* \return RMW_RET_BAD_ALLOC if memory allocation fails
282+
*/
283+
RMW_DDS_COMMON_PUBLIC
284+
rmw_ret_t
285+
encode_sertype_hash_for_user_data_qos(
286+
const rosidl_type_hash_t & type_hash,
287+
std::string & string_out);
288+
258289
} // namespace rmw_dds_common
259290

260291
#endif // RMW_DDS_COMMON__QOS_HPP_

0 commit comments

Comments
 (0)