Skip to content

Commit

Permalink
Add sequence numbers to message info structure (#318)
Browse files Browse the repository at this point in the history
* Add sequence numbers to message info structure

Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>

* Add rmw_feature_supported()

Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
  • Loading branch information
ivanpauno authored Mar 21, 2022
1 parent bceeda0 commit 3299fca
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 1 deletion.
63 changes: 63 additions & 0 deletions rmw/include/rmw/features.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

#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_
78 changes: 78 additions & 0 deletions rmw/include/rmw/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion rmw/src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 3299fca

Please sign in to comment.