Skip to content

Commit

Permalink
Add declaration for function to check QoS profile compatibility (#299)
Browse files Browse the repository at this point in the history
* Add declaration for function to check QoS profile compatibility

Currently, users who are creating a publisher or subscription can receive 'QoS incompatibility'
events from the RMW if an incompatible endpoint is discovered. While this is useful, we
currently don't have a nice way for application to generally check if two QoS profiles are
compatible. For example, it would be nice if tooling could query the communication graph and
report any detected QoS incompatibilities.

In order to reduce code duplication, I think an API for checking QoS compatibilty should live
in a common place. I've opted for `rmw` (over a place like `rcl`) since it's possible QoS
compatiblity rules may vary per RMW vendor. Since rules for all DDS implementations should be
the same, we could put that common logic in `rmw_dds_common`.

Signed-off-by: Jacob Perron <[email protected]>

* Refactor API

Use enum for output; if one or more policies is set to 'system default', then it's better to warn the caller that we aren't sure if QoS profiles are compatible.

Add optional 'reason', and 'reason_size', parameters for outputing a description of what is (or might be) the incompatiblity.

Update API docs.

Signed-off-by: Jacob Perron <[email protected]>

* Do not set output parameters if there is an error

This behaves more like other RMW functions.

Signed-off-by: Jacob Perron <[email protected]>

* Account for possible RMW_RET_ERROR return value

Signed-off-by: Jacob Perron <[email protected]>

* Warn on 'unknown' value

Since it's possible for rmw's to return an unknown value if the policy is set to an unsupported value by ROS 2.

Signed-off-by: Jacob Perron <[email protected]>
  • Loading branch information
jacobperron authored Feb 25, 2021
1 parent ae0553a commit c5c05f1
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
67 changes: 67 additions & 0 deletions rmw/include/rmw/qos_profiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,73 @@ static const rmw_qos_profile_t rmw_qos_profile_unknown =
false
};

typedef enum RMW_PUBLIC_TYPE rmw_qos_compatibility_type_t
{
/// QoS policies are compatible
RMW_QOS_COMPATIBILITY_OK = 0,

/// QoS policies may not be compatible
RMW_QOS_COMPATIBILITY_WARNING,

/// QoS policies are not compatible
RMW_QOS_COMPATIBILITY_ERROR
} rmw_qos_compatibility_type_t;


/// Check if two QoS profiles are compatible.
/**
* Two QoS profiles are compatible if a publisher and subcription
* using the QoS policies can communicate with each other.
*
* If any of the profile policies has the value "system default" or "unknown", then it may not be
* possible to determine the compatibilty.
* In this case, the output parameter `compatibility` is set to `RMW_QOS_COMPATIBILITY_WARNING`
* and `reason` is populated.
*
* If there is a compatibility warning or error, and a buffer is provided for `reason`, then an
* explanation of all warnings and errors will be populated into the buffer, separated by
* semi-colons (`;`).
* Errors will appear before warnings in the string buffer.
* If the provided buffer is not large enough, this function will still write to the buffer, up to
* the `reason_size` number of characters.
* Therefore, it is possible that not all errors and warnings are communicated if the buffer size limit
* is reached.
* A buffer size of 2048 should be more than enough to capture all possible errors and warnings.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | Yes
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] publisher_profile: The QoS profile used for a publisher.
* \param[in] subscription_profile: The QoS profile used for a subscription.
* \param[out] compatibility: `RMW_QOS_COMPATIBILITY_OK` if the QoS profiles are compatible, or
* `RMW_QOS_COMPATIBILITY_WARNING` if the QoS profiles might be compatible, or
* `RMW_QOS_COMPATIBILITY_ERROR` if the QoS profiles are not compatible.
* \param[out] reason: A detailed reason for a QoS incompatibility or potential incompatibility.
* Must be pre-allocated by the caller.
* This parameter is optional and may be set to `NULL` if the reason information is not
* desired.
* \param[in] reason_size: Size of the string buffer `reason`, if one is provided.
* If `reason` is `nullptr`, then this parameter must be zero.
* \return `RMW_RET_OK` if the check was successful, or
* \return `RMW_RET_INVALID_ARGUMENT` if `compatiblity` is `nullptr`, or
* \return `RMW_RET_INVALID_ARGUMENT` if `reason` is `NULL` and `reason_size` is not zero, or
* \return `RMW_RET_ERROR` if there is an unexpected error.
*/
RMW_PUBLIC
RMW_WARN_UNUSED
rmw_ret_t
rmw_qos_profile_check_compatible(
const rmw_qos_profile_t publisher_profile,
const rmw_qos_profile_t subscription_profile,
rmw_qos_compatibility_type_t * compatibility,
char * reason,
size_t reason_size);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions rmw/include/rmw/rmw.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
* - A function to validate a node's name
* - rmw_validate_node_name()
* - rmw/validate_node_name.h
* - A function to validate the compatibility of two QoS profiles
* - rmw_qos_profile_check_compatible()
* - rmw/qos_profiles.h
*
* It also has some machinery that is necessary to wait on and act on these concepts:
*
Expand Down

0 comments on commit c5c05f1

Please sign in to comment.