diff --git a/rmw/include/rmw/features.h b/rmw/include/rmw/features.h new file mode 100644 index 00000000..367b586e --- /dev/null +++ b/rmw/include/rmw/features.h @@ -0,0 +1,63 @@ +// Copyright 2022 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef RMW__FEATURES_H_ +#define RMW__FEATURES_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#include "rcutils/allocator.h" + +#include "rmw/macros.h" +#include "rmw/types.h" +#include "rmw/ret_types.h" +#include "rmw/visibility_control.h" + +/// List of optional rmw features. +/** + * Some of the features listed here might become mandatory in the feature, in which case all rmw + * implementations should return `true`. + * + * There might be some optional features that are not listed here, but the goal is to have all of + * them added. + */ +typedef enum RMW_PUBLIC_TYPE rmw_feature_e +{ + /// `rmw_message_info_t.publication_sequence_number` is filled correctly + /// by the rmw implementation. + RMW_FEATURE_MESSAGE_INFO_PUBLICATION_SEQUENCE_NUMBER = 0, + /// `rmw_message_info_t.reception_sequence_number` is filled correctly + /// by the rmw implementation. + RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER = 1, +} rmw_feature_t; + +/// Query if a feature is supported by the rmw implementation. +/** + * \return `true` if the rmw implementation supports the feature, `false` if not. + */ +RMW_PUBLIC +bool +rmw_feature_supported(rmw_feature_t feature); + +#ifdef __cplusplus +} +#endif + +#endif // RMW__FEATURES_H_ diff --git a/rmw/include/rmw/types.h b/rmw/include/rmw/types.h index 0ba286f7..4f08ea58 100644 --- a/rmw/include/rmw/types.h +++ b/rmw/include/rmw/types.h @@ -515,11 +515,89 @@ typedef struct RMW_PUBLIC_TYPE rmw_gid_s uint8_t data[RMW_GID_STORAGE_SIZE]; } rmw_gid_t; +#define RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED UINT64_MAX + /// Information describing an rmw message typedef struct RMW_PUBLIC_TYPE rmw_message_info_s { + /// Time when the message was published by the publisher. + /** + * The exact point at which the timestamp is taken is not specified, but + * it should be taken consistently at the same point in the + * publishing process each time. + */ rmw_time_point_value_t source_timestamp; + /// Time when the message was received by the subscription. + /** + * The exact point at which the timestamp is taken is not specified, but + * it should be taken consistently at the same point in the + * process of receiving a message each time. + */ rmw_time_point_value_t received_timestamp; + /// Sequence number of the received message set by the publisher. + /** + * This sequence number is set by the publisher and therefore uniquely identifies + * a message when combined with the publisher GID. + * For long running applications, the sequence number might wrap around at some point. + * + * If the rmw implementation doesn't support sequence numbers, its value will be + * RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED. + * + * Requirements: + * + * If `psn1` and `psn2` are the publication sequence numbers obtained by + * calls to `rmw_take*()`, where `psn1` was obtained in a call that happened before `psn2` and both + * sequence numbers are from the same publisher (i.e. also same publisher gid), then: + * + * - psn2 > psn1 (except in the case of a wrap around) + * - `psn2 - psn1 - 1` is the number of messages the publisher sent in the middle of both + * received messages. + * Those might have already been taken by other `rmw_take*()` calls that happened in between or lost. + * `psn2 - psn1 - 1 = 0` if and only if the messages were sent by the publisher consecutively. + */ + uint64_t publication_sequence_number; + /// Sequence number of the received message set by the subscription. + /** + * This sequence number is set by the subscription regardless of which + * publisher sent the message. + * For long running applications, the sequence number might wrap around at some point. + * + * If the rmw implementation doesn't support sequence numbers, its value will be + * RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED. + * + * Requirements: + * + * If `rsn1` and `rsn2` are the reception sequence numbers obtained by + * calls to `rmw_take*()`, where `rsn1` was obtained in a call that happened before `rsn2`, then: + * + * - rsn2 > rsn1 (except in the case of a wrap around) + * - `rsn2 = rsn1 + 1` if and only if both `rmw_take*()` calls happened consecutively. + */ + uint64_t reception_sequence_number; + /// Global unique identifier of the publisher that sent the message. + /** + * The identifier uniquely identifies the publisher for the local context, but + * it will not necessarily be the same identifier given in other contexts or processes + * for the same publisher. + * Therefore the identifier will uniquely identify the publisher within your application + * but may disagree about the identifier for that publisher when compared to another + * application. + * Even with this limitation, when combined with the publisher sequence number it can + * uniquely identify a message within your local context. + * Publisher GIDs generated by the rmw implementation could collide at some point, in which + * case it is not possible to distinguish which publisher sent the message. + * The details of how GIDs are generated are rmw implementation dependent. + * + * It is possible the the rmw implementation needs to reuse a publisher GID, + * due to running out of unique identifiers or some other constraint, in which case + * the rmw implementation may document what happens in that case, but that + * behavior is not defined here. + * However, this should be avoided, if at all possible, by the rmw implementation, + * and should be unlikely to happen in practice. + * + * \todo In the future we want this to uniquely identify the publisher globally across + * contexts, processes, and machines. + */ rmw_gid_t publisher_gid; /// Whether this message is from intra_process communication or not diff --git a/rmw/src/types.c b/rmw/src/types.c index 422ba077..dfb79dcf 100644 --- a/rmw/src/types.c +++ b/rmw/src/types.c @@ -19,6 +19,6 @@ RMW_WARN_UNUSED rmw_message_info_t rmw_get_zero_initialized_message_info(void) { - rmw_message_info_t zero_initialized_message_info = {0, 0, {NULL, {0}}, false}; + rmw_message_info_t zero_initialized_message_info = {0}; return zero_initialized_message_info; }