From 3d598890b2f4d368ae01079e116adc6e5b927fda Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Thu, 1 Dec 2022 17:29:18 +0000 Subject: [PATCH 1/4] Implement inconsistent topic. Note that this is not hooked up inside of CycloneDDS, so this will never fire currently. Signed-off-by: Chris Lalancette --- rmw_cyclonedds_cpp/src/rmw_node.cpp | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/rmw_cyclonedds_cpp/src/rmw_node.cpp b/rmw_cyclonedds_cpp/src/rmw_node.cpp index acfc33d4..d0a84044 100644 --- a/rmw_cyclonedds_cpp/src/rmw_node.cpp +++ b/rmw_cyclonedds_cpp/src/rmw_node.cpp @@ -515,6 +515,7 @@ MAKE_DDS_EVENT_CALLBACK_FN(requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QO MAKE_DDS_EVENT_CALLBACK_FN(sample_lost, SAMPLE_LOST) MAKE_DDS_EVENT_CALLBACK_FN(offered_incompatible_qos, OFFERED_INCOMPATIBLE_QOS) MAKE_DDS_EVENT_CALLBACK_FN(liveliness_changed, LIVELINESS_CHANGED) +MAKE_DDS_EVENT_CALLBACK_FN(inconsistent_topic, INCONSISTENT_TOPIC) static void listener_set_event_callbacks(dds_listener_t * l, void * arg) { @@ -525,6 +526,7 @@ static void listener_set_event_callbacks(dds_listener_t * l, void * arg) dds_lset_offered_deadline_missed_arg(l, on_offered_deadline_missed_fn, arg, false); dds_lset_offered_incompatible_qos_arg(l, on_offered_incompatible_qos_fn, arg, false); dds_lset_liveliness_changed_arg(l, on_liveliness_changed_fn, arg, false); + dds_lset_inconsistent_topic_arg(l, on_inconsistent_topic_fn, arg, false); } static bool get_readwrite_qos(dds_entity_t handle, rmw_qos_profile_t * rmw_qos_policies) @@ -716,6 +718,24 @@ extern "C" rmw_ret_t rmw_event_set_callback( break; } + case RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC: + { + auto pub_event = static_cast(rmw_event->data); + event_set_callback( + pub_event, DDS_INCONSISTENT_TOPIC_STATUS_ID, + callback, user_data); + break; + } + + case RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC: + { + auto sub_event = static_cast(rmw_event->data); + event_set_callback( + sub_event, DDS_INCONSISTENT_TOPIC_STATUS_ID, + callback, user_data); + break; + } + case RMW_EVENT_INVALID: { return RMW_RET_INVALID_ARGUMENT; @@ -3627,6 +3647,8 @@ static const std::unordered_map mask_map{ {RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS}, {RMW_EVENT_OFFERED_QOS_INCOMPATIBLE, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS}, {RMW_EVENT_MESSAGE_LOST, DDS_SAMPLE_LOST_STATUS}, + {RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC, DDS_INCONSISTENT_TOPIC_STATUS}, + {RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC, DDS_INCONSISTENT_TOPIC_STATUS}, }; static bool is_event_supported(const rmw_event_type_t event_t) @@ -3799,6 +3821,40 @@ extern "C" rmw_ret_t rmw_take_event( } } + case RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC: { + auto it = static_cast(event_info); + auto pub = static_cast(event_handle->data); + + const dds_entity_t topic = dds_get_topic(pub->enth); + dds_inconsistent_topic_status_t st; + if (dds_get_inconsistent_topic_status(topic, &st) < 0) { + *taken = false; + return RMW_RET_ERROR; + } else { + it->total_count = static_cast(st.total_count); + it->total_count_change = st.total_count_change; + *taken = true; + return RMW_RET_OK; + } + } + + case RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC: { + auto it = static_cast(event_info); + auto sub = static_cast(event_handle->data); + + const dds_entity_t topic = dds_get_topic(sub->enth); + dds_inconsistent_topic_status_t st; + if (dds_get_inconsistent_topic_status(topic, &st) < 0) { + *taken = false; + return RMW_RET_ERROR; + } else { + it->total_count = static_cast(st.total_count); + it->total_count_change = st.total_count_change; + *taken = true; + return RMW_RET_OK; + } + } + case RMW_EVENT_INVALID: { break; } From 984065abad9b7acb51322d945c8d69b10b9bbb42 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Tue, 17 Jan 2023 14:54:40 +0000 Subject: [PATCH 2/4] Rename RMW type name to "incompatible type". Signed-off-by: Chris Lalancette --- rmw_cyclonedds_cpp/src/rmw_node.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rmw_cyclonedds_cpp/src/rmw_node.cpp b/rmw_cyclonedds_cpp/src/rmw_node.cpp index d0a84044..a289e1b7 100644 --- a/rmw_cyclonedds_cpp/src/rmw_node.cpp +++ b/rmw_cyclonedds_cpp/src/rmw_node.cpp @@ -718,7 +718,7 @@ extern "C" rmw_ret_t rmw_event_set_callback( break; } - case RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC: + case RMW_EVENT_PUBLISHER_INCOMPATIBLE_TYPE: { auto pub_event = static_cast(rmw_event->data); event_set_callback( @@ -727,7 +727,7 @@ extern "C" rmw_ret_t rmw_event_set_callback( break; } - case RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC: + case RMW_EVENT_SUBSCRIPTION_INCOMPATIBLE_TYPE: { auto sub_event = static_cast(rmw_event->data); event_set_callback( @@ -3647,8 +3647,8 @@ static const std::unordered_map mask_map{ {RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE, DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS}, {RMW_EVENT_OFFERED_QOS_INCOMPATIBLE, DDS_OFFERED_INCOMPATIBLE_QOS_STATUS}, {RMW_EVENT_MESSAGE_LOST, DDS_SAMPLE_LOST_STATUS}, - {RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC, DDS_INCONSISTENT_TOPIC_STATUS}, - {RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC, DDS_INCONSISTENT_TOPIC_STATUS}, + {RMW_EVENT_PUBLISHER_INCOMPATIBLE_TYPE, DDS_INCONSISTENT_TOPIC_STATUS}, + {RMW_EVENT_SUBSCRIPTION_INCOMPATIBLE_TYPE, DDS_INCONSISTENT_TOPIC_STATUS}, }; static bool is_event_supported(const rmw_event_type_t event_t) @@ -3821,8 +3821,8 @@ extern "C" rmw_ret_t rmw_take_event( } } - case RMW_EVENT_PUBLISHER_INCONSISTENT_TOPIC: { - auto it = static_cast(event_info); + case RMW_EVENT_PUBLISHER_INCOMPATIBLE_TYPE: { + auto it = static_cast(event_info); auto pub = static_cast(event_handle->data); const dds_entity_t topic = dds_get_topic(pub->enth); @@ -3838,8 +3838,8 @@ extern "C" rmw_ret_t rmw_take_event( } } - case RMW_EVENT_SUBSCRIPTION_INCONSISTENT_TOPIC: { - auto it = static_cast(event_info); + case RMW_EVENT_SUBSCRIPTION_INCOMPATIBLE_TYPE: { + auto it = static_cast(event_info); auto sub = static_cast(event_handle->data); const dds_entity_t topic = dds_get_topic(sub->enth); From 35f5797a74244d3b3bf613d1fe5595f57bef0722 Mon Sep 17 00:00:00 2001 From: "Hunter L. Allen" Date: Thu, 16 Feb 2023 13:59:21 -0500 Subject: [PATCH 3/4] Detect incompatible types from incompatible QoS callbacks Signed-off-by: Hunter L. Allen --- rmw_cyclonedds_cpp/src/rmw_node.cpp | 52 ++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/rmw_cyclonedds_cpp/src/rmw_node.cpp b/rmw_cyclonedds_cpp/src/rmw_node.cpp index a289e1b7..362f03e4 100644 --- a/rmw_cyclonedds_cpp/src/rmw_node.cpp +++ b/rmw_cyclonedds_cpp/src/rmw_node.cpp @@ -511,11 +511,56 @@ static void dds_listener_callback(dds_entity_t entity, void * arg) MAKE_DDS_EVENT_CALLBACK_FN(requested_deadline_missed, REQUESTED_DEADLINE_MISSED) MAKE_DDS_EVENT_CALLBACK_FN(liveliness_lost, LIVELINESS_LOST) MAKE_DDS_EVENT_CALLBACK_FN(offered_deadline_missed, OFFERED_DEADLINE_MISSED) -MAKE_DDS_EVENT_CALLBACK_FN(requested_incompatible_qos, REQUESTED_INCOMPATIBLE_QOS) MAKE_DDS_EVENT_CALLBACK_FN(sample_lost, SAMPLE_LOST) -MAKE_DDS_EVENT_CALLBACK_FN(offered_incompatible_qos, OFFERED_INCOMPATIBLE_QOS) MAKE_DDS_EVENT_CALLBACK_FN(liveliness_changed, LIVELINESS_CHANGED) -MAKE_DDS_EVENT_CALLBACK_FN(inconsistent_topic, INCONSISTENT_TOPIC) + +/** + * Because the inconsistent topic is not handled correctly in CycloneDDS, + * this callback is signalled via the incompatible qos handlers + */ +// MAKE_DDS_EVENT_CALLBACK_FN(inconsistent_topic, INCONSISTENT_TOPIC) + +static void on_requested_incompatible_qos_fn( + dds_entity_t entity, + const dds_requested_incompatible_qos_status_t status, + void * arg) +{ + (void)entity; + auto data = static_cast(arg); + std::lock_guard guard(data->mutex); + uint32_t type = DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS_ID; + if (DDS_TYPE_CONSISTENCY_ENFORCEMENT_QOS_POLICY_ID == status.last_policy_id) { + /* incompatible types */ + type = DDS_INCONSISTENT_TOPIC_STATUS_ID; + } + auto cb = data->event_callback[type]; + if (cb) { + cb(data->event_data[type], 1); + } else { + data->event_unread_count[type]++; + } +} + +static void on_offered_incompatible_qos_fn( + dds_entity_t entity, + const dds_offered_incompatible_qos_status_t status, + void * arg) +{ + (void)entity; + auto data = static_cast(arg); + std::lock_guard guard(data->mutex); + uint32_t type = DDS_OFFERED_INCOMPATIBLE_QOS_STATUS_ID; + if (DDS_TYPE_CONSISTENCY_ENFORCEMENT_QOS_POLICY_ID == status.last_policy_id) { + /* incompatible types */ + type = DDS_INCONSISTENT_TOPIC_STATUS_ID; + } + auto cb = data->event_callback[type]; + if (cb) { + cb(data->event_data[type], 1); + } else { + data->event_unread_count[type]++; + } +} static void listener_set_event_callbacks(dds_listener_t * l, void * arg) { @@ -526,7 +571,6 @@ static void listener_set_event_callbacks(dds_listener_t * l, void * arg) dds_lset_offered_deadline_missed_arg(l, on_offered_deadline_missed_fn, arg, false); dds_lset_offered_incompatible_qos_arg(l, on_offered_incompatible_qos_fn, arg, false); dds_lset_liveliness_changed_arg(l, on_liveliness_changed_fn, arg, false); - dds_lset_inconsistent_topic_arg(l, on_inconsistent_topic_fn, arg, false); } static bool get_readwrite_qos(dds_entity_t handle, rmw_qos_profile_t * rmw_qos_policies) From a9300024262d6c9cf97476628287c65c286a4cac Mon Sep 17 00:00:00 2001 From: "Hunter L. Allen" Date: Thu, 23 Feb 2023 11:22:44 -0500 Subject: [PATCH 4/4] Clarify reason for special handling for inconsistent topic notification Co-authored-by: eboasson --- rmw_cyclonedds_cpp/src/rmw_node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rmw_cyclonedds_cpp/src/rmw_node.cpp b/rmw_cyclonedds_cpp/src/rmw_node.cpp index 362f03e4..36cf47ea 100644 --- a/rmw_cyclonedds_cpp/src/rmw_node.cpp +++ b/rmw_cyclonedds_cpp/src/rmw_node.cpp @@ -515,7 +515,7 @@ MAKE_DDS_EVENT_CALLBACK_FN(sample_lost, SAMPLE_LOST) MAKE_DDS_EVENT_CALLBACK_FN(liveliness_changed, LIVELINESS_CHANGED) /** - * Because the inconsistent topic is not handled correctly in CycloneDDS, + * Because the inconsistent topic is not raised by CycloneDDS when a reader/writer fail to match because of differing type definitions * this callback is signalled via the incompatible qos handlers */ // MAKE_DDS_EVENT_CALLBACK_FN(inconsistent_topic, INCONSISTENT_TOPIC)