From 1465a33de9d1c90a369b9f3c5a921b8f492a2680 Mon Sep 17 00:00:00 2001 From: Yadunund Date: Tue, 25 Jun 2024 06:29:47 +0800 Subject: [PATCH] Add other qos fields to liveliness tokens Signed-off-by: Yadunund --- rmw_zenoh_cpp/src/detail/liveliness_utils.cpp | 127 ++++++++++++++---- rmw_zenoh_cpp/src/detail/liveliness_utils.hpp | 16 ++- 2 files changed, 112 insertions(+), 31 deletions(-) diff --git a/rmw_zenoh_cpp/src/detail/liveliness_utils.cpp b/rmw_zenoh_cpp/src/detail/liveliness_utils.cpp index 963e70f4..4e5b5810 100644 --- a/rmw_zenoh_cpp/src/detail/liveliness_utils.cpp +++ b/rmw_zenoh_cpp/src/detail/liveliness_utils.cpp @@ -95,7 +95,7 @@ static const char CLI_STR[] = "SC"; static const char KEYEXPR_DELIMITER = '/'; static const char SLASH_REPLACEMENT = '%'; static const char QOS_DELIMITER = ':'; -static const char QOS_HISTORY_DELIMITER = ','; +static const char QOS_COMPONENT_DELIMITER = ','; static const std::unordered_map entity_to_str = { {EntityType::Node, NODE_STR}, @@ -138,6 +138,18 @@ static const std::unordered_map str_to {std::to_string(RMW_QOS_POLICY_DURABILITY_UNKNOWN), RMW_QOS_POLICY_DURABILITY_UNKNOWN} }; +static const std::unordered_map str_to_qos_liveliness = { + {std::to_string(RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT), + RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT}, + {std::to_string(RMW_QOS_POLICY_LIVELINESS_AUTOMATIC), + RMW_QOS_POLICY_LIVELINESS_AUTOMATIC}, + {std::to_string(RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC), + RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC}, + {std::to_string(RMW_QOS_POLICY_LIVELINESS_UNKNOWN), RMW_QOS_POLICY_LIVELINESS_UNKNOWN}, + {std::to_string(RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE), + RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE} +}; + std::vector split_keyexpr( const std::string & keyexpr, const char delim = KEYEXPR_DELIMITER) @@ -161,13 +173,34 @@ std::vector split_keyexpr( std::string qos_to_keyexpr(rmw_qos_profile_t qos) { std::string keyexpr = ""; + // Reliability. keyexpr += std::to_string(qos.reliability); keyexpr += QOS_DELIMITER; + // Durability. keyexpr += std::to_string(qos.durability); keyexpr += QOS_DELIMITER; + // History. keyexpr += std::to_string(qos.history); - keyexpr += QOS_HISTORY_DELIMITER; + keyexpr += QOS_COMPONENT_DELIMITER; keyexpr += std::to_string(qos.depth); + // Deadline. + keyexpr += QOS_DELIMITER; + keyexpr += std::to_string(qos.deadline.sec); + keyexpr += QOS_COMPONENT_DELIMITER; + keyexpr += std::to_string(qos.deadline.nsec); + // Lifespan. + keyexpr += QOS_DELIMITER; + keyexpr += std::to_string(qos.lifespan.sec); + keyexpr += QOS_COMPONENT_DELIMITER; + keyexpr += std::to_string(qos.lifespan.nsec); + // Liveliness. + keyexpr += QOS_DELIMITER; + keyexpr += std::to_string(qos.liveliness); + keyexpr += QOS_COMPONENT_DELIMITER; + keyexpr += std::to_string(qos.liveliness_lease_duration.sec); + keyexpr += QOS_COMPONENT_DELIMITER; + keyexpr += std::to_string(qos.liveliness_lease_duration.nsec); + return keyexpr; } @@ -176,49 +209,87 @@ std::optional keyexpr_to_qos(const std::string & keyexpr) { rmw_qos_profile_t qos; const std::vector parts = split_keyexpr(keyexpr, QOS_DELIMITER); - if (parts.size() < 3) { + if (parts.size() < 6) { return std::nullopt; } - const std::vector history_parts = split_keyexpr(parts[2], QOS_HISTORY_DELIMITER); + const std::vector history_parts = split_keyexpr(parts[2], QOS_COMPONENT_DELIMITER); if (history_parts.size() < 2) { return std::nullopt; } + const std::vector deadline_parts = split_keyexpr(parts[3], QOS_COMPONENT_DELIMITER); + if (deadline_parts.size() < 2) { + return std::nullopt; + } + const std::vector lifespan_parts = split_keyexpr(parts[4], QOS_COMPONENT_DELIMITER); + if (lifespan_parts.size() < 2) { + return std::nullopt; + } + const std::vector liveliness_parts = split_keyexpr(parts[5], + QOS_COMPONENT_DELIMITER); + if (liveliness_parts.size() < 3) { + return std::nullopt; + } try { qos.history = str_to_qos_history.at(history_parts[0]); qos.reliability = str_to_qos_reliability.at(parts[0]); qos.durability = str_to_qos_durability.at(parts[1]); + qos.liveliness = str_to_qos_liveliness.at(liveliness_parts[0]); } catch (const std::exception & e) { RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("Error setting QoS values from strings: %s", e.what()); return std::nullopt; } - // Get the history depth. - errno = 0; - char * endptr; - size_t num = strtoul(history_parts[1].c_str(), &endptr, 10); - if (endptr == history_parts[1].c_str()) { - // No values were converted, this is an error - RMW_SET_ERROR_MSG("no valid numbers available"); - return std::nullopt; - } else if (*endptr != '\0') { - // There was junk after the number - RMW_SET_ERROR_MSG("non-numeric values"); - return std::nullopt; - } else if (errno != 0) { - // Some other error occurred, which may include overflow or underflow - RMW_SET_ERROR_MSG( - "an undefined error occurred while getting the number, this may be an overflow"); + + // Helper function to convert string to size_t. + auto str_to_size_t = + [](const std::string & str) -> std::optional + { + errno = 0; + char * endptr; + size_t num = strtoul(str.c_str(), &endptr, 10); + if (endptr == str.c_str()) { + // No values were converted, this is an error + RMW_SET_ERROR_MSG("no valid numbers available"); + return std::nullopt; + } else if (*endptr != '\0') { + // There was junk after the number + RMW_SET_ERROR_MSG("non-numeric values"); + return std::nullopt; + } else if (errno != 0) { + // Some other error occurred, which may include overflow or underflow + RMW_SET_ERROR_MSG( + "an undefined error occurred while getting the number, this may be an overflow"); + return std::nullopt; + } + return num; + }; + + const auto maybe_depth = str_to_size_t(history_parts[1]); + const auto maybe_deadline_s = str_to_size_t(deadline_parts[0]); + const auto maybe_deadline_ns = str_to_size_t(deadline_parts[1]); + const auto maybe_lifespan_s = str_to_size_t(lifespan_parts[0]); + const auto maybe_lifespan_ns = str_to_size_t(lifespan_parts[1]); + const auto maybe_liveliness_s = str_to_size_t(liveliness_parts[1]); + const auto maybe_liveliness_ns = str_to_size_t(liveliness_parts[2]); + if (maybe_depth == std::nullopt || + maybe_deadline_s == std::nullopt || + maybe_deadline_ns == std::nullopt || + maybe_lifespan_s == std::nullopt || + maybe_lifespan_ns == std::nullopt || + maybe_liveliness_s == std::nullopt || + maybe_liveliness_ns == std::nullopt) + { + // Error already set. return std::nullopt; } - qos.depth = num; - - // Liveliness is always automatic given liveliness tokens. - qos.liveliness = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC; - qos.liveliness_lease_duration = RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT; + qos.depth = *maybe_depth; + qos.deadline.sec = *maybe_deadline_s; + qos.deadline.nsec = *maybe_deadline_ns; + qos.lifespan.sec = *maybe_lifespan_s; + qos.lifespan.nsec = *maybe_lifespan_ns; + qos.liveliness_lease_duration.sec = *maybe_liveliness_s; + qos.liveliness_lease_duration.nsec = *maybe_liveliness_ns; - // TODO(Yadunund): Update once we support these settings. - qos.deadline = RMW_QOS_DEADLINE_DEFAULT; - qos.lifespan = RMW_QOS_LIFESPAN_DEFAULT; return qos; } diff --git a/rmw_zenoh_cpp/src/detail/liveliness_utils.hpp b/rmw_zenoh_cpp/src/detail/liveliness_utils.hpp index 1b42f695..13a682e7 100644 --- a/rmw_zenoh_cpp/src/detail/liveliness_utils.hpp +++ b/rmw_zenoh_cpp/src/detail/liveliness_utils.hpp @@ -198,15 +198,25 @@ std::string demangle_name(const std::string & input); /** * Convert a rmw_qos_profile_t to a string with format: * - * ::," + * ::,:::" * Where: * - enum value from rmw_qos_reliability_policy_e. * - enum value from rmw_qos_durability_policy_e. * - enum value from rmw_qos_history_policy_e. * - The depth number. + * - The seconds component of the deadline duration. + * - The nanoseconds component of the deadline duration. + * - The seconds component of the lifespan duration. + * - The nanoseconds component of the lifespan duration. + * - enum value from rmw_qos_liveliness_policy_e. + * - The seconds component of the liveliness duration. + * - The nanoseconds component of the liveliness duration. * For example, the liveliness substring for a topic with Reliability policy: reliable, - * Durability policy: volatile, History policy: keep_last, and depth: 10, would be - * "1:2:1,10". See rmw/types.h for the values of each policy enum. + * Durability policy: volatile, History policy: keep_last, and depth: 10, + * Deadline: 5s0ns, Lifespan 60s3000ns, Liveliness: RMW_QOS_POLICY_LIVELINESS_AUTOMATIC, + * LivelinessDuration: 0s0ns would be "1:2:1,10:0,0:60,3000:1,0,0". + * + * See rmw/types.h for the values of each policy enum. */ std::string qos_to_keyexpr(rmw_qos_profile_t qos);