14#ifndef NROS_RCLCPP_SUBSCRIPTION_HPP
15#define NROS_RCLCPP_SUBSCRIPTION_HPP
21#include "rclcpp/detail/traits.hpp"
23#include "rclcpp/detail/entity_name.hpp"
26#include "rclcpp/subscription_handle.hpp"
27#include "rclcpp/inplace_fn.hpp"
28#include "rclcpp/size_bound.hpp"
37#include "rclcpp/detail/std_detect.hpp"
39#include "rclcpp/detail/nros_cpp_ffi.h"
63 const char* type_name,
const char* type_hash,
66 void* context,
size_t* out_handle_id,
67 const nros_cpp_subscription_options_t* options);
92 const nros_cpp_node_t* node,
const char* topic,
const char* type_name,
const char* type_hash,
94 size_t capture_len,
void (*capture_drop)(
void* capture),
size_t* out_handle_id,
95 const nros_cpp_subscription_options_t* options);
100 const uint8_t* attachment,
101 size_t attachment_len,
void* ctx);
104 const nros_cpp_node_t* node,
const char* topic,
const char* type_name,
const char* type_hash,
106 size_t* out_handle_id,
const nros_cpp_subscription_options_t* options);
115#if defined(NROS_SAFETY_E2E)
116typedef void (*nros_cpp_subscription_validated_callback_t)(
const uint8_t* data,
size_t len,
117 int64_t gap,
bool duplicate,
118 int8_t crc_valid,
void* ctx);
121 const nros_cpp_node_t* node,
const char* topic,
const char* type_name,
const char* type_hash,
122 nros_cpp_qos_t qos, nros_cpp_subscription_validated_callback_t callback,
void* context,
123 size_t* out_handle_id,
const nros_cpp_subscription_options_t* options);
238#if defined(NROS_SAFETY_E2E)
240 const ::rclcpp::IntegrityStatus&
integrity);
287 ::memcpy(topic_name_,
other.topic_name_,
sizeof(topic_name_));
288 user_fn_ =
other.user_fn_;
289 user_fn_ctx_ =
other.user_fn_ctx_;
290 user_ctx_ =
other.user_ctx_;
291 user_fn_info_ =
other.user_fn_info_;
292#if defined(NROS_SAFETY_E2E)
295 sched_handle_id_ =
other.sched_handle_id_;
296 executor_ =
other.executor_;
297 other.initialized_ =
false;
301 if (
this != &
other) {
302 initialized_ =
other.initialized_;
303 ::memcpy(topic_name_,
other.topic_name_,
sizeof(topic_name_));
304 user_fn_ =
other.user_fn_;
305 user_fn_ctx_ =
other.user_fn_ctx_;
306 user_ctx_ =
other.user_ctx_;
307 user_fn_info_ =
other.user_fn_info_;
308#if defined(NROS_SAFETY_E2E)
311 sched_handle_id_ =
other.sched_handle_id_;
312 executor_ =
other.executor_;
313 other.initialized_ =
false;
359 if (!initialized_ || executor_ ==
nullptr ||
361 return ::rclcpp::detail::qos_all_unknown();
363 return ::rclcpp::detail::qos_from_ffi(
f);
370 friend class ::rclcpp::Node;
375 static void message_trampoline(
const uint8_t* data,
size_t len,
void*
ctx) {
377 if (
self ==
nullptr)
return;
379 if (M::ffi_deserialize(data, len, &
msg) != 0)
return;
380 if (
self->user_fn_ !=
nullptr) {
382 }
else if (
self->user_fn_ctx_ !=
nullptr) {
393 if (
self ==
nullptr)
return;
395 if (M::ffi_deserialize(data, len, &
msg) != 0)
return;
396 if (
self->user_fn_info_ !=
nullptr) {
401#if defined(NROS_SAFETY_E2E)
407 static void message_safety_trampoline(
const uint8_t* data,
size_t len, int64_t gap,
408 bool duplicate, int8_t crc_valid,
void* ctx) {
410 if (self ==
nullptr)
return;
412 if (M::ffi_deserialize(data, len, &msg) != 0)
return;
413 if (self->user_fn_safety_ !=
nullptr) {
414 nros_cpp_integrity_status_t status;
416 status.duplicate = duplicate;
417 status.crc_valid = crc_valid;
418 self->user_fn_safety_(msg, status);
429 void store_topic_name(
const char* topic) {
431 while (topic[n] !=
'\0' && n + 1 <
sizeof(topic_name_)) {
432 topic_name_[n] = topic[n];
435 topic_name_[n] =
'\0';
448 size_t sched_handle_id_ =
static_cast<size_t>(-1);
459 void* executor_ =
nullptr;
464 void* user_ctx_ =
nullptr;
465#if defined(NROS_SAFETY_E2E)
468 TypedSubscriptionSafetyFn user_fn_safety_ =
nullptr;
486template <
typename M,
typename F,
typename>
488 F callback, const ::rclcpp::SubscriptionOptions& options) {
498 out.user_fn_ctx_ =
nullptr;
499 out.user_ctx_ =
nullptr;
503 : static_cast<uint8_t>(options.sched_context);
504 size_t handle =
static_cast<size_t>(-1);
507 nros_cpp_subscription_options_t ffi_options = nros_cpp_subscription_default_options();
508 ffi_options.sched_context = sched;
515 &handle_, topic, M::TYPE_NAME, M::TYPE_HASH, ffi_qos, &Subscription<M>::message_trampoline,
516 &out, &handle, &ffi_options);
518 out.sched_handle_id_ = handle;
519 out.executor_ = executor_handle_;
522 out.store_topic_name(topic);
523 out.initialized_ =
true;
537template <
typename M,
typename F,
typename>
539 Subscription<M>& out,
const char* topic,
540 const ::rclcpp::QoS& qos, F callback,
541 const ::rclcpp::SubscriptionOptions& options) {
549 out.user_fn_ctx_ =
nullptr;
550 out.user_ctx_ =
nullptr;
554 : static_cast<uint8_t>(options.sched_context);
555 size_t handle =
static_cast<size_t>(-1);
557 nros_cpp_subscription_options_t ffi_options = nros_cpp_subscription_default_options();
558 ffi_options.sched_context = sched;
559 ffi_options.callback_group = group.get_name();
564 &handle_, topic, M::TYPE_NAME, M::TYPE_HASH, ffi_qos, &Subscription<M>::message_trampoline,
565 &out, &handle, &ffi_options);
567 out.sched_handle_id_ = handle;
568 out.executor_ = executor_handle_;
571 out.store_topic_name(topic);
572 out.initialized_ =
true;
587template <
typename M,
typename F,
typename>
589 const ::rclcpp::QoS& qos, F callback,
590 const ::rclcpp::SubscriptionOptions& options) {
598 out.user_fn_ =
nullptr;
599 out.user_fn_ctx_ =
nullptr;
600 out.user_ctx_ =
nullptr;
604 : static_cast<uint8_t>(options.sched_context);
605 size_t handle =
static_cast<size_t>(-1);
607 nros_cpp_subscription_options_t ffi_options = nros_cpp_subscription_default_options();
608 ffi_options.sched_context = sched;
614 &handle_, topic, M::TYPE_NAME, M::TYPE_HASH, ffi_qos,
615 &Subscription<M>::message_info_trampoline, &out, &handle, &ffi_options);
617 out.sched_handle_id_ = handle;
618 out.executor_ = executor_handle_;
621 out.store_topic_name(topic);
622 out.initialized_ =
true;
630#if defined(NROS_SAFETY_E2E)
638template <
typename M,
typename F,
typename>
639Result Node::create_subscription_with_safety(Subscription<M>& out,
const char* topic,
640 const ::rclcpp::QoS& qos, F callback,
641 const ::rclcpp::SubscriptionOptions& options) {
648 out.user_fn_safety_ =
typename Subscription<M>::TypedSubscriptionSafetyFn(callback);
649 out.user_fn_ =
nullptr;
650 out.user_fn_ctx_ =
nullptr;
651 out.user_fn_info_ =
nullptr;
652 out.user_ctx_ =
nullptr;
656 : static_cast<uint8_t>(options.sched_context);
657 size_t handle =
static_cast<size_t>(-1);
659 nros_cpp_subscription_options_t ffi_options = nros_cpp_subscription_default_options();
660 ffi_options.sched_context = sched;
665 &handle_, topic, M::TYPE_NAME, M::TYPE_HASH, ffi_qos,
666 &Subscription<M>::message_safety_trampoline, &out, &handle, &ffi_options);
668 out.sched_handle_id_ = handle;
669 out.executor_ = executor_handle_;
672 out.store_topic_name(topic);
673 out.initialized_ =
true;
695template <
typename M,
typename Fn>
697 const QoS& qos,
const Fn& fn,
size_t* out_handle_id) {
712 const Fn* self =
static_cast<const Fn*
>(ctx);
714 if (M::ffi_deserialize(data, len, &msg) != 0)
return;
721 void (*destroy)(
void*) = [](
void* ctx) {
static_cast<Fn*
>(ctx)->clear(); };
724 nros_cpp_subscription_options_t opts = {};
727 h, topic, M::TYPE_NAME, M::TYPE_HASH, ffi_qos, invoke,
728 reinterpret_cast<const uint8_t*
>(&fn),
sizeof(Fn), destroy, out_handle_id, &opts));
Definition client.hpp:129
Definition executor.hpp:116
Result count_publishers(const char *topic_name, size_t *out_count)
Definition executor.hpp:321
Result create_subscription_in_group(const ::rclcpp::CallbackGroup &group, ::rclcpp::Subscription< M > &out, const char *topic, const ::rclcpp::QoS &qos, F callback, const ::rclcpp::SubscriptionOptions &options={})
const nros_cpp_node_t * ffi_handle() const
Definition node.hpp:1475
Result create_subscription_with_info(::rclcpp::Subscription< M > &out, const char *topic, const ::rclcpp::QoS &qos, F callback, const ::rclcpp::SubscriptionOptions &options={})
typename::rclcpp::Subscription< M >::SharedPtr create_subscription(const char *topic, const ::rclcpp::QoS &qos, Cb cb)
Definition result.hpp:216
Definition subscription.hpp:196
bool has_sched_handle() const
Definition subscription.hpp:332
Result get_publisher_count(::rclcpp::Executor &executor, size_t *out_count) const
Definition subscription.hpp:260
Subscription(Subscription &&other)
Definition subscription.hpp:286
Subscription & operator=(Subscription &&other)
Definition subscription.hpp:300
size_t sched_handle_id() const
Definition subscription.hpp:333
Subscription()
Definition subscription.hpp:320
~Subscription()
Definition subscription.hpp:274
void(*)(const M &msg, const uint8_t *attachment, size_t attachment_len) TypedSubscriptionInfoFn
Definition subscription.hpp:234
void(*)(const M &msg, void *ctx) TypedSubscriptionFnWithCtx
Definition subscription.hpp:231
const char * get_topic_name() const
Get the topic name.
Definition subscription.hpp:244
::rclcpp::QoS get_actual_qos() const
Definition subscription.hpp:357
void(*)(const M &msg) TypedSubscriptionFn
Definition subscription.hpp:230
bool is_valid() const
Check if the subscription is initialized and valid.
Definition subscription.hpp:247
Inline storage-size macros for opaque entity buffers.
rclcpp::Executor — drives transport I/O and dispatches callbacks.
int nros_cpp_ret_t
Definition future.hpp:21
ResultOf< void > Result
Definition result.hpp:246
static constexpr size_t SUBSCRIPTION_TOPIC_NAME_MAX
Definition subscription.hpp:142
rclcpp::Node and global session helpers.
rclcpp::QoS — full DDS-shaped QoS settings (Phase 108.B.7).
rclcpp::Result, rclcpp::ErrorCode, and the RCLCPP_TRY macro.
rclcpp::Stream<T> — multi-shot message receiver.
nros_cpp_ret_t nros_cpp_subscription_register_capturing(const nros_cpp_node_t *node, const char *topic, const char *type_name, const char *type_hash, nros_cpp_qos_t qos, nros_cpp_subscription_message_callback_t callback, const uint8_t *capture, size_t capture_len, void(*capture_drop)(void *capture), size_t *out_handle_id, const nros_cpp_subscription_options_t *options)
nros_cpp_ret_t nros_cpp_subscription_register(const nros_cpp_node_t *node, const char *topic, const char *type_name, const char *type_hash, nros_cpp_qos_t qos, nros_cpp_subscription_message_callback_t callback, void *context, size_t *out_handle_id, const nros_cpp_subscription_options_t *options)
void(* nros_cpp_subscription_message_info_callback_t)(const uint8_t *data, size_t len, const uint8_t *attachment, size_t attachment_len, void *ctx)
Definition subscription.hpp:99
nros_cpp_ret_t nros_cpp_subscription_register_with_info(const nros_cpp_node_t *node, const char *topic, const char *type_name, const char *type_hash, nros_cpp_qos_t qos, nros_cpp_subscription_message_info_callback_t callback, void *context, size_t *out_handle_id, const nros_cpp_subscription_options_t *options)
void(* nros_cpp_subscription_message_callback_t)(const uint8_t *data, size_t len, void *ctx)
Definition subscription.hpp:56